diff -r 000000000000 -r 164170e6151a wim/WimPlugin/src/WimCertStore.cpp --- /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 +#include +#include +#include +#include +#include + +// ============================ 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& 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( 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& 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& 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& 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( 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& aTrusters, +#else + RArray* 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; + 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& aTrusters +#else + RArray* 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( Token().TokenType() ).Fs(); + CCertificateAppInfoManager* appInfoManager = + CCertificateAppInfoManager::NewLC( iFs, EFalse ); + // Take references to those application infos + const RArray& 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* array = reinterpret_cast< RArray* >( 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& 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; + 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( 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(); + 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* certificateApps = new( ELeave ) RArray(); + 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* 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; + } + }