pkiutilities/ocsp/inc/ocsprequestandresponse.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 26 Jan 2010 15:20:08 +0200
changeset 0 164170e6151a
permissions -rw-r--r--
Revision: 201004

// 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:
// ocsp.h
// Header specifying client interface to the OCSP module.
// 
//

#ifndef OCSPREQUESTANDRESPONSE_H
#define OCSPREQUESTANDRESPONSE_H

/**
 * @file
 * @internalTechnology
 */

#include <e32base.h>
#include <signed.h>
#include <f32file.h>
#include <hash.h>
#include <x500dn.h>
#include <x509cert.h>
#include <ct/rmpointerarray.h>
#include <cctcertinfo.h>
#include <asn1enc.h>
#include <asn1dec.h>

#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
#include "ocsp.h"
#endif

#define KOCSPNonceBytes 16

// Default values for transport parameters
const TUint KTransportDefaultRequestRetryCount 	= 1;	// No retry
const TInt KTransportDefaultRequestTimeout 		= -1;	// Timeout disabled

class COCSPRequestCertInfo;
class COCSPResponseCertInfo;
class COCSPCertID;
class MOCSPTransport;
class COCSPResponse;
class COCSPTransportHandler;
class MOCSPAuthorisationScheme;
class COCSPTransaction;
class COCSPValidator;
class COCSPRequestCertInfo;
class COCSPResponseDecoder;

class CASN1EncBase;
class CASN1EncContainer;
class TASN1DecGeneric;

class CX509Certificate;
class CX509CertChain;
class CPKIXCertChainBase;
class COCSPParameters;


/**
 * Represents an OCSP protocol request.
 */

class COCSPRequest : public CBase
	{
public:

	/**
	 * Get the nonce used in the request.  Returns NULL if a nonce was not used.
	 */

	IMPORT_C const TDesC8* Nonce() const;

	/**
	 * Get the number of certificates used in a response
	 */
	
	IMPORT_C TInt CertCount() const;

	/**
	 * Get a COCSPRequestCertInfo object containing details about one of the
	 * certificates present in the request.
	 */

	IMPORT_C const COCSPRequestCertInfo& CertInfo(TUint aIndex) const;
	
public:

	// Not exported
	static COCSPRequest* NewLC(TBool aUseNonce);
	static COCSPRequest* NewL(TBool aUseNonce);
	
	~COCSPRequest();
	void AddCertificateL(const CX509Certificate& aSubject,
						 const CX509Certificate& aIssuer);

private:

	COCSPRequest();
	void ConstructL(TBool aUseNonce);

	HBufC8* iNonce;
	RPointerArray<const COCSPRequestCertInfo> iCertInfos;
	};

/**
 * Information about a certificate sent as part of an OCSP request.
 */

class COCSPRequestCertInfo : public CBase
	{
public:

	/**
	 * Get the certificate present in the request.
	 */
	
	IMPORT_C const CX509Certificate& Subject() const;

	/**
	 * Get the issuer of the certificate present in the request.
	 */
	
	IMPORT_C const CX509Certificate& Issuer() const;

public:

	// Not exported
	static COCSPRequestCertInfo* NewLC(
		const CX509Certificate& aSubject,
		const CX509Certificate& aIssuer);

	~COCSPRequestCertInfo();

	const COCSPCertID& CertID() const;

 private:
	
	COCSPRequestCertInfo(const CX509Certificate& aIssuer,
						 const CX509Certificate& aSubject);
	void ConstructL();

private:

	const CX509Certificate& iSubject;
	const CX509Certificate& iIssuer;
	COCSPCertID* iCertID;
	};


/**
 * Represents an OCSP protocol response.
 */

