diff -r 3255e7d5bd67 -r 989397f9511c cpsecplugins/cpadvancedsecplugin/src/advsecsettingscertmover_symbian.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cpsecplugins/cpadvancedsecplugin/src/advsecsettingscertmover_symbian.cpp Thu Oct 14 13:56:11 2010 +0300 @@ -0,0 +1,578 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0"" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Helper class to move certificates +* +*/ + +#include "advsecsettingscertmover_symbian.h" +#include "advsecsettingsstoreuids.h" +#include // CUnifiedCertStore +#include // CUnifiedKeyStore +#include // CCTCertInfo +#include // MCTWritableCertStore +#include // MCTKeyStoreManager + +const TInt KMaxBufferLength = 0x3000; // 12kB, for keys and certificates +_LIT_SECURITY_POLICY_C1( KKeyStoreUsePolicy, ECapabilityReadUserData ); + +// TODO: replace with proper logging +#ifdef _DEBUG +#define TRACE(x) RDebug::Printf(x) +#define TRACE1(x, y) RDebug::Printf((x), (y)) +#define TRACE2(x, y, z) RDebug::Printf((x), (y), (z)) +#else +#define TRACE(x) +#define TRACE1(x, y) +#define TRACE2(x, y, z) +#endif + + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::NewL() +// --------------------------------------------------------------------------- +// +CAdvSecSettingsCertMover *CAdvSecSettingsCertMover::NewL(RFs &aFs) +{ + TRACE("CAdvSecSettingsCertMover::NewL()"); + CAdvSecSettingsCertMover* self = new( ELeave ) CAdvSecSettingsCertMover(aFs); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::~CAdvSecSettingsCertMover() +// --------------------------------------------------------------------------- +// +CAdvSecSettingsCertMover::~CAdvSecSettingsCertMover() +{ + TRACE("CAdvSecSettingsCertMover::~CAdvSecSettingsCertMover()"); + Cancel(); + delete iCertStore; + iTargetCertStore = NULL; + delete iCertFilter; + iCerts.Close(); + + delete iKeyStore; + iSourceKeyStore = NULL; + iTargetKeyStore = NULL; + delete iKeyFilter; + iKeys.Close(); + if (iSavedKeyInfo) { + iSavedKeyInfo->Release(); + } + + delete iDataBuffer; + iClientStatus = NULL; + iCertInfo = NULL; +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::Move() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::Move(const CCTCertInfo &aCert, + TInt aSourceCertStoreTokenId, TInt aTargetCertStoreTokenId, + TRequestStatus &aStatus) +{ + TRACE("CAdvSecSettingsCertMover::Move()"); + aStatus = KRequestPending; + if (!iClientStatus) { + iClientStatus = &aStatus; + + iCertInfo = &aCert; + iSourceCertStoreTokenId = aSourceCertStoreTokenId; + iTargetCertStoreTokenId = aTargetCertStoreTokenId; + + if (iState <= EIdle) { + // Start move operation if initializations are complete. + if (iState == EIdle) { + TRAPD(err, StartMoveOperationL()); + if (err) { + TRACE1("CAdvSecSettingsCertMover::Move(), error %d", err); + User::RequestComplete(iClientStatus, err); + iClientStatus = NULL; + } + } + // If initializations are not complete yet, then moving + // starts in RunL() after initializations are completed. + } else { + // Possibly initializations have failed. + TRACE("CAdvSecSettingsCertMover::Move(), RequestComplete KErrGeneral"); + User::RequestComplete(iClientStatus, KErrGeneral); + iClientStatus = NULL; + } + } else { + TRACE("CAdvSecSettingsCertMover::Move(), RequestComplete KErrInUse"); + TRequestStatus* status = &aStatus; + User::RequestComplete(status, KErrInUse); + } +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::DoCancel() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::DoCancel() +{ + TRACE("CAdvSecSettingsCertMover::DoCancel()"); + switch (iState) { + case EInitializingCertStore: + iCertStore->CancelInitialize(); + iState = ENotInitialized; + break; + case EInitializingKeyStore: + iKeyStore->CancelInitialize(); + iState = ENotInitialized; + break; + case EMovingKeyListingKeys: + iKeyStore->CancelList(); + iState = EIdle; + break; + case EMovingKeyExportingKeys: + iSourceKeyStore->CancelExportKey(); + iState = EIdle; + break; + case EMovingKeyImportingKeys: + iTargetKeyStore->CancelImportKey(); + iState = EIdle; + break; + case EMovingKeyDeletingOriginal: + iSourceKeyStore->CancelDeleteKey(); + iState = EIdle; + break; + case EMovingCertListingCerts: + iCertStore->CancelList(); + iState = EIdle; + break; + case EMovingCertRetrievingCerts: + iSourceCertStore->CancelRetrieve(); + iState = EIdle; + break; + case EMovingCertAddingCerts: + iTargetCertStore->CancelAdd(); + iState = EIdle; + break; + case EMovingCertDeletingOriginal: + iSourceCertStore->CancelRemove(); + iState = EIdle; + break; + default: + break; + } + + if (iClientStatus) { + TRACE("CAdvSecSettingsCertMover::DoCancel(), RequestComplete KErrCancel"); + User::RequestComplete(iClientStatus, KErrCancel); + iClientStatus = NULL; + } +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::RunL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::RunL() +{ + TRACE2("CAdvSecSettingsCertMover::RunL(), iState=%d, iStatus.Int()=%d", iState, iStatus.Int()); + User::LeaveIfError(iStatus.Int()); + + switch (iState) { + case EInitializingCertStore: + iKeyStore->Initialize(iStatus); + iState = EInitializingKeyStore; + SetActive(); + break; + case EInitializingKeyStore: + iState = EIdle; + if (iClientStatus) { + StartMoveOperationL(); + } + break; + case EMovingKeyListingKeys: + ExportFirstKeyL(); + break; + case EMovingKeyExportingKeys: + SaveExportedKeyL(); + break; + case EMovingKeyImportingKeys: + DeleteOriginalKeyL(); + break; + case EMovingKeyDeletingOriginal: + ExportNextKeyL(); + break; + case EMovingCertListingCerts: + RetrieveFirstCertL(); + break; + case EMovingCertRetrievingCerts: + SaveRetrievedCertL(); + break; + case EMovingCertAddingCerts: + DeleteOriginalCertL(); + break; + case EMovingCertDeletingOriginal: + RetrieveNextCertL(); + break; + default: + ASSERT(EFalse); + break; + } +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::RunError() +// --------------------------------------------------------------------------- +// +TInt CAdvSecSettingsCertMover::RunError(TInt aError) +{ + TRACE1("CAdvSecSettingsCertMover::RunError(), aError=%d", aError); + if (iClientStatus) { + TRACE1("CAdvSecSettingsCertMover::RunError(), RequestComplete %d", aError); + User::RequestComplete(iClientStatus, aError); + iClientStatus = NULL; + } + if (iState < EIdle) { + iState = EFailed; + } else { + iState = EIdle; + } + return KErrNone; +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::CAdvSecSettingsCertMover() +// --------------------------------------------------------------------------- +// +CAdvSecSettingsCertMover::CAdvSecSettingsCertMover(RFs &aFs) : + CActive(CActive::EPriorityLow), iFs(aFs), iDataPtr(0,0) +{ + CActiveScheduler::Add(this); +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::ConstructL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::ConstructL() +{ + TRACE("CAdvSecSettingsCertMover::ConstructL()"); + const TBool KWriteMode = ETrue; + iCertStore = CUnifiedCertStore::NewL(iFs, KWriteMode); + iKeyStore = CUnifiedKeyStore::NewL(iFs); + + iDataBuffer = HBufC8::New(KMaxBufferLength); + iDataPtr.Set(iDataBuffer->Des()); + + iCertStore->Initialize(iStatus); + iState = EInitializingCertStore; + SetActive(); +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::StartMoveOperationL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::StartMoveOperationL() +{ + TRACE("CAdvSecSettingsCertMover::StartMoveOperationL()"); + FindSourceAndTargetKeyStoresL(); + FindSourceAndTargetCertStoreL(); + StartMovingKeysL(); +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::FindSourceAndTargetKeyStoresL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::FindSourceAndTargetKeyStoresL() +{ + TRACE("CAdvSecSettingsCertMover::FindSourceAndTargetKeyStoresL()"); + TInt keyStoreSourceTokenId = CorrespondingKeyStoreTokenId(iSourceCertStoreTokenId); + TInt keyStoreTargetTokenId = CorrespondingKeyStoreTokenId(iTargetCertStoreTokenId); + TInt keyStoreSourceIndex = KErrNotFound; + TInt keyStoreTargetIndex = KErrNotFound; + + TInt count = iKeyStore->KeyStoreManagerCount(); + for (TInt index = 0; index < count; index++) { + MCTKeyStoreManager& keystoremanager = iKeyStore->KeyStoreManager(index); + MCTToken& token = keystoremanager.Token(); + TUid tokenTypeUid = token.Handle().iTokenTypeUid; + if (tokenTypeUid.iUid == keyStoreSourceTokenId) { + keyStoreSourceIndex = index; + } + if (tokenTypeUid.iUid == keyStoreTargetTokenId) { + keyStoreTargetIndex = index; + } + } + + if (keyStoreSourceIndex == KErrNotFound || keyStoreTargetIndex == KErrNotFound) { + User::Leave(KErrNotFound); + } + + iSourceKeyStore = &( iKeyStore->KeyStoreManager(keyStoreSourceIndex) ); + iTargetKeyStore = &( iKeyStore->KeyStoreManager(keyStoreTargetIndex) ); +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::FindSourceAndTargetCertStoreL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::FindSourceAndTargetCertStoreL() +{ + TRACE("CAdvSecSettingsCertMover::FindSourceAndTargetCertStoreL()"); + TInt certStoreSourceIndex = KErrNotFound; + TInt certStoreTargetIndex = KErrNotFound; + + TInt count = iCertStore->WritableCertStoreCount(); + for (TInt index = 0; index < count; index++) { + MCTWritableCertStore& writablestore = iCertStore->WritableCertStore(index); + MCTToken& token = writablestore.Token(); + TUid tokenTypeUid = token.Handle().iTokenTypeUid; + if (tokenTypeUid.iUid == iSourceCertStoreTokenId) { + certStoreSourceIndex = index; + } + if (tokenTypeUid.iUid == iTargetCertStoreTokenId) { + certStoreTargetIndex = index; + } + } + + if (certStoreSourceIndex == KErrNotFound || certStoreTargetIndex == KErrNotFound) { + User::Leave(KErrNotFound); + } + + iSourceCertStore = &( iCertStore->WritableCertStore(certStoreSourceIndex) ); + iTargetCertStore = &( iCertStore->WritableCertStore(certStoreTargetIndex) ); +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::CorrespondingKeyStoreTokenId() +// --------------------------------------------------------------------------- +// +TInt CAdvSecSettingsCertMover::CorrespondingKeyStoreTokenId(TInt aCertStoreTokenId) +{ + TInt keyStoreTokenId = KErrNotFound; + switch (aCertStoreTokenId) { + case KAdvSecSettingsFileCertStore: + keyStoreTokenId = KAdvSecSettingsFileKeyStore; + break; + case KAdvSecSettingsDeviceCertStore: + keyStoreTokenId = KAdvSecSettingsDeviceKeyStore; + break; + default: + ASSERT(EFalse); // Unsupported cert store token id used + break; + } + return keyStoreTokenId; +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::StartMovingKeysL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::StartMovingKeysL() +{ + TRACE("CAdvSecSettingsCertMover::StartMovingKeysL()"); + if (iKeyFilter) { + delete iKeyFilter; + iKeyFilter = NULL; + } + iKeyFilter = new( ELeave ) TCTKeyAttributeFilter; + iKeyFilter->iKeyId = iCertInfo->SubjectKeyId(); + iKeyFilter->iPolicyFilter = TCTKeyAttributeFilter::EAllKeys; + iKeyStore->List(iKeys, *iKeyFilter, iStatus); + iState = EMovingKeyListingKeys; + SetActive(); +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::ExportFirstKeyL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::ExportFirstKeyL() +{ + TRACE1("CAdvSecSettingsCertMover::ExportFirstKeyL(), iKeys.Count()=%d", iKeys.Count()); + iKeyIndex = 0; + ExportOneKeyL(); +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::ExportOneKeyL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::ExportOneKeyL() +{ + TRACE("CAdvSecSettingsCertMover::ExportOneKeyL()"); + if (iKeyIndex < iKeys.Count()) { + const CCTKeyInfo& keyInfo = *(iKeys[iKeyIndex]); + iSourceKeyStore->ExportKey(keyInfo.Handle(), iDataBuffer, iStatus); + iState = EMovingKeyExportingKeys; + SetActive(); + } else { + TRACE("CAdvSecSettingsCertMover::ExportOneKeyL(), all done"); + StartMovingCertificatesL(); + } +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::ExportNextKeyL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::ExportNextKeyL() +{ + TRACE("CAdvSecSettingsCertMover::ExportNextKeyL()"); + ++iKeyIndex; + ExportOneKeyL(); +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::SaveExportedKeyL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::SaveExportedKeyL() +{ + TRACE("CAdvSecSettingsCertMover::SaveExportedKeyL()"); + const CCTKeyInfo& keyInfo = *(iKeys[iKeyIndex]); + iSourceKeyHandle = keyInfo.Handle(); + + // TODO: is this needed? should iSavedKeyInfo be always used? + // Keys having CCTKeyInfo::ELocal access type cannot be imported. + // Workaround is to create almost identical copy of CCTKeyInfo without + // ELocal access type flag. UsePolicy is also updated. + TInt accessType = keyInfo.AccessType(); + if (accessType & CCTKeyInfo::ELocal) { + accessType ^= CCTKeyInfo::ELocal; + + HBufC* label = keyInfo.Label().AllocLC(); + if (iSavedKeyInfo) { + iSavedKeyInfo->Release(); + iSavedKeyInfo = NULL; + } + iSavedKeyInfo = CCTKeyInfo::NewL( keyInfo.ID(), keyInfo.Usage(), + keyInfo.Size(), NULL, label, keyInfo.Token(), keyInfo.HandleID(), + KKeyStoreUsePolicy, keyInfo.ManagementPolicy(),keyInfo.Algorithm(), + keyInfo.AccessType(), keyInfo.Native(), keyInfo.StartDate(), + keyInfo.EndDate() ); + CleanupStack::Pop(label); + + iTargetKeyStore->ImportKey(*iDataBuffer, iSavedKeyInfo, iStatus); + } else { + iTargetKeyStore->ImportKey(*iDataBuffer, iKeys[iKeyIndex], iStatus); + } + iState = EMovingKeyImportingKeys; + SetActive(); +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::DeleteOriginalKeyL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::DeleteOriginalKeyL() +{ + TRACE("CAdvSecSettingsCertMover::DeleteOriginalKeyL()"); + iSourceKeyStore->DeleteKey(iSourceKeyHandle, iStatus); + iState = EMovingKeyDeletingOriginal; + SetActive(); +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::StartMovingCertificatesL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::StartMovingCertificatesL() +{ + TRACE("CAdvSecSettingsCertMover::StartMovingCertificatesL()"); + if (iCertFilter) { + delete iCertFilter; + iCertFilter = NULL; + } + iCertFilter = CCertAttributeFilter::NewL(); + iCertFilter->SetOwnerType(EUserCertificate); + iCertFilter->SetSubjectKeyId(iCertInfo->SubjectKeyId()); + iCertStore->List(iCerts, *iCertFilter, iStatus); + iState = EMovingCertListingCerts; + SetActive(); +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::RetrieveFirstCertL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::RetrieveFirstCertL() +{ + TRACE1("CAdvSecSettingsCertMover::RetrieveFirstCertL(), iCerts.Count()=%d", iCerts.Count()); + iCertIndex = 0; + RetrieveOneCertL(); +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::RetrieveOneCertL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::RetrieveOneCertL() +{ + TRACE("CAdvSecSettingsCertMover::RetrieveOneCertL()"); + if (iCertIndex < iCerts.Count()) { + const CCTCertInfo& certInfo = *(iCerts[iCertIndex]); + iSourceCertStore->Retrieve(certInfo, iDataPtr, iStatus); + iState = EMovingCertRetrievingCerts; + SetActive(); + } else { + TRACE("CAdvSecSettingsCertMover::RetrieveOneCertL(), all done"); + iState = EIdle; + User::RequestComplete(iClientStatus, KErrNone); + iClientStatus = NULL; + } +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::RetrieveNextCertL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::RetrieveNextCertL() +{ + TRACE("CAdvSecSettingsCertMover::RetrieveNextCertL()"); + ++iCertIndex; + RetrieveOneCertL(); +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::SaveRetrievedCertL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::SaveRetrievedCertL() +{ + TRACE("CAdvSecSettingsCertMover::SaveRetrievedCertL()"); + const CCTCertInfo& certInfo = *(iCerts[iCertIndex]); + iTargetCertStore->Add(certInfo.Label(), EX509Certificate, EUserCertificate, + &(certInfo.SubjectKeyId()), &(certInfo.IssuerKeyId()), *iDataBuffer, iStatus); + iState = EMovingCertAddingCerts; + SetActive(); +} + +// --------------------------------------------------------------------------- +// CAdvSecSettingsCertMover::DeleteOriginalCertL() +// --------------------------------------------------------------------------- +// +void CAdvSecSettingsCertMover::DeleteOriginalCertL() +{ + TRACE("CAdvSecSettingsCertMover::DeleteOriginalCertL()"); + const CCTCertInfo& certInfo = *(iCerts[iCertIndex]); + iSourceCertStore->Remove(certInfo, iStatus); + iState = EMovingCertDeletingOriginal; + SetActive(); +} +