--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cryptoservices/certificateandkeymgmt/certstore/CCheckedCertStore.cpp Wed Jul 08 11:25:26 2009 +0100
@@ -0,0 +1,786 @@
+/*
+* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include "CCheckedCertStore.h"
+
+#include <signed.h>
+#include <x509cert.h>
+#include <x509certext.h>
+#include <wtlscert.h>
+#include <x509keys.h>
+#include <securityerr.h>
+
+#include "certificateapps.h"
+
+_LIT(KPanicCategory, "CCheckedCertStore");
+#define assert(x) __ASSERT_ALWAYS((x), User::Panic(KPanicCategory, 1));
+
+/////////////////////////////////////////////////////////////////////
+// CCheckedCertStore
+/////////////////////////////////////////////////////////////////////
+
+CCheckedCertStore::~CCheckedCertStore()
+ {
+ Cancel();
+ Cleanup();
+
+ // Release the cert store - no need to release the token since this would
+ // have been done as part of MCTTokenInterface::Release()
+ iCertStore.Release();
+
+ iFs.Close();
+ }
+
+CCheckedCertStore::CCheckedCertStore(MCTCertStore& aTokenIF, RProperty& aProperty)
+: CActive(EPriorityStandard),
+ iCertStore(aTokenIF),
+ iPSCertstoreChangePropertyRef(aProperty)
+ {
+ // need to add reference since we now have the token
+ iCertStore.Token().AddRef();
+ }
+
+CCheckedCertStore::CCheckedCertStore(MCTWritableCertStore& aTokenIF, RProperty& aProperty)
+: CActive(EPriorityStandard),
+ iCertStore(aTokenIF),
+ iWritableCertStore(&aTokenIF),
+ iPSCertstoreChangePropertyRef(aProperty)
+ {
+ // need to add reference since we now have the token
+ iCertStore.Token().AddRef();
+ }
+
+/*static*/ CCheckedCertStore* CCheckedCertStore::NewCheckedCertStoreL(MCTTokenInterface* aTokenIF, RProperty& aProperty)
+ {
+ assert(aTokenIF);
+ MCTCertStore& tokenInterface = static_cast<MCTCertStore&>(*aTokenIF);
+ CCheckedCertStore* me = new (ELeave) CCheckedCertStore(tokenInterface, aProperty);
+ CleanupReleasePushL(*me);
+ me->ConstructL();
+ CleanupStack::Pop();
+ return (me);
+ }
+
+/*static*/ CCheckedCertStore* CCheckedCertStore::NewCheckedWritableCertStoreL(MCTTokenInterface* aTokenIF, RProperty& aProperty)
+ {
+ assert(aTokenIF);
+ MCTWritableCertStore& tokenInterface = static_cast<MCTWritableCertStore&>(*aTokenIF);
+ CCheckedCertStore* me = new (ELeave) CCheckedCertStore(tokenInterface, aProperty);
+ CleanupReleasePushL(*me);
+ me->ConstructL();
+ CleanupStack::Pop();
+ return (me);
+ }
+
+void CCheckedCertStore::ConstructL()
+ {
+ User::LeaveIfError(iFs.Connect());
+ CActiveScheduler::Add(this);
+ }
+
+MCTToken& CCheckedCertStore::Token()
+ {
+ return iCertStore.Token();
+ }
+
+// May require checking against the keystore *after* calling the server to complete
+// the List request
+void CCheckedCertStore::List(RMPointerArray<CCTCertInfo>& aCerts, const CCertAttributeFilter& aFilter,
+ TRequestStatus& aStatus)
+ {
+ assert(iState == EIdleState);
+
+ // Only allow filtering on key usage for user certs
+ if (aFilter.iKeyUsage != EX509UsageAll &&
+ (!aFilter.iOwnerTypeIsSet || EUserCertificate != aFilter.iOwnerType))
+ {
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, KErrNotSupported);
+ return;
+ }
+
+ // Store caller parameters for later reference
+ iCallerCerts = &aCerts;
+ iCallerFilter = &aFilter;
+ aStatus = KRequestPending;
+ iCallerStatus = &aStatus;
+
+ iState = EList;
+ iCertStore.List(aCerts, aFilter, iStatus);
+ SetActive();
+ }
+
+void CCheckedCertStore::CancelList()
+ {
+ if (iState == EList ||
+ iState == EInitKeyStoreForList ||
+ iState == EGetKeyInfosForList)
+ {
+ Cancel();
+ }
+ }
+
+void CCheckedCertStore::GetCert(CCTCertInfo*& aCertInfo, const TCTTokenObjectHandle& aHandle,
+ TRequestStatus& aStatus)
+ {
+ assert(iState == EIdleState);
+ iCertStore.GetCert(aCertInfo, aHandle, aStatus);
+ }
+
+void CCheckedCertStore::CancelGetCert()
+ {
+ iCertStore.CancelGetCert();
+ }
+
+void CCheckedCertStore::Applications(const CCTCertInfo& aCertInfo, RArray<TUid>& aApplications,
+ TRequestStatus& aStatus)
+ {
+ assert(iState == EIdleState);
+ iCertStore.Applications(aCertInfo, aApplications, aStatus);
+ }
+
+void CCheckedCertStore::CancelApplications()
+ {
+ iCertStore.CancelApplications();
+ }
+
+void CCheckedCertStore::IsApplicable(const CCTCertInfo& aCertInfo, TUid aApplication,
+ TBool& aIsApplicable, TRequestStatus& aStatus)
+ {
+ assert(iState == EIdleState);
+ iCertStore.IsApplicable(aCertInfo, aApplication, aIsApplicable, aStatus);
+ }
+
+void CCheckedCertStore::CancelIsApplicable()
+ {
+ iCertStore.CancelIsApplicable();
+ }
+
+void CCheckedCertStore::Trusted(const CCTCertInfo& aCertInfo, TBool& aTrusted,
+ TRequestStatus& aStatus)
+ {
+ assert(iState == EIdleState);
+ iCertStore.Trusted(aCertInfo, aTrusted, aStatus);
+ }
+
+void CCheckedCertStore::CancelTrusted()
+ {
+ iCertStore.CancelTrusted();
+ }
+
+void CCheckedCertStore::Retrieve(const CCTCertInfo& aCertInfo, TDes8& aEncodedCert,
+ TRequestStatus& aStatus)
+ {
+ assert(iState == EIdleState);
+ iCertStore.Retrieve(aCertInfo, aEncodedCert, aStatus);
+ }
+
+void CCheckedCertStore::CancelRetrieve()
+ {
+ iCertStore.CancelRetrieve();
+ }
+
+
+void CCheckedCertStore::Add(const TDesC& aLabel,
+ TCertificateFormat aFormat,
+ TCertificateOwnerType aCertificateOwnerType,
+ const TKeyIdentifier* aSubjectKeyId,
+ const TKeyIdentifier* aIssuerKeyId,
+ const TDesC8& aCert,
+ TRequestStatus& aStatus)
+ {
+ // default value for aDeletable = ETrue
+ Add( aLabel, aFormat, aCertificateOwnerType, aSubjectKeyId,
+ aIssuerKeyId, aCert, ETrue, aStatus );
+ }
+
+// new Add(.., TBool aDeletable, ..) method from MCTWritableCertStore
+void CCheckedCertStore::Add( const TDesC& aLabel,
+ TCertificateFormat aFormat,
+ TCertificateOwnerType aCertificateOwnerType,
+ const TKeyIdentifier* aSubjectKeyId,
+ const TKeyIdentifier* aIssuerKeyId,
+ const TDesC8& aCert,
+ const TBool aDeletable,
+ TRequestStatus& aStatus
+ )
+ {
+ assert(iWritableCertStore);
+ assert(iState == EIdleState);
+
+ TRAPD(err, DoAddL( aLabel,
+ aFormat,
+ aCertificateOwnerType,
+ aSubjectKeyId,
+ aIssuerKeyId,
+ aCert,
+ aDeletable,
+ aStatus ) );
+
+ if (err != KErrNone)
+ {
+ Complete(err);
+ }
+ }
+
+
+void CCheckedCertStore::DoAddL( const TDesC& aLabel,
+ TCertificateFormat aFormat,
+ TCertificateOwnerType aCertificateOwnerType,
+ const TKeyIdentifier* aSubjectKeyId,
+ const TKeyIdentifier* aIssuerKeyId,
+ const TDesC8& aCert,
+ const TBool aDeletable,
+ TRequestStatus& aStatus)
+ {
+
+ // Store caller parameters for later use
+ aStatus = KRequestPending;
+ iCallerStatus = &aStatus;
+ iFormat = aFormat;
+ iCertificateOwnerType = aCertificateOwnerType;
+ iSubjectKeyId = aSubjectKeyId;
+ iIssuerKeyId = aIssuerKeyId;
+ iDeletable = aDeletable;
+
+ // Store (copy) aCert (cert data) into iCertificate[:HBufC8]
+ assert(!iCertificate);
+ iCertificate = HBufC8::NewMaxL(aCert.Size());
+ TPtr8 theCert(iCertificate->Des());
+ theCert.FillZ();
+ theCert.Copy(aCert);
+
+ // Store (copy) aLabel (cert label) into iCertLabel[:HBufC]
+ assert(!iCertLabel);
+ iCertLabel = HBufC::NewMaxL(aLabel.Length());
+ TPtr theLabel(iCertLabel->Des());
+ theLabel.FillZ();
+ theLabel.Copy(aLabel);
+
+ // Checks subject key ID with certificate data, and sets up key filter
+ // which is used later to determine whether there is a key with the
+ // appropriate subject and thus, if it is OK to add the certificate
+ ComputeAndCheckSubjectKeyIdL();
+
+ // Is keystore checking required? Only if a user certificate
+ if (EUserCertificate==aCertificateOwnerType)
+ {
+ InitialiseKeyStoreL(EInitKeyStoreForAdd);
+ }
+ else
+ {
+ iState = EAdd;
+
+ // try new method first
+ iWritableCertStore->Add( *iCertLabel, // call new method
+ iFormat,
+ iCertificateOwnerType,
+ iSubjectKeyId,
+ iIssuerKeyId,
+ *iCertificate,
+ iDeletable, // with deletable param
+ iStatus );
+ SetActive();
+ }
+ }
+
+
+
+void CCheckedCertStore::CancelAdd()
+ {
+ if (iState == EInitKeyStoreForAdd ||
+ iState == EGetKeyInfosForAdd ||
+ iState == EAdd || iState == EOldAdd )
+ {
+ Cancel();
+ }
+ }
+
+void CCheckedCertStore::ComputeAndCheckSubjectKeyIdL()
+ {
+ switch (iFormat)
+ {
+ case EX509Certificate:
+ {
+ TPtr8 thePtr(iCertificate->Des());
+ CX509Certificate* cert = CX509Certificate::NewLC(thePtr);
+
+ TKeyUsageX509 x509Usage = EX509UsageNone;
+ const CX509CertExtension* ext = cert->Extension(KKeyUsage);
+
+ if (!ext)
+ {
+ x509Usage = EX509UsageAll;
+ }
+ else
+ {
+ CX509KeyUsageExt* keyUsageExt = CX509KeyUsageExt::NewLC(ext->Data());
+
+ if (keyUsageExt->IsSet(EX509DigitalSignature))
+ {
+ x509Usage |= EX509UsageDigitalSignature;
+ }
+ if (keyUsageExt->IsSet(EX509NonRepudiation))
+ {
+ x509Usage |= EX509UsageNonRepudiation;
+ }
+ if (keyUsageExt->IsSet(EX509KeyEncipherment))
+ {
+ x509Usage |= EX509UsageKeyEncipherment;
+ }
+ if (keyUsageExt->IsSet(EX509DataEncipherment))
+ {
+ x509Usage |= EX509UsageDataEncipherment;
+ }
+ if (keyUsageExt->IsSet(EX509KeyAgreement))
+ {
+ x509Usage |= EX509UsageKeyAgreement;
+ }
+ if (keyUsageExt->IsSet(EX509KeyCertSign))
+ {
+ x509Usage |= EX509UsageKeyCertSign;
+ }
+ if (keyUsageExt->IsSet(EX509CRLSign))
+ {
+ x509Usage |= EX509UsageCRLSign;
+ }
+ if (keyUsageExt->IsSet(EX509EncipherOnly))
+ {
+ x509Usage |= EX509UsageEncipherOnly;
+ }
+ if (keyUsageExt->IsSet(EX509DecipherOnly))
+ {
+ x509Usage |= EX509UsageDecipherOnly;
+ }
+
+ CleanupStack::PopAndDestroy(keyUsageExt);
+ }
+
+ iKeyFilter.iUsage = KeyUsageX509ToPKCS15Private(x509Usage);
+
+ iComputedSubjectKeyId.Zero();
+ // For non-user ceriticates (i.e. CA certificates), we use the SubjectKeyIdentifier API, as it
+ // tries to get the extension from cert., and calculates a value only if it is not found. This behaviour corresponds to the RFC.
+ // 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.
+ if (iCertificateOwnerType != EUserCertificate)
+ {
+ iComputedSubjectKeyId = cert->SubjectKeyIdentifierL();
+ }
+ else
+ {
+ // For non-CA certs, use the recommended method of computing it from RFC3280, section 4.2.1.2
+ iComputedSubjectKeyId = cert->KeyIdentifierL();
+ }
+ if (!iSubjectKeyId || *iSubjectKeyId == KNullDesC8)
+ {
+ iSubjectKeyId = &iComputedSubjectKeyId;
+ }
+ else if (iSubjectKeyId->Compare(iComputedSubjectKeyId)!=0)
+ {// Different subject ids
+ User::Leave(KErrArgument);
+ }
+
+ CleanupStack::PopAndDestroy(cert);
+ }
+ break;
+
+ case EWTLSCertificate:
+ {
+ CCertificate* cert = CWTLSCertificate::NewLC(*iCertificate);
+ iComputedSubjectKeyId = cert->KeyIdentifierL();
+ if (!iSubjectKeyId || *iSubjectKeyId == KNullDesC8)
+ {
+ iSubjectKeyId = &iComputedSubjectKeyId;
+ }
+ else if (iSubjectKeyId->Compare(iComputedSubjectKeyId)!=0)
+ {// Different subject ids
+ User::Leave(KErrArgument);
+ }
+
+ CleanupStack::PopAndDestroy(cert);
+ }
+ break;
+
+ case EX509CertificateUrl:
+ {
+ iKeyFilter.iUsage = EPKCS15UsageAll;
+
+ if (!iSubjectKeyId || *iSubjectKeyId == KNullDesC8)
+ {
+ User::Leave(KErrArgument);
+ }
+ }
+ break;
+
+ default:
+ User::Leave(KErrNotSupported);
+ break;
+ }
+
+ iKeyFilter.iKeyId = *iSubjectKeyId;
+ }
+
+void CCheckedCertStore::Remove(const CCTCertInfo& aCertInfo, TRequestStatus& aStatus)
+ {
+ assert(iWritableCertStore);
+ assert(iState == EIdleState);
+ aStatus = KRequestPending;
+ iCallerStatus = &aStatus;
+ iState = ERemove;
+ iWritableCertStore->Remove(aCertInfo, iStatus);
+ SetActive();
+ }
+
+void CCheckedCertStore::CancelRemove()
+ {
+ if (iState == ERemove)
+ {
+ Cancel();
+ }
+ }
+
+void CCheckedCertStore::SetApplicability(const CCTCertInfo& aCertInfo, const RArray<TUid>& aApplications, TRequestStatus &aStatus)
+ {
+ assert(iWritableCertStore);
+ assert(iState == EIdleState);
+ aStatus = KRequestPending;
+ iCallerStatus = &aStatus;
+ iState = ESetApplicability;
+ iWritableCertStore->SetApplicability(aCertInfo, aApplications, iStatus);
+ SetActive();
+ }
+
+void CCheckedCertStore::CancelSetApplicability()
+ {
+ if (iState == ESetApplicability)
+ {
+ Cancel();
+ }
+ }
+
+void CCheckedCertStore::SetTrust(const CCTCertInfo& aCertInfo, TBool aTrusted, TRequestStatus& aStatus)
+ {
+ assert(iWritableCertStore);
+ assert(iState == EIdleState);
+ aStatus = KRequestPending;
+ iCallerStatus = &aStatus;
+ iState = ESetTrust;
+ iWritableCertStore->SetTrust(aCertInfo, aTrusted, iStatus);
+ SetActive();
+ }
+
+void CCheckedCertStore::CancelSetTrust()
+ {
+ if (iState == ESetTrust)
+ {
+ Cancel();
+ }
+ }
+
+TInt CCheckedCertStore::RunError(TInt aError)
+ {
+ Complete(aError);
+ return KErrNone;
+ }
+
+void CCheckedCertStore::DoCancel()
+ {
+ // (see notes on cancellation in CUnifiedCertStore::DoCancel)
+
+ switch (iState)
+ {
+ case EGetKeyInfosForList:
+ case EAdd:
+ case ERemove:
+ case ESetApplicability:
+ case ESetTrust:
+ if (iStatus == KRequestPending)
+ {
+ // Attempt to cancel outstanding request and pass status back to
+ // client
+ CancelOutstandingRequest();
+ Complete(iStatus.Int());
+ }
+ else
+ {
+ // We've already been completed - call RunL() to process results
+ // and complete client
+ TRAPD(err, RunL());
+ if (err != KErrNone)
+ {
+ RunError(err);
+ }
+ }
+ break;
+
+ default:
+ CancelOutstandingRequest();
+ Complete(KErrCancel);
+ break;
+ }
+ }
+
+void CCheckedCertStore::CancelOutstandingRequest()
+ {
+ switch (iState)
+ {
+ case EList:
+ iCertStore.CancelList();
+ break;
+
+ case EInitKeyStoreForAdd:
+ case EInitKeyStoreForList:
+ assert(iUnifiedKeyStore);
+ iUnifiedKeyStore->CancelInitialize();
+ break;
+
+ case EGetKeyInfosForAdd:
+ case EGetKeyInfosForList:
+ assert(iUnifiedKeyStore);
+ iUnifiedKeyStore->CancelList();
+ break;
+
+ case EAdd:
+ case EOldAdd:
+ assert(iWritableCertStore);
+ iWritableCertStore->CancelAdd();
+ break;
+
+ case ERemove:
+ assert(iWritableCertStore);
+ iWritableCertStore->CancelRemove();
+ break;
+
+ case ESetApplicability:
+ assert(iWritableCertStore);
+ iWritableCertStore->CancelSetApplicability();
+ break;
+
+ case ESetTrust:
+ assert(iWritableCertStore);
+ iWritableCertStore->CancelSetTrust();
+ break;
+
+
+ default:
+ assert(EFalse);
+ break;
+ }
+
+ Complete(KErrCancel);
+ }
+
+void CCheckedCertStore::RunL()
+ {
+ assert(iCallerStatus);
+
+ // we allow only KErrNone OR, possibly, KErrNotSupported after new Add()
+ // otherwise - Leave!
+ if (iStatus!=KErrNone &&
+ !(iStatus==KErrNotSupported && iState==EAdd) &&
+ !(iStatus == KErrNotFound && (iState==EList || iState==EGetKeyInfosForList || iState==EInitKeyStoreForList)))
+ {
+ User::Leave(iStatus.Int());
+ }
+
+ switch (iState)
+ {
+ case EList:
+ if (iCallerFilter->iKeyUsage == EX509UsageAll)
+ {
+ // No key usage filter, so we're done
+ Complete(KErrNone);
+ }
+ else
+ {
+ // Set up key filter according list cert parameters
+ if (iCallerFilter->iSubjectKeyIdIsSet)
+ {
+ iKeyFilter.iKeyId = iCallerFilter->iSubjectKeyId;
+ }
+ else
+ {
+ iKeyFilter.iKeyId = KNullDesC8;
+ }
+ iKeyFilter.iUsage = KeyUsageX509ToPKCS15Private(iCallerFilter->iKeyUsage);
+ InitialiseKeyStoreL(EInitKeyStoreForList);
+ }
+ break;
+
+ case EInitKeyStoreForAdd:
+ case EInitKeyStoreForList:
+ assert(iUnifiedKeyStore);
+ iState = (iState == EInitKeyStoreForAdd) ? EGetKeyInfosForAdd : EGetKeyInfosForList;
+ iUnifiedKeyStore->List(iKeyInfos, iKeyFilter, iStatus);
+ SetActive();
+ break;
+
+ case EGetKeyInfosForList:
+ BuildCheckedCertificateListL(); // Not async
+ Complete(KErrNone);
+ break;
+
+ case EGetKeyInfosForAdd:
+ // We have a filter list of keys - there should be one with
+ // the appropriate subject if we are to add it
+ if (iKeyInfos.Count() == 0)
+ {
+ // The private key can't be found in any key store
+ Complete(KErrPrivateKeyNotFound);
+ }
+ else
+ {
+ // OK to go ahead and add the key
+ assert(iWritableCertStore);
+ iState = EAdd;
+
+ // try to use new Add(.., TBool aDeletable, ..)
+ // if it's not supported it will return with
+ // iStatus set to KErrNotSupported
+ iWritableCertStore->Add( *iCertLabel, // call new Add() method
+ iFormat,
+ iCertificateOwnerType,
+ iSubjectKeyId,
+ iIssuerKeyId,
+ *iCertificate,
+ iDeletable, // with deletable param
+ iStatus);
+ SetActive();
+ }
+ break;
+
+ case EAdd:
+ if (iStatus!=KErrNotSupported)
+ {
+ // Set published property
+ iPSCertstoreChangePropertyRef.Set(KUnifiedCertStorePropertyCat, // category
+ EUnifiedCertStoreFlag, // key
+ 1); // value
+
+ // when here means MCTWritableCertStore was able to find
+ // child's new Add(..,aDeletable,..) method
+ // thus, ok and complete with whatever result it returned
+ Complete(iStatus.Int());
+ }
+ else
+ {
+ // here: call to the new Add() method above didn't work,
+ // try to call old Add() method
+ iState = EOldAdd;
+ iStatus = KRequestPending;
+ iWritableCertStore->Add( *iCertLabel,
+ iFormat,
+ iCertificateOwnerType,
+ iSubjectKeyId,
+ iIssuerKeyId,
+ *iCertificate,
+ iStatus);
+ SetActive();
+ }
+ break;
+
+ case EOldAdd:
+ case ERemove:
+ case ESetApplicability:
+ case ESetTrust:
+ // Set published property
+ iPSCertstoreChangePropertyRef.Set(KUnifiedCertStorePropertyCat, // category
+ EUnifiedCertStoreFlag, // key
+ 1); // value
+ Complete(iStatus.Int());
+ break;
+
+ default:
+ assert(EFalse);
+ break;
+ }
+ }
+
+void CCheckedCertStore::InitialiseKeyStoreL(TState aNextState)
+ {
+ assert(aNextState == EInitKeyStoreForAdd || aNextState == EInitKeyStoreForList);
+ assert(!iUnifiedKeyStore);
+
+ iUnifiedKeyStore = CUnifiedKeyStore::NewL(iFs);
+ iUnifiedKeyStore->Initialize(iStatus);
+ iState = aNextState;
+ SetActive();
+ }
+
+void CCheckedCertStore::BuildCheckedCertificateListL()
+ {
+ TInt certCount = iCallerCerts->Count();
+ TInt keyCount = iKeyInfos.Count();
+
+ // Iterate backwards through cert array so remove doesn't affect indicies
+ for (TInt i = certCount - 1 ; i >= 0 ; --i)
+ {
+ CCTCertInfo* certInfo = (*iCallerCerts)[i];
+
+ // It's problem in the certstore implementation if the list contains NULL pointers
+ assert(certInfo);
+
+ // Check for key with corresponding id
+ TBool accept = EFalse;
+ for (TInt j = 0 ; j < keyCount ; ++j)
+ {
+ if (iKeyInfos[j]->ID()==certInfo->SubjectKeyId())
+ {
+ accept = ETrue;
+ break;
+ }
+ }
+
+ // If we don't have it, remove and release the cert info
+ if (!accept)
+ {
+ iCallerCerts->Remove(i);
+ certInfo->Release();
+ }
+ }
+ }
+
+void CCheckedCertStore::Complete(TInt aError)
+ {
+ if (iCallerStatus)
+ {
+ User::RequestComplete(iCallerStatus, aError);
+ }
+ Cleanup();
+ }
+
+void CCheckedCertStore::Cleanup()
+ {
+ // Reset the state machine
+ iState = EIdleState;
+ iKeyInfos.Close();
+ iSubjectKeyId = NULL;
+ iIssuerKeyId = NULL;
+
+ delete iCertLabel;
+ iCertLabel = NULL;
+
+ delete iCertificate;
+ iCertificate = NULL;
+
+ delete iUnifiedKeyStore;
+ iUnifiedKeyStore = 0;
+
+ iCallerCerts = NULL;
+ iCallerFilter = NULL;
+ }