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