os/security/cryptoservices/certificateandkeymgmt/tpkcs10/tcertrequeststep.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of the License "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 *
    16 */
    17 
    18 
    19 /**
    20  @file  
    21  @internalTechnology
    22 */
    23  
    24 #include "tcertrequeststep.h"
    25 #include <f32file.h> 
    26 #include <e32std.h>
    27 
    28 _LIT(KKeyLabel, "new pkcs10 test key"); 
    29 
    30 // CertRequest tester active.
    31 CPKCS10TesterActive::CPKCS10TesterActive( CTestExecuteLogger& aLogger ) : 
    32    CActive( EPriorityStandard ),
    33    iLogger( aLogger )
    34 	{
    35 	CActiveScheduler::Add( this );
    36 	User::LeaveIfError(iFs.Connect());
    37 	}
    38 
    39 CPKCS10TesterActive::~CPKCS10TesterActive()
    40 	{
    41    	delete iDN;
    42 	iDN=NULL;	 
    43 	delete iCertRequest;
    44 	iCertRequest=NULL;			
    45  	delete iOutputASN1Encoding;	
    46  	iOutputASN1Encoding=NULL; 			
    47  	delete iSecondOutputASN1Encoding;
    48  	iSecondOutputASN1Encoding=NULL;
    49  	if (iKeyInfo)
    50  	{
    51 		iKeyInfo->Release();
    52 		iKeyInfo=NULL;	 			
    53  	}
    54 	delete iKeyData;
    55 	iKeyData=NULL;
    56 	if(iKeyStore) // debug.
    57 	{
    58 	    iKeyStore->Cancel();
    59 		delete iKeyStore;
    60 		iKeyStore=NULL;	
    61 	}
    62 	iFs.Close ();
    63 	}
    64 	
    65 void CPKCS10TesterActive::DeleteAllKeysL()
    66 	{
    67 	// Delete Key store.
    68 	INFO_PRINTF1(_L("deleting store keys"));
    69   	iKeyStore = CUnifiedKeyStore::NewL(iFs);
    70   	CleanupStack::PushL(iKeyStore); 
    71   	iKeyStore->Initialize(iStatus);  
    72 	
    73 	iState = EDeleteAllInit;
    74 	SetActive();
    75    	CActiveScheduler::Start();
    76    	   	
    77    	iKeys.Close();
    78    	CleanupStack::Pop(iKeyStore);
    79    	delete iKeyStore;
    80 	iKeyStore = NULL;	
    81 	
    82 	}
    83 
    84 TVerdict CPKCS10TesterActive::doActiveCertRequestL(CCertificateRequestStep* aStep)
    85 	{
    86 	
    87 	iTestSuccess= EFail;
    88 	INFO_PRINTF1(_L("Active tester for Cert Request started. "));
    89 	iStepPointer = aStep;
    90 		
    91     DeleteAllKeysL();
    92 	
    93     INFO_PRINTF1(_L("initialising keystore"));
    94     
    95 	// Initialise Key store.
    96   	iKeyStore = CUnifiedKeyStore::NewL(iFs);
    97   	CleanupStack::PushL(iKeyStore); 
    98   	iKeyStore->Initialize(iStatus);  
    99 	iState = EInitKeyStore; 
   100 	SetActive();
   101    	CActiveScheduler::Start();
   102    	
   103    	// After encoding was produced it checks correctness
   104     if(iRunError==KErrNone)
   105      {
   106 	     if( !(iStepPointer->iOOMCondition) &&verifyCertReqEncodingL()!=EPass  )
   107 		 {
   108 			  iTestSuccess= EFail;
   109 		 }
   110 		 else    
   111 		 {
   112 		 	  iTestSuccess= EPass;
   113 		 }
   114 
   115 		 
   116 		 if( iTestSuccess && iStepPointer->iGenerateSecondRequest) // if cert was reused.
   117 		 {
   118 			// compare encoding of first and second request.
   119 			if((iOutputASN1Encoding->Compare(iSecondOutputASN1Encoding->Des())) == 0)
   120 			{
   121 		 		INFO_PRINTF1(_L("Reuse verified"));
   122 		 	}
   123 			else
   124 		 	{
   125 		 		iTestSuccess= EFail;
   126 		 		//iStepPointerSetTestStepResult(EFail);
   127 		 		INFO_PRINTF1(_L("New output encoding is not what is expected"));		
   128 		 	} 
   129 		 }
   130      }
   131   	
   132    	CleanupStack::Pop(iKeyStore);  
   133     return iTestSuccess;
   134 }
   135 	
   136 TInt CPKCS10TesterActive::RunError(TInt aError)
   137 	{
   138 	iRunError =aError;
   139 	iKeyStore->Cancel();
   140 	if(iCertRequest)
   141 	{
   142 		iCertRequest->Cancel();	
   143 	}
   144 	CActiveScheduler::Stop();
   145 	return KErrNone;
   146 	
   147 	}
   148 	
   149 void CPKCS10TesterActive::RunL()
   150 	{
   151 	iRunError =KErrNone;
   152 	
   153  	User::LeaveIfError(iStatus.Int());
   154    
   155 	switch(iState)
   156 		{
   157 		
   158 		case EDeleteAllInit:
   159 			INFO_PRINTF1(_L("  listing existing keys\n"));
   160 			iKeyStore->List(iKeys, iKeyFilter, iStatus);
   161 			iState = EDeleteAllDelete;
   162 			SetActive();
   163 			break;
   164 			
   165 		case EDeleteAllDelete:
   166 			if (iKeys.Count() == 0)
   167 				{
   168 				// key log is empty
   169 				iKeys.Close();
   170 				CActiveScheduler::Stop();
   171 				break;
   172 				}
   173 			
   174 			INFO_PRINTF1(_L("  deleting key\n"));
   175 			iKeyStore->DeleteKey(*iKeys[0], iStatus);
   176 			iState = EDeleteAllDelete;
   177 			SetActive();
   178 			iKeys[0]->Release();
   179 			iKeys.Remove(0);
   180 			break;
   181 		
   182 		case EInitKeyStore:
   183 			{
   184 	  		INFO_PRINTF1(_L("Importing keys"));
   185  			TFileName filename;
   186  			filename = iStepPointer->iPrivateKey;
   187 			RFile file;
   188 			User::LeaveIfError(file.Open(iFs,filename,EFileRead));
   189 			CleanupClosePushL(file);
   190 			TInt size;
   191 			User::LeaveIfError(file.Size(size));
   192 			iKeyData = HBufC8::NewMaxL(size);
   193 			TPtr8 keyPtr = iKeyData->Des();
   194 			User::LeaveIfError(file.Read(keyPtr));			
   195 			CleanupStack::PopAndDestroy(); // file
   196 
   197 			TTime start(0.0); 
   198 			TTime end(0.0); 
   199 			
   200 			// Assumes only one keystore
   201 			// Check parameters!
   202 		 	ASSERT(iKeyInfo == NULL);      
   203 			iKeyStore->ImportKey(0, *(iKeyData), EPKCS15UsageSign, KKeyLabel,0, start, end,iKeyInfo, iStatus);
   204 	  		iState = EImportKey;
   205 	  		SetActive();
   206 			break;
   207 			}
   208 	  	case EImportKey:
   209 			{
   210 			INFO_PRINTF1(_L("Setting security policy for new stored key"));
   211 			TSecureId secureId(0x101f7784); // Application secure ID 
   212 			TSecurityPolicy securePolicy(secureId,ECapabilityReadUserData);
   213 			iKeyStore->SetUsePolicy(iKeyInfo->Handle(),securePolicy,iStatus);
   214 			iState = EKeyPolicy;
   215  			SetActive();
   216  			break;
   217 		   	}
   218 		case EKeyPolicy:
   219 			{
   220 			iAttrCollection=CPKCS10Attributes::NewL();
   221  			CleanupStack::PushL(iAttrCollection); 
   222 			INFO_PRINTF1(_L("Adding generic attributes"));		
   223  			AddGenericAttributesL();
   224  			INFO_PRINTF1(_L("Adding Challenge password"));
   225  			AddChallengePasswordL();
   226  			INFO_PRINTF1(_L("Adding V3 extensions"));
   227  			AddV3ExtensionsL();
   228  			INFO_PRINTF1(_L("Generating distinguished name"));
   229  			iDN=MakeDistinguishedNameL();
   230  			CleanupStack::PushL(iDN);
   231    	 		INFO_PRINTF1(_L("Generating cert request"));
   232    	 		iCertRequest=CPKCS10Request::NewL(*iDN,*iKeyInfo,iAttrCollection);
   233      		CleanupStack::PushL(iCertRequest);
   234      		INFO_PRINTF1(_L("Setting digest algorithm"));
   235 			TAlgorithmId digestAlgo=iStepPointer->ConvertNameToDigestId(iStepPointer->iDigestAlg);
   236 			iCertRequest->SetDigestAlgL(digestAlgo);
   237  			INFO_PRINTF1(_L("Requesting cert request encoding"));
   238  	  		
   239  	  		// Clean up
   240  	  		CleanupStack::Pop(iCertRequest);
   241  			CleanupStack::Pop(iDN);
   242     	 	CleanupStack::Pop(iAttrCollection);
   243     	  	iAttrCollection=NULL;  
   244 			iOutputASN1Encoding=NULL;
   245 			iCertRequest->CreateEncoding(iOutputASN1Encoding,iStatus);
   246 			iState=EGenerateCertRequest; 
   247 	 		SetActive();     
   248 	  		break;	
   249 			}
   250 		case EGenerateCertRequest:
   251 			{ 
   252 			
   253 			// Use to debug encoding 			
   254   			// iStepPointer->OutputEncodingToFileL(iOutputASN1Encoding->Des()); //debug
   255 			// Used for cert request reuse cases  
   256 			if(iStepPointer->iGenerateSecondRequest)
   257 				{       
   258 						INFO_PRINTF1(_L("Reusing instance of CPKCS10Request"));
   259 				        if(iStepPointer->iRepopulateDataRequest)
   260 				        {
   261 				         	iAttrCollection=CPKCS10Attributes::NewL();
   262 				            CleanupStack::PushL(iAttrCollection); 
   263 				        	AddGenericAttributesL();
   264 				 			AddChallengePasswordL();
   265 				 			AddV3ExtensionsL();
   266 				 			// deletes previous value of iDN.
   267 				 			delete iDN;
   268 				 			iDN=MakeDistinguishedNameL();
   269 				 			CleanupStack::PushL(iDN);
   270 				   	 		TAlgorithmId digestAlgo2=iStepPointer->ConvertNameToDigestId(iStepPointer->iDigestAlg);
   271 							// Repopulates data.
   272 							CleanupStack::PushL(iCertRequest);
   273 							iCertRequest->SetDigestAlgL(digestAlgo2);
   274 							iCertRequest->SetDistinguishedNameL(*iDN);
   275 							iCertRequest->SetAttributes(iAttrCollection);
   276 							iCertRequest->SetKeyInfoL(*iKeyInfo);
   277 							// Clean up
   278 							CleanupStack::Pop(iCertRequest);
   279 							CleanupStack::Pop(iDN);
   280     						CleanupStack::Pop(iAttrCollection);
   281     						iAttrCollection=NULL;		
   282 				        }
   283 				        INFO_PRINTF1(_L("Launches second cert request"));
   284 				        iSecondOutputASN1Encoding=NULL;
   285 				        iCertRequest->CreateEncoding(iSecondOutputASN1Encoding,iStatus);
   286 				        iState=EGenerateSecondCertRequest;
   287 				}
   288 				else
   289 				{
   290 					 // if no reuse case delete keys and prepare for final state
   291 						INFO_PRINTF1(_L("Deleting key"));
   292  		 				iKeyStore->DeleteKey(*iKeyInfo, iStatus);
   293  		 				iState=EDeleteKey;
   294 				}
   295 			
   296  		  	SetActive();  
   297  		 	break;	
   298 			}
   299 		case EGenerateSecondCertRequest:
   300 			{
   301 			INFO_PRINTF1(_L("Deleting key"));
   302  		 	iKeyStore->DeleteKey(*iKeyInfo,iStatus);
   303  		 	iState=EDeleteKey;
   304  		 	SetActive();
   305  		 	break;
   306 			}
   307 		case EDeleteKey:
   308 			{
   309 		    iKeyInfo->Release();  
   310 			iKeyInfo = NULL;
   311 		 	CActiveScheduler::Stop();
   312  		    break;	
   313 			}
   314  		default:
   315 			{
   316 		  	INFO_PRINTF1(_L("Cert Request Active tester: State corrupted."));
   317 			User::Leave(KErrCorrupt);
   318 			}
   319  		} 
   320  		
   321    	return; 
   322 }
   323 
   324 	
   325 CCertificateRequestStep::~CCertificateRequestStep()
   326 /**
   327  * Destructor
   328  */
   329 	{   
   330  		delete iActiveObjTest;
   331  		delete iSched;
   332 	}
   333 
   334 CCertificateRequestStep::CCertificateRequestStep()
   335 {
   336 	SetTestStepName(KCertificateRequestStep);
   337 }
   338 
   339 TVerdict CCertificateRequestStep::doTestStepPreambleL()
   340 {
   341 	__UHEAP_MARK;	
   342 	User::LeaveIfError (iFs.Connect());
   343 	
   344 	// initializes data.
   345            
   346 	// Read values form config file 
   347 	GetIntFromConfig(ConfigSection(), _L("Expected_error"), iExpectedError);	
   348     GetStringFromConfig(ConfigSection(), _L("DN_country"), iDN_country);
   349     GetStringFromConfig(ConfigSection(), _L("DN_state"), iDN_state);
   350     GetStringFromConfig(ConfigSection(), _L("DN_locality"), iDN_locality);
   351     GetStringFromConfig(ConfigSection(), _L("DN_organization"), iDN_organization);
   352     GetStringFromConfig(ConfigSection(), _L("DN_unit"), iDN_unit);
   353     GetStringFromConfig(ConfigSection(), _L("DN_common"), iDN_common);
   354     GetStringFromConfig(ConfigSection(), _L("DN_email"), iDN_email);
   355     GetStringFromConfig(ConfigSection(), _L("PrivateKey"),iPrivateKey);
   356     GetStringFromConfig(ConfigSection(), _L("OPENSSL_certreq"),iOPENSSLCertReq);
   357     GetStringFromConfig(ConfigSection(), _L("KeyAlg"),iKeyAlg);
   358     GetStringFromConfig(ConfigSection(), _L("ChallengePassword"),iChallengePassword);
   359     GetStringFromConfig(ConfigSection(), _L("DigestAlg"),iDigestAlg);
   360     GetBoolFromConfig(ConfigSection(), _L("OOMCondition"),iOOMCondition);
   361     GetBoolFromConfig(ConfigSection(), _L("GenerateSecondRequest"),iGenerateSecondRequest);
   362     GetBoolFromConfig(ConfigSection(), _L("RepopulateDataRequest"),iRepopulateDataRequest);
   363     GetIntFromConfig(ConfigSection(), _L("ElemCertReqCount"),iElemCertReqCount);
   364     GetIntFromConfig(ConfigSection(), _L("ElemCertInfoCount"),iElemCertInfoCount);
   365     GetIntFromConfig(ConfigSection(), _L("CertReqVer"),iCertReqVer);
   366     GetIntFromConfig(ConfigSection(), _L("ElemSubPubKeytInfoCount"),iElemSubPubKeytInfoCount);
   367     GetIntFromConfig(ConfigSection(), _L("ElemKeyAlgIdenCount"),iElemKeyAlgIdenCount);
   368     GetIntFromConfig(ConfigSection(), _L("ElemSigAlgIdenCount"),iElemSigAlgIdenCount);
   369     GetIntFromConfig(ConfigSection(), _L("Attribute_count"),iAttribute_count );
   370     
   371     // Read generic Attributes (ARRAY).
   372     TInt index(0);
   373 	TName fGenericAttrOID;
   374 	fGenericAttrOID.Format(_L("Attribute_OID_%d"), index);
   375 	TName fGenericAttrValue;
   376 	fGenericAttrValue.Format(_L("Attribute_value_%d"), index); 
   377 	
   378 	TPtrC genericAttrOIDName;
   379 	TPtrC genericAttrValueName;
   380     
   381    	while (GetStringFromConfig(ConfigSection(), fGenericAttrOID, genericAttrOIDName)
   382 			&& GetStringFromConfig(ConfigSection(), fGenericAttrValue, genericAttrValueName))
   383 	{
   384 	   
   385 	    iArrayGenAttrOID.AppendL(genericAttrOIDName);
   386 	    iArrayGenAttrValue.AppendL(genericAttrValueName);
   387 		index++;
   388 		fGenericAttrOID.Format(_L("Attribute_OID_%d"), index);
   389 		fGenericAttrValue.Format(_L("Attribute_value_%d"), index);
   390 		
   391 	}	
   392 		
   393 	// Read the v3 extension attributes (Array)
   394 	index=0;
   395     TName fV3AttrOID;
   396 	fV3AttrOID.Format(_L("V3_Extension_OID_%d"), index);
   397 	TName fV3AttrCritical;
   398 	fV3AttrCritical.Format(_L("V3_Extension_Critical_%d"), index); 
   399 	TName fV3AttrValue;
   400 	fV3AttrValue.Format(_L("V3_Extension_Value_%d"), index); 
   401 
   402 	TPtrC v3AttrOID;
   403 	TBool v3AttrCritical;
   404 	TPtrC v3AttrValue;
   405 	
   406    	while (GetStringFromConfig(ConfigSection(), fV3AttrOID, v3AttrOID)
   407 			&& GetBoolFromConfig(ConfigSection(), fV3AttrCritical, v3AttrCritical)
   408 			&& GetStringFromConfig(ConfigSection(), fV3AttrValue, v3AttrValue))
   409 		{
   410 	    iArrayV3AttrOID.AppendL(v3AttrOID);
   411 	    iArrayV3AttrCritical.AppendL(v3AttrCritical);
   412 	    iArrayV3AttrValue.AppendL(v3AttrValue);
   413 		index++;
   414 		fV3AttrOID.Format(_L("V3_Extension_OID_%d"), index);
   415 		fV3AttrCritical.Format(_L("V3_Extension_Critical_%d"), index); 
   416 		fV3AttrValue.Format(_L("V3_Extension_Value_%d"), index); 
   417 		}	
   418 		
   419 	SetTestStepResult(EPass);
   420 	return TestStepResult();
   421 }
   422 
   423 
   424 TVerdict CCertificateRequestStep::doTestStepL()
   425 {
   426 	if (!iOOMCondition)
   427 		{
   428 		 doTestL(); 
   429 		}
   430 	else
   431 		{
   432  		return doOOMTestL();
   433 	    }	
   434 
   435    	 return TestStepResult();
   436 }
   437 
   438 TVerdict CCertificateRequestStep::doOOMTestL()
   439 {
   440 	TVerdict verdict = EFail;
   441  	TInt countAfter = 0;
   442 	TInt countBefore = 0;
   443  	for (TInt oomCount = 0; ; oomCount++)
   444  		{
   445  		INFO_PRINTF2(_L("\n ==== Number of memory allocations %d ===="), oomCount);
   446  		verdict = EFail;
   447  		__UHEAP_RESET;
   448  		__UHEAP_SETFAIL(RHeap::EDeterministic, oomCount);
   449  		countBefore = User::CountAllocCells();
   450  		TRAPD(error, doTestL());// ----> This is the actual test that runs under OOM conditions.
   451  		countAfter = User::CountAllocCells();
   452  		__UHEAP_RESET;
   453  		if (error != KErrNoMemory)  
   454  			{
   455  			verdict = EPass;
   456  			INFO_PRINTF2(_L("OOM Status %d"),error);
   457 			INFO_PRINTF1(_L("Test outcome : Passed"));
   458  			break;
   459  			}
   460  		else
   461  			{
   462  			if (countBefore != countAfter)
   463  				{
   464  				INFO_PRINTF2(_L("OOM Status %d"),error);
   465  				INFO_PRINTF2(_L("OOM Failed at %d"), oomCount);
   466  				SetTestStepResult(verdict);  
   467  				break;
   468  				}
   469  			}
   470  		INFO_PRINTF2(_L("OOM Failed Point status %d"), error);
   471 		}
   472 	INFO_PRINTF3(_L("Heap alloc count ok: %d final vs %d initial"), countAfter,countBefore);
   473  	SetTestStepResult(verdict);
   474  	if (verdict==EFail)
   475 	 	{
   476  		User::Leave(KErrGeneral);	 		
   477 	 	}	 	
   478  	return verdict;
   479 	}	
   480 	
   481 
   482 
   483 	
   484 void CCertificateRequestStep::doTestL()
   485 {
   486     
   487     iSched=new(ELeave) CActiveScheduler; 
   488     CleanupStack::PushL(iSched);  
   489 	CActiveScheduler::Install(iSched);
   490 	
   491 	
   492 	iActiveObjTest = new (ELeave) CPKCS10TesterActive(Logger());
   493 	CleanupStack::PushL(iActiveObjTest);
   494 
   495 	if (iActiveObjTest->doActiveCertRequestL(this) != EPass)
   496 	 {
   497 	 	SetTestStepResult(EFail);
   498 	 	INFO_PRINTF1(_L("Verification FAIL."));
   499 	 	// To keep happy out of memory test.
   500 	 	User::Leave(KErrNoMemory);
   501 
   502 	 }
   503 	 else
   504 	 {
   505 	 	INFO_PRINTF1(_L("Verification PASS."));	
   506 	 }
   507 
   508 	 CleanupStack::PopAndDestroy(iActiveObjTest);
   509 	 iActiveObjTest = NULL;
   510 	 CleanupStack::PopAndDestroy(iSched);
   511 	 iSched=NULL;
   512 	 
   513  }
   514 
   515 TVerdict CPKCS10TesterActive::verifyCertReqEncodingL()
   516 {   
   517     TVerdict certReqCheck= EPass;
   518 	INFO_PRINTF1(_L("Verifiying cert request encoding"));
   519 	TInt pos(0);
   520 	 
   521 	CArrayPtrFlat<TASN1DecGeneric>* certReq= TASN1DecSequence().DecodeDERLC(*iOutputASN1Encoding,pos);
   522 	// Verifies Number of elements in cert request.
   523 	if(certReq->Count() != iStepPointer->iElemCertReqCount)
   524 	{
   525 		INFO_PRINTF1(_L("VERIFICATION FAILED: Incorrect number of elements in cert request"));
   526 		certReqCheck= EFail;
   527 	}
   528 	
   529 	CArrayPtrFlat<TASN1DecGeneric>* certReqInfo=TASN1DecSequence().DecodeDERLC(*certReq->At(0));  
   530 	// Verifies Number of elements in cert request info.
   531 	if(certReqInfo->Count() != iStepPointer->iElemCertInfoCount)
   532 	{
   533 		INFO_PRINTF1(_L("VERIFICATION FAILED: Incorrect number of elements in cert request info"));
   534 		certReqCheck= EFail;
   535 	}
   536 		  
   537 	TASN1DecInteger decInt;
   538 	TInt version = decInt.DecodeDERShortL(*certReqInfo->At(0));
   539 	// Verifies expected version in cert request info.
   540 	if(version != iStepPointer->iCertReqVer)
   541 	{
   542 		INFO_PRINTF1(_L("VERIFICATION FAILED: Incorrect version in cert request info"));
   543 		certReqCheck= EFail;
   544 	}
   545 
   546 	pos = 0;
   547 	CX500DistinguishedName* dn = CX500DistinguishedName::NewLC(certReqInfo->At(1)->Encoding());
   548 	// Verifies distinguished name.
   549 	if(!(iDN->ExactMatchL(*dn)))
   550 		{
   551 		INFO_PRINTF1(_L("VERIFICATION FAILED: Incorrect distinguished name encoding"));
   552 		certReqCheck= EFail;
   553 	}
   554 	
   555 	CArrayPtrFlat<TASN1DecGeneric>* subjPubKeyInfo = TASN1DecSequence().DecodeDERLC(*certReqInfo->At(2));
   556 	// Verifies number of elements in public key info.
   557 	if( iStepPointer->iElemSubPubKeytInfoCount != subjPubKeyInfo->Count())
   558 	{
   559 		INFO_PRINTF1(_L("VERIFICATION FAILED: Incorrect number of elements in public key info."));
   560 		certReqCheck= EFail;
   561 	}
   562 	
   563 	CArrayPtrFlat<TASN1DecGeneric>* keyAlg = TASN1DecSequence().DecodeDERLC(*subjPubKeyInfo->At(0));
   564 	HBufC* keyAlgOid = TASN1DecObjectIdentifier().DecodeDERL(*keyAlg->At(0));
   565 	CleanupStack::PushL(keyAlgOid);
   566 	// Verifies number of elements in public key algorithm identifier.
   567 	if( keyAlg->Count() != iStepPointer->iElemKeyAlgIdenCount)
   568 	{
   569 		INFO_PRINTF1(_L("VERIFICATION FAILED: Incorrect number of elements in public key algorithm identifier."));
   570 		certReqCheck= EFail;
   571 	}
   572 
   573     HBufC8* pubKeyData = TASN1DecBitString().ExtractOctetStringL(*subjPubKeyInfo->At(1));
   574 	CleanupStack::PushL(pubKeyData);
   575     // Verifies number of elements in signature algorithm identifier.
   576 	CArrayPtrFlat<TASN1DecGeneric>* sigAlg = TASN1DecSequence().DecodeDERLC(*certReq->At(1));
   577 	
   578 	if( sigAlg->Count() != iStepPointer->iElemSigAlgIdenCount)
   579 	{
   580 		INFO_PRINTF1(_L("VERIFICATION FAILED: Incorrect number of elements in signature algorithm identifier."));
   581 		certReqCheck= EFail;
   582 	}
   583 	
   584 	
   585 	HBufC* sigAlgOid = TASN1DecObjectIdentifier().DecodeDERL(*sigAlg->At(0));
   586 	CleanupStack::PushL(sigAlgOid);
   587 	
   588 	HBufC8* signature = TASN1DecBitString().ExtractOctetStringL(*certReq->At(2));
   589 	CleanupStack::PushL(signature);
   590 	
   591 	CMessageDigest* digest = NULL;
   592 	
   593 	switch (iStepPointer->ConvertNameToDigestId(iStepPointer->iDigestAlg))
   594 		{
   595 		case ESHA1:
   596 			digest = CSHA1::NewL();
   597 			break;
   598 
   599 		case EMD2:
   600 			digest = CMD2::NewL();
   601 			break;
   602 
   603 		case EMD5:
   604 			digest = CMD5::NewL();
   605 			break;
   606 
   607 		default:
   608 				User::Leave(KErrCorrupt);
   609 		}
   610 	CleanupStack::PushL(digest);
   611 	 
   612 	if (iStepPointer->ConvertNameToEKeyAlgorithm(iStepPointer->iKeyAlg) == CCTKeyInfo::ERSA)
   613 	{	
   614 	    // Verifies key.
   615 		if(*keyAlgOid != KRSA)
   616 		{
   617 			INFO_PRINTF1(_L("VERIFICATION FAILED: Expecting RSA key."));
   618 			certReqCheck= EFail;
   619 		}
   620 				
   621 		// Verifies digest.
   622 		switch  (iStepPointer->ConvertNameToDigestId(iStepPointer->iDigestAlg))
   623 		{
   624 			case ESHA1:
   625 			{
   626 				if(*sigAlgOid != KSHA1WithRSA)
   627 				{
   628 					INFO_PRINTF1(_L("VERIFICATION FAILED: Expecting RSA with SHA1 signature."));
   629 					certReqCheck= EFail;
   630 				}
   631 			}
   632 			break;
   633 			case EMD2:
   634 			{
   635 				if(*sigAlgOid != KMD2WithRSA)
   636 				{
   637 					INFO_PRINTF1(_L("VERIFICATION FAILED: Expecting RSA with MD2 signature."));
   638 					certReqCheck= EFail;
   639 				}
   640 			}
   641 			break;
   642 			case EMD5:
   643 			{
   644 				if(*sigAlgOid != KMD5WithRSA)
   645 				{
   646 					INFO_PRINTF1(_L("VERIFICATION FAILED: Expecting RSA with MD5 signature."));
   647 					certReqCheck= EFail;
   648 				}
   649 			}
   650 			break;
   651 			default:
   652 			{
   653 				INFO_PRINTF1(_L("VERIFICATION FAILED: Unrecognised signature algorithm."));
   654 				User::Leave(KErrCorrupt);
   655 			}
   656 			break;
   657 		}
   658 		        
   659         // Checks RSA signature.
   660         // There are doubts about the validity of the method below
   661  /*		CRSAPublicKey* pubKey = TX509KeyFactory().RSAPublicKeyL(*pubKeyData);
   662 		CleanupStack::PushL(pubKey);
   663 		
   664 		RInteger sigInt = RInteger::NewL(*signature);
   665 		CleanupStack::PushL(sigInt);
   666 		CRSASignature* sig = CRSASignature::NewL(sigInt);
   667 		CleanupStack::Pop(); // sigInt
   668 		CleanupStack::PushL(sig);
   669 		CRSAPKCS1v15Verifier* verifier = CRSAPKCS1v15Verifier::NewLC(*pubKey);
   670 		digest->Update(certReq->At(0)->Encoding());
   671 		
   672 		if(!(verifier->VerifyL(digest->Final(),*sig)))
   673 		{
   674 			INFO_PRINTF1(_L("VERIFICATION FAILED: RSA Signature verification failed."));
   675 			User::Leave(KErrGeneral);
   676 		}   
   677 		CleanupStack::PopAndDestroy(verifier);	
   678 		CleanupStack::PopAndDestroy(sig);
   679 		CleanupStack::PopAndDestroy(pubKey);   */
   680 	}
   681 	else if (iStepPointer->ConvertNameToEKeyAlgorithm(iStepPointer->iKeyAlg)== CCTKeyInfo::EDSA)
   682 	{
   683 				// Verifies key 
   684 		if(*keyAlgOid != KDSA)
   685 		{
   686 				certReqCheck= EFail;
   687 		}
   688 		INFO_PRINTF1(_L("DSA key algorithm OID CORRECT"));
   689 		// Verifies digest
   690 	    if(*sigAlgOid != KDSAWithSHA1)
   691 		{
   692 				certReqCheck= EFail;
   693 		}
   694 		INFO_PRINTF1(_L("Signature algorithm OID CORRECT"));
   695 		
   696 		CDSAParameters* params = TX509KeyFactory().DSAParametersL(keyAlg->At(1)->Encoding());
   697 		CleanupStack::PushL(params);
   698 		CDSAPublicKey* pubKey = TX509KeyFactory().DSAPublicKeyL(*params, *pubKeyData);
   699 		CleanupStack::PushL(pubKey);
   700 
   701 		// Test sig
   702 		CDSASignature* sig = TX509KeyFactory().DSASignatureL(*signature);
   703 		CleanupStack::PushL(sig);
   704 
   705 		CDSAVerifier* verifier = CDSAVerifier::NewLC(*pubKey);
   706 		digest->Update(certReq->At(0)->Encoding());
   707 		// Verifies signature.
   708 		if(!(verifier->VerifyL(digest->Final(),*sig)))
   709 		{
   710 				certReqCheck= EFail;
   711 		}
   712 			
   713 		CleanupStack::PopAndDestroy(verifier);
   714 		CleanupStack::PopAndDestroy(sig);
   715 		CleanupStack::PopAndDestroy(pubKey);
   716 		CleanupStack::PopAndDestroy(params);
   717 	}
   718 	else
   719 	{
   720 		INFO_PRINTF1(_L("VERIFICATION FAILED: Invalid key algorithm."));
   721 		certReqCheck= EFail;
   722 	}
   723     
   724     // Verifies number of attributes.
   725     CArrayPtrFlat<TASN1DecGeneric>* attrSet = TASN1DecSet().DecodeDERLC(*certReqInfo->At(3));
   726     
   727     if(attrSet->Count() != iStepPointer->iAttribute_count)
   728 	{
   729 			INFO_PRINTF1(_L("VERIFICATION FAILED: Number of attributes incorrect"));
   730 			certReqCheck= EFail;
   731 	}
   732 		
   733 	// makes binary compare if key is not DSA.
   734  	if (iStepPointer->ConvertNameToEKeyAlgorithm(iStepPointer->iKeyAlg) != CCTKeyInfo::EDSA)  // Do not compare if we have DSA signatures, these are not deterministic!
   735 	{
   736 		if(!(CompareRequestToOPENSSLReqL()))
   737 		{
   738 				INFO_PRINTF1(_L("VERIFICATION FAILED: Binary compare with OPENSSL cert request does not match"));
   739 				certReqCheck= EFail;
   740 		}
   741 	}
   742 	else
   743 	{
   744 		INFO_PRINTF1(_L("No binary compare becuase is a DSA cert req."));	
   745 	}   
   746      
   747     INFO_PRINTF1(_L("Verification completed."));
   748    
   749     // pop and destroy: attrSet, digest, signature, sigAlgOid, sigAlg, pubKeyData
   750     // keyAlgOid, keyAlg, elmSubjPubKeyInfo, dnChecker, certReqInfo, certReqASN1
   751     CleanupStack::PopAndDestroy(12,certReq);
   752 	return certReqCheck;	
   753 }
   754 
   755 TVerdict CCertificateRequestStep::doTestStepPostambleL()
   756 {
   757  	iArrayGenAttrOID.Close();
   758  	iArrayGenAttrValue.Close();
   759 	iArrayV3AttrOID.Close();
   760 	iArrayV3AttrCritical.Close();
   761 	iArrayV3AttrValue.Close();
   762 	__UHEAP_MARKEND;
   763 	
   764 	return TestStepResult();
   765 }
   766 
   767 void cleanuparray(TAny* aArray)
   768 {
   769 	CArrayPtrFlat<CX520AttributeTypeAndValue>* array=(CArrayPtrFlat<CX520AttributeTypeAndValue>*)aArray;
   770 	array->ResetAndDestroy();
   771 	delete array;
   772 }
   773 	
   774 CX500DistinguishedName* CPKCS10TesterActive::MakeDistinguishedNameL()
   775 {
   776     CArrayPtrFlat<CX520AttributeTypeAndValue>* array = new(ELeave) CArrayPtrFlat<CX520AttributeTypeAndValue>(7);
   777 	TCleanupItem cleanup(cleanuparray, array);	
   778 	CleanupStack::PushL(cleanup);
   779 	array->SetReserveL(7);
   780 	
   781 	HBufC8 *converter = HBufC8::NewMaxLC(iStepPointer->iDN_common.Length());
   782     converter->Des().Copy(iStepPointer->iDN_common);	
   783 	CX520AttributeTypeAndValue* commonName = CX520AttributeTypeAndValue::NewLC(ECommonName,*converter);
   784 	array->AppendL(commonName);
   785 	CleanupStack::Pop(commonName);
   786 	CleanupStack::PopAndDestroy(converter);
   787 	
   788 	converter = HBufC8::NewMaxLC(iStepPointer->iDN_country.Length());
   789     converter->Des().Copy(iStepPointer->iDN_country);
   790 	CX520AttributeTypeAndValue* country = CX520AttributeTypeAndValue::NewLC(ECountryName,*converter);
   791 	array->AppendL(country);
   792 	CleanupStack::Pop(country);
   793 	CleanupStack::PopAndDestroy(converter);
   794 	
   795 	converter = HBufC8::NewMaxLC(iStepPointer->iDN_locality.Length());
   796     converter->Des().Copy(iStepPointer->iDN_locality);
   797 	CX520AttributeTypeAndValue* locality = CX520AttributeTypeAndValue::NewLC(ELocalityName,*converter);
   798 	array->AppendL(locality);
   799 	CleanupStack::Pop(locality);
   800 	CleanupStack::PopAndDestroy(converter);
   801 	
   802 	converter = HBufC8::NewMaxLC(iStepPointer->iDN_state.Length());
   803     converter->Des().Copy(iStepPointer->iDN_state);
   804 	CX520AttributeTypeAndValue* province = CX520AttributeTypeAndValue::NewLC(EStateOrProvinceName,*converter);
   805 	array->AppendL(province);
   806 	CleanupStack::Pop(province);
   807 	CleanupStack::PopAndDestroy(converter);
   808 		
   809 	converter = HBufC8::NewMaxLC(iStepPointer->iDN_organization.Length());
   810     converter->Des().Copy(iStepPointer->iDN_organization);
   811 	CX520AttributeTypeAndValue* org = CX520AttributeTypeAndValue::NewLC(EOrganizationName,*converter);
   812 	array->AppendL(org);
   813 	CleanupStack::Pop(org);
   814 	CleanupStack::PopAndDestroy(converter);
   815 	
   816 	converter = HBufC8::NewMaxLC(iStepPointer->iDN_unit.Length());
   817     converter->Des().Copy(iStepPointer->iDN_unit);
   818 	CX520AttributeTypeAndValue* unit = CX520AttributeTypeAndValue::NewLC(EOrganizationalUnitName,*converter);
   819 	array->AppendL(unit);
   820 	CleanupStack::Pop(unit);
   821 	CleanupStack::PopAndDestroy(converter);
   822 	//delete converter;
   823 	converter = HBufC8::NewMaxLC(iStepPointer->iDN_email.Length());
   824     converter->Des().Copy(iStepPointer->iDN_email);	
   825 	CX520AttributeTypeAndValue* email = CX520AttributeTypeAndValue::NewLC(EPKCS9EmailAddress,*converter);
   826 	array->AppendL(email);
   827 	CleanupStack::Pop(email);
   828 	CleanupStack::PopAndDestroy(converter);
   829     
   830 	CX500DistinguishedName* dn = CX500DistinguishedName::NewL(*array);
   831 	
   832 	CleanupStack::PopAndDestroy(); //array
   833 
   834 	return dn;
   835 }
   836 
   837 void CPKCS10TesterActive::AddGenericAttributesL()
   838 {
   839 	TInt index;
   840  	TInt numberGenAttr;
   841  	CPKCS10Attribute* genericAttr;
   842  	CASN1EncPrintableString* attrString;
   843  			
   844  	// Add generic attributes.
   845  	numberGenAttr= iStepPointer->iArrayGenAttrOID.Count() ;
   846  			
   847  	index=0;
   848  	HBufC8 *converter;
   849  	while(numberGenAttr>index)
   850  	{   
   851  	  	converter = HBufC8::NewMaxLC(iStepPointer->iArrayGenAttrValue[index].Length());
   852         converter->Des().Copy(iStepPointer->iArrayGenAttrValue[index]);
   853  	    attrString=CASN1EncPrintableString::NewLC(*converter);
   854  	    genericAttr= CPKCS10Attribute::NewL(iStepPointer->iArrayGenAttrOID[index],attrString);
   855  	    CleanupStack::Pop(attrString);  
   856  	    CleanupStack::PushL(genericAttr);
   857  	    iAttrCollection->AddPKCSAttributeL(genericAttr);
   858  	    CleanupStack::Pop(genericAttr);
   859  		CleanupStack::PopAndDestroy(converter);
   860  		index++;  
   861  	}
   862  	
   863  	if(numberGenAttr>0)
   864  	{
   865  		INFO_PRINTF1(_L("Generic attributes not found nor added"));	
   866  	}		
   867 }
   868 
   869 void CPKCS10TesterActive::AddChallengePasswordL()
   870 {
   871      if(iStepPointer->iChallengePassword.Length()>0)
   872    {
   873       HBufC8 *passwordString = HBufC8::NewMaxLC(iStepPointer->iChallengePassword.Length());
   874 	  passwordString->Des().Copy(iStepPointer->iChallengePassword);
   875    	  CPKCS9ChallengePasswordAttr* challengePassword = CPKCS9ChallengePasswordAttr::NewL(*passwordString);
   876    	  CleanupStack::PopAndDestroy(passwordString);
   877    	  CleanupStack::PushL(challengePassword);
   878    	  iAttrCollection->AddPKCSAttributeL(challengePassword);
   879    	  CleanupStack::Pop(challengePassword);
   880    }
   881    else
   882    {
   883    	   	INFO_PRINTF1(_L("Challenge Password not found or added"));
   884    }
   885 }
   886 
   887 void CPKCS10TesterActive::AddV3ExtensionsL()
   888 {
   889 	TInt index;
   890  	TInt numV3ExtensionAttr;
   891  	CX509CertExtension* v3ExtensionAttr;
   892  	HBufC8* rawExtensionValue;
   893  			
   894  	// Add generic attributes.
   895  	numV3ExtensionAttr= iStepPointer->iArrayV3AttrOID.Count() ;
   896  			
   897  	index=0;
   898    	
   899  	while(numV3ExtensionAttr>index)
   900 	{
   901 	
   902  		TFileName filename;
   903 		filename = iStepPointer->iArrayV3AttrValue[index];
   904 		RFile file;
   905 		User::LeaveIfError(file.Open(iFs,filename,EFileRead|EFileStream));
   906 		CleanupClosePushL(file);
   907 		TInt size;
   908 		User::LeaveIfError(file.Size(size));
   909 		rawExtensionValue = HBufC8::NewMaxL(size);
   910 		CleanupStack::PushL(rawExtensionValue);
   911 		TPtr8 extValuePtr = rawExtensionValue->Des();
   912 		
   913 		User::LeaveIfError(file.Read(extValuePtr));
   914 				
   915 		v3ExtensionAttr= CX509CertExtension::NewLC(iStepPointer->iArrayV3AttrOID[index], 
   916 											 iStepPointer->iArrayV3AttrCritical[index],
   917 											 extValuePtr);  
   918 	
   919 		if(index==0) // creates a new  CPKCS9ExtensionRequestAttr object.
   920 		{
   921 			iV3ExtensionsCollection = CPKCS9ExtensionRequestAttr::NewL(*v3ExtensionAttr);	
   922 		}
   923 		else // adds extension to existing CPKCS9ExtensionRequestAttr.
   924 		{
   925 			iV3ExtensionsCollection->AddExtensionL(*v3ExtensionAttr);	
   926 		}
   927 		CleanupStack::PopAndDestroy(v3ExtensionAttr);
   928 		CleanupStack::PopAndDestroy(); // rawExtensionValue			
   929 		CleanupStack::PopAndDestroy(); // file
   930 		index++;
   931 	}
   932 	
   933 	if(numV3ExtensionAttr>0)
   934 	{
   935 		// Add extension attributes to collection of attributes.
   936 		iAttrCollection->AddPKCSAttributeL(iV3ExtensionsCollection);	
   937 	}
   938 		else
   939 	{
   940 		INFO_PRINTF1(_L("Extension requests not found nor added"));
   941 	}
   942 
   943 }
   944 
   945 TAlgorithmId CCertificateRequestStep::ConvertNameToDigestId(const TDesC& aName)
   946 {
   947 	if (aName.Compare(_L("SHA1"))==0)
   948 		{
   949 		return ESHA1;	
   950 		}
   951 	else if (aName.Compare(_L("MD2"))==0)
   952 			{
   953 			return EMD2;
   954 			}
   955 		 else if (aName.Compare(_L("MD5"))==0)
   956 			{
   957 			return EMD5;
   958 			}
   959 			else
   960 			 { //invalid algorithm
   961 			 return TAlgorithmId(7);	
   962 			 }
   963 }
   964 TInt  CCertificateRequestStep::ConvertNameToEKeyAlgorithm(const TDesC& aName)
   965 {
   966 	if (aName.Compare(_L("RSA"))==0)
   967 			{
   968 			return CCTKeyInfo::ERSA;
   969 			}
   970 			else if (aName.Compare(_L("DSA"))==0)
   971 			{
   972 				return CCTKeyInfo::EDSA;
   973 			}
   974 				else
   975 				 { //invalid algorithm
   976 					 return 7;	
   977 				 }
   978 
   979 }
   980 	
   981 void CCertificateRequestStep::OutputEncodingToFileL(const TDesC8& aEncoding)
   982 {
   983 	INFO_PRINTF1(_L("Writting encoding to file"));
   984 	
   985 	_LIT(KPath, "c:\\tpkcs10\\myresults\\");
   986 	TInt err=iFs.MkDir(KPath);
   987 	if (err!=KErrNone && err!=KErrAlreadyExists)
   988 	{
   989 		User::Leave(err);	 
   990 	}
   991 
   992 	_LIT(KExtension, ".der");
   993 	TFileName rName;
   994 	rName.Append(KPath);
   995 	rName.Append(ConfigSection());
   996 	rName.Append(KExtension);
   997 	rName.LowerCase();
   998 		
   999 	RFile file;
  1000 	CleanupClosePushL(file);
  1001 	User::LeaveIfError(file.Replace(iFs, rName, EFileWrite | EFileStream));
  1002 	User::LeaveIfError(file.Write(aEncoding));
  1003 	CleanupStack::PopAndDestroy(&file);
  1004 }
  1005 	
  1006 	
  1007 TBool CPKCS10TesterActive::CompareRequestToOPENSSLReqL()
  1008 {
  1009 	RFile file;
  1010 	TFileName fileName;
  1011 	fileName = iStepPointer->iOPENSSLCertReq;
  1012 	User::LeaveIfError(file.Open(iFs, fileName, EFileRead));
  1013 	CleanupClosePushL(file);
  1014 	TInt size;
  1015 	User::LeaveIfError(file.Size(size));
  1016 	HBufC8* buf = HBufC8::NewMaxLC(size);
  1017 	TPtr8 ptr = buf->Des();
  1018 	User::LeaveIfError(file.Read(ptr));
  1019 	TBool result = *iOutputASN1Encoding == *buf;
  1020 	CleanupStack::PopAndDestroy(2); // buf, file
  1021 	return result;
  1022 }
  1023 
  1024 TBool CCertificateRequestStep::IsMatchingEncodingL(CASN1EncBase* aASN1Enc1, CASN1EncBase* aASN1Enc2)
  1025 	{
  1026 	TBool result = EFalse;
  1027 	
  1028 	// Check the length first
  1029 	TInt lenEnc1 = aASN1Enc1->LengthDER();
  1030 	TInt lenEnc2 = aASN1Enc2->LengthDER();
  1031 	if (lenEnc1 == lenEnc2)
  1032 		{
  1033 		// Get the encoding and compare them
  1034 		HBufC8* enc1Buf = HBufC8::NewMaxLC(lenEnc1);
  1035 		HBufC8* enc2Buf = HBufC8::NewMaxLC(lenEnc2);
  1036 		TPtr8 enc1Ptr(enc1Buf->Des());
  1037 		TPtr8 enc2Ptr(enc2Buf->Des());
  1038 		TUint pos1 = 0, pos2 = 0;
  1039 
  1040 		aASN1Enc1->WriteDERL(enc1Ptr, pos1);
  1041 		aASN1Enc2->WriteDERL(enc2Ptr, pos2);
  1042 
  1043 		result = (*enc1Buf == *enc2Buf);
  1044 		CleanupStack::PopAndDestroy(2, enc1Buf);
  1045 		}
  1046 	else
  1047 		{
  1048 		result = EFalse;
  1049 		}
  1050 
  1051 	return result;
  1052 	}