wim/WimPlugin/src/WimCertStore.cpp
changeset 0 164170e6151a
child 20 63339781d179
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wim/WimPlugin/src/WimCertStore.cpp	Tue Jan 26 15:20:08 2010 +0200
@@ -0,0 +1,2138 @@
+/*
+* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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:  Implementation of single certificate store interface
+*
+*/
+
+
+// INCLUDE FILES
+
+#include "WimCertStore.h"
+#include "WimCertConverter.h"
+#include "WimCertInfo.h"
+#include "WimTrustSettingsAPI.h"
+#include "WimTrace.h"
+#include "WimToken.h"
+#include "WimTokenListener.h"
+#include <unifiedkeystore.h>
+#include <ct.h>
+#include <x509cert.h>
+#include <x509certext.h>
+#include <wtlscert.h>
+#include <certificateapps.h>
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::CWimCertStore()
+// Default constructor
+// -----------------------------------------------------------------------------
+//
+CWimCertStore::CWimCertStore( CWimToken& aToken )
+                            : CActive( EPriorityNormal ),
+                              iToken( aToken )
+    {
+    CActiveScheduler::Add( this );
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::NewL()
+// Two-phased constructor
+// -----------------------------------------------------------------------------
+//
+CWimCertStore* CWimCertStore::NewL( CWimToken& aToken )
+    {
+    _WIMTRACE ( _L( "CWimCertStore::NewL()" ) );
+    CWimCertStore* self = new( ELeave ) CWimCertStore( aToken );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::ConstructL()
+// Instantiates converter, completes message
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::ConstructL()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::ConstructL()" ) );
+    iCWimCertConverter = CWimCertConverter::NewL( Token() );
+    // Open trust settings database
+    iCWimTrustSettingsStore = CWimTrustSettingsAPI::NewL();
+    iPhase = EIdle;
+    iPhaseOriginal = EIdle;
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::~CWimCertStore()
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CWimCertStore::~CWimCertStore()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::~CWimCertStore()" ) );
+    Cancel();
+    iKeyInfos.Close();
+    if ( iCerts )
+        {
+        delete iCerts;
+        }
+    iCertInfos.ResetAndDestroy();
+    iCertsList = NULL;
+    delete iUnifiedKeyStore;
+    if ( iCWimTrustSettingsStore )
+        {
+        iCWimTrustSettingsStore->Close();
+        }
+    iOriginalRequestStatus = NULL;
+    iFilter = NULL;
+    iEncodedCert = NULL;
+    if ( iCWimCertConverter )
+        {
+        delete iCWimCertConverter;
+        }
+
+    if ( iOldTrusters )
+        {
+        iOldTrusters->Close();
+        delete iOldTrusters;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::Token()
+// Returns a reference to current token (MCTToken) of this certificate store
+// interface. Reference is created during construction.
+// -----------------------------------------------------------------------------
+//
+MCTToken& CWimCertStore::Token()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::Token()" ) );
+    return iToken;
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::DoRelease()
+// Deletes this interface on demand.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoRelease()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoRelease()" ) );
+    delete this;
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::List()
+// Lists certificates according to filter parameter.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::List( RMPointerArray<CCTCertInfo>& aCertInfos,
+                          const CCertAttributeFilter& aFilter,
+                          TRequestStatus& aStatus )
+    {
+    _WIMTRACE ( _L( "CWimCertStore::List()" ) );
+
+    if ( !EnteringAllowed( aStatus ) )
+        {
+        return;
+        }
+
+    iCertsList = &aCertInfos;
+    iFilter = &aFilter;
+
+    if ( iFilter->iKeyUsage != EX509UsageAll )
+        {
+        // We must ensure that in this case only user certs are allowed
+        if ( iFilter->iOwnerTypeIsSet &&
+             iFilter->iOwnerType == EUserCertificate )
+            {
+            // We have to initialize the unified key store because
+            // in this phase we don't know if user certificates are found or not.
+            // User certificate private key must be checked for usage reason
+            if ( iUnifiedKeyStore )
+                {
+                User::RequestComplete( iOriginalRequestStatus, KErrCorrupt );
+                }
+            else
+                {
+                iFs = static_cast<CCTTokenType&>( Token().TokenType() ).Fs();
+                TRAPD( err, iUnifiedKeyStore = CUnifiedKeyStore::NewL( iFs ) );
+
+                if ( err != KErrNone )
+                    {
+                    User::RequestComplete( iOriginalRequestStatus, err );
+                    }
+                else
+                    {
+                    iPhase = EGetKeyInfos;
+                    iUnifiedKeyStore->Initialize( iStatus );
+                    SetActive();
+                    }
+                }
+            }
+        else
+            {
+            User::RequestComplete( iOriginalRequestStatus, KErrArgument );
+            }
+        }
+    else
+        {
+        iPhase = EList;
+        iPhaseOriginal = EList;
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete( status, KErrNone );
+        SetActive();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::CancelList()
+// Cancels issued List operation. Main functionality in DoCancel().
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::CancelList()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::CancelList()" ) );
+    if ( TokenRemoved() )
+        {
+        return;
+        }
+    Cancel();
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::GetCert()
+// Fetches one certificate info according to given handle.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::GetCert( CCTCertInfo*& aCertInfo,
+                             const TCTTokenObjectHandle& aHandle,
+                             TRequestStatus& aStatus )
+    {
+    _WIMTRACE ( _L( "CWimCertStore::GetCert()" ) );
+
+    if ( !EnteringAllowed( aStatus ) )
+        {
+        return;
+        }
+
+    if ( aHandle.iTokenHandle != Token().Handle() )
+        {
+        User::RequestComplete( iOriginalRequestStatus, KErrBadHandle );
+        }
+    else
+        {
+        iCertInfo = &aCertInfo;
+        iHandle = &aHandle;
+        iPhase = EGetCert;
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete( status, KErrNone );
+        SetActive();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::DoGetCert()
+// Fetches one certificate
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoGetCert()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoGetCert()" ) );
+
+    TInt err = KErrNotFound;
+    TRAP( err, *iCertInfo =
+            CCTCertInfo::NewL( iCerts->EntryByHandleL ( iHandle->iObjectId ) ) );
+    User::RequestComplete( iOriginalRequestStatus, err );
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::CancelGetCert()
+// Cancels issued GetCert operation. Main functionality in DoCancel().
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::CancelGetCert()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::CancelGetCert()" ) );
+    Cancel();
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::Applications()
+// Lists the applications of a certificate. Applications are represented by UIDs
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::Applications( const CCTCertInfo& aCertInfo,
+                                  RArray<TUid>& aApplications,
+                                  TRequestStatus& aStatus )
+    {
+    _WIMTRACE ( _L( "CWimCertStore::Applications()" ) );
+
+    if ( !EnteringAllowed( aStatus ) )
+        {
+        return;
+        }
+
+    iCertInfoReadOnly = &aCertInfo;
+    iApplications = &aApplications;
+    iPhase = EApplications;
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone );
+    SetActive();
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::DoApplications()
+// Fetch all certificate's applications
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoApplications()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoApplications()" ) );
+
+    TInt err = KErrNone;
+    TInt index = iCerts->Index( *iCertInfoReadOnly );
+
+    if ( index != KErrNotFound )
+        {
+        const RArray<TUid>& apps = iCerts->Mapping( index )->CertificateApps();
+        TInt end = apps.Count();
+        for ( TInt i = 0; ( i < end ) && ( err == KErrNone ); i++ )
+            {
+            err = iApplications->Append( apps[i] );
+            }
+        }
+    else
+        {
+        err = index;
+        }
+
+    if ( err != KErrNone )
+        {
+        iApplications->Reset();
+        }
+    User::RequestComplete( iOriginalRequestStatus, err );
+    }
+// -----------------------------------------------------------------------------
+// CWimCertStore::CancelApplications()
+// Cancels issued Applications operation. Main functionality in DoCancel().
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::CancelApplications()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::CancelApplications()" ) );
+    Cancel();
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::IsApplicable()
+// Checks if a particular certificate is applicable to a particular application.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::IsApplicable( const CCTCertInfo& aCertInfo,
+                                  TUid aApplication,
+                                  TBool& aIsApplicable,
+                                  TRequestStatus& aStatus )
+    {
+    _WIMTRACE ( _L( "CWimCertStore::IsApplicable()" ) );
+
+    if ( !EnteringAllowed( aStatus ) )
+        {
+        return;
+        }
+
+    iCertInfoReadOnly = &aCertInfo;
+    iApplication = aApplication;
+    iIsApplicable = &aIsApplicable;
+    iPhase = EIsApplicable;
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone );
+    SetActive();
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::DoIsApplicable()
+// Match given application to certificate's application
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoIsApplicable()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoIsApplicable()" ) );
+
+    TInt index = iCerts->Index( *iCertInfoReadOnly );
+    if ( index != KErrNotFound )
+        {
+        const RArray<TUid>& apps = iCerts->Mapping( index )->CertificateApps();
+        TInt end = apps.Count();
+        TInt i = 0;
+        for ( ; i < end; i++ )
+            {
+            if ( apps[i] == iApplication )
+                {
+                i = end + 1; // This completes loop but differentiates from
+                             // normal end condition
+                }
+            }
+        if ( i == end )
+            {
+            *iIsApplicable = EFalse;
+            }
+        else
+            {
+            *iIsApplicable = ETrue;
+            }
+        index = KErrNone;
+        }
+    User::RequestComplete( iOriginalRequestStatus, index );
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::CancelIsApplicable()
+// Cancels issued IsApplicable operation. Main functionality in DoCancel().
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::CancelIsApplicable()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::CancelIsApplicable()" ) );
+    Cancel();
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::Trusted()
+// Returns a parameter with true or false, if a certificate is trusted.
+// Trust is only meaningful for CA certificates where it means that the
+// certificate can be used as a trust root for the purposes
+// of certificate validation.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::Trusted( const CCTCertInfo& aCertInfo,
+                             TBool& aTrusted,
+                             TRequestStatus& aStatus )
+    {
+    _WIMTRACE ( _L( "CWimCertStore::Trusted()" ) );
+
+    if ( !EnteringAllowed( aStatus ) )
+        {
+        return;
+        }
+
+    iCertInfoReadOnly = &aCertInfo;
+    iTrustedCert = &aTrusted;
+    iPhase = ETrusted;
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone );
+    SetActive();
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::DoTrusted()
+// 
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoTrusted()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoTrusted()" ) );
+
+    TInt index = iCerts->Index( *iCertInfoReadOnly );
+    if ( index != KErrNotFound )
+        {
+        *iTrustedCert = iCerts->Mapping( index )->Trusted();
+        index = KErrNone;
+        }
+
+    User::RequestComplete( iOriginalRequestStatus, index );
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::CancelTrusted()
+// Cancels issued Trusted operation. Main functionality in DoCancel().
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::CancelTrusted()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::CancelTrusted()" ) );
+    Cancel();
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::Retrieve()
+// Retrieves all the data of the certificate.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::Retrieve( const CCTCertInfo& aCertInfo,
+                              TDes8& aEncodedCert,
+                              TRequestStatus& aStatus )
+    {
+    _WIMTRACE ( _L( "CWimCertStore::Retrieve()" ) );
+
+    if ( !EnteringAllowed( aStatus ) )
+        {
+        return;
+        }
+
+    iCertInfoReadOnly = &aCertInfo;
+    iEncodedCert = &aEncodedCert;
+    iPhase = ERetrieve;
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone );
+    SetActive();
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::DoRetrieve()
+// Retrieves all the data of the certificate.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoRetrieve()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoRetrieve()" ) );
+
+    // Let's get the index of certificate info
+    // Index used as handle in WimClient in order to locate this certificate
+    iCertIndex = iCerts->Index( *iCertInfoReadOnly );
+
+    if ( iCertIndex == KErrNotFound )
+        {
+        User::RequestComplete( iOriginalRequestStatus, KErrNotFound );
+        }
+    else
+        {
+        iPhase = ERetrieveFromWim;
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete( status, KErrNone );
+        SetActive();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::CancelRetrieve()
+// Cancels issued Retrieve operation and informs converter to stop.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::CancelRetrieve()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::CancelRetrieve()" ) );
+    Cancel();
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::Add()
+// Adds a certificate to the WIM store.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::Add( const TDesC& aLabel,
+                         TCertificateFormat aFormat,
+                         TCertificateOwnerType aCertificateOwnerType,
+                         const TKeyIdentifier* aSubjectKeyId,
+                         const TKeyIdentifier* aIssuerKeyId,
+                         const TDesC8& aCert,
+                         TRequestStatus& aStatus )
+    {
+    _WIMTRACE ( _L( "CWimCertStore::Add()" ) );
+
+    if ( !EnteringAllowed( aStatus ) )
+        {
+        return;
+        }
+
+    // Label must be
+    if ( aLabel.Length() == 0 )
+        {
+        User::RequestComplete( iOriginalRequestStatus, KErrArgument );
+        return;
+        }
+
+    switch ( aCertificateOwnerType )
+        {
+        case ECACertificate:
+            {
+            break;
+            }
+        case EUserCertificate:
+            {
+            break;
+            }
+        case EPeerCertificate:
+            {
+            break;
+            }
+        default:
+            {
+            User::RequestComplete( iOriginalRequestStatus, KErrArgument );
+            return;
+            }
+        }
+
+    iKeyFilter.iKeyId = KNullDesC8;
+    iKeyFilter.iUsage = ( TKeyUsagePKCS15 )0;
+    iLabel = &aLabel;
+    iFormat = aFormat;
+    iCertificateOwnerType = aCertificateOwnerType;
+
+    if ( aSubjectKeyId && ( *aSubjectKeyId != KNullDesC8 ) )
+        {
+        iSubjectKeyId = aSubjectKeyId;
+        }
+    else
+        {
+        iSubjectKeyId = 0;
+        }
+
+    iIssuerKeyId = aIssuerKeyId;
+    iCert = &aCert;
+
+    TRAPD( err, ComputeAndCheckSubjectKeyIdL() );
+
+    if ( err != KErrNone )
+        {
+        User::RequestComplete( iOriginalRequestStatus, err );
+        return;
+        }
+
+    if ( aCertificateOwnerType == EUserCertificate )
+        {
+        if ( iUnifiedKeyStore ) // Should never happen
+            {
+            User::RequestComplete( iOriginalRequestStatus, KErrCorrupt );
+            }
+        else
+            {
+            iFs = static_cast<CCTTokenType&>( Token().TokenType() ).Fs();
+
+            TRAPD( err2, iUnifiedKeyStore = CUnifiedKeyStore::NewL( iFs ) );
+            if ( err2 != KErrNone )
+                {
+                User::RequestComplete( iOriginalRequestStatus, err2 );
+                }
+            else
+                {
+                iPhase = EGetCorrespondingPrivateKey;
+                iUnifiedKeyStore->Initialize( iStatus );
+                SetActive();
+                }
+            }
+        }
+    else
+        {
+        iPhase = EAdd;
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete( status, KErrNone );
+        SetActive();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::DoAdd()
+// Adds a certificate to the WIM store.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoAdd()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoAdd()" ) );
+
+    // Check that certificate label don't already exist
+    TInt iend = iCerts->Count();
+    for ( TInt i = 0; i < iend; i++ )
+        {
+        if ( iCerts->Entry( i ).Label() == *iLabel )
+            {
+            User::RequestComplete( iOriginalRequestStatus, KErrBadName );
+            return;
+            }
+        }
+    iPhase = EAddToWim;
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone );
+    SetActive();
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::ComputeAndCheckSubjectKeyIdL()
+// Computes subject key id
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::ComputeAndCheckSubjectKeyIdL()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::ComputeAndCheckSubjectKeyIdL()" ) );
+    switch ( iFormat )
+        {
+        case EX509Certificate:
+            {
+            CX509Certificate* cert = CX509Certificate::NewLC( *iCert );
+            const CX509CertExtension* ext = cert->Extension( KKeyUsage );
+            if ( ext )
+                {
+                CX509KeyUsageExt* keyUsageExt =
+                                  CX509KeyUsageExt::NewLC( ext->Data() );
+                if ( keyUsageExt->IsSet( EX509DigitalSignature ) )
+                    {
+                    iKeyFilter.iUsage =
+                        ( TKeyUsagePKCS15 )
+                        ( iKeyFilter.iUsage | EX509UsageDigitalSignature );
+                    }
+                if ( keyUsageExt->IsSet( EX509NonRepudiation ) )
+                    {
+                    iKeyFilter.iUsage =
+                        ( TKeyUsagePKCS15 )
+                        ( iKeyFilter.iUsage | EX509UsageNonRepudiation );
+                    }
+                if ( keyUsageExt->IsSet( EX509KeyEncipherment ) )
+                    {
+                    iKeyFilter.iUsage =
+                        ( TKeyUsagePKCS15 )
+                        ( iKeyFilter.iUsage | EX509UsageKeyEncipherment );
+                    }
+                if ( keyUsageExt->IsSet( EX509DataEncipherment ) )
+                    {
+                    iKeyFilter.iUsage =
+                        ( TKeyUsagePKCS15 )
+                        ( iKeyFilter.iUsage | EX509UsageDataEncipherment );
+                    }
+                if ( keyUsageExt->IsSet( EX509KeyAgreement ) )
+                    {
+                    iKeyFilter.iUsage =
+                        ( TKeyUsagePKCS15 )
+                        ( iKeyFilter.iUsage | EX509UsageKeyAgreement );
+                    }
+                if ( keyUsageExt->IsSet( EX509KeyCertSign ) )
+                    {
+                    iKeyFilter.iUsage =
+                        ( TKeyUsagePKCS15 )
+                        ( iKeyFilter.iUsage | EX509UsageKeyCertSign );
+                    }
+                if ( keyUsageExt->IsSet( EX509CRLSign ) )
+                    {
+                    iKeyFilter.iUsage =
+                        ( TKeyUsagePKCS15 )
+                        ( iKeyFilter.iUsage | EX509UsageCRLSign );
+                    }
+                if ( keyUsageExt->IsSet( EX509EncipherOnly ) )
+                    {
+                    iKeyFilter.iUsage =
+                        ( TKeyUsagePKCS15 )
+                        ( iKeyFilter.iUsage | EX509UsageEncipherOnly );
+                    }
+                if ( keyUsageExt->IsSet( EX509DecipherOnly ) )
+                    {
+                    iKeyFilter.iUsage =
+                        ( TKeyUsagePKCS15 )
+                        ( iKeyFilter.iUsage | EX509UsageDecipherOnly );
+                    }
+
+                CleanupStack::PopAndDestroy( keyUsageExt );
+                }
+            iComputedSubjectKeyId = cert->KeyIdentifierL();
+            if ( !iSubjectKeyId )
+                {
+                iSubjectKeyId = &iComputedSubjectKeyId;
+                }
+            else if ( iComputedSubjectKeyId.Compare( *iSubjectKeyId ) )
+                {
+                User::Leave( KErrArgument );
+                }
+            CleanupStack::PopAndDestroy( cert );
+            break;
+            }
+        case EWTLSCertificate:
+            {
+            CCertificate* cert = CWTLSCertificate::NewLC( *iCert );
+            iComputedSubjectKeyId = cert->KeyIdentifierL();
+            if ( !iSubjectKeyId )
+                {
+                iSubjectKeyId = &iComputedSubjectKeyId;
+                }
+            else if ( iComputedSubjectKeyId.Compare( *iSubjectKeyId ) )
+                {
+                User::Leave( KErrArgument );
+                }
+            CleanupStack::PopAndDestroy( cert );
+            break;
+            }
+        case EX509CertificateUrl:
+            {
+            iKeyFilter.iUsage = EPKCS15UsageAll;
+            if ( !iSubjectKeyId )
+                {
+                User::Leave( KErrArgument );
+                }
+            break;
+            }
+        default:
+            {
+            User::Leave( KErrNotSupported );
+            break;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::CancelAdd()
+// Cancels issued Add operation and informs converter to stop.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::CancelAdd()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::CancelAdd()" ) );
+    Cancel();
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::Remove()
+// Removes a certificate from WIM store
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::Remove( const CCTCertInfo& aCertInfo,
+                                     TRequestStatus& aStatus )
+    {
+    _WIMTRACE ( _L( "CWimCertStore::Remove()" ) );
+
+    if ( !EnteringAllowed( aStatus ) )
+        {
+        return;
+        }
+
+    iCertInfoReadOnly = &aCertInfo;
+    iPhase = ERemove;
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone );
+    SetActive();
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::DoRemove()
+// Removes a certificate from WIM store
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoRemove()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoRemove()" ) );
+
+    TInt index = iCerts->Index( *iCertInfoReadOnly );
+    // Check that given certificate info exists
+    if ( index == KErrNotFound )
+        {
+        User::RequestComplete( iOriginalRequestStatus, KErrNotFound );
+        return;
+        }
+
+    CWimCertStoreMapping* mapping = iCerts->Mapping( index );
+
+    if ( !mapping )
+        {
+        User::RequestComplete( iOriginalRequestStatus, KErrNotFound );
+        return;
+        }
+
+    // Is certificate deletable?
+
+    const CCTCertInfo& certInfo = iCerts->Entry( index );
+
+    if ( !certInfo.IsDeletable() )
+        {
+        User::RequestComplete( iOriginalRequestStatus, KErrAccessDenied );
+        return;
+        }
+
+    // This index is used in the next phase when deleting certificate from Wim
+    iCertIndex = index;
+    iPhase = EDeleteFromWim;
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone );
+    SetActive();
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::CancelRemove()
+// Cancels ongoing certificate removal.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::CancelRemove()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::CancelRemove()" ) );
+    Cancel();
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::SetApplicability()
+// Replaces the current applicability settings with the settings
+// in the supplied array.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::SetApplicability( const CCTCertInfo& aCertInfo,
+#ifdef __SECURITY_PLATSEC_ARCH__
+                                      const RArray<TUid>& aTrusters,
+#else
+                                      RArray<TUid>* aTrusters,
+#endif
+                                      TRequestStatus& aStatus )
+    {
+    _WIMTRACE ( _L( "CWimCertStore::SetApplicability()" ) );
+
+    if ( !EnteringAllowed( aStatus ) )
+        {
+        return;
+        }
+
+    TRAPD( err, CheckApplicabilityL( aTrusters ) );
+
+    if ( err == KErrNone )
+        {
+        iCertInfoReadOnly = &aCertInfo;
+
+#ifdef __SECURITY_PLATSEC_ARCH__
+        iApplications = new RArray<TUid>;
+        if ( iApplications )
+            {
+            for ( TInt i = 0; i < aTrusters.Count(); i++ )
+                {
+                iApplications->Append( aTrusters[i] );
+                }
+            }
+        else
+            {
+            User::RequestComplete( iOriginalRequestStatus, KErrNoMemory );
+            }
+#else
+        iApplications = aTrusters;
+#endif
+
+        iPhase = ESetApplicability;
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete( status, KErrNone );
+        SetActive();
+        }
+    else
+        {
+        User::RequestComplete( iOriginalRequestStatus, err );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::DoSetApplicability()
+// Replaces the current applicability settings with the settings
+// in the supplied array.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoSetApplicability()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoSetApplicability()" ) );
+
+    TRAPD( err, DoSetApplicabilityL() );
+    if ( err != KErrNone )
+        {
+#ifdef __SECURITY_PLATSEC_ARCH__
+        iApplications->Close();
+        delete iApplications;
+        iApplications = NULL;
+#endif
+        User::RequestComplete( iOriginalRequestStatus, err );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::CheckApplicabilityL()
+// Check that given applications exist
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::CheckApplicabilityL(
+#ifdef __SECURITY_PLATSEC_ARCH__
+    const RArray<TUid>& aTrusters
+#else
+    RArray<TUid>* aTrusters
+#endif
+    )
+    {
+    _WIMTRACE ( _L( "CWimCertStore::CheckApplicabilityL()" ) );
+
+#ifndef __SECURITY_PLATSEC_ARCH__
+    TCleanupItem cleanupTrusters( CWimCertStore::CleanTrustersArray, aTrusters );
+    CleanupStack::PushL( cleanupTrusters );
+#endif
+    // Let's fetch application infos from file this device supports
+    iFs = static_cast<CCTTokenType&>( Token().TokenType() ).Fs();
+    CCertificateAppInfoManager* appInfoManager =
+                                CCertificateAppInfoManager::NewLC( iFs, EFalse );
+    // Take references to those application infos
+    const RArray<TCertificateAppInfo>& applications =
+                                       appInfoManager->Applications();
+    // Chcek that given new applications exists in supported applications
+#ifdef __SECURITY_PLATSEC_ARCH__
+    TInt count1 = aTrusters.Count();
+#else
+    TInt count1 = aTrusters->Count();
+#endif
+
+    TInt count2 = applications.Count();
+    TInt i = 0;
+    for ( ; i < count1; i++ )
+        {
+        TInt j = 0;
+        for ( ; j < count2; j++ )
+            {
+#ifdef __SECURITY_PLATSEC_ARCH__
+            if ( aTrusters[i] == applications[j].Id() ) // Match found
+#else
+            if ( ( *aTrusters)[i] == applications[j].Id() ) // Match found
+#endif
+
+                {
+                j = count2 + 1; // This stops loop but differentiates from
+                                // normal end ( j == count2 )
+                }
+            }
+        if ( j == count2 )      // Some of the given application does not exist
+            {
+            User::Leave( KErrArgument );
+            }
+        }
+
+    // Application info not needed anymore
+    CleanupStack::PopAndDestroy( appInfoManager );
+#ifndef __SECURITY_PLATSEC_ARCH__
+    CleanupStack::Pop();
+#endif
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::CleanTrustersArray()
+// Deletes array of trusters.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::CleanTrustersArray( TAny* aTrusters )
+    {
+    RArray<TUid>* array = reinterpret_cast< RArray<TUid>* >( aTrusters );
+    array->Close();
+    delete array;
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::DoSetApplicabilityL()
+// Replaces the current applicability settings with the settings
+// in the supplied array.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoSetApplicabilityL()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoSetApplicabilityL()" ) );
+
+    TCleanupItem cleanupTrusters( CWimCertStore::CleanTrustersArray, iApplications );
+    CleanupStack::PushL( cleanupTrusters );
+
+    // Check that given certificate info exists
+    TInt index = iCerts->Index( *iCertInfoReadOnly );
+    if ( index == KErrNotFound )
+        {
+        User::Leave( index );
+        }
+
+    // The idea behind next operation is to keep old applications in safe
+    // until they are succesfully replaced with given new applications
+
+    // Take a pointer to mapping
+    CWimCertStoreMapping* mapping = iCerts->Mapping( index );
+    // Check that mapping is found
+    if ( !mapping )
+        {
+        User::Leave( KErrNotFound );
+        }
+    // Take a reference to old applications
+    const RArray<TUid>& trusters = mapping->CertificateApps();
+        
+    // Copy old applications to recently created new pointer array
+    if ( iOldTrusters )
+        {
+        // There can be old trusters if next leaving function has leaved
+        // last time
+        iOldTrusters->Close();
+        delete iOldTrusters;
+        iOldTrusters = NULL;
+        }
+
+    iOldTrusters = new( ELeave ) RArray<TUid>;
+    TInt end = trusters.Count();
+    for ( TInt i = 0; i < end; i++ )
+        {
+        User::LeaveIfError( iOldTrusters->Append( trusters[i] ) );
+        }
+    // Set new applications to mapping. This replaces old ones
+    mapping->SetCertificateAppsL( iApplications );
+
+    // In this phase old applications are in oldTrusted
+    // and new applications are in mapping
+    // Now we must update TrustSettingStore to make applications permanent
+    iStatus = KRequestPending;
+    iPhase = EWaitSetApplicability;
+    iCWimTrustSettingsStore->SetApplicability( *iCertInfos[index],
+                                               *iApplications,
+                                                iStatus );
+    SetActive();
+ 
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::CancelSetApplicability()
+// Cancels an ongoing operation. The operation will be
+// completed with KErrCancel if it was cancelled
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::CancelSetApplicability()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::CancelSetApplicability()" ) );
+    Cancel();
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::SetTrust()
+// Changes the trust settings. A CA certificate is trusted if the
+// user is willing to use it for authenticating servers. It has no
+// meaning with other types of certificates.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::SetTrust( const CCTCertInfo& aCertInfo,
+                              TBool aTrusted,
+                              TRequestStatus& aStatus )
+    {
+    _WIMTRACE ( _L( "CWimCertStore::SetTrust()" ) );
+
+    if ( !EnteringAllowed( aStatus ) )
+        {
+        return;
+        }
+
+    switch ( aTrusted )
+        {
+        case EFalse:
+            {
+            break;
+            }
+        case ETrue:
+            {
+            break;
+            }
+        default:
+            {
+            User::RequestComplete( iOriginalRequestStatus, KErrArgument );
+            return;
+            }
+        }
+
+    iCertInfoReadOnly = &aCertInfo;
+    iTrustedValue = aTrusted;
+    iPhase = ESetTrust;
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone );
+    SetActive();
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::DoSetTrust()
+// Changes the trust settings.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoSetTrust()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoSetTrust()" ) );
+    TRAPD( err, DoSetTrustL() );
+    
+    if ( err != KErrNone )
+        {
+        User::RequestComplete( iOriginalRequestStatus, err );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::DoSetTrustL()
+// Changes the trust settings.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoSetTrustL()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoSetTrustL()" ) );
+    // Check that given certificate info exists
+    TInt index = iCerts->Index( *iCertInfoReadOnly );
+    if ( index == KErrNotFound )
+        {
+        User::Leave( index );
+        }
+
+    CWimCertStoreMapping* mapping = iCerts->Mapping( index );
+    // Check that mapping is found
+    if ( !mapping )
+        {
+        User::Leave( KErrNotFound );
+        }
+    // Save old trust value for back up reason
+    iOldTrusted = mapping->Trusted();
+    // Set new trust value
+    const_cast<CWimCertStoreMapping*>( mapping )->SetTrusted( iTrusted );
+    // In this phase old trust value is in iOldTrusted
+    // and new value is in mapping
+    // Now we must update TrustSettingStore to make trust value permanent
+    iPhase = EWaitSetTrust;
+    iStatus = KRequestPending;
+    iCWimTrustSettingsStore->SetTrust( *iCertInfos[index],
+                                        iTrusted,
+                                        iStatus );
+    SetActive();
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::CancelSetTrust()
+// Cancels an ongoing SetTrust operation.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::CancelSetTrust()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::CancelSetTrust()" ) );
+    Cancel();
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::RunL()
+// The first thing is to ensure that certificates are read from WIM
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::RunL()
+    {
+    _WIMTRACE3( _L( "CWimCertStore::RunL()| iStatus=%d, iPhase=%d" ), iStatus.Int(), iPhase );
+    if ( !iCerts &&
+         iPhase != EList &&
+         iPhase != EInitializeGetCertList &&
+         iPhase != EInitializeLoadMappings &&
+         iPhase != EGetKeyInfos )
+        {
+        iPhaseOriginal = iPhase;
+        iPhase = EList;
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete( status, KErrNone );
+        SetActive();
+        }
+    else
+        {
+        switch ( iPhase )
+        {
+            case EInitializeGetCertList:
+                {
+                DoInitializeGetCertListL();
+                break;
+                }
+            case EInitializeLoadMappings:
+                {
+                DoInitializeLoadMappingsL();
+                break;
+                }
+            case EInitializeLoadTrustSettingsStart:
+                {
+                DoInitializeLoadTrustSettingsStartL();
+                break;
+                }
+            case EInitializeLoadTrustSettingsWait:
+                {
+                DoInitializeLoadTrustSettingsWaitL();
+                break;
+                }
+            case EGetKeyInfos:
+                {
+                DoGetKeyInfos();
+                break;
+                }
+            case EList:
+                {
+                DoList();
+                break;
+                }
+            case EListGo:
+                {
+                DoListGoL();
+                break;
+                }
+            case EGetCert:
+                {
+                DoGetCert();
+                break;
+                }
+            case EApplications:
+                {
+                DoApplications();
+                break;
+                }
+            case EIsApplicable:
+                {
+                DoIsApplicable();
+                break;
+                }
+            case ETrusted:
+                {
+                DoTrusted();
+                break;
+                }
+            case ESetApplicability:
+                {
+                DoSetApplicability();
+                break;
+                }
+            case EWaitSetApplicability:
+                {
+                // If there is an error undo the change
+                if ( iStatus.Int() != KErrNone ) 
+                    {
+                    TInt index = iCerts->Index( *iCertInfoReadOnly );
+                    // Take a pointer to mapping
+                    CWimCertStoreMapping* mapping = iCerts->Mapping( index );
+                    // Set backed up trusters to mapping
+                    mapping->SetCertificateAppsL( iOldTrusters );
+                    iOldTrusters = NULL; // Ownership moved to mapping
+                    }
+                else // Delete old trusters array, it is not needed anymore
+                    {
+                    iOldTrusters->Close();
+                    delete iOldTrusters;
+                    iOldTrusters = NULL;
+                    }
+                User::RequestComplete( iOriginalRequestStatus, iStatus.Int() );
+                break;
+                }
+            case ESetTrust:
+                {
+                DoSetTrust();
+                break;
+                }
+            case EWaitSetTrust:
+                {
+                if ( iStatus.Int() != KErrNone )
+                    {
+                    // Couldn't add changes to file, so restore old settings
+                    TInt index = iCerts->Index( *iCertInfoReadOnly );
+                    CWimCertStoreMapping* mapping = iCerts->Mapping( index );
+                    mapping->SetTrusted( iOldTrusted );
+                    }
+                User::RequestComplete( iOriginalRequestStatus, iStatus.Int() );
+                break;
+                }
+            case ERetrieve:
+                {
+                DoRetrieve();
+                break;
+                }
+            case ERetrieveFromWim:
+                {
+                iPhase = ERetrieveWait;
+                iCWimCertConverter->RetrieveCertByIndexL( iCertIndex,
+                                                        *iEncodedCert,
+                                                         iStatus );
+                SetActive();
+                break;
+                }
+            case ERetrieveWait:
+                {
+                iPhase = EIdle;
+                User::RequestComplete( iOriginalRequestStatus, iStatus.Int() );
+                break;
+                }
+            case EGetCorrespondingPrivateKey:
+                {
+                if ( iStatus.Int() == KErrNone )
+                    {
+                    iKeyFilter.iKeyId = *iSubjectKeyId;
+                    iUnifiedKeyStore->List( iKeyInfos, iKeyFilter, iStatus );
+                    iPhase = ECheckCorrespondingPrivateKey;
+                    SetActive();
+                    }
+                else
+                    {
+                    iPhase = EIdle;
+                    User::RequestComplete( iOriginalRequestStatus, iStatus.Int() );
+                    }
+                break;
+                }
+            case ECheckCorrespondingPrivateKey:
+                {
+                DoCheckCorrespondingPrivateKey();
+                break;
+                }
+            case EAdd:
+                {
+                DoAdd();
+                break;
+                }
+            case EAddToWim:
+                {
+                iPhase = ECheckAddToWim;
+                // Update last Wim cache
+                iCWimCertConverter->AddCertificate ( *iLabel,
+                                                  iFormat,
+                                                  iCertificateOwnerType,
+                                                 *iSubjectKeyId,
+                                                 *iIssuerKeyId,
+                                                 *iCert,
+                                                  iStatus );
+                SetActive();
+                break;
+                }
+            case ECheckAddToWim:
+                {
+                if ( iStatus.Int() == KErrNone )
+                    {
+                    iPhase = EList;
+                    iPhaseOriginal = ECompleteMessage;
+                    TRequestStatus* status = &iStatus;
+                    User::RequestComplete( status, KErrNone );
+                    SetActive();
+                    }
+                else
+                    {
+                    iPhase = EIdle;
+                    User::RequestComplete( iOriginalRequestStatus, iStatus.Int() );
+                    }
+                break;
+                }
+            case ERemove:
+                {
+                DoRemove();
+                break;
+                }
+            case EDeleteFromWim:
+                {
+                iPhase = ECheckDeleteFromWim;
+                // Update Wim cache
+                iCWimCertConverter->RemoveL( iCertIndex, iStatus );
+                SetActive();
+                break;
+                }
+            case ECheckDeleteFromWim:
+                {
+                DoCheckDeleteFromWim();
+                break;
+                }
+            case EWaitRemoveTrustSettings:
+                {
+                if ( iStatus.Int() == KErrNone )
+                    {
+                    iPhase = EList;
+                    iPhaseOriginal = ECompleteMessage;
+                    TRequestStatus* status = &iStatus;
+                    User::RequestComplete( status, KErrNone );
+                    SetActive();
+                    }
+                else
+                    {
+                    iPhase = EIdle;
+                    User::RequestComplete( iOriginalRequestStatus,
+                                           iStatus.Int() );
+                    }
+                break;
+                }
+            case ECompleteMessage:
+                {
+                iPhase = EIdle;
+                User::RequestComplete( iOriginalRequestStatus, iStatus.Int() );
+                break;
+                }
+            default:
+                {
+                // Here we should not be
+                User::RequestComplete( iOriginalRequestStatus, KErrCorrupt );
+                break;
+                }
+            } // switch
+        } // if
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::DoInitializeGetCertListL()
+// Certificates are fetched from Wim
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoInitializeGetCertListL()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoInitializeGetCertListL()" ) );
+    iCertInfos.ResetAndDestroy();
+    if ( iCWimCertConverter )
+        {
+        delete iCWimCertConverter;
+        iCWimCertConverter = NULL;
+        }
+    iCWimCertConverter = CWimCertConverter::NewL( Token() );
+    iStatus = KRequestPending;
+    // Call converter to fetch certificate infos from Wim
+    iPhase = EInitializeLoadMappings;
+    iCWimCertConverter->Restore( iCertInfos, iStatus );
+    SetActive();
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::DoInitializeLoadMappingsL()
+// Load certificates into mappings
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoInitializeLoadMappingsL()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoInitializeLoadMappingsL()" ) );
+     if ( iStatus.Int() == KErrNone || iStatus.Int() == KErrNotFound )
+        {
+        // Load certificate infos into mappings
+        LoadMappingsL();
+        iCertIndex = 0;
+        if ( iCertInfos.Count() > 0 )
+            {
+            iPhase = EInitializeLoadTrustSettingsStart;
+            }
+        else
+            {
+            iPhase = EListGo;
+            }
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete( status, KErrNone );
+        SetActive();
+        }
+     else // Something went wrong with Restore or Cancel call was issued
+        {
+        FreeUnifiedKeyStore();
+        iPhase = EIdle;
+        User::RequestComplete( iOriginalRequestStatus, iStatus.Int() );
+        }
+    }
+// -----------------------------------------------------------------------------
+// void CWimCertStore::DoInitializeLoadTrustSettingsStartL()
+// Fetch trust settings for a certificate
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoInitializeLoadTrustSettingsStartL()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoInitializeLoadTrustSettingsStartL()" ) );
+    switch ( iStatus.Int() )
+        {
+        case KErrNone:
+            {
+            // Application array is created here
+            // Ownership is transferred to CWimCertStoreMapping class
+            iCertificateApps = new( ELeave ) RArray<TUid>();
+            iStatus = KRequestPending;
+            iCWimTrustSettingsStore->
+               GetTrustSettings( *iCertInfos[iCertIndex],
+                                  iTrusted,
+                                 *iCertificateApps,
+                                  iStatus );
+            iPhase = EInitializeLoadTrustSettingsWait;
+            SetActive();
+            break;
+            }
+        case KErrArgument:
+            {
+            // Certificate data was corrupted. Skip default trustsettings.
+            if ( iCertIndex < iCerts->Count() - 1 )
+                {
+                iCertIndex++;
+                iPhase = EInitializeLoadTrustSettingsStart;
+                }
+            else
+                {
+                iCertIndex = 0;
+                iPhase = EListGo;
+                }
+            TRequestStatus* status = &iStatus;
+            User::RequestComplete( status, KErrNone );
+            SetActive();
+            break;
+            }
+        default:
+            {
+            FreeUnifiedKeyStore();
+            iPhase = EIdle;
+            User::RequestComplete( iOriginalRequestStatus, iStatus.Int() );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::DoInitializeLoadTrustSettingsWaitL()
+// Check if trust settings were found, if not, do them and assign to mappings
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoInitializeLoadTrustSettingsWaitL()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoInitializeLoadTrustSettingsWaitL()" ) );
+    switch ( iStatus.Int() )
+        {
+        case KErrNone:
+            {
+            // Parameters are fetched from trust store
+            // and assigned into mapping
+            SetTrustSettingsOnMappingL( iTrusted,
+                                        iCertificateApps );
+            if ( iCertIndex < iCerts->Count() - 1 )
+                {
+                iCertIndex++;
+                iPhase = EInitializeLoadTrustSettingsStart;
+                }
+            else
+                {
+                iCertIndex = 0;
+                iPhase = EListGo;
+                }
+            TRequestStatus* status = &iStatus;
+            User::RequestComplete( status, KErrNone );
+            SetActive();
+            break;
+            }
+        case KErrNotFound: // Trust settings not found; let's do
+            {
+            iStatus = KRequestPending;
+            iCWimTrustSettingsStore->SetDefaultTrustSettings( 
+                                                        *iCertInfos[iCertIndex],
+                                                        ETrue,
+                                                        iStatus );
+            iPhase = EInitializeLoadTrustSettingsStart;
+
+            // Nobody is taking ownership of these so delete them
+            if ( iCertificateApps )
+                {
+                iCertificateApps->Close();
+                delete iCertificateApps;
+                iCertificateApps = NULL;
+                }
+
+            SetActive();
+            break;
+            }
+        default: // Something went wrong with GetTrustSettings
+                // or Cancel call was issued
+            {
+            // Nobody is taking ownership of these so delete them
+            if ( iCertificateApps )
+                {
+                iCertificateApps->Close();
+                delete iCertificateApps;
+                iCertificateApps = NULL;
+                }
+
+            FreeUnifiedKeyStore();
+            iPhase = EIdle;
+            User::RequestComplete( iOriginalRequestStatus,
+                                   iStatus.Int() );
+            break;
+            }
+        } // switch
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::DoGetKeyInfos()
+// Fetch keys from keystores
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoGetKeyInfos()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoGetKeyInfos()" ) );
+    if ( iStatus.Int() == KErrNone )
+        {
+        // In this phase key info count must allways be zero
+        if ( iKeyInfos.Count() == 0 )
+            {
+            iCertIndex = 0;
+            iKeyFilter.iKeyId = KNullDesC8;
+            iKeyFilter.iUsage =
+                KeyUsageX509ToPKCS15Private( iFilter->iKeyUsage );
+            iPhase = EList;
+            iPhaseOriginal = EList;
+            iUnifiedKeyStore->List( iKeyInfos, iKeyFilter, iStatus );
+            SetActive();
+            }
+        else
+            {
+            FreeUnifiedKeyStore();
+            iPhase = EIdle;
+            User::RequestComplete( iOriginalRequestStatus, KErrCorrupt );
+            }
+        }
+    else // Something went wrong (or call was cancelled) with
+         // iUnifiedKeyStore->Initialize( iStatus )
+        {
+        FreeUnifiedKeyStore();
+        iPhase = EIdle;
+        User::RequestComplete( iOriginalRequestStatus, iStatus.Int() );
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::DoList()
+// Start listing certificates
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoList()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoList()" ) );
+    if ( iStatus.Int() == KErrNone )
+        {
+        iCertIndex = 0;
+        iPhase = EInitializeGetCertList;
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete( status, KErrNone );
+        SetActive();
+        }
+    else // iUnifiedKeyStore->List call has been cancelled or failed
+        {
+        FreeUnifiedKeyStore();
+        iPhase = EIdle;
+        User::RequestComplete( iOriginalRequestStatus, iStatus.Int() );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::DoListGoL()
+// In this phase all certificates are fetched from Wim.
+// Serve the original request.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoListGoL()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoListGoL()" ) );
+    if ( iPhaseOriginal == EList )
+        {
+        if ( iCertIndex < ( iCerts->Count() ) )
+            {
+            const CCTCertInfo& certInfo = iCerts->Entry( iCertIndex );
+            TBool accept = ETrue;
+            if ( iFilter->iUidIsSet )
+                {
+                accept = iCerts->Mapping( iCertIndex )->
+                                 IsApplicable( iFilter->iUid );
+                }
+            if ( iFilter->iFormatIsSet && accept )
+                {
+                accept = ( iFilter->iFormat == certInfo.CertificateFormat() );
+                }
+            if ( iFilter->iOwnerTypeIsSet && accept )
+                {
+                accept = ( iFilter->iOwnerType == certInfo.CertificateOwnerType() );
+                }
+            if ( ( iFilter->iSubjectKeyId != KNullDesC8 ) && accept )
+                {
+                accept = ( iFilter->iSubjectKeyId == certInfo.SubjectKeyId() );
+                }
+            if ( ( iFilter->iIssuerKeyId != KNullDesC8 ) && accept )
+                {
+                accept = ( iFilter->iIssuerKeyId == certInfo.IssuerKeyId() );
+                }
+            if ( ( iFilter->iLabelIsSet ) && accept )
+                {
+                accept = ( iFilter->iLabel == certInfo.Label() );
+                }
+            if ( ( iFilter->iKeyUsage != EX509UsageAll ) && accept &&
+                 ( certInfo.CertificateOwnerType() == EUserCertificate) )
+                {
+                // This test must be done after we checked that
+                // the certificate owner is a user cert
+                // We must get the private key info associated with the
+                // certificate so that we know the usages
+                TInt end = iKeyInfos.Count();
+                TInt i = 0;
+                for ( ; i < end; i++ )
+                    {
+                    if ( iKeyInfos[i]->ID() == certInfo.SubjectKeyId() )
+                        {
+                        i = end + 1; // This completes loop and
+                                     // differentiates from normal
+                                    // ending (i == end)
+                        }
+                    }
+                if ( i == end )
+                    {
+                    accept = EFalse;
+                    }
+                }
+
+            if ( accept )
+                {
+                // Here is done another copy of certificate for
+                // application needs
+                CCTCertInfo* copy = CCTCertInfo::NewLC( certInfo );
+                User::LeaveIfError( iCertsList->Append( copy ) );
+                CleanupStack::Pop( copy );
+                }
+
+            // iCertIndex is initialized in EList/KErrNone
+            iCertIndex++;
+
+            // Poll status in order to give time for other aos
+            TRequestStatus* status = &iStatus;
+            User::RequestComplete( status, KErrNone );
+            SetActive();
+            } // if ( iCertIndex...
+        else
+            {
+            // All certificates are listed or there are not any
+            iKeyInfos.Close();
+            delete iUnifiedKeyStore;
+            iUnifiedKeyStore = NULL;
+            iPhase = EIdle;
+            User::RequestComplete( iOriginalRequestStatus, KErrNone );
+            }
+        }
+    else
+        {
+        iPhase = iPhaseOriginal;
+        iPhaseOriginal = EIdle;
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete( status, KErrNone );
+        SetActive();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::DoCheckCorrespondingPrivateKey()
+// Check if private key is found for user certificate
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoCheckCorrespondingPrivateKey()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoCheckCorrespondingPrivateKey()" ) );
+    if ( iStatus.Int() == KErrNone )
+        {
+        if ( ( iKeyInfos.Count() == 0 ) ||
+           ( ( iFormat != EX509CertificateUrl ) &&
+             ( iKeyInfos[0]->Usage() != iKeyFilter.iUsage ) ) )
+            {
+            // The private key can't be found in any key store,
+            // so we must return an error
+            iPhase = EIdle;
+            User::RequestComplete( iOriginalRequestStatus, KErrArgument );
+            }
+        else
+            {
+            //
+            iPhase = EAdd;
+            TRequestStatus* status = &iStatus;
+            User::RequestComplete( status, KErrNone );
+            SetActive();
+            }
+        }
+    else
+        {
+        iPhase = EIdle;
+        User::RequestComplete( iOriginalRequestStatus, iStatus.Int() );
+        }
+    iKeyInfos.Close();
+    delete iUnifiedKeyStore;
+    iUnifiedKeyStore = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::DoCheckDeleteFromWim()
+// If delete from Wim succeeded, continue deleting from trust setting store
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoCheckDeleteFromWim()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoCheckDeleteFromWim()" ) );
+    if ( iStatus.Int() == KErrNone )
+        {
+        iStatus = KRequestPending;
+        iPhase = EWaitRemoveTrustSettings;
+        iCWimTrustSettingsStore->RemoveTrustSettings(
+                                            *iCertInfos[iCertIndex], iStatus );
+        SetActive();
+        }
+    else
+        {
+        iPhase = EIdle;
+        User::RequestComplete( iOriginalRequestStatus, iStatus.Int() );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::FreeUnifiedKeyStore()
+// Frees key storage resources.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::FreeUnifiedKeyStore()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::FreeUnifiedKeyStore()" ) );
+    if ( iUnifiedKeyStore )
+        {
+        iKeyInfos.Close();
+        delete iUnifiedKeyStore;
+        iUnifiedKeyStore = NULL;
+        iCertsList->Reset();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::RunError()
+// Unexpected error in RunL (e.g. Leave) leads us here.
+// -----------------------------------------------------------------------------
+//
+TInt CWimCertStore::RunError( TInt aError )
+    {
+    _WIMTRACE ( _L( "CWimCertStore::RunError()" ) );
+
+    FreeUnifiedKeyStore();
+    iPhase = EIdle;
+    User::RequestComplete( iOriginalRequestStatus, aError );
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::DoCancel()
+// Cancels current operation.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::DoCancel()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::DoCancel()" ) );
+
+    if ( iUnifiedKeyStore )
+        {
+        switch ( iPhase )
+            {
+            case EGetKeyInfos:
+                {
+                if ( iUnifiedKeyStore->IsActive() )
+                    {
+                    iUnifiedKeyStore->CancelInitialize();
+                    }
+                break;
+                }
+            case EList:
+                {
+                if ( iUnifiedKeyStore->IsActive() )
+                    {
+                    iUnifiedKeyStore->CancelList();
+                    }
+                break;
+                }
+            default:
+                {
+                // Other phases won't cause any action
+                break;
+                }
+            }
+        }
+
+    if ( iCWimCertConverter )
+        {
+        switch ( iPhase )
+            {
+            case EInitializeLoadMappings:
+                {
+                if ( iCWimCertConverter->IsActive() )
+                    {
+                    iCWimCertConverter->CancelRestore();
+                    delete iCWimCertConverter;
+                    iCWimCertConverter = NULL;
+                    }
+                break;
+                }
+            case ERetrieveWait:
+                {
+                if ( iCWimCertConverter->IsActive() )
+                    {
+                    iCWimCertConverter->CancelRetrieve();
+                    delete iCWimCertConverter;
+                    iCWimCertConverter = NULL;
+                    }
+                break;
+                }
+            case ECheckAddToWim:
+                {
+                if ( iCWimCertConverter->IsActive() )
+                    {
+                    iCWimCertConverter->CancelAddCertificate();
+                    delete iCWimCertConverter;
+                    iCWimCertConverter = NULL;
+                    }
+                break;
+                }
+            case ECheckDeleteFromWim:
+                {
+                if ( iCWimCertConverter->IsActive() )
+                    {
+                    iCWimCertConverter->CancelRemove();
+                    delete iCWimCertConverter;
+                    iCWimCertConverter = NULL;
+                    }
+                break;
+                }
+            default:
+                {
+                // Other phases won't cause any action
+                break;
+                }
+            }
+        }
+
+    if ( iCWimTrustSettingsStore )
+        {
+        switch ( iPhase )
+            {
+            case EInitializeLoadTrustSettingsStart:
+                {
+                if ( iCWimTrustSettingsStore->IsActive() )
+                    {
+                    iCWimTrustSettingsStore->CancelDoing();
+                    }
+                break;
+                }
+            default:
+                {
+                // Other phases won't cause any action
+                break;
+                }
+            }
+        }
+
+    if ( iCerts )
+        {
+        delete iCerts;
+        iCerts = NULL;
+        }
+
+    if ( iPhase == EInitializeLoadTrustSettingsWait )
+        {
+        // Nobody is taking ownership of these so delete them
+        iCertificateApps->Close();
+        delete iCertificateApps;
+        }
+
+    FreeUnifiedKeyStore();
+    iPhase = EIdle;
+    User::RequestComplete( iOriginalRequestStatus, KErrCancel );
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::LoadMappingsL()
+// In this phase we have retrieved certificate infos from WimClient and they
+// are in the iCertInfos array. This methdod creates iCerts array
+// and loads those certificates into it. Trust settings are updated in the next
+// phase.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::LoadMappingsL()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::LoadMappingsL()" ) );
+    if ( iCerts )
+        {
+        delete iCerts;
+        iCerts = NULL;
+        }
+    // Create a manager class for mapping entries
+    iCerts = CWimCertStoreMappings::NewL();
+    TInt count = iCertInfos.Count();
+    // Go through all certificates and insert them into a mapping array
+    for ( TInt i = 0; i < count; i++ )
+        {
+        CWimCertStoreMapping* certMapping = CWimCertStoreMapping::NewL();
+        CleanupStack::PushL( certMapping );
+        // Ownership moves to CWimCertStoreMapping
+        CCTCertInfo* certInfo = ( CCTCertInfo* )( iCertInfos )[i]->CctCert();
+        certMapping->SetEntryL( certInfo );
+        // Set default applications. This object must not push to cleanupstack
+        // because on leave at AddL this object is deleted in association with
+        // certMapping
+        RArray<TUid>* certificateApps = new( ELeave ) RArray<TUid>();
+        certMapping->SetCertificateAppsL( certificateApps );
+        // Set default
+        certMapping->SetTrusted( ETrue );
+        // Append mapping pointer to pointer array
+        iCerts->AddL( certMapping );
+        CleanupStack::Pop( certMapping );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// void CWimCertStore::SetTrustSettingsOnMappingL()
+// If certificate has no trust settings and there should be,
+// here they are updated. This method sets applications and trusted
+// information into mapping entry.
+// -----------------------------------------------------------------------------
+//
+void CWimCertStore::SetTrustSettingsOnMappingL( TBool aTrusted,
+                                                RArray<TUid>* aApplications )
+    {
+    _WIMTRACE ( _L( "CWimCertStore::SetTrustSettingsOnMappingL()" ) );
+    // Take a pointer to mapping
+    CWimCertStoreMapping* mapping = iCerts->Mapping( iCertIndex );
+    // Check that mapping is found
+    if ( !mapping )
+        {
+        User::Leave( KErrNotFound );
+        }
+    // Ownership is changed here:
+    // iCertificateApps is not any more responsible for this array.
+    mapping->SetCertificateAppsL( aApplications );
+    mapping->SetTrusted( aTrusted );
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::EnteringAllowed()
+// Check if token is removed and if this ao is active.
+// -----------------------------------------------------------------------------
+//
+TBool CWimCertStore::EnteringAllowed( TRequestStatus& aStatus )
+    {
+    _WIMTRACE ( _L( "CWimCertStore::EnteringAllowed()" ) );
+    if ( TokenRemoved() )
+        {
+        TRequestStatus* status = &aStatus;
+        User::RequestComplete( status, KErrHardwareNotAvailable );
+        return EFalse;
+        }
+
+    // If this active object is in running, don't accept entering
+    if ( IsActive() )
+        {
+        // If the caller status is the same as the status, that activated
+        // this object, just return
+        if ( &aStatus == iOriginalRequestStatus )
+            {
+            return EFalse;
+            }
+        else
+            {
+            // Otherwise complete it with error
+            TRequestStatus* status = &aStatus;
+            User::RequestComplete( status, KErrInUse );
+            return EFalse;
+            }
+        }
+    else
+        {
+        iOriginalRequestStatus = &aStatus;
+        aStatus = KRequestPending;
+        return ETrue;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CWimCertStore::TokenRemoved()
+// Returns true or false indicating if token is removed
+// -----------------------------------------------------------------------------
+//
+TBool CWimCertStore::TokenRemoved()
+    {
+    _WIMTRACE ( _L( "CWimCertStore::TokenRemoved()" ) );
+    // If token listener is not alive, then token is removed
+    if ( iToken.TokenListener()->TokenStatus() != KRequestPending )
+        {
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }
+    }