--- /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;
+ }