cryptoservices/filebasedcertificateandkeystores/test/tkeystore/t_open.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
--- /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;
+}