sl@0: /* sl@0: * Copyright (c) 2006-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: #include "tcmsstep.h" sl@0: #include sl@0: #include sl@0: #include "pkcs7signedobject.h" sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "validate.h" sl@0: sl@0: sl@0: CTCmsBaseStep::CTCmsBaseStep() sl@0: { sl@0: } sl@0: sl@0: CTCmsBaseStep::~CTCmsBaseStep() sl@0: { sl@0: iFs.Close (); sl@0: delete iDataContent; sl@0: delete iExpectedEncoding; sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: TVerdict CTCmsBaseStep::doTestStepPreambleL() sl@0: { sl@0: __UHEAP_MARK; sl@0: User::LeaveIfError (iFs.Connect()); sl@0: sl@0: //Read the data to be signed sl@0: iDataContent = readFileL(_L("Data")); sl@0: sl@0: if (iDataContent == NULL) sl@0: { sl@0: iDataContent=KNullDesC8().AllocL(); sl@0: } sl@0: sl@0: //Read the expected data type sl@0: TPtrC contentDataType; sl@0: if (GetStringFromConfig(ConfigSection(), _L("ExpectedDataType"), contentDataType)) sl@0: { sl@0: iExpectedDataType=CovertContentDataTypeNameToDataType(contentDataType); sl@0: } sl@0: sl@0: //Read the expected result sl@0: iExpectedEncoding = readFileL(_L("Result")); sl@0: if (!iExpectedEncoding) sl@0: { sl@0: INFO_PRINTF1(_L("Failed to read 'Result' section of script")); sl@0: SetTestStepResult(ETestSuiteError); sl@0: } sl@0: sl@0: GetIntFromConfig(ConfigSection(), _L("ExpectedResult"), iExpectedResult); sl@0: GetBoolFromConfig(ConfigSection(), _L("IsOOMTest"), iIsOOMTest); sl@0: return TestStepResult(); sl@0: } sl@0: sl@0: TInt CTCmsBaseStep::CovertContentDataTypeNameToDataType(const TDesC& aDataTypeName) sl@0: { sl@0: if (aDataTypeName.Compare(_L("DATA"))==0) sl@0: { sl@0: return EContentTypeData; sl@0: } sl@0: else if (aDataTypeName.Compare(_L("SIGNEDDATA"))==0) sl@0: { sl@0: return EContentTypeSignedData; sl@0: } sl@0: else if (aDataTypeName.Compare(_L("ENVELOPEDDATA"))==0) sl@0: { sl@0: return EContentTypeEnvelopedData; sl@0: } sl@0: else if (aDataTypeName.Compare(_L("DIGESTEDDATA"))==0) sl@0: { sl@0: return EContentTypeDigestedData; sl@0: } sl@0: else if (aDataTypeName.Compare(_L("ENCRYPTEDDATA"))==0) sl@0: { sl@0: return EContentTypeEncryptedData; sl@0: } sl@0: else if (aDataTypeName.Compare(_L("SIGNEDANDENVELOPEDDATA"))==0) sl@0: { sl@0: return CPKCS7ContentInfo::EContentTypeSignedAndEnvelopedData; sl@0: } sl@0: else if (aDataTypeName.Compare(_L("AUTHDATA"))==0) sl@0: { sl@0: return EContentTypeAuthenticatedData; sl@0: } sl@0: else sl@0: { sl@0: User::Leave(KErrArgument); sl@0: return EContentTypeData; sl@0: } sl@0: } sl@0: sl@0: HBufC8* CTCmsBaseStep::readFileL (TPtrC tag) sl@0: { sl@0: TPtrC fileName; sl@0: if (GetStringFromConfig(ConfigSection(), tag, fileName) == EFalse) sl@0: { sl@0: return NULL; sl@0: } sl@0: sl@0: RFile file; sl@0: if (file.Open(iFs, fileName, EFileRead) != KErrNone) sl@0: { sl@0: INFO_PRINTF2(_L("Cannot open file %S for reading"), &fileName); sl@0: return NULL; sl@0: } sl@0: CleanupClosePushL(file); sl@0: TInt fileSize = 0; sl@0: User::LeaveIfError(file.Size(fileSize)); sl@0: HBufC8* result = HBufC8::NewMaxL(fileSize); sl@0: TPtr8 rawDataPtr(result->Des()); sl@0: file.Read (rawDataPtr); sl@0: CleanupStack::PopAndDestroy (&file); sl@0: INFO_PRINTF3(_L("Read %d octets from %S"), result->Size(), &fileName); sl@0: return result; sl@0: } sl@0: sl@0: void CTCmsBaseStep::OutputResultToFileL(const TDesC8& aSignature) sl@0: { sl@0: TDriveUnit sysDrive (RFs::GetSystemDrive()); sl@0: TBuf<128> rName (sysDrive.Name());; sl@0: rName.Append(_L("\\tpkcs7\\myresults\\")); sl@0: sl@0: TInt err=iFs.MkDir(rName); sl@0: if (err!=KErrNone && err!=KErrAlreadyExists) sl@0: { sl@0: User::Leave(err); sl@0: } sl@0: sl@0: RFile file; sl@0: CleanupClosePushL(file); sl@0: sl@0: _LIT(KExtension, ".der"); sl@0: rName.Append(ConfigSection()); sl@0: rName.Append(KExtension); sl@0: rName.LowerCase(); sl@0: User::LeaveIfError(file.Replace(iFs, rName, EFileWrite | EFileStream)); sl@0: User::LeaveIfError(file.Write(aSignature)); sl@0: CleanupStack::PopAndDestroy(&file); sl@0: } sl@0: sl@0: sl@0: HBufC8* CTCmsBaseStep::CreateDEREncodingLC(const CASN1EncBase& aEncoding) sl@0: { sl@0: TUint len = aEncoding.LengthDER(); sl@0: HBufC8* buf = HBufC8::NewMaxLC(len); sl@0: TUint pos = 0; sl@0: TPtr8 bufptr(buf->Des()); sl@0: aEncoding.WriteDERL(bufptr, pos); sl@0: return buf; sl@0: } sl@0: sl@0: TVerdict CTCmsBaseStep::doTestStepL() sl@0: { sl@0: if (!iIsOOMTest) sl@0: { sl@0: TRAPD(err, doTestL();) sl@0: if (err!=iExpectedResult) sl@0: { sl@0: SetTestStepResult(EFail); sl@0: User::Leave(err); sl@0: } sl@0: return TestStepResult(); sl@0: } sl@0: else sl@0: { sl@0: return doOOMTestL(); sl@0: } sl@0: } sl@0: sl@0: TVerdict CTCmsBaseStep::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: __UHEAP_RESET; sl@0: __UHEAP_SETFAIL(RHeap::EDeterministic, oomCount); sl@0: countBefore = User::CountAllocCells(); sl@0: TRAPD(error, doTestL()); 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(EFail); 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: // Implementation of CMS Data Test Step sl@0: // sl@0: CTCmsDataStep::CTCmsDataStep() sl@0: { sl@0: } sl@0: sl@0: CTCmsDataStep::~CTCmsDataStep() sl@0: { sl@0: } sl@0: sl@0: sl@0: void CTCmsDataStep::doTestL() sl@0: { sl@0: __UHEAP_MARK; sl@0: CCmsContentInfo* content=CCmsContentInfo::NewL(EContentTypeData, *iDataContent); sl@0: CleanupStack::PushL(content); sl@0: CASN1EncSequence* contentSeq=content->EncodeASN1DERLC(); sl@0: HBufC8* signature=CreateDEREncodingLC(*contentSeq); sl@0: CleanupStack::Pop(signature); sl@0: CleanupStack::PopAndDestroy(2, content); sl@0: CleanupStack::PushL(signature); sl@0: //OutputResultToFileL(signature->Des()); sl@0: sl@0: TBool r=signature->Compare(*iExpectedEncoding); sl@0: if (r!=0 && !iIsOOMTest) sl@0: { sl@0: INFO_PRINTF1(_L("CMS Data Type Encoding Error")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: else sl@0: { sl@0: DecodingAndCheckL(*iExpectedEncoding); sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy(signature); sl@0: } sl@0: void CTCmsDataStep::DecodingAndCheckL(TDesC8& aRawData) sl@0: { sl@0: INFO_PRINTF1(_L("Start CMS Data Type Decoding")); sl@0: CCmsContentInfo* content=CCmsContentInfo::NewL(aRawData); sl@0: CleanupStack::PushL(content); sl@0: if (content->ContentType()!=EContentTypeData) sl@0: { sl@0: INFO_PRINTF1(_L("CMS Data Type is not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: else sl@0: { sl@0: if (content->ContentData()!=iDataContent->Des()) sl@0: { sl@0: INFO_PRINTF1(_L("CMS Data Content is not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: } sl@0: CleanupStack::PopAndDestroy(content); sl@0: } sl@0: // sl@0: // Implementation of CMS Data Test Step sl@0: // sl@0: CTCmsDataDecodingStep::CTCmsDataDecodingStep() sl@0: { sl@0: } sl@0: sl@0: CTCmsDataDecodingStep::~CTCmsDataDecodingStep() sl@0: { sl@0: } sl@0: sl@0: void CTCmsDataDecodingStep::doTestL() sl@0: { sl@0: DecodingAndCheckL(*iExpectedEncoding); sl@0: } sl@0: sl@0: sl@0: // sl@0: // Implementation of Signed Data Test Base Step sl@0: // sl@0: CTSignedDataBaseStep::CTSignedDataBaseStep() : iContentType(EContentTypeData), iRsaAlgorithm(ETrue) sl@0: { sl@0: } sl@0: sl@0: CTSignedDataBaseStep::~CTSignedDataBaseStep() sl@0: { sl@0: iDecPKCS8Data.ResetAndDestroy(); sl@0: iCertificates.ResetAndDestroy(); sl@0: iSignerInfoVersion.Close(); sl@0: iHashName.Close(); sl@0: iValidateResults.Close(); sl@0: iSignedAttributePresent.Close(); sl@0: iUnSignedAttributePresent.Close(); sl@0: delete iRootCertificate; sl@0: delete iAdditionalCertificate; sl@0: delete iAdditionalEncodedCertificate; sl@0: } sl@0: sl@0: sl@0: TInt CTSignedDataBaseStep::CovertHashNameToAlgorithmId(const TDesC& aHashName) sl@0: { sl@0: if (aHashName.Compare(_L("SHA1"))==0) sl@0: { sl@0: return ESHA1; sl@0: } sl@0: else if (aHashName.Compare(_L("MD5"))==0) sl@0: { sl@0: return EMD5; sl@0: } sl@0: else sl@0: { sl@0: return EMD2; sl@0: } sl@0: } sl@0: sl@0: TInt CTSignedDataBaseStep::CovertCertificateNameToCertificateType(const TDesC& aCertificateName) sl@0: { sl@0: if (aCertificateName.Compare(_L("X509"))==0) sl@0: { sl@0: return CCmsCertificateChoice::ECertificateX509; sl@0: } sl@0: else if (aCertificateName.Compare(_L("Attribute"))==0) sl@0: { sl@0: return CCmsCertificateChoice::ECertificateAttribute; sl@0: } sl@0: else sl@0: { sl@0: return CCmsCertificateChoice::ECertificateExtendedCerificate; sl@0: } sl@0: } sl@0: sl@0: sl@0: TVerdict CTSignedDataBaseStep::doTestStepPreambleL() sl@0: { sl@0: if (CTCmsBaseStep::doTestStepPreambleL()==EFail) sl@0: { sl@0: SetTestStepResult(EFail); sl@0: } sl@0: else sl@0: { sl@0: //Read the configurations sl@0: GetBoolFromConfig(ConfigSection(), _L("HashAvailable"), iIsHashAvailable); sl@0: GetBoolFromConfig(ConfigSection(), _L("DataDetached"), iIsDetached); sl@0: GetBoolFromConfig(ConfigSection(), _L("CertificateSetPresent"), iCertificateSetPresent); sl@0: GetBoolFromConfig(ConfigSection(), _L("CRLsSetPresent"), iCRLsSetPresent); sl@0: GetIntFromConfig(ConfigSection(), _L("SignedDataVersion"), iSignedDataVersion); sl@0: GetIntFromConfig(ConfigSection(), _L("AlgorithmCount"), iAlgorithmCount); sl@0: GetIntFromConfig(ConfigSection(), _L("CertsCount"), iCertsCount); sl@0: GetIntFromConfig(ConfigSection(), _L("SignerCount"), iSignerCount); sl@0: GetBoolFromConfig(ConfigSection(), _L("NoCertSet"), iNoCertSet); sl@0: GetBoolFromConfig(ConfigSection(), _L("ValidateUsingUserCerts"), iValidateUsingUserCerts); sl@0: GetBoolFromConfig(ConfigSection(), _L("NoSigning"), iNoSigning); sl@0: GetBoolFromConfig(ConfigSection(), _L("NoValidationTest"), iNoValidationTest); sl@0: GetBoolFromConfig(ConfigSection(), _L("TwoStepCreation"), iTwoStepCreation); sl@0: GetBoolFromConfig(ConfigSection(), _L("ValidationDetachedWithoutInput"), iValidationDetachedWithoutInput); sl@0: sl@0: sl@0: HBufC8* certificate = readFileL(_L("RootCertificate")); sl@0: if (certificate) sl@0: { sl@0: CleanupStack::PushL(certificate); sl@0: iRootCertificate = CX509Certificate::NewL(*certificate); sl@0: CleanupStack::PopAndDestroy (certificate); sl@0: } sl@0: sl@0: certificate = readFileL(_L("AddtionalCertificate")); sl@0: if (certificate) sl@0: { sl@0: CleanupStack::PushL(certificate); sl@0: iAdditionalCertificate = CX509Certificate::NewL(*certificate); sl@0: CleanupStack::PopAndDestroy (certificate); sl@0: } sl@0: TPtrC certTypeName; sl@0: if (GetStringFromConfig(ConfigSection(), _L("AdditionalEncodedCertificateType"), certTypeName)) sl@0: { sl@0: iAdditionalEncodedCertificateType=CovertCertificateNameToCertificateType(certTypeName); sl@0: iAdditionalEncodedCertificate=readFileL (_L("AdditionalEncodedCertificate")); sl@0: } sl@0: sl@0: //Read the certificates, private keys and hash algorithm sl@0: TInt index(0); sl@0: sl@0: TName fKeyName; sl@0: fKeyName.Format(_L("PrivateKey_%d"), index); sl@0: sl@0: TName fCertName; sl@0: fCertName.Format(_L("Certificate_%d"), index); sl@0: sl@0: TName fHashAlgorithmName; sl@0: fHashAlgorithmName.Format(_L("HashAlgorithm_%d"), index); sl@0: sl@0: TName fValidationResult; sl@0: fValidationResult.Format(_L("ValidationResult_%d"), index); sl@0: sl@0: TName fSignedAttributePresent; sl@0: fSignedAttributePresent.Format(_L("SignedAttributePresent_%d"), index); sl@0: sl@0: TName fUnSignedAttributePresent; sl@0: fUnSignedAttributePresent.Format(_L("UnSignedAttributePresent_%d"), index); sl@0: sl@0: TName fSignerInfoVersion; sl@0: fSignerInfoVersion.Format(_L("SignerInfoVersion_%d"), index); sl@0: sl@0: TPtrC hashName; sl@0: TBool vResult(EFalse); sl@0: TBool sAP(EFalse); sl@0: TBool uSAP(EFalse); sl@0: TInt signerInfoVersion; sl@0: TPtrC keyName; sl@0: TPtrC certName; sl@0: sl@0: while ( GetStringFromConfig(ConfigSection(), fKeyName, keyName) sl@0: && GetStringFromConfig(ConfigSection(), fCertName, certName) sl@0: && GetStringFromConfig(ConfigSection(), fHashAlgorithmName, hashName) sl@0: && GetBoolFromConfig(ConfigSection(), fValidationResult, vResult) sl@0: && GetBoolFromConfig(ConfigSection(), fSignedAttributePresent, sAP) sl@0: && GetBoolFromConfig(ConfigSection(), fUnSignedAttributePresent, uSAP) sl@0: && GetIntFromConfig(ConfigSection(), fSignerInfoVersion, signerInfoVersion) ) sl@0: { sl@0: //Construct private keys sl@0: HBufC8* privateKey(NULL); sl@0: if ((privateKey=readFileL(fKeyName))!=NULL) sl@0: { sl@0: CleanupStack::PushL (privateKey); sl@0: CDecPKCS8Data* pkcs8Data=TASN1DecPKCS8::DecodeDERL(privateKey->Des()); sl@0: CleanupStack::PushL (pkcs8Data); sl@0: iDecPKCS8Data.AppendL(pkcs8Data); sl@0: CleanupStack::Pop(pkcs8Data); sl@0: CleanupStack::PopAndDestroy(privateKey); sl@0: } sl@0: sl@0: //Construct X509 certificate sl@0: HBufC8* cert(NULL); sl@0: if ((cert=readFileL(fCertName))!=NULL) sl@0: { sl@0: CleanupStack::PushL (cert); sl@0: CX509Certificate* x509cert=CX509Certificate::NewLC(cert->Des()); sl@0: iCertificates.AppendL(x509cert); sl@0: CleanupStack::Pop(x509cert); sl@0: CleanupStack::PopAndDestroy(cert); sl@0: } sl@0: sl@0: TInt hashId=CovertHashNameToAlgorithmId(hashName); sl@0: iHashName.AppendL(hashId); sl@0: sl@0: iValidateResults.AppendL(vResult); sl@0: iSignedAttributePresent.AppendL(sAP); sl@0: iUnSignedAttributePresent.AppendL(uSAP); sl@0: iSignerInfoVersion.AppendL(signerInfoVersion); sl@0: sl@0: //for next pair sl@0: index++; sl@0: fKeyName.Format(_L("PrivateKey_%d"), index); sl@0: fCertName.Format(_L("Certificate_%d"), index); sl@0: fHashAlgorithmName.Format(_L("HashAlgorithm_%d"), index); sl@0: fValidationResult.Format(_L("ValidationResult_%d"), index); sl@0: fSignedAttributePresent.Format(_L("SignedAttributePresent_%d"), index); sl@0: fUnSignedAttributePresent.Format(_L("UnSignedAttributePresent_%d"), index); sl@0: fSignerInfoVersion.Format(_L("SignerInfoVersion_%d"), index); sl@0: } sl@0: } sl@0: return TestStepResult(); sl@0: } sl@0: sl@0: CMessageDigest* CTSignedDataBaseStep::CreateHashLC(TAlgorithmId aAlgorithmId) sl@0: { sl@0: CMessageDigest* hash(NULL); sl@0: switch (aAlgorithmId) sl@0: { sl@0: case EMD2: sl@0: hash=CMD2::NewL(); sl@0: break; sl@0: sl@0: case EMD5: sl@0: hash=CMD5::NewL(); sl@0: break; sl@0: sl@0: case ESHA1: sl@0: hash=CSHA1::NewL(); sl@0: break; sl@0: sl@0: default: sl@0: User::Leave(KErrNotSupported); sl@0: } sl@0: CleanupStack::PushL(hash); sl@0: return hash; sl@0: } sl@0: sl@0: sl@0: // sl@0: // Implementation of CMS Signed Data Test Step sl@0: // sl@0: CTCmsSignedDataStep::CTCmsSignedDataStep() sl@0: { sl@0: } sl@0: sl@0: CTCmsSignedDataStep::~CTCmsSignedDataStep() sl@0: { sl@0: } sl@0: sl@0: sl@0: void CTCmsSignedDataStep::CheckAndValidateSignedDataL(TDesC8& aRawData) sl@0: { sl@0: //Decode the content info encoding read from predefined file sl@0: CCmsContentInfo* content=CCmsContentInfo::NewL(aRawData); sl@0: CleanupStack::PushL(content); sl@0: if (content->ContentType()!=EContentTypeSignedData) sl@0: { sl@0: INFO_PRINTF1(_L("Content Type is not Signed Data")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: else sl@0: { sl@0: //Decode the signed data and check the fields sl@0: CCmsSignedObject* signedData=CCmsSignedObject::NewL(*content); sl@0: CleanupStack::PushL(signedData); sl@0: CheckSignedDataFieldsL(*signedData); sl@0: sl@0: //Validate the signatures sl@0: const RPointerArray& signerInfos=signedData->SignerInfo(); sl@0: CheckSignerInfoFieldsL(signerInfos); sl@0: sl@0: if (!iNoValidationTest) sl@0: { sl@0: TInt count=signerInfos.Count(); sl@0: for (TInt i=0;iValidateSignerLC(*signerInfos[i], iCertificates, certificateEncoding, ETrue, hash->Hash(iDataContent->Des())); sl@0: } sl@0: else sl@0: { sl@0: if (iIsDetached) sl@0: { sl@0: if (!iValidationDetachedWithoutInput) sl@0: { sl@0: isValid = signedData->ValidateSignerLC(*signerInfos[i], iCertificates, certificateEncoding, EFalse, iDataContent->Des()); sl@0: } sl@0: else sl@0: { sl@0: isValid = signedData->ValidateSignerLC(*signerInfos[i], iCertificates, certificateEncoding); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: isValid = signedData->ValidateSignerLC(*signerInfos[i], iCertificates, certificateEncoding); sl@0: } sl@0: } sl@0: } sl@0: else sl@0: { sl@0: INFO_PRINTF1(_L("Test validation by using the embedded certificates")); sl@0: sl@0: if (iIsHashAvailable) sl@0: { sl@0: isValid = signedData->ValidateSignerLC(*signerInfos[i], certificateEncoding, ETrue, hash->Hash(iDataContent->Des())); sl@0: } sl@0: else sl@0: { sl@0: if (iIsDetached) sl@0: { sl@0: if (!iValidationDetachedWithoutInput) sl@0: { sl@0: isValid = signedData->ValidateSignerLC(*signerInfos[i], certificateEncoding, EFalse, iDataContent->Des()); sl@0: } sl@0: else sl@0: { sl@0: isValid = signedData->ValidateSignerLC(*signerInfos[i], certificateEncoding); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: isValid = signedData->ValidateSignerLC(*signerInfos[i], certificateEncoding); sl@0: } sl@0: } sl@0: } sl@0: sl@0: if (!isValid) sl@0: { sl@0: INFO_PRINTF1(_L("Couldn't validate signer")); sl@0: } sl@0: else sl@0: { sl@0: CActiveScheduler* sched = NULL; sl@0: if (CActiveScheduler::Current() == NULL) sl@0: { sl@0: INFO_PRINTF1(_L("Installing scheduler")); sl@0: sched = new (ELeave) CActiveScheduler(); sl@0: CleanupStack::PushL (sched); sl@0: CActiveScheduler::Install (sched); sl@0: } sl@0: RPointerArray roots (&iRootCertificate, 1); sl@0: CPKIXCertChain * chain = CPKIXCertChain::NewLC(iFs, *certificateEncoding, roots); sl@0: sl@0: TTime tm; sl@0: _LIT(KDateCorrect1,"20061128:"); sl@0: TBuf <24> theDate(KDateCorrect1); sl@0: TInt err=tm.Set(theDate); sl@0: if(err) sl@0: { sl@0: tm.HomeTime(); sl@0: } sl@0: sl@0: CPKIXValidationResult* result = CPKIXValidationResult::NewLC(); sl@0: CTPKCS7Validator* validator = new (ELeave) CTPKCS7Validator (chain, result, &tm); sl@0: validator->doValidate (); sl@0: sched->Start (); sl@0: if (result->Error().iReason == EValidatedOK) sl@0: { sl@0: isValid = ETrue; sl@0: INFO_PRINTF1(_L("Validation success")); sl@0: } sl@0: else sl@0: { sl@0: isValid = EFalse; sl@0: INFO_PRINTF2(_L("Validation failed: %d"), result->Error().iReason); sl@0: } sl@0: delete validator; sl@0: CleanupStack::PopAndDestroy(result); sl@0: CleanupStack::PopAndDestroy(chain); sl@0: if (sched) sl@0: { sl@0: CActiveScheduler::Install (NULL); sl@0: CleanupStack::PopAndDestroy (sched); sl@0: } sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy(certificateEncoding); sl@0: if (hash) sl@0: { sl@0: CleanupStack::PopAndDestroy(hash); sl@0: } sl@0: sl@0: if (isValid!=iValidateResults[i]) sl@0: { sl@0: INFO_PRINTF1(_L("validate result not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: } sl@0: } sl@0: CleanupStack::PopAndDestroy(signedData); sl@0: } sl@0: CleanupStack::PopAndDestroy(content); sl@0: } sl@0: sl@0: void CTCmsSignedDataStep::CheckEncapsulatedContentFieldsL(const CEncapsulatedContentInfo& aEncapContentInfo) sl@0: { sl@0: if (aEncapContentInfo.ContentType()!=EContentTypeData) sl@0: { sl@0: INFO_PRINTF1(_L("Encapsulated data Content is not data content type")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: else sl@0: { sl@0: if (aEncapContentInfo.IsContentDataPresent() == iIsDetached) sl@0: { sl@0: INFO_PRINTF1(_L("Encapsulated data Content attachment not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: else sl@0: { sl@0: if (aEncapContentInfo.IsContentDataPresent() && aEncapContentInfo.ContentData()!=*iDataContent) sl@0: { sl@0: INFO_PRINTF1(_L("Encapsulated data Content not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CTCmsSignedDataStep::CheckAlgorithmSetFieldsL(const RPointerArray& aAlgorithms) sl@0: { sl@0: if (iAlgorithmCount!=aAlgorithms.Count()) sl@0: { sl@0: INFO_PRINTF1(_L("Number of Algorithm ID is not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: } sl@0: sl@0: void CTCmsSignedDataStep::CheckCertificateSetFieldsL(const CCmsSignedObject& aSignedData) sl@0: { sl@0: if (aSignedData.IsCertificateSetPresent()) sl@0: { sl@0: const RPointerArray& certSet=aSignedData.Certificates(); sl@0: if (iCertsCount!=certSet.Count()) sl@0: { sl@0: INFO_PRINTF1(_L("Number of Certificates is not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: else sl@0: { sl@0: //Signer Certificate is in the Signed data sl@0: if (!iNoCertSet) sl@0: { sl@0: TInt count = iCertificates.Count(); sl@0: for (TInt i=0;iCertificateType()==CCmsCertificateChoice::ECertificateX509 && !iCertificates[i]->IsEqualL(certSet[i]->Certificate())) sl@0: { sl@0: INFO_PRINTF2(_L("X509 Certificates %d is not as expected"), i); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: } sl@0: } sl@0: sl@0: if (iAdditionalCertificate || iAdditionalEncodedCertificate) sl@0: { sl@0: if (certSet[iCertsCount-1]->CertificateType()==CCmsCertificateChoice::ECertificateAttribute && sl@0: certSet[iCertsCount-1]->AttributeCertificate()->Compare(*iAdditionalEncodedCertificate)!=0) sl@0: { sl@0: INFO_PRINTF1(_L("Additional Attribute Certificates is not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: else if (certSet[iCertsCount-1]->CertificateType()==CCmsCertificateChoice::ECertificateX509) sl@0: { sl@0: if (iAdditionalCertificate && !certSet[iCertsCount-1]->Certificate().IsEqualL(*iAdditionalCertificate)) sl@0: { sl@0: INFO_PRINTF1(_L("Additional X509 Certificates is not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: else sl@0: { sl@0: if (iAdditionalEncodedCertificate) sl@0: { sl@0: CX509Certificate* addX509Cert=CX509Certificate::NewLC(*iAdditionalEncodedCertificate); sl@0: if (!certSet[iCertsCount-1]->Certificate().IsEqualL(*addX509Cert)) sl@0: { sl@0: INFO_PRINTF1(_L("Additional X509 Certificates is not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: CleanupStack::PopAndDestroy(addX509Cert); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CTCmsSignedDataStep::CheckSignerInfoFieldsL(const RPointerArray& signerInfos) sl@0: { sl@0: TInt count=signerInfos.Count(); sl@0: if (iDecPKCS8Data.Count()!=count && iSignerCount!=count) sl@0: { sl@0: INFO_PRINTF1(_L("Number of Signer Info is not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: for (TInt i=0;iIsSignedAttributesPresent()!=iSignedAttributePresent[i] sl@0: || signerInfos[i]->IsUnsignedAttributesPresent()!=iUnSignedAttributePresent[i] sl@0: || signerInfos[i]->Version()!=iSignerInfoVersion[i]) sl@0: { sl@0: INFO_PRINTF1(_L("Signed or Unsigned Attribute presence or Signer Version is not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: sl@0: const CX509AlgorithmIdentifier& digestId=signerInfos[i]->DigestAlgorithm(); sl@0: if (digestId.Algorithm()!=(TAlgorithmId)iHashName[i]) sl@0: { sl@0: INFO_PRINTF1(_L("Digest Algorithm ID is not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: sl@0: const CX509AlgorithmIdentifier& sigId=signerInfos[i]->SignatureAlgorithm(); sl@0: if (iDecPKCS8Data[i]->Algorithm()!=sigId.Algorithm()) sl@0: { sl@0: INFO_PRINTF1(_L("Signature Algorithm ID is not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: sl@0: const CCmsSignerIdentifier& signerId=signerInfos[i]->SignerIdentifier(); sl@0: if (signerId.SignerIdentifierType()==CCmsSignerIdentifier::EIssuerAndSerialNumber) sl@0: { sl@0: if (!iCertificates[i]->IssuerName().ExactMatchL(signerId.IssuerAndSerialNumber()->IssuerName())) sl@0: { sl@0: INFO_PRINTF1(_L("Issuer name is not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: else sl@0: { sl@0: RInteger sn1=RInteger::NewL(iCertificates[i]->SerialNumber()); sl@0: CleanupClosePushL(sn1); sl@0: RInteger sn2=RInteger::NewL(signerId.IssuerAndSerialNumber()->SerialNumber()); sl@0: CleanupClosePushL(sn2); sl@0: if (sn1!=sn2) sl@0: { sl@0: INFO_PRINTF1(_L("Serial number is not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: CleanupStack::PopAndDestroy(2, &sn1);//sn2, sn1 sl@0: sl@0: } sl@0: } sl@0: else if (signerId.SignerIdentifierType()==CCmsSignerIdentifier::ESubjectKeyIdentifier) sl@0: { sl@0: const CX509CertExtension* certExt = iCertificates[i]->Extension(KSubjectKeyId); sl@0: if (certExt) sl@0: { sl@0: CX509SubjectKeyIdExt* ext=CX509SubjectKeyIdExt::NewLC(certExt->Data()); sl@0: if (signerId.SubjectKeyIdentifier().Compare(ext->KeyId())!=0) sl@0: { sl@0: INFO_PRINTF1(_L("Subject Key Id is not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: CleanupStack::PopAndDestroy(ext); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CTCmsSignedDataStep::CheckSignedDataFieldsL(const CCmsSignedObject& aSignedData) sl@0: { sl@0: if (aSignedData.IsCertificateSetPresent()!=iCertificateSetPresent || sl@0: aSignedData.IsCertificateRevocationListsPresent()!=iCRLsSetPresent || sl@0: aSignedData.Version()!=iSignedDataVersion) sl@0: { sl@0: INFO_PRINTF1(_L("cert present or CRL present or version not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: else sl@0: { sl@0: const CEncapsulatedContentInfo& encapContentInfo=aSignedData.ContentInfo(); sl@0: CheckEncapsulatedContentFieldsL(encapContentInfo); sl@0: const RPointerArray& algorithms=aSignedData.DigestAlgorithms(); sl@0: CheckAlgorithmSetFieldsL(algorithms); sl@0: CheckCertificateSetFieldsL(aSignedData); sl@0: } sl@0: } sl@0: sl@0: void CTCmsSignedDataStep::doTestL() sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: CCmsSignedObject* signedData(NULL); sl@0: TInt count=iDecPKCS8Data.Count(); sl@0: sl@0: //Create Signed Object sl@0: for (TInt i=0;iKeyPairData(); sl@0: sl@0: CMessageDigest* hash(NULL); sl@0: TPtrC8 hashValue; sl@0: if (iIsHashAvailable) sl@0: { sl@0: hash=CreateHashLC((TAlgorithmId)iHashName[i]); sl@0: hashValue.Set(hash->Hash(iDataContent->Des())); sl@0: } sl@0: sl@0: //If it is the first time, a signed object needs to be created sl@0: if (i==0) sl@0: { sl@0: if (iIsHashAvailable) sl@0: { sl@0: if (decPKCS8Data->Algorithm()==ERSA) sl@0: { sl@0: const CRSAPrivateKey& RSAPrivateKey=static_cast(keyPair)->PrivateKey(); sl@0: if (!iTwoStepCreation) sl@0: { sl@0: signedData=CCmsSignedObject::NewL((TCmsContentInfoType)iContentType, sl@0: hashValue, sl@0: (TAlgorithmId)iHashName[i], sl@0: RSAPrivateKey, sl@0: *iCertificates[i], sl@0: !iNoCertSet); sl@0: CleanupStack::PushL(signedData); sl@0: } sl@0: else sl@0: { sl@0: signedData=CCmsSignedObject::NewL((TCmsContentInfoType)iContentType, iIsDetached, iDataContent->Des()); sl@0: CleanupStack::PushL(signedData); sl@0: signedData->SignL(hashValue, (TAlgorithmId)iHashName[i], RSAPrivateKey, *iCertificates[i], !iNoCertSet); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: const CDSAPrivateKey& DSAPrivateKey=static_cast(keyPair)->PrivateKey(); sl@0: if (!iTwoStepCreation) sl@0: { sl@0: signedData=CCmsSignedObject::NewL((TCmsContentInfoType)iContentType, sl@0: hashValue, sl@0: (TAlgorithmId)iHashName[i], sl@0: DSAPrivateKey, sl@0: *iCertificates[i], sl@0: !iNoCertSet); sl@0: CleanupStack::PushL(signedData); sl@0: } sl@0: else sl@0: { sl@0: signedData=CCmsSignedObject::NewL((TCmsContentInfoType)iContentType, iIsDetached, iDataContent->Des()); sl@0: CleanupStack::PushL(signedData); sl@0: signedData->SignL(hashValue, (TAlgorithmId)iHashName[i], DSAPrivateKey, *iCertificates[i], !iNoCertSet); sl@0: } sl@0: iRsaAlgorithm=EFalse; sl@0: } sl@0: CleanupStack::Pop(signedData); sl@0: CleanupStack::PopAndDestroy(hash); sl@0: CleanupStack::PushL(signedData); sl@0: } sl@0: else sl@0: { sl@0: signedData=CCmsSignedObject::NewL((TCmsContentInfoType)iContentType, iIsDetached, iDataContent->Des()); sl@0: CleanupStack::PushL(signedData); sl@0: if (!iNoSigning) sl@0: { sl@0: if (decPKCS8Data->Algorithm()==ERSA) sl@0: { sl@0: const CRSAPrivateKey& RSAPrivateKey=static_cast(keyPair)->PrivateKey(); sl@0: signedData->SignL(KNullDesC8, (TAlgorithmId)iHashName[i], RSAPrivateKey, *iCertificates[i], !iNoCertSet); sl@0: } sl@0: else sl@0: { sl@0: const CDSAPrivateKey& DSAPrivateKey=static_cast(keyPair)->PrivateKey(); sl@0: signedData->SignL(KNullDesC8, (TAlgorithmId)iHashName[i], DSAPrivateKey, *iCertificates[i], !iNoCertSet); sl@0: iRsaAlgorithm=EFalse; sl@0: } sl@0: } sl@0: } sl@0: } sl@0: else sl@0: { sl@0: //multiple signatures sl@0: if (iIsHashAvailable) sl@0: { sl@0: if (decPKCS8Data->Algorithm()==ERSA) sl@0: { sl@0: const CRSAPrivateKey& RSAPrivateKey=static_cast(keyPair)->PrivateKey(); sl@0: signedData->SignL(hashValue, (TAlgorithmId)iHashName[i], RSAPrivateKey, *iCertificates[i], !iNoCertSet); sl@0: } sl@0: else sl@0: { sl@0: const CDSAPrivateKey& DSAPrivateKey=static_cast(keyPair)->PrivateKey(); sl@0: signedData->SignL(hashValue, (TAlgorithmId)iHashName[i], DSAPrivateKey, *iCertificates[i], !iNoCertSet); sl@0: iRsaAlgorithm=EFalse; sl@0: } sl@0: CleanupStack::PopAndDestroy(hash); sl@0: } sl@0: else sl@0: { sl@0: if (decPKCS8Data->Algorithm()==ERSA) sl@0: { sl@0: const CRSAPrivateKey& RSAPrivateKey=static_cast(keyPair)->PrivateKey(); sl@0: signedData->SignL(KNullDesC8, (TAlgorithmId)iHashName[i], RSAPrivateKey, *iCertificates[i], !iNoCertSet); sl@0: } sl@0: else sl@0: { sl@0: const CDSAPrivateKey& DSAPrivateKey=static_cast(keyPair)->PrivateKey(); sl@0: signedData->SignL(KNullDesC8, (TAlgorithmId)iHashName[i], DSAPrivateKey, *iCertificates[i], !iNoCertSet); sl@0: iRsaAlgorithm=EFalse; sl@0: } sl@0: } sl@0: } sl@0: } sl@0: sl@0: if (iAdditionalCertificate) sl@0: { sl@0: signedData->AddCertificateL(*iAdditionalCertificate); sl@0: } sl@0: sl@0: if (iAdditionalEncodedCertificate) sl@0: { sl@0: signedData->AddCertificateL(*iAdditionalEncodedCertificate, (CCmsCertificateChoice::TCertificateType)iAdditionalEncodedCertificateType); sl@0: } sl@0: sl@0: //Encoding the Signed object sl@0: CASN1EncSequence* signedObjectSeq=signedData->EncodeASN1DERLC(); sl@0: HBufC8* buf=CreateDEREncodingLC(*signedObjectSeq); sl@0: sl@0: //Encoding the wrapper Content Info sl@0: CCmsContentInfo* content=CCmsContentInfo::NewL(EContentTypeSignedData, *buf); sl@0: CleanupStack::PushL(content); sl@0: CASN1EncSequence* contentSeq=content->EncodeASN1DERLC(); sl@0: HBufC8* signature=CreateDEREncodingLC(*contentSeq); sl@0: CleanupStack::Pop(signature); sl@0: CleanupStack::PopAndDestroy(5, signedData); //contentSeq,content,buf,signedObjectSeq,signedData sl@0: CleanupStack::PushL(signature); sl@0: sl@0: sl@0: //write the result to a file, for initial debuging sl@0: //OutputResultToFileL(signature->Des()); sl@0: sl@0: //Compare the result with the expected result, if the signature algorithms are RSA sl@0: sl@0: if (iRsaAlgorithm) sl@0: { sl@0: sl@0: //Check if the signature is the same as expected sl@0: TBool r=signature->Compare(*iExpectedEncoding); sl@0: if (r!=0 && !iIsOOMTest) sl@0: { sl@0: INFO_PRINTF1(_L("RSA Signature Encoding Error")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: else sl@0: { sl@0: CheckAndValidateSignedDataL(*iExpectedEncoding); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: CheckAndValidateSignedDataL(*iExpectedEncoding); sl@0: CheckAndValidateSignedDataL(*signature); sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy(signature); sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: // sl@0: // Implementation of CMS Signed Data Decoding Test Step sl@0: // sl@0: sl@0: CTCmsSignedDataDecodingStep::CTCmsSignedDataDecodingStep() sl@0: { sl@0: } sl@0: sl@0: CTCmsSignedDataDecodingStep::~CTCmsSignedDataDecodingStep() sl@0: { sl@0: } sl@0: sl@0: void CTCmsSignedDataDecodingStep::doTestL() sl@0: { sl@0: __UHEAP_MARK; sl@0: CheckAndValidateSignedDataL(*iExpectedEncoding); sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: // sl@0: // Implementation of CMS Content Info Test step sl@0: // sl@0: CTCmsContentInfoDecodingStep::CTCmsContentInfoDecodingStep() sl@0: { sl@0: } sl@0: sl@0: CTCmsContentInfoDecodingStep::~CTCmsContentInfoDecodingStep() sl@0: { sl@0: } sl@0: sl@0: void CTCmsContentInfoDecodingStep::doTestL() sl@0: { sl@0: INFO_PRINTF1(_L("Start CMS Data Type Decoding")); sl@0: CCmsContentInfo* content=CCmsContentInfo::NewL(*iExpectedEncoding); sl@0: CleanupStack::PushL(content); sl@0: if (content->ContentType()!=iExpectedDataType) sl@0: { sl@0: INFO_PRINTF1(_L("CMS Data Type is not as expected")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: CleanupStack::PopAndDestroy(content); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: