--- /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 <miscutil.h>
+
+#include <ocsp.h>
+#include <x509cert.h>
+
+#include <ocsptransport.h>
+
+#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<TInt64>((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);
+ }