]> git.saurik.com Git - apple/security.git/blame - SecurityTests/clxutils/ocspTool/ocspRequest.cpp
Security-57337.20.44.tar.gz
[apple/security.git] / SecurityTests / clxutils / ocspTool / ocspRequest.cpp
CommitLineData
b1ab9ed8 1/*
d8f41ccd 2 * Copyright (c) 2004-2005 Apple Computer, Inc. All Rights Reserved.
b1ab9ed8
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24/*
25 * ocspRequest.cpp - OCSP Request class
26 */
27
28#include "ocspRequest.h"
d8f41ccd
A
29#include <clAppUtils/CertParser.h>
30#include <security_cdsa_utils/cuCdsaUtils.h>
b1ab9ed8
A
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/*
d8f41ccd 50 * The only constructor.
b1ab9ed8 51 */
d8f41ccd
A
52OCSPRequest::OCSPRequest(
53 CertParser &subject,
54 CertParser &issuer,
b1ab9ed8
A
55 bool genNonce)
56 : mCoder(NULL),
d8f41ccd 57 mSubject(subject),
b1ab9ed8
A
58 mIssuer(issuer),
59 mGenNonce(genNonce),
60 mCertID(NULL)
61{
62 SecAsn1CoderCreate(&mCoder);
63 mNonce.Data = NULL;
64 mNonce.Length = 0;
65 mEncoded.Data = NULL;
66 mEncoded.Length = 0;
67}
68
69OCSPRequest::~OCSPRequest()
70{
71 delete mCertID;
72 if(mCoder) {
73 SecAsn1CoderRelease(mCoder);
74 }
75}
76
77const CSSM_DATA *OCSPRequest::encode()
78{
79 /* fields obtained from issuer */
d8f41ccd
A
80 CSSM_DATA issuerName;
81 CSSM_DATA issuerKey;
b1ab9ed8
A
82 CSSM_KEY_PTR issuerPubKey;
83 /* from subject */
d8f41ccd 84 CSSM_DATA subjectSerial;
b1ab9ed8 85
d8f41ccd 86 CSSM_RETURN crtn = CSSM_OK;
b1ab9ed8
A
87 uint8 issuerNameHash[CC_SHA1_DIGEST_LENGTH];
88 uint8 pubKeyHash[CC_SHA1_DIGEST_LENGTH];
89 SecAsn1OCSPRequest singleReq;
90 SecAsn1OCSPCertID &certId = singleReq.reqCert;
91 SecAsn1OCSPSignedRequest signedReq;
92 SecAsn1OCSPRequest *reqArray[2] = { &singleReq, NULL };
93 SecAsn1OCSPTbsRequest &tbs = signedReq.tbsRequest;
94 uint8 version = 0;
95 CSSM_DATA vers = {1, &version};
96 uint8 nonceBytes[OCSP_NONCE_SIZE];
97 CSSM_DATA nonceData = {OCSP_NONCE_SIZE, nonceBytes};
98 OCSPNonce *nonce = NULL;
99 NSS_CertExtension *extenArray[2] = {NULL, NULL};
100
101 if(mEncoded.Data) {
102 /* already done */
103 return &mEncoded;
104 }
105
106 /*
107 * One single request, no extensions
108 */
109 memset(&singleReq, 0, sizeof(singleReq));
110
111 /* algId refers to the hash we'll perform in issuer name and key */
112 certId.algId.algorithm = CSSMOID_SHA1;
113 certId.algId.parameters.Data = nullParam;
114 certId.algId.parameters.Length = sizeof(nullParam);
115
116 /* gather fields from two certs */
d8f41ccd
A
117 issuerName.Length = 0; // don't check
118 issuerName.Data = (uint8 *)mSubject.fieldForOid(CSSMOID_X509V1IssuerNameStd,
119 issuerName.Length);
120 issuerKey.Length = sizeof(CSSM_KEY);
121 issuerKey.Data = (uint8 *)mIssuer.fieldForOid(CSSMOID_CSSMKeyStruct,
122 issuerKey.Length);
123 subjectSerial.Length = 0;
124 subjectSerial.Data = (uint8 *)mSubject.fieldForOid(CSSMOID_X509V1SerialNumber,
125 subjectSerial.Length);
b1ab9ed8
A
126
127 /* SHA1(issuerName) */
d8f41ccd 128 ocspdSha1(issuerName.Data, issuerName.Length, issuerNameHash);
b1ab9ed8
A
129
130 /* SHA1(issuer public key) */
d8f41ccd
A
131 issuerPubKey = (CSSM_KEY_PTR)issuerKey.Data;
132 ocspdSha1(issuerPubKey->KeyData.Data, issuerPubKey->KeyData.Length, pubKeyHash);
b1ab9ed8
A
133
134 /* build the CertID from those components */
135 certId.issuerNameHash.Data = issuerNameHash;
136 certId.issuerNameHash.Length = CC_SHA1_DIGEST_LENGTH;
137 certId.issuerPubKeyHash.Data = pubKeyHash;
138 certId.issuerPubKeyHash.Length = CC_SHA1_DIGEST_LENGTH;
d8f41ccd 139 certId.serialNumber = subjectSerial;
b1ab9ed8
A
140
141 /*
142 * Build top level request with one entry in requestList, no signature,
143 * one optional extension (a nonce)
144 */
145 memset(&signedReq, 0, sizeof(signedReq));
146 tbs.version = &vers;
147 tbs.requestList = reqArray;
148
149 /* one extension - the nonce */
150 if(mGenNonce) {
151 DevRandomGenerator drg;
152 drg.random(nonceBytes, OCSP_NONCE_SIZE);
153 nonce = new OCSPNonce(mCoder, false, nonceData);
154 extenArray[0] = nonce->nssExt();
155 tbs.requestExtensions = extenArray;
156 SecAsn1AllocCopyItem(mCoder, &nonceData, &mNonce);
157 }
158
159 /* Encode */
160 if(SecAsn1EncodeItem(mCoder, &signedReq, kSecAsn1OCSPSignedRequestTemplate,
161 &mEncoded)) {
d8f41ccd 162 printf("OCSPRequest::encode: error encoding OCSP req\n");
b1ab9ed8
A
163 crtn = CSSMERR_TP_INTERNAL_ERROR;
164 goto errOut;
165 }
166 /* save a copy of the CertID */
d8f41ccd 167 mCertID = new OCSPClientCertID(issuerName, issuerPubKey->KeyData, subjectSerial);
b1ab9ed8
A
168
169errOut:
b1ab9ed8
A
170 if(nonce) {
171 delete nonce;
172 }
173 if(crtn) {
174 CssmError::throwMe(crtn);
175 }
176 return &mEncoded;
177}
178
179const CSSM_DATA *OCSPRequest::nonce()
180{
181 /* not legal before encode() called */
182 assert(mEncoded.Data != NULL);
183 if(mNonce.Data) {
184 return &mNonce;
185 }
186 else {
187 return NULL;
188 }
189}
190
191OCSPClientCertID *OCSPRequest::certID()
192{
193 encode();
194 return mCertID;
195}
196