cryptoservices/certificateandkeymgmt/certstore/CCheckedCertStore.cpp
changeset 8 35751d3474b7
parent 0 2c201484c85f
--- a/cryptoservices/certificateandkeymgmt/certstore/CCheckedCertStore.cpp	Tue Jul 21 01:04:32 2009 +0100
+++ b/cryptoservices/certificateandkeymgmt/certstore/CCheckedCertStore.cpp	Thu Sep 10 14:01:51 2009 +0300
@@ -1,786 +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;
-    }
+/*
+* 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;
+    }