2  * Copyright (c) 2004,2011-2012,2014 Apple Inc. All Rights Reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. Please obtain a copy of the License at 
  10  * http://www.opensource.apple.com/apsl/ and read it before using this 
  13  * The Original Code and all software distributed under the License are 
  14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  18  * Please see the License for the specific language governing rights and 
  19  * limitations under the License. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  25  * ocspRequest.cpp - OCSP Request class 
  28 #include "ocspRequest.h" 
  29 #include "certGroupUtils.h" 
  30 #include "tpdebugging.h" 
  31 #include <security_ocspd/ocspResponse.h> 
  32 #include <security_ocspd/ocspExtensions.h> 
  33 #include <security_ocspd/ocspdUtils.h> 
  36 #include <Security/oidsalg.h> 
  37 #include <Security/oidscert.h> 
  38 #include <Security/ocspTemplates.h> 
  39 #include <security_utilities/devrandom.h> 
  40 #include <CommonCrypto/CommonDigest.h> 
  41 #include <security_cdsa_utilities/cssmerrors.h> 
  43 /* preencoded DER NULL */ 
  44 static uint8 nullParam
[2] = {5, 0}; 
  46 /* size of nonce we generate, in bytes */ 
  47 #define OCSP_NONCE_SIZE         8 
  50  * The only constructor. Subject and issuer must remain valid for the 
  51  * lifetime of this object (they are not refcounted). 
  53 OCSPRequest::OCSPRequest( 
  63         SecAsn1CoderCreate(&mCoder
); 
  70 OCSPRequest::~OCSPRequest() 
  74                 SecAsn1CoderRelease(mCoder
); 
  78 const CSSM_DATA 
*OCSPRequest::encode() 
  80         /* fields obtained from issuer */ 
  81         CSSM_DATA_PTR   issuerName
; 
  82         CSSM_DATA_PTR   issuerKey
; 
  83         CSSM_KEY_PTR    issuerPubKey
; 
  84         CSSM_DATA               issuerPubKeyBytes
; 
  86         CSSM_DATA_PTR   subjectSerial
=NULL
; 
  89         uint8                                           issuerNameHash
[CC_SHA1_DIGEST_LENGTH
]; 
  90         uint8                                           pubKeyHash
[CC_SHA1_DIGEST_LENGTH
]; 
  91         SecAsn1OCSPRequest                      singleReq
; 
  92         SecAsn1OCSPCertID                       
&certId 
= singleReq
.reqCert
; 
  93         SecAsn1OCSPSignedRequest        signedReq
; 
  94         SecAsn1OCSPRequest                      
*reqArray
[2] = { &singleReq
, NULL 
}; 
  95         SecAsn1OCSPTbsRequest           
&tbs 
= signedReq
.tbsRequest
; 
  97         CSSM_DATA                                       vers 
= {1, &version
}; 
  98         uint8                                           nonceBytes
[OCSP_NONCE_SIZE
]; 
  99         CSSM_DATA                                       nonceData 
= {OCSP_NONCE_SIZE
, nonceBytes
}; 
 100         OCSPNonce                                       
*nonce 
= NULL
; 
 101         NSS_CertExtension                       
*extenArray
[2] = {NULL
, NULL
}; 
 109          * One single request, no extensions 
 111         memset(&singleReq
, 0, sizeof(singleReq
)); 
 113         /* algId refers to the hash we'll perform in issuer name and key */ 
 114         certId
.algId
.algorithm 
= CSSMOID_SHA1
; 
 115         certId
.algId
.parameters
.Data 
= nullParam
; 
 116         certId
.algId
.parameters
.Length 
= sizeof(nullParam
); 
 118         /* gather fields from two certs */ 
 119         crtn 
= mSubject
.fetchField(&CSSMOID_X509V1IssuerNameStd
, &issuerName
); 
 121                 CssmError::throwMe(crtn
); 
 123         crtn 
= mIssuer
.fetchField(&CSSMOID_CSSMKeyStruct
, &issuerKey
); 
 127         crtn 
= mSubject
.fetchField(&CSSMOID_X509V1SerialNumber
, &subjectSerial
); 
 132         /* SHA1(issuerName) */ 
 133         ocspdSha1(issuerName
->Data
, (CC_LONG
)issuerName
->Length
, issuerNameHash
); 
 135         /* SHA1(issuer public key) */ 
 136         if(issuerKey
->Length 
!= sizeof(CSSM_KEY
)) { 
 137                 tpErrorLog("OCSPRequest::encode: malformed issuer key\n"); 
 138                 crtn 
= CSSMERR_TP_INTERNAL_ERROR
; 
 141         issuerPubKey 
= (CSSM_KEY_PTR
)issuerKey
->Data
; 
 142         ocspdGetPublicKeyBytes(mCoder
, issuerPubKey
, issuerPubKeyBytes
); 
 143         ocspdSha1(issuerPubKeyBytes
.Data
, (CC_LONG
)issuerPubKeyBytes
.Length
, pubKeyHash
); 
 145         /* build the CertID from those components */ 
 146         certId
.issuerNameHash
.Data 
= issuerNameHash
; 
 147         certId
.issuerNameHash
.Length 
= CC_SHA1_DIGEST_LENGTH
; 
 148         certId
.issuerPubKeyHash
.Data 
= pubKeyHash
; 
 149         certId
.issuerPubKeyHash
.Length 
= CC_SHA1_DIGEST_LENGTH
; 
 150         certId
.serialNumber 
= *subjectSerial
; 
 153          * Build top level request with one entry in requestList, no signature, 
 154          * one optional extension (a nonce) 
 156         memset(&signedReq
, 0, sizeof(signedReq
)); 
 158         tbs
.requestList 
= reqArray
; 
 160         /* one extension - the nonce */ 
 162                 DevRandomGenerator drg
; 
 163                 drg
.random(nonceBytes
, OCSP_NONCE_SIZE
); 
 164                 nonce 
= new OCSPNonce(mCoder
, false, nonceData
); 
 165                 extenArray
[0] = nonce
->nssExt(); 
 166                 tbs
.requestExtensions 
= extenArray
; 
 167                 SecAsn1AllocCopyItem(mCoder
, &nonceData
, &mNonce
); 
 171         if(SecAsn1EncodeItem(mCoder
, &signedReq
, kSecAsn1OCSPSignedRequestTemplate
, 
 173                 tpErrorLog("OCSPRequest::encode: error encoding OCSP req\n"); 
 174                 crtn 
= CSSMERR_TP_INTERNAL_ERROR
; 
 177         /* save a copy of the CertID */ 
 178         mCertID 
= new OCSPClientCertID(*issuerName
, issuerPubKeyBytes
, *subjectSerial
); 
 182                 mIssuer
.freeField(&CSSMOID_X509V1IssuerNameStd
, issuerName
); 
 185                 mIssuer
.freeField(&CSSMOID_CSSMKeyStruct
, issuerKey
); 
 188                 mSubject
.freeField(&CSSMOID_X509V1SerialNumber
, subjectSerial
); 
 194                 CssmError::throwMe(crtn
); 
 199 const CSSM_DATA 
*OCSPRequest::nonce() 
 201         /* not legal before encode() called */ 
 202         assert(mEncoded
.Data 
!= NULL
); 
 211 OCSPClientCertID 
*OCSPRequest::certID()