diff -r 000000000000 -r 164170e6151a pkiutilities/ocsp/test/engine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkiutilities/ocsp/test/engine.cpp Tue Jan 26 15:20:08 2010 +0200 @@ -0,0 +1,1123 @@ +// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "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 "engine.h" +#include "transport.h" +#include "panic.h" +#include "logger.h" +#include "main.h" +#include "requestlogger.h" +#include "testfilterparameters.h" +#include + +#include +#include + +#include + +#include "ocspsupporttransport.h" + +// Log file created by the transport filter +_LIT(KFilterLogFileName, "\\tocsphttpfilter.log"); + +const TInt KTimeMilliToMicro = 1000; + +CTOCSPEngine* CTOCSPEngine::NewL(CTOCSPLogger& aLog) + { + CTOCSPEngine* self = new (ELeave) CTOCSPEngine(aLog); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +CTOCSPEngine::CTOCSPEngine(CTOCSPLogger& aLog) : + CActive(EPriorityNormal), + iLog(aLog) + { + CActiveScheduler::Add(this); + } + + +void CTOCSPEngine::ConstructL() + { + // Open file server session + User::LeaveIfError(iFs.Connect()); + iCertUtils = CCertUtils::NewL(iFs); + + // Create cancellation timer + iTimer = CCallbackTimer::NewL(*this); + } + +CTOCSPEngine::~CTOCSPEngine() + { + Cancel(); // Calls Reset along the way + Destroy(); + delete iTimer; + delete iCertUtils; + delete iUnifiedCertStore; + iFs.Close(); + } + +// Common code between destructor and ResetL() +void CTOCSPEngine::Destroy() + { + delete iParams; + iParams = NULL; + + delete iClient; + iClient = NULL; + + iSubjectCerts.ResetAndDestroy(); + iIssuerCerts.ResetAndDestroy(); + iSigningCerts.ResetAndDestroy(); + iTransportLog.Close(); + + delete iRequestLog; + iRequestLog = NULL; + + // Not owned + iTransport = NULL; + } + +void CTOCSPEngine::Reset() + { + Destroy(); + + // Delete and reset all the filter parameters + DeleteFilterParameters(); + + iUseDirectAuthorisation = EFalse; + iUseCADelegateAuthorisation = EFalse; + iUseCADirectAuthorisation = EFalse; + iUseAllSchemes = EFalse; + + iCancelTime = 0; + } + + +void CTOCSPEngine::StartL(TRequestStatus& aStatus) + { + iParams = COCSPParameters::NewL(); + InitDirectAuthL(); + + // Delete the transport filter log file + TInt err = iFs.Delete(KFilterLogFileName); + if ((err != KErrNone) && (err != KErrNotFound)) + { + if (iVerbose) + { + iLog.LogL(_L("Failed to delete transport filter log file ("), ETrue); + iLog.LogL(KFilterLogFileName); + iLog.LogL(_L("). Error: "), ETrue); + iLog.LogL(err); + } + User::Leave(err); + } + + iState = EInitCertStore; + aStatus = KRequestPending; + iOriginalRequestStatus = &aStatus; + SetActive(); + + // Initialise unified cert store here if it doesn't already exist + if (!iUnifiedCertStore) + { + iUnifiedCertStore = CUnifiedCertStore::NewL(iFs, ETrue); + iUnifiedCertStore->Initialize(iStatus); + } + else + { + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + } + } + +void CTOCSPEngine::EndL(TRequestStatus& aStatus) + { + Reset(); + CleanUpDirectAuthL(aStatus); + } + + +void CTOCSPEngine::SetURIL(const TDesC8& aURI, TBool aUseAIA) + { + iParams->SetURIL(aURI, aUseAIA); + } + + +void CTOCSPEngine::SetDefaultTransportL() + { + iIap = 0; + MOCSPTransport* trans = COCSPTransportDefault::NewL(iIap); + CleanupStack::PushL(trans); + SetTransportL(trans); + CleanupStack::Pop(trans); + } + + +void CTOCSPEngine::SetTestTransportL(const TDesC& aResponseFile, const TDesC* aRequestFile) + { + CTOCSPTransport* trans = CTOCSPTransport::NewL(aResponseFile, aRequestFile); + CleanupStack::PushL(trans); + SetTransportL(trans); + CleanupStack::Pop(trans); + } + +void CTOCSPEngine::SetOcspSupportTransportL() + { + iIap = 0; + Swi::COcspSupportTransport* trans = Swi::COcspSupportTransport::NewL(iIap); + + CleanupStack::PushL(trans); + SetTransportL(trans); + CleanupStack::Pop(trans); + } + +void CTOCSPEngine::SetTransportRetryCount(TUint aRetryCount) + { + __ASSERT_DEBUG(iTransport != NULL, Panic(KErrTOCSPScriptParameterError)); + iParams->SetRetryCount(aRetryCount); + } + +void CTOCSPEngine::SetTransportTimeout(TInt aTimeout) + { + __ASSERT_DEBUG(iTransport != NULL, Panic(KErrTOCSPScriptParameterError)); + iParams->SetTimeout(aTimeout); + } + +void CTOCSPEngine::SetTransportL(MOCSPTransport* aTransport) + { + // To log the request, we wrap the transport in our request logger transport + if (iRequestLog) + { + aTransport = CTOCSPRequestLogger::NewL(*iRequestLog, aTransport); + } + iTransport = aTransport; + iParams->SetTransport(aTransport); + } + +void CTOCSPEngine::SetFilterParameters(TInt aNumDelayResp, TInt aCountDropResp, + TInt countCorruptHTTPDataHeader, TInt countCorruptHTTPDataBodySizeLarge, TInt countCorruptHTTPDataBodySizeSmall, + TInt aCountCorruptOCSPData, + TInt aCountInternalErrorResp, TInt aCountTryLaterResp, + TInt aCountSigValidateFailure) + { + iNumDelayResp = aNumDelayResp; + iCountDropResp = aCountDropResp; + iCountCorruptHTTPDataHeader = countCorruptHTTPDataHeader; + iCountCorruptHTTPDataBodySizeLarge = countCorruptHTTPDataBodySizeLarge; + iCountCorruptHTTPDataBodySizeSmall = countCorruptHTTPDataBodySizeSmall; + iCountCorruptOCSPData = aCountCorruptOCSPData; + iCountInternalErrorResp = aCountInternalErrorResp; + iCountTryLaterResp = aCountTryLaterResp; + iCountSigValidateFailure = aCountSigValidateFailure; + } + +void CTOCSPEngine::AddCertL(const TDesC8& aSubject, const TDesC8& aIssuer) + { + // Create certificate objects and keep hold of them - these are added + // to the client later + + CX509Certificate* subject = CX509Certificate::NewLC(aSubject); + User::LeaveIfError(iSubjectCerts.Append(subject)); + CleanupStack::Pop(subject); // Now owned through iCerts + + CX509Certificate* issuer = CX509Certificate::NewLC(aIssuer); + User::LeaveIfError(iIssuerCerts.Append(issuer)); + CleanupStack::Pop(issuer); // Now owned through iCerts + + // Add certificates to parameter + iParams->AddCertificateL(*subject, *issuer); + } + +void CTOCSPEngine::ReadTransportLogL() + { + // Read and process the transport filter log (if it exists) + RFile file; + TInt size; + if (file.Open(iFs, KFilterLogFileName, EFileShareAny | EFileRead) != KErrNone) + { + return; + } + + CleanupClosePushL(file); + file.Size(size); + RFileReadStream fileStream(file); + CleanupClosePushL(fileStream); + RBuf8 logBuffer; + logBuffer.CreateL(size); + CleanupClosePushL(logBuffer); + fileStream.ReadL(logBuffer, size); + TInt readPos = 0; + TPtrC8 currentLine; + while (MiscUtil::ReadNonEmptyLineL(logBuffer, readPos, currentLine)) + { + TLex8 lex(currentLine); + TPtrC8 methodName = lex.NextToken(); + + // Validate and store the entry + TTransportLog logEntry; + if (methodName.Length() <= 4) + { + logEntry.iHttpMethod.Copy(methodName); + logEntry.iHttpMethod.UpperCase(); + } + + // Get the timestamps and calculate transaction duration + TInt64 startTime = 0; + TInt64 endTime = 0; + lex.SkipSpaceAndMark(); User::LeaveIfError(lex.Val(startTime)); + lex.SkipSpaceAndMark(); User::LeaveIfError(lex.Val(endTime)); + logEntry.iTransDurationMs = static_cast((endTime - startTime) / KTimeMilliToMicro); + + iTransportLog.AppendL(logEntry); + } + CleanupStack::PopAndDestroy(3, &file); // fileStream, logBuffer + } + +TBool CTOCSPEngine::ReadLineL(const TDesC8& aBuffer, TInt& aPos, TPtrC8& aLine) const + { + TBool endOfBuffer = EFalse; + aLine.Set(NULL, 0); + + TInt bufferLength = aBuffer.Length(); + __ASSERT_ALWAYS(aPos >=0 && aPos <= bufferLength, User::Leave(KErrArgument)); + + // Skip blank lines + while (aPos < bufferLength) + { + TChar c = aBuffer[aPos]; + if (c != '\r' && c != '\n') + { + break; + } + aPos++; + } + + // Find the position of the next delimter + TInt endPos = aPos; + while (endPos < bufferLength) + { + TChar c = aBuffer[endPos]; + if (c == '\n' || c == '\r') + { + break; + } + ++endPos; + } + + if (endPos != aPos) + { + TInt tokenLen = endPos - aPos; + aLine.Set(&aBuffer[aPos], tokenLen); + } + else + { + return ETrue; // End of buffer + } + + aPos = endPos; + return endOfBuffer; + } + +void CTOCSPEngine::LogResponseDetailsL() + { + if (iVerbose) + { + _LIT(KDateFormat, "%F%H:%T %D/%M/%Y"); + TBuf<32> timeString; + + iLog.LogL(_L("Response details:\n")); + + TTime timeNow; + timeNow.UniversalTime(); + timeNow.FormatL(timeString, KDateFormat); + iLog.LogL(_L(" Response generation time == ")); + iLog.LogL(timeString); + iLog.LogL(_L("\n")); + + TBuf<10> indexText; + + for (int i = 0 ; i < iClient->TransactionCount() ; ++i) + { + const COCSPResponse* response = iClient->Response(i); + + iLog.LogL(_L(" Response ")); + indexText.Zero(); + indexText.Num(i); + iLog.LogL(indexText); + iLog.LogL(_L(":\n")); + + if (response) + { + response->ProducedAt().FormatL(timeString, KDateFormat); + iLog.LogL(_L(" producedAt == ")); + iLog.LogL(timeString); + iLog.NewLineL(); + + TInt count = response->CertCount(); + for (TInt index = 0; index < count; ++index) + { + const COCSPResponseCertInfo& certInfo = response->CertInfo(index); + + iLog.LogL(_L(" Cert ")); + indexText.Zero(); + indexText.Num(index); + iLog.LogL(indexText); + iLog.LogL(_L(" Results:")); + + iLog.LogL(_L("\n status == ")); + iLog.LogL(TranslateResultL(certInfo.Status())); + + certInfo.ThisUpdate().FormatL(timeString, KDateFormat); + iLog.LogL(_L("\n thisUpdate == ")); + iLog.LogL(timeString); + iLog.NewLineL(); + + if (certInfo.NextUpdate()) + { + timeString.Zero(); + certInfo.NextUpdate()->FormatL(timeString, KDateFormat); + iLog.LogL(_L(" nextUpdate == ")); + iLog.LogL(timeString); + iLog.NewLineL(); + } + + if (certInfo.RevocationTime()) + { + timeString.Zero(); + certInfo.RevocationTime()->FormatL(timeString, KDateFormat); + iLog.LogL(_L(" revocationTime == ")); + iLog.LogL(timeString); + iLog.NewLineL(); + } + } + } + else + { + iLog.LogL(_L(" missing")); + iLog.NewLineL(); + } + + const TOCSPOutcome& outcome = iClient->Outcome(i); + iLog.LogL(_L(" Validation outcome:")); + iLog.NewLineL(); + iLog.LogL(_L(" status == ")); + iLog.LogL(TranslateStatusL(outcome.iStatus)); + iLog.NewLineL(); + iLog.LogL(_L(" result == ")); + iLog.LogL(TranslateResultL(outcome.iResult)); + iLog.NewLineL(); + } + + iLog.LogL(_L(" OCSP Summary result == ")); + iLog.LogL(TranslateResultL(iClient->SummaryResult())); + iLog.NewLineL(); + } + } + + +void CTOCSPEngine::RunL() + { + TInt err = iStatus.Int(); + if( KErrNotFound != err && KErrNone != err ) + { + iLog.LogL(_L("Client request completed with code:")); + iLog.LogL(err); + iLog.NewLineL(); + User::LeaveIfError(err); + } + + if( KErrNotFound == err ) + { + iLog.LogL(_L("Item not found leave code")); + iLog.NewLineL(); + // Handle error + User::Leave(err); + } + + switch (iState) + { + case EInitCertStore: + // Remove all certificates so we always start from the same state + iCertUtils->RemoveCertsL(*iUnifiedCertStore, iStatus); + iState = ERemovingCerts; + SetActive(); + break; + + case EAddingCert: + case ERemovingCerts: + User::RequestComplete(iOriginalRequestStatus, KErrNone); + break; + + case EChecking: + // Cancel the timer + iTimer->Cancel(); + ReadTransportLogL(); + LogResponseDetailsL(); + User::RequestComplete(iOriginalRequestStatus, KErrNone); + break; + + default: + User::Panic(_L("TOCSP"), 1); + break; + } + } + +TInt CTOCSPEngine::RunError(TInt aError) + { + User::RequestComplete(iOriginalRequestStatus, aError); + return KErrNone; + } + +void CTOCSPEngine::DoCancel() + { + switch (iState) + { + case EInitCertStore: + if (iUnifiedCertStore) + { + iUnifiedCertStore->CancelInitialize(); + } + break; + + case EAddingCert: + case ERemovingCerts: + iCertUtils->Cancel(); + break; + + case EChecking: + iClient->CancelCheck(); + break; + + default: + User::Panic(_L("TOCSP"), 1); + break; + } + + Reset(); + User::RequestComplete(iOriginalRequestStatus, KErrCancel); + } + +// Implementation of MTimerRun +void CTOCSPEngine::TimerRun(TInt /*aError*/) + { + // Cancellation timer expired + this->Cancel(); + } + +void CTOCSPEngine::SetValidationTimeL(const TTime& aWhen) + { + iParams->SetValidationTimeL(aWhen); + } + + +void CTOCSPEngine::SetNonce(const TBool aNonce) + { + iParams->SetUseNonce(aNonce); + } + + +void CTOCSPEngine::SetMaxStatusAgeL(TUint aMaxAge) + { + iParams->SetMaxStatusAgeL(aMaxAge); + } + +void CTOCSPEngine::InitDirectAuthL() + { + // Add OCSP test harness to cert store client list + TName name(_L("TOCSP")); + iCertUtils->AddApplicationL(name, TUid::Uid(KTOCSP_UID)); + } + +void CTOCSPEngine::CleanUpDirectAuthL(TRequestStatus& aStatus) + { + iOriginalRequestStatus = &aStatus; + aStatus = KRequestPending; + + // Should always succeed, as called after InitDirectAuthL + iCertUtils->RemoveApplicationL(TUid::Uid(KTOCSP_UID)); + + //This should remove the X509Certs, which is the only certificate type used by the test. + iCertUtils->RemoveCertsL(*iUnifiedCertStore, iStatus); + iState = ERemovingCerts; + SetActive(); + } + +void CTOCSPEngine::AddDirectAuthorisationCert(const TDesC& aCert, + const TDesC& aLabel, + TRequestStatus& aStatus) + { + TRAPD(err, DoAddDirectAuthorisationCertL(aCert, aLabel, aStatus)); + if (err != KErrNone) + { + Cancel(); + TRequestStatus* status = &aStatus; + User::RequestComplete(status, err); + } + } + +void CTOCSPEngine::DoAddDirectAuthorisationCertL(const TDesC& aCert, + const TDesC& aLabel, + TRequestStatus& aStatus) + { + TPtrC cert = aCert; + HBufC8* certData = ReadDataL(iFs, cert); + CleanupStack::PushL(certData); + + // Make and store the certificate + CX509Certificate* cert2 = CX509Certificate::NewLC(*certData); + User::LeaveIfError(iSigningCerts.Append(cert2)); + CleanupStack::Pop(cert2); // Now owned through iCerts + CleanupStack::PopAndDestroy(certData); + + iUseDirectAuthorisation = ETrue; + + iCert = aCert; + iLabel = aLabel; + + iOriginalRequestStatus = &aStatus; + aStatus = KRequestPending; + iState = EAddingCert; + + iCertUtils->AddCert(iLabel, EX509Certificate, ECACertificate, KTOCSP_UID, + KNullDesC, iCert, *iUnifiedCertStore, iStatus); + SetActive(); + } + + +/** + Called when "AUTHORISATIONCERT AUTHCERTNONE" is parsed. + Sets a flag so an instance of COCSPDirectAuthorisationScheme + is allocated in PrepareAuthorisationSchemeL(). + + This function should be used to test direct authorisation + without supplying a cert. When a cert is supplied, use + AddDirectAuthorisationCert(). + + @see AddDirectAuthorisationCert + @see UseCADelegateAuthorisation + */ +void CTOCSPEngine::UseDirectAuthorisation() + { + iUseDirectAuthorisation = ETrue; + } + +/** + Called when a "CADELEGATE" command is parsed. It sets + a flag so that an instance of COCSPDelegateAuthorisationScheme + is allocated in PrepareAuthorisationSchemeL(). + + @see AddDirectAuthorisationCert + @see UseCADirectAuthorisation + */ +void CTOCSPEngine::UseCADelegateAuthorisation() + { + iUseCADelegateAuthorisation = ETrue; + } + +/** + Called when "CADIRECT" command is parsed. It sets + a flag so that an instance of COCSPCaDirectAuthorisationScheme + is allocated in PrepareAuthorisationSchemeL(). + + @see AddDirectAuthorisationCert + @see UseCADelegateAuthorisation + @see UseDirectAuthorisation +*/ +void CTOCSPEngine::UseCADirectAuthorisation() + { + iUseCADirectAuthorisation = ETrue; + } + +/** + Called when "ALLSCHEMES" command is parsed. It sets + a flag so that all schemes are allocated in + PrepareAuthorisationSchemeL(). + + @see AddDirectAuthorisationCert + @see UseCADelegateAuthorisation + @see UseCADirectAuthorisation +*/ +void CTOCSPEngine::UseAllAuthorisationSchemes() + { + iUseAllSchemes = ETrue; + } + +void CTOCSPEngine::PrepareAuthorisationL() + { + if (iUseAllSchemes) + { + // iUseDirectAuthorisation may also be set because + // "AUTHORISATIONCERT" commands have been parsed. + ASSERT(!(iUseCADelegateAuthorisation || iUseCADirectAuthorisation)); + + // This assumes __SECURITY_PLATSEC_ARCH__ is defined. This + // is the case because AddAllAuthorisationSchemesL() is added + // to 9.1 onwards. + iParams->AddAllAuthorisationSchemesL(TUid::Uid(KTOCSP_UID), *iUnifiedCertStore); + return; + } + + if (iUseDirectAuthorisation) + { + // Register direct authorisation object with OCSP validator + COCSPDirectAuthorisationScheme* scheme = + COCSPDirectAuthorisationScheme::NewLC(TUid::Uid(KTOCSP_UID), *iUnifiedCertStore); + iParams->AddAuthorisationSchemeL(scheme); + CleanupStack::Pop(); // scheme, now owned by client + } + + if (iUseCADelegateAuthorisation) + { + COCSPDelegateAuthorisationScheme* schemeDel = + COCSPDelegateAuthorisationScheme::NewLC(*iUnifiedCertStore); + iParams->AddAuthorisationSchemeL(schemeDel); + CleanupStack::Pop(schemeDel); // scheme, now owned by client + } + + if (iUseCADirectAuthorisation) + { + COCSPCaDirectAuthorisationScheme* schemeCad = + COCSPCaDirectAuthorisationScheme::NewLC(); + iParams->AddAuthorisationSchemeL(schemeCad); + CleanupStack::Pop(schemeCad); // scheme, now owned by client + } + } + +// Set filter parameters +void CTOCSPEngine::DefineAndSetFilterParametersL() + { + TUid categoryUid = TUid::Uid(KFilterParametersCategoryUID); + + // Define the parameters + RProperty::Define(categoryUid, KFilterParameterNumDelayResp, RProperty::EInt); + RProperty::Define(categoryUid, KFilterParameterCountDropResp, RProperty::EInt); + RProperty::Define(categoryUid, KFilterParameterCountCorruptHTTPDataHeader, RProperty::EInt); + RProperty::Define(categoryUid, KFilterParameterCountCorruptHTTPDataBodySizeLarge, RProperty::EInt); + RProperty::Define(categoryUid, KFilterParameterCountCorruptHTTPDataBodySizeSmall, RProperty::EInt); + RProperty::Define(categoryUid, KFilterParameterCountCorruptOCSPData, RProperty::EInt); + RProperty::Define(categoryUid, KFilterParameterCountInternalErrorResp, RProperty::EInt); + RProperty::Define(categoryUid, KFilterParameterCountTryLaterResp, RProperty::EInt); + RProperty::Define(categoryUid, KFilterParameterCountSigValidateFailure, RProperty::EInt); + + // and Set them + User::LeaveIfError(RProperty::Set(categoryUid, KFilterParameterNumDelayResp, iNumDelayResp)); + User::LeaveIfError(RProperty::Set(categoryUid, KFilterParameterCountDropResp, iCountDropResp)); + User::LeaveIfError(RProperty::Set(categoryUid, KFilterParameterCountCorruptHTTPDataHeader, iCountCorruptHTTPDataHeader)); + User::LeaveIfError(RProperty::Set(categoryUid, KFilterParameterCountCorruptHTTPDataBodySizeLarge, iCountCorruptHTTPDataBodySizeLarge)); + User::LeaveIfError(RProperty::Set(categoryUid, KFilterParameterCountCorruptHTTPDataBodySizeSmall, iCountCorruptHTTPDataBodySizeSmall)); + User::LeaveIfError(RProperty::Set(categoryUid, KFilterParameterCountCorruptOCSPData, iCountCorruptOCSPData)); + User::LeaveIfError(RProperty::Set(categoryUid, KFilterParameterCountInternalErrorResp, iCountInternalErrorResp)); + User::LeaveIfError(RProperty::Set(categoryUid, KFilterParameterCountTryLaterResp, iCountTryLaterResp)); + User::LeaveIfError(RProperty::Set(categoryUid, KFilterParameterCountSigValidateFailure, iCountSigValidateFailure)); + } + +void CTOCSPEngine::DeleteFilterParameters() + { + TUid categoryUid = TUid::Uid(KFilterParametersCategoryUID); + RProperty::Delete(categoryUid, KFilterParameterNumDelayResp); + RProperty::Delete(categoryUid, KFilterParameterCountDropResp); + RProperty::Delete(categoryUid, KFilterParameterCountCorruptHTTPDataHeader); + RProperty::Delete(categoryUid, KFilterParameterCountCorruptHTTPDataBodySizeLarge); + RProperty::Delete(categoryUid, KFilterParameterCountCorruptHTTPDataBodySizeSmall); + RProperty::Delete(categoryUid, KFilterParameterCountCorruptOCSPData); + RProperty::Delete(categoryUid, KFilterParameterCountInternalErrorResp); + RProperty::Delete(categoryUid, KFilterParameterCountTryLaterResp); + RProperty::Delete(categoryUid, KFilterParameterCountSigValidateFailure); + // Reset the params + iNumDelayResp = iCountDropResp = iCountCorruptHTTPDataHeader = iCountCorruptHTTPDataBodySizeLarge = + iCountCorruptHTTPDataBodySizeSmall = iCountCorruptOCSPData = iCountInternalErrorResp = + iCountTryLaterResp = iCountSigValidateFailure = 0; + } + +void CTOCSPEngine::SetCancelTime(TInt aTime) + { + iCancelTime = aTime; + } + +void CTOCSPEngine::Check(TRequestStatus& aStatus) + { + TRAPD(err, DoCheckL(aStatus)); + if (err != KErrNone) + { + Cancel(); + TRequestStatus* status = &aStatus; + User::RequestComplete(status, err); + } + } + +void CTOCSPEngine::DoCheckL(TRequestStatus& aStatus) + { + iOriginalRequestStatus = &aStatus; + aStatus = KRequestPending; + iState = EChecking; + + PrepareAuthorisationL(); + + // Set filter parameters + DefineAndSetFilterParametersL(); + + if (iVerbose) + { + iLog.LogL(_L("Checking...\n"), ETrue); + } + + iClient = COCSPClient::NewL(iParams); + iParams = NULL; // Client takes ownership + + // Setup cancellation timer + if (iCancelTime) + { + iTimer->After(iCancelTime * KTimeMilliToMicro); + } + iClient->Check(iStatus); + SetActive(); + } + +void CTOCSPEngine::LogValidationL(const TOCSPOutcome& aOutcome) const + { + if (iVerbose) + { + iLog.LogL(_L("Validation complete:\n status == ")); + iLog.LogL(TranslateStatusL(aOutcome.iStatus)); + + // Output summary result + iLog.LogL(_L("\n summary result == ")); + iLog.LogL(TranslateResultL(aOutcome.iResult)); + iLog.NewLineL(); + } + } + + +TPtrC CTOCSPEngine::TranslateStatusL(OCSP::TStatus aStatus) + { + switch ((TInt) aStatus) + { + case OCSP::ETransportError: + return _L("Transport error"); + case OCSP::ETimeOut: + return _L("Request timedout"); + case OCSP::EClientInternalError: + return _L("Client internal error"); + case OCSP::ENoServerSpecified: + return _L("No server specified"); + case OCSP::EInvalidURI: + return _L("Invalid URI"); + case OCSP::EMalformedResponse: + return _L("Malformed response"); + case OCSP::EUnknownResponseType: + return _L("Unknown response type"); + case OCSP::EUnknownCriticalExtension: + return _L("Unknown critical extension"); + case OCSP::EMalformedRequest: + return _L("Server: Malformed request"); + case OCSP::EServerInternalError: + return _L("Server: Internal error"); + case OCSP::ETryLater: + return _L("Server: Try later"); + case OCSP::ESignatureRequired: + return _L("Server: Signature required"); + case OCSP::EClientUnauthorised: + return _L("Server: Client unauthorised"); + case OCSP::EMissingCertificates: + return _L("Missing certificates"); + case OCSP::EResponseSignatureValidationFailure: + return _L("Response signature validation failure"); + case OCSP::EThisUpdateTooLate: + return _L("Time error: This update too late"); + case OCSP::EThisUpdateTooEarly: + return _L("Time error: This update too early"); + case OCSP::ENextUpdateTooEarly: + return _L("Time error: Next update too early"); + case OCSP::ECertificateNotValidAtValidationTime: + return _L("Time error: Not valid at validation time"); + case OCSP::ENonceMismatch: + return _L("Nonce mismatch"); + case OCSP::EMissingNonce: + return _L("Missing nonce"); + case OCSP::EValid: + return _L("Valid"); + case TOCSP::ETooManyTransactions: + return _L("(test) Too many transactions"); + case TOCSP::EURIMismatch: + return _L("(test) URI mismatch"); + case TOCSP::ERequestMismatch: + return _L("(test) Request mismatch"); + default: + return _L("Unknown"); + } + } + + +TPtrC CTOCSPEngine::TranslateResultL(OCSP::TResult aResult) + { + switch (aResult) + { + case OCSP::EGood: + return _L("Good"); + case OCSP::ERevoked: + return _L("Revoked"); + case OCSP::EUnknown: + return _L("Unknown"); + default: + return _L("Unknown"); + } + } + + +HBufC8* CTOCSPEngine::ReadDataL(RFs& session, const TDesC& aFileName) const + { + RFile file; + User::LeaveIfError(file.Open(session, aFileName, EFileRead | EFileShareReadersOnly)); + CleanupClosePushL(file); + + TInt size = 0; + User::LeaveIfError(file.Size(size)); + + HBufC8* data = HBufC8::NewLC(size); + TPtr8 dataPtr = data->Des(); + User::LeaveIfError(file.Read(dataPtr)); + + CleanupStack::Pop(data); + CleanupStack::PopAndDestroy(); // Close file; + + return data; + } + + +void CTOCSPEngine::LogRequestL(const TDesC& aFilename) + { + delete iRequestLog; + iRequestLog = NULL; + + iRequestLog = aFilename.AllocL(); + } + + +void CTOCSPEngine::LogResponseL(const TDesC& aFilename) + { + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + + TInt err = fs.MkDirAll(aFilename); + if (err != KErrAlreadyExists) + { + User::LeaveIfError(err); + } + + RFile file; + User::LeaveIfError(file.Replace(fs, aFilename, EFileWrite)); + CleanupClosePushL(file); + + RFileWriteStream writeStream(file); + CleanupClosePushL(writeStream); + + writeStream.WriteUint32L(iClient->TransactionCount()); + + for (int i = 0 ; i < iClient->TransactionCount() ; ++i) + { + const COCSPResponse* response = iClient->Response(i); + if (response) + { + const TPtrC8 data = response->Encoding(); + writeStream.WriteUint32L(data.Length()); + writeStream.WriteL(data); + } + else + { + writeStream.WriteUint32L(0); + } + } + + CleanupStack::PopAndDestroy(3); // writeStream, file, fs + } + + +void CTOCSPEngine::SetVerbose(TBool aVerbose) + { + iVerbose = aVerbose; + } + +TBool CTOCSPEngine::TestSummaryL(OCSP::TResult aExpected) + { + TBool result = iClient->SummaryResult() == aExpected; + + if (iVerbose && !result) + { + iLog.LogL(_L("Summary result fail: expected ")); + iLog.LogL(aExpected); + iLog.NewLineL(); + } + + return result; + } + +TBool CTOCSPEngine::TestOutcomeL(TInt aIndex, const TOCSPOutcome& aExpected) + { + TBool result = EFalse; + // This assumes one-transaction-per-certificate behaviour + if(iClient) + { + result = iClient->Outcome(aIndex) == aExpected; + } + + if (iVerbose && !result) + { + iLog.LogL(_L("Outcome result fail for cert ")); + iLog.LogL(aIndex); + iLog.LogL(_L(":\n")); + //iLog.LogL(_L("Expected Result:\n")); + iLog.LogL(_L("Expected Status == ")); + iLog.LogL(TranslateStatusL(aExpected.iStatus)); + iLog.NewLineL(); + iLog.LogL(_L("Expected Result == ")); + iLog.LogL(TranslateResultL(aExpected.iResult)); + iLog.NewLineL(); + } + + return result; + } + +void CTOCSPEngine::SetReponderCertCheck() + { + iParams->SetOCSPCheckForResponderCert(ETrue); + } + +void CTOCSPEngine::AddCertToStore(const TDesC& aCertFileName, const TDesC& aLabel, TCertificateOwnerType aCertType, TRequestStatus& aStatus) + { + iOriginalRequestStatus = &aStatus; + aStatus = KRequestPending; + iState = EAddingCert; + + iCert = aCertFileName; + iLabel = aLabel; + + iCertUtils->AddCert(iLabel, EX509Certificate, aCertType, KTOCSP_UID, + KNullDesC, iCert, *iUnifiedCertStore, iStatus); + + SetActive(); + } + +TBool CTOCSPEngine::TestTransportL(TInt aRetryCountNum, const TDesC& aExpectedHttpMethod, + TInt aExpectedRespTimeMin, TInt aExpectedRespTimeMax) + { + // This assumes one-tranaction-per-certificate behaviour + // This also assumes test case includes only certificate revocation check request (which + // means CHECKRESPONDERCERT command cannot be used with this) + // Ensure we have read the entry from the transport log + TBool result = ETrue; + if (iTransportLog.Count() < (aRetryCountNum + 1)) + { + if (iVerbose) + { + iLog.LogL(_L("Transport filter log contains insufficient entries: ")); + iLog.LogL(_L("\n Expected number of entries: ")); + iLog.LogL(aRetryCountNum + 1); + iLog.LogL(_L("\n Actual entries: ")); + iLog.LogL(iTransportLog.Count()); + iLog.NewLineL(); + } + result = EFalse; + } + + TTransportLog& logEntry = iTransportLog[aRetryCountNum]; + // Convert to 8-bit + RBuf8 expectedMethod; + expectedMethod.CreateL(aExpectedHttpMethod.Length()); + CleanupClosePushL(expectedMethod); + expectedMethod.Copy(aExpectedHttpMethod); + expectedMethod.UpperCase(); + if (expectedMethod != logEntry.iHttpMethod) + { + if (iVerbose) + { + iLog.LogL(_L("Transport outcome result failed for send number: ")); + iLog.LogL(aRetryCountNum); + iLog.LogL(_L("\n Expected method: ")); + iLog.LogL(expectedMethod); + iLog.LogL(_L("\n Got method: ")); + iLog.LogL(logEntry.iHttpMethod); + iLog.NewLineL(); + } + result = EFalse; + } + CleanupStack::PopAndDestroy(&expectedMethod); + + // Test the range of response time + if (aExpectedRespTimeMin > logEntry.iTransDurationMs || aExpectedRespTimeMax < logEntry.iTransDurationMs) + { + if (iVerbose) + { + iLog.LogL(_L("Transport outcome result failed for send number: ")); + iLog.LogL(aRetryCountNum); + iLog.LogL(_L("\n Expected response time range (ms): ")); + iLog.LogL(aExpectedRespTimeMin); + iLog.LogL(_L(" to ")); + iLog.LogL(aExpectedRespTimeMax); + iLog.LogL(_L("\n Actual response time (ms): ")); + iLog.LogL(logEntry.iTransDurationMs); + iLog.NewLineL(); + } + result = EFalse; + } + else if (iVerbose) + { + iLog.LogL(_L("Send number: ")); + iLog.LogL(aRetryCountNum); + iLog.LogL(_L(" Response duration(ms): ")); + iLog.LogL(logEntry.iTransDurationMs); + iLog.NewLineL(); + } + + return result; + } + +TBool CTOCSPEngine::TestTransportRetryL(TInt aRetryCount) + { + // This assumes one-tranaction-per-certificate behaviour + // This also assumes test case includes only certificate revocation check request (which means + // CHECKRESPONDERCERT command cannot be used with this) + // Check the number of retries + TBool result = ETrue; + if (iTransportLog.Count() != aRetryCount) + { + if (iVerbose) + { + iLog.LogL(_L("Transport retry outcome result failed:")); + iLog.LogL(_L("\n Expected number of retries: ")); + iLog.LogL(aRetryCount); + iLog.LogL(_L("\n Actual retries: ")); + iLog.LogL(iTransportLog.Count()); + iLog.NewLineL(); + } + result = EFalse; + } + + return result; + } + +void CTOCSPEngine::SetCheckCertsWithAiaOnly(TBool aCheckCertsWithAiaOnly) + { + iParams->SetCheckCertsWithAiaOnly(aCheckCertsWithAiaOnly); + } + +void CTOCSPEngine::SetUseAIA(TBool aUseAIA) + { + iParams->SetUseAIA(aUseAIA); + }