diff -r 000000000000 -r 2c201484c85f cryptoservices/certificateandkeymgmt/twtlscert/ValidateTest.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cryptoservices/certificateandkeymgmt/twtlscert/ValidateTest.cpp Wed Jul 08 11:25:26 2009 +0100 @@ -0,0 +1,589 @@ +/* +* Copyright (c) 1998-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: +* +*/ + + + +#include "ValidateTest.h" +#include "t_input.h" +#include + +_LIT(KPath, ""); +_LIT(KChainStart, ""); +_LIT(KDateIssuedStart, ""); +_LIT(KIOStart, ""); + +CTestAction* CValidateTest::NewL(RFs& aFs, CConsoleBase& aConsole, + Output& aOut, const TTestActionSpec& aTestActionSpec) + { + CTestAction* self = CValidateTest::NewLC(aFs, aConsole, aOut, aTestActionSpec); + CleanupStack::Pop(self); + return self; + } + +CTestAction* CValidateTest::NewLC(RFs& aFs, CConsoleBase& aConsole, + Output& aOut, const TTestActionSpec& aTestActionSpec) + { + CValidateTest* self = new(ELeave) CValidateTest(aFs, aConsole, aOut); + CleanupStack::PushL(self); + self->ConstructL(aTestActionSpec); + return self; + } + + +void CValidateTest::TestValidation(TRequestStatus& aStatus) + { + iOriginalRequestStatus = &aStatus; + aStatus = KRequestPending; + + iState = EInit; + TRequestStatus* status = &aStatus; + User::RequestComplete(status, KErrNone); + } + +CValidateTest::CValidateTest(RFs& aFs, + CConsoleBase& aConsole, + Output& aOut) +: CTestAction(aConsole, aOut), iFs(aFs) + { + } + +void CValidateTest::ConstructL(const TTestActionSpec& aTestActionSpec) + { + CTestAction::ConstructL(aTestActionSpec); + iValidationResult = CWTLSValidationResult::NewL(); + HBufC* aBody = HBufC::NewLC(aTestActionSpec.iActionBody.Length()); + aBody->Des().Copy(aTestActionSpec.iActionBody); + // creates the test chan validation object + iTestChain = CTestChainValidate::NewL(); + TPtrC chainBuf = Input::ParseElement(*aBody, KChainStart); + + iTestChain->AddChainL(chainBuf); + TPtrC ioDateIssued = Input::ParseElement(*aBody, KDateIssuedStart); + iTestChain->AddDateIssued(ioDateIssued); + TPtrC ioBuf = Input::ParseElement(*aBody, KIOStart); + iTestChain->AddIOL(ioBuf); + + CleanupStack::PopAndDestroy(aBody); + } + +CValidateTest::~CValidateTest() + { + delete iTestChain; + delete iCertUtils; + delete iValidationResult; + delete iChain; + REComSession::FinalClose(); + } + +void CValidateTest::DoPerformPrerequisite(TRequestStatus& aStatus) + { + TInt err = KErrNone; + + switch (iState) + { + case EInit: + iResult = ETrue; + __ASSERT_DEBUG(!iCertUtils, User::Panic(_L("TWTLSCertTest"), 1)); + iCertUtils = CCertUtils::NewL(iFs); + TRAP(err, HandleEInitL(aStatus)); + break; + + case EValidationStoreInitStoreManager1: + TRAP(err, HandleEValidationInitStoreManager1L(aStatus)); + iActionState = EAction; + break; + case EValidationStoreDepopulateStore1: + case EValidationStorePopulateStoreRoots: + case EValidationStorePopulateStoreExtras: + case EValidationStoreValidate: + case EValidationStoreValidated: + case EValidationStoreInitStoreManager2: + case EValidationStoreDepopulateStore2: + case EValidationStoreEnd: + case EValidationSuppliedInit: + case EValidationSuppliedValidate: + case EValidationSuppliedValidated: + case EFinished: + break; // Nothing to do, for compiler + } + } + +void CValidateTest::DoPerformPostrequisite(TRequestStatus& aStatus) + { + TInt err = KErrNone; + + switch (iState) + { + case EInit: + case EValidationStoreInitStoreManager1: + case EValidationStoreDepopulateStore1: + case EValidationStorePopulateStoreRoots: + case EValidationStorePopulateStoreExtras: + case EValidationStoreValidate: + case EValidationStoreValidated: + case EValidationStoreInitStoreManager2: + case EValidationStoreDepopulateStore2: + case EValidationStoreEnd: + break; // Nothing to do, for compiler + case EValidationSuppliedInit: + { + iConsole.Printf(_L("started with supplied certs...\n")); + iOut.writeString(_L("started with supplied certs...")); + iOut.writeNewLine(); + + iState = EValidationSuppliedValidate; + TRequestStatus* status = &aStatus; + User::RequestComplete(status, KErrNone); + } + break; + + case EValidationSuppliedValidate: + { + HBufC8* encodedCerts = ReadFilesLC(*iTestChain->iServerCerts); + + if(!encodedCerts) + { + TRequestStatus* status = &aStatus; + iFinished = ETrue; + User::RequestComplete(status, KErrNone); + } + else + { + TInt certCount = iTestChain->iRootCerts->MdcaCount(); + CArrayPtrFlat* roots = + new(ELeave) CArrayPtrFlat(1); + TCleanupItem cleanup(CleanupCertArray, roots); + CleanupStack::PushL(cleanup); + for (TInt i = 0; i < certCount; i++) + { + // build the root certificates array including all the candidates. + HBufC8* encCert = + ReadFileLC(iTestChain->iRootCerts->MdcaPoint(i)); + CWTLSCertificate* cert = CWTLSCertificate::NewLC(encCert->Des()); + roots->AppendL(cert); + CleanupStack::Pop(); // cert + CleanupStack::PopAndDestroy(); // encCert + } + + __ASSERT_DEBUG(!iChain, User::Panic(_L("CValidateTest"), 1)); + iChain = CWTLSCertChain::NewL(iFs, *encodedCerts, *roots); + + CleanupStack::PopAndDestroy(2); // encodedCerts, roots + + TDateTime dt(2000, EJuly, 0, 0, 0, 0, 0); + if(iTestChain->iDateIssued == 1) + { + dt.SetYear(2002); + } + iTime = dt; + + iChain->ValidateL(*iValidationResult, iTime, aStatus); + iState = EValidationSuppliedValidated; + } + } + break; + + case EValidationSuppliedValidated: + { + delete iChain; + iChain = 0; + TWTLSValidationStatus* expectedStatus = iTestChain->iError; + const TWTLSValidationStatus& actualStatus = iValidationResult->Error(); + + iOut.writeString(_L("Expected Error = ")); + WriteError(expectedStatus->iReason); + iOut.writeNewLine(); + + iOut.writeString(_L("Actual Error = ")); + WriteError(actualStatus.iReason); + iOut.writeNewLine(); + + TInt wCount = iTestChain->iWarnings->Count(); + iOut.writeString(_L("Expected Warnings = ")); + iOut.writeNewLine(); + for (TInt i = 0; i < wCount; i++) + { + TWTLSValidationStatus warning = iTestChain->iWarnings->At(i); + WriteError(warning.iReason); + iOut.writeNewLine(); + } + + iOut.writeString(_L("Actual Warnings = ")); + iOut.writeNewLine(); + const CArrayFixFlat& warnings = + iValidationResult->Warnings(); + wCount = warnings.Count(); + for (TInt j = 0; j < wCount; j++) + { + TWTLSValidationStatus warning = warnings.At(j); + WriteError(warning.iReason); + iOut.writeNewLine(); + } + iOut.writeNewLine(); + + if(expectedStatus->iReason != actualStatus.iReason) + { + iConsole.Printf(_L("FAILED!!!!\n")); + iOut.writeString(_L("FAILED!!!!")); + iOut.writeNewLine(); + iResult = EFalse; + } + + // End of validatewith supplied + if (err != KErrNone) + { + iOut.writeString(_L("Failed: leave code = ")); + iOut.writeNum(err); + iOut.writeNewLine(); + } + + iState = EFinished; + TRequestStatus* status = &aStatus; + User::RequestComplete(status, KErrNone); + } + break; + + case EFinished: + { + TTime end; + end.HomeTime(); + TTimeIntervalMicroSeconds intervalMS = end.MicroSecondsFrom(iStart); + iConsole.Printf(_L("Time taken = %d milliseconds\n"), (intervalMS.Int64()/1000)); + + TRequestStatus* status = &aStatus; + iFinished = ETrue; + User::RequestComplete(status, KErrNone); + } + break; + } + } + +void CValidateTest::PerformAction(TRequestStatus& aStatus) + { + TRequestStatus* status = &aStatus; + + switch (iState) + { + case EValidationStoreDepopulateStore1: + { + iCertUtils->RemoveCertsL(aStatus); + iState = EValidationStorePopulateStoreRoots; + break; + } + + case EValidationStorePopulateStoreRoots: + { + TUid uid = { 1 }; + TRAP_IGNORE(iCertUtils->RemoveApplicationL(uid)); + iCertUtils->AddApplicationL(_L("testwtls"), uid); + iCertUtils->AddCACertsL(*iTestChain->iRootCerts, + *iTestChain->iRootLabels, EWTLSCertificate, 1, KPath, aStatus); + iState = EValidationStorePopulateStoreExtras; + break; + } + + case EValidationStorePopulateStoreExtras: + { + iCertUtils->AddCACertsL(*iTestChain->iExtraCerts, + *iTestChain->iExtraLabels, EWTLSCertificate, 2, KPath, aStatus); + iState = EValidationStoreValidate; + break; + } + + case EValidationStoreValidate: + { + HBufC8* encodedCerts = ReadFilesLC(*iTestChain->iServerCerts); + + TUid testUid = TUid::Uid(1); + + if(!encodedCerts) + { + TRequestStatus* status = &aStatus; + iFinished = ETrue; + User::RequestComplete(status, KErrNone); + } + else + { + __ASSERT_DEBUG(!iChain, User::Panic(_L("CValidateTest"), 1)); + iChain = CWTLSCertChain::NewL(iFs, *encodedCerts, testUid); + CleanupStack::PopAndDestroy(); // encodedCerts + + TDateTime dt(2000, EJuly, 0, 0, 0, 0, 0); + if(iTestChain->iDateIssued == 1) + { + dt.SetYear(2002); + } + iTime = dt; + + TRAP_IGNORE(iChain->ValidateL(*iValidationResult, iTime, aStatus)); + iState = EValidationStoreValidated; + }; + break; + } + + case EValidationStoreValidated: + { + TInt count = iChain->Count(); + if (count > 0) + { + iOut.writeString(_L("EE certificate = ")); + const CWTLSCertificate& eeCert = iChain->Cert(0); + HBufC* eeSubject = eeCert.SubjectL(); + CleanupStack::PushL(eeSubject); + iOut.writeString(*eeSubject); + CleanupStack::PopAndDestroy(); + iOut.writeNewLine(); + for (TInt i = 1; i < count - 1; i++) + { + iOut.writeString(_L("Intermediate certificate = ")); + const CWTLSCertificate& iCert = iChain->Cert(i); + HBufC* subject = iCert.SubjectL(); + CleanupStack::PushL(subject); + iOut.writeString(*subject); + CleanupStack::PopAndDestroy(); + iOut.writeNewLine(); + } + iOut.writeString(_L("Root certificate = ")); + const CWTLSCertificate& rCert = iChain->Cert(count-1); + HBufC* rSubject = rCert.SubjectL(); + CleanupStack::PushL(rSubject); + iOut.writeString(*rSubject); + CleanupStack::PopAndDestroy(); + iOut.writeNewLine(); + } + + TWTLSValidationStatus* expectedStatus = iTestChain->iError; + const TWTLSValidationStatus& actualStatus = iValidationResult->Error(); + + iOut.writeString(_L("Expected Error = ")); + WriteError(expectedStatus->iReason); + iOut.writeNewLine(); + + iOut.writeString(_L("Actual Error = ")); + WriteError(actualStatus.iReason); + iOut.writeNewLine(); + + TInt wCount = iTestChain->iWarnings->Count(); + iOut.writeString(_L("Expected Warnings = ")); + iOut.writeNewLine(); + for (TInt i = 0; i < wCount; i++) + { + TWTLSValidationStatus warning = iTestChain->iWarnings->At(i); + WriteError(warning.iReason); + iOut.writeNewLine(); + } + + iOut.writeString(_L("Actual Warnings = ")); + iOut.writeNewLine(); + const CArrayFixFlat& warnings = + iValidationResult->Warnings(); + wCount = warnings.Count(); + for (TInt j = 0; j < wCount; j++) + { + TWTLSValidationStatus warning = warnings.At(j); + WriteError(warning.iReason); + iOut.writeNewLine(); + } + iOut.writeNewLine(); + + if(expectedStatus->iReason != actualStatus.iReason) + { + iConsole.Printf(_L("FAILED!!!!\n")); + iOut.writeString(_L("FAILED!!!!")); + iOut.writeNewLine(); + iResult = EFalse; + } + + // End of DoValidate + iState = EValidationStoreInitStoreManager2; + User::RequestComplete(status, KErrNone); + delete iChain; + iChain = 0; + break; + } + + case EValidationStoreInitStoreManager2: + { + User::RequestComplete(status, KErrNone); + iState = EValidationStoreDepopulateStore2; + break; + } + + case EValidationStoreDepopulateStore2: + { + iCertUtils->RemoveCertsL(aStatus); + TUid uid = { 1 }; + iCertUtils->RemoveApplicationL(uid); + iState = EValidationStoreEnd; + break; + } + + case EValidationStoreEnd: + { + iState = EValidationSuppliedInit; + iActionState = EPostrequisite; + User::RequestComplete(status, KErrNone); + break; + } + case EInit: + case EValidationStoreInitStoreManager1: + case EValidationSuppliedInit: + case EValidationSuppliedValidate: + case EValidationSuppliedValidated: + case EFinished: + break; // Nothing to do, for compiler + } + } + +HBufC8* CValidateTest::ReadFileLC(const TDesC& aFilename) + { + RFile file; + User::LeaveIfError(file.Open(iFs, aFilename, EFileRead)); + CleanupClosePushL(file); + TInt size; + file.Size(size); + CleanupStack::PopAndDestroy(1);//fileClose + + HBufC8* res = HBufC8::NewLC(size); + TPtr8 p(res->Des()); + p.SetLength(size); + + RFileReadStream stream; + User::LeaveIfError(stream.Open(iFs, aFilename, EFileStream)); + CleanupClosePushL(stream); + stream.ReadL(p, size); + CleanupStack::PopAndDestroy();//streamClose...bleurgh + return res; + } + + +HBufC8* CValidateTest::ReadFilesLC(CDesCArray& aServerCerts) + { + TInt count = aServerCerts.MdcaCount(); + TInt totalSize = 0; + TInt i; + + for (i = 0; i < count; i++) + { + TPtrC filename = aServerCerts.MdcaPoint(i); + RFile file; + TRAPD(err, file.Open(iFs, filename, EFileRead)); + if(err != KErrNone) + { + HBufC *failedToLoad = filename.AllocLC(); + SetScriptError(EFileNotFound, failedToLoad->Des()); + CleanupStack::PopAndDestroy(2);//fsclose, fileClose + return(NULL); + }; + CleanupClosePushL(file); + TInt size; + file.Size(size); + CleanupStack::PopAndDestroy(1); // fileClose + totalSize += size; + } + + HBufC8* res = HBufC8::NewLC(totalSize); + TPtr8 pRes = res->Des(); + for (i = 0; i < count; i++) + { + HBufC8* cert = ReadFileLC(aServerCerts.MdcaPoint(i)); + pRes.Append(cert->Des()); + CleanupStack::PopAndDestroy();//cert + } + return res; + } + +void CValidateTest::WriteError(TValidationError aError) + { + switch(aError) + { + //errors + case EValidatedOK: + { + iOut.writeString(_L("Validated OK")); + break; + } + case EChainHasNoRoot: + { + iOut.writeString(_L("No trusted root found")); + break; + } + case ESignatureInvalid: + { + iOut.writeString(_L("Signature invalid")); + break; + } + case EDateOutOfRange: + { + iOut.writeString(_L("Date out of range")); + break; + } + case ENamesDontChain: + { + iOut.writeString(_L("Names don't chain")); + break; + } + case ENotCACert: + { + iOut.writeString(_L("Cert not authorised to sign other certs")); + break; + } + + default: + { + iOut.writeString(_L("Unknown")); + break; + } + } + } + +void CValidateTest::CleanupCertArray(TAny* aCertArray) + { + CArrayPtrFlat* certs = REINTERPRET_CAST(CArrayPtrFlat*, aCertArray); + certs->ResetAndDestroy(); + delete certs; + } + +void CValidateTest::HandleEInitL(TRequestStatus& aStatus) + { + iConsole.Printf(_L("Chain validation tests...\n")); + iStart.HomeTime(); + + iConsole.Printf(_L("started with store...\n")); + iOut.writeString(_L("started with store...")); + iOut.writeNewLine(); + + iState = EValidationStoreInitStoreManager1; + TRequestStatus* status = &aStatus; + User::RequestComplete(status, KErrNone); + } + +void CValidateTest::HandleEValidationInitStoreManager1L(TRequestStatus& aStatus) + { + TRequestStatus* status = &aStatus; + User::RequestComplete(status, KErrNone); + iState = EValidationStoreDepopulateStore1; + } + + +void CValidateTest::DoReportAction() + { + } + +void CValidateTest::DoCheckResult(TInt /*aError*/) + { + }