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