--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cryptoservices/filebasedcertificateandkeystores/test/tkeystore/t_open.cpp Wed Jul 08 11:25:26 2009 +0100
@@ -0,0 +1,1298 @@
+/*
+* Copyright (c) 2003-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 <e32base.h>
+#include "t_keystore_actions.h"
+#include "t_keystore_defs.h"
+#include "t_input.h"
+#include <asn1enc.h>
+#include <asn1dec.h>
+#include <x509cert.h>
+#include <x509keys.h>
+#include <asymmetrickeys.h>
+
+/*static*/ CTestAction* COpenKey::NewL(RFs& aFs, CConsoleBase& aConsole, Output& aOut, const TTestActionSpec& aTestActionSpec)
+{
+ CTestAction* self = COpenKey::NewLC(aFs, aConsole, aOut, aTestActionSpec);
+ CleanupStack::Pop(self);
+ return self;
+}
+
+/*static*/ CTestAction* COpenKey::NewLC(RFs& aFs, CConsoleBase& aConsole, Output& aOut, const TTestActionSpec& aTestActionSpec)
+{
+ COpenKey* self = new (ELeave) COpenKey(aFs, aConsole, aOut);
+ CleanupStack::PushL(self);
+ self->ConstructL(aTestActionSpec);
+ return self;
+}
+
+COpenKey::~COpenKey()
+{
+ iKeys.Close();
+}
+
+void COpenKey::PerformAction(TRequestStatus& aStatus)
+{
+ switch (iState)
+ {
+ case EListKeysPreOpen:
+ {// Currently uses the first store, change to check the script for a specific store
+ CUnifiedKeyStore* keyStore = CSharedKeyStores::TheUnifiedKeyStores().operator[](iKeystore);
+ ASSERT(keyStore); // Flag it up
+ if (keyStore)
+ keyStore->List(iKeys, iFilter, aStatus);
+
+ iState = EOpenKey;
+ }
+ break;
+
+ case EOpenKey:
+ {
+ CUnifiedKeyStore* keyStore = CSharedKeyStores::TheUnifiedKeyStores().operator[](iKeystore);
+ ASSERT(keyStore); // Flag it up
+
+ TInt keyCount = iKeys.Count();
+
+ TInt i;
+ for (i = 0; i < keyCount; i++)
+ {
+ CCTKeyInfo* keyInfo = iKeys[i];
+
+ if (keyInfo->Label() == *iLabel)
+ {
+ switch (iType)
+ {
+ case ERSASign:
+ keyStore->Open(*keyInfo, iRSASigner, aStatus);
+ break;
+ case EDSASign:
+ keyStore->Open(*keyInfo, iDSASigner, aStatus);
+ break;
+ case EDecrypt:
+ keyStore->Open(*keyInfo, iDecryptor, aStatus);
+ break;
+ case EDH:
+ keyStore->Open(*keyInfo, iDH, aStatus);
+ break;
+ }
+ break;
+ }
+ }
+ iState = EFinished;
+ if (i == keyCount)
+ {
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, KErrNotFound);
+ }
+ }
+ break;
+
+ case EFinished:
+ {
+ HBufC* label = 0;
+ iKeys.Close();
+ if (aStatus.Int() == KErrNone)
+ {
+ switch (iType)
+ {
+ case ERSASign:
+ if (iRSASigner)
+ {
+ label = iRSASigner->Label().AllocLC();
+ iRSASigner->Release();
+ }
+ break;
+ case EDSASign:
+ if (iDSASigner)
+ {
+ label = iDSASigner->Label().AllocLC();
+ iDSASigner->Release();
+ }
+ break;
+ case EDecrypt:
+ if (iDecryptor)
+ {
+ label = iDecryptor->Label().AllocLC();
+ iDecryptor->Release();
+ }
+ case EDH:
+ if (iDH)
+ {
+ label = iDH->Label().AllocLC();
+ iDH->Release();
+ }
+ break;
+ }
+ if (*label != *iLabel)
+ aStatus = KErrBadName;
+ CleanupStack::PopAndDestroy(label);
+ }
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, aStatus.Int());
+ if (aStatus.Int()==iExpectedResult)
+ {
+ iResult = ETrue;
+ }
+ else
+ {
+ iResult = EFalse;
+ }
+
+ iActionState = EPostrequisite;
+ }
+ break;
+ default:
+ ASSERT(EFalse);
+ }
+
+}
+
+void COpenKey::PerformCancel()
+ {
+ CUnifiedKeyStore* keystore = CSharedKeyStores::TheUnifiedKeyStores().operator[](iKeystore);
+ ASSERT(keystore);
+
+ switch (iState)
+ {
+ case EOpenKey:
+ keystore->CancelList();
+ break;
+
+ case EFinished:
+ keystore->CancelOpen();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+void COpenKey::Reset()
+ {
+ iState = EListKeysPreOpen;
+ iKeys.Close();
+ if (iRSASigner)
+ {
+ iRSASigner->Release();
+ iRSASigner = NULL;
+ }
+ if (iDSASigner)
+ {
+ iDSASigner->Release();
+ iDSASigner = NULL;
+ }
+ if (iDecryptor)
+ {
+ iDecryptor->Release();
+ iDecryptor = NULL;
+ }
+ if (iDH)
+ {
+ iDH->Release();
+ iDH = NULL;
+ }
+ }
+
+void COpenKey::DoReportAction()
+{
+ _LIT(KDeleting, "Opening...");
+ iOut.writeString(KDeleting);
+ iOut.writeNewLine();
+}
+
+void COpenKey::DoCheckResult(TInt aError)
+{
+ if (iFinished)
+ {
+ TBuf<256> buf;
+ if (aError == KErrNone)
+ {
+ _LIT(KSuccessful, "Key open success\n");
+ buf.Format(KSuccessful);
+ iConsole.Write(buf);
+ iOut.writeString(buf);
+ iOut.writeNewLine();
+ }
+ else
+ {
+ if (aError!=iExpectedResult)
+ {
+ _LIT(KFailed, "!!!Key open failure %d!!!\n");
+ buf.Format(KFailed, aError);
+ iConsole.Write(buf);
+ iOut.writeString(buf);
+ }
+ else
+ {
+ _LIT(KFailed, "Key open failed, but expected\n");
+ iConsole.Write(KFailed);
+ iOut.writeString(KFailed);
+ }
+
+ iOut.writeNewLine();
+ }
+ }
+}
+
+COpenKey::COpenKey(RFs& aFs, CConsoleBase& aConsole, Output& aOut)
+: CKeyStoreTestAction(aFs, aConsole, aOut)
+{}
+
+void COpenKey::ConstructL(const TTestActionSpec& aTestActionSpec)
+ {
+ TInt pos = 0, err = 0;
+ CKeyStoreTestAction::ConstructL(aTestActionSpec);
+ SetKeyType(Input::ParseElement(aTestActionSpec.iActionBody, KOpenStart, KOpenEnd, pos, err));
+ iState = EListKeysPreOpen;
+
+ }
+void COpenKey::SetKeyType(const TDesC8& aKeyType)
+{
+ if (aKeyType.Compare(KAlgRSA)==0)
+ {
+ iType = ERSASign;
+ }
+ else if (aKeyType.Compare(KAlgDSA)==0)
+ {
+ iType = EDSASign;
+ }
+ else if (aKeyType.Compare(KDecryptUsage)==0)
+ {
+ iType = EDecrypt;
+ }
+ else if (aKeyType.Compare(KAlgDH)==0)
+ {
+ iType = EDH;
+ }
+}
+
+
+////////////////////////////////////
+// CSign
+////////////////////////////////////
+/*static*/ CTestAction* CSign::NewL(RFs& aFs, CConsoleBase& aConsole, Output& aOut, const TTestActionSpec& aTestActionSpec)
+{
+ CTestAction* self = CSign::NewLC(aFs, aConsole, aOut, aTestActionSpec);
+ CleanupStack::Pop(self);
+ return self;
+}
+
+/*static*/ CTestAction* CSign::NewLC(RFs& aFs, CConsoleBase& aConsole, Output& aOut, const TTestActionSpec& aTestActionSpec)
+{
+ CSign* self = new (ELeave) CSign(aFs, aConsole, aOut);
+ CleanupStack::PushL(self);
+ self->ConstructL(aTestActionSpec);
+ return self;
+}
+
+CSign::~CSign()
+{
+ iKeys.Close();
+ delete iReadText;
+ delete iExportedPublicKey;
+ delete iRSASignature;
+ delete iDSASignature;
+ delete iHash;
+}
+
+void CSign::PerformAction(TRequestStatus& aStatus)
+{
+ // Jump straight to final state if an error occured
+ if (aStatus.Int()!=KErrNone)
+ {
+ iState=EFinished;
+ }
+
+ switch (iState)
+ {
+ case EListKeysPreOpen:
+ {
+ CUnifiedKeyStore* keyStore = CSharedKeyStores::TheUnifiedKeyStores().operator[](iKeystore);
+ ASSERT(keyStore); // Flag it up
+ if (keyStore)
+ keyStore->List(iKeys, iFilter, aStatus);
+
+ iState = EOpenKey;
+ }
+ break;
+
+ case EOpenKey:
+ {
+ CUnifiedKeyStore* keyStore = CSharedKeyStores::TheUnifiedKeyStores().operator[](iKeystore);
+ ASSERT(keyStore); // Flag it up
+
+ TInt keyCount = iKeys.Count();
+
+ TInt i;
+ for (i = 0; i < keyCount; i++)
+ {
+ CCTKeyInfo* keyInfo = iKeys[i];
+
+ if (keyInfo->Label() == *iLabel)
+ {
+ switch (iType)
+ {
+ case ERSASign:
+ keyStore->Open(*keyInfo, iRSASigner, aStatus);
+ break;
+ case EDSASign:
+ keyStore->Open(*keyInfo, iDSASigner, aStatus);
+ break;
+ case EDH:
+ case EDecrypt:
+ break; // Nothing to do, for the compiler
+ }
+ break;
+ }
+ }
+ iState = ESign;
+ if (i == keyCount)
+ {
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, KErrNotFound);
+ }
+ }
+ break;
+
+ case ESign:
+ {
+ switch (iType)
+ {
+ case ERSASign:
+ {
+ if (iHash)
+ {
+ if (iFailHashDigest) // Don't hash it, fail deliberately
+ iRSASigner->Sign(*iReadText,iRSASignature,aStatus);
+ else // message gets signed by the keystore
+ iRSASigner->SignMessage(*iReadText,iRSASignature,aStatus);
+ }
+ else
+ {
+ iRSASigner->Sign(*iReadText,iRSASignature,aStatus);
+ }
+ }
+ break;
+ case EDSASign:
+ {
+ if (iHash)
+ {
+ if (iFailHashDigest) // Don't hash it, deliberately fail it
+ iDSASigner->Sign(*iReadText,iDSASignature,aStatus);
+ else // message gets signed by the keystore
+ iDSASigner->SignMessage(*iReadText,iDSASignature,aStatus);
+ }
+ else
+ {
+ iDSASigner->Sign(*iReadText,iDSASignature,aStatus);
+ }
+ }
+ break;
+ default:
+ ASSERT(EFalse);
+ }
+ iState = EExportPublic;
+ }
+ break;
+
+ case EExportPublic:
+ {
+ CUnifiedKeyStore* keyStore = CSharedKeyStores::TheUnifiedKeyStores().operator[](iKeystore);
+ ASSERT(keyStore); // Flag it up
+ TInt keyCount = iKeys.Count();
+ TInt i;
+ for (i = 0; i < keyCount; i++)
+ {
+ CCTKeyInfo* keyInfo = iKeys[i];
+
+ if (keyInfo->Label() == *iLabel)
+ {
+ iExportHandle = keyInfo->Handle();
+
+ switch (iType)
+ {
+ case ERSASign:
+ keyStore->ExportPublic(iExportHandle, iExportedPublicKey, aStatus);
+ break;
+ case EDSASign:
+ keyStore->ExportPublic(iExportHandle, iExportedPublicKey, aStatus);
+ break;
+ case EDH:
+ case EDecrypt:
+ break; // Nothing to do, for the compiler
+ }
+ break;
+ }
+ }
+ iState = EVerify;
+ if (i == keyCount)
+ {
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, KErrNotFound);
+ }
+ }
+ break;
+
+ case EVerify:
+ {
+ TInt keyCount = iKeys.Count();
+ TInt i;
+ for (i = 0; i < keyCount; i++)
+ {
+ CCTKeyInfo* keyInfo = iKeys[i];
+
+ if (keyInfo->Label() == *iLabel)
+ {
+ iExportHandle = keyInfo->Handle();
+ CX509SubjectPublicKeyInfo* ki =
+ CX509SubjectPublicKeyInfo::NewLC(*iExportedPublicKey);
+
+ switch (iType)
+ {
+ case ERSASign:
+ {
+ TX509KeyFactory factory;
+ CRSAPublicKey* key = factory.RSAPublicKeyL(ki->KeyData());
+ CleanupStack::PushL(key);
+
+ CRSAPKCS1v15Verifier* verifier = NULL;
+
+ if (iHash) // Must compare with hash of original data
+ {
+ verifier = CRSAPKCS1v15Verifier::NewLC(*key);
+ iHash->Reset();
+ iVerifyResult = verifier->VerifyL(iHash->Final(*iReadText), *iRSASignature);
+ }
+ else
+ {
+ verifier = CRSAPKCS1v15Verifier::NewLC(*key);
+ iVerifyResult = verifier->VerifyL(*iReadText, *iRSASignature);
+ }
+
+ _LIT(KReturned, "Returned... ");
+ iOut.writeString(KReturned);
+ iOut.writeNewLine();
+
+ CleanupStack::PopAndDestroy(2, key);
+ }
+ break;
+ case EDSASign:
+ {
+ TX509KeyFactory factory;
+ CDSAPublicKey* key = factory.DSAPublicKeyL(ki->EncodedParams(), ki->KeyData());
+ CleanupStack::PushL(key);
+
+ CDSAVerifier* verifier = CDSAVerifier::NewLC(*key);
+ if (iHash) // Must compare with hash of original value
+ {
+ iHash->Reset();
+ iVerifyResult = verifier->VerifyL(iHash->Final(*iReadText),*iDSASignature);
+ }
+ else
+ {
+ iVerifyResult = verifier->VerifyL(*iReadText,*iDSASignature);
+ }
+ _LIT(KReturned, "Returned... ");
+ iOut.writeString(KReturned);
+ iOut.writeNewLine();
+ CleanupStack::PopAndDestroy(verifier);
+ CleanupStack::PopAndDestroy(key);
+ }
+ break;
+ default:
+ ASSERT(EFalse);
+
+ }
+ CleanupStack::PopAndDestroy(ki);
+ }
+ }
+ iState = EFinished;
+ TRequestStatus* status = &aStatus;
+ if (!iVerifyResult)
+ {
+ _LIT(KVerifyFail, "**Verify failed**");
+ iOut.writeString(KVerifyFail);
+ iOut.writeNewLine();
+
+ // Flat verify failed as KErrGeneral
+ if (aStatus.Int() == KErrNone)
+ {
+ aStatus = KErrGeneral;
+ }
+ }
+ User::RequestComplete(status, aStatus.Int());
+ }
+ break;
+
+ case EFinished:
+ {
+ iActionState = EPostrequisite;
+ iResult = (aStatus.Int() == iExpectedResult);
+
+ if ((aStatus.Int() != KErrNone)&&(aStatus!=KErrNoMemory))
+ {
+ _LIT(KExportFail," !Failed when exporting public key! ");
+ iOut.writeString(KExportFail);
+ }
+
+ iKeys.Close();
+ switch (iType)
+ {
+ case ERSASign:
+ if (iRSASigner)
+ iRSASigner->Release();
+ break;
+ case EDSASign:
+ if (iDSASigner)
+ iDSASigner->Release();
+ break;
+ case EDecrypt:
+ if (iDecryptor)
+ iDecryptor->Release();
+ case EDH:
+ if (iDH)
+ iDH->Release();
+ break;
+ }
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, aStatus.Int());
+ }
+ break;
+ default:
+ ASSERT(EFalse);
+ }
+
+}
+
+void CSign::PerformCancel()
+ {
+ CUnifiedKeyStore* keystore = CSharedKeyStores::TheUnifiedKeyStores().operator[](iKeystore);
+ ASSERT(keystore);
+
+ switch (iState)
+ {
+ case EOpenKey:
+ keystore->CancelList();
+ break;
+
+ case ESign:
+ keystore->CancelOpen();
+ break;
+
+ case EExportPublic:
+ switch (iType)
+ {
+ case ERSASign:
+ ASSERT(iRSASigner);
+ iRSASigner->CancelSign();
+ break;
+
+ case EDSASign:
+ ASSERT(iDSASigner);
+ iDSASigner->CancelSign();
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case EVerify:
+ keystore->CancelExportPublic();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+void CSign::Reset()
+ {
+ iState = EListKeysPreOpen;
+ iKeys.Close();
+ if (iRSASigner)
+ {
+ iRSASigner->Release();
+ iRSASigner = NULL;
+ }
+ if (iDSASigner)
+ {
+ iDSASigner->Release();
+ iDSASigner = NULL;
+ }
+ delete iExportedPublicKey;
+ iExportedPublicKey = NULL;
+ delete iRSASignature;
+ iRSASignature = NULL;
+ delete iDSASignature;
+ iDSASignature = NULL;
+ }
+
+void CSign::DoReportAction()
+{
+ _LIT(KSigning, "Signing... ");
+ iOut.writeString(KSigning);
+ iOut.writeNewLine();
+}
+
+void CSign::DoCheckResult(TInt aError)
+{
+ if (iFinished)
+ {
+ TBuf<256> buf;
+ if (aError == KErrNone)
+ {
+ iOut.writeNewLine();
+ _LIT(KSuccessful, "Sign success\n");
+ buf.Format(KSuccessful);
+ iConsole.Write(buf);
+ iOut.writeString(buf);
+ iOut.writeNewLine();
+ }
+ else
+ {
+ if (aError!=iExpectedResult)
+ {
+ _LIT(KFailed, "!!!Sign failure %d!!!\n");
+ buf.Format(KFailed, aError);
+ iConsole.Write(buf);
+ iOut.writeString(buf);
+ }
+ else
+ {
+ _LIT(KFailed, "Sign failed, but expected\n");
+ iConsole.Write(KFailed);
+ iOut.writeString(KFailed);
+ }
+
+ iOut.writeNewLine();
+ }
+ }
+}
+
+CSign::CSign(RFs& aFs, CConsoleBase& aConsole, Output& aOut)
+: CKeyStoreTestAction(aFs, aConsole, aOut)
+{}
+
+void CSign::ConstructL(const TTestActionSpec& aTestActionSpec)
+{
+ CKeyStoreTestAction::ConstructL(aTestActionSpec);
+
+ SetKeyType(Input::ParseElement(aTestActionSpec.iActionBody, KOpenStart));
+ SetDigestSignL(Input::ParseElement(aTestActionSpec.iActionBody, KSignDigestStart));
+ SetSignText(Input::ParseElement(aTestActionSpec.iActionBody, KTextStart, KTextEnd));
+
+ iFilter.iPolicyFilter = TCTKeyAttributeFilter::EAllKeys;
+
+ iState = EListKeysPreOpen;
+}
+
+
+void CSign::SetKeyType(const TDesC8& aKeyType)
+{
+ if (aKeyType.Compare(KAlgRSA)==0)
+ {
+ iType = ERSASign;
+ }
+ else if (aKeyType.Compare(KAlgDSA)==0)
+ {
+ iType = EDSASign;
+ }
+ else if (aKeyType.Compare(KDecryptUsage)==0)
+ {
+ iType = EDecrypt;
+ }
+ else if (aKeyType.Compare(KAlgDH)==0)
+ {
+ iType = EDH;
+ }
+}
+
+void CSign::SetDigestSignL(const TDesC8& aSignDigestDesc)
+{
+ TLex8 lexer(aSignDigestDesc);
+ TInt digest = 0;
+ lexer.Val(digest);
+
+ if (digest > 0)
+ iHash = CMessageDigestFactory::NewDigestL(CMessageDigest::ESHA1);
+
+ if (digest==2)
+ iFailHashDigest = ETrue;
+}
+
+void CSign::SetSignText(const TDesC8& aText)
+{
+ iReadText = HBufC8::NewMax(aText.Size());
+ if (iReadText)
+ {
+ TPtr8 theText(iReadText->Des());
+ theText.FillZ();
+ theText.Copy(aText);
+ }
+}
+
+////////////////////////////////////
+// CDecrypt
+////////////////////////////////////
+/*static*/ CTestAction* CDecrypt::NewL(RFs& aFs, CConsoleBase& aConsole, Output& aOut, const TTestActionSpec& aTestActionSpec)
+{
+ CTestAction* self = CDecrypt::NewLC(aFs, aConsole, aOut, aTestActionSpec);
+ CleanupStack::Pop(self);
+ return self;
+}
+
+/*static*/ CTestAction* CDecrypt::NewLC(RFs& aFs, CConsoleBase& aConsole, Output& aOut, const TTestActionSpec& aTestActionSpec)
+{
+ CDecrypt* self = new (ELeave) CDecrypt(aFs, aConsole, aOut);
+ CleanupStack::PushL(self);
+ self->ConstructL(aTestActionSpec);
+ return self;
+}
+
+CDecrypt::~CDecrypt()
+{
+ iKeys.Close();
+ delete iReadText;
+ delete iPlainText;
+ delete iPublic;
+}
+
+void CDecrypt::PerformAction(TRequestStatus& aStatus)
+{
+ // Jump straight to final state if an error occured
+ if (aStatus.Int()!=KErrNone)
+ {
+ iState=EFinished;
+ }
+
+ switch (iState)
+ {
+ case EListKeysPreOpen:
+ {// Currently uses the first store, change to check the script for a specific store
+ CUnifiedKeyStore* keyStore = CSharedKeyStores::TheUnifiedKeyStores().operator[](iKeystore);
+ ASSERT(keyStore); // Flag it up
+ if (keyStore)
+ keyStore->List(iKeys, iFilter, aStatus);
+
+ iState = EOpenKey;
+ }
+ break;
+
+ case EOpenKey:
+ {
+ CUnifiedKeyStore* keyStore = CSharedKeyStores::TheUnifiedKeyStores().operator[](iKeystore);
+ ASSERT(keyStore); // Flag it up
+
+ TInt keyCount = iKeys.Count();
+
+ TInt i;
+ for (i = 0; i < keyCount; i++)
+ {
+ CCTKeyInfo* keyInfo = iKeys[i];
+
+ if (keyInfo->Label() == *iLabel)
+ {
+ keyStore->Open(*keyInfo, iDecryptor, aStatus);
+ break;
+ }
+ }
+ iState = EExportPublic;
+ if (i == keyCount)
+ {
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, KErrNotFound);
+ }
+ }
+ break;
+
+ case EExportPublic:
+ {
+ if (aStatus.Int()!=KErrNone)
+ {
+ _LIT(KSignFail," !Failed when opening! ");
+ iOut.writeString(KSignFail);
+ iState=EFinished;
+ // need to set it to true so that test is true if some error was expected
+ iVerifyResult=ETrue;
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, aStatus.Int());
+ break;
+ }
+
+ CUnifiedKeyStore* keyStore = CSharedKeyStores::TheUnifiedKeyStores().operator[](iKeystore);
+ ASSERT(keyStore); // Flag it up
+
+ TInt keyCount = iKeys.Count();
+
+ TInt i;
+ for (i = 0; i < keyCount; i++)
+ {
+ CCTKeyInfo* keyInfo = iKeys[i];
+
+ if (keyInfo->Label() == *iLabel)
+ {
+ iExportHandle = keyInfo->Handle();
+
+ keyStore->ExportPublic(iExportHandle, iPublic, aStatus);
+ break;
+ }
+ }
+ iState = EDecrypt;
+ if (i == keyCount)
+ {
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, KErrNotFound);
+ }
+ }
+ break;
+
+ case EDecrypt:
+ {
+
+ if (aStatus.Int()!=KErrNone)
+ {
+ iState=EFinished;
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, aStatus.Int());
+ break;
+ }
+
+ CX509SubjectPublicKeyInfo* ki =
+ CX509SubjectPublicKeyInfo::NewLC(*iPublic);
+
+ TX509KeyFactory factory;
+ CRSAPublicKey* key = factory.RSAPublicKeyL(ki->KeyData());
+ CleanupStack::PushL(key);
+
+ // Encrypt with public key
+ CRSAPKCS1v15Encryptor* encryptor = CRSAPKCS1v15Encryptor::NewLC(*key);
+ HBufC8* cipherText = HBufC8::NewLC(encryptor->MaxOutputLength());
+ TPtr8 cipherTextPtr = cipherText->Des();
+
+ encryptor->EncryptL(*iReadText, cipherTextPtr);
+
+ // Now decrypt again
+ iPlainText = HBufC8::NewMaxL(100);
+ iPlainTextPtr.Set(iPlainText->Des());
+ iDecryptor->Decrypt(*cipherText, iPlainTextPtr, aStatus);
+
+ CleanupStack::PopAndDestroy(cipherText);
+ CleanupStack::PopAndDestroy(encryptor);
+ CleanupStack::PopAndDestroy(key);
+ CleanupStack::PopAndDestroy(ki);
+
+ iState = EFinished;
+ }
+ break;
+
+ case EFinished:
+ {
+ if (aStatus == KErrNone && (!iPlainText ||
+ *iPlainText != *iReadText))
+ {
+ aStatus = KErrGeneral; // Decryption failed
+ }
+
+ iActionState = EPostrequisite;
+ iResult = (aStatus.Int() == iExpectedResult);
+
+ if (iDecryptor)
+ {
+ iDecryptor->Release();
+ }
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, aStatus.Int());
+ }
+ break;
+ default:
+ ASSERT(EFalse);
+ }
+
+}
+
+void CDecrypt::PerformCancel()
+ {
+ CUnifiedKeyStore* keystore = CSharedKeyStores::TheUnifiedKeyStores().operator[](iKeystore);
+ ASSERT(keystore);
+
+ switch (iState)
+ {
+ case EOpenKey:
+ keystore->CancelList();
+ break;
+
+ case EExportPublic:
+ keystore->CancelOpen();
+ break;
+
+ case EDecrypt:
+ keystore->CancelExportPublic();
+ break;
+
+ case EFinished:
+ ASSERT(iDecryptor);
+ iDecryptor->CancelDecrypt();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+void CDecrypt::Reset()
+ {
+ iState = EListKeysPreOpen;
+ iKeys.Close();
+ if (iDecryptor)
+ {
+ iDecryptor->Release();
+ iDecryptor = NULL;
+ }
+ delete iPlainText;
+ iPlainText = NULL;
+ delete iPublic;
+ iPublic = NULL;
+ }
+
+void CDecrypt::DoReportAction()
+{
+ _LIT(KSigning, "Decrypting... ");
+ iOut.writeString(KSigning);
+ iOut.writeNewLine();
+// iOut.writeString(*iReadText);
+// iOut.writeNewLine();
+}
+
+void CDecrypt::DoCheckResult(TInt aError)
+{
+ if (iFinished)
+ {
+ TBuf<256> buf;
+ if (aError == KErrNone)
+ {
+ iOut.writeNewLine();
+ _LIT(KSuccessful, "Decrypt success\n");
+ buf.Format(KSuccessful);
+ iConsole.Write(buf);
+ iOut.writeString(buf);
+ iOut.writeNewLine();
+ }
+ else
+ {
+ if (aError!=iExpectedResult)
+ {
+ _LIT(KFailed, "!!!Decrypt failure %d!!!\n");
+ buf.Format(KFailed, aError);
+ iConsole.Write(buf);
+ iOut.writeString(buf);
+ }
+ else
+ {
+ _LIT(KFailed, "Decrypt failed, but expected\n");
+ iConsole.Write(KFailed);
+ iOut.writeString(KFailed);
+ }
+
+ iOut.writeNewLine();
+ }
+ }
+}
+
+CDecrypt::CDecrypt(RFs& aFs, CConsoleBase& aConsole, Output& aOut)
+ : CKeyStoreTestAction(aFs, aConsole, aOut), iPlainTextPtr(0,0)
+{}
+
+void CDecrypt::ConstructL(const TTestActionSpec& aTestActionSpec)
+{
+ CKeyStoreTestAction::ConstructL(aTestActionSpec);
+
+ SetSignText(Input::ParseElement(aTestActionSpec.iActionBody, KTextStart));
+ iFilter.iPolicyFilter = TCTKeyAttributeFilter::EAllKeys;
+
+ iState = EListKeysPreOpen;
+}
+
+void CDecrypt::SetSignText(const TDesC8& aText)
+{
+ iReadText = HBufC8::NewMax(aText.Size());
+ if (iReadText)
+ {
+ TPtr8 theText(iReadText->Des());
+ theText.FillZ();
+ theText.Copy(aText);
+ }
+}
+
+////////////////////////////////////
+// CDerive
+////////////////////////////////////
+
+/*static*/ CTestAction* CDerive::NewL(RFs& aFs, CConsoleBase& aConsole, Output& aOut, const TTestActionSpec& aTestActionSpec)
+{
+ CTestAction* self = CDerive::NewLC(aFs, aConsole, aOut, aTestActionSpec);
+ CleanupStack::Pop(self);
+ return self;
+}
+
+/*static*/ CTestAction* CDerive::NewLC(RFs& aFs, CConsoleBase& aConsole, Output& aOut, const TTestActionSpec& aTestActionSpec)
+{
+ CDerive* self = new (ELeave) CDerive(aFs, aConsole, aOut);
+ CleanupStack::PushL(self);
+ self->ConstructL(aTestActionSpec);
+ return self;
+}
+
+CDerive::~CDerive()
+ {
+ iKeys.Close();
+ iN.Close();
+ iG.Close();
+ if (iDH)
+ {
+ iDH->Release();
+ }
+ delete iPublicKey;
+ delete iOutput;
+ delete iRemote;
+ }
+
+void CDerive::PerformAction(TRequestStatus& aStatus)
+ {
+ // Jump straight to final state if an error occured
+ if (aStatus.Int()!=KErrNone)
+ {
+ iState=EFinished;
+ }
+
+ switch (iState)
+ {
+ case EListKeysPreOpen:
+ {
+ CUnifiedKeyStore* keyStore = CSharedKeyStores::TheUnifiedKeyStores().operator[](iKeystore);
+ ASSERT(keyStore); // Flag it up
+ if (keyStore)
+ keyStore->List(iKeys, iFilter, aStatus);
+
+ iState = EOpenKey;
+ }
+ break;
+
+ case EOpenKey:
+ {
+ CUnifiedKeyStore* keyStore = CSharedKeyStores::TheUnifiedKeyStores().operator[](iKeystore);
+ ASSERT(keyStore); // Flag it up
+
+ TInt keyCount = iKeys.Count();
+
+ TInt i;
+ for (i = 0; i < keyCount; i++)
+ {
+ CCTKeyInfo* keyInfo = iKeys[i];
+
+ if (keyInfo->Label() == *iLabel)
+ {
+ keyStore->Open(*keyInfo, iDH, aStatus);
+ break;
+ }
+ }
+ iState = EExportPublic;
+ if (i == keyCount)
+ {
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, KErrNotFound);
+ }
+ }
+ break;
+
+ case EExportPublic:
+ {
+ ASSERT(iDH);
+ iDH->PublicKey(iN, iG, iPublicKey, aStatus);
+ iState = EDerive;
+ }
+ break;
+
+ case EDerive:
+ {
+ if (aStatus.Int()!=KErrNone)
+ {
+ iState=EFinished;
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, aStatus.Int());
+ break;
+ }
+
+ ASSERT(iPublicKey);
+ iDH->Agree(iRemote->PublicKey(), iOutput, aStatus);
+
+ iState = EFinished;
+ }
+ break;
+
+ case EFinished:
+ {
+ if (aStatus.Int()==KErrNone)
+ {
+ CDH* dh = CDH::NewLC(iRemote->PrivateKey());
+ const HBufC8* output = dh->AgreeL(*iPublicKey);
+ CleanupStack::PopAndDestroy(dh);
+
+ if (aStatus == KErrNone && (!iOutput ||
+ *iOutput != *output))
+ {
+ aStatus = KErrGeneral; // Agree failed
+ }
+
+ delete const_cast<HBufC8*>(output);
+ }
+
+ iActionState = EPostrequisite;
+ iResult = (aStatus.Int() == iExpectedResult);
+
+ if (aStatus != KErrNone)
+ {
+ _LIT(KSignFail," !Failed when agreeing key!");
+ iOut.writeString(KSignFail);
+ }
+
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, aStatus.Int());
+ }
+ break;
+ default:
+ ASSERT(EFalse);
+ }
+ }
+
+void CDerive::PerformCancel()
+ {
+ CUnifiedKeyStore* keystore = CSharedKeyStores::TheUnifiedKeyStores().operator[](iKeystore);
+ ASSERT(keystore);
+
+ switch (iState)
+ {
+ case EOpenKey:
+ keystore->CancelList();
+ break;
+
+ case EExportPublic:
+ keystore->CancelOpen();
+ break;
+
+ case EDerive:
+ keystore->CancelExportPublic();
+ break;
+
+ case EFinished:
+ ASSERT(iDH);
+ iDH->CancelAgreement();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+void CDerive::Reset()
+ {
+ iState = EListKeysPreOpen;
+ iKeys.Close();
+ if (iDH)
+ {
+ iDH->Release();
+ iDH = NULL;
+ }
+ delete iPublicKey;
+ iPublicKey = NULL;
+ delete iOutput;
+ iOutput = NULL;
+ }
+
+void CDerive::DoReportAction()
+{
+ _LIT(KSigning, "Deriving key... ");
+ iOut.writeString(KSigning);
+ iOut.writeNewLine();
+}
+
+void CDerive::DoCheckResult(TInt aError)
+{
+ if (iFinished)
+ {
+ TBuf<256> buf;
+ if (aError == KErrNone)
+ {
+ iOut.writeNewLine();
+ _LIT(KSuccessful, "Derive success\n");
+ buf.Format(KSuccessful);
+ iConsole.Write(buf);
+ iOut.writeString(buf);
+ iOut.writeNewLine();
+ }
+ else
+ {
+ if (aError!=iExpectedResult)
+ {
+ _LIT(KFailed, "!!!Derive failure %d!!!\n");
+ buf.Format(KFailed, aError);
+ iConsole.Write(buf);
+ iOut.writeString(buf);
+ }
+ else
+ {
+ _LIT(KFailed, "Derive failed, but expected\n");
+ iConsole.Write(KFailed);
+ iOut.writeString(KFailed);
+ }
+
+ iOut.writeNewLine();
+ }
+ }
+}
+
+CDerive::CDerive(RFs& aFs, CConsoleBase& aConsole, Output& aOut)
+ : CKeyStoreTestAction(aFs, aConsole, aOut)
+{}
+
+void CDerive::ConstructL(const TTestActionSpec& aTestActionSpec)
+{
+ CKeyStoreTestAction::ConstructL(aTestActionSpec);
+
+ // Set parameters
+ HBufC8* nData = Input::ParseElementHexL(aTestActionSpec.iActionBody, _L8("<n>"));
+ CleanupStack::PushL(nData);
+ iN = RInteger::NewL(*nData);
+ CleanupStack::PopAndDestroy(nData);
+ HBufC8* gData = Input::ParseElementHexL(aTestActionSpec.iActionBody, _L8("<g>"));
+ CleanupStack::PushL(gData);
+ iG = RInteger::NewL(*gData);
+ CleanupStack::PopAndDestroy(gData);
+
+ // Generate 'remote' key pair
+ RInteger n = RInteger::NewL(iN);
+ CleanupStack::PushL(n);
+ RInteger g = RInteger::NewL(iG);
+ CleanupStack::PushL(g);
+ iRemote = CDHKeyPair::NewL(n, g);
+ CleanupStack::Pop(2); // n, g
+
+ iFilter.iPolicyFilter = TCTKeyAttributeFilter::EAllKeys;
+
+ iState = EListKeysPreOpen;
+}