pkiutilities/ocsp/src/cadirectauthorisation.cpp
changeset 0 164170e6151a
equal deleted inserted replaced
-1:000000000000 0:164170e6151a
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Define methods for authorisation scheme based on the CA who issued the certificate
       
    15 // issues and signs the response.
       
    16 // 
       
    17 //
       
    18 
       
    19 #include "ocsp.h"
       
    20 #include "panic.h"
       
    21 #include <pkixcertchain.h>
       
    22 #include <asn1dec.h>
       
    23 #include <x509keys.h>
       
    24 #include <x509cert.h>
       
    25 #include "ocsprequestandresponse.h"
       
    26 
       
    27 
       
    28 EXPORT_C COCSPCaDirectAuthorisationScheme* COCSPCaDirectAuthorisationScheme::NewLC()
       
    29 	{
       
    30 	COCSPCaDirectAuthorisationScheme* self = new(ELeave) COCSPCaDirectAuthorisationScheme();
       
    31 	CleanupStack::PushL(self);
       
    32 	return self;
       
    33 	}
       
    34 
       
    35 /**
       
    36 	Validate the response if it is signed by the CA.  The response can
       
    37 	optionally contain a copy of the CA's certificate.
       
    38 */
       
    39 void COCSPCaDirectAuthorisationScheme::ValidateL(OCSP::TStatus& aOCSPStatus,
       
    40 	COCSPResponse& aResponse, const TTime /* aValidationTime */, TRequestStatus& aStatus,
       
    41 	const COCSPRequest& aRequest)
       
    42 	{
       
    43 	TRequestStatus* validatorReqStatus = &aStatus;
       
    44 	aOCSPStatus = OCSP::EResponseSignatureValidationFailure;
       
    45 
       
    46 	// the OCSP requests are constructed in
       
    47 	// COCSPClient::ConstructL that exactly one certificate
       
    48 	// and its signer are sent in each request.
       
    49 	// (RFC 2560 S4.1.1 allows multiple pairs)
       
    50 	
       
    51 	// check the response is actually signed by the CA
       
    52 	// this effectively tests the same condition.
       
    53 	// By assuming there is only one request / response pair,
       
    54 	// there is no need to iterate through each response, which
       
    55 	// simplifies this scheme's implementation.
       
    56 
       
    57 	if (DoValidateL(aRequest, aResponse ))
       
    58 		{
       
    59 		aOCSPStatus = OCSP::EValid;
       
    60 		}
       
    61 	User::RequestComplete(validatorReqStatus, KErrNone);
       
    62 	};
       
    63 
       
    64 /**
       
    65 	Checks if the response is signed by the CA.
       
    66 	If the response has a certificate chain, it must contain
       
    67 	exactly the CA cert.  It is acceptable for the response
       
    68 	to have no certificate chain.
       
    69 
       
    70 	The responder ID in the certificate must match the CA cert,
       
    71 	and the whole response must be signed by the CA cert's signer.
       
    72 */
       
    73 TBool COCSPCaDirectAuthorisationScheme::DoValidateL(
       
    74 	const COCSPRequest& aRequest, COCSPResponse& aResponse)
       
    75 {
       
    76 	// check the response contains either zero or one certificates.
       
    77 	// If the response contains a certificate, then it must be the
       
    78 	// same as the CA.
       
    79 
       
    80 	// get the intermediate which signed the EE
       
    81 	const CX509Certificate& caCert = aRequest.CertInfo(0).Issuer();
       
    82 	
       
    83 	// Retrieves the chain from the response of the responder certificate
       
    84 	// whic signed the response.
       
    85 	const TPtrC8* certChainData = aResponse.DataElementEncoding(COCSPResponse::ECertificateChain);
       
    86 	if (certChainData != 0)
       
    87 		{
       
    88 		if (! CertChainMatchesCertL(*certChainData, caCert))
       
    89 			return EFalse;
       
    90 		}
       
    91 
       
    92 	return
       
    93 			OCSPUtils::DoesResponderIdMatchCertL(aResponse, caCert)
       
    94 		&&	OCSPUtils::IsResponseSignedByCertL(&aResponse, caCert);
       
    95 }
       
    96 
       
    97 /**
       
    98 	Checks whether the encoded cert chain contains exactly
       
    99 	one cert which matches the supplied cert.
       
   100 
       
   101 	This is used to verify that, when a cert chain is sent with
       
   102 	the response, it contains exactly the CA cert.
       
   103 
       
   104 	@param	aCertChainData	DER-encoded certificate chain data
       
   105 							extracted from response.
       
   106 	@param	aCert			Certificate to look for.
       
   107 	@return					ETrue if the certificate chain contains
       
   108 							exactly one response which matches
       
   109 							aCert; EFalse otherwise.
       
   110  */
       
   111 TBool COCSPCaDirectAuthorisationScheme::CertChainMatchesCertL(
       
   112 	const TDesC8& aCertChainData, const CX509Certificate& aCert)
       
   113 	{
       
   114 	// here we cannot assume that the response contains only the CA certificate,
       
   115 	// which signed the response as that can be a subordinate CA, so the chain
       
   116 	// can be like RCA(root CA) -> ICA(intermediate CA) -> SCA (sub-ordinate CA)
       
   117 	// we need to retrieve the SCA for this verification.
       
   118 	CX509Certificate* respCert = OCSPUtils::GetResponderCertLC(aCertChainData);
       
   119 	TBool match = aCert.IsEqualL(*respCert);
       
   120 	CleanupStack::PopAndDestroy(respCert);
       
   121 	return match;
       
   122 	}
       
   123 
       
   124 /**
       
   125 	This is a no-op because this implementation is not an
       
   126 	active object.
       
   127  */
       
   128 void COCSPCaDirectAuthorisationScheme::CancelValidate()
       
   129 	{}
       
   130 
       
   131 const CX509Certificate* COCSPCaDirectAuthorisationScheme::ResponderCert() const	
       
   132 	{
       
   133 	return NULL;
       
   134 	}