os/security/cryptoservices/certificateandkeymgmt/certstore/unifiedcertstore.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/security/cryptoservices/certificateandkeymgmt/certstore/unifiedcertstore.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,1469 @@
     1.4 +/*
     1.5 +* Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.6 +* All rights reserved.
     1.7 +* This component and the accompanying materials are made available
     1.8 +* under the terms of the License "Eclipse Public License v1.0"
     1.9 +* which accompanies this distribution, and is available
    1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.11 +*
    1.12 +* Initial Contributors:
    1.13 +* Nokia Corporation - initial contribution.
    1.14 +*
    1.15 +* Contributors:
    1.16 +*
    1.17 +* Description: 
    1.18 +*
    1.19 +*/
    1.20 +
    1.21 +
    1.22 +#include "unifiedcertstore.h"
    1.23 +#include "unifiedcertstoreworkingvars.h"
    1.24 +#include "CCheckedCertStore.h"
    1.25 +#include <certificateapps.h>
    1.26 +#include <x509cert.h>
    1.27 +#include <wtlscert.h>
    1.28 +#include <hash.h>
    1.29 +#include <ecom/ecom.h>
    1.30 +
    1.31 +_LIT(KUCSPanic, "CUnifiedCertStore"); 
    1.32 +#define assert(x) __ASSERT_ALWAYS((x), User::Panic(KUCSPanic, 1));
    1.33 +
    1.34 +/////////////////////////////////////////////////////////////////////////////////////
    1.35 +//CUnifiedCertStore
    1.36 +/////////////////////////////////////////////////////////////////////////////////////
    1.37 +
    1.38 +EXPORT_C CUnifiedCertStore* CUnifiedCertStore::NewL(RFs& aFs, TBool aOpenForWrite)
    1.39 +	{
    1.40 +	CUnifiedCertStore* self = CUnifiedCertStore::NewLC(aFs, aOpenForWrite);
    1.41 +	CleanupStack::Pop(self);
    1.42 +	return self;
    1.43 +	}
    1.44 +
    1.45 +EXPORT_C CUnifiedCertStore* CUnifiedCertStore::NewLC(RFs& aFs, TBool aOpenForWrite)
    1.46 +	{
    1.47 +	CUnifiedCertStore* self = new(ELeave) CUnifiedCertStore(aFs, aOpenForWrite);
    1.48 +	CleanupStack::PushL(self);
    1.49 +	RArray<TInt> orderingFilter;
    1.50 +	self->ConstructL(orderingFilter);
    1.51 +	return self;
    1.52 +	}
    1.53 +
    1.54 +EXPORT_C CUnifiedCertStore::~CUnifiedCertStore()
    1.55 +	{
    1.56 +	Cancel();
    1.57 +
    1.58 +	assert(!iWorkingVars);
    1.59 +
    1.60 +	TInt end = iReadOnlyCertStores.Count();
    1.61 +	TInt i;
    1.62 +	for (i = 0; i < end; i++)
    1.63 +		{
    1.64 +		iReadOnlyCertStores[i]->Release();
    1.65 +		}
    1.66 +	iReadOnlyCertStores.Close();
    1.67 +
    1.68 +	end = iWritableCertStores.Count();
    1.69 +	for (i = 0; i < end; i++)
    1.70 +		{
    1.71 +		iWritableCertStores[i]->Release();
    1.72 +		}
    1.73 +	iWritableCertStores.Close();
    1.74 +
    1.75 +	// The elements are already released by the two loops above
    1.76 +	iCertStores.Close();
    1.77 +	
    1.78 +	// release resources allocated to order attributes list
    1.79 +	iOrderAttributes.Close();
    1.80 +    
    1.81 +    DestroyTemporaryMembers();
    1.82 +	iHardwareTypeUids.Close();
    1.83 +	REComSession::FinalClose();
    1.84 +	}
    1.85 +
    1.86 +
    1.87 +EXPORT_C void CUnifiedCertStore::Initialize(TRequestStatus& aStatus)
    1.88 +	{
    1.89 +	BeginAsyncOp(aStatus, EInitializeGetTokenList);
    1.90 +	TRAPD(err, InitializeL());
    1.91 +	if (err != KErrNone)
    1.92 +		{
    1.93 +		Complete(err);
    1.94 +		}
    1.95 +	}
    1.96 +
    1.97 +void CUnifiedCertStore::InitializeL()
    1.98 +	{
    1.99 +	AllocWorkingVarsL();
   1.100 +	
   1.101 +	// We want the list of all token types that support a readable or writable 
   1.102 +	// certstore interface
   1.103 +	RArray<TUid> uidArray;
   1.104 +	CleanupClosePushL(uidArray);
   1.105 +		
   1.106 +	User::LeaveIfError(uidArray.Append(TUid::Uid(KInterfaceWritableCertStore)));
   1.107 +	
   1.108 +	TCTFindTokenTypesByInterface filter(uidArray.Array());
   1.109 +	CCTTokenTypeInfo::ListL(iWorkingVars->iWritableTokenTypes, filter);
   1.110 +
   1.111 +	uidArray.Reset();
   1.112 +
   1.113 +	User::LeaveIfError(uidArray.Append(TUid::Uid(KInterfaceCertStore)));
   1.114 +
   1.115 +	RCPointerArray<CCTTokenTypeInfo> tokenTypes;
   1.116 +	CleanupClosePushL(tokenTypes);
   1.117 +
   1.118 +	TCTFindTokenTypesByInterface filter2(uidArray.Array());
   1.119 +	CCTTokenTypeInfo::ListL(tokenTypes, filter2);
   1.120 +	
   1.121 +  	// Check whether client specified order list has attributes in it
   1.122 +  	if(iOrderAttributes.Count() > 0)
   1.123 +  	    {
   1.124 +  	    ApplyOrderingL(tokenTypes);
   1.125 +  	    }
   1.126 +
   1.127 +	// Make a note of all hardware token types
   1.128 +	TInt i = 0;
   1.129 +	TInt end = tokenTypes.Count();
   1.130 +	for (; i < end; i++)
   1.131 +		{
   1.132 +		TCTTokenTypeAttribute software;
   1.133 +		software.iUID = KCTSoftware;
   1.134 +		TInt find = tokenTypes[i]->Attributes().Find(software);
   1.135 +		// In the case (TInt)ETrue == KThirdPartyCertStore == 1  
   1.136 +		if (find != KErrNotFound && tokenTypes[i]->Attributes()[find].iVal != 
   1.137 +			(TInt)ETrue && tokenTypes[i]->Attributes()[find].iVal != KManufactureCertStore)
   1.138 +			{
   1.139 +			// This is a hardware type. Add its UID to the list.
   1.140 +			User::LeaveIfError(iHardwareTypeUids.Append(tokenTypes[i]->Type()));
   1.141 +			}
   1.142 +		}
   1.143 +
   1.144 +	i = 0;
   1.145 +	while (i < end)
   1.146 +		{
   1.147 +		TInt j = 0;
   1.148 +		TInt jEnd = iWorkingVars->iWritableTokenTypes.Count();
   1.149 +		while (j < jEnd)
   1.150 +			{
   1.151 +			if (iWorkingVars->iWritableTokenTypes[j]->Type() == tokenTypes[i]->Type())
   1.152 +				{
   1.153 +				break;
   1.154 +				}
   1.155 +			j++;
   1.156 +			}
   1.157 +		if (j == jEnd)
   1.158 +			{
   1.159 +			User::LeaveIfError(iWorkingVars->iReadOnlyTokenTypes.Append(tokenTypes[i]));
   1.160 +			tokenTypes.Remove(i);
   1.161 +			end--;
   1.162 +			}
   1.163 +		else
   1.164 +			{
   1.165 +			i++;
   1.166 +			}
   1.167 +		}
   1.168 +
   1.169 +	CleanupStack::PopAndDestroy(2);	// uidArray, tokenTypes
   1.170 +	
   1.171 +	iWorkingVars->iIndex = -1;
   1.172 +
   1.173 +	TRequestStatus* status = &iStatus;
   1.174 +	User::RequestComplete(status, KErrNone);
   1.175 +	SetActive();
   1.176 +	}
   1.177 +
   1.178 +EXPORT_C void CUnifiedCertStore::CancelInitialize()
   1.179 +	{
   1.180 +	if (iState == EInitializeGetTokenList ||
   1.181 +		iState == EInitializeGetToken ||
   1.182 +		iState == EInitializeGetWritableInterface ||
   1.183 +		iState == EInitializeGetReadableInterface ||
   1.184 +		iState == EInitializeGetReadableInterfaceFinished ||
   1.185 +		iState == EInitializeFinished)
   1.186 +		{
   1.187 +		Cancel();
   1.188 +		}	
   1.189 +	}
   1.190 +
   1.191 +void CUnifiedCertStore::List(RMPointerArray<CCTCertInfo>& aCertInfos,
   1.192 +							 const CCertAttributeFilter& aFilter,
   1.193 +							 TRequestStatus& aStatus)
   1.194 +	{
   1.195 +	BeginAsyncOp(aStatus, EList);	
   1.196 +	TRAPD(err, ListL(aCertInfos, aFilter));
   1.197 +	if (err != KErrNone)
   1.198 +		{
   1.199 +		Complete(err);
   1.200 +		}
   1.201 +	}
   1.202 +
   1.203 +void CUnifiedCertStore::ListL(RMPointerArray<CCTCertInfo>& aCertInfos,
   1.204 +							  const CCertAttributeFilter& aFilter)
   1.205 +	{
   1.206 +	if (!iIsInitialized)
   1.207 +		{
   1.208 +		User::Leave(KErrNotReady);
   1.209 +		}
   1.210 +
   1.211 +	AllocWorkingVarsL();
   1.212 +	iWorkingVars->iCertInfos = &aCertInfos;
   1.213 +	iWorkingVars->iFilter = &aFilter;
   1.214 +	iWorkingVars->iCertIndex = aCertInfos.Count();
   1.215 +	iIndex = -1;
   1.216 +	
   1.217 +	SetActive();
   1.218 +	TRequestStatus* status = &iStatus;
   1.219 +	User::RequestComplete(status, KErrNone);
   1.220 +	}
   1.221 +
   1.222 +void CUnifiedCertStore::CancelList()
   1.223 +	{
   1.224 +	if (iState == EList ||
   1.225 +		iState == ERetrieveForList)
   1.226 +		{
   1.227 +		Cancel();
   1.228 +		}
   1.229 +	}
   1.230 +
   1.231 +EXPORT_C void CUnifiedCertStore::List(RMPointerArray<CCTCertInfo>& aCertInfos,
   1.232 +									  const CCertAttributeFilter& aFilter, 
   1.233 +									  const TDesC8& aIssuer, 
   1.234 +									  TRequestStatus& aStatus)
   1.235 +	{
   1.236 +	RPointerArray<const TDesC8> array;
   1.237 +	if (array.Append(&aIssuer) != KErrNone)
   1.238 +		{
   1.239 +		TRequestStatus* status = &aStatus;
   1.240 +		User::RequestComplete(status, KErrNoMemory);
   1.241 +		}
   1.242 +	else
   1.243 +		{
   1.244 +		List(aCertInfos, aFilter, array, aStatus);
   1.245 +		array.Close();
   1.246 +		}
   1.247 +	}
   1.248 +
   1.249 +EXPORT_C void CUnifiedCertStore::List(RMPointerArray<CCTCertInfo>& aCertInfos,
   1.250 +									  const CCertAttributeFilter& aFilter, 
   1.251 +									  RPointerArray<const TDesC8> aIssuers, 
   1.252 +									  TRequestStatus& aStatus)
   1.253 +	{
   1.254 +	BeginAsyncOp(aStatus, EList);	
   1.255 +	TRAPD(err, ListL(aCertInfos, aFilter, aIssuers));
   1.256 +	if (err != KErrNone)
   1.257 +		{
   1.258 +		Complete(err);
   1.259 +		}
   1.260 +	}
   1.261 +
   1.262 +void CUnifiedCertStore::ListL(RMPointerArray<CCTCertInfo>& aCertInfos,
   1.263 +							  const CCertAttributeFilter& aFilter, 
   1.264 +							  RPointerArray<const TDesC8> aIssuers)
   1.265 +	{
   1.266 +	// Obscure special case: If aIssuers has no elements, we should
   1.267 +	// return nothing.
   1.268 +	if (aIssuers.Count() == 0)
   1.269 +		{
   1.270 +		Complete(KErrNone);
   1.271 +		return;
   1.272 +		}
   1.273 +
   1.274 +	AllocWorkingVarsL();
   1.275 +	iWorkingVars->iCertInfos = &aCertInfos;
   1.276 +	iWorkingVars->iFilter = &aFilter;
   1.277 +	iWorkingVars->iCertIndex = aCertInfos.Count();
   1.278 +	
   1.279 +	TInt count = aIssuers.Count();
   1.280 +	for (TInt i = 0 ; i < count ; ++i)
   1.281 +		{
   1.282 +		User::LeaveIfError(iWorkingVars->iIssuerNames.Append(aIssuers[i]));
   1.283 +		}
   1.284 +	
   1.285 +	iIndex = -1;
   1.286 +	SetActive();
   1.287 +	TRequestStatus* status = &iStatus;
   1.288 +	User::RequestComplete(status, KErrNone);	
   1.289 +	}
   1.290 +
   1.291 +EXPORT_C void CUnifiedCertStore::Retrieve(const CCTCertInfo& aCertInfo, 
   1.292 +								 CCertificate*& aCert,
   1.293 +								 TRequestStatus& aStatus)
   1.294 +	{
   1.295 +	BeginAsyncOp(aStatus, ERetrieve);	
   1.296 +	TRAPD(err, RetrieveL(aCertInfo, aCert));
   1.297 +	if (err != KErrNone)
   1.298 +		{
   1.299 +		Complete(err);
   1.300 +		}
   1.301 +	}
   1.302 +
   1.303 +void CUnifiedCertStore::RetrieveL(const CCTCertInfo& aCertInfo, 
   1.304 +								  CCertificate*& aCert)
   1.305 +	{
   1.306 +	FindCertStoreL(aCertInfo.Handle());
   1.307 +
   1.308 +    if (aCertInfo.CertificateFormat() != EX509Certificate &&
   1.309 +        aCertInfo.CertificateFormat() != EWTLSCertificate)
   1.310 +        {
   1.311 +        User::Leave(KErrNotSupported);
   1.312 +        }
   1.313 +
   1.314 +	AllocWorkingVarsL();
   1.315 +	iWorkingVars->iCertDesC = HBufC8::NewMaxL(aCertInfo.Size());
   1.316 +	iWorkingVars->iReturnedCert = &aCert;
   1.317 +	iWorkingVars->iCertType = aCertInfo.CertificateFormat();
   1.318 +	iWorkingVars->iCertDes.Set(iWorkingVars->iCertDesC->Des());
   1.319 +	iCurrentCertStore->Retrieve(aCertInfo, iWorkingVars->iCertDes, iStatus);
   1.320 +	SetActive();
   1.321 +    }
   1.322 +
   1.323 +void CUnifiedCertStore::GetCert(CCTCertInfo*& aCertInfo, 
   1.324 +								const TCTTokenObjectHandle& aHandle, 
   1.325 +								TRequestStatus& aStatus)
   1.326 +	{
   1.327 +	BeginAsyncOp(aStatus, EGetCert);
   1.328 +	TRAPD(err, GetCertL(aCertInfo, aHandle));
   1.329 +	if (err != KErrNone)
   1.330 +		{
   1.331 +		Complete(err);
   1.332 +		}
   1.333 +	}
   1.334 +
   1.335 +void CUnifiedCertStore::GetCertL(CCTCertInfo*& aCertInfo,
   1.336 +								 const TCTTokenObjectHandle& aHandle)
   1.337 +	{
   1.338 +	FindCertStoreL(aHandle);
   1.339 +	iCurrentCertStore->GetCert(aCertInfo, aHandle, iStatus);
   1.340 +	SetActive();
   1.341 +	}
   1.342 +
   1.343 +void CUnifiedCertStore::CancelGetCert()
   1.344 +	{
   1.345 +	if (iState == EGetCert)
   1.346 +		{
   1.347 +		Cancel();
   1.348 +		}
   1.349 +	}
   1.350 +
   1.351 +void CUnifiedCertStore::Applications(const CCTCertInfo& aCertInfo,
   1.352 +									 RArray<TUid>& aApplications,
   1.353 +									 TRequestStatus& aStatus)
   1.354 +	{
   1.355 +	BeginAsyncOp(aStatus, EApplications);
   1.356 +	TRAPD(err, ApplicationsL(aCertInfo, aApplications));
   1.357 +	if (err != KErrNone)
   1.358 +		{
   1.359 +		Complete(err);
   1.360 +		}
   1.361 +	}
   1.362 +
   1.363 +void CUnifiedCertStore::ApplicationsL(const CCTCertInfo& aCertInfo,
   1.364 +									 RArray<TUid>& aApplications)
   1.365 +	{
   1.366 +	FindCertStoreL(aCertInfo.Handle());
   1.367 +	iCurrentCertStore->Applications(aCertInfo, aApplications, iStatus);
   1.368 +	SetActive();
   1.369 +	}
   1.370 +
   1.371 +void CUnifiedCertStore::CancelApplications()
   1.372 +	{
   1.373 +	if (iState == EApplications)
   1.374 +		{
   1.375 +		Cancel();
   1.376 +		}
   1.377 +	}
   1.378 +
   1.379 +void CUnifiedCertStore::IsApplicable(const CCTCertInfo& aCertInfo,
   1.380 +									 TUid aApplication, 
   1.381 +									 TBool& aIsApplicable, 
   1.382 +									 TRequestStatus& aStatus)
   1.383 +	{
   1.384 +	BeginAsyncOp(aStatus, EIsApplicable);
   1.385 +	TRAPD(err, IsApplicableL(aCertInfo, aApplication, aIsApplicable));
   1.386 +	if (err != KErrNone)
   1.387 +		{
   1.388 +		Complete(err);
   1.389 +		}
   1.390 +	}
   1.391 +
   1.392 +void CUnifiedCertStore::IsApplicableL(const CCTCertInfo& aCertInfo,
   1.393 +									  TUid aApplication, 
   1.394 +									  TBool& aIsApplicable)
   1.395 +	{
   1.396 +	FindCertStoreL(aCertInfo.Handle());
   1.397 +	iCurrentCertStore->IsApplicable(aCertInfo, aApplication, aIsApplicable, iStatus);
   1.398 +	SetActive();
   1.399 +	}
   1.400 +
   1.401 +void CUnifiedCertStore::CancelIsApplicable()
   1.402 +	{
   1.403 +	if (iState == EIsApplicable)
   1.404 +		{
   1.405 +		Cancel();
   1.406 +		}
   1.407 +	}
   1.408 +
   1.409 +void CUnifiedCertStore::Trusted(const CCTCertInfo& aCertInfo, 
   1.410 +								TBool& aTrusted, 
   1.411 +								TRequestStatus& aStatus)
   1.412 +	{
   1.413 +	BeginAsyncOp(aStatus, ETrusted);
   1.414 +	TRAPD(err, TrustedL(aCertInfo, aTrusted));
   1.415 +	if (err != KErrNone)
   1.416 +		{
   1.417 +		Complete(err);
   1.418 +		}
   1.419 +	}
   1.420 +
   1.421 +void CUnifiedCertStore::TrustedL(const CCTCertInfo& aCertInfo, 
   1.422 +								 TBool& aTrusted)
   1.423 +	{
   1.424 +	FindCertStoreL(aCertInfo.Handle());
   1.425 +	iCurrentCertStore->Trusted(aCertInfo, aTrusted, iStatus);
   1.426 +	SetActive();
   1.427 +	}
   1.428 +
   1.429 +void CUnifiedCertStore::CancelTrusted()
   1.430 +	{
   1.431 +	if (iState == ETrusted)
   1.432 +		{
   1.433 +		Cancel();
   1.434 +		}
   1.435 +	}
   1.436 +
   1.437 +void CUnifiedCertStore::Retrieve(const CCTCertInfo& aCertInfo,
   1.438 +								 TDes8& aEncodedCert,
   1.439 +								 TRequestStatus& aStatus)
   1.440 +	{
   1.441 +	BeginAsyncOp(aStatus, ERetrieveData);
   1.442 +	TRAPD(err, RetrieveDataL(aCertInfo, aEncodedCert));
   1.443 +	if (err != KErrNone)
   1.444 +		{
   1.445 +		Complete(err);
   1.446 +		}
   1.447 +	}
   1.448 +
   1.449 +void CUnifiedCertStore::RetrieveDataL(const CCTCertInfo& aCertInfo,
   1.450 +									  TDes8& aEncodedCert)
   1.451 +	{
   1.452 +	FindCertStoreL(aCertInfo.Handle());
   1.453 +	iCurrentCertStore->Retrieve(aCertInfo, aEncodedCert, iStatus);	
   1.454 +	SetActive();
   1.455 +	}
   1.456 +
   1.457 +void CUnifiedCertStore::CancelRetrieve()
   1.458 +	{
   1.459 +	if (iState == ERetrieveData)
   1.460 +		{
   1.461 +		Cancel();
   1.462 +		}
   1.463 +	}
   1.464 +
   1.465 +EXPORT_C void CUnifiedCertStore::Remove(const CCTCertInfo& aCertInfo,
   1.466 +										TRequestStatus& aStatus)
   1.467 +	{
   1.468 +	BeginAsyncOp(aStatus, ERemove);
   1.469 +	TRAPD(err, RemoveL(aCertInfo));
   1.470 +	if (err != KErrNone)
   1.471 +		{
   1.472 +		Complete(err);
   1.473 +		}
   1.474 +	}
   1.475 +
   1.476 +void CUnifiedCertStore::RemoveL(const CCTCertInfo& aCertInfo)
   1.477 +	{
   1.478 +	FindWritableCertStoreL(aCertInfo.Handle());
   1.479 +	iCurrentWritableCertStore->Remove(aCertInfo, iStatus);	
   1.480 +	SetActive();
   1.481 +	}
   1.482 +
   1.483 +EXPORT_C void CUnifiedCertStore::CancelRemove()
   1.484 +	{
   1.485 +	if (iState == ERemove)
   1.486 +		{
   1.487 +		Cancel();
   1.488 +		}
   1.489 +	}
   1.490 +
   1.491 +EXPORT_C void CUnifiedCertStore::SetApplicability(const CCTCertInfo& aCertInfo, 
   1.492 +												  const RArray<TUid>& aApplications,
   1.493 +												  TRequestStatus& aStatus)
   1.494 +	{
   1.495 +	BeginAsyncOp(aStatus, ESetApplicability);	
   1.496 +	TRAPD(err, SetApplicabilityL(aCertInfo, aApplications));
   1.497 +	if (err != KErrNone)
   1.498 +		{
   1.499 +		Complete(err);
   1.500 +		}
   1.501 +	}
   1.502 +
   1.503 +void CUnifiedCertStore::SetApplicabilityL(const CCTCertInfo& aCertInfo, 
   1.504 +										  const RArray<TUid>& aApplications)
   1.505 +	{
   1.506 +	FindWritableCertStoreL(aCertInfo.Handle());
   1.507 +	
   1.508 +	// Search for duplicates in the array of application
   1.509 +	// complete with KErrArgument if there are any duplicates
   1.510 +	if(aApplications.Count() > 1)
   1.511 +		{
   1.512 +		TInt i=0, j=1;
   1.513 +
   1.514 +		for(i=0; i<aApplications.Count()-1; i++ )
   1.515 +			{
   1.516 +			for(j=i+1; j<aApplications.Count(); j++)
   1.517 +				{
   1.518 +				if(aApplications[i] == aApplications[j])
   1.519 +					{
   1.520 +					User::Leave(KErrArgument);
   1.521 +					}
   1.522 +				}		  			
   1.523 +			}
   1.524 +		}
   1.525 +
   1.526 +	// Check requested applications actaully exist
   1.527 +	CCertificateAppInfoManager* appInfoManager = CCertificateAppInfoManager::NewLC(iFs, EFalse);
   1.528 +	const RArray<TCertificateAppInfo>& applications = appInfoManager->Applications();
   1.529 +
   1.530 +	for (TInt i = 0 ; i < aApplications.Count() ; ++i)
   1.531 +		{
   1.532 +		TInt j = 0;
   1.533 +		for ( ; j < applications.Count() ; ++j)
   1.534 +			{
   1.535 +			if (aApplications[i] == applications[j].Id())
   1.536 +				{
   1.537 +				break;
   1.538 +				}
   1.539 +			}
   1.540 +		if (j == applications.Count())
   1.541 +			{
   1.542 +			User::Leave(KErrArgument);
   1.543 +			}
   1.544 +		}
   1.545 +	CleanupStack::PopAndDestroy(appInfoManager);
   1.546 +
   1.547 +	iCurrentWritableCertStore->SetApplicability(aCertInfo, aApplications, iStatus);
   1.548 +	SetActive();
   1.549 +	}
   1.550 +
   1.551 +EXPORT_C void CUnifiedCertStore::CancelSetApplicability()
   1.552 +	{
   1.553 +	if (iState == ESetApplicability)
   1.554 +		{
   1.555 +		Cancel();
   1.556 +		}
   1.557 +	}
   1.558 +
   1.559 +EXPORT_C void CUnifiedCertStore::SetTrust(const CCTCertInfo& aCertInfo, 
   1.560 +										  TBool aTrusted,
   1.561 +										  TRequestStatus& aStatus)
   1.562 +	{
   1.563 +	BeginAsyncOp(aStatus, ESetTrust);	
   1.564 +	TRAPD(err, SetTrustL(aCertInfo, aTrusted));
   1.565 +	if (err != KErrNone)
   1.566 +		{
   1.567 +		Complete(err);
   1.568 +		}
   1.569 +	}
   1.570 +
   1.571 +void CUnifiedCertStore::SetTrustL(const CCTCertInfo& aCertInfo, TBool aTrusted)
   1.572 +	{
   1.573 +	FindWritableCertStoreL(aCertInfo.Handle());
   1.574 +	iCurrentWritableCertStore->SetTrust(aCertInfo, aTrusted, iStatus);
   1.575 +	SetActive();
   1.576 +	}
   1.577 +
   1.578 +EXPORT_C void CUnifiedCertStore::CancelSetTrust()
   1.579 +	{
   1.580 +	if (iState == ESetTrust)
   1.581 +		{
   1.582 +		Cancel();
   1.583 +		}
   1.584 +	}
   1.585 +
   1.586 +/**
   1.587 + * Get the certstore containing a given certificate.
   1.588 + * 
   1.589 + * Returns the certstore containing the cert referenced in certinfo or NULL if
   1.590 + * not found.
   1.591 + */
   1.592 +MCTCertStore* CUnifiedCertStore::GetCertStore(const TCTTokenObjectHandle& aHandle)
   1.593 +	{
   1.594 +	TInt count = iCertStores.Count();
   1.595 +	for (TInt i = 0; i < count; i++)
   1.596 +		{
   1.597 +		MCTCertStore* certstore = iCertStores[i];
   1.598 +		MCTToken& token = certstore->Token();
   1.599 +		if (token.Handle() == aHandle.iTokenHandle)
   1.600 +			{
   1.601 +			return certstore;
   1.602 +			}
   1.603 +		}
   1.604 +	return NULL;
   1.605 +	}
   1.606 +
   1.607 +/**
   1.608 + * Set iCurrentCertStore to the certstore containing a given certificate, or
   1.609 + * leave if it could not be found.  The handle is the handle of the *certinfo*,
   1.610 + * *NOT* the token.
   1.611 + */
   1.612 +void CUnifiedCertStore::FindCertStoreL(const TCTTokenObjectHandle& aHandle)
   1.613 +	{
   1.614 +	assert(!iCurrentCertStore);
   1.615 +	assert(!iCurrentWritableCertStore);
   1.616 +		
   1.617 +	if (!iIsInitialized)
   1.618 +		{
   1.619 +		User::Leave(KErrNotReady);
   1.620 +		}
   1.621 +
   1.622 +	iCurrentCertStore = GetCertStore(aHandle);
   1.623 +	
   1.624 +	if (!iCurrentCertStore)
   1.625 +		{
   1.626 +		User::Leave(KErrNotFound);
   1.627 +		}
   1.628 +	}
   1.629 +
   1.630 +/**
   1.631 + * Set iCurrentWritableCertStore to the writable certstore containing a given
   1.632 + * certificate, or leave if it could not be found.  The handle is the handle of
   1.633 + * the *certinfo*, *NOT* the token.
   1.634 + */
   1.635 +void CUnifiedCertStore::FindWritableCertStoreL(const TCTTokenObjectHandle& aHandle)
   1.636 +	{
   1.637 +	assert(!iCurrentCertStore);
   1.638 +	assert(!iCurrentWritableCertStore);
   1.639 +		
   1.640 +	if (!iIsInitialized)
   1.641 +		{
   1.642 +		User::Leave(KErrNotReady);
   1.643 +		}
   1.644 +
   1.645 +	if (!iOpenedForWrite)
   1.646 +		{
   1.647 +		User::Leave(KErrAccessDenied);
   1.648 +		}
   1.649 +
   1.650 +	iCurrentWritableCertStore = NULL;
   1.651 +	TInt count = iWritableCertStores.Count();
   1.652 +	for (TInt i = 0; i < count; i++)
   1.653 +		{
   1.654 +		MCTWritableCertStore* certstore = iWritableCertStores[i];
   1.655 +		MCTToken& token = certstore->Token();
   1.656 +		if (token.Handle() == aHandle.iTokenHandle)
   1.657 +			{
   1.658 +			iCurrentWritableCertStore = certstore;
   1.659 +			break;
   1.660 +			}
   1.661 +		}
   1.662 +
   1.663 +	if (!iCurrentWritableCertStore)
   1.664 +		{
   1.665 +		User::Leave(KErrNotFound);
   1.666 +		}
   1.667 +	}
   1.668 +
   1.669 +EXPORT_C TInt CUnifiedCertStore::CertStoreCount() const
   1.670 +	{
   1.671 +	return iCertStores.Count();
   1.672 +	}
   1.673 +
   1.674 +EXPORT_C MCTCertStore& CUnifiedCertStore::CertStore(TInt aIndex)
   1.675 +	{
   1.676 +	assert(aIndex < iCertStores.Count());
   1.677 +	return *iCertStores[aIndex];
   1.678 +	}
   1.679 +
   1.680 +EXPORT_C TInt CUnifiedCertStore::WritableCertStoreCount() const
   1.681 +	{
   1.682 +	return iWritableCertStores.Count();
   1.683 +	}
   1.684 +
   1.685 +EXPORT_C MCTWritableCertStore& CUnifiedCertStore::WritableCertStore(TInt aIndex)
   1.686 +	{
   1.687 +	assert(aIndex < iWritableCertStores.Count());
   1.688 +	return *iWritableCertStores[aIndex];
   1.689 +	}
   1.690 +
   1.691 +EXPORT_C TInt CUnifiedCertStore::ReadOnlyCertStoreCount() const
   1.692 +	{
   1.693 +	return iReadOnlyCertStores.Count();
   1.694 +	}
   1.695 +
   1.696 +EXPORT_C MCTCertStore& CUnifiedCertStore::ReadOnlyCertStore(TInt aIndex)
   1.697 +	{
   1.698 +	assert(aIndex < iReadOnlyCertStores.Count());
   1.699 +	return *iReadOnlyCertStores[aIndex];
   1.700 +	}
   1.701 +
   1.702 +CUnifiedCertStore::CUnifiedCertStore(RFs& aFs, TBool aOpenForWrite)
   1.703 +	: CActive(EPriorityNormal), iFs(aFs), iOpenedForWrite(aOpenForWrite), iOrderAttributes()
   1.704 +	{
   1.705 +	CActiveScheduler::Add(this);
   1.706 +	assert(IsAdded());
   1.707 +	}
   1.708 +
   1.709 +void CUnifiedCertStore::ConstructL(RArray<TInt>& aOrderFilter)
   1.710 +	{
   1.711 +
   1.712 + 	for (TInt i=0;i<aOrderFilter.Count();i++)
   1.713 + 		{
   1.714 + 		User::LeaveIfError(iOrderAttributes.Append(aOrderFilter[i]));	
   1.715 + 		}
   1.716 +	}
   1.717 +
   1.718 +void CUnifiedCertStore::RunL()
   1.719 +	{
   1.720 +	if ((iState != EInitializeGetReadableInterface) &&
   1.721 +		(iState != EInitializeGetReadableInterfaceFinished) &&
   1.722 +		(iState != EInitializeGetToken)) // We don't want to leave if we're in this state
   1.723 +										 // since we want to enumerate all tokens, see below
   1.724 +		{
   1.725 +		User::LeaveIfError(iStatus.Int());
   1.726 +		}
   1.727 +
   1.728 +	switch (iState)
   1.729 +		{
   1.730 +		case EInitializeGetTokenList:
   1.731 +			// We need to try to get a list of Tokens for each of the Token Types
   1.732 +			iWorkingVars->iIndex++;
   1.733 +			TInt end;
   1.734 +			if (!iCurrentlyDoingReadOnly)
   1.735 +				{
   1.736 +				end = iWorkingVars->iWritableTokenTypes.Count();
   1.737 +				}
   1.738 +			else
   1.739 +				{
   1.740 +				end = iWorkingVars->iReadOnlyTokenTypes.Count();
   1.741 +				}
   1.742 +			if (iWorkingVars->iIndex < end)
   1.743 +				{
   1.744 +				assert(!iTokenType);
   1.745 +				TInt createRes = KErrNone;
   1.746 +				if (iCurrentlyDoingReadOnly)
   1.747 +					{
   1.748 +					TRAP(createRes, iTokenType = MCTTokenType::NewL(*iWorkingVars->iReadOnlyTokenTypes[iWorkingVars->iIndex], iFs));
   1.749 +					}
   1.750 +				else
   1.751 +					{
   1.752 +					TRAP(createRes, iTokenType = MCTTokenType::NewL(*iWorkingVars->iWritableTokenTypes[iWorkingVars->iIndex], iFs));
   1.753 +					}
   1.754 +
   1.755 +				if (KErrNoMemory==createRes)
   1.756 +					{
   1.757 +					// Leave if there's no memory, so OOM tests work
   1.758 +					User::Leave(createRes);
   1.759 +					}
   1.760 +				else if (KErrNone!=createRes)
   1.761 +					{
   1.762 +					//	ECOM couldn't load that token type, don't give up, try the next...
   1.763 +					TRequestStatus* stat = &iStatus;
   1.764 +					User::RequestComplete(stat, KErrNone);
   1.765 +					}
   1.766 +				else
   1.767 +					{
   1.768 +					assert(iTokens.Count() == 0);
   1.769 +					iTokenType->List(iTokens, iStatus);
   1.770 +					iIndexTokens = -1;
   1.771 +					iState = EInitializeGetToken;
   1.772 +					}				   
   1.773 +				}
   1.774 +			else if (!iCurrentlyDoingReadOnly)
   1.775 +				{
   1.776 +				iCurrentlyDoingReadOnly = ETrue;
   1.777 +				iWorkingVars->iIndex = -1;
   1.778 +				TRequestStatus* status = &iStatus;
   1.779 +				User::RequestComplete(status, KErrNone);
   1.780 +				}
   1.781 +			else
   1.782 +				{
   1.783 +				iState = EInitializeFinished;
   1.784 +				TRequestStatus* status = &iStatus;
   1.785 +				User::RequestComplete(status, KErrNone);
   1.786 +				}
   1.787 +			SetActive();
   1.788 +			break;
   1.789 +
   1.790 +		case EInitializeGetToken:
   1.791 +			if (iStatus.Int() == KErrHardwareNotAvailable) 
   1.792 +				{
   1.793 +				// If the hardware corresponding to this
   1.794 +				// TokenType has been removed then just skip it
   1.795 +				// but DO NOT leave!
   1.796 +				++iIndexTokens;
   1.797 +				iState = EInitializeGetToken;
   1.798 +				TRequestStatus* status = &iStatus;
   1.799 +				User::RequestComplete(status,KErrNone);
   1.800 +				}
   1.801 +            else 
   1.802 +				{
   1.803 +				User::LeaveIfError(iStatus.Int());
   1.804 +
   1.805 +				// iIndexTokens is initialized at EInitializeGetTokenList
   1.806 +				++iIndexTokens;
   1.807 +
   1.808 +				//	We need to try to get a certstore interface (readable or
   1.809 +				//	writable) for each of the Tokens in iTokens		
   1.810 +				if (iIndexTokens < iTokens.Count())
   1.811 +					{
   1.812 +                    assert(!iToken);
   1.813 +					iTokenType->OpenToken(*iTokens[iIndexTokens], iToken, iStatus);
   1.814 +					if ((iOpenedForWrite) && !iCurrentlyDoingReadOnly)
   1.815 +						{
   1.816 +						iState = EInitializeGetWritableInterface;
   1.817 +						}
   1.818 +					else
   1.819 +						{
   1.820 +						iState = EInitializeGetReadableInterface;
   1.821 +						}
   1.822 +					}
   1.823 +				else
   1.824 +					{
   1.825 +					// We don't need the iTokenType anymore
   1.826 +					iTokenType->Release();
   1.827 +					iTokenType = 0;
   1.828 +					// We don't need the list of Tokens anymore
   1.829 +					iTokens.Close();
   1.830 +					iState = EInitializeGetTokenList;
   1.831 +					TRequestStatus* status = &iStatus;
   1.832 +					User::RequestComplete(status, KErrNone);
   1.833 +					}
   1.834 +				}
   1.835 +			SetActive();
   1.836 +			break;
   1.837 +
   1.838 +		case EInitializeGetWritableInterface:
   1.839 +			{
   1.840 +			User::LeaveIfError(iStatus.Int());
   1.841 +			// First we try to get a writable interface to the store, if
   1.842 +			// that doesn't work we will try to get a readable interface
   1.843 +            assert(iToken);
   1.844 +            assert(!iTokenInterface);
   1.845 +			TUid uid = { KInterfaceWritableCertStore };
   1.846 +			iToken->GetInterface(uid, iTokenInterface, iStatus);
   1.847 +			iState = EInitializeGetReadableInterface;
   1.848 +			SetActive();
   1.849 +			}
   1.850 +			break;
   1.851 +
   1.852 +		case EInitializeGetReadableInterface:
   1.853 +			// We check if we managed to get a writable interface
   1.854 +			if (iStatus == KErrNoMemory)
   1.855 +				{
   1.856 +				User::Leave(KErrNoMemory);
   1.857 +				}
   1.858 +            
   1.859 +			if (!iCurrentlyDoingReadOnly && iOpenedForWrite && (iStatus == KErrNone))
   1.860 +				{
   1.861 +				assert(iTokenInterface);
   1.862 +
   1.863 +				//	Drop the interface into a "writable checking" object
   1.864 +				CCheckedCertStore* interf = 
   1.865 +					CCheckedCertStore::NewCheckedWritableCertStoreL(iTokenInterface, iPSCertstoreChangeProperty);
   1.866 +
   1.867 +                CleanupReleasePushL(*interf);
   1.868 +				iTokenInterface = 0;
   1.869 +				
   1.870 +				User::LeaveIfError(iWritableCertStores.Append(interf));
   1.871 +				CleanupStack::Pop();
   1.872 +				
   1.873 +				User::LeaveIfError(iCertStores.Append(interf));	
   1.874 +				
   1.875 +				// We don't need the Token anymore
   1.876 +				iToken->Release();
   1.877 +				iToken = 0;
   1.878 +				iState = EInitializeGetToken;
   1.879 +				TRequestStatus* status = &iStatus;
   1.880 +				User::RequestComplete(status, KErrNone);
   1.881 +				}
   1.882 +			else 
   1.883 +				{
   1.884 +				// We do the check only if we were not trying to get a Writeable Interface
   1.885 +				// before, if we trying to get a writeable interface before, we know that we
   1.886 +				// have a valid iToken.
   1.887 +				if ((iCurrentlyDoingReadOnly || !iOpenedForWrite) && (iStatus != KErrNone))
   1.888 +					{
   1.889 +					User::Leave(iStatus.Int());
   1.890 +					}
   1.891 +				else
   1.892 +					{
   1.893 +					assert(iToken);
   1.894 +                    assert(!iTokenInterface);
   1.895 +					TUid uid = { KInterfaceCertStore };
   1.896 +					iToken->GetInterface(uid, iTokenInterface, iStatus);
   1.897 +					iState = EInitializeGetReadableInterfaceFinished;
   1.898 +					}
   1.899 +				}
   1.900 +			SetActive();
   1.901 +			break;
   1.902 +
   1.903 +		case EInitializeGetReadableInterfaceFinished:
   1.904 +			{
   1.905 +			if (iStatus == KErrNoMemory)
   1.906 +				{
   1.907 +				User::Leave(KErrNoMemory);
   1.908 +				}
   1.909 +            
   1.910 +			if (iStatus == KErrNone)
   1.911 +				{
   1.912 +				assert(iTokenInterface);
   1.913 +
   1.914 +				//	Drop the interface into a "read only checking" object
   1.915 +                CCheckedCertStore* interf = 
   1.916 +						CCheckedCertStore::NewCheckedCertStoreL(iTokenInterface, iPSCertstoreChangeProperty);
   1.917 +				
   1.918 +				CleanupReleasePushL(*interf);
   1.919 +				iTokenInterface = 0;
   1.920 +
   1.921 +				User::LeaveIfError(iReadOnlyCertStores.Append(interf));
   1.922 +				CleanupStack::Pop(interf);
   1.923 +                
   1.924 +				User::LeaveIfError(iCertStores.Append(interf));
   1.925 +				}			
   1.926 +				
   1.927 +			// We don't need the Token anymore
   1.928 +			iToken->Release();
   1.929 +			iToken = 0;
   1.930 +			
   1.931 +			iStatus = KErrNone;
   1.932 +			iState = EInitializeGetToken;
   1.933 +			TRequestStatus* status = &iStatus;
   1.934 +			User::RequestComplete(status, iStatus.Int());
   1.935 +			SetActive();
   1.936 +            }
   1.937 +			break;
   1.938 +
   1.939 +		case EInitializeFinished:
   1.940 +            assert(!iTokenType);
   1.941 +            assert(!iToken);
   1.942 +            assert(!iTokenInterface);
   1.943 +			iIsInitialized = ETrue;
   1.944 +			Complete(iStatus.Int());
   1.945 +			break;
   1.946 +
   1.947 +		case EList:
   1.948 +			// iIndex has been initialized in List
   1.949 +			iIndex++;
   1.950 +			iCurrentCertStore = NULL;
   1.951 +			if (iIndex < iCertStores.Count())
   1.952 +				{
   1.953 +				iCurrentCertStore = iCertStores[iIndex];
   1.954 +				iCurrentCertStore->List(*iWorkingVars->iCertInfos, *iWorkingVars->iFilter, iStatus);
   1.955 +				iWorkingVars->iCertIndex = 0;
   1.956 +				SetActive();
   1.957 +				}
   1.958 +			else if (iWorkingVars->iIssuerNames.Count() > 0)
   1.959 +				{
   1.960 +				// We have an issuer name. We now remove all certs
   1.961 +				// that don't match that issuer.
   1.962 +
   1.963 +				// If this is the first time in here, we need to parse
   1.964 +				// and hash all the issuer names.
   1.965 +				if (iWorkingVars->iParsedIssuerNames.Count() == 0)
   1.966 +					{
   1.967 +					CSHA1* sha1 = CSHA1::NewL();
   1.968 +					CleanupStack::PushL(sha1);
   1.969 +					TInt count = iWorkingVars->iIssuerNames.Count();
   1.970 +					for (TInt i = 0; i < count; i++)
   1.971 +						{
   1.972 +						CX500DistinguishedName* dn = 
   1.973 +							CX500DistinguishedName::NewLC(*iWorkingVars->
   1.974 +														  iIssuerNames[i]);
   1.975 +						User::LeaveIfError(
   1.976 +							iWorkingVars->iParsedIssuerNames.Append(dn));
   1.977 +						CleanupStack::Pop(dn);
   1.978 +						TPtrC8 hash=sha1->Hash(*iWorkingVars->iIssuerNames[i]);
   1.979 +						User::LeaveIfError(
   1.980 +							iWorkingVars->iHashedIssuerNames.Append(
   1.981 +								hash.AllocLC()));
   1.982 +						CleanupStack::Pop();
   1.983 +						}
   1.984 +					CleanupStack::PopAndDestroy();
   1.985 +					}
   1.986 +
   1.987 +				while (iWorkingVars->iCertIndex <
   1.988 +					   iWorkingVars->iCertInfos->Count())
   1.989 +					{
   1.990 +					CCTCertInfo* info = 
   1.991 +						(*iWorkingVars->iCertInfos)[iWorkingVars->iCertIndex];
   1.992 +					TCompareResults res = CompareCertInfoDN(info);
   1.993 +					if (res == EYes)
   1.994 +						{
   1.995 +						// It matches. leave it for the next one.
   1.996 +						iWorkingVars->iCertIndex++;
   1.997 +						}
   1.998 +					else if (res == ENo)
   1.999 +						{
  1.1000 +						// It doesn't match. Remove it and try the next one.
  1.1001 +						info->Release();
  1.1002 +						iWorkingVars->iCertInfos->
  1.1003 +							Remove(iWorkingVars->iCertIndex);
  1.1004 +						}
  1.1005 +					else // res == EMaybe
  1.1006 +						{
  1.1007 +						// Need to load the cert and properly compare the DNs.
  1.1008 +						iCurrentCertStore = GetCertStore(info->Handle());
  1.1009 +						assert(iCurrentCertStore);
  1.1010 +						
  1.1011 +						iWorkingVars->iCertDesC=HBufC8::NewMaxL(info->Size());
  1.1012 +						iWorkingVars->iCertType = info->CertificateFormat();
  1.1013 +						iState = ERetrieveForList;
  1.1014 +						iWorkingVars->iCertDes.Set(iWorkingVars->iCertDesC->Des());
  1.1015 +						iCurrentCertStore->Retrieve(*info, iWorkingVars->iCertDes, iStatus);
  1.1016 +						SetActive();
  1.1017 +						return;
  1.1018 +						}
  1.1019 +					}
  1.1020 +				Complete(KErrNone);
  1.1021 +				}
  1.1022 +			else
  1.1023 +				{
  1.1024 +				Complete(KErrNone);
  1.1025 +				}
  1.1026 +			break;
  1.1027 +
  1.1028 +	case ERetrieve:
  1.1029 +		{
  1.1030 +		switch (iWorkingVars->iCertType)
  1.1031 +			{
  1.1032 +            case EX509Certificate:
  1.1033 +                {
  1.1034 +                TPtr8 theCert(iWorkingVars->iCertDesC->Des());
  1.1035 +                *(iWorkingVars->iReturnedCert) = CX509Certificate::NewL(theCert);
  1.1036 +                }
  1.1037 +                break;
  1.1038 +            case EWTLSCertificate:
  1.1039 +                {
  1.1040 +                TPtr8 theCert(iWorkingVars->iCertDesC->Des());
  1.1041 +                *(iWorkingVars->iReturnedCert) = CWTLSCertificate::NewL(theCert);			
  1.1042 +                }
  1.1043 +                break;
  1.1044 +            default:
  1.1045 +                assert(EFalse);
  1.1046 +                break;
  1.1047 +			}
  1.1048 +		Complete(KErrNone);
  1.1049 +		}
  1.1050 +		break;
  1.1051 +
  1.1052 +	case ERetrieveForList:
  1.1053 +		{
  1.1054 +		TPtr8 theCert(iWorkingVars->iCertDesC->Des());
  1.1055 +		CX509Certificate* cert=CX509Certificate::NewLC(theCert);
  1.1056 +		if (MatchL(cert->IssuerName()))
  1.1057 +			{
  1.1058 +			// It matches. leave it for the next one.
  1.1059 +			iWorkingVars->iCertIndex++;
  1.1060 +			}
  1.1061 +		else
  1.1062 +			{
  1.1063 +			// It doesn't match. Remove it and try the next one.
  1.1064 +			(*iWorkingVars->iCertInfos)[iWorkingVars->iCertIndex]->Release();
  1.1065 +			iWorkingVars->iCertInfos->Remove(iWorkingVars->iCertIndex);
  1.1066 +			}
  1.1067 +		CleanupStack::PopAndDestroy(cert);
  1.1068 +		delete iWorkingVars->iCertDesC;
  1.1069 +		iWorkingVars->iCertDesC = 0;
  1.1070 +		iState = EList;
  1.1071 +		SetActive();
  1.1072 +		TRequestStatus* status = & iStatus;
  1.1073 +		User::RequestComplete(status, KErrNone);
  1.1074 +		break;
  1.1075 +		}
  1.1076 +		
  1.1077 + 	case ERemove:
  1.1078 + 	case ESetApplicability:
  1.1079 + 	case ESetTrust:
  1.1080 +	case EGetCert:
  1.1081 +	case EApplications:
  1.1082 +	case EIsApplicable:
  1.1083 +	case ETrusted:
  1.1084 +	case ERetrieveData:
  1.1085 +		Complete(KErrNone);
  1.1086 +		break;
  1.1087 +
  1.1088 +	default:
  1.1089 +        User::Panic(KUCSPanic, 1);
  1.1090 +		break;
  1.1091 +		}
  1.1092 +	}
  1.1093 +
  1.1094 +TInt CUnifiedCertStore::RunError(TInt aError)
  1.1095 +	{
  1.1096 +	Complete(aError);
  1.1097 +	return KErrNone;
  1.1098 +	}
  1.1099 +
  1.1100 +void CUnifiedCertStore::DoCancel()
  1.1101 +	{
  1.1102 +	// If the current state is the last state involved in handling a request, we
  1.1103 +	// check to see if we have already been completed - in this case we can
  1.1104 +	// simply complete the client with iStatus (this may be KErrNone).  If we
  1.1105 +	// have not we cancel the outstanding request and pass the resulting iStatus
  1.1106 +	// back to the client - this too may indicate a successful completion if the
  1.1107 +	// cancel arrived after the request was executed.
  1.1108 +	//
  1.1109 +	// For more complex cases, where there are more states to go through before
  1.1110 +	// we finish servicing the client request, we cancel any outstanding
  1.1111 +	// request, and return KErrCancel to the client.
  1.1112 +
  1.1113 +	switch (iState)
  1.1114 +		{
  1.1115 +		case EInitializeFinished:
  1.1116 +		case ERetrieve:
  1.1117 +		case EGetCert:
  1.1118 +		case EApplications:
  1.1119 +		case EIsApplicable:
  1.1120 +		case ETrusted:
  1.1121 +		case ERetrieveData:
  1.1122 +		case ERemove:
  1.1123 +		case ESetApplicability:
  1.1124 +		case ESetTrust:		
  1.1125 +			if (iStatus == KRequestPending)
  1.1126 +				{
  1.1127 +				// Attempt to cancel outstanding request and pass status back to
  1.1128 +				// client
  1.1129 +				CancelOutstandingRequest();
  1.1130 +				Complete(iStatus.Int());
  1.1131 +				}
  1.1132 +			else
  1.1133 +				{
  1.1134 +				// We've already been completed - call RunL() to process results
  1.1135 +				// and complete client
  1.1136 +				TRAPD(err, RunL());
  1.1137 +				if (err != KErrNone)
  1.1138 +					{
  1.1139 +					RunError(err);
  1.1140 +					}
  1.1141 +				}
  1.1142 +			break;
  1.1143 +			
  1.1144 +		default:
  1.1145 +			CancelOutstandingRequest();
  1.1146 +			Complete(KErrCancel);
  1.1147 +			break;
  1.1148 +		}
  1.1149 +	}
  1.1150 +
  1.1151 +void CUnifiedCertStore::CancelOutstandingRequest()
  1.1152 +	{
  1.1153 +	switch (iState)
  1.1154 +		{
  1.1155 +		case EInitializeGetTokenList:
  1.1156 +		case EInitializeGetToken:
  1.1157 +		case EInitializeGetWritableInterface:
  1.1158 +		case EInitializeGetReadableInterface:
  1.1159 +		case EInitializeGetReadableInterfaceFinished:
  1.1160 +		case EInitializeFinished:
  1.1161 +			// Don't have to cancel initialisation stuff - this happens when we
  1.1162 +			// release the objects in DestroyTemporaryMembers().
  1.1163 +			iStatus = KErrCancel;
  1.1164 +			break;
  1.1165 +
  1.1166 +		case EList:
  1.1167 +			if (iCurrentCertStore)
  1.1168 +				{
  1.1169 +				iCurrentCertStore->CancelList();
  1.1170 +				}
  1.1171 +			break;
  1.1172 +			
  1.1173 +		case ERetrieve:
  1.1174 +		case ERetrieveForList:
  1.1175 +		case ERetrieveData:
  1.1176 +			assert(iCurrentCertStore);
  1.1177 +			iCurrentCertStore->CancelRetrieve();
  1.1178 +			break;
  1.1179 +			
  1.1180 +		case EGetCert:
  1.1181 +			assert(iCurrentCertStore);
  1.1182 +			iCurrentCertStore->CancelGetCert();
  1.1183 +			break;
  1.1184 +			
  1.1185 +		case EApplications:
  1.1186 +			assert(iCurrentCertStore);
  1.1187 +			iCurrentCertStore->CancelApplications();
  1.1188 +			break;
  1.1189 +			
  1.1190 +		case EIsApplicable:
  1.1191 +			assert(iCurrentCertStore);
  1.1192 +			iCurrentCertStore->CancelIsApplicable();
  1.1193 +			break;
  1.1194 +			
  1.1195 +		case ETrusted:
  1.1196 +			assert(iCurrentCertStore);
  1.1197 +			iCurrentCertStore->CancelTrusted();
  1.1198 +			break;
  1.1199 +			
  1.1200 +		case ERemove:
  1.1201 +			assert(iCurrentWritableCertStore);
  1.1202 +			iCurrentWritableCertStore->CancelRemove();
  1.1203 +			break;
  1.1204 +			
  1.1205 +		case ESetApplicability:
  1.1206 +			assert(iCurrentWritableCertStore);
  1.1207 +			iCurrentWritableCertStore->CancelSetApplicability();
  1.1208 +			break;
  1.1209 +			
  1.1210 +		case ESetTrust:
  1.1211 +			assert(iCurrentWritableCertStore);
  1.1212 +			iCurrentWritableCertStore->CancelSetTrust();
  1.1213 +			break;
  1.1214 +			
  1.1215 +		default:
  1.1216 +			User::Panic(KUCSPanic, 1);
  1.1217 +			break;
  1.1218 +		}
  1.1219 +	}
  1.1220 +
  1.1221 +TBool CUnifiedCertStore::MatchL(const CX500DistinguishedName& aName) const
  1.1222 +	{
  1.1223 +	// Return true if the supplied DN is the same as any of the supplied DNs.
  1.1224 +	TInt count = iWorkingVars->iIssuerNames.Count();
  1.1225 +	for (TInt i = 0; i < count; i++)
  1.1226 +		{
  1.1227 +		if (aName.ExactMatchL(*iWorkingVars->iParsedIssuerNames[i]))
  1.1228 +			return ETrue;
  1.1229 +		}
  1.1230 +	return EFalse;
  1.1231 +	}
  1.1232 +
  1.1233 +void CUnifiedCertStore::AllocWorkingVarsL()
  1.1234 +	{
  1.1235 +	assert(!iWorkingVars);
  1.1236 +	iWorkingVars = new (ELeave) CUnifiedCertStoreWorkingVars;
  1.1237 +	}
  1.1238 +
  1.1239 +void CUnifiedCertStore::BeginAsyncOp(TRequestStatus& aStatus, TState aState)
  1.1240 +	{
  1.1241 +	assert(iState == EIdle);
  1.1242 +	assert(!iClientStatus);
  1.1243 +	
  1.1244 +	iClientStatus = &aStatus;
  1.1245 +	*iClientStatus = KRequestPending;
  1.1246 +	iState = aState;
  1.1247 +	}
  1.1248 +
  1.1249 +void CUnifiedCertStore::Complete(TInt aError)
  1.1250 +	{
  1.1251 +	assert(iClientStatus);
  1.1252 +	User::RequestComplete(iClientStatus, aError);	
  1.1253 +	DestroyTemporaryMembers();
  1.1254 +	iState = EIdle;
  1.1255 +	}
  1.1256 +
  1.1257 +void CUnifiedCertStore::DestroyTemporaryMembers()
  1.1258 +	{
  1.1259 +	if (!iIsInitialized)
  1.1260 +		{
  1.1261 +		TInt end = iReadOnlyCertStores.Count();
  1.1262 +		TInt i;
  1.1263 +		for (i = 0; i < end; i++)
  1.1264 +			{
  1.1265 +			iReadOnlyCertStores[i]->Release();
  1.1266 +			}
  1.1267 +		iReadOnlyCertStores.Close();
  1.1268 +
  1.1269 +		end = iWritableCertStores.Count();
  1.1270 +		for (i = 0; i < end; i++)
  1.1271 +			{
  1.1272 +			iWritableCertStores[i]->Release();
  1.1273 +			}
  1.1274 +		iWritableCertStores.Close();
  1.1275 +
  1.1276 +		// The elements are already released by the two loops above
  1.1277 +		iCertStores.Close();
  1.1278 +		}
  1.1279 +
  1.1280 +    if (iTokenType)
  1.1281 +		{
  1.1282 +		iTokenType->Release();
  1.1283 +		iTokenType = 0;
  1.1284 +		}
  1.1285 +
  1.1286 +	if (iToken)
  1.1287 +		{
  1.1288 +		iToken->Release();
  1.1289 +		iToken = 0;
  1.1290 +		}
  1.1291 +
  1.1292 +	if (iTokenInterface)
  1.1293 +		{
  1.1294 +		iTokenInterface->Release();
  1.1295 +		iTokenInterface = 0;
  1.1296 +		}
  1.1297 +
  1.1298 +	iTokens.Close();
  1.1299 +
  1.1300 +	delete iWorkingVars;
  1.1301 +	iWorkingVars = 0;
  1.1302 +
  1.1303 +	iCurrentCertStore = NULL;
  1.1304 +	iCurrentWritableCertStore = NULL;
  1.1305 +	}
  1.1306 +
  1.1307 +CUnifiedCertStore::TCompareResults 
  1.1308 +CUnifiedCertStore::CompareCertInfoDN(const CCTCertInfo* aCertInfo)
  1.1309 +	{
  1.1310 +	if (aCertInfo->IssuerHash() && 
  1.1311 +		(aCertInfo->CertificateFormat() == EX509CertificateUrl ||
  1.1312 +			iHardwareTypeUids.Find(aCertInfo->Token().TokenType().Type()) != 
  1.1313 +		 KErrNotFound))
  1.1314 +		{
  1.1315 +		TInt count = iWorkingVars->iHashedIssuerNames.Count();
  1.1316 +		for (TInt i = 0; i < count; i++)
  1.1317 +			{
  1.1318 +			if (*aCertInfo->IssuerHash()==*iWorkingVars->iHashedIssuerNames[i])
  1.1319 +				return EYes;
  1.1320 +			}
  1.1321 +		return ENo;
  1.1322 +		}
  1.1323 +	if (aCertInfo->CertificateFormat() != EX509Certificate)
  1.1324 +		return ENo;
  1.1325 +	return EMaybe;
  1.1326 +	}
  1.1327 +
  1.1328 +EXPORT_C CUnifiedCertStore* CUnifiedCertStore::NewL(RFs& aFs, 
  1.1329 +                                                     TBool aOpenForWrite,
  1.1330 +                                                     RArray<TInt>& aOrderFilter)
  1.1331 + 	{
  1.1332 + 	CUnifiedCertStore* self = CUnifiedCertStore::NewLC(aFs, 
  1.1333 + 	                                                   aOpenForWrite, 
  1.1334 + 	                                                   aOrderFilter);
  1.1335 + 	CleanupStack::Pop(self);
  1.1336 + 	return self;
  1.1337 + 	}
  1.1338 +
  1.1339 +EXPORT_C CUnifiedCertStore* CUnifiedCertStore::NewLC(RFs& aFs, 
  1.1340 +                                                      TBool aOpenForWrite,
  1.1341 +                                                      RArray<TInt>& aOrderFilter)
  1.1342 + 	{
  1.1343 + 	CUnifiedCertStore* self = new(ELeave) CUnifiedCertStore(aFs, 
  1.1344 + 	                                                        aOpenForWrite);
  1.1345 + 	CleanupStack::PushL(self);
  1.1346 + 	self->ConstructL(aOrderFilter);
  1.1347 + 	return self;
  1.1348 + 	}
  1.1349 +
  1.1350 +void CUnifiedCertStore::FilterTokenTypesL(RCPointerArray<CCTTokenTypeInfo>& aSearchTokenTypes,
  1.1351 +                                         RCPointerArray<CCTTokenTypeInfo>& aTempTokenTypes,
  1.1352 +										 TInt aOrderAttribute)
  1.1353 +	{
  1.1354 +	//We allow aOrderAttribute=KUnknownHardwareCertStore here to keep DC.
  1.1355 +	//assert(aOrderAttribute);
  1.1356 +	
  1.1357 +	// Get number of token types
  1.1358 +	TInt tokenTypesCount = aSearchTokenTypes.Count(); 
  1.1359 +	
  1.1360 +	// loop through token types
  1.1361 +	for(TInt tokenTypesLoop = tokenTypesCount-1; tokenTypesLoop >= 0; tokenTypesLoop--)
  1.1362 +		{
  1.1363 +		// get the list of attributes supported by this token type.
  1.1364 +		// Note: The attribute list consists of values such as
  1.1365 +		// KCTSoftware defined in TCTTokenTypeAttribute.h
  1.1366 +		const RArray<TCTTokenTypeAttribute>& attributesList = 
  1.1367 +			aSearchTokenTypes[tokenTypesLoop]->Attributes();
  1.1368 +		
  1.1369 +		// Get the number of attributes in the attribute list.
  1.1370 +		// The number of attributes will match the ECOM resource
  1.1371 +		// file definition. E.g. see 101f5015.rss for the software
  1.1372 +		// implementation of certstore. 
  1.1373 +		TInt attributeCount = attributesList.Count();
  1.1374 +		
  1.1375 +		// Check each attribute in the attribute list
  1.1376 +		for(TInt attribLoop = 0; attribLoop < attributeCount; attribLoop++)
  1.1377 +			{
  1.1378 +			// Check whether attribute in the list matches an order attribute
  1.1379 +			// E.g. KCTSoftware
  1.1380 +			if(attributesList[attribLoop].iUID == KCTSoftware
  1.1381 +				&& attributesList[attribLoop].iVal == aOrderAttribute)
  1.1382 +				{
  1.1383 +				// Found the attribute of interest. Add token type to the temp container. 
  1.1384 +				User::LeaveIfError(aTempTokenTypes.Append(aSearchTokenTypes[tokenTypesLoop]));
  1.1385 +				// Remove from the Searchlist.
  1.1386 +				aSearchTokenTypes.Remove(tokenTypesLoop);
  1.1387 +				// No need to examine the other attributes, so break loop
  1.1388 +				break;
  1.1389 +				}
  1.1390 +			}
  1.1391 +		}                      
  1.1392 +	}
  1.1393 + 	
  1.1394 +void CUnifiedCertStore::ApplyOrderingL(RCPointerArray<CCTTokenTypeInfo>& aTokenTypes)
  1.1395 +	{
  1.1396 +	// Number of attributes in ordering filter
  1.1397 +	TInt numOrderAttributes=iOrderAttributes.Count();
  1.1398 +	assert(numOrderAttributes>0);
  1.1399 +	
  1.1400 +	// Contains writable tokens types
  1.1401 +	RCPointerArray<CCTTokenTypeInfo> tempWritableTokenTypes;
  1.1402 +	CleanupClosePushL(tempWritableTokenTypes);
  1.1403 +	
  1.1404 +	// Contains read-only tokens types
  1.1405 +	RCPointerArray<CCTTokenTypeInfo> tempReadOnlyTokenTypes;
  1.1406 +	CleanupClosePushL(tempReadOnlyTokenTypes);
  1.1407 +		
  1.1408 +	// For each order attribute, order the token types
  1.1409 +	for(TInt attributeLoop = 0; attributeLoop < numOrderAttributes; attributeLoop++)
  1.1410 +		{
  1.1411 +		// Get ordering attribute Uid from Order filter
  1.1412 +		TInt orderAttribute = iOrderAttributes[attributeLoop];
  1.1413 +		
  1.1414 +		// Order for writable token types
  1.1415 +		FilterTokenTypesL(iWorkingVars->iWritableTokenTypes,
  1.1416 +			tempWritableTokenTypes,
  1.1417 +			orderAttribute);
  1.1418 +		
  1.1419 +		// Order for read-only token types
  1.1420 +		FilterTokenTypesL(aTokenTypes,
  1.1421 +			tempReadOnlyTokenTypes,
  1.1422 +			orderAttribute);
  1.1423 +		}
  1.1424 +		
  1.1425 +	// release and close the resources so can refill container, and get rid of 
  1.1426 +	// the TokenType which have been filtered out.
  1.1427 +	TInt tokenTypesCount = iWorkingVars->iWritableTokenTypes.Count();
  1.1428 +	TInt i;	
  1.1429 +	for(i = tokenTypesCount-1; i >= 0 ;i--)
  1.1430 +		{
  1.1431 +		if (iWorkingVars->iWritableTokenTypes[i])
  1.1432 +			{
  1.1433 +			CCTTokenTypeInfo* ptr=iWorkingVars->iWritableTokenTypes[i];
  1.1434 +			iWorkingVars->iWritableTokenTypes.Remove(i);
  1.1435 +			delete ptr;			
  1.1436 +			}
  1.1437 +		}
  1.1438 +	iWorkingVars->iWritableTokenTypes.Reset();
  1.1439 +	
  1.1440 +	// release and close the resources so can refill container, and get rid of 
  1.1441 +	// the TokenType which have been filtered out.
  1.1442 +	tokenTypesCount = aTokenTypes.Count();
  1.1443 +	for(i = tokenTypesCount-1; i >= 0 ;i--)
  1.1444 +		{
  1.1445 +		if (aTokenTypes[i])
  1.1446 +			{
  1.1447 +			CCTTokenTypeInfo* ptr=aTokenTypes[i];
  1.1448 +			aTokenTypes.Remove(i);
  1.1449 +			delete ptr;			
  1.1450 +			}
  1.1451 +		}
  1.1452 +	aTokenTypes.Reset();
  1.1453 +	
  1.1454 +	// Assign contents of temp token types to containers. 
  1.1455 +	// Note: temp tokens types are ordered according to user specification
  1.1456 +	tokenTypesCount = tempWritableTokenTypes.Count();
  1.1457 +	for(i = 0; i < tokenTypesCount; i++)
  1.1458 +		{
  1.1459 +		User::LeaveIfError(iWorkingVars->iWritableTokenTypes.Append(tempWritableTokenTypes[i]));
  1.1460 +		tempWritableTokenTypes[i] = NULL; 
  1.1461 +		}
  1.1462 +		
  1.1463 +	tokenTypesCount = tempReadOnlyTokenTypes.Count();
  1.1464 +	for(i = 0; i < tokenTypesCount; i++)
  1.1465 +		{
  1.1466 +		User::LeaveIfError(aTokenTypes.Append(tempReadOnlyTokenTypes[i]));
  1.1467 +		tempReadOnlyTokenTypes[i] = NULL;
  1.1468 +		}
  1.1469 +	
  1.1470 +	CleanupStack::PopAndDestroy(2);	// tempReadOnlyTokenTypes, tempWritableTokenTypes, 
  1.1471 +	}
  1.1472 +