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