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