class COCSPResponse : public CSignedObject
	{
public:

	/**
	 * Get the number of certificates statuses present in the response.
	 */

	IMPORT_C TInt CertCount() const;

	/**
	 * Get a COCSPResponseCertInfo object containing details about one of the
	 * certificate statuses present in the response.
	 */

	IMPORT_C const COCSPResponseCertInfo& CertInfo(TUint aIndex) const;

	/**
	 * Get the producedAt time for the response.
	 */

	IMPORT_C TTime ProducedAt() const;

	/**
	 * Get the archiveCutoff time for the response, or NULL if it was not present.
	 */

	IMPORT_C const TTime* ArchiveCutoff() const;

public:

	// This class is created and initialised by the response decoder
	friend class COCSPResponseDecoder;
	
	~COCSPResponse();

	/**
	 * Get the index for the given cert, or KErrNotFound.
	 */
	
	TInt Find(const COCSPCertID& aCertID) const;

	// Enums to use in DataElementEncoding
	enum
		{
		ECertificateChain,
		ENonce,
		EResponderIDName,    // Only one of the ResponderIDs won't be NULL
		EResponderIDKeyHash
		};

  	// From CSignedObject
  	const TPtrC8* DataElementEncoding(const TUint aIndex) const;

private:

	COCSPResponse();

  	// From CSignedObject
	const TPtrC8 SignedDataL() const;
	void InternalizeL(RReadStream& aStream);

private:

	// Time of response, and of archiveCutoff extension (if present)
	TTime iProducedAt;
	TTime* iArchiveCutoff;

	// Value of nonce in response extension (if present)
	TPtrC8 iNonce;

	// Point to the signing certificates in the response
	TPtrC8 iSigningCerts;

	// Point to the signed portion of the data
	TPtrC8 iSignedData;

	// There are two ways the responder ID can be specified - only
	// one of these will be used
	TPtrC8 iResponderIDName;
	TPtrC8 iResponderIDKeyHash;

	RPointerArray<COCSPResponseCertInfo> iCertInfos;
	};


/**
 * Information about a certificate status, as given in OCSP response
 * singleResponse data item.
 */

class COCSPResponseCertInfo : public CBase
	{
public:
	
	IMPORT_C OCSP::TResult Status() const;
	IMPORT_C TTime ThisUpdate() const;
	IMPORT_C const TTime* NextUpdate() const;     // NULL if nextUpdate not set
	IMPORT_C const TTime* RevocationTime() const; // NULL if not revoked

public:
	
	static COCSPResponseCertInfo* NewLC(CArrayPtr<TASN1DecGeneric>& aItems);
	~COCSPResponseCertInfo();
	COCSPCertID& CertID() const;
	
private:
	void ConstructL(CArrayPtr<TASN1DecGeneric>& aItems);

private:
	OCSP::TResult iStatus;

	TTime iThisUpdate;
	TTime* iNextUpdate;
	TTime* iRevocationTime;

	COCSPCertID* iCertID;
	};

/**
	Utility class contains functions common to all validation
	schemes.
 */
namespace OCSPUtils
	{
	TBool IsAIAForOCSPPresentL(const CX509Certificate& aCert);
	
	TBool DoesResponderIdMatchCertL( const COCSPResponse& aResponse, 
											const CX509Certificate& aResponderCert);
	TBool DoesDNNameMatchL( 	const COCSPResponse& aResponse, const CX509Certificate& aCert);
	TBool DoesIssuerKeyMatchL(const COCSPResponse& aResponse, const CX509Certificate& aCert);
	TBool IsResponseSignedByCertL( COCSPResponse* aResponse, const CX509Certificate& aCert);
	TBool DoesCertHaveOCSPNoCheckExt( const CX509Certificate& aCert);
	TDesC8* ServerUriL(	const CX509Certificate& aCert, const COCSPParameters* aParameters );
	TBool IsUriAvailableL( const CX509Certificate& aCert, const COCSPParameters* aParameters );
	TDesC8* GetAIAL(const CX509Certificate& aCert);
	TBool DoesCertHaveOCSPSigningExtL(const CX509Certificate& aCert);
	CX509Certificate* GetResponderCertLC(const TDesC8& aEncodedCerts);
	}

// Base class interface for authorisation schemes, for plugging into the validator object
class MOCSPAuthorisationScheme
	{
public:
	virtual ~MOCSPAuthorisationScheme() {};

	virtual void ValidateL(
		OCSP::TStatus& aOCSPStatus, COCSPResponse& aResponse,
		const TTime aValidationTime, TRequestStatus& aStatus,
		const COCSPRequest& aRequest) = 0;

	virtual void CancelValidate() = 0;
	// Returns the responder certificate. This method shall return valid responder
	// certificate for delegate and direct schemes, for the cadirect scheme although
	// the CA cert is the response cert but it returns NULL as the need for retrieving
	// this certificate is to further send it for OCSP checking, this logic is only valid 
	// for delegate and direct schemes.
	virtual const CX509Certificate* ResponderCert() const = 0;
	};


