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