1 |
|
|
/* $OpenBSD: ocsp_ext.c,v 1.15 2016/12/27 16:01:19 jsing Exp $ */ |
2 |
|
|
/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL |
3 |
|
|
* project. */ |
4 |
|
|
|
5 |
|
|
/* History: |
6 |
|
|
This file was transfered to Richard Levitte from CertCo by Kathy |
7 |
|
|
Weinhold in mid-spring 2000 to be included in OpenSSL or released |
8 |
|
|
as a patch kit. */ |
9 |
|
|
|
10 |
|
|
/* ==================================================================== |
11 |
|
|
* Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. |
12 |
|
|
* |
13 |
|
|
* Redistribution and use in source and binary forms, with or without |
14 |
|
|
* modification, are permitted provided that the following conditions |
15 |
|
|
* are met: |
16 |
|
|
* |
17 |
|
|
* 1. Redistributions of source code must retain the above copyright |
18 |
|
|
* notice, this list of conditions and the following disclaimer. |
19 |
|
|
* |
20 |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
21 |
|
|
* notice, this list of conditions and the following disclaimer in |
22 |
|
|
* the documentation and/or other materials provided with the |
23 |
|
|
* distribution. |
24 |
|
|
* |
25 |
|
|
* 3. All advertising materials mentioning features or use of this |
26 |
|
|
* software must display the following acknowledgment: |
27 |
|
|
* "This product includes software developed by the OpenSSL Project |
28 |
|
|
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)" |
29 |
|
|
* |
30 |
|
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
31 |
|
|
* endorse or promote products derived from this software without |
32 |
|
|
* prior written permission. For written permission, please contact |
33 |
|
|
* openssl-core@openssl.org. |
34 |
|
|
* |
35 |
|
|
* 5. Products derived from this software may not be called "OpenSSL" |
36 |
|
|
* nor may "OpenSSL" appear in their names without prior written |
37 |
|
|
* permission of the OpenSSL Project. |
38 |
|
|
* |
39 |
|
|
* 6. Redistributions of any form whatsoever must retain the following |
40 |
|
|
* acknowledgment: |
41 |
|
|
* "This product includes software developed by the OpenSSL Project |
42 |
|
|
* for use in the OpenSSL Toolkit (http://www.openssl.org/)" |
43 |
|
|
* |
44 |
|
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
45 |
|
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
46 |
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
47 |
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
48 |
|
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
49 |
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
50 |
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
51 |
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
52 |
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
53 |
|
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
54 |
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
55 |
|
|
* OF THE POSSIBILITY OF SUCH DAMAGE. |
56 |
|
|
* ==================================================================== |
57 |
|
|
* |
58 |
|
|
* This product includes cryptographic software written by Eric Young |
59 |
|
|
* (eay@cryptsoft.com). This product includes software written by Tim |
60 |
|
|
* Hudson (tjh@cryptsoft.com). |
61 |
|
|
* |
62 |
|
|
*/ |
63 |
|
|
|
64 |
|
|
#include <stdio.h> |
65 |
|
|
#include <stdlib.h> |
66 |
|
|
#include <string.h> |
67 |
|
|
|
68 |
|
|
#include <openssl/objects.h> |
69 |
|
|
#include <openssl/ocsp.h> |
70 |
|
|
#include <openssl/x509.h> |
71 |
|
|
#include <openssl/x509v3.h> |
72 |
|
|
|
73 |
|
|
/* Standard wrapper functions for extensions */ |
74 |
|
|
|
75 |
|
|
/* OCSP request extensions */ |
76 |
|
|
|
77 |
|
|
int |
78 |
|
|
OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x) |
79 |
|
|
{ |
80 |
|
|
return X509v3_get_ext_count(x->tbsRequest->requestExtensions); |
81 |
|
|
} |
82 |
|
|
|
83 |
|
|
int |
84 |
|
|
OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos) |
85 |
|
|
{ |
86 |
|
16 |
return X509v3_get_ext_by_NID(x->tbsRequest->requestExtensions, nid, |
87 |
|
|
lastpos); |
88 |
|
|
} |
89 |
|
|
|
90 |
|
|
int |
91 |
|
|
OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, int lastpos) |
92 |
|
|
{ |
93 |
|
|
return X509v3_get_ext_by_OBJ(x->tbsRequest->requestExtensions, obj, |
94 |
|
|
lastpos); |
95 |
|
|
} |
96 |
|
|
|
97 |
|
|
int |
98 |
|
|
OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos) |
99 |
|
|
{ |
100 |
|
|
return X509v3_get_ext_by_critical(x->tbsRequest->requestExtensions, |
101 |
|
|
crit, lastpos); |
102 |
|
|
} |
103 |
|
|
|
104 |
|
|
X509_EXTENSION * |
105 |
|
|
OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc) |
106 |
|
|
{ |
107 |
|
16 |
return X509v3_get_ext(x->tbsRequest->requestExtensions, loc); |
108 |
|
|
} |
109 |
|
|
|
110 |
|
|
X509_EXTENSION * |
111 |
|
|
OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc) |
112 |
|
|
{ |
113 |
|
|
return X509v3_delete_ext(x->tbsRequest->requestExtensions, loc); |
114 |
|
|
} |
115 |
|
|
|
116 |
|
|
void * |
117 |
|
|
OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx) |
118 |
|
|
{ |
119 |
|
|
return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx); |
120 |
|
|
} |
121 |
|
|
|
122 |
|
|
int |
123 |
|
|
OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, |
124 |
|
|
unsigned long flags) |
125 |
|
|
{ |
126 |
|
|
return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value, |
127 |
|
|
crit, flags); |
128 |
|
|
} |
129 |
|
|
|
130 |
|
|
int |
131 |
|
|
OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc) |
132 |
|
|
{ |
133 |
|
|
return X509v3_add_ext(&(x->tbsRequest->requestExtensions), ex, |
134 |
|
|
loc) != NULL; |
135 |
|
|
} |
136 |
|
|
|
137 |
|
|
/* Single extensions */ |
138 |
|
|
|
139 |
|
|
int |
140 |
|
|
OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x) |
141 |
|
|
{ |
142 |
|
|
return X509v3_get_ext_count(x->singleRequestExtensions); |
143 |
|
|
} |
144 |
|
|
|
145 |
|
|
int |
146 |
|
|
OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos) |
147 |
|
|
{ |
148 |
|
|
return X509v3_get_ext_by_NID(x->singleRequestExtensions, nid, lastpos); |
149 |
|
|
} |
150 |
|
|
|
151 |
|
|
int |
152 |
|
|
OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos) |
153 |
|
|
{ |
154 |
|
|
return X509v3_get_ext_by_OBJ(x->singleRequestExtensions, obj, lastpos); |
155 |
|
|
} |
156 |
|
|
|
157 |
|
|
int |
158 |
|
|
OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos) |
159 |
|
|
{ |
160 |
|
|
return X509v3_get_ext_by_critical(x->singleRequestExtensions, crit, |
161 |
|
|
lastpos); |
162 |
|
|
} |
163 |
|
|
|
164 |
|
|
X509_EXTENSION * |
165 |
|
|
OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc) |
166 |
|
|
{ |
167 |
|
|
return X509v3_get_ext(x->singleRequestExtensions, loc); |
168 |
|
|
} |
169 |
|
|
|
170 |
|
|
X509_EXTENSION * |
171 |
|
|
OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc) |
172 |
|
|
{ |
173 |
|
|
return X509v3_delete_ext(x->singleRequestExtensions, loc); |
174 |
|
|
} |
175 |
|
|
|
176 |
|
|
void * |
177 |
|
|
OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx) |
178 |
|
|
{ |
179 |
|
|
return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx); |
180 |
|
|
} |
181 |
|
|
|
182 |
|
|
int |
183 |
|
|
OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, |
184 |
|
|
unsigned long flags) |
185 |
|
|
{ |
186 |
|
|
return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit, |
187 |
|
|
flags); |
188 |
|
|
} |
189 |
|
|
|
190 |
|
|
int |
191 |
|
|
OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc) |
192 |
|
|
{ |
193 |
|
|
return X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL; |
194 |
|
|
} |
195 |
|
|
|
196 |
|
|
/* OCSP Basic response */ |
197 |
|
|
|
198 |
|
|
int |
199 |
|
|
OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x) |
200 |
|
|
{ |
201 |
|
|
return X509v3_get_ext_count(x->tbsResponseData->responseExtensions); |
202 |
|
|
} |
203 |
|
|
|
204 |
|
|
int |
205 |
|
|
OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos) |
206 |
|
|
{ |
207 |
|
8 |
return X509v3_get_ext_by_NID(x->tbsResponseData->responseExtensions, |
208 |
|
|
nid, lastpos); |
209 |
|
|
} |
210 |
|
|
|
211 |
|
|
int |
212 |
|
|
OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, int lastpos) |
213 |
|
|
{ |
214 |
|
|
return X509v3_get_ext_by_OBJ(x->tbsResponseData->responseExtensions, |
215 |
|
|
obj, lastpos); |
216 |
|
|
} |
217 |
|
|
|
218 |
|
|
int |
219 |
|
|
OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, int lastpos) |
220 |
|
|
{ |
221 |
|
|
return X509v3_get_ext_by_critical( |
222 |
|
|
x->tbsResponseData->responseExtensions, crit, lastpos); |
223 |
|
|
} |
224 |
|
|
|
225 |
|
|
X509_EXTENSION * |
226 |
|
|
OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc) |
227 |
|
|
{ |
228 |
|
8 |
return X509v3_get_ext(x->tbsResponseData->responseExtensions, loc); |
229 |
|
|
} |
230 |
|
|
|
231 |
|
|
X509_EXTENSION * |
232 |
|
|
OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc) |
233 |
|
|
{ |
234 |
|
|
return X509v3_delete_ext(x->tbsResponseData->responseExtensions, loc); |
235 |
|
|
} |
236 |
|
|
|
237 |
|
|
void * |
238 |
|
|
OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, int *idx) |
239 |
|
|
{ |
240 |
|
|
return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, |
241 |
|
|
crit, idx); |
242 |
|
|
} |
243 |
|
|
|
244 |
|
|
int |
245 |
|
|
OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, int crit, |
246 |
|
|
unsigned long flags) |
247 |
|
|
{ |
248 |
|
|
return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid, |
249 |
|
|
value, crit, flags); |
250 |
|
|
} |
251 |
|
|
|
252 |
|
|
int |
253 |
|
|
OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc) |
254 |
|
|
{ |
255 |
|
12 |
return X509v3_add_ext(&(x->tbsResponseData->responseExtensions), ex, |
256 |
|
4 |
loc) != NULL; |
257 |
|
|
} |
258 |
|
|
|
259 |
|
|
/* OCSP single response extensions */ |
260 |
|
|
|
261 |
|
|
int |
262 |
|
|
OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x) |
263 |
|
|
{ |
264 |
|
|
return X509v3_get_ext_count(x->singleExtensions); |
265 |
|
|
} |
266 |
|
|
|
267 |
|
|
int |
268 |
|
|
OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos) |
269 |
|
|
{ |
270 |
|
|
return X509v3_get_ext_by_NID(x->singleExtensions, nid, lastpos); |
271 |
|
|
} |
272 |
|
|
|
273 |
|
|
int |
274 |
|
|
OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, |
275 |
|
|
int lastpos) |
276 |
|
|
{ |
277 |
|
|
return X509v3_get_ext_by_OBJ(x->singleExtensions, obj, lastpos); |
278 |
|
|
} |
279 |
|
|
|
280 |
|
|
int |
281 |
|
|
OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, int lastpos) |
282 |
|
|
{ |
283 |
|
|
return X509v3_get_ext_by_critical(x->singleExtensions, crit, lastpos); |
284 |
|
|
} |
285 |
|
|
|
286 |
|
|
X509_EXTENSION * |
287 |
|
|
OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc) |
288 |
|
|
{ |
289 |
|
|
return X509v3_get_ext(x->singleExtensions, loc); |
290 |
|
|
} |
291 |
|
|
|
292 |
|
|
X509_EXTENSION * |
293 |
|
|
OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc) |
294 |
|
|
{ |
295 |
|
|
return X509v3_delete_ext(x->singleExtensions, loc); |
296 |
|
|
} |
297 |
|
|
|
298 |
|
|
void * |
299 |
|
|
OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, int *idx) |
300 |
|
|
{ |
301 |
|
|
return X509V3_get_d2i(x->singleExtensions, nid, crit, idx); |
302 |
|
|
} |
303 |
|
|
|
304 |
|
|
int |
305 |
|
|
OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, int crit, |
306 |
|
|
unsigned long flags) |
307 |
|
|
{ |
308 |
|
|
return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags); |
309 |
|
|
} |
310 |
|
|
|
311 |
|
|
int |
312 |
|
|
OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc) |
313 |
|
|
{ |
314 |
|
|
return X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL; |
315 |
|
|
} |
316 |
|
|
|
317 |
|
|
/* Nonce handling functions */ |
318 |
|
|
|
319 |
|
|
/* Add a nonce to an extension stack. A nonce can be specificed or if NULL |
320 |
|
|
* a random nonce will be generated. |
321 |
|
|
* Note: OpenSSL 0.9.7d and later create an OCTET STRING containing the |
322 |
|
|
* nonce, previous versions used the raw nonce. |
323 |
|
|
*/ |
324 |
|
|
|
325 |
|
|
static int |
326 |
|
|
ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, unsigned char *val, int len) |
327 |
|
|
{ |
328 |
|
8 |
unsigned char *tmpval; |
329 |
|
4 |
ASN1_OCTET_STRING os; |
330 |
|
|
int ret = 0; |
331 |
|
|
|
332 |
✓✗ |
4 |
if (len <= 0) |
333 |
|
4 |
len = OCSP_DEFAULT_NONCE_LENGTH; |
334 |
|
|
/* Create the OCTET STRING manually by writing out the header and |
335 |
|
|
* appending the content octets. This avoids an extra memory allocation |
336 |
|
|
* operation in some cases. Applications should *NOT* do this because |
337 |
|
|
* it relies on library internals. |
338 |
|
|
*/ |
339 |
|
4 |
os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING); |
340 |
|
4 |
os.data = malloc(os.length); |
341 |
✓✗ |
4 |
if (os.data == NULL) |
342 |
|
|
goto err; |
343 |
|
4 |
tmpval = os.data; |
344 |
|
4 |
ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL); |
345 |
✗✓ |
4 |
if (val) |
346 |
|
|
memcpy(tmpval, val, len); |
347 |
|
|
else |
348 |
|
4 |
arc4random_buf(tmpval, len); |
349 |
✓✗ |
4 |
if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce, &os, 0, |
350 |
|
|
X509V3_ADD_REPLACE)) |
351 |
|
|
goto err; |
352 |
|
4 |
ret = 1; |
353 |
|
|
|
354 |
|
|
err: |
355 |
|
4 |
free(os.data); |
356 |
|
4 |
return ret; |
357 |
|
4 |
} |
358 |
|
|
|
359 |
|
|
/* Add nonce to an OCSP request */ |
360 |
|
|
int |
361 |
|
|
OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) |
362 |
|
|
{ |
363 |
|
8 |
return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len); |
364 |
|
|
} |
365 |
|
|
|
366 |
|
|
/* Same as above but for a response */ |
367 |
|
|
int |
368 |
|
|
OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len) |
369 |
|
|
{ |
370 |
|
|
return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val, |
371 |
|
|
len); |
372 |
|
|
} |
373 |
|
|
|
374 |
|
|
/* Check nonce validity in a request and response. |
375 |
|
|
* Return value reflects result: |
376 |
|
|
* 1: nonces present and equal. |
377 |
|
|
* 2: nonces both absent. |
378 |
|
|
* 3: nonce present in response only. |
379 |
|
|
* 0: nonces both present and not equal. |
380 |
|
|
* -1: nonce in request only. |
381 |
|
|
* |
382 |
|
|
* For most responders clients can check return > 0. |
383 |
|
|
* If responder doesn't handle nonces return != 0 may be |
384 |
|
|
* necessary. return == 0 is always an error. |
385 |
|
|
*/ |
386 |
|
|
int |
387 |
|
|
OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs) |
388 |
|
|
{ |
389 |
|
|
/* |
390 |
|
|
* Since we are only interested in the presence or absence of |
391 |
|
|
* the nonce and comparing its value there is no need to use |
392 |
|
|
* the X509V3 routines: this way we can avoid them allocating an |
393 |
|
|
* ASN1_OCTET_STRING structure for the value which would be |
394 |
|
|
* freed immediately anyway. |
395 |
|
|
*/ |
396 |
|
|
int req_idx, resp_idx; |
397 |
|
|
X509_EXTENSION *req_ext, *resp_ext; |
398 |
|
|
|
399 |
|
8 |
req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); |
400 |
|
4 |
resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, |
401 |
|
|
NID_id_pkix_OCSP_Nonce, -1); |
402 |
|
|
/* Check both absent */ |
403 |
✗✓ |
4 |
if (req_idx < 0 && resp_idx < 0) |
404 |
|
|
return 2; |
405 |
|
|
/* Check in request only */ |
406 |
✗✓ |
4 |
if (req_idx >= 0 && resp_idx < 0) |
407 |
|
|
return -1; |
408 |
|
|
/* Check in response but not request */ |
409 |
✗✓ |
4 |
if (req_idx < 0 && resp_idx >= 0) |
410 |
|
|
return 3; |
411 |
|
|
/* Otherwise nonce in request and response so retrieve the extensions */ |
412 |
|
4 |
req_ext = OCSP_REQUEST_get_ext(req, req_idx); |
413 |
|
4 |
resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx); |
414 |
✗✓ |
4 |
if (ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value)) |
415 |
|
|
return 0; |
416 |
|
4 |
return 1; |
417 |
|
4 |
} |
418 |
|
|
|
419 |
|
|
/* Copy the nonce value (if any) from an OCSP request to |
420 |
|
|
* a response. |
421 |
|
|
*/ |
422 |
|
|
int |
423 |
|
|
OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req) |
424 |
|
|
{ |
425 |
|
|
X509_EXTENSION *req_ext; |
426 |
|
|
int req_idx; |
427 |
|
|
|
428 |
|
|
/* Check for nonce in request */ |
429 |
|
8 |
req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); |
430 |
|
|
/* If no nonce that's OK */ |
431 |
✗✓ |
4 |
if (req_idx < 0) |
432 |
|
|
return 2; |
433 |
|
4 |
req_ext = OCSP_REQUEST_get_ext(req, req_idx); |
434 |
|
4 |
return OCSP_BASICRESP_add_ext(resp, req_ext, -1); |
435 |
|
4 |
} |
436 |
|
|
|
437 |
|
|
X509_EXTENSION * |
438 |
|
|
OCSP_crlID_new(char *url, long *n, char *tim) |
439 |
|
|
{ |
440 |
|
|
X509_EXTENSION *x = NULL; |
441 |
|
|
OCSP_CRLID *cid = NULL; |
442 |
|
|
|
443 |
|
|
if (!(cid = OCSP_CRLID_new())) |
444 |
|
|
goto err; |
445 |
|
|
if (url) { |
446 |
|
|
if (!(cid->crlUrl = ASN1_IA5STRING_new())) |
447 |
|
|
goto err; |
448 |
|
|
if (!(ASN1_STRING_set(cid->crlUrl, url, -1))) |
449 |
|
|
goto err; |
450 |
|
|
} |
451 |
|
|
if (n) { |
452 |
|
|
if (!(cid->crlNum = ASN1_INTEGER_new())) |
453 |
|
|
goto err; |
454 |
|
|
if (!(ASN1_INTEGER_set(cid->crlNum, *n))) |
455 |
|
|
goto err; |
456 |
|
|
} |
457 |
|
|
if (tim) { |
458 |
|
|
if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new())) |
459 |
|
|
goto err; |
460 |
|
|
if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) |
461 |
|
|
goto err; |
462 |
|
|
} |
463 |
|
|
x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid); |
464 |
|
|
|
465 |
|
|
err: |
466 |
|
|
if (cid) |
467 |
|
|
OCSP_CRLID_free(cid); |
468 |
|
|
return x; |
469 |
|
|
} |
470 |
|
|
|
471 |
|
|
/* AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */ |
472 |
|
|
X509_EXTENSION * |
473 |
|
|
OCSP_accept_responses_new(char **oids) |
474 |
|
|
{ |
475 |
|
|
int nid; |
476 |
|
|
STACK_OF(ASN1_OBJECT) *sk = NULL; |
477 |
|
|
ASN1_OBJECT *o = NULL; |
478 |
|
|
X509_EXTENSION *x = NULL; |
479 |
|
|
|
480 |
|
|
if (!(sk = sk_ASN1_OBJECT_new_null())) |
481 |
|
|
return NULL; |
482 |
|
|
while (oids && *oids) { |
483 |
|
|
if ((nid = OBJ_txt2nid(*oids)) != NID_undef && |
484 |
|
|
(o = OBJ_nid2obj(nid))) |
485 |
|
|
if (sk_ASN1_OBJECT_push(sk, o) == 0) { |
486 |
|
|
sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); |
487 |
|
|
return NULL; |
488 |
|
|
} |
489 |
|
|
oids++; |
490 |
|
|
} |
491 |
|
|
x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk); |
492 |
|
|
sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); |
493 |
|
|
return x; |
494 |
|
|
} |
495 |
|
|
|
496 |
|
|
/* ArchiveCutoff ::= GeneralizedTime */ |
497 |
|
|
X509_EXTENSION * |
498 |
|
|
OCSP_archive_cutoff_new(char* tim) |
499 |
|
|
{ |
500 |
|
|
X509_EXTENSION *x = NULL; |
501 |
|
|
ASN1_GENERALIZEDTIME *gt = NULL; |
502 |
|
|
|
503 |
|
|
if (!(gt = ASN1_GENERALIZEDTIME_new())) |
504 |
|
|
return NULL; |
505 |
|
|
if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) |
506 |
|
|
goto err; |
507 |
|
|
x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt); |
508 |
|
|
|
509 |
|
|
err: |
510 |
|
|
if (gt) |
511 |
|
|
ASN1_GENERALIZEDTIME_free(gt); |
512 |
|
|
return x; |
513 |
|
|
} |
514 |
|
|
|
515 |
|
|
/* per ACCESS_DESCRIPTION parameter are oids, of which there are currently |
516 |
|
|
* two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value. This |
517 |
|
|
* method forces NID_ad_ocsp and uniformResourceLocator [6] IA5String. |
518 |
|
|
*/ |
519 |
|
|
X509_EXTENSION * |
520 |
|
|
OCSP_url_svcloc_new(X509_NAME* issuer, char **urls) |
521 |
|
|
{ |
522 |
|
|
X509_EXTENSION *x = NULL; |
523 |
|
|
ASN1_IA5STRING *ia5 = NULL; |
524 |
|
|
OCSP_SERVICELOC *sloc = NULL; |
525 |
|
|
ACCESS_DESCRIPTION *ad = NULL; |
526 |
|
|
|
527 |
|
|
if (!(sloc = OCSP_SERVICELOC_new())) |
528 |
|
|
goto err; |
529 |
|
|
if (!(sloc->issuer = X509_NAME_dup(issuer))) |
530 |
|
|
goto err; |
531 |
|
|
if (urls && *urls && |
532 |
|
|
!(sloc->locator = sk_ACCESS_DESCRIPTION_new_null())) |
533 |
|
|
goto err; |
534 |
|
|
while (urls && *urls) { |
535 |
|
|
if (!(ad = ACCESS_DESCRIPTION_new())) |
536 |
|
|
goto err; |
537 |
|
|
if (!(ad->method = OBJ_nid2obj(NID_ad_OCSP))) |
538 |
|
|
goto err; |
539 |
|
|
if (!(ad->location = GENERAL_NAME_new())) |
540 |
|
|
goto err; |
541 |
|
|
if (!(ia5 = ASN1_IA5STRING_new())) |
542 |
|
|
goto err; |
543 |
|
|
if (!ASN1_STRING_set((ASN1_STRING*)ia5, *urls, -1)) |
544 |
|
|
goto err; |
545 |
|
|
ad->location->type = GEN_URI; |
546 |
|
|
ad->location->d.ia5 = ia5; |
547 |
|
|
ia5 = NULL; |
548 |
|
|
if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) |
549 |
|
|
goto err; |
550 |
|
|
ad = NULL; |
551 |
|
|
urls++; |
552 |
|
|
} |
553 |
|
|
x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc); |
554 |
|
|
|
555 |
|
|
err: |
556 |
|
|
if (ia5) |
557 |
|
|
ASN1_IA5STRING_free(ia5); |
558 |
|
|
if (ad) |
559 |
|
|
ACCESS_DESCRIPTION_free(ad); |
560 |
|
|
if (sloc) |
561 |
|
|
OCSP_SERVICELOC_free(sloc); |
562 |
|
|
return x; |
563 |
|
|
} |