class CPKIXValidationResultBase;
class CCertAttributeFilter;
class MCertStore;

class COCSPDelegateAuthorisationScheme : public CActive, public MOCSPAuthorisationScheme
/**
	Implement part of S2.2.2 of RFC 2560.
	
	"a CA Designated Responder (Authorized Responder) who holds
	a specially marked certificate issued directly by the CA,
	indicating that the responder may issue OCSP responses for
	that CA."
*/
	{
public:
	IMPORT_C static COCSPDelegateAuthorisationScheme* NewLC(MCertStore& aCertStore);
	virtual ~COCSPDelegateAuthorisationScheme();
	
	virtual void ValidateL(
		OCSP::TStatus& aOCSPStatus, COCSPResponse& aResponse,
		const TTime aValidationTime, TRequestStatus& aStatus,
		const COCSPRequest& aRequest);
	
	virtual void CancelValidate();
	const CX509Certificate* ResponderCert() const;
	
protected:
	virtual void RunL();
	virtual void DoCancel();
	TInt RunError(TInt aError);
	
private:
	COCSPDelegateAuthorisationScheme(MCertStore& aCertStore);
	void ConstructL();
	
	void ValidateDelegateCertL(const TDesC8& aResponseCertChain, const TTime aValidationTime);
	void OnChainValidationL();
	
	// searches on the basis of the issuer's subject name
	void ValidateFromRootsL();
	
	void OnRetrieveNextL();
	void OnRetrievingEntryL();
	
private:

	enum TDelegateAuthState
	{
	EOnChainValidation,
	ERetrieveNext,
	ERetrievingEntry,
	};
	/**
		This is a required argument for CPKIXCertChainBase, even
		though no certificates are used from the store.
	 */
	MCertStore& iCertStore;
	/**
		Pointer to client's OSCP status.  This object sets the
		status according to the result of the validation.  If
		the validation cannot be carried out, the default value
		is OCSP::EResponseSignatureValidationFailure.
	 */
	OCSP::TStatus* iOCSPStatus;
	/**
		Pointer to client's request status.  This is recorded
		on the call to Validate() and used to notify the client
		of completion later.
	 */
	TRequestStatus* iClientStatus;
	/**
		Array used to hold pointer to issuer cert.  This contains
		the pointer to the CA.
	 */
	RPointerArray<CX509Certificate> iRespSignIntCert;
	/**
		This object is used to chain the response signer back
		to the CA.
	 */
	CPKIXCertChainBase* iRespSignCertChainBase;
	/**
		The cert chain stores the validation result in
		this object.
		
		@see iRespSignCertChain;
	 */
	CPKIXValidationResultBase* iPKIXResultBase;
	/**
		Response from OCSP server.  Once it has been established
		that the certificate sent with the response is an authorised
		responder for the CA, the response is checked to ensure
		that it really is signed by that certificate.
		
		This is not const because, if DSA is used, then
		SetParametersL() will be called on the response before
		the signature is verified.
	 */
	COCSPResponse* iResponse;
	const COCSPRequest* iRequest;
	CCertAttributeFilter* iCertFilter;
	RMPointerArray<CCTCertInfo> iCertStoreEntries;
	TDelegateAuthState	iState;
	HBufC8* iEncodedCert;
	const CX509Certificate* iResponseCert;
	TInt iCertCount;
	TTime iValidationTime;
	TBool iValidateFromResponse;
	
	};

class COCSPCaDirectAuthorisationScheme : public CBase, public MOCSPAuthorisationScheme
/**
	Implement part of S2.2 of RFC 2560.
	
	"The key used to sign the response MUST belong to one of the following...

	-- the CA who issued the certificate in question"
*/
	{
public:
	IMPORT_C static COCSPCaDirectAuthorisationScheme* NewLC();
	const CX509Certificate* ResponderCert() const;
	
private:
	virtual void ValidateL(
		OCSP::TStatus& aOCSPStatus, COCSPResponse& aResponse,
		const TTime aValidationTime, TRequestStatus& aStatus,
		const COCSPRequest& aRequest);
	virtual void CancelValidate();

	TBool DoValidateL(
		const COCSPRequest& aRequest, COCSPResponse& aResponse);
	TBool CertChainMatchesCertL(
		const TDesC8& aCertChainData, const CX509Certificate& aCert);
	};

