diff -r 000000000000 -r 2c201484c85f cryptoservices/certificateandkeymgmt/tpkcs10/tcertrequeststep.cpp --- /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 +#include + +_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* 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* 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* 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* 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* 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* 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* array=(CArrayPtrFlat*)aArray; + array->ResetAndDestroy(); + delete array; +} + +CX500DistinguishedName* CPKCS10TesterActive::MakeDistinguishedNameL() +{ + CArrayPtrFlat* array = new(ELeave) CArrayPtrFlat(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; + }