--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cryptoservices/filebasedcertificateandkeystores/source/keystore/Server/keystorepassphrase.cpp Wed Jul 08 11:25:26 2009 +0100
@@ -0,0 +1,449 @@
+/*
+* Copyright (c) 2004-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 "keystorepassphrase.h"
+#include "FSDialog.h"
+#include "pbedata.h"
+#include "fstokenutil.h"
+#include <mctauthobject.h>
+#include <securityerr.h>
+
+const int KRetryCount = 3;
+
+// TPasswordManager ////////////////////////////////////////////////////////////
+
+/*static*/ void TPasswordManager::GetPassword(FSResources::TStrings aLabel,
+ TPINValue& aValue,
+ TRequestStatus& aStatus,
+ TBool aRetry)
+ {
+ TPINParams params;
+
+ params.iPINLabel = FSResources::Strings()[aLabel];
+ params.iMinLength = 0;
+ params.iMaxLength = KMaxPINLength;
+
+ FSDialog::Dialog()->EnterPIN(params, aRetry, aValue, aStatus);
+ }
+
+/*static*/ void TPasswordManager::KeystorePassword(TPINValue& aValue,
+ TRequestStatus& aStatus,
+ TBool aRetry)
+ {
+ GetPassword(FSResources::EPinGLabel, aValue, aStatus, aRetry);
+ }
+
+/*static*/ void TPasswordManager::CreatePassword(TPINValue& aValue,
+ TRequestStatus& aStatus)
+ {
+ GetPassword(FSResources::ECreatePinGLabel, aValue, aStatus);
+ }
+
+/*static*/ void TPasswordManager::ImportPassword(TPINValue& aValue,
+ TRequestStatus& aStatus)
+ {
+ GetPassword(FSResources::EImportPassphraseLabel, aValue, aStatus);
+ }
+
+/*static*/ void TPasswordManager::ExportPassword(TPINValue& aValue,
+ TRequestStatus& aStatus)
+ {
+ GetPassword(FSResources::EExportPassphraseLabel, aValue, aStatus);
+ }
+
+/*static*/ void TPasswordManager::Cancel()
+ {
+ FSDialog::Dialog()->Cancel();
+ }
+
+
+// CPassphrase /////////////////////////////////////////////////////////////////
+
+CPassphrase* CPassphrase::NewLC(TInt aTimeout, CStreamStore& aStore,
+ TStreamId aStreamId, const TDesC& aPassphrase)
+ {
+ CPassphrase* self = new (ELeave) CPassphrase(aStore, aTimeout);
+ CleanupStack::PushL(self);
+ self->ConstructL(aStreamId, aPassphrase);
+ return self;
+ }
+
+CPassphrase* CPassphrase::NewL(TInt aTimeout, CStreamStore& aStore,
+ TStreamId aStreamId, const TDesC& aPassphrase)
+ {
+ CPassphrase* self = NewLC(aTimeout, aStore, aStreamId, aPassphrase);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CPassphrase* CPassphrase::NewLC(TInt aTimeout, CStreamStore& aStore,
+ const TDesC& aPassphrase)
+ {
+ CPassphrase* self = new (ELeave) CPassphrase(aStore, aTimeout);
+ CleanupStack::PushL(self);
+ self->ConstructL(aPassphrase);
+ return self;
+ }
+
+CPassphrase* CPassphrase::NewL(TInt aTimeout, CStreamStore& aStore,
+ const TDesC& aPassphrase)
+ {
+ CPassphrase* self = NewLC(aTimeout, aStore, aPassphrase);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CPassphrase::CPassphrase(CStreamStore& aStore, TInt aTimeout)
+ : iStore(aStore)
+ {
+ iExpires = (aTimeout != KTimeoutNever);
+ if (iExpires)
+ {
+ iExpiryTime.UniversalTime();
+ iExpiryTime += TTimeIntervalSeconds(aTimeout);
+ }
+ }
+
+void CPassphrase::ConstructL(TStreamId aStreamId, const TDesC& aPassphrase)
+ {
+ iStreamId = aStreamId;
+
+ RStoreReadStream stream;
+ stream.OpenLC(iStore, iStreamId);
+ HBufC8* encryptedMasterKey = HBufC8::NewLC(stream, 10000); //some large number
+ CPBEncryptionData* encryptionData = CPBEncryptionData::NewLC(stream);
+ iSecurity = CPBEncryptSet::NewL(*encryptionData, *encryptedMasterKey, aPassphrase);
+ CleanupStack::PopAndDestroy(3); // encryptionData, encryptedMasterKey, stream
+ iSecureStore = CSecureStore::NewL(iStore, *iSecurity);
+ }
+
+void CPassphrase::ConstructL(const TDesC& aPassphrase)
+ {
+ TPBPassword password(aPassphrase);
+ iSecurity = CPBEncryptSet::NewL(password, ECipherAES_CBC_256);
+
+ RStoreWriteStream stream;
+ iStreamId = stream.CreateLC(iStore);
+ stream << iSecurity->EncryptedMasterKey();
+ iSecurity->EncryptionData().ExternalizeL(stream);
+ stream.CommitL();
+ CleanupStack::PopAndDestroy(); // stream
+
+ iSecureStore = CSecureStore::NewL(iStore, *iSecurity);
+ }
+
+CPassphrase::~CPassphrase()
+ {
+ delete iSecurity;
+ delete iSecureStore;
+ }
+
+TInt CPassphrase::TimeRemainingL(const TTime& aCurrentTime) const
+ {
+ if (iExpires)
+ {
+ TTimeIntervalSeconds seconds;
+ User::LeaveIfError(iExpiryTime.SecondsFrom(aCurrentTime, seconds));
+ TInt result = seconds.Int();
+ if (result < 0)
+ {
+ result = 0;
+ }
+ return result;
+ }
+ else
+ {
+ return KTimeoutNever;
+ }
+ }
+
+void CPassphrase::RevertStore(TAny* aStore)
+ {
+ // This is a CleanupItem
+ CStreamStore* store = reinterpret_cast<CStreamStore*>(aStore);
+ TRAP_IGNORE(store->RevertL());
+ }
+
+void CPassphrase::ChangePassphraseL(const TDesC& aNewPassphrase)
+ {
+ iSecurity->ChangePasswordL(aNewPassphrase);
+
+ TCleanupItem cleanupStore(RevertStore, &iStore);
+ CleanupStack::PushL(cleanupStore);
+
+ RStoreWriteStream stream;
+ stream.ReplaceLC(iStore, iStreamId);
+ stream << iSecurity->EncryptedMasterKey();
+ iSecurity->EncryptionData().ExternalizeL(stream);
+ stream.CommitL();
+ CleanupStack::PopAndDestroy(); // stream
+ iStore.CommitL();
+ CleanupStack::Pop(); // cleanupStore
+ }
+
+CStreamStore& CPassphrase::Store() const
+ {
+ return *iSecureStore;
+ }
+
+TStreamId CPassphrase::StreamId() const
+ {
+ return iStreamId;
+ }
+
+// CPassphraseManager //////////////////////////////////////////////////////////
+
+CPassphraseManager* CPassphraseManager::NewL(CStreamStore& aStore)
+ {
+ return new (ELeave) CPassphraseManager(aStore);
+ }
+
+CPassphraseManager::CPassphraseManager(CStreamStore& aStore)
+ : CActive(EPriorityNormal), iStore(aStore)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CPassphraseManager::~CPassphraseManager()
+ {
+ Cancel();
+ iCache.ResetAndDestroy();
+ }
+
+/** Return a cached passphrase if present, otherwise return NULL. */
+CPassphrase* CPassphraseManager::GetCachedPassphrase(TStreamId aStreamId)
+ {
+ for (TInt i = 0 ; i < iCache.Count() ; ++i)
+ {
+ CPassphrase* p = iCache[i];
+ if (p->StreamId() == aStreamId)
+ {
+ return p;
+ }
+ }
+
+ return NULL;
+ }
+
+void CPassphraseManager::GetPassphrase(TStreamId aStreamId,
+ TInt aTimeout,
+ CPassphrase*& aPassphrase,
+ TRequestStatus& aStatus)
+ {
+ ASSERT(iTimeout >= KTimeoutNever);
+ CPassphrase* p = GetCachedPassphrase(aStreamId);
+ if (p)
+ {
+ aPassphrase = p;
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, KErrNone);
+ }
+ else
+ {
+ iRetries = KRetryCount;
+ iClientStatus = &aStatus;
+ aStatus = KRequestPending;
+ iNewPassphraseStream = aStreamId;
+ iTimeout = aTimeout;
+ iNewPassphrasePtr = &aPassphrase;
+ iState = EGetPassphrase;
+ TPasswordManager::KeystorePassword(iNewPassphrase, iStatus);
+ SetActive();
+ }
+ }
+
+void CPassphraseManager::CreatePassphrase(TInt aTimeout,
+ CPassphrase*& aPassphrase,
+ TRequestStatus& aStatus)
+ {
+ ASSERT(iTimeout >= -1);
+ iClientStatus = &aStatus;
+ aStatus = KRequestPending;
+ iTimeout = aTimeout;
+ iNewPassphrasePtr = &aPassphrase;
+ iState = ECreatePassphrase;
+ TPasswordManager::CreatePassword(iNewPassphrase, iStatus);
+ SetActive();
+ }
+
+void CPassphraseManager::ChangePassphrase(TStreamId aStreamId, TRequestStatus& aStatus)
+ {
+ iRetries = KRetryCount;
+ iClientStatus = &aStatus;
+ aStatus = KRequestPending;
+ iNewPassphraseStream = aStreamId;
+ iState = EChangePassphrase;
+
+ TPINParams params;
+ params.iPINLabel =
+ FSResources::Strings()[FSResources::EPinGLabel];
+ params.iMinLength = 0;
+ params.iMaxLength = KMaxPINLength;
+
+ FSDialog::Dialog()->ChangePIN(params, EFalse, iOldPassphrase, iNewPassphrase, iStatus);
+ SetActive();
+ }
+
+void CPassphraseManager::RunL()
+ {
+ User::LeaveIfError(iStatus.Int());
+
+ switch (iState)
+ {
+ case EGetPassphrase:
+ {
+ TRAPD(err, HandleGetPassphraseL());
+ if (err == KErrBadPassphrase && --iRetries > 0)
+ {
+ TPasswordManager::KeystorePassword(iNewPassphrase, iStatus, ETrue);
+ SetActive();
+ }
+ else
+ {
+ User::LeaveIfError(err);
+ }
+ }
+ break;
+
+ case ECreatePassphrase:
+ {
+ CPassphrase* phrase = CPassphrase::NewLC(iTimeout, iStore,
+ iNewPassphrase);
+ *iNewPassphrasePtr = phrase;
+ User::LeaveIfError(iCache.Append(phrase));
+ CleanupStack::Pop(phrase);
+ Complete(KErrNone);
+ }
+ break;
+
+ case EChangePassphrase:
+ {
+ CPassphrase* phrase = NULL;
+ TRAPD(err, phrase = CPassphrase::NewL( 0,
+ iStore,
+ iNewPassphraseStream,
+ iOldPassphrase));
+
+ if(KErrBadPassphrase == err && --iRetries > 0)
+ {
+ TPINParams params;
+ params.iPINLabel = FSResources::Strings()[FSResources::EPinGLabel];
+ params.iMinLength = 0;
+ params.iMaxLength = KMaxPINLength;
+
+ FSDialog::Dialog()->ChangePIN(params, ETrue, iOldPassphrase, iNewPassphrase, iStatus);
+ SetActive();
+ break;
+ }
+
+ if(KErrNone != err)
+ {
+ User::Leave(err);
+ }
+
+ CleanupStack::PushL(phrase);
+
+ phrase->ChangePassphraseL(iNewPassphrase);
+ RemoveCachedPassphrases(phrase->StreamId());
+ CleanupStack::PopAndDestroy(phrase);
+ Complete(KErrNone);
+ }
+ break;
+
+ default:
+ PanicServer(EPanicInvalidState);
+ }
+
+ }
+
+void CPassphraseManager::HandleGetPassphraseL()
+ {
+ CPassphrase* phrase = CPassphrase::NewLC(iTimeout, iStore,
+ iNewPassphraseStream,
+ iNewPassphrase);
+ *iNewPassphrasePtr = phrase;
+ User::LeaveIfError(iCache.Append(phrase));
+ CleanupStack::Pop(phrase);
+ Complete(KErrNone);
+ }
+
+TInt CPassphraseManager::RunError(TInt aError)
+ {
+ Complete(aError);
+ return KErrNone;
+ }
+
+void CPassphraseManager::DoCancel()
+ {
+ TPasswordManager::Cancel();
+ RunError(KErrCancel);
+ }
+
+void CPassphraseManager::Complete(TInt aError)
+ {
+ iNewPassphrasePtr = NULL;
+ iState = EIdle;
+ if (iClientStatus)
+ {
+ User::RequestComplete(iClientStatus, aError);
+ }
+ }
+
+void CPassphraseManager::ExpireCacheL()
+ {
+ TTime timeNow;
+ timeNow.UniversalTime();
+
+ for (TInt i = iCache.Count() - 1; i >= 0; --i)
+ {
+ CPassphrase* passphrase = iCache[i];
+ if (passphrase->TimeRemainingL(timeNow) == 0)
+ {
+ iCache.Remove(i);
+ delete passphrase;
+ }
+ }
+ }
+
+void CPassphraseManager::RemoveCachedPassphrases(TStreamId aStreamId)
+ {
+ for (TInt i = iCache.Count() - 1; i >= 0; --i)
+ {
+ CPassphrase* passphrase = iCache[i];
+ if (aStreamId == KNullStreamId || passphrase->StreamId() == aStreamId)
+ {
+ iCache.Remove(i);
+ delete passphrase;
+ }
+ }
+ }
+
+TInt CPassphraseManager::TimeRemainingL(TStreamId aStreamId)
+ {
+ CPassphrase* passphrase = GetCachedPassphrase(aStreamId);
+ if (passphrase)
+ {
+ TTime timeNow;
+ timeNow.UniversalTime();
+ return passphrase->TimeRemainingL(timeNow);
+ }
+ else
+ {
+ return 0;
+ }
+ }