// Authorisation scheme taking a cert store UID, and allowing those cert chains
// with a root cert in the cert store valid for that UID
	
	/**
	Implement part of S2.2 of RFC 2560.
	
	"The key used to sign the response MUST belong to one of the following...

	-- a Trusted Responder whose public key is trusted by the requester"
*/
class COCSPDirectAuthorisationScheme : public CActive, public MOCSPAuthorisationScheme
	{
public:
	IMPORT_C static COCSPDirectAuthorisationScheme* NewLC(const TUid& aCertStoreUid, MCertStore& aCertStore);

	~COCSPDirectAuthorisationScheme();

	// From MOCSPAuthorisationScheme
	void ValidateL(OCSP::TStatus& aOCSPStatus, COCSPResponse& aResponse, 
		const TTime aValidationTime, TRequestStatus& aStatus,
		const COCSPRequest& aRequest);
	void CancelValidate();
	
	const CX509Certificate* ResponderCert() const;
	
protected:
	virtual void DoCancel();
	virtual void RunL();
	virtual TInt RunError(TInt aError);
	
private:
	void ConstructL();
	
	COCSPDirectAuthorisationScheme(const TUid& aCertStoreUid, MCertStore& aCertStore);

	TBool ValidateSignatureL();
	void ValidateFromRoots();
	void ValidateCertChainL(); 
	void StartValidateL();
	void OnValidateCertChainL();
	void OnListCertEntries();
	void OnRetrieveNextL();
	void OnRetrievingEntryL();

private:
	TUid iCertStoreUid;

	COCSPResponse* iResponse;

	CPKIXCertChainBase* iCertChain;

	TRequestStatus* iClientStatus;
	CPKIXValidationResultBase* iPKIXResult;
	OCSP::TStatus* iOCSPStatus;

	enum TStatus
		{
		EValidateCertChain, // waiting for cert chain validation to complete
		EListCertEntries,   // waiting listing to complete
		ERetrieveNext,      // get next cert entry
		ERetrievingEntry,   // waiting for entry retrieval to complete
		};
	TStatus iState;

	MCertStore& iCertStore;
	
	CCertAttributeFilter* iCertFilter;
	RMPointerArray<CCTCertInfo> iCertStoreEntries;
	HBufC8* iEncodedCertBuf;
	TPtr8* iEncodedCertPtr;

	RFs iFs;
	TInt iCurEntry; // while async processing 509 certs, points to the current one

	TTime iValidationTime;
	const COCSPRequest* iRequest;
	const CX509Certificate* iResponseCert;
	};


/**
 * Interface through which the OCSP module sends requests to the outside world.
 * Normally, the appropriate concrete objects are made automatically, depending
 * on the URI, and so clients don't have to deal with this.  However, clients
 * can override the automatically created object by specifying their own
 * transport object instead.
 */

class MOCSPTransport
	{
public:

	virtual ~MOCSPTransport() {};

	/**
	 * Send request data to a URI. This is an asynchronous method.
	 * @param aURI			Target URI for sending the request
	 * @param aRequest		Request packet
	 * @param aTimeout		Request timeout in milliseconds (ignored if feature not supported)
	 * @param aStatus		The request status object. On request completion, indicates the status
	 */
	virtual void SendRequest(const TDesC8& aURI,
							 const TDesC8& aRequest,
							 const TInt aTimeout,
							 TRequestStatus& aStatus) = 0;

	/**
	 * Cancel the request.
	 */
	
	virtual void CancelRequest() = 0;

	// The following methods will only be called after the aStatus above is completed

	/**
	 * Get the response data.  Panic if completion gave an error.
	 */
	
	virtual TPtrC8 GetResponse() const = 0;	
	};


/**
 * Specifies paremeters needed to perform revocation checking.  The important
 * things to set are the certificates to be checked all - all the other
 * parameters have defaults.
 */

