cryptoservices/certificateandkeymgmt/tpkcs10/tcertrequeststep.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cryptoservices/certificateandkeymgmt/tpkcs10/tcertrequeststep.cpp	Wed Jul 08 11:25:26 2009 +0100
@@ -0,0 +1,1054 @@
+/*
+* Copyright (c) 2007-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: 
+*
+*/
+
+
+
+
+/**
+ @file  
+ @internalTechnology
+*/
+ 
+#include "tcertrequeststep.h"
+#include <f32file.h> 
+#include <e32std.h>
+
+_LIT(KKeyLabel, "new pkcs10 test key"); 
+
+// CertRequest tester active.
+CPKCS10TesterActive::CPKCS10TesterActive( CTestExecuteLogger& aLogger ) : 
+   CActive( EPriorityStandard ),
+   iLogger( aLogger )
+	{
+	CActiveScheduler::Add( this );
+	User::LeaveIfError(iFs.Connect());
+	}
+
+CPKCS10TesterActive::~CPKCS10TesterActive()
+	{
+   	delete iDN;
+	iDN=NULL;	 
+	delete iCertRequest;
+	iCertRequest=NULL;			
+ 	delete iOutputASN1Encoding;	
+ 	iOutputASN1Encoding=NULL; 			
+ 	delete iSecondOutputASN1Encoding;
+ 	iSecondOutputASN1Encoding=NULL;
+ 	if (iKeyInfo)
+ 	{
+		iKeyInfo->Release();
+		iKeyInfo=NULL;	 			
+ 	}
+	delete iKeyData;
+	iKeyData=NULL;
+	if(iKeyStore) // debug.
+	{
+	    iKeyStore->Cancel();
+		delete iKeyStore;
+		iKeyStore=NULL;	
+	}
+	iFs.Close ();
+	}
+	
+void CPKCS10TesterActive::DeleteAllKeysL()
+	{
+	// Delete Key store.
+	INFO_PRINTF1(_L("deleting store keys"));
+  	iKeyStore = CUnifiedKeyStore::NewL(iFs);
+  	CleanupStack::PushL(iKeyStore); 
+  	iKeyStore->Initialize(iStatus);  
+	
+	iState = EDeleteAllInit;
+	SetActive();
+   	CActiveScheduler::Start();
+   	   	
+   	iKeys.Close();
+   	CleanupStack::Pop(iKeyStore);
+   	delete iKeyStore;
+	iKeyStore = NULL;	
+	
+	}
+
+TVerdict CPKCS10TesterActive::doActiveCertRequestL(CCertificateRequestStep* aStep)
+	{
+	
+	iTestSuccess= EFail;
+	INFO_PRINTF1(_L("Active tester for Cert Request started. "));
+	iStepPointer = aStep;
+		
+    DeleteAllKeysL();
+	
+    INFO_PRINTF1(_L("initialising keystore"));
+    
+	// Initialise Key store.
+  	iKeyStore = CUnifiedKeyStore::NewL(iFs);
+  	CleanupStack::PushL(iKeyStore); 
+  	iKeyStore->Initialize(iStatus);  
+	iState = EInitKeyStore; 
+	SetActive();
+   	CActiveScheduler::Start();
+   	
+   	// After encoding was produced it checks correctness
+    if(iRunError==KErrNone)
+     {
+	     if( !(iStepPointer->iOOMCondition) &&verifyCertReqEncodingL()!=EPass  )
+		 {
+			  iTestSuccess= EFail;
+		 }
+		 else    
+		 {
+		 	  iTestSuccess= EPass;
+		 }
+
+		 
+		 if( iTestSuccess && iStepPointer->iGenerateSecondRequest) // if cert was reused.
+		 {
+			// compare encoding of first and second request.
+			if((iOutputASN1Encoding->Compare(iSecondOutputASN1Encoding->Des())) == 0)
+			{
+		 		INFO_PRINTF1(_L("Reuse verified"));
+		 	}
+			else
+		 	{
+		 		iTestSuccess= EFail;
+		 		//iStepPointerSetTestStepResult(EFail);
+		 		INFO_PRINTF1(_L("New output encoding is not what is expected"));		
+		 	} 
+		 }
+     }
+  	
+   	CleanupStack::Pop(iKeyStore);  
+    return iTestSuccess;
+}
+	
+TInt CPKCS10TesterActive::RunError(TInt aError)
+	{
+	iRunError =aError;
+	iKeyStore->Cancel();
+	if(iCertRequest)
+	{
+		iCertRequest->Cancel();	
+	}
+	CActiveScheduler::Stop();
+	return KErrNone;
+	
+	}
+	
+void CPKCS10TesterActive::RunL()
+	{
+	iRunError =KErrNone;
+	
+ 	User::LeaveIfError(iStatus.Int());
+   
+	switch(iState)
+		{
+		
+		case EDeleteAllInit:
+			INFO_PRINTF1(_L("  listing existing keys\n"));
+			iKeyStore->List(iKeys, iKeyFilter, iStatus);
+			iState = EDeleteAllDelete;
+			SetActive();
+			break;
+			
+		case EDeleteAllDelete:
+			if (iKeys.Count() == 0)
+				{
+				// key log is empty
+				iKeys.Close();
+				CActiveScheduler::Stop();
+				break;
+				}
+			
+			INFO_PRINTF1(_L("  deleting key\n"));
+			iKeyStore->DeleteKey(*iKeys[0], iStatus);
+			iState = EDeleteAllDelete;
+			SetActive();
+			iKeys[0]->Release();
+			iKeys.Remove(0);
+			break;
+		
+		case EInitKeyStore:
+			{
+	  		INFO_PRINTF1(_L("Importing keys"));
+ 			TFileName filename;
+ 			filename = iStepPointer->iPrivateKey;
+			RFile file;
+			User::LeaveIfError(file.Open(iFs,filename,EFileRead));
+			CleanupClosePushL(file);
+			TInt size;
+			User::LeaveIfError(file.Size(size));
+			iKeyData = HBufC8::NewMaxL(size);
+			TPtr8 keyPtr = iKeyData->Des();
+			User::LeaveIfError(file.Read(keyPtr));			
+			CleanupStack::PopAndDestroy(); // file
+
+			TTime start(0.0); 
+			TTime end(0.0); 
+			
+			// Assumes only one keystore
+			// Check parameters!
+		 	ASSERT(iKeyInfo == NULL);      
+			iKeyStore->ImportKey(0, *(iKeyData), EPKCS15UsageSign, KKeyLabel,0, start, end,iKeyInfo, iStatus);
+	  		iState = EImportKey;
+	  		SetActive();
+			break;
+			}
+	  	case EImportKey:
+			{
+			INFO_PRINTF1(_L("Setting security policy for new stored key"));
+			TSecureId secureId(0x101f7784); // Application secure ID 
+			TSecurityPolicy securePolicy(secureId,ECapabilityReadUserData);
+			iKeyStore->SetUsePolicy(iKeyInfo->Handle(),securePolicy,iStatus);
+			iState = EKeyPolicy;
+ 			SetActive();
+ 			break;
+		   	}
+		case EKeyPolicy:
+			{
+			iAttrCollection=CPKCS10Attributes::NewL();
+ 			CleanupStack::PushL(iAttrCollection); 
+			INFO_PRINTF1(_L("Adding generic attributes"));		
+ 			AddGenericAttributesL();
+ 			INFO_PRINTF1(_L("Adding Challenge password"));
+ 			AddChallengePasswordL();
+ 			INFO_PRINTF1(_L("Adding V3 extensions"));
+ 			AddV3ExtensionsL();
+ 			INFO_PRINTF1(_L("Generating distinguished name"));
+ 			iDN=MakeDistinguishedNameL();
+ 			CleanupStack::PushL(iDN);
+   	 		INFO_PRINTF1(_L("Generating cert request"));
+   	 		iCertRequest=CPKCS10Request::NewL(*iDN,*iKeyInfo,iAttrCollection);
+     		CleanupStack::PushL(iCertRequest);
+     		INFO_PRINTF1(_L("Setting digest algorithm"));
+			TAlgorithmId digestAlgo=iStepPointer->ConvertNameToDigestId(iStepPointer->iDigestAlg);
+			iCertRequest->SetDigestAlgL(digestAlgo);
+ 			INFO_PRINTF1(_L("Requesting cert request encoding"));
+ 	  		
+ 	  		// Clean up
+ 	  		CleanupStack::Pop(iCertRequest);
+ 			CleanupStack::Pop(iDN);
+    	 	CleanupStack::Pop(iAttrCollection);
+    	  	iAttrCollection=NULL;  
+			iOutputASN1Encoding=NULL;
+			iCertRequest->CreateEncoding(iOutputASN1Encoding,iStatus);
+			iState=EGenerateCertRequest; 
+	 		SetActive();     
+	  		break;	
+			}
+		case EGenerateCertRequest:
+			{ 
+			
+			// Use to debug encoding 			
+  			// iStepPointer->OutputEncodingToFileL(iOutputASN1Encoding->Des()); //debug
+			// Used for cert request reuse cases  
+			if(iStepPointer->iGenerateSecondRequest)
+				{       
+						INFO_PRINTF1(_L("Reusing instance of CPKCS10Request"));
+				        if(iStepPointer->iRepopulateDataRequest)
+				        {
+				         	iAttrCollection=CPKCS10Attributes::NewL();
+				            CleanupStack::PushL(iAttrCollection); 
+				        	AddGenericAttributesL();
+				 			AddChallengePasswordL();
+				 			AddV3ExtensionsL();
+				 			// deletes previous value of iDN.
+				 			delete iDN;
+				 			iDN=MakeDistinguishedNameL();
+				 			CleanupStack::PushL(iDN);
+				   	 		TAlgorithmId digestAlgo2=iStepPointer->ConvertNameToDigestId(iStepPointer->iDigestAlg);
+							// Repopulates data.
+							CleanupStack::PushL(iCertRequest);
+							iCertRequest->SetDigestAlgL(digestAlgo2);
+							iCertRequest->SetDistinguishedNameL(*iDN);
+							iCertRequest->SetAttributes(iAttrCollection);
+							iCertRequest->SetKeyInfoL(*iKeyInfo);
+							// Clean up
+							CleanupStack::Pop(iCertRequest);
+							CleanupStack::Pop(iDN);
+    						CleanupStack::Pop(iAttrCollection);
+    						iAttrCollection=NULL;		
+				        }
+				        INFO_PRINTF1(_L("Launches second cert request"));
+				        iSecondOutputASN1Encoding=NULL;
+				        iCertRequest->CreateEncoding(iSecondOutputASN1Encoding,iStatus);
+				        iState=EGenerateSecondCertRequest;
+				}
+				else
+				{
+					 // if no reuse case delete keys and prepare for final state
+						INFO_PRINTF1(_L("Deleting key"));
+ 		 				iKeyStore->DeleteKey(*iKeyInfo, iStatus);
+ 		 				iState=EDeleteKey;
+				}
+			
+ 		  	SetActive();  
+ 		 	break;	
+			}
+		case EGenerateSecondCertRequest:
+			{
+			INFO_PRINTF1(_L("Deleting key"));
+ 		 	iKeyStore->DeleteKey(*iKeyInfo,iStatus);
+ 		 	iState=EDeleteKey;
+ 		 	SetActive();
+ 		 	break;
+			}
+		case EDeleteKey:
+			{
+		    iKeyInfo->Release();  
+			iKeyInfo = NULL;
+		 	CActiveScheduler::Stop();
+ 		    break;	
+			}
+ 		default:
+			{
+		  	INFO_PRINTF1(_L("Cert Request Active tester: State corrupted."));
+			User::Leave(KErrCorrupt);
+			}
+ 		} 
+ 		
+   	return; 
+}
+
+	
+CCertificateRequestStep::~CCertificateRequestStep()
+/**
+ * Destructor
+ */
+	{   
+ 		delete iActiveObjTest;
+ 		delete iSched;
+	}
+
+CCertificateRequestStep::CCertificateRequestStep()
+{
+	SetTestStepName(KCertificateRequestStep);
+}
+
+TVerdict CCertificateRequestStep::doTestStepPreambleL()
+{
+	__UHEAP_MARK;	
+	User::LeaveIfError (iFs.Connect());
+	
+	// initializes data.
+           
+	// Read values form config file 
+	GetIntFromConfig(ConfigSection(), _L("Expected_error"), iExpectedError);	
+    GetStringFromConfig(ConfigSection(), _L("DN_country"), iDN_country);
+    GetStringFromConfig(ConfigSection(), _L("DN_state"), iDN_state);
+    GetStringFromConfig(ConfigSection(), _L("DN_locality"), iDN_locality);
+    GetStringFromConfig(ConfigSection(), _L("DN_organization"), iDN_organization);
+    GetStringFromConfig(ConfigSection(), _L("DN_unit"), iDN_unit);
+    GetStringFromConfig(ConfigSection(), _L("DN_common"), iDN_common);
+    GetStringFromConfig(ConfigSection(), _L("DN_email"), iDN_email);
+    GetStringFromConfig(ConfigSection(), _L("PrivateKey"),iPrivateKey);
+    GetStringFromConfig(ConfigSection(), _L("OPENSSL_certreq"),iOPENSSLCertReq);
+    GetStringFromConfig(ConfigSection(), _L("KeyAlg"),iKeyAlg);
+    GetStringFromConfig(ConfigSection(), _L("ChallengePassword"),iChallengePassword);
+    GetStringFromConfig(ConfigSection(), _L("DigestAlg"),iDigestAlg);
+    GetBoolFromConfig(ConfigSection(), _L("OOMCondition"),iOOMCondition);
+    GetBoolFromConfig(ConfigSection(), _L("GenerateSecondRequest"),iGenerateSecondRequest);
+    GetBoolFromConfig(ConfigSection(), _L("RepopulateDataRequest"),iRepopulateDataRequest);
+    GetIntFromConfig(ConfigSection(), _L("ElemCertReqCount"),iElemCertReqCount);
+    GetIntFromConfig(ConfigSection(), _L("ElemCertInfoCount"),iElemCertInfoCount);
+    GetIntFromConfig(ConfigSection(), _L("CertReqVer"),iCertReqVer);
+    GetIntFromConfig(ConfigSection(), _L("ElemSubPubKeytInfoCount"),iElemSubPubKeytInfoCount);
+    GetIntFromConfig(ConfigSection(), _L("ElemKeyAlgIdenCount"),iElemKeyAlgIdenCount);
+    GetIntFromConfig(ConfigSection(), _L("ElemSigAlgIdenCount"),iElemSigAlgIdenCount);
+    GetIntFromConfig(ConfigSection(), _L("Attribute_count"),iAttribute_count );
+    
+    // Read generic Attributes (ARRAY).
+    TInt index(0);
+	TName fGenericAttrOID;
+	fGenericAttrOID.Format(_L("Attribute_OID_%d"), index);
+	TName fGenericAttrValue;
+	fGenericAttrValue.Format(_L("Attribute_value_%d"), index); 
+	
+	TPtrC genericAttrOIDName;
+	TPtrC genericAttrValueName;
+    
+   	while (GetStringFromConfig(ConfigSection(), fGenericAttrOID, genericAttrOIDName)
+			&& GetStringFromConfig(ConfigSection(), fGenericAttrValue, genericAttrValueName))
+	{
+	   
+	    iArrayGenAttrOID.AppendL(genericAttrOIDName);
+	    iArrayGenAttrValue.AppendL(genericAttrValueName);
+		index++;
+		fGenericAttrOID.Format(_L("Attribute_OID_%d"), index);
+		fGenericAttrValue.Format(_L("Attribute_value_%d"), index);
+		
+	}	
+		
+	// Read the v3 extension attributes (Array)
+	index=0;
+    TName fV3AttrOID;
+	fV3AttrOID.Format(_L("V3_Extension_OID_%d"), index);
+	TName fV3AttrCritical;
+	fV3AttrCritical.Format(_L("V3_Extension_Critical_%d"), index); 
+	TName fV3AttrValue;
+	fV3AttrValue.Format(_L("V3_Extension_Value_%d"), index); 
+
+	TPtrC v3AttrOID;
+	TBool v3AttrCritical;
+	TPtrC v3AttrValue;
+	
+   	while (GetStringFromConfig(ConfigSection(), fV3AttrOID, v3AttrOID)
+			&& GetBoolFromConfig(ConfigSection(), fV3AttrCritical, v3AttrCritical)
+			&& GetStringFromConfig(ConfigSection(), fV3AttrValue, v3AttrValue))
+		{
+	    iArrayV3AttrOID.AppendL(v3AttrOID);
+	    iArrayV3AttrCritical.AppendL(v3AttrCritical);
+	    iArrayV3AttrValue.AppendL(v3AttrValue);
+		index++;
+		fV3AttrOID.Format(_L("V3_Extension_OID_%d"), index);
+		fV3AttrCritical.Format(_L("V3_Extension_Critical_%d"), index); 
+		fV3AttrValue.Format(_L("V3_Extension_Value_%d"), index); 
+		}	
+		
+	SetTestStepResult(EPass);
+	return TestStepResult();
+}
+
+
+TVerdict CCertificateRequestStep::doTestStepL()
+{
+	if (!iOOMCondition)
+		{
+		 doTestL(); 
+		}
+	else
+		{
+ 		return doOOMTestL();
+	    }	
+
+   	 return TestStepResult();
+}
+
+TVerdict CCertificateRequestStep::doOOMTestL()
+{
+	TVerdict verdict = EFail;
+ 	TInt countAfter = 0;
+	TInt countBefore = 0;
+ 	for (TInt oomCount = 0; ; oomCount++)
+ 		{
+ 		INFO_PRINTF2(_L("\n ==== Number of memory allocations %d ===="), oomCount);
+ 		verdict = EFail;
+ 		__UHEAP_RESET;
+ 		__UHEAP_SETFAIL(RHeap::EDeterministic, oomCount);
+ 		countBefore = User::CountAllocCells();
+ 		TRAPD(error, doTestL());// ----> This is the actual test that runs under OOM conditions.
+ 		countAfter = User::CountAllocCells();
+ 		__UHEAP_RESET;
+ 		if (error != KErrNoMemory)  
+ 			{
+ 			verdict = EPass;
+ 			INFO_PRINTF2(_L("OOM Status %d"),error);
+			INFO_PRINTF1(_L("Test outcome : Passed"));
+ 			break;
+ 			}
+ 		else
+ 			{
+ 			if (countBefore != countAfter)
+ 				{
+ 				INFO_PRINTF2(_L("OOM Status %d"),error);
+ 				INFO_PRINTF2(_L("OOM Failed at %d"), oomCount);
+ 				SetTestStepResult(verdict);  
+ 				break;
+ 				}
+ 			}
+ 		INFO_PRINTF2(_L("OOM Failed Point status %d"), error);
+		}
+	INFO_PRINTF3(_L("Heap alloc count ok: %d final vs %d initial"), countAfter,countBefore);
+ 	SetTestStepResult(verdict);
+ 	if (verdict==EFail)
+	 	{
+ 		User::Leave(KErrGeneral);	 		
+	 	}	 	
+ 	return verdict;
+	}	
+	
+
+
+	
+void CCertificateRequestStep::doTestL()
+{
+    
+    iSched=new(ELeave) CActiveScheduler; 
+    CleanupStack::PushL(iSched);  
+	CActiveScheduler::Install(iSched);
+	
+	
+	iActiveObjTest = new (ELeave) CPKCS10TesterActive(Logger());
+	CleanupStack::PushL(iActiveObjTest);
+
+	if (iActiveObjTest->doActiveCertRequestL(this) != EPass)
+	 {
+	 	SetTestStepResult(EFail);
+	 	INFO_PRINTF1(_L("Verification FAIL."));
+	 	// To keep happy out of memory test.
+	 	User::Leave(KErrNoMemory);
+
+	 }
+	 else
+	 {
+	 	INFO_PRINTF1(_L("Verification PASS."));	
+	 }
+
+	 CleanupStack::PopAndDestroy(iActiveObjTest);
+	 iActiveObjTest = NULL;
+	 CleanupStack::PopAndDestroy(iSched);
+	 iSched=NULL;
+	 
+ }
+
+TVerdict CPKCS10TesterActive::verifyCertReqEncodingL()
+{   
+    TVerdict certReqCheck= EPass;
+	INFO_PRINTF1(_L("Verifiying cert request encoding"));
+	TInt pos(0);
+	 
+	CArrayPtrFlat<TASN1DecGeneric>* certReq= TASN1DecSequence().DecodeDERLC(*iOutputASN1Encoding,pos);
+	// Verifies Number of elements in cert request.
+	if(certReq->Count() != iStepPointer->iElemCertReqCount)
+	{
+		INFO_PRINTF1(_L("VERIFICATION FAILED: Incorrect number of elements in cert request"));
+		certReqCheck= EFail;
+	}
+	
+	CArrayPtrFlat<TASN1DecGeneric>* certReqInfo=TASN1DecSequence().DecodeDERLC(*certReq->At(0));  
+	// Verifies Number of elements in cert request info.
+	if(certReqInfo->Count() != iStepPointer->iElemCertInfoCount)
+	{
+		INFO_PRINTF1(_L("VERIFICATION FAILED: Incorrect number of elements in cert request info"));
+		certReqCheck= EFail;
+	}
+		  
+	TASN1DecInteger decInt;
+	TInt version = decInt.DecodeDERShortL(*certReqInfo->At(0));
+	// Verifies expected version in cert request info.
+	if(version != iStepPointer->iCertReqVer)
+	{
+		INFO_PRINTF1(_L("VERIFICATION FAILED: Incorrect version in cert request info"));
+		certReqCheck= EFail;
+	}
+
+	pos = 0;
+	CX500DistinguishedName* dn = CX500DistinguishedName::NewLC(certReqInfo->At(1)->Encoding());
+	// Verifies distinguished name.
+	if(!(iDN->ExactMatchL(*dn)))
+		{
+		INFO_PRINTF1(_L("VERIFICATION FAILED: Incorrect distinguished name encoding"));
+		certReqCheck= EFail;
+	}
+	
+	CArrayPtrFlat<TASN1DecGeneric>* subjPubKeyInfo = TASN1DecSequence().DecodeDERLC(*certReqInfo->At(2));
+	// Verifies number of elements in public key info.
+	if( iStepPointer->iElemSubPubKeytInfoCount != subjPubKeyInfo->Count())
+	{
+		INFO_PRINTF1(_L("VERIFICATION FAILED: Incorrect number of elements in public key info."));
+		certReqCheck= EFail;
+	}
+	
+	CArrayPtrFlat<TASN1DecGeneric>* keyAlg = TASN1DecSequence().DecodeDERLC(*subjPubKeyInfo->At(0));
+	HBufC* keyAlgOid = TASN1DecObjectIdentifier().DecodeDERL(*keyAlg->At(0));
+	CleanupStack::PushL(keyAlgOid);
+	// Verifies number of elements in public key algorithm identifier.
+	if( keyAlg->Count() != iStepPointer->iElemKeyAlgIdenCount)
+	{
+		INFO_PRINTF1(_L("VERIFICATION FAILED: Incorrect number of elements in public key algorithm identifier."));
+		certReqCheck= EFail;
+	}
+
+    HBufC8* pubKeyData = TASN1DecBitString().ExtractOctetStringL(*subjPubKeyInfo->At(1));
+	CleanupStack::PushL(pubKeyData);
+    // Verifies number of elements in signature algorithm identifier.
+	CArrayPtrFlat<TASN1DecGeneric>* sigAlg = TASN1DecSequence().DecodeDERLC(*certReq->At(1));
+	
+	if( sigAlg->Count() != iStepPointer->iElemSigAlgIdenCount)
+	{
+		INFO_PRINTF1(_L("VERIFICATION FAILED: Incorrect number of elements in signature algorithm identifier."));
+		certReqCheck= EFail;
+	}
+	
+	
+	HBufC* sigAlgOid = TASN1DecObjectIdentifier().DecodeDERL(*sigAlg->At(0));
+	CleanupStack::PushL(sigAlgOid);
+	
+	HBufC8* signature = TASN1DecBitString().ExtractOctetStringL(*certReq->At(2));
+	CleanupStack::PushL(signature);
+	
+	CMessageDigest* digest = NULL;
+	
+	switch (iStepPointer->ConvertNameToDigestId(iStepPointer->iDigestAlg))
+		{
+		case ESHA1:
+			digest = CSHA1::NewL();
+			break;
+
+		case EMD2:
+			digest = CMD2::NewL();
+			break;
+
+		case EMD5:
+			digest = CMD5::NewL();
+			break;
+
+		default:
+				User::Leave(KErrCorrupt);
+		}
+	CleanupStack::PushL(digest);
+	 
+	if (iStepPointer->ConvertNameToEKeyAlgorithm(iStepPointer->iKeyAlg) == CCTKeyInfo::ERSA)
+	{	
+	    // Verifies key.
+		if(*keyAlgOid != KRSA)
+		{
+			INFO_PRINTF1(_L("VERIFICATION FAILED: Expecting RSA key."));
+			certReqCheck= EFail;
+		}
+				
+		// Verifies digest.
+		switch  (iStepPointer->ConvertNameToDigestId(iStepPointer->iDigestAlg))
+		{
+			case ESHA1:
+			{
+				if(*sigAlgOid != KSHA1WithRSA)
+				{
+					INFO_PRINTF1(_L("VERIFICATION FAILED: Expecting RSA with SHA1 signature."));
+					certReqCheck= EFail;
+				}
+			}
+			break;
+			case EMD2:
+			{
+				if(*sigAlgOid != KMD2WithRSA)
+				{
+					INFO_PRINTF1(_L("VERIFICATION FAILED: Expecting RSA with MD2 signature."));
+					certReqCheck= EFail;
+				}
+			}
+			break;
+			case EMD5:
+			{
+				if(*sigAlgOid != KMD5WithRSA)
+				{
+					INFO_PRINTF1(_L("VERIFICATION FAILED: Expecting RSA with MD5 signature."));
+					certReqCheck= EFail;
+				}
+			}
+			break;
+			default:
+			{
+				INFO_PRINTF1(_L("VERIFICATION FAILED: Unrecognised signature algorithm."));
+				User::Leave(KErrCorrupt);
+			}
+			break;
+		}
+		        
+        // Checks RSA signature.
+        // There are doubts about the validity of the method below
+ /*		CRSAPublicKey* pubKey = TX509KeyFactory().RSAPublicKeyL(*pubKeyData);
+		CleanupStack::PushL(pubKey);
+		
+		RInteger sigInt = RInteger::NewL(*signature);
+		CleanupStack::PushL(sigInt);
+		CRSASignature* sig = CRSASignature::NewL(sigInt);
+		CleanupStack::Pop(); // sigInt
+		CleanupStack::PushL(sig);
+		CRSAPKCS1v15Verifier* verifier = CRSAPKCS1v15Verifier::NewLC(*pubKey);
+		digest->Update(certReq->At(0)->Encoding());
+		
+		if(!(verifier->VerifyL(digest->Final(),*sig)))
+		{
+			INFO_PRINTF1(_L("VERIFICATION FAILED: RSA Signature verification failed."));
+			User::Leave(KErrGeneral);
+		}   
+		CleanupStack::PopAndDestroy(verifier);	
+		CleanupStack::PopAndDestroy(sig);
+		CleanupStack::PopAndDestroy(pubKey);   */
+	}
+	else if (iStepPointer->ConvertNameToEKeyAlgorithm(iStepPointer->iKeyAlg)== CCTKeyInfo::EDSA)
+	{
+				// Verifies key 
+		if(*keyAlgOid != KDSA)
+		{
+				certReqCheck= EFail;
+		}
+		INFO_PRINTF1(_L("DSA key algorithm OID CORRECT"));
+		// Verifies digest
+	    if(*sigAlgOid != KDSAWithSHA1)
+		{
+				certReqCheck= EFail;
+		}
+		INFO_PRINTF1(_L("Signature algorithm OID CORRECT"));
+		
+		CDSAParameters* params = TX509KeyFactory().DSAParametersL(keyAlg->At(1)->Encoding());
+		CleanupStack::PushL(params);
+		CDSAPublicKey* pubKey = TX509KeyFactory().DSAPublicKeyL(*params, *pubKeyData);
+		CleanupStack::PushL(pubKey);
+
+		// Test sig
+		CDSASignature* sig = TX509KeyFactory().DSASignatureL(*signature);
+		CleanupStack::PushL(sig);
+
+		CDSAVerifier* verifier = CDSAVerifier::NewLC(*pubKey);
+		digest->Update(certReq->At(0)->Encoding());
+		// Verifies signature.
+		if(!(verifier->VerifyL(digest->Final(),*sig)))
+		{
+				certReqCheck= EFail;
+		}
+			
+		CleanupStack::PopAndDestroy(verifier);
+		CleanupStack::PopAndDestroy(sig);
+		CleanupStack::PopAndDestroy(pubKey);
+		CleanupStack::PopAndDestroy(params);
+	}
+	else
+	{
+		INFO_PRINTF1(_L("VERIFICATION FAILED: Invalid key algorithm."));
+		certReqCheck= EFail;
+	}
+    
+    // Verifies number of attributes.
+    CArrayPtrFlat<TASN1DecGeneric>* attrSet = TASN1DecSet().DecodeDERLC(*certReqInfo->At(3));
+    
+    if(attrSet->Count() != iStepPointer->iAttribute_count)
+	{
+			INFO_PRINTF1(_L("VERIFICATION FAILED: Number of attributes incorrect"));
+			certReqCheck= EFail;
+	}
+		
+	// makes binary compare if key is not DSA.
+ 	if (iStepPointer->ConvertNameToEKeyAlgorithm(iStepPointer->iKeyAlg) != CCTKeyInfo::EDSA)  // Do not compare if we have DSA signatures, these are not deterministic!
+	{
+		if(!(CompareRequestToOPENSSLReqL()))
+		{
+				INFO_PRINTF1(_L("VERIFICATION FAILED: Binary compare with OPENSSL cert request does not match"));
+				certReqCheck= EFail;
+		}
+	}
+	else
+	{
+		INFO_PRINTF1(_L("No binary compare becuase is a DSA cert req."));	
+	}   
+     
+    INFO_PRINTF1(_L("Verification completed."));
+   
+    // pop and destroy: attrSet, digest, signature, sigAlgOid, sigAlg, pubKeyData
+    // keyAlgOid, keyAlg, elmSubjPubKeyInfo, dnChecker, certReqInfo, certReqASN1
+    CleanupStack::PopAndDestroy(12,certReq);
+	return certReqCheck;	
+}
+
+TVerdict CCertificateRequestStep::doTestStepPostambleL()
+{
+ 	iArrayGenAttrOID.Close();
+ 	iArrayGenAttrValue.Close();
+	iArrayV3AttrOID.Close();
+	iArrayV3AttrCritical.Close();
+	iArrayV3AttrValue.Close();
+	__UHEAP_MARKEND;
+	
+	return TestStepResult();
+}
+
+void cleanuparray(TAny* aArray)
+{
+	CArrayPtrFlat<CX520AttributeTypeAndValue>* array=(CArrayPtrFlat<CX520AttributeTypeAndValue>*)aArray;
+	array->ResetAndDestroy();
+	delete array;
+}
+	
+CX500DistinguishedName* CPKCS10TesterActive::MakeDistinguishedNameL()
+{
+    CArrayPtrFlat<CX520AttributeTypeAndValue>* array = new(ELeave) CArrayPtrFlat<CX520AttributeTypeAndValue>(7);
+	TCleanupItem cleanup(cleanuparray, array);	
+	CleanupStack::PushL(cleanup);
+	array->SetReserveL(7);
+	
+	HBufC8 *converter = HBufC8::NewMaxLC(iStepPointer->iDN_common.Length());
+    converter->Des().Copy(iStepPointer->iDN_common);	
+	CX520AttributeTypeAndValue* commonName = CX520AttributeTypeAndValue::NewLC(ECommonName,*converter);
+	array->AppendL(commonName);
+	CleanupStack::Pop(commonName);
+	CleanupStack::PopAndDestroy(converter);
+	
+	converter = HBufC8::NewMaxLC(iStepPointer->iDN_country.Length());
+    converter->Des().Copy(iStepPointer->iDN_country);
+	CX520AttributeTypeAndValue* country = CX520AttributeTypeAndValue::NewLC(ECountryName,*converter);
+	array->AppendL(country);
+	CleanupStack::Pop(country);
+	CleanupStack::PopAndDestroy(converter);
+	
+	converter = HBufC8::NewMaxLC(iStepPointer->iDN_locality.Length());
+    converter->Des().Copy(iStepPointer->iDN_locality);
+	CX520AttributeTypeAndValue* locality = CX520AttributeTypeAndValue::NewLC(ELocalityName,*converter);
+	array->AppendL(locality);
+	CleanupStack::Pop(locality);
+	CleanupStack::PopAndDestroy(converter);
+	
+	converter = HBufC8::NewMaxLC(iStepPointer->iDN_state.Length());
+    converter->Des().Copy(iStepPointer->iDN_state);
+	CX520AttributeTypeAndValue* province = CX520AttributeTypeAndValue::NewLC(EStateOrProvinceName,*converter);
+	array->AppendL(province);
+	CleanupStack::Pop(province);
+	CleanupStack::PopAndDestroy(converter);
+		
+	converter = HBufC8::NewMaxLC(iStepPointer->iDN_organization.Length());
+    converter->Des().Copy(iStepPointer->iDN_organization);
+	CX520AttributeTypeAndValue* org = CX520AttributeTypeAndValue::NewLC(EOrganizationName,*converter);
+	array->AppendL(org);
+	CleanupStack::Pop(org);
+	CleanupStack::PopAndDestroy(converter);
+	
+	converter = HBufC8::NewMaxLC(iStepPointer->iDN_unit.Length());
+    converter->Des().Copy(iStepPointer->iDN_unit);
+	CX520AttributeTypeAndValue* unit = CX520AttributeTypeAndValue::NewLC(EOrganizationalUnitName,*converter);
+	array->AppendL(unit);
+	CleanupStack::Pop(unit);
+	CleanupStack::PopAndDestroy(converter);
+	//delete converter;
+	converter = HBufC8::NewMaxLC(iStepPointer->iDN_email.Length());
+    converter->Des().Copy(iStepPointer->iDN_email);	
+	CX520AttributeTypeAndValue* email = CX520AttributeTypeAndValue::NewLC(EPKCS9EmailAddress,*converter);
+	array->AppendL(email);
+	CleanupStack::Pop(email);
+	CleanupStack::PopAndDestroy(converter);
+    
+	CX500DistinguishedName* dn = CX500DistinguishedName::NewL(*array);
+	
+	CleanupStack::PopAndDestroy(); //array
+
+	return dn;
+}
+
+void CPKCS10TesterActive::AddGenericAttributesL()
+{
+	TInt index;
+ 	TInt numberGenAttr;
+ 	CPKCS10Attribute* genericAttr;
+ 	CASN1EncPrintableString* attrString;
+ 			
+ 	// Add generic attributes.
+ 	numberGenAttr= iStepPointer->iArrayGenAttrOID.Count() ;
+ 			
+ 	index=0;
+ 	HBufC8 *converter;
+ 	while(numberGenAttr>index)
+ 	{   
+ 	  	converter = HBufC8::NewMaxLC(iStepPointer->iArrayGenAttrValue[index].Length());
+        converter->Des().Copy(iStepPointer->iArrayGenAttrValue[index]);
+ 	    attrString=CASN1EncPrintableString::NewLC(*converter);
+ 	    genericAttr= CPKCS10Attribute::NewL(iStepPointer->iArrayGenAttrOID[index],attrString);
+ 	    CleanupStack::Pop(attrString);  
+ 	    CleanupStack::PushL(genericAttr);
+ 	    iAttrCollection->AddPKCSAttributeL(genericAttr);
+ 	    CleanupStack::Pop(genericAttr);
+ 		CleanupStack::PopAndDestroy(converter);
+ 		index++;  
+ 	}
+ 	
+ 	if(numberGenAttr>0)
+ 	{
+ 		INFO_PRINTF1(_L("Generic attributes not found nor added"));	
+ 	}		
+}
+
+void CPKCS10TesterActive::AddChallengePasswordL()
+{
+     if(iStepPointer->iChallengePassword.Length()>0)
+   {
+      HBufC8 *passwordString = HBufC8::NewMaxLC(iStepPointer->iChallengePassword.Length());
+	  passwordString->Des().Copy(iStepPointer->iChallengePassword);
+   	  CPKCS9ChallengePasswordAttr* challengePassword = CPKCS9ChallengePasswordAttr::NewL(*passwordString);
+   	  CleanupStack::PopAndDestroy(passwordString);
+   	  CleanupStack::PushL(challengePassword);
+   	  iAttrCollection->AddPKCSAttributeL(challengePassword);
+   	  CleanupStack::Pop(challengePassword);
+   }
+   else
+   {
+   	   	INFO_PRINTF1(_L("Challenge Password not found or added"));
+   }
+}
+
+void CPKCS10TesterActive::AddV3ExtensionsL()
+{
+	TInt index;
+ 	TInt numV3ExtensionAttr;
+ 	CX509CertExtension* v3ExtensionAttr;
+ 	HBufC8* rawExtensionValue;
+ 			
+ 	// Add generic attributes.
+ 	numV3ExtensionAttr= iStepPointer->iArrayV3AttrOID.Count() ;
+ 			
+ 	index=0;
+   	
+ 	while(numV3ExtensionAttr>index)
+	{
+	
+ 		TFileName filename;
+		filename = iStepPointer->iArrayV3AttrValue[index];
+		RFile file;
+		User::LeaveIfError(file.Open(iFs,filename,EFileRead|EFileStream));
+		CleanupClosePushL(file);
+		TInt size;
+		User::LeaveIfError(file.Size(size));
+		rawExtensionValue = HBufC8::NewMaxL(size);
+		CleanupStack::PushL(rawExtensionValue);
+		TPtr8 extValuePtr = rawExtensionValue->Des();
+		
+		User::LeaveIfError(file.Read(extValuePtr));
+				
+		v3ExtensionAttr= CX509CertExtension::NewLC(iStepPointer->iArrayV3AttrOID[index], 
+											 iStepPointer->iArrayV3AttrCritical[index],
+											 extValuePtr);  
+	
+		if(index==0) // creates a new  CPKCS9ExtensionRequestAttr object.
+		{
+			iV3ExtensionsCollection = CPKCS9ExtensionRequestAttr::NewL(*v3ExtensionAttr);	
+		}
+		else // adds extension to existing CPKCS9ExtensionRequestAttr.
+		{
+			iV3ExtensionsCollection->AddExtensionL(*v3ExtensionAttr);	
+		}
+		CleanupStack::PopAndDestroy(v3ExtensionAttr);
+		CleanupStack::PopAndDestroy(); // rawExtensionValue			
+		CleanupStack::PopAndDestroy(); // file
+		index++;
+	}
+	
+	if(numV3ExtensionAttr>0)
+	{
+		// Add extension attributes to collection of attributes.
+		iAttrCollection->AddPKCSAttributeL(iV3ExtensionsCollection);	
+	}
+		else
+	{
+		INFO_PRINTF1(_L("Extension requests not found nor added"));
+	}
+
+}
+
+TAlgorithmId CCertificateRequestStep::ConvertNameToDigestId(const TDesC& aName)
+{
+	if (aName.Compare(_L("SHA1"))==0)
+		{
+		return ESHA1;	
+		}
+	else if (aName.Compare(_L("MD2"))==0)
+			{
+			return EMD2;
+			}
+		 else if (aName.Compare(_L("MD5"))==0)
+			{
+			return EMD5;
+			}
+			else
+			 { //invalid algorithm
+			 return TAlgorithmId(7);	
+			 }
+}
+TInt  CCertificateRequestStep::ConvertNameToEKeyAlgorithm(const TDesC& aName)
+{
+	if (aName.Compare(_L("RSA"))==0)
+			{
+			return CCTKeyInfo::ERSA;
+			}
+			else if (aName.Compare(_L("DSA"))==0)
+			{
+				return CCTKeyInfo::EDSA;
+			}
+				else
+				 { //invalid algorithm
+					 return 7;	
+				 }
+
+}
+	
+void CCertificateRequestStep::OutputEncodingToFileL(const TDesC8& aEncoding)
+{
+	INFO_PRINTF1(_L("Writting encoding to file"));
+	
+	_LIT(KPath, "c:\\tpkcs10\\myresults\\");
+	TInt err=iFs.MkDir(KPath);
+	if (err!=KErrNone && err!=KErrAlreadyExists)
+	{
+		User::Leave(err);	 
+	}
+
+	_LIT(KExtension, ".der");
+	TFileName rName;
+	rName.Append(KPath);
+	rName.Append(ConfigSection());
+	rName.Append(KExtension);
+	rName.LowerCase();
+		
+	RFile file;
+	CleanupClosePushL(file);
+	User::LeaveIfError(file.Replace(iFs, rName, EFileWrite | EFileStream));
+	User::LeaveIfError(file.Write(aEncoding));
+	CleanupStack::PopAndDestroy(&file);
+}
+	
+	
+TBool CPKCS10TesterActive::CompareRequestToOPENSSLReqL()
+{
+	RFile file;
+	TFileName fileName;
+	fileName = iStepPointer->iOPENSSLCertReq;
+	User::LeaveIfError(file.Open(iFs, fileName, EFileRead));
+	CleanupClosePushL(file);
+	TInt size;
+	User::LeaveIfError(file.Size(size));
+	HBufC8* buf = HBufC8::NewMaxLC(size);
+	TPtr8 ptr = buf->Des();
+	User::LeaveIfError(file.Read(ptr));
+	TBool result = *iOutputASN1Encoding == *buf;
+	CleanupStack::PopAndDestroy(2); // buf, file
+	return result;
+}
+
+TBool CCertificateRequestStep::IsMatchingEncodingL(CASN1EncBase* aASN1Enc1, CASN1EncBase* aASN1Enc2)
+	{
+	TBool result = EFalse;
+	
+	// Check the length first
+	TInt lenEnc1 = aASN1Enc1->LengthDER();
+	TInt lenEnc2 = aASN1Enc2->LengthDER();
+	if (lenEnc1 == lenEnc2)
+		{
+		// Get the encoding and compare them
+		HBufC8* enc1Buf = HBufC8::NewMaxLC(lenEnc1);
+		HBufC8* enc2Buf = HBufC8::NewMaxLC(lenEnc2);
+		TPtr8 enc1Ptr(enc1Buf->Des());
+		TPtr8 enc2Ptr(enc2Buf->Des());
+		TUint pos1 = 0, pos2 = 0;
+
+		aASN1Enc1->WriteDERL(enc1Ptr, pos1);
+		aASN1Enc2->WriteDERL(enc2Ptr, pos2);
+
+		result = (*enc1Buf == *enc2Buf);
+		CleanupStack::PopAndDestroy(2, enc1Buf);
+		}
+	else
+		{
+		result = EFalse;
+		}
+
+	return result;
+	}