]>
Commit | Line | Data |
---|---|---|
5782ceb2 DSH |
1 | /* ocsp.c */ |
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | |
3 | * project 2000. | |
4 | */ | |
5 | /* ==================================================================== | |
6 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | |
7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | |
11 | * | |
12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | |
14 | * | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in | |
17 | * the documentation and/or other materials provided with the | |
18 | * distribution. | |
19 | * | |
20 | * 3. All advertising materials mentioning features or use of this | |
21 | * software must display the following acknowledgment: | |
22 | * "This product includes software developed by the OpenSSL Project | |
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | |
24 | * | |
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
26 | * endorse or promote products derived from this software without | |
27 | * prior written permission. For written permission, please contact | |
28 | * licensing@OpenSSL.org. | |
29 | * | |
30 | * 5. Products derived from this software may not be called "OpenSSL" | |
31 | * nor may "OpenSSL" appear in their names without prior written | |
32 | * permission of the OpenSSL Project. | |
33 | * | |
34 | * 6. Redistributions of any form whatsoever must retain the following | |
35 | * acknowledgment: | |
36 | * "This product includes software developed by the OpenSSL Project | |
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | |
38 | * | |
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | |
51 | * ==================================================================== | |
52 | * | |
53 | * This product includes cryptographic software written by Eric Young | |
54 | * (eay@cryptsoft.com). This product includes software written by Tim | |
55 | * Hudson (tjh@cryptsoft.com). | |
56 | * | |
57 | */ | |
58 | ||
59 | #include <stdio.h> | |
60 | #include <string.h> | |
61 | #include <openssl/pem.h> | |
62 | #include <openssl/ocsp.h> | |
63 | #include <openssl/err.h> | |
cdc7b8cc | 64 | #include <openssl/ssl.h> |
5782ceb2 DSH |
65 | #include "apps.h" |
66 | ||
73758d43 DSH |
67 | static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer, |
68 | STACK_OF(OCSP_CERTID) *ids); | |
69 | static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer, | |
70 | STACK_OF(OCSP_CERTID) *ids); | |
71 | static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, | |
72 | STACK *names, STACK_OF(OCSP_CERTID) *ids); | |
5782ceb2 DSH |
73 | |
74 | #undef PROG | |
75 | #define PROG ocsp_main | |
76 | ||
77 | int MAIN(int, char **); | |
78 | ||
79 | int MAIN(int argc, char **argv) | |
80 | { | |
81 | char **args; | |
67c18019 | 82 | char *host = NULL, *port = NULL, *path = "/"; |
5782ceb2 DSH |
83 | char *reqin = NULL, *respin = NULL; |
84 | char *reqout = NULL, *respout = NULL; | |
85 | char *signfile = NULL, *keyfile = NULL; | |
86 | char *outfile = NULL; | |
67c18019 | 87 | int add_nonce = 1, noverify = 0, use_ssl = -1; |
5782ceb2 DSH |
88 | OCSP_REQUEST *req = NULL; |
89 | OCSP_RESPONSE *resp = NULL; | |
81f169e9 | 90 | OCSP_BASICRESP *bs = NULL; |
5782ceb2 DSH |
91 | X509 *issuer = NULL, *cert = NULL; |
92 | X509 *signer = NULL; | |
93 | EVP_PKEY *key = NULL; | |
94 | BIO *cbio = NULL, *derbio = NULL; | |
95 | BIO *out = NULL; | |
96 | int req_text = 0, resp_text = 0; | |
81f169e9 DSH |
97 | char *CAfile = NULL, *CApath = NULL; |
98 | X509_STORE *store = NULL; | |
cdc7b8cc | 99 | SSL_CTX *ctx = NULL; |
8c950429 DSH |
100 | STACK_OF(X509) *sign_other = NULL, *verify_other = NULL; |
101 | char *sign_certfile = NULL, *verify_certfile = NULL; | |
102 | unsigned long sign_flags = 0, verify_flags = 0; | |
5782ceb2 DSH |
103 | int ret = 1; |
104 | int badarg = 0; | |
81f169e9 | 105 | int i; |
73758d43 DSH |
106 | STACK *reqnames = NULL; |
107 | STACK_OF(OCSP_CERTID) *ids = NULL; | |
5782ceb2 | 108 | if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); |
cdc7b8cc | 109 | SSL_load_error_strings(); |
5782ceb2 | 110 | args = argv + 1; |
73758d43 DSH |
111 | reqnames = sk_new_null(); |
112 | ids = sk_OCSP_CERTID_new_null(); | |
5782ceb2 DSH |
113 | while (!badarg && *args && *args[0] == '-') |
114 | { | |
115 | if (!strcmp(*args, "-out")) | |
116 | { | |
117 | if (args[1]) | |
118 | { | |
119 | args++; | |
120 | outfile = *args; | |
121 | } | |
122 | else badarg = 1; | |
123 | } | |
67c18019 DSH |
124 | else if (!strcmp(*args, "-url")) |
125 | { | |
126 | if (args[1]) | |
127 | { | |
128 | args++; | |
129 | if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl)) | |
130 | { | |
131 | BIO_printf(bio_err, "Error parsing URL\n"); | |
132 | badarg = 1; | |
133 | } | |
134 | } | |
135 | else badarg = 1; | |
136 | } | |
5782ceb2 DSH |
137 | else if (!strcmp(*args, "-host")) |
138 | { | |
139 | if (args[1]) | |
140 | { | |
141 | args++; | |
142 | host = *args; | |
143 | } | |
144 | else badarg = 1; | |
145 | } | |
73758d43 DSH |
146 | else if (!strcmp(*args, "-noverify")) |
147 | noverify = 1; | |
5782ceb2 DSH |
148 | else if (!strcmp(*args, "-nonce")) |
149 | add_nonce = 2; | |
150 | else if (!strcmp(*args, "-no_nonce")) | |
151 | add_nonce = 0; | |
8c950429 DSH |
152 | else if (!strcmp(*args, "-no_certs")) |
153 | sign_flags |= OCSP_NOCERTS; | |
154 | else if (!strcmp(*args, "-no_signature_verify")) | |
155 | verify_flags |= OCSP_NOSIGS; | |
156 | else if (!strcmp(*args, "-no_cert_verify")) | |
157 | verify_flags |= OCSP_NOVERIFY; | |
158 | else if (!strcmp(*args, "-no_chain")) | |
159 | verify_flags |= OCSP_NOCHAIN; | |
160 | else if (!strcmp(*args, "-no_cert_checks")) | |
161 | verify_flags |= OCSP_NOCHECKS; | |
162 | else if (!strcmp(*args, "-no_explicit")) | |
163 | verify_flags |= OCSP_NOEXPLICIT; | |
164 | else if (!strcmp(*args, "-trust_other")) | |
165 | verify_flags |= OCSP_TRUSTOTHER; | |
166 | else if (!strcmp(*args, "-no_intern")) | |
167 | verify_flags |= OCSP_NOINTERN; | |
5782ceb2 DSH |
168 | else if (!strcmp(*args, "-text")) |
169 | { | |
170 | req_text = 1; | |
171 | resp_text = 1; | |
172 | } | |
173 | else if (!strcmp(*args, "-req_text")) | |
174 | req_text = 1; | |
175 | else if (!strcmp(*args, "-resp_text")) | |
176 | resp_text = 1; | |
177 | else if (!strcmp(*args, "-reqin")) | |
178 | { | |
179 | if (args[1]) | |
180 | { | |
181 | args++; | |
182 | reqin = *args; | |
183 | } | |
184 | else badarg = 1; | |
185 | } | |
186 | else if (!strcmp(*args, "-respin")) | |
187 | { | |
188 | if (args[1]) | |
189 | { | |
190 | args++; | |
191 | respin = *args; | |
192 | } | |
193 | else badarg = 1; | |
194 | } | |
195 | else if (!strcmp(*args, "-signer")) | |
196 | { | |
197 | if (args[1]) | |
198 | { | |
199 | args++; | |
200 | signfile = *args; | |
201 | } | |
202 | else badarg = 1; | |
203 | } | |
9235adbf RL |
204 | else if (!strcmp (*args, "-VAfile")) |
205 | { | |
206 | if (args[1]) | |
207 | { | |
208 | args++; | |
8c950429 DSH |
209 | verify_certfile = *args; |
210 | verify_flags |= OCSP_TRUSTOTHER; | |
211 | } | |
212 | else badarg = 1; | |
213 | } | |
214 | else if (!strcmp(*args, "-sign_other")) | |
215 | { | |
216 | if (args[1]) | |
217 | { | |
218 | args++; | |
219 | sign_certfile = *args; | |
220 | } | |
221 | else badarg = 1; | |
222 | } | |
223 | else if (!strcmp(*args, "-verify_other")) | |
224 | { | |
225 | if (args[1]) | |
226 | { | |
227 | args++; | |
228 | verify_certfile = *args; | |
9235adbf RL |
229 | } |
230 | else badarg = 1; | |
231 | } | |
81f169e9 DSH |
232 | else if (!strcmp (*args, "-CAfile")) |
233 | { | |
234 | if (args[1]) | |
235 | { | |
236 | args++; | |
237 | CAfile = *args; | |
238 | } | |
239 | else badarg = 1; | |
240 | } | |
241 | else if (!strcmp (*args, "-CApath")) | |
242 | { | |
243 | if (args[1]) | |
244 | { | |
245 | args++; | |
246 | CApath = *args; | |
247 | } | |
248 | else badarg = 1; | |
249 | } | |
5782ceb2 DSH |
250 | else if (!strcmp(*args, "-signkey")) |
251 | { | |
252 | if (args[1]) | |
253 | { | |
254 | args++; | |
255 | keyfile = *args; | |
256 | } | |
257 | else badarg = 1; | |
258 | } | |
259 | else if (!strcmp(*args, "-reqout")) | |
260 | { | |
261 | if (args[1]) | |
262 | { | |
263 | args++; | |
264 | reqout = *args; | |
265 | } | |
266 | else badarg = 1; | |
267 | } | |
268 | else if (!strcmp(*args, "-respout")) | |
269 | { | |
270 | if (args[1]) | |
271 | { | |
272 | args++; | |
273 | respout = *args; | |
274 | } | |
275 | else badarg = 1; | |
276 | } | |
277 | else if (!strcmp(*args, "-path")) | |
278 | { | |
279 | if (args[1]) | |
280 | { | |
281 | args++; | |
282 | path = *args; | |
283 | } | |
284 | else badarg = 1; | |
285 | } | |
286 | else if (!strcmp(*args, "-issuer")) | |
287 | { | |
288 | if (args[1]) | |
289 | { | |
290 | args++; | |
291 | X509_free(issuer); | |
292 | issuer = load_cert(bio_err, *args, FORMAT_PEM); | |
293 | if(!issuer) goto end; | |
294 | } | |
295 | else badarg = 1; | |
296 | } | |
297 | else if (!strcmp (*args, "-cert")) | |
298 | { | |
299 | if (args[1]) | |
300 | { | |
301 | args++; | |
302 | X509_free(cert); | |
303 | cert = load_cert(bio_err, *args, FORMAT_PEM); | |
304 | if(!cert) goto end; | |
73758d43 DSH |
305 | if(!add_ocsp_cert(&req, cert, issuer, ids)) |
306 | goto end; | |
307 | if(!sk_push(reqnames, *args)) | |
5782ceb2 DSH |
308 | goto end; |
309 | } | |
310 | else badarg = 1; | |
311 | } | |
312 | else if (!strcmp(*args, "-serial")) | |
313 | { | |
314 | if (args[1]) | |
315 | { | |
316 | args++; | |
73758d43 DSH |
317 | if(!add_ocsp_serial(&req, *args, issuer, ids)) |
318 | goto end; | |
319 | if(!sk_push(reqnames, *args)) | |
5782ceb2 DSH |
320 | goto end; |
321 | } | |
322 | else badarg = 1; | |
323 | } | |
324 | else badarg = 1; | |
325 | args++; | |
326 | } | |
327 | ||
328 | /* Have we anything to do? */ | |
329 | if (!req && !reqin && !respin) badarg = 1; | |
330 | ||
331 | if (badarg) | |
332 | { | |
333 | BIO_printf (bio_err, "OCSP utility\n"); | |
334 | BIO_printf (bio_err, "Usage ocsp [options]\n"); | |
335 | BIO_printf (bio_err, "where options are\n"); | |
8c950429 DSH |
336 | BIO_printf (bio_err, "-out file output filename\n"); |
337 | BIO_printf (bio_err, "-issuer file issuer certificate\n"); | |
338 | BIO_printf (bio_err, "-cert file certificate to check\n"); | |
339 | BIO_printf (bio_err, "-serial n serial number to check\n"); | |
340 | BIO_printf (bio_err, "-signer file certificate to sign OCSP request with\n"); | |
341 | BIO_printf (bio_err, "-signkey file private key to sign OCSP request with\n"); | |
b3f2e399 DSH |
342 | BIO_printf (bio_err, "-sign_certs file additional certificates to include in signed request\n"); |
343 | BIO_printf (bio_err, "-no_certs don't include any certificates in signed request\n"); | |
8c950429 DSH |
344 | BIO_printf (bio_err, "-req_text print text form of request\n"); |
345 | BIO_printf (bio_err, "-resp_text print text form of response\n"); | |
346 | BIO_printf (bio_err, "-text print text form of request and response\n"); | |
347 | BIO_printf (bio_err, "-reqout file write DER encoded OCSP request to \"file\"\n"); | |
348 | BIO_printf (bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n"); | |
349 | BIO_printf (bio_err, "-reqin file read DER encoded OCSP request from \"file\"\n"); | |
350 | BIO_printf (bio_err, "-respin file read DER encoded OCSP reponse from \"file\"\n"); | |
351 | BIO_printf (bio_err, "-nonce add OCSP nonce to request\n"); | |
352 | BIO_printf (bio_err, "-no_nonce don't add OCSP nonce to request\n"); | |
67c18019 | 353 | BIO_printf (bio_err, "-url URL OCSP responder URL\n"); |
8c950429 DSH |
354 | BIO_printf (bio_err, "-host host:n send OCSP request to host on port n\n"); |
355 | BIO_printf (bio_err, "-path path to use in OCSP request\n"); | |
356 | BIO_printf (bio_err, "-CApath dir trusted certificates directory\n"); | |
357 | BIO_printf (bio_err, "-CAfile file trusted certificates file\n"); | |
358 | BIO_printf (bio_err, "-VAfile file validator certificates file\n"); | |
359 | BIO_printf (bio_err, "-noverify don't verify response at all\n"); | |
b3f2e399 DSH |
360 | BIO_printf (bio_err, "-verify_certs file additional certificates to search for signer\n"); |
361 | BIO_printf (bio_err, "-trust_other don't verify additional certificates\n"); | |
362 | BIO_printf (bio_err, "-no_intern don't search certificates contained in response for signer\n"); | |
363 | BIO_printf (bio_err, "-no_sig_verify don't check signature on response\n"); | |
364 | BIO_printf (bio_err, "-no_cert_verify don't check signing certificate\n"); | |
365 | BIO_printf (bio_err, "-no_chain don't chain verify response\n"); | |
366 | BIO_printf (bio_err, "-no_cert_checks don't do additional checks on signing certificate\n"); | |
5782ceb2 DSH |
367 | goto end; |
368 | } | |
369 | ||
370 | if(outfile) out = BIO_new_file(outfile, "w"); | |
371 | else out = BIO_new_fp(stdout, BIO_NOCLOSE); | |
372 | ||
373 | if(!out) | |
374 | { | |
375 | BIO_printf(bio_err, "Error opening output file\n"); | |
376 | goto end; | |
377 | } | |
378 | ||
379 | if (!req && (add_nonce != 2)) add_nonce = 0; | |
380 | ||
381 | if (!req && reqin) | |
382 | { | |
383 | derbio = BIO_new_file(reqin, "rb"); | |
384 | if (!derbio) | |
385 | { | |
386 | BIO_printf(bio_err, "Error Opening OCSP request file\n"); | |
387 | goto end; | |
388 | } | |
389 | req = d2i_OCSP_REQUEST_bio(derbio, NULL); | |
390 | BIO_free(derbio); | |
391 | if(!req) | |
392 | { | |
393 | BIO_printf(bio_err, "Error reading OCSP request\n"); | |
394 | goto end; | |
395 | } | |
396 | } | |
397 | ||
398 | if (!req && (signfile || reqout || host || add_nonce)) | |
399 | { | |
400 | BIO_printf(bio_err, "Need an OCSP request for this operation!\n"); | |
401 | goto end; | |
402 | } | |
403 | ||
73758d43 | 404 | if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1); |
5782ceb2 DSH |
405 | |
406 | if (signfile) | |
407 | { | |
408 | if (!keyfile) keyfile = signfile; | |
409 | signer = load_cert(bio_err, signfile, FORMAT_PEM); | |
410 | if (!signer) | |
411 | { | |
412 | BIO_printf(bio_err, "Error loading signer certificate\n"); | |
413 | goto end; | |
414 | } | |
8c950429 DSH |
415 | if (sign_certfile) |
416 | { | |
417 | sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM); | |
418 | if (!sign_other) goto end; | |
419 | } | |
5782ceb2 DSH |
420 | key = load_key(bio_err, keyfile, FORMAT_PEM, NULL, NULL); |
421 | if (!key) | |
422 | { | |
423 | BIO_printf(bio_err, "Error loading signer private key\n"); | |
424 | goto end; | |
425 | } | |
8c950429 | 426 | if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags)) |
5782ceb2 DSH |
427 | { |
428 | BIO_printf(bio_err, "Error signing OCSP request\n"); | |
429 | goto end; | |
430 | } | |
431 | } | |
432 | ||
433 | if (reqout) | |
434 | { | |
435 | derbio = BIO_new_file(reqout, "wb"); | |
436 | if (!derbio) | |
437 | { | |
438 | BIO_printf(bio_err, "Error opening file %s\n", reqout); | |
439 | goto end; | |
440 | } | |
441 | i2d_OCSP_REQUEST_bio(derbio, req); | |
442 | BIO_free(derbio); | |
443 | } | |
444 | ||
445 | if (req_text && req) OCSP_REQUEST_print(out, req, 0); | |
446 | ||
447 | if (host) | |
448 | { | |
449 | cbio = BIO_new_connect(host); | |
450 | if (!cbio) | |
451 | { | |
452 | BIO_printf(bio_err, "Error creating connect BIO\n"); | |
453 | goto end; | |
454 | } | |
67c18019 | 455 | if (port) BIO_set_conn_port(cbio, port); |
cdc7b8cc DSH |
456 | if (use_ssl == 1) |
457 | { | |
458 | BIO *sbio; | |
459 | ctx = SSL_CTX_new(SSLv23_client_method()); | |
460 | SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); | |
461 | sbio = BIO_new_ssl(ctx, 1); | |
462 | cbio = BIO_push(sbio, cbio); | |
463 | } | |
5782ceb2 DSH |
464 | if (BIO_do_connect(cbio) <= 0) |
465 | { | |
466 | BIO_printf(bio_err, "Error connecting BIO\n"); | |
467 | goto end; | |
468 | } | |
469 | resp = OCSP_sendreq_bio(cbio, path, req); | |
cdc7b8cc | 470 | BIO_free_all(cbio); |
5782ceb2 DSH |
471 | cbio = NULL; |
472 | if (!resp) | |
473 | { | |
474 | BIO_printf(bio_err, "Error querying OCSP responsder\n"); | |
475 | goto end; | |
476 | } | |
477 | } | |
478 | else if (respin) | |
479 | { | |
480 | derbio = BIO_new_file(respin, "rb"); | |
481 | if (!derbio) | |
482 | { | |
483 | BIO_printf(bio_err, "Error Opening OCSP response file\n"); | |
484 | goto end; | |
485 | } | |
486 | resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); | |
487 | BIO_free(derbio); | |
488 | if(!resp) | |
489 | { | |
490 | BIO_printf(bio_err, "Error reading OCSP response\n"); | |
491 | goto end; | |
492 | } | |
493 | ||
494 | } | |
495 | else | |
496 | { | |
497 | ret = 0; | |
498 | goto end; | |
499 | } | |
500 | ||
501 | if (respout) | |
502 | { | |
503 | derbio = BIO_new_file(respout, "wb"); | |
504 | if(!derbio) | |
505 | { | |
506 | BIO_printf(bio_err, "Error opening file %s\n", respout); | |
507 | goto end; | |
508 | } | |
509 | i2d_OCSP_RESPONSE_bio(derbio, resp); | |
510 | BIO_free(derbio); | |
511 | } | |
512 | ||
73758d43 DSH |
513 | i = OCSP_response_status(resp); |
514 | ||
515 | if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) | |
516 | { | |
517 | BIO_printf(out, "Responder Error: %s (%ld)\n", | |
518 | OCSP_response_status_str(i), i); | |
519 | ret = 0; | |
520 | goto end; | |
521 | } | |
522 | ||
5782ceb2 DSH |
523 | if (resp_text) OCSP_RESPONSE_print(out, resp, 0); |
524 | ||
81f169e9 DSH |
525 | store = setup_verify(bio_err, CAfile, CApath); |
526 | if(!store) goto end; | |
8c950429 DSH |
527 | if (verify_certfile) |
528 | { | |
529 | verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM); | |
530 | if (!verify_other) goto end; | |
531 | } | |
9235adbf | 532 | |
81f169e9 DSH |
533 | bs = OCSP_response_get1_basic(resp); |
534 | ||
73758d43 DSH |
535 | if (!bs) |
536 | { | |
537 | BIO_printf(bio_err, "Error parsing response\n"); | |
538 | goto end; | |
539 | } | |
81f169e9 | 540 | |
73758d43 | 541 | if (!noverify) |
81f169e9 | 542 | { |
46a58ab9 | 543 | if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) |
73758d43 | 544 | { |
46a58ab9 DSH |
545 | if (i == -1) |
546 | BIO_printf(bio_err, "WARNING: no nonce in response\n"); | |
547 | else | |
548 | { | |
549 | BIO_printf(bio_err, "Nonce Verify error\n"); | |
550 | goto end; | |
551 | } | |
73758d43 DSH |
552 | } |
553 | ||
8c950429 | 554 | i = OCSP_basic_verify(bs, verify_other, store, verify_flags); |
9235adbf | 555 | if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0); |
73758d43 DSH |
556 | |
557 | if(i <= 0) | |
558 | { | |
559 | BIO_printf(bio_err, "Response Verify Failure\n", i); | |
560 | ERR_print_errors(bio_err); | |
561 | } | |
562 | else | |
563 | BIO_printf(bio_err, "Response verify OK\n"); | |
564 | ||
81f169e9 | 565 | } |
73758d43 DSH |
566 | |
567 | if (!print_ocsp_summary(out, bs, req, reqnames, ids)) | |
568 | goto end; | |
81f169e9 | 569 | |
5782ceb2 DSH |
570 | ret = 0; |
571 | ||
572 | end: | |
573 | ERR_print_errors(bio_err); | |
574 | X509_free(signer); | |
81f169e9 | 575 | X509_STORE_free(store); |
5782ceb2 DSH |
576 | EVP_PKEY_free(key); |
577 | X509_free(issuer); | |
578 | X509_free(cert); | |
cdc7b8cc | 579 | BIO_free_all(cbio); |
5782ceb2 DSH |
580 | BIO_free(out); |
581 | OCSP_REQUEST_free(req); | |
582 | OCSP_RESPONSE_free(resp); | |
81f169e9 | 583 | OCSP_BASICRESP_free(bs); |
73758d43 DSH |
584 | sk_free(reqnames); |
585 | sk_OCSP_CERTID_free(ids); | |
8c950429 DSH |
586 | sk_X509_pop_free(sign_other, X509_free); |
587 | sk_X509_pop_free(verify_other, X509_free); | |
5782ceb2 | 588 | |
67c18019 DSH |
589 | if (use_ssl != -1) |
590 | { | |
591 | OPENSSL_free(host); | |
592 | OPENSSL_free(port); | |
593 | OPENSSL_free(path); | |
cdc7b8cc | 594 | SSL_CTX_free(ctx); |
67c18019 DSH |
595 | } |
596 | ||
5782ceb2 DSH |
597 | EXIT(ret); |
598 | } | |
599 | ||
73758d43 DSH |
600 | static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer, |
601 | STACK_OF(OCSP_CERTID) *ids) | |
5782ceb2 DSH |
602 | { |
603 | OCSP_CERTID *id; | |
604 | if(!issuer) | |
605 | { | |
606 | BIO_printf(bio_err, "No issuer certificate specified\n"); | |
607 | return 0; | |
608 | } | |
609 | if(!*req) *req = OCSP_REQUEST_new(); | |
610 | if(!*req) goto err; | |
611 | id = OCSP_cert_to_id(NULL, cert, issuer); | |
73758d43 | 612 | if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err; |
5782ceb2 DSH |
613 | if(!OCSP_request_add0_id(*req, id)) goto err; |
614 | return 1; | |
615 | ||
616 | err: | |
617 | BIO_printf(bio_err, "Error Creating OCSP request\n"); | |
618 | return 0; | |
619 | } | |
620 | ||
73758d43 DSH |
621 | static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer, |
622 | STACK_OF(OCSP_CERTID) *ids) | |
5782ceb2 DSH |
623 | { |
624 | OCSP_CERTID *id; | |
625 | X509_NAME *iname; | |
626 | ASN1_BIT_STRING *ikey; | |
627 | ASN1_INTEGER *sno; | |
628 | if(!issuer) | |
629 | { | |
630 | BIO_printf(bio_err, "No issuer certificate specified\n"); | |
631 | return 0; | |
632 | } | |
633 | if(!*req) *req = OCSP_REQUEST_new(); | |
634 | if(!*req) goto err; | |
635 | iname = X509_get_subject_name(issuer); | |
88ce56f8 | 636 | ikey = X509_get0_pubkey_bitstr(issuer); |
5782ceb2 DSH |
637 | sno = s2i_ASN1_INTEGER(NULL, serial); |
638 | if(!sno) | |
639 | { | |
640 | BIO_printf(bio_err, "Error converting serial number %s\n", serial); | |
641 | return 0; | |
642 | } | |
643 | id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno); | |
644 | ASN1_INTEGER_free(sno); | |
73758d43 | 645 | if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err; |
5782ceb2 DSH |
646 | if(!OCSP_request_add0_id(*req, id)) goto err; |
647 | return 1; | |
648 | ||
649 | err: | |
650 | BIO_printf(bio_err, "Error Creating OCSP request\n"); | |
651 | return 0; | |
652 | } | |
73758d43 DSH |
653 | |
654 | static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, | |
655 | STACK *names, STACK_OF(OCSP_CERTID) *ids) | |
656 | { | |
657 | OCSP_CERTID *id; | |
658 | char *name; | |
659 | int i; | |
660 | ||
661 | int status, reason; | |
662 | ||
663 | ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; | |
664 | ||
665 | if (!bs || !req || !sk_num(names) || !sk_OCSP_CERTID_num(ids)) | |
666 | return 1; | |
667 | ||
668 | for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) | |
669 | { | |
670 | id = sk_OCSP_CERTID_value(ids, i); | |
671 | name = sk_value(names, i); | |
672 | BIO_printf(out, "%s: ", name); | |
673 | ||
674 | if(!OCSP_resp_find_status(bs, id, &status, &reason, | |
675 | &rev, &thisupd, &nextupd)) | |
676 | { | |
677 | BIO_puts(out, "ERROR: No Status found.\n"); | |
678 | continue; | |
679 | } | |
680 | BIO_printf(out, "%s\n", OCSP_cert_status_str(status)); | |
681 | ||
682 | BIO_puts(out, "\tThis Update: "); | |
683 | ASN1_GENERALIZEDTIME_print(out, thisupd); | |
684 | BIO_puts(out, "\n"); | |
685 | ||
686 | if(nextupd) | |
687 | { | |
688 | BIO_puts(out, "\tNext Update: "); | |
689 | ASN1_GENERALIZEDTIME_print(out, thisupd); | |
690 | BIO_puts(out, "\n"); | |
691 | } | |
692 | ||
693 | if (status != V_OCSP_CERTSTATUS_REVOKED) | |
694 | continue; | |
695 | ||
8e8972bb | 696 | if (reason != -1) |
73758d43 DSH |
697 | BIO_printf(out, "\tReason: %s\n", |
698 | OCSP_crl_reason_str(reason)); | |
699 | ||
700 | BIO_puts(out, "\tRevocation Time: "); | |
701 | ASN1_GENERALIZEDTIME_print(out, rev); | |
702 | BIO_puts(out, "\n"); | |
703 | } | |
704 | ||
705 | return 1; | |
706 | } | |
707 |