class COCSPParameters : public CBase
	{
public:
	
	/**
	 * Create a new parameters object.
	 */

	IMPORT_C static COCSPParameters* NewL();
	IMPORT_C static COCSPParameters* NewLC();
	
	/**
	 * Add a certificate chain to be checked.  Does not take ownership -
	 * certificates must not be destroyed until the OCSP check complete.
	 */

	IMPORT_C void AddCertificatesL(const CX509CertChain& aChain);

	/**
	 * Add a certificate to be checked.  Does not take ownership - certificates
	 * must not be destroyed until the OCSP check complete.
	 */

	IMPORT_C void AddCertificateL(const CX509Certificate& aSubject, const CX509Certificate& aIssuer);

	/**
	 * Set whether or not to use a nonce.  By default this is turned on.
	 */

	IMPORT_C void SetUseNonce(TBool aUseNonce);

	/**
	 * Set the URI of the OCSP responder to use.  The descriptor is copied.
	 *
	 * @param aURI The URI of the responder to use.
	 * @param aUseAIA Indicates whether to use the responder specified in
	 * certifcate AuthorityInfoAccess extensions in preference to the one given
	 * here.
	 */

	IMPORT_C void SetURIL(const TDesC8& aURI, TBool aUseAIA);

	/**
	 * Set the transport to use.  This method must be called - if no transport
	 * is set COCSPClient::NewL will leave with KErrArgument.  This object takes
	 * ownership.
	 */

	IMPORT_C void SetTransport(MOCSPTransport* aTransport);

	/**
	 * Set the retry count for failed send request attempts.
	 * A default value of 1 (no retry) is used.
	 * 
	 * @param aRetryCount		Retry count
	 */
	IMPORT_C void SetRetryCount(const TUint aRetryCount);

	/**
	 * Set the request timeout.
	 * A default value of -1 (default transport timeout) is used.
	 * 
	 * @param aTimeout			Request timeout in milliseconds
	 */
	IMPORT_C void SetTimeout(const TInt aTimeout);

	/**
	 * Add an authorisation scheme - takes ownership if it doesn't leave.
	 * Clients must specify at least one such scheme, used to validate the signature
	 * on the response.
	 */

	IMPORT_C void AddAuthorisationSchemeL(MOCSPAuthorisationScheme* aScheme);

	IMPORT_C void AddAllAuthorisationSchemesL(const TUid& aCertStoreUid, MCertStore& aCertStore);

	/**
	 * Specify the authorisation time (optional - uses producedAt time from response otherwise).
	 */

	IMPORT_C void SetValidationTimeL(const TTime& aValidationTime);

	/**
	 * Specify the maximum age of the thisUpdate field in seconds (zero => don't check).
	 */

	IMPORT_C void SetMaxStatusAgeL(TUint aMaxAge);

	/**
	 * Specify how much leeway we allow when comparing times.
	 */

	IMPORT_C void SetTimeLeewayL(TUint aLeewaySeconds);
	
	IMPORT_C void SetOCSPCheckForResponderCert(const TBool aResponderCertCheck);
	
	IMPORT_C void SetCheckCertsWithAiaOnly(const TBool aCheckCertsWithAiaOnly);
	
	IMPORT_C void SetUseAIA(const TBool aUseAIA);
	
public:
	
	// Not exported

	~COCSPParameters();
	TUint CertCount() const;
	const CX509Certificate& SubjectCert(TUint aIndex) const;
	const CX509Certificate& IssuerCert(TUint aIndex) const;
	TBool UseNonce() const;
	const TDesC8& DefaultURI() const;
	TBool UseAIA() const;
	MOCSPTransport* Transport() const;
	TUint AuthSchemeCount() const;
	MOCSPAuthorisationScheme& AuthScheme(TUint aIndex) const;
	const TTime* ValidationTime() const;
	const TUint* MaxStatusAge() const;
	const TUint* TimeLeeway() const;
	TBool GenerateResponseForMissingUri() const;

	TUint RetryCount() const;
	TInt Timeout() const;
	TBool ReponderCertCheck() const;
	const CX509Certificate& CACert(TUint aIndex) const;
	TBool CheckCertsWithAiaOnly() const;
	
private:
	void ConstructL();
	COCSPParameters();
	
#ifdef _DEBUG
	/** Panic codes used by this functions in this class. */
	enum TPanic
	{
		/** AddAllAuthorisationSchemesL() called when already added at least one. */
		EAAASAlreadyHaveSchemes = 0x10
	};
	static void Panic(TPanic aPanic);
#endif
private:

	RPointerArray<CX509Certificate>			iSubjectCerts;
	RPointerArray<CX509Certificate>			iIssuerCerts;	
	TBool									iUseNonce;
	HBufC8*									iDefaultURI;
	MOCSPTransport*							iTransport;
	TBool									iUseAIA;
	RPointerArray<MOCSPAuthorisationScheme> iAuthSchemes;
	TTime*									iValidationTime;
	TUint*									iMaxStatusAge;
	TUint*									iTimeLeeway;
	TBool									iGenerateResponseForMissingUri;
	
	TBool									iResponderCertCheck;
	TUint									iRetryCount;
	TInt									iTimeout;
	TBool									iCheckCertsWithAiaOnly;
	};


