--- a/cryptoservices/certificateandkeymgmt/certstore/unifiedkeystore.cpp Tue Jul 21 01:04:32 2009 +0100
+++ b/cryptoservices/certificateandkeymgmt/certstore/unifiedkeystore.cpp Thu Sep 10 14:01:51 2009 +0300
@@ -1,1121 +1,1233 @@
-/*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-
-
-#include "unifiedkeystore.h"
-#include <ecom.h>
-#include <random.h>
-#include <pbedata.h>
-#include <asnpkcs.h>
-
-_LIT(KUnifiedKeyStore, "UnifiedKeyStore");
-
-/////////////////////////////////////////////////////////////////////////////////////
-//CUnifiedKeyStore
-/////////////////////////////////////////////////////////////////////////////////////
-
-EXPORT_C CUnifiedKeyStore* CUnifiedKeyStore::NewL(RFs& aFs)
- {
- CUnifiedKeyStore* self = CUnifiedKeyStore::NewLC(aFs);
- CleanupStack::Pop(self);
- return self;
- }
-
-EXPORT_C CUnifiedKeyStore* CUnifiedKeyStore::NewLC(RFs& aFs)
- {
- CUnifiedKeyStore* self = new(ELeave) CUnifiedKeyStore(aFs);
- CleanupStack::PushL(self);
- self->ConstructL();
- return self;
- }
-
-EXPORT_C CUnifiedKeyStore::~CUnifiedKeyStore()
- {
- Cancel();
- Cleanup();
-
- iKeyStoresHolder.ResetAndDestroy();
- iKeyStoresHolder.Close();
-
- REComSession::FinalClose();
- }
-
-void CUnifiedKeyStore::DoInitializeL()
-{// We want the list of all token types that support a keystore interface
- RArray<TUid> uidArray;
- CleanupClosePushL(uidArray);
-
- User::LeaveIfError(uidArray.Append(TUid::Uid(KInterfaceKeyStore)));
-
- TCTFindTokenTypesByInterface filter(uidArray.Array());
- CCTTokenTypeInfo::ListL(iTokenTypes, filter);
-
- CleanupStack::PopAndDestroy(); // uidArray
-}
-
-EXPORT_C void CUnifiedKeyStore::Initialize(TRequestStatus& aStatus)
-{// The following assertion checks that we didn't call Initialize twice
- __ASSERT_DEBUG((iKeyStoresHolder.Count()==0), User::Panic(KUnifiedKeyStore, EUnexpectedInitialise));
-
- TRAPD(err, DoInitializeL());
- if (err != KErrNone)
- {
- TRequestStatus* status = &aStatus;
- User::RequestComplete(status, err);
- return;
- }
-
- iIndexTokenTypes = -1;
- StartAsyncOperation(EInitializeGetTokenList, aStatus);
-
- SetActive();
- TRequestStatus* status = &iStatus;
- User::RequestComplete(status, KErrNone);
-}
-
-EXPORT_C void CUnifiedKeyStore::CancelInitialize()
- {
- if (iState == EInitializeGetTokenList ||
- iState == EInitializeGetToken ||
- iState == EInitialiseGetKeyManagerInterface ||
- iState == EInitializeGetKeyUserInterface ||
- iState == EInitializeGetKeyUserInterfaceFinished ||
- iState == EInitializeFinished)
- {
- Cancel();
- }
- }
-
-EXPORT_C void CUnifiedKeyStore::CreateKey(TInt aKeyStoreIndex, TKeyUsagePKCS15 aUsage,TUint aSize,
- const TDesC& aLabel, CCTKeyInfo::EKeyAlgorithm aAlgorithm,
- TInt aAccessType, TTime aStartDate, TTime aEndDate,
- CCTKeyInfo*& aKeyInfoOut, TRequestStatus& aStatus)
- {
- StartAsyncOperation(ECreateKey, aStatus);
- TRAPD(err, PrepareToCreateKeyL(aKeyStoreIndex, aUsage, aSize, aLabel, aAlgorithm, aAccessType,
- aStartDate, aEndDate, aStatus));
- if (KErrNone != err)
- {
- Complete(err);
- return;
- }
-
- iKeyInfoOut = &aKeyInfoOut;
- aKeyInfoOut = NULL;
- iKeyStoreManager->CreateKey(iKeyInfo, iStatus);
- SetActive();
- }
-
-EXPORT_C void CUnifiedKeyStore::CancelCreateKey()
- {
- if (iState == ECreateKey)
- {
- Cancel();
- }
- }
-
-EXPORT_C void CUnifiedKeyStore::ImportKey(TInt aKeyStoreIndex, const TDesC8& aKeyData,
- TKeyUsagePKCS15 aUsage, const TDesC& aLabel,
- TInt aAccessType, TTime aStartDate, TTime aEndDate,
- CCTKeyInfo*& aKeyInfoOut, TRequestStatus& aStatus)
- {
- TBool isEncrypted = TASN1DecPKCS8::IsEncryptedPKCS8Data(aKeyData);
- StartAsyncOperation(isEncrypted ? EImportKeyEncrypted : EImportKey, aStatus);
-
- ASSERT(!iKeyData);
- iKeyData = aKeyData.Alloc();
- if (!iKeyData) // OOM or some other catastrophe
- {
- Complete(KErrNoMemory);
- return;
- }
-
- TRAPD(err, PrepareToCreateKeyL(aKeyStoreIndex, aUsage, 0, aLabel, CCTKeyInfo::EInvalidAlgorithm, aAccessType,
- aStartDate, aEndDate, aStatus));
- if (KErrNone != err)
- {
- Complete(err);
- return;
- }
-
- iKeyInfoOut = &aKeyInfoOut;
- aKeyInfoOut = NULL;
-
- if (isEncrypted)
- {
- iKeyStoreManager->ImportEncryptedKey(*iKeyData, iKeyInfo, iStatus);
- }
- else
- {
- iKeyStoreManager->ImportKey(*iKeyData, iKeyInfo, iStatus);
- }
- SetActive();
- }
-
-EXPORT_C void CUnifiedKeyStore::CancelImportKey()
- {
- if (iState == EImportKey ||
- iState == EImportKeyEncrypted)
- {
- Cancel();
- }
- }
-
-void CUnifiedKeyStore::PrepareToCreateKeyL( TInt aKeyStoreIndex,
- TKeyUsagePKCS15 aUsage, TUint aSize,
- const TDesC& aLabel,
- CCTKeyInfo::EKeyAlgorithm aAlgorithm,
- TInt aAccessType,
- TTime aStartTime, TTime aEndTime,
- TRequestStatus& aStatus)
- {
- ASSERT(!iKeyStoreManager);
-
- // These values are filled in by the server when the key is created
- TKeyIdentifier keyID;
- keyID.MaxSize();
- keyID.FillZ(keyID.MaxSize());
- TInt keyHandle = 0;
-
- // Get the secure ID of the current process
- RProcess thisProcess;
- User::LeaveIfError(thisProcess.Open(thisProcess.Id()));
- TSecureId creatorId = thisProcess.SecureId();
- thisProcess.Close();
-
- // Default management policy: resict to creating process
- TSecurityPolicy managementPolicy(creatorId);
-
- // Default use policy: also resict to creating process
- TSecurityPolicy usePolicy(creatorId);
-
- HBufC* label = aLabel.AllocLC();
-
- // Panics if keystore manager index invalid
- MCTKeyStoreManager& keystore = KeyStoreManager(aKeyStoreIndex);
-
- iKeyInfo = CCTKeyInfo::NewL(keyID, aUsage, aSize, NULL, label, keystore.Token(),
- keyHandle, usePolicy, managementPolicy, aAlgorithm,
- aAccessType, ETrue, aStartTime, aEndTime);
- CleanupStack::Pop(label);
-
- iKeyStoreManager = &keystore;
- iOriginalRequestStatus = &aStatus;
- aStatus = KRequestPending;
- }
-
-// ************************************************************************
-// MKeyStore
-// ************************************************************************
-
-void CUnifiedKeyStore::List(RMPointerArray<CCTKeyInfo>& aKeys,
- const TCTKeyAttributeFilter& aFilter,
- TRequestStatus& aStatus)
- {
- StartAsyncOperation(EList, aStatus);
-
- iKeyInfos = &aKeys;
-
- delete iFilter;
- iFilter = new TCTKeyAttributeFilter(aFilter);
- if (!iFilter)
- {
- Complete(KErrNoMemory);
- return;
- }
-
- iIndex = -1;
-
- SetActive();
- TRequestStatus* status = &iStatus;
- User::RequestComplete(status, KErrNone);
-}
-
-void CUnifiedKeyStore::CancelList()
- {
- if (iState == EList)
- {
- Cancel();
- }
- }
-
-void CUnifiedKeyStore::GetKeyInfo(TCTTokenObjectHandle aHandle,
- CCTKeyInfo*& aKeyInfo,
- TRequestStatus& aStatus)
- {
- StartAsyncOperation(EGetKeyInfo, aStatus);
-
- ASSERT(!iKeyStore);
- iKeyStore = FindKeyStore(aHandle);
- if (!iKeyStore)
- {
- Complete(KErrNotFound);
- return;
- }
-
- iKeyStore->GetKeyInfo(aHandle, aKeyInfo, iStatus);
- SetActive();
- }
-
-void CUnifiedKeyStore::CancelGetKeyInfo()
- {
- if (iState == EGetKeyInfo)
- {
- Cancel();
- }
- }
-
-// Implementation for most of the Open() method
-TBool CUnifiedKeyStore::DoOpen(const TCTTokenObjectHandle& aHandle,
- TRequestStatus& aStatus)
- {
- StartAsyncOperation(EOpen, aStatus);
-
- ASSERT(!iKeyStore);
- iKeyStore = FindKeyStore(aHandle);
- if (!iKeyStore)
- {
- Complete(KErrNotFound);
- return EFalse;
- }
-
- SetActive();
- return ETrue;
- }
-
-void CUnifiedKeyStore::Open(const TCTTokenObjectHandle& aHandle,
- MRSASigner*& aSigner,
- TRequestStatus& aStatus)
- {
- if (DoOpen(aHandle, aStatus))
- {
- iKeyStore->Open(aHandle, aSigner, iStatus);
- }
- }
-
-void CUnifiedKeyStore::Open(const TCTTokenObjectHandle& aHandle,
- MDSASigner*& aSigner,
- TRequestStatus& aStatus)
- {
- if (DoOpen(aHandle, aStatus))
- {
- iKeyStore->Open(aHandle, aSigner, iStatus);
- }
- }
-
-void CUnifiedKeyStore::Open(const TCTTokenObjectHandle& aHandle,
- MCTDecryptor*& aDecryptor,
- TRequestStatus& aStatus)
- {
- if (DoOpen(aHandle, aStatus))
- {
- iKeyStore->Open(aHandle, aDecryptor, iStatus);
- }
- }
-
-void CUnifiedKeyStore::Open(const TCTTokenObjectHandle& aHandle,
- MCTDH*& aDH, TRequestStatus& aStatus)
- {
- if (DoOpen(aHandle, aStatus))
- {
- iKeyStore->Open(aHandle, aDH, iStatus);
- }
- }
-
-void CUnifiedKeyStore::CancelOpen()
- {
- if (iState == EOpen)
- {
- Cancel();
- }
- }
-
-/** Returns the public key in DER-encoded ASN-1 */
-void CUnifiedKeyStore::ExportPublic(const TCTTokenObjectHandle& aHandle,
- HBufC8*& aPublicKey,
- TRequestStatus& aStatus)
- {
- StartAsyncOperation(EExportPublic, aStatus);
-
- iKeyStore = FindKeyStore(aHandle);
- if (!iKeyStore)
- {
- Complete(KErrNotFound);
- return;
- }
-
- iKeyStore->ExportPublic(aHandle, aPublicKey, iStatus);
- SetActive();
- }
-
-void CUnifiedKeyStore::CancelExportPublic()
- {
- if (iState == EExportPublic)
- {
- Cancel();
- }
- }
-
-// ************************************************************************
-// MKeyStoreManager
-// ************************************************************************
-
-EXPORT_C void CUnifiedKeyStore::ExportKey(TCTTokenObjectHandle aHandle,
- HBufC8*& aKey, TRequestStatus& aStatus)
- {
- StartAsyncOperation(EExportKey, aStatus);
-
- ASSERT(!iKeyStoreManager);
- iKeyStoreManager = FindKeyStoreManager(aHandle);
- if (!iKeyStoreManager)
- {
- Complete(KErrNotFound);
- return;
- }
-
- iKeyStoreManager->ExportKey(aHandle, aKey, iStatus);
- SetActive();
- }
-
-EXPORT_C void CUnifiedKeyStore::CancelExportKey()
- {
- if (iState == EExportKey)
- {
- Cancel();
- }
- }
-
-EXPORT_C void CUnifiedKeyStore::ExportEncryptedKey(TCTTokenObjectHandle aHandle,
- const CPBEncryptParms& aEncryptParams,
- HBufC8*& aKey, TRequestStatus& aStatus)
- {
- StartAsyncOperation(EExportEncryptedKey, aStatus);
-
- ASSERT(!iKeyStoreManager);
- iKeyStoreManager = FindKeyStoreManager(aHandle);
- if (!iKeyStoreManager)
- {
- Complete(KErrNotFound);
- return;
- }
-
- iKeyStoreManager->ExportEncryptedKey(aHandle, aEncryptParams, aKey, iStatus);
- SetActive();
- }
-
-EXPORT_C void CUnifiedKeyStore::CancelExportEncryptedKey()
- {
- if (iState == EExportEncryptedKey)
- {
- Cancel();
- }
- }
-
-EXPORT_C void CUnifiedKeyStore::DeleteKey(TCTTokenObjectHandle aHandle,
- TRequestStatus& aStatus)
- {
- StartAsyncOperation(EDeleteKey, aStatus);
-
- iKeyStoreManager = FindKeyStoreManager(aHandle);
- if (!iKeyStoreManager)
- {
- Complete(KErrNotFound);
- return;
- }
-
- iKeyStoreManager->DeleteKey(aHandle, iStatus);
- SetActive();
- }
-
-EXPORT_C void CUnifiedKeyStore::CancelDeleteKey()
- {
- if (iState == EDeleteKey)
- {
- Cancel();
- }
- }
-
-EXPORT_C void CUnifiedKeyStore::SetUsePolicy(TCTTokenObjectHandle aHandle,
- const TSecurityPolicy& aPolicy,
- TRequestStatus& aStatus)
- {
- StartAsyncOperation(ESetUsePolicy, aStatus);
-
- iKeyStoreManager = FindKeyStoreManager(aHandle);
- if (!iKeyStoreManager)
- {
- Complete(KErrNotFound);
- return;
- }
-
- iKeyStoreManager->SetUsePolicy(aHandle, aPolicy, iStatus);
- SetActive();
- }
-
-EXPORT_C void CUnifiedKeyStore::CancelSetUsePolicy()
- {
- if (iState == ESetUsePolicy)
- {
- Cancel();
- }
- }
-
-EXPORT_C void CUnifiedKeyStore::SetManagementPolicy(TCTTokenObjectHandle aHandle,
- const TSecurityPolicy& aPolicy,
- TRequestStatus& aStatus)
- {
- StartAsyncOperation(ESetManagementPolicy, aStatus);
-
- iKeyStoreManager = FindKeyStoreManager(aHandle);
- if (!iKeyStoreManager)
- {
- Complete(KErrNotFound);
- return;
- }
-
- iKeyStoreManager->SetManagementPolicy(aHandle, aPolicy, iStatus);
- SetActive();
- }
-
-EXPORT_C void CUnifiedKeyStore::CancelSetManagementPolicy()
- {
- if (iState == ESetManagementPolicy)
- {
- Cancel();
- }
- }
-
-EXPORT_C void CUnifiedKeyStore::SetPassphraseTimeout(TInt aTimeout,
- TRequestStatus& aStatus)
- {
- StartAsyncOperation(ESetPassphraseTimeout, aStatus);
-
- iIndex = -1;
- iNewTimeout = aTimeout;
- SetActive();
-
- TRequestStatus* status = &iStatus;
- User::RequestComplete(status, KErrNone);
- }
-
-EXPORT_C void CUnifiedKeyStore::CancelSetPassphraseTimeout()
- {
- if (iState == ESetPassphraseTimeout)
- {
- Cancel();
- }
- }
-
-EXPORT_C void CUnifiedKeyStore::Relock(TRequestStatus& aStatus)
- {
- StartAsyncOperation(ERelock, aStatus);
-
- iIndex = -1;
- SetActive();
-
- TRequestStatus* status = &iStatus;
- User::RequestComplete(status, KErrNone);
- }
-
-EXPORT_C void CUnifiedKeyStore::CancelRelock()
- {
- if (iState == ERelock)
- {
- Cancel();
- }
- }
-
-// ************************************************************************
-// Other exports
-// ************************************************************************
-
-EXPORT_C TInt CUnifiedKeyStore::KeyStoreCount() const
-{
- return (iKeyStoresHolder.Count());
-}
-
-EXPORT_C MCTKeyStore& CUnifiedKeyStore::KeyStore(TInt aIndex)
-{
- __ASSERT_ALWAYS(aIndex >= 0 && aIndex < iKeyStoresHolder.Count(),
- User::Panic(KUnifiedKeyStore, EArrayAccessOutOfBounds));
-
- MCTKeyStore* keyStore = static_cast<MCTKeyStore*>(iKeyStoresHolder[aIndex]->KeyStore());
- return (*keyStore);
-}
-
-EXPORT_C TInt CUnifiedKeyStore::KeyStoreManagerCount() const
- {
- TInt result = 0;
- for (TInt i = 0 ; i < iKeyStoresHolder.Count() ; ++i)
- {
- if (iKeyStoresHolder[i]->IsKeyManager())
- {
- ++result;
- }
- }
- return result;
- }
-
-EXPORT_C MCTKeyStoreManager& CUnifiedKeyStore::KeyStoreManager(TInt aIndex)
- {
- __ASSERT_ALWAYS(aIndex >= 0, User::Panic(KUnifiedKeyStore, EArrayAccessOutOfBounds));
- TInt managerIndex = 0;
- MCTKeyStoreManager* result = NULL;
- for (TInt i = 0 ; i < iKeyStoresHolder.Count() ; ++i)
- {
- if (iKeyStoresHolder[i]->IsKeyManager())
- {
- if (managerIndex == aIndex)
- {
- result = static_cast<MCTKeyStoreManager*>(iKeyStoresHolder[i]->KeyStore());
- break;
- }
- ++managerIndex;
- }
- }
- __ASSERT_ALWAYS(result != NULL, User::Panic(KUnifiedKeyStore, EArrayAccessOutOfBounds));
- return *result;
- }
-
-CUnifiedKeyStore::CUnifiedKeyStore(RFs& aFs)
- : CActive(EPriorityNormal), iFs(aFs), iState(EIdle)
-{// Currently defaults to always try for key store manager interface
-// This may change (add parameter to NewL for required interface)
- iRequestUid.iUid = KInterfaceKeyStoreManager;
- CActiveScheduler::Add(this);
-}
-
-void CUnifiedKeyStore::ConstructL()
-{}
-
-void CUnifiedKeyStore::StartAsyncOperation(TState aState, TRequestStatus& aStatus)
- {
- ASSERT(iState == EIdle);
- ASSERT(iOriginalRequestStatus == NULL);
- iState = aState;
- iOriginalRequestStatus = &aStatus;
- aStatus = KRequestPending;
- }
-
-MCTKeyStore* CUnifiedKeyStore::FindKeyStore(const TCTTokenObjectHandle& aHandle)
- {
- for (TInt index = 0 ; index < iKeyStoresHolder.Count() ; ++index)
- {
- MCTTokenInterface* store = iKeyStoresHolder[index]->KeyStore();
- ASSERT(store);
- if (store->Token().Handle() == aHandle.iTokenHandle)
- {
- return static_cast<MCTKeyStoreManager*>(store);
- }
- }
- return NULL;
- }
-
-MCTKeyStoreManager* CUnifiedKeyStore::FindKeyStoreManager(const TCTTokenObjectHandle& aHandle)
- {
- for (TInt index = 0 ; index < iKeyStoresHolder.Count() ; ++index)
- {
- MCTTokenInterface* store = iKeyStoresHolder[index]->KeyStore();
- ASSERT(store);
- if (store->Token().Handle() == aHandle.iTokenHandle && iKeyStoresHolder[index]->IsKeyManager())
- {
- return static_cast<MCTKeyStoreManager*>(store);
- }
- }
- return NULL;
- }
-
-void CUnifiedKeyStore::RunL()
-{
- if (EInitializeGetKeyUserInterfaceFinished != iState &&
- EInitializeGetKeyUserInterface != iState &&
- EInitializeGetToken != iState)
- {
- User::LeaveIfError(iStatus.Int());
- }
-
- switch (iState)
- {
- case EInitializeGetTokenList:
- {// Try to get a list of Tokens for each of the Token Types
- iIndexTokenTypes++;
- if (iIndexTokenTypes < iTokenTypes.Count())
- {
- __ASSERT_DEBUG(!iTokenType, User::Panic(KUnifiedKeyStore, EArrayAccessOutOfBounds));
- iTokenType = MCTTokenType::NewL(*iTokenTypes[iIndexTokenTypes], iFs);
- __ASSERT_DEBUG(iTokens.Count()==0, User::Panic(KUnifiedKeyStore, ETokensArrayAlreadyInUse));
- iTokenType->List(iTokens, iStatus);
- iIndexTokens = -1;
- iState = EInitializeGetToken;
- }
- else
- {// We don't need the list of Token Types anymore
- iTokenTypes.ResetAndDestroy();
- iTokenTypes.Close();
- iState = EInitializeFinished;
- TRequestStatus* status = &iStatus;
- User::RequestComplete(status, KErrNone);
- }
- SetActive();
- break;
- }
- case EInitializeGetToken:
- {
- if (iStatus.Int() == KErrHardwareNotAvailable)
- {
- // If the hardware corresponding to this
- // TokenType has been removed then just skip it
- // but DO NOT leave!
- ++iIndexTokens;
- iState = EInitializeGetToken;
- TRequestStatus* status = &iStatus;
- User::RequestComplete(status, KErrNone);
- }
- else
- {
- User::LeaveIfError(iStatus.Int());
- iIndexTokens++;
-
- if (iIndexTokens < iTokens.Count())
- {
- iTokenType->OpenToken(*iTokens[iIndexTokens], iToken, iStatus);
- iRequestUid.iUid = KInterfaceKeyStoreManager;
- iState = EInitialiseGetKeyManagerInterface;
- }
- else
- {// Don't need the iTokenType anymore
- iTokenType->Release();
- iTokenType = 0;
-
- iTokens.Close(); // Don't need the list of Tokens anymore
- iState = EInitializeGetTokenList;
- TRequestStatus* status = &iStatus;
- User::RequestComplete(status, KErrNone);
- }
- }
- SetActive();
- break;
- }
- case EInitialiseGetKeyManagerInterface:
- {// First try to get a manager interface to the store, if
- // unsuccessful, try once to get a user interface
- if (iToken)
- {
- iRequestUid.iUid = KInterfaceKeyStoreManager;
- iToken->GetInterface(iRequestUid, iTokenInterface, iStatus);
- iState = EInitializeGetKeyUserInterface;
- SetActive();
- }
- else
- {// No token
- User::Leave(KErrNotReady);
- }
- break;
- }
- case EInitializeGetKeyUserInterface:
- {// Did we get a manager interface?
- if (iStatus==KErrNoMemory)
- {
- User::Leave(KErrNoMemory);
- }
-
- if (iRequestUid.iUid==KInterfaceKeyStoreManager)
- {
- if (KErrNone==iStatus.Int())
- {// Success! Store it and finish up
- CKeyStoreIF* keyStore = new (ELeave) CKeyStoreIF(iTokenInterface, ETrue);
- CleanupStack::PushL(keyStore);
- User::LeaveIfError(iKeyStoresHolder.Append(keyStore));
- CleanupStack::Pop(keyStore);
-
- iTokenInterface = 0;
- iToken->Release();
- iToken = 0;
- iState = EInitializeGetToken;
- TRequestStatus* status = &iStatus;
- User::RequestComplete(status, KErrNone);
- }
- else
- {// No luck getting a manager, so try getting a user
- iRequestUid.iUid = KInterfaceKeyStore;
- iToken->GetInterface(iRequestUid, iTokenInterface, iStatus);
- iState = EInitializeGetKeyUserInterfaceFinished;
- }
- }
- else if (iRequestUid.iUid==KInterfaceKeyStore)
- {// We were trying for user IF
- if (iStatus==KErrNone)
- {
- if (iToken)
- {
- iRequestUid.iUid = KInterfaceKeyStore;
- iToken->GetInterface(iRequestUid, iTokenInterface, iStatus);
- iState = EInitializeGetKeyUserInterfaceFinished;
- }
- else
- {
- User::Leave(KErrNotReady);
- }
- }
- else
- {// Couldn't even get a user IF
- User::Leave(iStatus.Int());
- }
- }
-
- SetActive();
- break;
- }
- case EInitializeGetKeyUserInterfaceFinished:
- {
- if (iStatus==KErrNone)
- {
- CKeyStoreIF* keyStore = new (ELeave) CKeyStoreIF(iTokenInterface, EFalse);
- CleanupStack::PushL(keyStore);
- User::LeaveIfError(iKeyStoresHolder.Append(keyStore));
- CleanupStack::Pop(keyStore);
-
- iTokenInterface = 0;
- iToken->Release();
- iToken = 0;
- iState = EInitializeGetToken;
- TRequestStatus* status = &iStatus;
- User::RequestComplete(status, KErrNone);
- }
- else if (iStatus == KErrNoMemory)
- {
- User::Leave(KErrNoMemory);
- }
- else
- {
- iState = EInitializeGetToken;
- TRequestStatus* status = &iStatus;
- User::RequestComplete(status,iStatus.Int());
- }
-
- SetActive();
- break;
- }
- case EInitializeFinished:
- Complete(KErrNone);
- break;
-
- case EList:
- {// iIndex has been initialized in List function
- ++iIndex;
- if (iIndex < iKeyStoresHolder.Count())
- {
- iKeyStore = static_cast<MCTKeyStore*>(iKeyStoresHolder[iIndex]->KeyStore());
- ASSERT(iKeyStore);
- iKeyStore->List(*iKeyInfos, *iFilter, iStatus);
- SetActive();
- }
- else
- {
- Complete(KErrNone);
- }
- break;
- }
-
- case EGetKeyInfo:
- Complete(KErrNone);
- break;
-
- case ECreateKey:
- *iKeyInfoOut = iKeyInfo;
- iKeyInfo = NULL; // Release ownership
- Complete(KErrNone);
- break;
-
- case EImportKey:
- case EImportKeyEncrypted:
- *iKeyInfoOut = iKeyInfo;
- iKeyInfo = NULL; // Release ownership
- Complete(KErrNone);
- break;
-
- case EExportKey:
- case EExportEncryptedKey:
- Complete(KErrNone);
- break;
-
- case ERelock:
- ++iIndex;
-
- // Find next key store manager
- while (iIndex < iKeyStoresHolder.Count() && !iKeyStoresHolder[iIndex]->IsKeyManager())
- ++iIndex;
-
- if (iIndex < iKeyStoresHolder.Count())
- {
- iKeyStoreManager = static_cast<MCTKeyStoreManager*>(iKeyStoresHolder[iIndex]->KeyStore());
- ASSERT(iKeyStoreManager);
- iKeyStoreManager->Relock(iStatus);
- SetActive();
- }
- else
- {
- Complete(KErrNone);
- }
- break;
-
- case ESetPassphraseTimeout:
- ++iIndex;
-
- // Find next key store manager
- while (iIndex < iKeyStoresHolder.Count() && !iKeyStoresHolder[iIndex]->IsKeyManager())
- ++iIndex;
-
- if (iIndex < iKeyStoresHolder.Count())
- {
- iKeyStoreManager = static_cast<MCTKeyStoreManager*>(iKeyStoresHolder[iIndex]->KeyStore());
- ASSERT(iKeyStoreManager);
- iKeyStoreManager->SetPassphraseTimeout(iNewTimeout, iStatus);
- SetActive();
- }
- else
- {
- Complete(KErrNone);
- }
- break;
-
- case EOpen:
- case EExportPublic:
- case EDeleteKey:
- case ESetUsePolicy:
- case ESetManagementPolicy:
- Complete(KErrNone);
- break;
- default:
- User::Panic(KUnifiedKeyStore, EUnrecognisedState);
- break;
- }
-}
-
-TInt CUnifiedKeyStore::RunError(TInt aError)
- {
- Complete(aError);
- return KErrNone;
- }
-
-void CUnifiedKeyStore::DoCancel()
- {
- // If the current state is the last state involved in handling a request, we
- // check to see if we have already been completed - in this case we can
- // simply complete the client with iStatus (this may be KErrNone). If we
- // have not we cancel the outstanding request and pass the resulting iStatus
- // back to the client - this too may indicate a successful completion if the
- // cancel arrived after the request was executed.
- //
- // For more complex cases, where there are more states to go through before
- // we finish servicing the client request, we cancel any outstanding
- // request, and return KErrCancel to the client.
-
- switch (iState)
- {
- case EInitializeFinished:
- case EGetKeyInfo:
- case ECreateKey:
- case EImportKey:
- case EImportKeyEncrypted:
- case EExportKey:
- case EExportEncryptedKey:
- case EOpen:
- case EExportPublic:
- case EDeleteKey:
- case ESetUsePolicy:
- case ESetManagementPolicy:
- if (iStatus == KRequestPending)
- {
- // Attempt to cancel outstanding request and pass status back to
- // client
- CancelOutstandingRequest();
- Complete(iStatus.Int());
- }
- else
- {
- // We've already been completed - call RunL() to process results
- // and complete client
- TRAPD(err, RunL());
- if (err != KErrNone)
- {
- RunError(err);
- }
- }
- break;
-
- default:
- CancelOutstandingRequest();
- Complete(KErrCancel);
- break;
- }
- }
-
-void CUnifiedKeyStore::CancelOutstandingRequest()
- {
- switch (iState)
- {
- case EInitializeGetTokenList:
- case EInitializeGetToken:
- case EInitialiseGetKeyManagerInterface:
- case EInitializeGetKeyUserInterface:
- case EInitializeGetKeyUserInterfaceFinished:
- case EInitializeFinished:
- // Don't have to cancel initialisation stuff - this happens when we
- // release the objects in Cleanup().
- iStatus = KErrCancel;
- break;
-
- case EList:
- if (iKeyStore)
- {
- iKeyStore->CancelList();
- }
- break;
-
- case EGetKeyInfo:
- ASSERT(iKeyStore);
- iKeyStore->CancelGetKeyInfo();
- break;
-
- case EOpen:
- ASSERT(iKeyStore);
- iKeyStore->CancelOpen();
- break;
-
- case EExportPublic:
- ASSERT(iKeyStore);
- iKeyStore->CancelExportPublic();
- break;
-
- case ECreateKey:
- ASSERT(iKeyStoreManager);
- iKeyStoreManager->CancelCreateKey();
- break;
-
- case EImportKey:
- case EImportKeyEncrypted:
- ASSERT(iKeyStoreManager);
- iKeyStoreManager->CancelImportKey();
- break;
-
- case EExportKey:
- case EExportEncryptedKey:
- ASSERT(iKeyStoreManager);
- iKeyStoreManager->CancelExportKey();
- break;
-
- case EDeleteKey:
- ASSERT(iKeyStoreManager);
- iKeyStoreManager->CancelDeleteKey();
- break;
-
- case ERelock:
- ASSERT(iKeyStoreManager);
- iKeyStoreManager->CancelRelock();
- break;
-
- case ESetPassphraseTimeout:
- ASSERT(iKeyStoreManager);
- iKeyStoreManager->CancelSetPassphraseTimeout();
- break;
-
- case ESetUsePolicy:
- ASSERT(iKeyStoreManager);
- iKeyStoreManager->CancelSetUsePolicy();
- break;
-
- case ESetManagementPolicy:
- ASSERT(iKeyStoreManager);
- iKeyStoreManager->CancelSetManagementPolicy();
- break;
-
- default:
- User::Panic(KUnifiedKeyStore, EUnrecognisedState);
- break;
- }
- }
-
-
-void CUnifiedKeyStore::Complete(TInt aError)
- {
- Cleanup();
- if (iOriginalRequestStatus)
- {
- User::RequestComplete(iOriginalRequestStatus, aError);
- }
- }
-
-void CUnifiedKeyStore::Cleanup()
- {
- // If we have a key info, we want to release it
- if (iKeyInfo)
- {
- iKeyInfo->Release();
- iKeyInfo = NULL;
- }
-
- delete iKeyData;
- iKeyData = NULL;
-
- delete iFilter;
- iFilter = NULL;
-
- delete iPbeParams;
- iPbeParams = NULL;
-
- iTokenTypes.Close();
-
- if (iTokenType)
- {
- iTokenType->Release();
- iTokenType = 0;
- }
-
- iTokens.Close();
-
- if (iToken)
- {
- iToken->Release();
- iToken = 0;
- }
-
- if (iTokenInterface)
- {
- iTokenInterface->Release();
- iTokenInterface = 0;
- }
-
- iKeyInfoOut = NULL;
- iKeyStore = NULL;
- iKeyStoreManager = NULL;
-
- iState = EIdle;
- }
-
-CUnifiedKeyStore::CKeyStoreIF::CKeyStoreIF(MCTTokenInterface* aKeyStore, TBool aIsKeyManager)
-: iKeyStore(aKeyStore), iIsKeyManager(aIsKeyManager)
-{}
-
-CUnifiedKeyStore::CKeyStoreIF::~CKeyStoreIF()
-{
- if (iKeyStore)
- {
- iKeyStore->Release();
- iKeyStore = NULL;
- }
-}
+/*
+* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include "unifiedkeystore.h"
+#include <ecom/ecom.h>
+#include <random.h>
+#include <pbedata.h>
+#include <asnpkcs.h>
+#include "mctcertappinterface.h"
+#include <mctkeystoreuids.h>
+
+_LIT(KUnifiedKeyStore, "UnifiedKeyStore");
+
+/////////////////////////////////////////////////////////////////////////////////////
+//CUnifiedKeyStore
+/////////////////////////////////////////////////////////////////////////////////////
+
+EXPORT_C CUnifiedKeyStore* CUnifiedKeyStore::NewL(RFs& aFs)
+ {
+ CUnifiedKeyStore* self = CUnifiedKeyStore::NewLC(aFs);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+EXPORT_C CUnifiedKeyStore* CUnifiedKeyStore::NewLC(RFs& aFs)
+ {
+ CUnifiedKeyStore* self = new(ELeave) CUnifiedKeyStore(aFs);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+EXPORT_C CUnifiedKeyStore::~CUnifiedKeyStore()
+ {
+ Cancel();
+ Cleanup();
+
+ iKeyStoresHolder.ResetAndDestroy();
+ iKeyStoresHolder.Close();
+
+ REComSession::FinalClose();
+ }
+
+void CUnifiedKeyStore::DoInitializeL()
+{// We want the list of all token types that support a keystore interface
+ RArray<TUid> uidArray;
+ CleanupClosePushL(uidArray);
+
+ User::LeaveIfError(uidArray.Append(TUid::Uid(KInterfaceKeyStore)));
+
+ TCTFindTokenTypesByInterface filter(uidArray.Array());
+ CCTTokenTypeInfo::ListL(iTokenTypes, filter);
+
+ CleanupStack::PopAndDestroy(); // uidArray
+}
+
+EXPORT_C void CUnifiedKeyStore::Initialize(TRequestStatus& aStatus)
+{// The following assertion checks that we didn't call Initialize twice
+ __ASSERT_DEBUG((iKeyStoresHolder.Count()==0), User::Panic(KUnifiedKeyStore, EUnexpectedInitialise));
+
+ TRAPD(err, DoInitializeL());
+ if (err != KErrNone)
+ {
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, err);
+ return;
+ }
+
+ iIndexTokenTypes = -1;
+ StartAsyncOperation(EInitializeGetTokenList, aStatus);
+
+ SetActive();
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+}
+
+EXPORT_C void CUnifiedKeyStore::CancelInitialize()
+ {
+ if (iState == EInitializeGetTokenList ||
+ iState == EInitializeGetToken ||
+ iState == EInitialiseGetKeyManagerInterface ||
+ iState == EInitializeGetKeyUserInterface ||
+ iState == EInitializeGetKeyUserInterfaceFinished ||
+ iState == EInitializeFinished)
+ {
+ Cancel();
+ }
+ }
+
+EXPORT_C void CUnifiedKeyStore::CreateKey(TInt aKeyStoreIndex, TKeyUsagePKCS15 aUsage,TUint aSize,
+ const TDesC& aLabel, CCTKeyInfo::EKeyAlgorithm aAlgorithm,
+ TInt aAccessType, TTime aStartDate, TTime aEndDate,
+ CCTKeyInfo*& aKeyInfoOut, TRequestStatus& aStatus)
+ {
+ StartAsyncOperation(ECreateKey, aStatus);
+ TRAPD(err, PrepareToCreateKeyL(aKeyStoreIndex, aUsage, aSize, aLabel, aAlgorithm, aAccessType,
+ aStartDate, aEndDate, aStatus));
+ if (KErrNone != err)
+ {
+ Complete(err);
+ return;
+ }
+
+ iKeyInfoOut = &aKeyInfoOut;
+ aKeyInfoOut = NULL;
+ iKeyStoreManager->CreateKey(iKeyInfo, iStatus);
+ SetActive();
+ }
+
+EXPORT_C void CUnifiedKeyStore::CancelCreateKey()
+ {
+ if (iState == ECreateKey)
+ {
+ Cancel();
+ }
+ }
+
+EXPORT_C void CUnifiedKeyStore::ImportKey(TInt aKeyStoreIndex, const TDesC8& aKeyData,
+ TKeyUsagePKCS15 aUsage, const TDesC& aLabel,
+ TInt aAccessType, TTime aStartDate, TTime aEndDate,
+ CCTKeyInfo*& aKeyInfoOut, TRequestStatus& aStatus)
+ {
+ TBool isEncrypted = TASN1DecPKCS8::IsEncryptedPKCS8Data(aKeyData);
+ StartAsyncOperation(isEncrypted ? EImportKeyEncrypted : EImportKey, aStatus);
+
+ ASSERT(!iKeyData);
+ iKeyData = aKeyData.Alloc();
+ if (!iKeyData) // OOM or some other catastrophe
+ {
+ Complete(KErrNoMemory);
+ return;
+ }
+
+ TRAPD(err, PrepareToCreateKeyL(aKeyStoreIndex, aUsage, 0, aLabel, CCTKeyInfo::EInvalidAlgorithm, aAccessType,
+ aStartDate, aEndDate, aStatus));
+ if (KErrNone != err)
+ {
+ Complete(err);
+ return;
+ }
+
+ iKeyInfoOut = &aKeyInfoOut;
+ aKeyInfoOut = NULL;
+
+ if (isEncrypted)
+ {
+ iKeyStoreManager->ImportEncryptedKey(*iKeyData, iKeyInfo, iStatus);
+ }
+ else
+ {
+ iKeyStoreManager->ImportKey(*iKeyData, iKeyInfo, iStatus);
+ }
+ SetActive();
+ }
+
+EXPORT_C void CUnifiedKeyStore::CancelImportKey()
+ {
+ if (iState == EImportKey ||
+ iState == EImportKeyEncrypted)
+ {
+ Cancel();
+ }
+ }
+
+void CUnifiedKeyStore::PrepareToCreateKeyL( TInt aKeyStoreIndex,
+ TKeyUsagePKCS15 aUsage, TUint aSize,
+ const TDesC& aLabel,
+ CCTKeyInfo::EKeyAlgorithm aAlgorithm,
+ TInt aAccessType,
+ TTime aStartTime, TTime aEndTime,
+ TRequestStatus& aStatus)
+ {
+ ASSERT(!iKeyStoreManager);
+
+ // These values are filled in by the server when the key is created
+ TKeyIdentifier keyID;
+ keyID.MaxSize();
+ keyID.FillZ(keyID.MaxSize());
+ TInt keyHandle = 0;
+
+ // Get the secure ID of the current process
+ RProcess thisProcess;
+ User::LeaveIfError(thisProcess.Open(thisProcess.Id()));
+ TSecureId creatorId = thisProcess.SecureId();
+ thisProcess.Close();
+
+ // Default management policy: resict to creating process
+ TSecurityPolicy managementPolicy(creatorId);
+
+ // Default use policy: also resict to creating process
+ TSecurityPolicy usePolicy(creatorId);
+
+ HBufC* label = aLabel.AllocLC();
+
+ // Panics if keystore manager index invalid
+ MCTKeyStoreManager& keystore = KeyStoreManager(aKeyStoreIndex);
+
+ iKeyInfo = CCTKeyInfo::NewL(keyID, aUsage, aSize, NULL, label, keystore.Token(),
+ keyHandle, usePolicy, managementPolicy, aAlgorithm,
+ aAccessType, ETrue, aStartTime, aEndTime);
+ CleanupStack::Pop(label);
+
+ iKeyStoreManager = &keystore;
+ iOriginalRequestStatus = &aStatus;
+ aStatus = KRequestPending;
+ }
+
+// ************************************************************************
+// MKeyStore
+// ************************************************************************
+
+void CUnifiedKeyStore::List(RMPointerArray<CCTKeyInfo>& aKeys,
+ const TCTKeyAttributeFilter& aFilter,
+ TRequestStatus& aStatus)
+ {
+ StartAsyncOperation(EList, aStatus);
+
+ iKeyInfos = &aKeys;
+
+ delete iFilter;
+ iFilter = new TCTKeyAttributeFilter(aFilter);
+ if (!iFilter)
+ {
+ Complete(KErrNoMemory);
+ return;
+ }
+
+ iIndex = -1;
+
+ SetActive();
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+}
+
+void CUnifiedKeyStore::CancelList()
+ {
+ if (iState == EList)
+ {
+ Cancel();
+ }
+ }
+
+void CUnifiedKeyStore::GetKeyInfo(TCTTokenObjectHandle aHandle,
+ CCTKeyInfo*& aKeyInfo,
+ TRequestStatus& aStatus)
+ {
+ StartAsyncOperation(EGetKeyInfo, aStatus);
+
+ ASSERT(!iKeyStore);
+ iKeyStore = FindKeyStore(aHandle);
+ if (!iKeyStore)
+ {
+ Complete(KErrNotFound);
+ return;
+ }
+
+ iKeyStore->GetKeyInfo(aHandle, aKeyInfo, iStatus);
+ SetActive();
+ }
+
+void CUnifiedKeyStore::CancelGetKeyInfo()
+ {
+ if (iState == EGetKeyInfo)
+ {
+ Cancel();
+ }
+ }
+
+// Implementation for most of the Open() method
+TBool CUnifiedKeyStore::DoOpen(const TCTTokenObjectHandle& aHandle,
+ TRequestStatus& aStatus)
+ {
+ StartAsyncOperation(EOpen, aStatus);
+
+ ASSERT(!iKeyStore);
+ iKeyStore = FindKeyStore(aHandle);
+ if (!iKeyStore)
+ {
+ Complete(KErrNotFound);
+ return EFalse;
+ }
+
+ SetActive();
+ return ETrue;
+ }
+
+void CUnifiedKeyStore::Open(const TCTTokenObjectHandle& aHandle,
+ MRSASigner*& aSigner,
+ TRequestStatus& aStatus)
+ {
+ if (DoOpen(aHandle, aStatus))
+ {
+ iKeyStore->Open(aHandle, aSigner, iStatus);
+ }
+ }
+
+void CUnifiedKeyStore::Open(const TCTTokenObjectHandle& aHandle,
+ MDSASigner*& aSigner,
+ TRequestStatus& aStatus)
+ {
+ if (DoOpen(aHandle, aStatus))
+ {
+ iKeyStore->Open(aHandle, aSigner, iStatus);
+ }
+ }
+
+void CUnifiedKeyStore::Open(const TCTTokenObjectHandle& aHandle,
+ MCTDecryptor*& aDecryptor,
+ TRequestStatus& aStatus)
+ {
+ if (DoOpen(aHandle, aStatus))
+ {
+ iKeyStore->Open(aHandle, aDecryptor, iStatus);
+ }
+ }
+
+void CUnifiedKeyStore::Open(const TCTTokenObjectHandle& aHandle,
+ MCTDH*& aDH, TRequestStatus& aStatus)
+ {
+ if (DoOpen(aHandle, aStatus))
+ {
+ iKeyStore->Open(aHandle, aDH, iStatus);
+ }
+ }
+
+void CUnifiedKeyStore::CancelOpen()
+ {
+ if (iState == EOpen)
+ {
+ Cancel();
+ }
+ }
+
+/** Returns the public key in DER-encoded ASN-1 */
+void CUnifiedKeyStore::ExportPublic(const TCTTokenObjectHandle& aHandle,
+ HBufC8*& aPublicKey,
+ TRequestStatus& aStatus)
+ {
+ StartAsyncOperation(EExportPublic, aStatus);
+
+ iKeyStore = FindKeyStore(aHandle);
+ if (!iKeyStore)
+ {
+ Complete(KErrNotFound);
+ return;
+ }
+
+ iKeyStore->ExportPublic(aHandle, aPublicKey, iStatus);
+ SetActive();
+ }
+
+void CUnifiedKeyStore::CancelExportPublic()
+ {
+ if (iState == EExportPublic)
+ {
+ Cancel();
+ }
+ }
+
+// ************************************************************************
+// MKeyStoreManager
+// ************************************************************************
+
+EXPORT_C void CUnifiedKeyStore::ExportKey(TCTTokenObjectHandle aHandle,
+ HBufC8*& aKey, TRequestStatus& aStatus)
+ {
+ StartAsyncOperation(EExportKey, aStatus);
+
+ ASSERT(!iKeyStoreManager);
+ iKeyStoreManager = FindKeyStoreManager(aHandle);
+ if (!iKeyStoreManager)
+ {
+ Complete(KErrNotFound);
+ return;
+ }
+
+ iKeyStoreManager->ExportKey(aHandle, aKey, iStatus);
+ SetActive();
+ }
+
+EXPORT_C void CUnifiedKeyStore::CancelExportKey()
+ {
+ if (iState == EExportKey)
+ {
+ Cancel();
+ }
+ }
+
+EXPORT_C void CUnifiedKeyStore::ExportEncryptedKey(TCTTokenObjectHandle aHandle,
+ const CPBEncryptParms& aEncryptParams,
+ HBufC8*& aKey, TRequestStatus& aStatus)
+ {
+ StartAsyncOperation(EExportEncryptedKey, aStatus);
+
+ ASSERT(!iKeyStoreManager);
+ iKeyStoreManager = FindKeyStoreManager(aHandle);
+ if (!iKeyStoreManager)
+ {
+ Complete(KErrNotFound);
+ return;
+ }
+
+ iKeyStoreManager->ExportEncryptedKey(aHandle, aEncryptParams, aKey, iStatus);
+ SetActive();
+ }
+
+EXPORT_C void CUnifiedKeyStore::CancelExportEncryptedKey()
+ {
+ if (iState == EExportEncryptedKey)
+ {
+ Cancel();
+ }
+ }
+
+EXPORT_C void CUnifiedKeyStore::DeleteKey(TCTTokenObjectHandle aHandle,
+ TRequestStatus& aStatus)
+ {
+ StartAsyncOperation(EDeleteKey, aStatus);
+
+ iKeyStoreManager = FindKeyStoreManager(aHandle);
+ if (!iKeyStoreManager)
+ {
+ Complete(KErrNotFound);
+ return;
+ }
+
+ iKeyStoreManager->DeleteKey(aHandle, iStatus);
+ SetActive();
+ }
+
+EXPORT_C void CUnifiedKeyStore::CancelDeleteKey()
+ {
+ if (iState == EDeleteKey)
+ {
+ Cancel();
+ }
+ }
+
+EXPORT_C void CUnifiedKeyStore::SetUsePolicy(TCTTokenObjectHandle aHandle,
+ const TSecurityPolicy& aPolicy,
+ TRequestStatus& aStatus)
+ {
+ StartAsyncOperation(ESetUsePolicy, aStatus);
+
+ iKeyStoreManager = FindKeyStoreManager(aHandle);
+ if (!iKeyStoreManager)
+ {
+ Complete(KErrNotFound);
+ return;
+ }
+
+ iKeyStoreManager->SetUsePolicy(aHandle, aPolicy, iStatus);
+ SetActive();
+ }
+
+EXPORT_C void CUnifiedKeyStore::CancelSetUsePolicy()
+ {
+ if (iState == ESetUsePolicy)
+ {
+ Cancel();
+ }
+ }
+
+EXPORT_C void CUnifiedKeyStore::SetManagementPolicy(TCTTokenObjectHandle aHandle,
+ const TSecurityPolicy& aPolicy,
+ TRequestStatus& aStatus)
+ {
+ StartAsyncOperation(ESetManagementPolicy, aStatus);
+
+ iKeyStoreManager = FindKeyStoreManager(aHandle);
+ if (!iKeyStoreManager)
+ {
+ Complete(KErrNotFound);
+ return;
+ }
+
+ iKeyStoreManager->SetManagementPolicy(aHandle, aPolicy, iStatus);
+ SetActive();
+ }
+
+EXPORT_C void CUnifiedKeyStore::CancelSetManagementPolicy()
+ {
+ if (iState == ESetManagementPolicy)
+ {
+ Cancel();
+ }
+ }
+
+EXPORT_C void CUnifiedKeyStore::SetPassphraseTimeout(TInt aTimeout,
+ TRequestStatus& aStatus)
+ {
+ StartAsyncOperation(ESetPassphraseTimeout, aStatus);
+
+ iIndex = -1;
+ iNewTimeout = aTimeout;
+ SetActive();
+
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ }
+
+EXPORT_C void CUnifiedKeyStore::CancelSetPassphraseTimeout()
+ {
+ if (iState == ESetPassphraseTimeout)
+ {
+ Cancel();
+ }
+ }
+
+EXPORT_C void CUnifiedKeyStore::Relock(TRequestStatus& aStatus)
+ {
+ StartAsyncOperation(ERelock, aStatus);
+
+ iIndex = -1;
+ SetActive();
+
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ }
+
+EXPORT_C void CUnifiedKeyStore::CancelRelock()
+ {
+ if (iState == ERelock)
+ {
+ Cancel();
+ }
+ }
+
+// ************************************************************************
+// Other exports
+// ************************************************************************
+
+EXPORT_C TInt CUnifiedKeyStore::KeyStoreCount() const
+{
+ return (iKeyStoresHolder.Count());
+}
+
+EXPORT_C MCTKeyStore& CUnifiedKeyStore::KeyStore(TInt aIndex)
+{
+ __ASSERT_ALWAYS(aIndex >= 0 && aIndex < iKeyStoresHolder.Count(),
+ User::Panic(KUnifiedKeyStore, EArrayAccessOutOfBounds));
+
+ MCTKeyStore* keyStore = static_cast<MCTKeyStore*>(iKeyStoresHolder[aIndex]->KeyStore());
+ return (*keyStore);
+}
+
+EXPORT_C TInt CUnifiedKeyStore::KeyStoreManagerCount() const
+ {
+ TInt result = 0;
+ for (TInt i = 0 ; i < iKeyStoresHolder.Count() ; ++i)
+ {
+ if (iKeyStoresHolder[i]->IsKeyManager())
+ {
+ ++result;
+ }
+ }
+ return result;
+ }
+
+EXPORT_C MCTKeyStoreManager& CUnifiedKeyStore::KeyStoreManager(TInt aIndex)
+ {
+ __ASSERT_ALWAYS(aIndex >= 0, User::Panic(KUnifiedKeyStore, EArrayAccessOutOfBounds));
+ TInt managerIndex = 0;
+ MCTKeyStoreManager* result = NULL;
+ for (TInt i = 0 ; i < iKeyStoresHolder.Count() ; ++i)
+ {
+ if (iKeyStoresHolder[i]->IsKeyManager())
+ {
+ if (managerIndex == aIndex)
+ {
+ result = static_cast<MCTKeyStoreManager*>(iKeyStoresHolder[i]->KeyStore());
+ break;
+ }
+ ++managerIndex;
+ }
+ }
+ __ASSERT_ALWAYS(result != NULL, User::Panic(KUnifiedKeyStore, EArrayAccessOutOfBounds));
+ return *result;
+ }
+
+#ifdef SYMBIAN_AUTH_SERVER
+
+EXPORT_C void CUnifiedKeyStore::CreateKey( TInt aKeyStoreIndex, TKeyUsagePKCS15 aUsage,TUint aSize,
+ const TDesC& aLabel, CCTKeyInfo::EKeyAlgorithm aAlgorithm,
+ TInt aAccessType, TTime aStartDate, TTime aEndDate,
+ const TDesC& aAuthenticationString, TInt aFreshness,
+ CCTKeyInfo*& aKeyInfoOut, TRequestStatus& aStatus)
+ {
+
+ StartAsyncOperation(ECreateKey, aStatus);
+ TRAPD(err, PrepareToCreateKeyL(aKeyStoreIndex, aUsage, aSize, aLabel, aAlgorithm, aAccessType,
+ aStartDate, aEndDate, aStatus));
+ if (KErrNone != err)
+ {
+ Complete(err);
+ return;
+ }
+
+ iKeyInfoOut = &aKeyInfoOut;
+ aKeyInfoOut = NULL;
+ iKeyStoreManager->CreateKey(aAuthenticationString, aFreshness, iKeyInfo, iStatus);
+ SetActive();
+
+ }
+
+
+EXPORT_C void CUnifiedKeyStore::ImportKey( TInt aKeyStoreIndex, const TDesC8& aKeyData,
+ TKeyUsagePKCS15 aUsage, const TDesC& aLabel,
+ TInt aAccessType, TTime aStartDate, TTime aEndDate,
+ const TDesC& aAuthenticationString, TInt aFreshness,
+ CCTKeyInfo*& aKeyInfoOut, TRequestStatus& aStatus)
+ {
+ TBool isEncrypted = TASN1DecPKCS8::IsEncryptedPKCS8Data(aKeyData);
+ StartAsyncOperation(isEncrypted ? EImportKeyEncrypted : EImportKey, aStatus);
+
+ ASSERT(!iKeyData);
+ iKeyData = aKeyData.Alloc();
+ if (!iKeyData) // OOM or some other catastrophe
+ {
+ Complete(KErrNoMemory);
+ return;
+ }
+
+ TRAPD(err, PrepareToCreateKeyL(aKeyStoreIndex, aUsage, 0, aLabel, CCTKeyInfo::EInvalidAlgorithm, aAccessType,
+ aStartDate, aEndDate, aStatus));
+ if (KErrNone != err)
+ {
+ Complete(err);
+ return;
+ }
+
+ iKeyInfoOut = &aKeyInfoOut;
+ aKeyInfoOut = NULL;
+
+ if (isEncrypted)
+ {
+ iKeyStoreManager->ImportEncryptedKey(*iKeyData, aAuthenticationString, aFreshness, iKeyInfo, iStatus);
+ }
+ else
+ {
+ iKeyStoreManager->ImportKey(*iKeyData, aAuthenticationString, aFreshness, iKeyInfo, iStatus);
+ }
+ SetActive();
+ }
+
+EXPORT_C void CUnifiedKeyStore::SetAuthenticationPolicy( const TCTTokenObjectHandle aHandle,
+ const TDesC& aAuthenticationString,
+ TInt aFreshness,
+ TRequestStatus& aStatus)
+ {
+ StartAsyncOperation(ESetAuthenticationPolicy, aStatus);
+
+ ASSERT(!iKeyStoreManager);
+ iKeyStoreManager = FindKeyStoreManager(aHandle);
+ if (!iKeyStoreManager)
+ {
+ Complete(KErrNotFound);
+ return;
+ }
+
+ iKeyStoreManager->SetAuthenticationPolicy(aHandle, aAuthenticationString, aFreshness, iStatus);
+ SetActive();
+
+ }
+
+EXPORT_C void CUnifiedKeyStore::GetAuthenticationPolicy( const TCTTokenObjectHandle aHandle,
+ HBufC*& aAuthenticationString,
+ TInt& aFreshness,
+ TRequestStatus& aStatus)
+ {
+ StartAsyncOperation(EGetAuthenticationPolicy, aStatus);
+
+ ASSERT(!iKeyStoreManager);
+ iKeyStoreManager = FindKeyStoreManager(aHandle);
+ if (!iKeyStoreManager)
+ {
+ Complete(KErrNotFound);
+ return;
+ }
+
+ iKeyStoreManager->GetAuthenticationPolicy(aHandle, aAuthenticationString, aFreshness, iStatus);
+ SetActive();
+
+ }
+
+#endif // SYMBIAN_AUTH_SERVER
+
+CUnifiedKeyStore::CUnifiedKeyStore(RFs& aFs)
+ : CActive(EPriorityNormal), iFs(aFs), iState(EIdle)
+{// Currently defaults to always try for key store manager interface
+// This may change (add parameter to NewL for required interface)
+ iRequestUid.iUid = KInterfaceKeyStoreManager;
+ CActiveScheduler::Add(this);
+}
+
+void CUnifiedKeyStore::ConstructL()
+{}
+
+void CUnifiedKeyStore::StartAsyncOperation(TState aState, TRequestStatus& aStatus)
+ {
+ ASSERT(iState == EIdle);
+ ASSERT(iOriginalRequestStatus == NULL);
+ iState = aState;
+ iOriginalRequestStatus = &aStatus;
+ aStatus = KRequestPending;
+ }
+
+MCTKeyStore* CUnifiedKeyStore::FindKeyStore(const TCTTokenObjectHandle& aHandle)
+ {
+ for (TInt index = 0 ; index < iKeyStoresHolder.Count() ; ++index)
+ {
+ MCTTokenInterface* store = iKeyStoresHolder[index]->KeyStore();
+ ASSERT(store);
+ if (store->Token().Handle() == aHandle.iTokenHandle)
+ {
+ return static_cast<MCTKeyStoreManager*>(store);
+ }
+ }
+ return NULL;
+ }
+
+MCTKeyStoreManager* CUnifiedKeyStore::FindKeyStoreManager(const TCTTokenObjectHandle& aHandle)
+ {
+ for (TInt index = 0 ; index < iKeyStoresHolder.Count() ; ++index)
+ {
+ MCTTokenInterface* store = iKeyStoresHolder[index]->KeyStore();
+ ASSERT(store);
+ if (store->Token().Handle() == aHandle.iTokenHandle && iKeyStoresHolder[index]->IsKeyManager())
+ {
+ return static_cast<MCTKeyStoreManager*>(store);
+ }
+ }
+ return NULL;
+ }
+
+void CUnifiedKeyStore::RunL()
+{
+ if (EInitializeGetKeyUserInterfaceFinished != iState &&
+ EInitializeGetKeyUserInterface != iState &&
+ EInitializeGetToken != iState)
+ {
+ User::LeaveIfError(iStatus.Int());
+ }
+
+ switch (iState)
+ {
+ case EInitializeGetTokenList:
+ {// Try to get a list of Tokens for each of the Token Types
+ iIndexTokenTypes++;
+ if (iIndexTokenTypes < iTokenTypes.Count())
+ {
+ __ASSERT_DEBUG(!iTokenType, User::Panic(KUnifiedKeyStore, EArrayAccessOutOfBounds));
+ iTokenType = MCTTokenType::NewL(*iTokenTypes[iIndexTokenTypes], iFs);
+ __ASSERT_DEBUG(iTokens.Count()==0, User::Panic(KUnifiedKeyStore, ETokensArrayAlreadyInUse));
+ iTokenType->List(iTokens, iStatus);
+ iIndexTokens = -1;
+ iState = EInitializeGetToken;
+ }
+ else
+ {// We don't need the list of Token Types anymore
+ iTokenTypes.ResetAndDestroy();
+ iTokenTypes.Close();
+ iState = EInitializeFinished;
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ }
+ SetActive();
+ break;
+ }
+ case EInitializeGetToken:
+ {
+ if (iStatus.Int() == KErrHardwareNotAvailable)
+ {
+ // If the hardware corresponding to this
+ // TokenType has been removed then just skip it
+ // but DO NOT leave!
+ ++iIndexTokens;
+ iState = EInitializeGetToken;
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ }
+ else
+ {
+ User::LeaveIfError(iStatus.Int());
+ iIndexTokens++;
+
+ if (iIndexTokens < iTokens.Count())
+ {
+ iTokenType->OpenToken(*iTokens[iIndexTokens], iToken, iStatus);
+ iRequestUid.iUid = KInterfaceKeyStoreManager;
+ iState = EInitialiseGetKeyManagerInterface;
+ }
+ else
+ {// Don't need the iTokenType anymore
+ iTokenType->Release();
+ iTokenType = 0;
+
+ iTokens.Close(); // Don't need the list of Tokens anymore
+ iState = EInitializeGetTokenList;
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ }
+ }
+ SetActive();
+ break;
+ }
+ case EInitialiseGetKeyManagerInterface:
+ {// First try to get a manager interface to the store, if
+ // unsuccessful, try once to get a user interface
+ if (iToken)
+ {
+ iRequestUid.iUid = KInterfaceKeyStoreManager;
+ iToken->GetInterface(iRequestUid, iTokenInterface, iStatus);
+ iState = EInitializeGetKeyUserInterface;
+ SetActive();
+ }
+ else
+ {// No token
+ User::Leave(KErrNotReady);
+ }
+ break;
+ }
+ case EInitializeGetKeyUserInterface:
+ {// Did we get a manager interface?
+ if (iStatus==KErrNoMemory)
+ {
+ User::Leave(KErrNoMemory);
+ }
+
+ if (iRequestUid.iUid==KInterfaceKeyStoreManager)
+ {
+ if (KErrNone==iStatus.Int())
+ {// Success! Store it and finish up
+ CKeyStoreIF* keyStore = new (ELeave) CKeyStoreIF(iTokenInterface, ETrue);
+ CleanupStack::PushL(keyStore);
+ User::LeaveIfError(iKeyStoresHolder.Append(keyStore));
+ CleanupStack::Pop(keyStore);
+
+ iTokenInterface = 0;
+ iToken->Release();
+ iToken = 0;
+ iState = EInitializeGetToken;
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ }
+ else
+ {// No luck getting a manager, so try getting a user
+ iRequestUid.iUid = KInterfaceKeyStore;
+ iToken->GetInterface(iRequestUid, iTokenInterface, iStatus);
+ iState = EInitializeGetKeyUserInterfaceFinished;
+ }
+ }
+ else if (iRequestUid.iUid==KInterfaceKeyStore)
+ {// We were trying for user IF
+ if (iStatus==KErrNone)
+ {
+ if (iToken)
+ {
+ iRequestUid.iUid = KInterfaceKeyStore;
+ iToken->GetInterface(iRequestUid, iTokenInterface, iStatus);
+ iState = EInitializeGetKeyUserInterfaceFinished;
+ }
+ else
+ {
+ User::Leave(KErrNotReady);
+ }
+ }
+ else
+ {// Couldn't even get a user IF
+ User::Leave(iStatus.Int());
+ }
+ }
+
+ SetActive();
+ break;
+ }
+ case EInitializeGetKeyUserInterfaceFinished:
+ {
+ if (iStatus==KErrNone)
+ {
+ CKeyStoreIF* keyStore = new (ELeave) CKeyStoreIF(iTokenInterface, EFalse);
+ CleanupStack::PushL(keyStore);
+ User::LeaveIfError(iKeyStoresHolder.Append(keyStore));
+ CleanupStack::Pop(keyStore);
+
+ iTokenInterface = 0;
+ iToken->Release();
+ iToken = 0;
+ iState = EInitializeGetToken;
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ }
+ else if (iStatus == KErrNoMemory)
+ {
+ User::Leave(KErrNoMemory);
+ }
+ else
+ {
+ iState = EInitializeGetToken;
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status,iStatus.Int());
+ }
+
+ SetActive();
+ break;
+ }
+ case EInitializeFinished:
+ Complete(KErrNone);
+ break;
+
+ case EList:
+ {// iIndex has been initialized in List function
+ ++iIndex;
+ if (iIndex < iKeyStoresHolder.Count())
+ {
+ iKeyStore = static_cast<MCTKeyStore*>(iKeyStoresHolder[iIndex]->KeyStore());
+ ASSERT(iKeyStore);
+ iKeyStore->List(*iKeyInfos, *iFilter, iStatus);
+ SetActive();
+ }
+ else
+ {
+ Complete(KErrNone);
+ }
+ break;
+ }
+
+ case EGetKeyInfo:
+ Complete(KErrNone);
+ break;
+
+ case ECreateKey:
+ *iKeyInfoOut = iKeyInfo;
+ iKeyInfo = NULL; // Release ownership
+ Complete(KErrNone);
+ break;
+
+ case EImportKey:
+ case EImportKeyEncrypted:
+ *iKeyInfoOut = iKeyInfo;
+ iKeyInfo = NULL; // Release ownership
+ Complete(KErrNone);
+ break;
+
+ case EExportKey:
+ case EExportEncryptedKey:
+ Complete(KErrNone);
+ break;
+
+ case ERelock:
+ ++iIndex;
+
+ // Find next key store manager
+ while (iIndex < iKeyStoresHolder.Count() && !iKeyStoresHolder[iIndex]->IsKeyManager())
+ ++iIndex;
+
+ if (iIndex < iKeyStoresHolder.Count())
+ {
+ iKeyStoreManager = static_cast<MCTKeyStoreManager*>(iKeyStoresHolder[iIndex]->KeyStore());
+ ASSERT(iKeyStoreManager);
+ iKeyStoreManager->Relock(iStatus);
+ SetActive();
+ }
+ else
+ {
+ Complete(KErrNone);
+ }
+ break;
+
+ case ESetPassphraseTimeout:
+ ++iIndex;
+
+ // Find next key store manager
+ while (iIndex < iKeyStoresHolder.Count() && !iKeyStoresHolder[iIndex]->IsKeyManager())
+ ++iIndex;
+
+ if (iIndex < iKeyStoresHolder.Count())
+ {
+ iKeyStoreManager = static_cast<MCTKeyStoreManager*>(iKeyStoresHolder[iIndex]->KeyStore());
+ ASSERT(iKeyStoreManager);
+ iKeyStoreManager->SetPassphraseTimeout(iNewTimeout, iStatus);
+ SetActive();
+ }
+ else
+ {
+ Complete(KErrNone);
+ }
+ break;
+
+ case EOpen:
+ case EExportPublic:
+ case EDeleteKey:
+ case ESetUsePolicy:
+ case ESetManagementPolicy:
+ case EGetAuthenticationPolicy:
+ case ESetAuthenticationPolicy:
+ Complete(KErrNone);
+ break;
+ default:
+ User::Panic(KUnifiedKeyStore, EUnrecognisedState);
+ break;
+ }
+}
+
+TInt CUnifiedKeyStore::RunError(TInt aError)
+ {
+ Complete(aError);
+ return KErrNone;
+ }
+
+void CUnifiedKeyStore::DoCancel()
+ {
+ // If the current state is the last state involved in handling a request, we
+ // check to see if we have already been completed - in this case we can
+ // simply complete the client with iStatus (this may be KErrNone). If we
+ // have not we cancel the outstanding request and pass the resulting iStatus
+ // back to the client - this too may indicate a successful completion if the
+ // cancel arrived after the request was executed.
+ //
+ // For more complex cases, where there are more states to go through before
+ // we finish servicing the client request, we cancel any outstanding
+ // request, and return KErrCancel to the client.
+
+ switch (iState)
+ {
+ case EInitializeFinished:
+ case EGetKeyInfo:
+ case ECreateKey:
+ case EImportKey:
+ case EImportKeyEncrypted:
+ case EExportKey:
+ case EExportEncryptedKey:
+ case EOpen:
+ case EExportPublic:
+ case EDeleteKey:
+ case ESetUsePolicy:
+ case ESetManagementPolicy:
+ if (iStatus == KRequestPending)
+ {
+ // Attempt to cancel outstanding request and pass status back to
+ // client
+ CancelOutstandingRequest();
+ Complete(iStatus.Int());
+ }
+ else
+ {
+ // We've already been completed - call RunL() to process results
+ // and complete client
+ TRAPD(err, RunL());
+ if (err != KErrNone)
+ {
+ RunError(err);
+ }
+ }
+ break;
+
+ default:
+ CancelOutstandingRequest();
+ Complete(KErrCancel);
+ break;
+ }
+ }
+
+void CUnifiedKeyStore::CancelOutstandingRequest()
+ {
+ switch (iState)
+ {
+ case EInitializeGetTokenList:
+ case EInitializeGetToken:
+ case EInitialiseGetKeyManagerInterface:
+ case EInitializeGetKeyUserInterface:
+ case EInitializeGetKeyUserInterfaceFinished:
+ case EInitializeFinished:
+ // Don't have to cancel initialisation stuff - this happens when we
+ // release the objects in Cleanup().
+ iStatus = KErrCancel;
+ break;
+
+ case EList:
+ if (iKeyStore)
+ {
+ iKeyStore->CancelList();
+ }
+ break;
+
+ case EGetKeyInfo:
+ ASSERT(iKeyStore);
+ iKeyStore->CancelGetKeyInfo();
+ break;
+
+ case EOpen:
+ ASSERT(iKeyStore);
+ iKeyStore->CancelOpen();
+ break;
+
+ case EExportPublic:
+ ASSERT(iKeyStore);
+ iKeyStore->CancelExportPublic();
+ break;
+
+ case ECreateKey:
+ ASSERT(iKeyStoreManager);
+ iKeyStoreManager->CancelCreateKey();
+ break;
+
+ case EImportKey:
+ case EImportKeyEncrypted:
+ ASSERT(iKeyStoreManager);
+ iKeyStoreManager->CancelImportKey();
+ break;
+
+ case EExportKey:
+ case EExportEncryptedKey:
+ ASSERT(iKeyStoreManager);
+ iKeyStoreManager->CancelExportKey();
+ break;
+
+ case EDeleteKey:
+ ASSERT(iKeyStoreManager);
+ iKeyStoreManager->CancelDeleteKey();
+ break;
+
+ case ERelock:
+ ASSERT(iKeyStoreManager);
+ iKeyStoreManager->CancelRelock();
+ break;
+
+ case ESetPassphraseTimeout:
+ ASSERT(iKeyStoreManager);
+ iKeyStoreManager->CancelSetPassphraseTimeout();
+ break;
+
+ case ESetUsePolicy:
+ ASSERT(iKeyStoreManager);
+ iKeyStoreManager->CancelSetUsePolicy();
+ break;
+
+ case ESetManagementPolicy:
+ ASSERT(iKeyStoreManager);
+ iKeyStoreManager->CancelSetManagementPolicy();
+ break;
+
+ default:
+ User::Panic(KUnifiedKeyStore, EUnrecognisedState);
+ break;
+ }
+ }
+
+
+void CUnifiedKeyStore::Complete(TInt aError)
+ {
+ Cleanup();
+ if (iOriginalRequestStatus)
+ {
+ User::RequestComplete(iOriginalRequestStatus, aError);
+ }
+ }
+
+void CUnifiedKeyStore::Cleanup()
+ {
+ // If we have a key info, we want to release it
+ if (iKeyInfo)
+ {
+ iKeyInfo->Release();
+ iKeyInfo = NULL;
+ }
+
+ delete iKeyData;
+ iKeyData = NULL;
+
+ delete iFilter;
+ iFilter = NULL;
+
+ delete iPbeParams;
+ iPbeParams = NULL;
+
+ iTokenTypes.Close();
+
+ if (iTokenType)
+ {
+ iTokenType->Release();
+ iTokenType = 0;
+ }
+
+ iTokens.Close();
+
+ if (iToken)
+ {
+ iToken->Release();
+ iToken = 0;
+ }
+
+ if (iTokenInterface)
+ {
+ iTokenInterface->Release();
+ iTokenInterface = 0;
+ }
+
+ iKeyInfoOut = NULL;
+ iKeyStore = NULL;
+ iKeyStoreManager = NULL;
+
+ iState = EIdle;
+ }
+
+CUnifiedKeyStore::CKeyStoreIF::CKeyStoreIF(MCTTokenInterface* aKeyStore, TBool aIsKeyManager)
+: iKeyStore(aKeyStore), iIsKeyManager(aIsKeyManager)
+{}
+
+CUnifiedKeyStore::CKeyStoreIF::~CKeyStoreIF()
+{
+ if (iKeyStore)
+ {
+ iKeyStore->Release();
+ iKeyStore = NULL;
+ }
+}
+