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