/**
 * Checks the revocation state of one or more certificates.
 *
 * The current implementation makes one OCSP request for every certificate
 * checked - future impelementations may check multiple certificates with a
 * single request.
 */

class COCSPClient : public CActive
	{
public:

	/**
	 * Create a new OCSP client.
	 * 
	 * @param aParams An object describing the parameters for the check.  This
	 * method takes ownership if it does not leave.
	 */

	IMPORT_C static COCSPClient* NewL(const COCSPParameters* aParams);
	
	~COCSPClient();

	/**
	 * Start the checker - this is an asynchronous method.
	 */

	IMPORT_C void Check(TRequestStatus& aStatus);

	/**
	 * Cancel checking.
	 */

	IMPORT_C void CancelCheck(void);

	/**
	 * Get the summary result of the check.  If any certificates were revoked,
	 * this returns ERevoked.  If no certificates were revoked, but if there
	 * were any errors communicating with ocsp servers or any certs had unknown
	 * status, this returns EUnknown.  Otherwise it returns EGood. 
	 * Panics if the check has not been run, or is not complete.
	 */

	IMPORT_C OCSP::TResult SummaryResult(void) const;

	/**
	 * Get the number of transactions made.
	 * Panics if the check has not been run, or is not complete.
	 */

	IMPORT_C TInt TransactionCount(void) const;

	/** 
	 * Get the request object for a specified transaction.
	 * Panics if the check has not been run, is not complete, or the index is invalid.
	 */

	IMPORT_C const COCSPRequest& Request(TInt aIndex) const;

	/**
	 * Get the outcome for an individual transaction.
	 */

	IMPORT_C const TOCSPOutcome& Outcome(TInt aIndex) const;

	/** 
	 * Get the response object for a specified transaction.  If there was an
	 * error sending the request, this may return NULL for the corresponding
	 * response.
	 * Panics if the check has not been run, is not complete, or the index is invalid.
	 */

	IMPORT_C const COCSPResponse* Response(TInt aIndex) const;
	
	IMPORT_C TBool CertsAvailableForOCSPCheck();
	
protected:
	virtual void RunL();
	virtual TInt RunError(TInt aErr);
	virtual void DoCancel();
	
private:
	
	enum TState
		{
		EInitial,
		ESendingRequest,		// Request is being sent to server
		EValidatingResponse,	// Request is being validated
		EHaveResult,			// Validation complete
		EError,					// We got an error
		};
		
	COCSPClient();
	void ConstructL(const COCSPParameters* aParams);
	void Destroy();
	void DoCheck();
	void SendRequest();
	void DoSendRequestL();
	void ValidateResponseL();
	void HandleResponseReceivedL();
	void HandleResponseValidatedL();
	void HandleTransactionErrorL(OCSP::TStatus aStatus);
	
	TState							iState;	
	TRequestStatus*					iClientStatus;
	const COCSPParameters*			iParams;
	const TDesC8*					iURI;
	MOCSPTransport*					iTransport;
	COCSPTransaction*				iTransaction;
	RPointerArray<COCSPRequest>		iRequests;
	RPointerArray<COCSPResponse>	iResponses;
	COCSPValidator*					iValidator;
	RArray<TOCSPOutcome>			iOutcomes;
	OCSP::TResult					iSummaryResult;
	
	};


#endif // OCSPREQUESTANDRESPONSE_H