os/security/cryptoservices/certificateandkeymgmt/certstore/CCheckedCertStore.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/security/cryptoservices/certificateandkeymgmt/certstore/CCheckedCertStore.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,786 @@
     1.4 +/*
     1.5 +* Copyright (c) 2002-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 "CCheckedCertStore.h"
    1.23 +
    1.24 +#include <signed.h>
    1.25 +#include <x509cert.h>
    1.26 +#include <x509certext.h>
    1.27 +#include <wtlscert.h>
    1.28 +#include <x509keys.h>
    1.29 +#include <securityerr.h>
    1.30 +
    1.31 +#include "certificateapps.h"
    1.32 +
    1.33 +_LIT(KPanicCategory, "CCheckedCertStore");
    1.34 +#define assert(x) __ASSERT_ALWAYS((x), User::Panic(KPanicCategory, 1));
    1.35 +
    1.36 +/////////////////////////////////////////////////////////////////////
    1.37 +//	CCheckedCertStore
    1.38 +/////////////////////////////////////////////////////////////////////
    1.39 +
    1.40 +CCheckedCertStore::~CCheckedCertStore()
    1.41 +    {
    1.42 +    Cancel();
    1.43 +    Cleanup();
    1.44 +    
    1.45 +	// Release the cert store - no need to release the token since this would
    1.46 +	// have been done as part of MCTTokenInterface::Release()
    1.47 +    iCertStore.Release();
    1.48 +
    1.49 +	iFs.Close();
    1.50 +    }
    1.51 +
    1.52 +CCheckedCertStore::CCheckedCertStore(MCTCertStore& aTokenIF, RProperty& aProperty)
    1.53 +:	CActive(EPriorityStandard), 
    1.54 +	iCertStore(aTokenIF),
    1.55 +	iPSCertstoreChangePropertyRef(aProperty)	
    1.56 +    {
    1.57 +	// need to add reference since we now have the token
    1.58 +	iCertStore.Token().AddRef();
    1.59 +    }
    1.60 +
    1.61 +CCheckedCertStore::CCheckedCertStore(MCTWritableCertStore& aTokenIF, RProperty& aProperty)
    1.62 +:	CActive(EPriorityStandard),
    1.63 +	iCertStore(aTokenIF),
    1.64 +	iWritableCertStore(&aTokenIF),
    1.65 +	iPSCertstoreChangePropertyRef(aProperty)
    1.66 +    {
    1.67 +	// need to add reference since we now have the token
    1.68 +	iCertStore.Token().AddRef();
    1.69 +    }
    1.70 +
    1.71 +/*static*/ CCheckedCertStore* CCheckedCertStore::NewCheckedCertStoreL(MCTTokenInterface* aTokenIF, RProperty& aProperty)
    1.72 +    {
    1.73 +    assert(aTokenIF);
    1.74 +	MCTCertStore& tokenInterface = static_cast<MCTCertStore&>(*aTokenIF);
    1.75 +	CCheckedCertStore* me = new (ELeave) CCheckedCertStore(tokenInterface, aProperty);
    1.76 +    CleanupReleasePushL(*me);
    1.77 +    me->ConstructL();
    1.78 +    CleanupStack::Pop();
    1.79 +	return (me);
    1.80 +    }
    1.81 +	
    1.82 +/*static*/ CCheckedCertStore* CCheckedCertStore::NewCheckedWritableCertStoreL(MCTTokenInterface* aTokenIF, RProperty& aProperty)
    1.83 +    {
    1.84 +    assert(aTokenIF);
    1.85 +	MCTWritableCertStore& tokenInterface = static_cast<MCTWritableCertStore&>(*aTokenIF);
    1.86 +	CCheckedCertStore* me = new (ELeave) CCheckedCertStore(tokenInterface, aProperty);
    1.87 +    CleanupReleasePushL(*me);
    1.88 +    me->ConstructL();
    1.89 +    CleanupStack::Pop();
    1.90 +	return (me);
    1.91 +    }
    1.92 +
    1.93 +void CCheckedCertStore::ConstructL()
    1.94 +    {
    1.95 +	User::LeaveIfError(iFs.Connect());	
    1.96 +	CActiveScheduler::Add(this);
    1.97 +    }
    1.98 +
    1.99 +MCTToken& CCheckedCertStore::Token()
   1.100 +    {
   1.101 +	return iCertStore.Token();
   1.102 +    }
   1.103 +
   1.104 +//	May require checking against the keystore *after* calling the server to complete
   1.105 +//	the List request
   1.106 +void CCheckedCertStore::List(RMPointerArray<CCTCertInfo>& aCerts, const CCertAttributeFilter& aFilter,
   1.107 +                             TRequestStatus& aStatus)
   1.108 +    {
   1.109 +    assert(iState == EIdleState);
   1.110 +
   1.111 +    // Only allow filtering on key usage for user certs
   1.112 +    if (aFilter.iKeyUsage != EX509UsageAll &&
   1.113 +        (!aFilter.iOwnerTypeIsSet || EUserCertificate != aFilter.iOwnerType))
   1.114 +        {
   1.115 +        TRequestStatus* status = &aStatus;
   1.116 +        User::RequestComplete(status, KErrNotSupported);
   1.117 +        return;
   1.118 +        }
   1.119 +
   1.120 +    // Store caller parameters for later reference
   1.121 +    iCallerCerts = &aCerts;
   1.122 +    iCallerFilter = &aFilter;
   1.123 +    aStatus = KRequestPending;
   1.124 +    iCallerStatus = &aStatus;
   1.125 +
   1.126 +    iState = EList;
   1.127 +    iCertStore.List(aCerts, aFilter, iStatus);
   1.128 +    SetActive();
   1.129 +    }
   1.130 +
   1.131 +void CCheckedCertStore::CancelList()
   1.132 +    {
   1.133 +    if (iState == EList ||
   1.134 +        iState == EInitKeyStoreForList ||
   1.135 +        iState == EGetKeyInfosForList)
   1.136 +        {
   1.137 +        Cancel();
   1.138 +        }
   1.139 +    }
   1.140 +
   1.141 +void CCheckedCertStore::GetCert(CCTCertInfo*& aCertInfo, const TCTTokenObjectHandle& aHandle, 
   1.142 +                                TRequestStatus& aStatus)
   1.143 +    {
   1.144 +    assert(iState == EIdleState);
   1.145 +    iCertStore.GetCert(aCertInfo, aHandle, aStatus);
   1.146 +    }
   1.147 +
   1.148 +void CCheckedCertStore::CancelGetCert()
   1.149 +    {
   1.150 +    iCertStore.CancelGetCert();
   1.151 +    }
   1.152 +
   1.153 +void CCheckedCertStore::Applications(const CCTCertInfo& aCertInfo, RArray<TUid>& aApplications,
   1.154 +									 TRequestStatus& aStatus)
   1.155 +    {
   1.156 +    assert(iState == EIdleState);
   1.157 +    iCertStore.Applications(aCertInfo, aApplications, aStatus);
   1.158 +    }
   1.159 +
   1.160 +void CCheckedCertStore::CancelApplications()
   1.161 +    {
   1.162 +    iCertStore.CancelApplications();
   1.163 +    }
   1.164 +
   1.165 +void CCheckedCertStore::IsApplicable(const CCTCertInfo& aCertInfo, TUid aApplication, 
   1.166 +                                     TBool& aIsApplicable, TRequestStatus& aStatus)
   1.167 +    {
   1.168 +    assert(iState == EIdleState);
   1.169 +    iCertStore.IsApplicable(aCertInfo, aApplication, aIsApplicable, aStatus);
   1.170 +    }
   1.171 +
   1.172 +void CCheckedCertStore::CancelIsApplicable()
   1.173 +    {
   1.174 +    iCertStore.CancelIsApplicable();
   1.175 +    }
   1.176 +
   1.177 +void CCheckedCertStore::Trusted(const CCTCertInfo& aCertInfo, TBool& aTrusted, 
   1.178 +                                TRequestStatus& aStatus)
   1.179 +    {
   1.180 +    assert(iState == EIdleState);
   1.181 +    iCertStore.Trusted(aCertInfo, aTrusted, aStatus);
   1.182 +    }
   1.183 +
   1.184 +void CCheckedCertStore::CancelTrusted()
   1.185 +    {
   1.186 +    iCertStore.CancelTrusted();
   1.187 +    }
   1.188 +
   1.189 +void CCheckedCertStore::Retrieve(const CCTCertInfo& aCertInfo, TDes8& aEncodedCert, 
   1.190 +                                 TRequestStatus& aStatus)
   1.191 +    {
   1.192 +    assert(iState == EIdleState);
   1.193 +    iCertStore.Retrieve(aCertInfo, aEncodedCert, aStatus);
   1.194 +    }
   1.195 +
   1.196 +void CCheckedCertStore::CancelRetrieve()
   1.197 +    {
   1.198 +    iCertStore.CancelRetrieve();
   1.199 +    }
   1.200 +
   1.201 +
   1.202 +void CCheckedCertStore::Add(const TDesC& aLabel, 
   1.203 +							TCertificateFormat aFormat,
   1.204 +                            TCertificateOwnerType aCertificateOwnerType, 
   1.205 +                            const TKeyIdentifier* aSubjectKeyId,
   1.206 +                            const TKeyIdentifier* aIssuerKeyId,
   1.207 +                            const TDesC8& aCert, 
   1.208 +                            TRequestStatus& aStatus)
   1.209 +    {
   1.210 + 	// default value for aDeletable = ETrue		
   1.211 +	Add( aLabel, aFormat, aCertificateOwnerType, aSubjectKeyId, 
   1.212 +			aIssuerKeyId, aCert, ETrue, aStatus );
   1.213 +    }
   1.214 +  
   1.215 +// new Add(.., TBool aDeletable, ..) method from MCTWritableCertStore
   1.216 +void CCheckedCertStore::Add( const TDesC& aLabel, 
   1.217 +							 TCertificateFormat aFormat,
   1.218 +                             TCertificateOwnerType aCertificateOwnerType, 
   1.219 +                             const TKeyIdentifier* aSubjectKeyId,
   1.220 +                             const TKeyIdentifier* aIssuerKeyId,
   1.221 +                             const TDesC8& aCert, 
   1.222 +                             const TBool aDeletable,
   1.223 +                             TRequestStatus& aStatus
   1.224 +                             )
   1.225 +    {
   1.226 +    assert(iWritableCertStore);
   1.227 +    assert(iState == EIdleState);
   1.228 +
   1.229 +    TRAPD(err, DoAddL(	aLabel, 
   1.230 +    					aFormat,
   1.231 +    					aCertificateOwnerType, 
   1.232 +    					aSubjectKeyId, 
   1.233 +    					aIssuerKeyId, 
   1.234 +    					aCert, 
   1.235 +    					aDeletable,
   1.236 +    					aStatus		) );
   1.237 +    
   1.238 +	if (err != KErrNone)
   1.239 +		{
   1.240 +    	    Complete(err);
   1.241 +		}
   1.242 +	}
   1.243 +
   1.244 + 
   1.245 +void CCheckedCertStore::DoAddL(	const TDesC& aLabel,
   1.246 +								TCertificateFormat aFormat,
   1.247 +                               	TCertificateOwnerType aCertificateOwnerType, 
   1.248 +                               	const TKeyIdentifier* aSubjectKeyId,
   1.249 +                               	const TKeyIdentifier* aIssuerKeyId,
   1.250 +                               	const TDesC8& aCert, 
   1.251 +                               	const TBool aDeletable,
   1.252 +                               	TRequestStatus& aStatus)
   1.253 +    {
   1.254 +    
   1.255 +    //	Store caller parameters for later use
   1.256 +	    aStatus			= KRequestPending;
   1.257 +	    iCallerStatus	= &aStatus;
   1.258 +	    iFormat 	 	= aFormat;
   1.259 +	    iCertificateOwnerType = aCertificateOwnerType;
   1.260 +	    iSubjectKeyId	= aSubjectKeyId;
   1.261 +	    iIssuerKeyId	= aIssuerKeyId;
   1.262 +		iDeletable  	= aDeletable;
   1.263 +
   1.264 +	// Store (copy)  aCert (cert data) into iCertificate[:HBufC8]
   1.265 +	    assert(!iCertificate);
   1.266 +	    iCertificate = HBufC8::NewMaxL(aCert.Size());
   1.267 +	    TPtr8 theCert(iCertificate->Des());
   1.268 +	    theCert.FillZ();
   1.269 +	    theCert.Copy(aCert);
   1.270 +
   1.271 +	// Store (copy) aLabel (cert label) into iCertLabel[:HBufC]
   1.272 +	    assert(!iCertLabel);
   1.273 +	    iCertLabel = HBufC::NewMaxL(aLabel.Length());
   1.274 +	    TPtr theLabel(iCertLabel->Des());
   1.275 +	    theLabel.FillZ();
   1.276 +	    theLabel.Copy(aLabel);
   1.277 +
   1.278 +    //	Checks subject key ID with certificate data, and sets up key filter
   1.279 +    //	which is used later to determine whether there is a key with the
   1.280 +    //	appropriate subject and thus, if it is OK to add the certificate	
   1.281 +	    ComputeAndCheckSubjectKeyIdL();
   1.282 +
   1.283 +    //	Is keystore checking required? Only if a user certificate
   1.284 +    if (EUserCertificate==aCertificateOwnerType)
   1.285 +		{
   1.286 +        	InitialiseKeyStoreL(EInitKeyStoreForAdd);
   1.287 +		}
   1.288 +    else
   1.289 +		{
   1.290 +        iState = EAdd;
   1.291 +        
   1.292 +        // try new method first
   1.293 +        iWritableCertStore->Add( *iCertLabel,			// call new method
   1.294 +        						 iFormat,
   1.295 +        						 iCertificateOwnerType,
   1.296 +                                 iSubjectKeyId,
   1.297 +                                 iIssuerKeyId,
   1.298 +                                 *iCertificate,
   1.299 +                                 iDeletable,			// with deletable param
   1.300 +                                 iStatus );                    
   1.301 +        SetActive();
   1.302 +		}
   1.303 +	}
   1.304 +
   1.305 +
   1.306 +
   1.307 +void CCheckedCertStore::CancelAdd()
   1.308 +    {
   1.309 +    if (iState == EInitKeyStoreForAdd ||
   1.310 +        iState == EGetKeyInfosForAdd ||
   1.311 +        iState == EAdd || iState == EOldAdd )
   1.312 +        {
   1.313 +        Cancel();
   1.314 +        }
   1.315 +    }
   1.316 +
   1.317 +void CCheckedCertStore::ComputeAndCheckSubjectKeyIdL()
   1.318 +    {
   1.319 +	switch (iFormat)
   1.320 +        {
   1.321 +		case EX509Certificate:
   1.322 +            {
   1.323 +			TPtr8 thePtr(iCertificate->Des());
   1.324 +			CX509Certificate* cert = CX509Certificate::NewLC(thePtr);
   1.325 +
   1.326 +			TKeyUsageX509 x509Usage = EX509UsageNone;
   1.327 +			const CX509CertExtension* ext = cert->Extension(KKeyUsage);
   1.328 +
   1.329 +			if (!ext)
   1.330 +                {
   1.331 +				x509Usage = EX509UsageAll;
   1.332 +                }
   1.333 +			else
   1.334 +                {
   1.335 +				CX509KeyUsageExt* keyUsageExt = CX509KeyUsageExt::NewLC(ext->Data());
   1.336 +				
   1.337 +				if (keyUsageExt->IsSet(EX509DigitalSignature))
   1.338 +					{
   1.339 +					x509Usage |= EX509UsageDigitalSignature;
   1.340 +					}
   1.341 +				if (keyUsageExt->IsSet(EX509NonRepudiation))
   1.342 +					{
   1.343 +					x509Usage |= EX509UsageNonRepudiation;
   1.344 +					}
   1.345 +				if (keyUsageExt->IsSet(EX509KeyEncipherment))
   1.346 +					{
   1.347 +					x509Usage |= EX509UsageKeyEncipherment;
   1.348 +					}
   1.349 +				if (keyUsageExt->IsSet(EX509DataEncipherment))
   1.350 +					{
   1.351 +					x509Usage |= EX509UsageDataEncipherment;
   1.352 +					}
   1.353 +				if (keyUsageExt->IsSet(EX509KeyAgreement))
   1.354 +					{
   1.355 +					x509Usage |= EX509UsageKeyAgreement;
   1.356 +					}
   1.357 +				if (keyUsageExt->IsSet(EX509KeyCertSign))
   1.358 +					{
   1.359 +					x509Usage |= EX509UsageKeyCertSign;
   1.360 +					}
   1.361 +				if (keyUsageExt->IsSet(EX509CRLSign))
   1.362 +					{
   1.363 +					x509Usage |= EX509UsageCRLSign;
   1.364 +					}
   1.365 +				if (keyUsageExt->IsSet(EX509EncipherOnly))
   1.366 +					{
   1.367 +					x509Usage |= EX509UsageEncipherOnly;
   1.368 +					}
   1.369 +				if (keyUsageExt->IsSet(EX509DecipherOnly))
   1.370 +					{
   1.371 +					x509Usage |= EX509UsageDecipherOnly;
   1.372 +					}
   1.373 +
   1.374 +				CleanupStack::PopAndDestroy(keyUsageExt);
   1.375 +                }
   1.376 +
   1.377 +			iKeyFilter.iUsage = KeyUsageX509ToPKCS15Private(x509Usage);
   1.378 +			
   1.379 +			iComputedSubjectKeyId.Zero();
   1.380 +			// For non-user ceriticates (i.e. CA certificates), we use the SubjectKeyIdentifier API, as it
   1.381 +			// tries to get the extension from cert., and calculates a value only if it is not found. This behaviour corresponds to the RFC.
   1.382 +			// For user ceritificates, the key identifier is used for matching key store with cert store, so we cannot use the value in the certificate itself.
   1.383 +			if (iCertificateOwnerType != EUserCertificate)
   1.384 +				{
   1.385 +				iComputedSubjectKeyId = cert->SubjectKeyIdentifierL();
   1.386 +				}
   1.387 +			else
   1.388 +				{
   1.389 +				// For non-CA certs, use the recommended method of computing it from RFC3280, section 4.2.1.2
   1.390 +				iComputedSubjectKeyId = cert->KeyIdentifierL();									
   1.391 +				}
   1.392 +			if (!iSubjectKeyId || *iSubjectKeyId == KNullDesC8)
   1.393 +                {
   1.394 +				iSubjectKeyId = &iComputedSubjectKeyId;
   1.395 +                }
   1.396 +			else if (iSubjectKeyId->Compare(iComputedSubjectKeyId)!=0)
   1.397 +                {//	Different subject ids
   1.398 +				User::Leave(KErrArgument);
   1.399 +                }
   1.400 +			
   1.401 +			CleanupStack::PopAndDestroy(cert);
   1.402 +            }	
   1.403 +            break;
   1.404 +	
   1.405 +        case EWTLSCertificate:
   1.406 +            {
   1.407 +            CCertificate* cert = CWTLSCertificate::NewLC(*iCertificate);
   1.408 +            iComputedSubjectKeyId = cert->KeyIdentifierL();
   1.409 +            if (!iSubjectKeyId || *iSubjectKeyId == KNullDesC8)
   1.410 +                {
   1.411 +                iSubjectKeyId = &iComputedSubjectKeyId;
   1.412 +                }
   1.413 +            else if (iSubjectKeyId->Compare(iComputedSubjectKeyId)!=0)
   1.414 +                {//	Different subject ids
   1.415 +                User::Leave(KErrArgument);
   1.416 +                }
   1.417 +	
   1.418 +            CleanupStack::PopAndDestroy(cert);
   1.419 +            }
   1.420 +            break;
   1.421 +
   1.422 +        case EX509CertificateUrl:
   1.423 +            {
   1.424 +            iKeyFilter.iUsage = EPKCS15UsageAll;
   1.425 +		
   1.426 +            if (!iSubjectKeyId || *iSubjectKeyId == KNullDesC8)
   1.427 +                {
   1.428 +                User::Leave(KErrArgument);
   1.429 +                }
   1.430 +            }
   1.431 +            break;
   1.432 +
   1.433 +        default:
   1.434 +            User::Leave(KErrNotSupported);	
   1.435 +            break;
   1.436 +        }
   1.437 +
   1.438 +	iKeyFilter.iKeyId = *iSubjectKeyId;
   1.439 +    }
   1.440 +
   1.441 +void CCheckedCertStore::Remove(const CCTCertInfo& aCertInfo, TRequestStatus& aStatus)
   1.442 +    {
   1.443 +    assert(iWritableCertStore);
   1.444 +    assert(iState == EIdleState);
   1.445 +    aStatus = KRequestPending;
   1.446 +    iCallerStatus = &aStatus;
   1.447 +    iState = ERemove;
   1.448 +    iWritableCertStore->Remove(aCertInfo, iStatus);
   1.449 +    SetActive();
   1.450 +    }
   1.451 +
   1.452 +void CCheckedCertStore::CancelRemove()
   1.453 +    {
   1.454 +    if (iState == ERemove)
   1.455 +        {
   1.456 +        Cancel();
   1.457 +        }
   1.458 +    }
   1.459 +
   1.460 +void CCheckedCertStore::SetApplicability(const CCTCertInfo& aCertInfo, const RArray<TUid>& aApplications, TRequestStatus &aStatus)
   1.461 +    {
   1.462 +    assert(iWritableCertStore);
   1.463 +    assert(iState == EIdleState);
   1.464 +    aStatus = KRequestPending;
   1.465 +    iCallerStatus = &aStatus;
   1.466 +    iState = ESetApplicability;
   1.467 +    iWritableCertStore->SetApplicability(aCertInfo, aApplications, iStatus);
   1.468 +    SetActive();
   1.469 +    }
   1.470 +	
   1.471 +void CCheckedCertStore::CancelSetApplicability()
   1.472 +    {
   1.473 +    if (iState == ESetApplicability)
   1.474 +        {
   1.475 +        Cancel();
   1.476 +        }    
   1.477 +    }
   1.478 +
   1.479 +void CCheckedCertStore::SetTrust(const CCTCertInfo& aCertInfo, TBool aTrusted, TRequestStatus& aStatus)
   1.480 +    {
   1.481 +    assert(iWritableCertStore);
   1.482 +    assert(iState == EIdleState);
   1.483 +    aStatus = KRequestPending;
   1.484 +    iCallerStatus = &aStatus;
   1.485 +    iState = ESetTrust;
   1.486 +    iWritableCertStore->SetTrust(aCertInfo, aTrusted, iStatus);
   1.487 +    SetActive();
   1.488 +    }
   1.489 +
   1.490 +void CCheckedCertStore::CancelSetTrust()
   1.491 +    {
   1.492 +    if (iState == ESetTrust)
   1.493 +        {
   1.494 +        Cancel();
   1.495 +        }        
   1.496 +    }
   1.497 +
   1.498 +TInt CCheckedCertStore::RunError(TInt aError)
   1.499 +    {
   1.500 +    Complete(aError);
   1.501 +	return KErrNone;
   1.502 +    }
   1.503 +	
   1.504 +void CCheckedCertStore::DoCancel()
   1.505 +    {
   1.506 +	// (see notes on cancellation in CUnifiedCertStore::DoCancel)
   1.507 +
   1.508 +	switch (iState)
   1.509 +		{
   1.510 +        case EGetKeyInfosForList:
   1.511 +        case EAdd:
   1.512 +		case ERemove:
   1.513 +		case ESetApplicability:
   1.514 +		case ESetTrust:
   1.515 +			if (iStatus == KRequestPending)
   1.516 +				{
   1.517 +				// Attempt to cancel outstanding request and pass status back to
   1.518 +				// client
   1.519 +				CancelOutstandingRequest();
   1.520 +				Complete(iStatus.Int());
   1.521 +				}
   1.522 +			else
   1.523 +				{
   1.524 +				// We've already been completed - call RunL() to process results
   1.525 +				// and complete client
   1.526 +				TRAPD(err, RunL());
   1.527 +				if (err != KErrNone)
   1.528 +					{
   1.529 +					RunError(err);
   1.530 +					}
   1.531 +				}
   1.532 +			break;
   1.533 +			
   1.534 +		default:
   1.535 +			CancelOutstandingRequest();
   1.536 +			Complete(KErrCancel);
   1.537 +			break;
   1.538 +		}	
   1.539 +	}
   1.540 +
   1.541 +void CCheckedCertStore::CancelOutstandingRequest()
   1.542 +	{
   1.543 +    switch (iState)
   1.544 +        {
   1.545 +        case EList:
   1.546 +            iCertStore.CancelList();
   1.547 +            break;
   1.548 +
   1.549 +        case EInitKeyStoreForAdd:
   1.550 +        case EInitKeyStoreForList:
   1.551 +            assert(iUnifiedKeyStore);
   1.552 +            iUnifiedKeyStore->CancelInitialize();
   1.553 +            break;
   1.554 +
   1.555 +        case EGetKeyInfosForAdd:
   1.556 +        case EGetKeyInfosForList:
   1.557 +            assert(iUnifiedKeyStore);
   1.558 +            iUnifiedKeyStore->CancelList();
   1.559 +            break;
   1.560 +
   1.561 +        case EAdd:
   1.562 +        case EOldAdd:
   1.563 +            assert(iWritableCertStore);
   1.564 +            iWritableCertStore->CancelAdd();
   1.565 +            break;
   1.566 +            
   1.567 +        case ERemove:
   1.568 +		    assert(iWritableCertStore);
   1.569 +   			iWritableCertStore->CancelRemove();
   1.570 +			break;
   1.571 +			
   1.572 +        case ESetApplicability:
   1.573 +		    assert(iWritableCertStore);
   1.574 +   			iWritableCertStore->CancelSetApplicability();
   1.575 +			break;
   1.576 +			
   1.577 +        case ESetTrust:
   1.578 +		    assert(iWritableCertStore);
   1.579 +   			iWritableCertStore->CancelSetTrust();
   1.580 +			break;
   1.581 +
   1.582 +
   1.583 +        default:
   1.584 +            assert(EFalse);
   1.585 +            break;            
   1.586 +        }
   1.587 +
   1.588 +    Complete(KErrCancel);
   1.589 +    }
   1.590 +
   1.591 +void CCheckedCertStore::RunL()
   1.592 +    {
   1.593 +    assert(iCallerStatus);
   1.594 +    
   1.595 +	// we allow only KErrNone OR, possibly, KErrNotSupported after new Add()
   1.596 +	// otherwise - Leave!
   1.597 +	if (iStatus!=KErrNone &&
   1.598 +	    !(iStatus==KErrNotSupported && iState==EAdd) &&
   1.599 +	    !(iStatus == KErrNotFound && (iState==EList || iState==EGetKeyInfosForList || iState==EInitKeyStoreForList)))
   1.600 +		{
   1.601 +    	User::Leave(iStatus.Int());
   1.602 +    	}
   1.603 +		
   1.604 +    switch (iState)
   1.605 +        {
   1.606 +        case EList:
   1.607 +            if (iCallerFilter->iKeyUsage == EX509UsageAll)
   1.608 +                {
   1.609 +                // No key usage filter, so we're done
   1.610 +                Complete(KErrNone);
   1.611 +                }
   1.612 +            else
   1.613 +                {
   1.614 +                // Set up key filter according list cert parameters
   1.615 +                if (iCallerFilter->iSubjectKeyIdIsSet)
   1.616 +                    {
   1.617 +                    iKeyFilter.iKeyId = iCallerFilter->iSubjectKeyId;
   1.618 +                    }
   1.619 +                else
   1.620 +                    {
   1.621 +                    iKeyFilter.iKeyId = KNullDesC8;
   1.622 +                    }
   1.623 +                iKeyFilter.iUsage = KeyUsageX509ToPKCS15Private(iCallerFilter->iKeyUsage);
   1.624 +                InitialiseKeyStoreL(EInitKeyStoreForList);
   1.625 +                }
   1.626 +            break;
   1.627 +
   1.628 +        case EInitKeyStoreForAdd:
   1.629 +        case EInitKeyStoreForList:
   1.630 +            assert(iUnifiedKeyStore);
   1.631 +            iState = (iState == EInitKeyStoreForAdd) ? EGetKeyInfosForAdd : EGetKeyInfosForList;
   1.632 +            iUnifiedKeyStore->List(iKeyInfos, iKeyFilter, iStatus);			
   1.633 +            SetActive();
   1.634 +            break;
   1.635 +
   1.636 +        case EGetKeyInfosForList:
   1.637 +            BuildCheckedCertificateListL();	//	Not async
   1.638 +            Complete(KErrNone);
   1.639 +            break;
   1.640 +
   1.641 +        case EGetKeyInfosForAdd:
   1.642 +            // We have a filter list of keys - there should be one with
   1.643 +            // the appropriate subject if we are to add it
   1.644 +            if (iKeyInfos.Count() == 0)
   1.645 +                {
   1.646 +                //	The private key can't be found in any key store
   1.647 +                Complete(KErrPrivateKeyNotFound); 
   1.648 +                }
   1.649 +            else
   1.650 +                {
   1.651 +                //	OK to go ahead and add the key
   1.652 +                assert(iWritableCertStore);
   1.653 +                iState = EAdd;
   1.654 +                
   1.655 +                // try to use new Add(.., TBool aDeletable, ..)
   1.656 +                // if it's not supported it will return with
   1.657 +                // iStatus set to KErrNotSupported
   1.658 +                iWritableCertStore->Add( *iCertLabel,	// call new Add() method
   1.659 +                						 iFormat,
   1.660 +                						 iCertificateOwnerType,
   1.661 +                                         iSubjectKeyId,
   1.662 +                                         iIssuerKeyId,
   1.663 +                                         *iCertificate,
   1.664 +                                         iDeletable,  	// with deletable param
   1.665 +                                         iStatus);
   1.666 +                SetActive();
   1.667 +                }
   1.668 +            break;
   1.669 +                
   1.670 +        case EAdd:
   1.671 +         	if (iStatus!=KErrNotSupported)
   1.672 +         		{
   1.673 + 	     		// Set published property
   1.674 + 		      	iPSCertstoreChangePropertyRef.Set(KUnifiedCertStorePropertyCat, // category
   1.675 +  												EUnifiedCertStoreFlag,        // key
   1.676 +  	    										1);                           // value
   1.677 +         		
   1.678 +		        // when here means MCTWritableCertStore was able to find 
   1.679 +		        // child's new Add(..,aDeletable,..) method
   1.680 +				// thus, ok and complete with whatever result it returned
   1.681 +			    Complete(iStatus.Int());
   1.682 +		        }
   1.683 +		    else
   1.684 +		       	{
   1.685 +				// here: call to the new Add() method above didn't work,
   1.686 +				// try to call old Add() method
   1.687 +			    iState = EOldAdd;
   1.688 +               	iStatus = KRequestPending;
   1.689 +               	iWritableCertStore->Add( *iCertLabel,	
   1.690 +                						 iFormat,
   1.691 +                						 iCertificateOwnerType,
   1.692 +                                         iSubjectKeyId,
   1.693 +                                         iIssuerKeyId,
   1.694 +                                         *iCertificate,
   1.695 +                                         iStatus);
   1.696 +                SetActive();                                         
   1.697 +               	} 
   1.698 +           	break;
   1.699 +
   1.700 +        case EOldAdd:
   1.701 +        case ERemove:  
   1.702 +        case ESetApplicability:     
   1.703 +		case ESetTrust:              
   1.704 +      		// Set published property
   1.705 + 	      	iPSCertstoreChangePropertyRef.Set(KUnifiedCertStorePropertyCat, // category
   1.706 +											EUnifiedCertStoreFlag,        // key
   1.707 + 	      									1);                           // value      
   1.708 +            Complete(iStatus.Int());
   1.709 +            break;
   1.710 +            
   1.711 +        default:
   1.712 +            assert(EFalse);
   1.713 +            break;
   1.714 +        }
   1.715 +    }
   1.716 +	
   1.717 +void CCheckedCertStore::InitialiseKeyStoreL(TState aNextState)
   1.718 +    {
   1.719 +    assert(aNextState == EInitKeyStoreForAdd || aNextState == EInitKeyStoreForList);
   1.720 +	assert(!iUnifiedKeyStore);
   1.721 +    
   1.722 +	iUnifiedKeyStore = CUnifiedKeyStore::NewL(iFs);
   1.723 +    iUnifiedKeyStore->Initialize(iStatus);		
   1.724 +    iState = aNextState;
   1.725 +    SetActive();
   1.726 +    }
   1.727 +
   1.728 +void CCheckedCertStore::BuildCheckedCertificateListL()
   1.729 +    {
   1.730 +	TInt certCount = iCallerCerts->Count();
   1.731 +    TInt keyCount = iKeyInfos.Count();
   1.732 +    
   1.733 +    // Iterate backwards through cert array so remove doesn't affect indicies
   1.734 +    for (TInt i = certCount - 1 ; i >= 0 ; --i)
   1.735 +        {
   1.736 +		CCTCertInfo* certInfo = (*iCallerCerts)[i];
   1.737 +
   1.738 +        // It's problem in the certstore implementation if the list contains NULL pointers
   1.739 +        assert(certInfo); 
   1.740 +
   1.741 +        // Check for key with corresponding id
   1.742 +		TBool accept = EFalse;
   1.743 +        for (TInt j = 0 ; j < keyCount ; ++j)
   1.744 +            {
   1.745 +            if (iKeyInfos[j]->ID()==certInfo->SubjectKeyId())
   1.746 +                {
   1.747 +                accept = ETrue;
   1.748 +                break;
   1.749 +                }
   1.750 +            }
   1.751 +
   1.752 +        // If we don't have it, remove and release the cert info
   1.753 +        if (!accept)
   1.754 +            {
   1.755 +            iCallerCerts->Remove(i);
   1.756 +            certInfo->Release();
   1.757 +            }
   1.758 +        }
   1.759 +    }
   1.760 +
   1.761 +void CCheckedCertStore::Complete(TInt aError)
   1.762 +    {
   1.763 +	if (iCallerStatus)
   1.764 +        {
   1.765 +		User::RequestComplete(iCallerStatus, aError);
   1.766 +        }
   1.767 +    Cleanup();
   1.768 +    }
   1.769 +
   1.770 +void CCheckedCertStore::Cleanup()
   1.771 +    {
   1.772 +    //	Reset the state machine	
   1.773 +	iState = EIdleState;
   1.774 +	iKeyInfos.Close();
   1.775 +    iSubjectKeyId = NULL;
   1.776 +    iIssuerKeyId = NULL;
   1.777 +
   1.778 +    delete iCertLabel;
   1.779 +    iCertLabel = NULL;
   1.780 +
   1.781 +    delete iCertificate;
   1.782 +    iCertificate = NULL;
   1.783 +
   1.784 +    delete iUnifiedKeyStore;
   1.785 +    iUnifiedKeyStore = 0;		
   1.786 +
   1.787 +    iCallerCerts = NULL;
   1.788 +    iCallerFilter = NULL;
   1.789 +    }