]> git.saurik.com Git - apple/security.git/blame - OSX/libsecurity_apple_x509_tp/lib/ocspRequest.cpp
Security-57336.10.29.tar.gz
[apple/security.git] / OSX / libsecurity_apple_x509_tp / lib / ocspRequest.cpp
CommitLineData
b1ab9ed8 1/*
d8f41ccd 2 * Copyright (c) 2004,2011-2012,2014 Apple Inc. All Rights Reserved.
949d2ff0 3 *
b1ab9ed8 4 * @APPLE_LICENSE_HEADER_START@
949d2ff0 5 *
b1ab9ed8
A
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
11 * file.
949d2ff0 12 *
b1ab9ed8
A
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.
949d2ff0 20 *
b1ab9ed8
A
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24/*
25 * ocspRequest.cpp - OCSP Request class
26 */
949d2ff0 27
b1ab9ed8
A
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>
34#include <assert.h>
35#include <string.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>
42
43/* preencoded DER NULL */
44static uint8 nullParam[2] = {5, 0};
45
46/* size of nonce we generate, in bytes */
47#define OCSP_NONCE_SIZE 8
48
49/*
949d2ff0
A
50 * The only constructor. Subject and issuer must remain valid for the
51 * lifetime of this object (they are not refcounted).
b1ab9ed8
A
52 */
53OCSPRequest::OCSPRequest(
54 TPCertInfo &subject,
55 TPCertInfo &issuer,
56 bool genNonce)
57 : mCoder(NULL),
949d2ff0 58 mSubject(subject),
b1ab9ed8
A
59 mIssuer(issuer),
60 mGenNonce(genNonce),
61 mCertID(NULL)
62{
63 SecAsn1CoderCreate(&mCoder);
64 mNonce.Data = NULL;
65 mNonce.Length = 0;
66 mEncoded.Data = NULL;
67 mEncoded.Length = 0;
68}
69
70OCSPRequest::~OCSPRequest()
71{
72 delete mCertID;
73 if(mCoder) {
74 SecAsn1CoderRelease(mCoder);
75 }
76}
77
78const CSSM_DATA *OCSPRequest::encode()
79{
80 /* fields obtained from issuer */
81 CSSM_DATA_PTR issuerName;
82 CSSM_DATA_PTR issuerKey;
83 CSSM_KEY_PTR issuerPubKey;
949d2ff0 84 CSSM_DATA issuerPubKeyBytes;
b1ab9ed8 85 /* from subject */
427c49bc 86 CSSM_DATA_PTR subjectSerial=NULL;
b1ab9ed8
A
87
88 CSSM_RETURN crtn;
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;
96 uint8 version = 0;
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};
949d2ff0 102
b1ab9ed8
A
103 if(mEncoded.Data) {
104 /* already done */
105 return &mEncoded;
106 }
107
949d2ff0 108 /*
b1ab9ed8
A
109 * One single request, no extensions
110 */
111 memset(&singleReq, 0, sizeof(singleReq));
949d2ff0 112
b1ab9ed8
A
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);
117
118 /* gather fields from two certs */
119 crtn = mSubject.fetchField(&CSSMOID_X509V1IssuerNameStd, &issuerName);
120 if(crtn) {
121 CssmError::throwMe(crtn);
122 }
123 crtn = mIssuer.fetchField(&CSSMOID_CSSMKeyStruct, &issuerKey);
124 if(crtn) {
125 goto errOut;
126 }
127 crtn = mSubject.fetchField(&CSSMOID_X509V1SerialNumber, &subjectSerial);
128 if(crtn) {
129 goto errOut;
130 }
131
132 /* SHA1(issuerName) */
427c49bc 133 ocspdSha1(issuerName->Data, (CC_LONG)issuerName->Length, issuerNameHash);
b1ab9ed8
A
134
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;
139 goto errOut;
140 }
141 issuerPubKey = (CSSM_KEY_PTR)issuerKey->Data;
949d2ff0
A
142 ocspdGetPublicKeyBytes(mCoder, issuerPubKey, issuerPubKeyBytes);
143 ocspdSha1(issuerPubKeyBytes.Data, (CC_LONG)issuerPubKeyBytes.Length, pubKeyHash);
144
b1ab9ed8
A
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;
949d2ff0 149 certId.issuerPubKeyHash.Length = CC_SHA1_DIGEST_LENGTH;
b1ab9ed8
A
150 certId.serialNumber = *subjectSerial;
151
949d2ff0 152 /*
b1ab9ed8
A
153 * Build top level request with one entry in requestList, no signature,
154 * one optional extension (a nonce)
155 */
156 memset(&signedReq, 0, sizeof(signedReq));
157 tbs.version = &vers;
158 tbs.requestList = reqArray;
159
160 /* one extension - the nonce */
161 if(mGenNonce) {
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);
168 }
949d2ff0 169
b1ab9ed8 170 /* Encode */
949d2ff0 171 if(SecAsn1EncodeItem(mCoder, &signedReq, kSecAsn1OCSPSignedRequestTemplate,
b1ab9ed8
A
172 &mEncoded)) {
173 tpErrorLog("OCSPRequest::encode: error encoding OCSP req\n");
174 crtn = CSSMERR_TP_INTERNAL_ERROR;
175 goto errOut;
176 }
177 /* save a copy of the CertID */
949d2ff0
A
178 mCertID = new OCSPClientCertID(*issuerName, issuerPubKeyBytes, *subjectSerial);
179
b1ab9ed8
A
180errOut:
181 if(issuerName) {
182 mIssuer.freeField(&CSSMOID_X509V1IssuerNameStd, issuerName);
183 }
184 if(issuerKey) {
185 mIssuer.freeField(&CSSMOID_CSSMKeyStruct, issuerKey);
186 }
187 if(subjectSerial) {
188 mSubject.freeField(&CSSMOID_X509V1SerialNumber, subjectSerial);
189 }
190 if(nonce) {
191 delete nonce;
192 }
193 if(crtn) {
194 CssmError::throwMe(crtn);
195 }
196 return &mEncoded;
197}
198
199const CSSM_DATA *OCSPRequest::nonce()
200{
201 /* not legal before encode() called */
202 assert(mEncoded.Data != NULL);
203 if(mNonce.Data) {
204 return &mNonce;
205 }
206 else {
207 return NULL;
208 }
209}
210
211OCSPClientCertID *OCSPRequest::certID()
212{
213 encode();
214 return mCertID;
215}
216