diff -r 675a964f4eb5 -r 35751d3474b7 cryptoservices/certificateandkeymgmt/tpkcs10/tcertrequeststep.cpp --- a/cryptoservices/certificateandkeymgmt/tpkcs10/tcertrequeststep.cpp Tue Jul 21 01:04:32 2009 +0100 +++ b/cryptoservices/certificateandkeymgmt/tpkcs10/tcertrequeststep.cpp Thu Sep 10 14:01:51 2009 +0300 @@ -1,1054 +1,1052 @@ -/* -* 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; - } +/* +* 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; + }