]> git.ipfire.org Git - thirdparty/openssl.git/blob - apps/ocsp.c
More type-checking.
[thirdparty/openssl.git] / apps / ocsp.c
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 #ifndef OPENSSL_NO_OCSP
59
60 #include <stdio.h>
61 #include <stdlib.h>
62 #include <string.h>
63 #include <time.h>
64 #include "apps.h" /* needs to be included before the openssl headers! */
65 #include <openssl/e_os2.h>
66 #include <openssl/crypto.h>
67 #include <openssl/err.h>
68 #include <openssl/ssl.h>
69 #include <openssl/evp.h>
70 #include <openssl/bn.h>
71
72 #if defined(NETWARE_CLIB)
73 # ifdef NETWARE_BSDSOCK
74 # include <sys/socket.h>
75 # include <sys/bsdskt.h>
76 # else
77 # include <novsock2.h>
78 # endif
79 #elif defined(NETWARE_LIBC)
80 # ifdef NETWARE_BSDSOCK
81 # include <sys/select.h>
82 # else
83 # include <novsock2.h>
84 # endif
85 #endif
86
87 /* Maximum leeway in validity period: default 5 minutes */
88 #define MAX_VALIDITY_PERIOD (5 * 60)
89
90 static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md, X509 *issuer,
91 STACK_OF(OCSP_CERTID) *ids);
92 static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, const EVP_MD * cert_id_md, X509 *issuer,
93 STACK_OF(OCSP_CERTID) *ids);
94 static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
95 STACK_OF(STRING) *names,
96 STACK_OF(OCSP_CERTID) *ids, long nsec,
97 long maxage);
98
99 static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
100 X509 *ca, X509 *rcert, EVP_PKEY *rkey,
101 STACK_OF(X509) *rother, unsigned long flags,
102 int nmin, int ndays);
103
104 static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
105 static BIO *init_responder(char *port);
106 static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port);
107 static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
108 static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
109 OCSP_REQUEST *req, int req_timeout);
110
111 #undef PROG
112 #define PROG ocsp_main
113
114 int MAIN(int, char **);
115
116 int MAIN(int argc, char **argv)
117 {
118 ENGINE *e = NULL;
119 char **args;
120 char *host = NULL, *port = NULL, *path = "/";
121 char *reqin = NULL, *respin = NULL;
122 char *reqout = NULL, *respout = NULL;
123 char *signfile = NULL, *keyfile = NULL;
124 char *rsignfile = NULL, *rkeyfile = NULL;
125 char *outfile = NULL;
126 int add_nonce = 1, noverify = 0, use_ssl = -1;
127 OCSP_REQUEST *req = NULL;
128 OCSP_RESPONSE *resp = NULL;
129 OCSP_BASICRESP *bs = NULL;
130 X509 *issuer = NULL, *cert = NULL;
131 X509 *signer = NULL, *rsigner = NULL;
132 EVP_PKEY *key = NULL, *rkey = NULL;
133 BIO *acbio = NULL, *cbio = NULL;
134 BIO *derbio = NULL;
135 BIO *out = NULL;
136 int req_timeout = -1;
137 int req_text = 0, resp_text = 0;
138 long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
139 char *CAfile = NULL, *CApath = NULL;
140 X509_STORE *store = NULL;
141 STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
142 char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
143 unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
144 int ret = 1;
145 int accept_count = -1;
146 int badarg = 0;
147 int i;
148 int ignore_err = 0;
149 STACK_OF(STRING) *reqnames = NULL;
150 STACK_OF(OCSP_CERTID) *ids = NULL;
151
152 X509 *rca_cert = NULL;
153 char *ridx_filename = NULL;
154 char *rca_filename = NULL;
155 CA_DB *rdb = NULL;
156 int nmin = 0, ndays = -1;
157 const EVP_MD *cert_id_md = NULL;
158
159 if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
160
161 if (!load_config(bio_err, NULL))
162 goto end;
163 SSL_load_error_strings();
164 OpenSSL_add_ssl_algorithms();
165 args = argv + 1;
166 reqnames = sk_STRING_new_null();
167 ids = sk_OCSP_CERTID_new_null();
168 while (!badarg && *args && *args[0] == '-')
169 {
170 if (!strcmp(*args, "-out"))
171 {
172 if (args[1])
173 {
174 args++;
175 outfile = *args;
176 }
177 else badarg = 1;
178 }
179 else if (!strcmp(*args, "-timeout"))
180 {
181 if (args[1])
182 {
183 args++;
184 req_timeout = atol(*args);
185 if (req_timeout < 0)
186 {
187 BIO_printf(bio_err,
188 "Illegal timeout value %s\n",
189 *args);
190 badarg = 1;
191 }
192 }
193 else badarg = 1;
194 }
195 else if (!strcmp(*args, "-url"))
196 {
197 if (args[1])
198 {
199 args++;
200 if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl))
201 {
202 BIO_printf(bio_err, "Error parsing URL\n");
203 badarg = 1;
204 }
205 }
206 else badarg = 1;
207 }
208 else if (!strcmp(*args, "-host"))
209 {
210 if (args[1])
211 {
212 args++;
213 host = *args;
214 }
215 else badarg = 1;
216 }
217 else if (!strcmp(*args, "-port"))
218 {
219 if (args[1])
220 {
221 args++;
222 port = *args;
223 }
224 else badarg = 1;
225 }
226 else if (!strcmp(*args, "-ignore_err"))
227 ignore_err = 1;
228 else if (!strcmp(*args, "-noverify"))
229 noverify = 1;
230 else if (!strcmp(*args, "-nonce"))
231 add_nonce = 2;
232 else if (!strcmp(*args, "-no_nonce"))
233 add_nonce = 0;
234 else if (!strcmp(*args, "-resp_no_certs"))
235 rflags |= OCSP_NOCERTS;
236 else if (!strcmp(*args, "-resp_key_id"))
237 rflags |= OCSP_RESPID_KEY;
238 else if (!strcmp(*args, "-no_certs"))
239 sign_flags |= OCSP_NOCERTS;
240 else if (!strcmp(*args, "-no_signature_verify"))
241 verify_flags |= OCSP_NOSIGS;
242 else if (!strcmp(*args, "-no_cert_verify"))
243 verify_flags |= OCSP_NOVERIFY;
244 else if (!strcmp(*args, "-no_chain"))
245 verify_flags |= OCSP_NOCHAIN;
246 else if (!strcmp(*args, "-no_cert_checks"))
247 verify_flags |= OCSP_NOCHECKS;
248 else if (!strcmp(*args, "-no_explicit"))
249 verify_flags |= OCSP_NOEXPLICIT;
250 else if (!strcmp(*args, "-trust_other"))
251 verify_flags |= OCSP_TRUSTOTHER;
252 else if (!strcmp(*args, "-no_intern"))
253 verify_flags |= OCSP_NOINTERN;
254 else if (!strcmp(*args, "-text"))
255 {
256 req_text = 1;
257 resp_text = 1;
258 }
259 else if (!strcmp(*args, "-req_text"))
260 req_text = 1;
261 else if (!strcmp(*args, "-resp_text"))
262 resp_text = 1;
263 else if (!strcmp(*args, "-reqin"))
264 {
265 if (args[1])
266 {
267 args++;
268 reqin = *args;
269 }
270 else badarg = 1;
271 }
272 else if (!strcmp(*args, "-respin"))
273 {
274 if (args[1])
275 {
276 args++;
277 respin = *args;
278 }
279 else badarg = 1;
280 }
281 else if (!strcmp(*args, "-signer"))
282 {
283 if (args[1])
284 {
285 args++;
286 signfile = *args;
287 }
288 else badarg = 1;
289 }
290 else if (!strcmp (*args, "-VAfile"))
291 {
292 if (args[1])
293 {
294 args++;
295 verify_certfile = *args;
296 verify_flags |= OCSP_TRUSTOTHER;
297 }
298 else badarg = 1;
299 }
300 else if (!strcmp(*args, "-sign_other"))
301 {
302 if (args[1])
303 {
304 args++;
305 sign_certfile = *args;
306 }
307 else badarg = 1;
308 }
309 else if (!strcmp(*args, "-verify_other"))
310 {
311 if (args[1])
312 {
313 args++;
314 verify_certfile = *args;
315 }
316 else badarg = 1;
317 }
318 else if (!strcmp (*args, "-CAfile"))
319 {
320 if (args[1])
321 {
322 args++;
323 CAfile = *args;
324 }
325 else badarg = 1;
326 }
327 else if (!strcmp (*args, "-CApath"))
328 {
329 if (args[1])
330 {
331 args++;
332 CApath = *args;
333 }
334 else badarg = 1;
335 }
336 else if (!strcmp (*args, "-validity_period"))
337 {
338 if (args[1])
339 {
340 args++;
341 nsec = atol(*args);
342 if (nsec < 0)
343 {
344 BIO_printf(bio_err,
345 "Illegal validity period %s\n",
346 *args);
347 badarg = 1;
348 }
349 }
350 else badarg = 1;
351 }
352 else if (!strcmp (*args, "-status_age"))
353 {
354 if (args[1])
355 {
356 args++;
357 maxage = atol(*args);
358 if (maxage < 0)
359 {
360 BIO_printf(bio_err,
361 "Illegal validity age %s\n",
362 *args);
363 badarg = 1;
364 }
365 }
366 else badarg = 1;
367 }
368 else if (!strcmp(*args, "-signkey"))
369 {
370 if (args[1])
371 {
372 args++;
373 keyfile = *args;
374 }
375 else badarg = 1;
376 }
377 else if (!strcmp(*args, "-reqout"))
378 {
379 if (args[1])
380 {
381 args++;
382 reqout = *args;
383 }
384 else badarg = 1;
385 }
386 else if (!strcmp(*args, "-respout"))
387 {
388 if (args[1])
389 {
390 args++;
391 respout = *args;
392 }
393 else badarg = 1;
394 }
395 else if (!strcmp(*args, "-path"))
396 {
397 if (args[1])
398 {
399 args++;
400 path = *args;
401 }
402 else badarg = 1;
403 }
404 else if (!strcmp(*args, "-issuer"))
405 {
406 if (args[1])
407 {
408 args++;
409 X509_free(issuer);
410 issuer = load_cert(bio_err, *args, FORMAT_PEM,
411 NULL, e, "issuer certificate");
412 if(!issuer) goto end;
413 }
414 else badarg = 1;
415 }
416 else if (!strcmp (*args, "-cert"))
417 {
418 if (args[1])
419 {
420 args++;
421 X509_free(cert);
422 cert = load_cert(bio_err, *args, FORMAT_PEM,
423 NULL, e, "certificate");
424 if(!cert) goto end;
425 if (!cert_id_md) cert_id_md = EVP_sha1();
426 if(!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids))
427 goto end;
428 if(!sk_STRING_push(reqnames, *args))
429 goto end;
430 }
431 else badarg = 1;
432 }
433 else if (!strcmp(*args, "-serial"))
434 {
435 if (args[1])
436 {
437 args++;
438 if (!cert_id_md) cert_id_md = EVP_sha1();
439 if(!add_ocsp_serial(&req, *args, cert_id_md, issuer, ids))
440 goto end;
441 if(!sk_STRING_push(reqnames, *args))
442 goto end;
443 }
444 else badarg = 1;
445 }
446 else if (!strcmp(*args, "-index"))
447 {
448 if (args[1])
449 {
450 args++;
451 ridx_filename = *args;
452 }
453 else badarg = 1;
454 }
455 else if (!strcmp(*args, "-CA"))
456 {
457 if (args[1])
458 {
459 args++;
460 rca_filename = *args;
461 }
462 else badarg = 1;
463 }
464 else if (!strcmp (*args, "-nmin"))
465 {
466 if (args[1])
467 {
468 args++;
469 nmin = atol(*args);
470 if (nmin < 0)
471 {
472 BIO_printf(bio_err,
473 "Illegal update period %s\n",
474 *args);
475 badarg = 1;
476 }
477 }
478 if (ndays == -1)
479 ndays = 0;
480 else badarg = 1;
481 }
482 else if (!strcmp (*args, "-nrequest"))
483 {
484 if (args[1])
485 {
486 args++;
487 accept_count = atol(*args);
488 if (accept_count < 0)
489 {
490 BIO_printf(bio_err,
491 "Illegal accept count %s\n",
492 *args);
493 badarg = 1;
494 }
495 }
496 else badarg = 1;
497 }
498 else if (!strcmp (*args, "-ndays"))
499 {
500 if (args[1])
501 {
502 args++;
503 ndays = atol(*args);
504 if (ndays < 0)
505 {
506 BIO_printf(bio_err,
507 "Illegal update period %s\n",
508 *args);
509 badarg = 1;
510 }
511 }
512 else badarg = 1;
513 }
514 else if (!strcmp(*args, "-rsigner"))
515 {
516 if (args[1])
517 {
518 args++;
519 rsignfile = *args;
520 }
521 else badarg = 1;
522 }
523 else if (!strcmp(*args, "-rkey"))
524 {
525 if (args[1])
526 {
527 args++;
528 rkeyfile = *args;
529 }
530 else badarg = 1;
531 }
532 else if (!strcmp(*args, "-rother"))
533 {
534 if (args[1])
535 {
536 args++;
537 rcertfile = *args;
538 }
539 else badarg = 1;
540 }
541 else if ((cert_id_md = EVP_get_digestbyname((*args)+1))==NULL)
542 {
543 badarg = 1;
544 }
545 args++;
546 }
547
548 /* Have we anything to do? */
549 if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1;
550
551 if (badarg)
552 {
553 BIO_printf (bio_err, "OCSP utility\n");
554 BIO_printf (bio_err, "Usage ocsp [options]\n");
555 BIO_printf (bio_err, "where options are\n");
556 BIO_printf (bio_err, "-out file output filename\n");
557 BIO_printf (bio_err, "-issuer file issuer certificate\n");
558 BIO_printf (bio_err, "-cert file certificate to check\n");
559 BIO_printf (bio_err, "-serial n serial number to check\n");
560 BIO_printf (bio_err, "-signer file certificate to sign OCSP request with\n");
561 BIO_printf (bio_err, "-signkey file private key to sign OCSP request with\n");
562 BIO_printf (bio_err, "-sign_other file additional certificates to include in signed request\n");
563 BIO_printf (bio_err, "-no_certs don't include any certificates in signed request\n");
564 BIO_printf (bio_err, "-req_text print text form of request\n");
565 BIO_printf (bio_err, "-resp_text print text form of response\n");
566 BIO_printf (bio_err, "-text print text form of request and response\n");
567 BIO_printf (bio_err, "-reqout file write DER encoded OCSP request to \"file\"\n");
568 BIO_printf (bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n");
569 BIO_printf (bio_err, "-reqin file read DER encoded OCSP request from \"file\"\n");
570 BIO_printf (bio_err, "-respin file read DER encoded OCSP reponse from \"file\"\n");
571 BIO_printf (bio_err, "-nonce add OCSP nonce to request\n");
572 BIO_printf (bio_err, "-no_nonce don't add OCSP nonce to request\n");
573 BIO_printf (bio_err, "-url URL OCSP responder URL\n");
574 BIO_printf (bio_err, "-host host:n send OCSP request to host on port n\n");
575 BIO_printf (bio_err, "-path path to use in OCSP request\n");
576 BIO_printf (bio_err, "-CApath dir trusted certificates directory\n");
577 BIO_printf (bio_err, "-CAfile file trusted certificates file\n");
578 BIO_printf (bio_err, "-VAfile file validator certificates file\n");
579 BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
580 BIO_printf (bio_err, "-status_age n maximum status age in seconds\n");
581 BIO_printf (bio_err, "-noverify don't verify response at all\n");
582 BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n");
583 BIO_printf (bio_err, "-trust_other don't verify additional certificates\n");
584 BIO_printf (bio_err, "-no_intern don't search certificates contained in response for signer\n");
585 BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n");
586 BIO_printf (bio_err, "-no_cert_verify don't check signing certificate\n");
587 BIO_printf (bio_err, "-no_chain don't chain verify response\n");
588 BIO_printf (bio_err, "-no_cert_checks don't do additional checks on signing certificate\n");
589 BIO_printf (bio_err, "-port num port to run responder on\n");
590 BIO_printf (bio_err, "-index file certificate status index file\n");
591 BIO_printf (bio_err, "-CA file CA certificate\n");
592 BIO_printf (bio_err, "-rsigner file responder certificate to sign responses with\n");
593 BIO_printf (bio_err, "-rkey file responder key to sign responses with\n");
594 BIO_printf (bio_err, "-rother file other certificates to include in response\n");
595 BIO_printf (bio_err, "-resp_no_certs don't include any certificates in response\n");
596 BIO_printf (bio_err, "-nmin n number of minutes before next update\n");
597 BIO_printf (bio_err, "-ndays n number of days before next update\n");
598 BIO_printf (bio_err, "-resp_key_id identify reponse by signing certificate key ID\n");
599 BIO_printf (bio_err, "-nrequest n number of requests to accept (default unlimited)\n");
600 BIO_printf (bio_err, "-<dgst alg> use specified digest in the request");
601 goto end;
602 }
603
604 if(outfile) out = BIO_new_file(outfile, "w");
605 else out = BIO_new_fp(stdout, BIO_NOCLOSE);
606
607 if(!out)
608 {
609 BIO_printf(bio_err, "Error opening output file\n");
610 goto end;
611 }
612
613 if (!req && (add_nonce != 2)) add_nonce = 0;
614
615 if (!req && reqin)
616 {
617 derbio = BIO_new_file(reqin, "rb");
618 if (!derbio)
619 {
620 BIO_printf(bio_err, "Error Opening OCSP request file\n");
621 goto end;
622 }
623 req = d2i_OCSP_REQUEST_bio(derbio, NULL);
624 BIO_free(derbio);
625 if(!req)
626 {
627 BIO_printf(bio_err, "Error reading OCSP request\n");
628 goto end;
629 }
630 }
631
632 if (!req && port)
633 {
634 acbio = init_responder(port);
635 if (!acbio)
636 goto end;
637 }
638
639 if (rsignfile && !rdb)
640 {
641 if (!rkeyfile) rkeyfile = rsignfile;
642 rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,
643 NULL, e, "responder certificate");
644 if (!rsigner)
645 {
646 BIO_printf(bio_err, "Error loading responder certificate\n");
647 goto end;
648 }
649 rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,
650 NULL, e, "CA certificate");
651 if (rcertfile)
652 {
653 rother = load_certs(bio_err, rcertfile, FORMAT_PEM,
654 NULL, e, "responder other certificates");
655 if (!rother) goto end;
656 }
657 rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL,
658 "responder private key");
659 if (!rkey)
660 goto end;
661 }
662 if(acbio)
663 BIO_printf(bio_err, "Waiting for OCSP client connections...\n");
664
665 redo_accept:
666
667 if (acbio)
668 {
669 if (!do_responder(&req, &cbio, acbio, port))
670 goto end;
671 if (!req)
672 {
673 resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
674 send_ocsp_response(cbio, resp);
675 goto done_resp;
676 }
677 }
678
679 if (!req && (signfile || reqout || host || add_nonce || ridx_filename))
680 {
681 BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
682 goto end;
683 }
684
685 if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1);
686
687 if (signfile)
688 {
689 if (!keyfile) keyfile = signfile;
690 signer = load_cert(bio_err, signfile, FORMAT_PEM,
691 NULL, e, "signer certificate");
692 if (!signer)
693 {
694 BIO_printf(bio_err, "Error loading signer certificate\n");
695 goto end;
696 }
697 if (sign_certfile)
698 {
699 sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,
700 NULL, e, "signer certificates");
701 if (!sign_other) goto end;
702 }
703 key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL,
704 "signer private key");
705 if (!key)
706 goto end;
707
708 if (!OCSP_request_sign(req, signer, key, NULL, sign_other, sign_flags))
709 {
710 BIO_printf(bio_err, "Error signing OCSP request\n");
711 goto end;
712 }
713 }
714
715 if (req_text && req) OCSP_REQUEST_print(out, req, 0);
716
717 if (reqout)
718 {
719 derbio = BIO_new_file(reqout, "wb");
720 if(!derbio)
721 {
722 BIO_printf(bio_err, "Error opening file %s\n", reqout);
723 goto end;
724 }
725 i2d_OCSP_REQUEST_bio(derbio, req);
726 BIO_free(derbio);
727 }
728
729 if (ridx_filename && (!rkey || !rsigner || !rca_cert))
730 {
731 BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n");
732 goto end;
733 }
734
735 if (ridx_filename && !rdb)
736 {
737 rdb = load_index(ridx_filename, NULL);
738 if (!rdb) goto end;
739 if (!index_index(rdb)) goto end;
740 }
741
742 if (rdb)
743 {
744 i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays);
745 if (cbio)
746 send_ocsp_response(cbio, resp);
747 }
748 else if (host)
749 {
750 #ifndef OPENSSL_NO_SOCK
751 resp = process_responder(bio_err, req, host, path,
752 port, use_ssl, req_timeout);
753 if (!resp)
754 goto end;
755 #else
756 BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n");
757 goto end;
758 #endif
759 }
760 else if (respin)
761 {
762 derbio = BIO_new_file(respin, "rb");
763 if (!derbio)
764 {
765 BIO_printf(bio_err, "Error Opening OCSP response file\n");
766 goto end;
767 }
768 resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
769 BIO_free(derbio);
770 if(!resp)
771 {
772 BIO_printf(bio_err, "Error reading OCSP response\n");
773 goto end;
774 }
775
776 }
777 else
778 {
779 ret = 0;
780 goto end;
781 }
782
783 done_resp:
784
785 if (respout)
786 {
787 derbio = BIO_new_file(respout, "wb");
788 if(!derbio)
789 {
790 BIO_printf(bio_err, "Error opening file %s\n", respout);
791 goto end;
792 }
793 i2d_OCSP_RESPONSE_bio(derbio, resp);
794 BIO_free(derbio);
795 }
796
797 i = OCSP_response_status(resp);
798
799 if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL)
800 {
801 BIO_printf(out, "Responder Error: %s (%d)\n",
802 OCSP_response_status_str(i), i);
803 if (ignore_err)
804 goto redo_accept;
805 ret = 0;
806 goto end;
807 }
808
809 if (resp_text) OCSP_RESPONSE_print(out, resp, 0);
810
811 /* If running as responder don't verify our own response */
812 if (cbio)
813 {
814 if (accept_count > 0)
815 accept_count--;
816 /* Redo if more connections needed */
817 if (accept_count)
818 {
819 BIO_free_all(cbio);
820 cbio = NULL;
821 OCSP_REQUEST_free(req);
822 req = NULL;
823 OCSP_RESPONSE_free(resp);
824 resp = NULL;
825 goto redo_accept;
826 }
827 goto end;
828 }
829
830 if (!store)
831 store = setup_verify(bio_err, CAfile, CApath);
832 if (!store)
833 goto end;
834 if (verify_certfile)
835 {
836 verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,
837 NULL, e, "validator certificate");
838 if (!verify_other) goto end;
839 }
840
841 bs = OCSP_response_get1_basic(resp);
842
843 if (!bs)
844 {
845 BIO_printf(bio_err, "Error parsing response\n");
846 goto end;
847 }
848
849 if (!noverify)
850 {
851 if (req && ((i = OCSP_check_nonce(req, bs)) <= 0))
852 {
853 if (i == -1)
854 BIO_printf(bio_err, "WARNING: no nonce in response\n");
855 else
856 {
857 BIO_printf(bio_err, "Nonce Verify error\n");
858 goto end;
859 }
860 }
861
862 i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
863 if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0);
864
865 if(i <= 0)
866 {
867 BIO_printf(bio_err, "Response Verify Failure\n");
868 ERR_print_errors(bio_err);
869 }
870 else
871 BIO_printf(bio_err, "Response verify OK\n");
872
873 }
874
875 if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage))
876 goto end;
877
878 ret = 0;
879
880 end:
881 ERR_print_errors(bio_err);
882 X509_free(signer);
883 X509_STORE_free(store);
884 EVP_PKEY_free(key);
885 EVP_PKEY_free(rkey);
886 X509_free(issuer);
887 X509_free(cert);
888 X509_free(rsigner);
889 X509_free(rca_cert);
890 free_index(rdb);
891 BIO_free_all(cbio);
892 BIO_free_all(acbio);
893 BIO_free(out);
894 OCSP_REQUEST_free(req);
895 OCSP_RESPONSE_free(resp);
896 OCSP_BASICRESP_free(bs);
897 sk_STRING_free(reqnames);
898 sk_OCSP_CERTID_free(ids);
899 sk_X509_pop_free(sign_other, X509_free);
900 sk_X509_pop_free(verify_other, X509_free);
901
902 if (use_ssl != -1)
903 {
904 OPENSSL_free(host);
905 OPENSSL_free(port);
906 OPENSSL_free(path);
907 }
908
909 OPENSSL_EXIT(ret);
910 }
911
912 static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md,X509 *issuer,
913 STACK_OF(OCSP_CERTID) *ids)
914 {
915 OCSP_CERTID *id;
916 if(!issuer)
917 {
918 BIO_printf(bio_err, "No issuer certificate specified\n");
919 return 0;
920 }
921 if(!*req) *req = OCSP_REQUEST_new();
922 if(!*req) goto err;
923 id = OCSP_cert_to_id(cert_id_md, cert, issuer);
924 if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
925 if(!OCSP_request_add0_id(*req, id)) goto err;
926 return 1;
927
928 err:
929 BIO_printf(bio_err, "Error Creating OCSP request\n");
930 return 0;
931 }
932
933 static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,const EVP_MD *cert_id_md, X509 *issuer,
934 STACK_OF(OCSP_CERTID) *ids)
935 {
936 OCSP_CERTID *id;
937 X509_NAME *iname;
938 ASN1_BIT_STRING *ikey;
939 ASN1_INTEGER *sno;
940 if(!issuer)
941 {
942 BIO_printf(bio_err, "No issuer certificate specified\n");
943 return 0;
944 }
945 if(!*req) *req = OCSP_REQUEST_new();
946 if(!*req) goto err;
947 iname = X509_get_subject_name(issuer);
948 ikey = X509_get0_pubkey_bitstr(issuer);
949 sno = s2i_ASN1_INTEGER(NULL, serial);
950 if(!sno)
951 {
952 BIO_printf(bio_err, "Error converting serial number %s\n", serial);
953 return 0;
954 }
955 id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno);
956 ASN1_INTEGER_free(sno);
957 if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
958 if(!OCSP_request_add0_id(*req, id)) goto err;
959 return 1;
960
961 err:
962 BIO_printf(bio_err, "Error Creating OCSP request\n");
963 return 0;
964 }
965
966 static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
967 STACK_OF(STRING) *names,
968 STACK_OF(OCSP_CERTID) *ids, long nsec,
969 long maxage)
970 {
971 OCSP_CERTID *id;
972 char *name;
973 int i;
974
975 int status, reason;
976
977 ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
978
979 if (!bs || !req || !sk_STRING_num(names) || !sk_OCSP_CERTID_num(ids))
980 return 1;
981
982 for (i = 0; i < sk_OCSP_CERTID_num(ids); i++)
983 {
984 id = sk_OCSP_CERTID_value(ids, i);
985 name = sk_STRING_value(names, i);
986 BIO_printf(out, "%s: ", name);
987
988 if(!OCSP_resp_find_status(bs, id, &status, &reason,
989 &rev, &thisupd, &nextupd))
990 {
991 BIO_puts(out, "ERROR: No Status found.\n");
992 continue;
993 }
994
995 /* Check validity: if invalid write to output BIO so we
996 * know which response this refers to.
997 */
998 if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage))
999 {
1000 BIO_puts(out, "WARNING: Status times invalid.\n");
1001 ERR_print_errors(out);
1002 }
1003 BIO_printf(out, "%s\n", OCSP_cert_status_str(status));
1004
1005 BIO_puts(out, "\tThis Update: ");
1006 ASN1_GENERALIZEDTIME_print(out, thisupd);
1007 BIO_puts(out, "\n");
1008
1009 if(nextupd)
1010 {
1011 BIO_puts(out, "\tNext Update: ");
1012 ASN1_GENERALIZEDTIME_print(out, nextupd);
1013 BIO_puts(out, "\n");
1014 }
1015
1016 if (status != V_OCSP_CERTSTATUS_REVOKED)
1017 continue;
1018
1019 if (reason != -1)
1020 BIO_printf(out, "\tReason: %s\n",
1021 OCSP_crl_reason_str(reason));
1022
1023 BIO_puts(out, "\tRevocation Time: ");
1024 ASN1_GENERALIZEDTIME_print(out, rev);
1025 BIO_puts(out, "\n");
1026 }
1027
1028 return 1;
1029 }
1030
1031
1032 static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
1033 X509 *ca, X509 *rcert, EVP_PKEY *rkey,
1034 STACK_OF(X509) *rother, unsigned long flags,
1035 int nmin, int ndays)
1036 {
1037 ASN1_TIME *thisupd = NULL, *nextupd = NULL;
1038 OCSP_CERTID *cid, *ca_id = NULL;
1039 OCSP_BASICRESP *bs = NULL;
1040 int i, id_count, ret = 1;
1041
1042 id_count = OCSP_request_onereq_count(req);
1043
1044 if (id_count <= 0)
1045 {
1046 *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
1047 goto end;
1048 }
1049
1050
1051 bs = OCSP_BASICRESP_new();
1052 thisupd = X509_gmtime_adj(NULL, 0);
1053 if (ndays != -1)
1054 nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24 );
1055
1056 /* Examine each certificate id in the request */
1057 for (i = 0; i < id_count; i++)
1058 {
1059 OCSP_ONEREQ *one;
1060 ASN1_INTEGER *serial;
1061 char **inf;
1062 ASN1_OBJECT *cert_id_md_oid;
1063 const EVP_MD *cert_id_md;
1064 one = OCSP_request_onereq_get0(req, i);
1065 cid = OCSP_onereq_get0_id(one);
1066
1067 OCSP_id_get0_info(NULL,&cert_id_md_oid, NULL,NULL, cid);
1068
1069 cert_id_md = EVP_get_digestbyobj(cert_id_md_oid);
1070 if (! cert_id_md)
1071 {
1072 *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR,
1073 NULL);
1074 goto end;
1075 }
1076 if (ca_id) OCSP_CERTID_free(ca_id);
1077 ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca);
1078
1079 /* Is this request about our CA? */
1080 if (OCSP_id_issuer_cmp(ca_id, cid))
1081 {
1082 OCSP_basic_add1_status(bs, cid,
1083 V_OCSP_CERTSTATUS_UNKNOWN,
1084 0, NULL,
1085 thisupd, nextupd);
1086 continue;
1087 }
1088 OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
1089 inf = lookup_serial(db, serial);
1090 if (!inf)
1091 OCSP_basic_add1_status(bs, cid,
1092 V_OCSP_CERTSTATUS_UNKNOWN,
1093 0, NULL,
1094 thisupd, nextupd);
1095 else if (inf[DB_type][0] == DB_TYPE_VAL)
1096 OCSP_basic_add1_status(bs, cid,
1097 V_OCSP_CERTSTATUS_GOOD,
1098 0, NULL,
1099 thisupd, nextupd);
1100 else if (inf[DB_type][0] == DB_TYPE_REV)
1101 {
1102 ASN1_OBJECT *inst = NULL;
1103 ASN1_TIME *revtm = NULL;
1104 ASN1_GENERALIZEDTIME *invtm = NULL;
1105 OCSP_SINGLERESP *single;
1106 int reason = -1;
1107 unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]);
1108 single = OCSP_basic_add1_status(bs, cid,
1109 V_OCSP_CERTSTATUS_REVOKED,
1110 reason, revtm,
1111 thisupd, nextupd);
1112 if (invtm)
1113 OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0);
1114 else if (inst)
1115 OCSP_SINGLERESP_add1_ext_i2d(single, NID_hold_instruction_code, inst, 0, 0);
1116 ASN1_OBJECT_free(inst);
1117 ASN1_TIME_free(revtm);
1118 ASN1_GENERALIZEDTIME_free(invtm);
1119 }
1120 }
1121
1122 OCSP_copy_nonce(bs, req);
1123
1124 OCSP_basic_sign(bs, rcert, rkey, NULL, rother, flags);
1125
1126 *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
1127
1128 end:
1129 ASN1_TIME_free(thisupd);
1130 ASN1_TIME_free(nextupd);
1131 OCSP_CERTID_free(ca_id);
1132 OCSP_BASICRESP_free(bs);
1133 return ret;
1134
1135 }
1136
1137 static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser)
1138 {
1139 int i;
1140 BIGNUM *bn = NULL;
1141 char *itmp, *row[DB_NUMBER],**rrow;
1142 for (i = 0; i < DB_NUMBER; i++) row[i] = NULL;
1143 bn = ASN1_INTEGER_to_BN(ser,NULL);
1144 OPENSSL_assert(bn); /* FIXME: should report an error at this point and abort */
1145 if (BN_is_zero(bn))
1146 itmp = BUF_strdup("00");
1147 else
1148 itmp = BN_bn2hex(bn);
1149 row[DB_serial] = itmp;
1150 BN_free(bn);
1151 rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
1152 OPENSSL_free(itmp);
1153 return rrow;
1154 }
1155
1156 /* Quick and dirty OCSP server: read in and parse input request */
1157
1158 static BIO *init_responder(char *port)
1159 {
1160 BIO *acbio = NULL, *bufbio = NULL;
1161 bufbio = BIO_new(BIO_f_buffer());
1162 if (!bufbio)
1163 goto err;
1164 #ifndef OPENSSL_NO_SOCK
1165 acbio = BIO_new_accept(port);
1166 #else
1167 BIO_printf(bio_err, "Error setting up accept BIO - sockets not supported.\n");
1168 #endif
1169 if (!acbio)
1170 goto err;
1171 BIO_set_accept_bios(acbio, bufbio);
1172 bufbio = NULL;
1173
1174 if (BIO_do_accept(acbio) <= 0)
1175 {
1176 BIO_printf(bio_err, "Error setting up accept BIO\n");
1177 ERR_print_errors(bio_err);
1178 goto err;
1179 }
1180
1181 return acbio;
1182
1183 err:
1184 BIO_free_all(acbio);
1185 BIO_free(bufbio);
1186 return NULL;
1187 }
1188
1189 static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port)
1190 {
1191 int have_post = 0, len;
1192 OCSP_REQUEST *req = NULL;
1193 char inbuf[1024];
1194 BIO *cbio = NULL;
1195
1196 if (BIO_do_accept(acbio) <= 0)
1197 {
1198 BIO_printf(bio_err, "Error accepting connection\n");
1199 ERR_print_errors(bio_err);
1200 return 0;
1201 }
1202
1203 cbio = BIO_pop(acbio);
1204 *pcbio = cbio;
1205
1206 for(;;)
1207 {
1208 len = BIO_gets(cbio, inbuf, sizeof inbuf);
1209 if (len <= 0)
1210 return 1;
1211 /* Look for "POST" signalling start of query */
1212 if (!have_post)
1213 {
1214 if(strncmp(inbuf, "POST", 4))
1215 {
1216 BIO_printf(bio_err, "Invalid request\n");
1217 return 1;
1218 }
1219 have_post = 1;
1220 }
1221 /* Look for end of headers */
1222 if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
1223 break;
1224 }
1225
1226 /* Try to read OCSP request */
1227
1228 req = d2i_OCSP_REQUEST_bio(cbio, NULL);
1229
1230 if (!req)
1231 {
1232 BIO_printf(bio_err, "Error parsing OCSP request\n");
1233 ERR_print_errors(bio_err);
1234 }
1235
1236 *preq = req;
1237
1238 return 1;
1239
1240 }
1241
1242 static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
1243 {
1244 char http_resp[] =
1245 "HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n"
1246 "Content-Length: %d\r\n\r\n";
1247 if (!cbio)
1248 return 0;
1249 BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL));
1250 i2d_OCSP_RESPONSE_bio(cbio, resp);
1251 (void)BIO_flush(cbio);
1252 return 1;
1253 }
1254
1255 static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
1256 OCSP_REQUEST *req, int req_timeout)
1257 {
1258 int fd;
1259 int rv;
1260 OCSP_REQ_CTX *ctx = NULL;
1261 OCSP_RESPONSE *rsp = NULL;
1262 fd_set confds;
1263 struct timeval tv;
1264
1265 if (req_timeout != -1)
1266 BIO_set_nbio(cbio, 1);
1267
1268 rv = BIO_do_connect(cbio);
1269
1270 if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio)))
1271 {
1272 BIO_puts(err, "Error connecting BIO\n");
1273 return NULL;
1274 }
1275
1276 if (req_timeout == -1)
1277 return OCSP_sendreq_bio(cbio, path, req);
1278
1279 if (BIO_get_fd(cbio, &fd) <= 0)
1280 {
1281 BIO_puts(err, "Can't get connection fd\n");
1282 goto err;
1283 }
1284
1285 if (rv <= 0)
1286 {
1287 FD_ZERO(&confds);
1288 openssl_fdset(fd, &confds);
1289 tv.tv_usec = 0;
1290 tv.tv_sec = req_timeout;
1291 rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
1292 if (rv == 0)
1293 {
1294 BIO_puts(err, "Timeout on connect\n");
1295 return NULL;
1296 }
1297 }
1298
1299
1300 ctx = OCSP_sendreq_new(cbio, path, req, -1);
1301 if (!ctx)
1302 return NULL;
1303
1304 for (;;)
1305 {
1306 rv = OCSP_sendreq_nbio(&rsp, ctx);
1307 if (rv != -1)
1308 break;
1309 FD_ZERO(&confds);
1310 openssl_fdset(fd, &confds);
1311 tv.tv_usec = 0;
1312 tv.tv_sec = req_timeout;
1313 if (BIO_should_read(cbio))
1314 rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv);
1315 else if (BIO_should_write(cbio))
1316 rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
1317 else
1318 {
1319 BIO_puts(err, "Unexpected retry condition\n");
1320 goto err;
1321 }
1322 if (rv == 0)
1323 {
1324 BIO_puts(err, "Timeout on request\n");
1325 break;
1326 }
1327 if (rv == -1)
1328 {
1329 BIO_puts(err, "Select error\n");
1330 break;
1331 }
1332
1333 }
1334 err:
1335 if (ctx)
1336 OCSP_REQ_CTX_free(ctx);
1337
1338 return rsp;
1339 }
1340
1341 OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
1342 char *host, char *path, char *port, int use_ssl,
1343 int req_timeout)
1344 {
1345 BIO *cbio = NULL;
1346 SSL_CTX *ctx = NULL;
1347 OCSP_RESPONSE *resp = NULL;
1348 cbio = BIO_new_connect(host);
1349 if (!cbio)
1350 {
1351 BIO_printf(err, "Error creating connect BIO\n");
1352 goto end;
1353 }
1354 if (port) BIO_set_conn_port(cbio, port);
1355 if (use_ssl == 1)
1356 {
1357 BIO *sbio;
1358 #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
1359 ctx = SSL_CTX_new(SSLv23_client_method());
1360 #elif !defined(OPENSSL_NO_SSL3)
1361 ctx = SSL_CTX_new(SSLv3_client_method());
1362 #elif !defined(OPENSSL_NO_SSL2)
1363 ctx = SSL_CTX_new(SSLv2_client_method());
1364 #else
1365 BIO_printf(err, "SSL is disabled\n");
1366 goto end;
1367 #endif
1368 if (ctx == NULL)
1369 {
1370 BIO_printf(err, "Error creating SSL context.\n");
1371 goto end;
1372 }
1373 SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
1374 sbio = BIO_new_ssl(ctx, 1);
1375 cbio = BIO_push(sbio, cbio);
1376 }
1377 resp = query_responder(err, cbio, path, req, req_timeout);
1378 if (!resp)
1379 BIO_printf(bio_err, "Error querying OCSP responsder\n");
1380 end:
1381 if (ctx)
1382 SSL_CTX_free(ctx);
1383 if (cbio)
1384 BIO_free_all(cbio);
1385 return resp;
1386 }
1387
1388 #endif