xref: /freebsd/crypto/openssl/apps/ocsp.c (revision 2b743a9e9ddc6736208dc8ca1ce06ce64ad20a19)
1 /* ocsp.c */
2 /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3  * project 2000.
4  */
5 /* ====================================================================
6  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58 #ifndef OPENSSL_NO_OCSP
59 
60 #include <stdio.h>
61 #include <string.h>
62 #include "apps.h"
63 #include <openssl/pem.h>
64 #include <openssl/ocsp.h>
65 #include <openssl/err.h>
66 #include <openssl/ssl.h>
67 #include <openssl/bn.h>
68 
69 /* Maximum leeway in validity period: default 5 minutes */
70 #define MAX_VALIDITY_PERIOD	(5 * 60)
71 
72 static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
73 				STACK_OF(OCSP_CERTID) *ids);
74 static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
75 				STACK_OF(OCSP_CERTID) *ids);
76 static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
77 				STACK *names, STACK_OF(OCSP_CERTID) *ids,
78 				long nsec, long maxage);
79 
80 static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
81 			X509 *ca, X509 *rcert, EVP_PKEY *rkey,
82 			STACK_OF(X509) *rother, unsigned long flags,
83 			int nmin, int ndays);
84 
85 static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
86 static BIO *init_responder(char *port);
87 static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port);
88 static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
89 
90 #undef PROG
91 #define PROG ocsp_main
92 
93 int MAIN(int, char **);
94 
95 int MAIN(int argc, char **argv)
96 	{
97 	ENGINE *e = NULL;
98 	char **args;
99 	char *host = NULL, *port = NULL, *path = "/";
100 	char *reqin = NULL, *respin = NULL;
101 	char *reqout = NULL, *respout = NULL;
102 	char *signfile = NULL, *keyfile = NULL;
103 	char *rsignfile = NULL, *rkeyfile = NULL;
104 	char *outfile = NULL;
105 	int add_nonce = 1, noverify = 0, use_ssl = -1;
106 	OCSP_REQUEST *req = NULL;
107 	OCSP_RESPONSE *resp = NULL;
108 	OCSP_BASICRESP *bs = NULL;
109 	X509 *issuer = NULL, *cert = NULL;
110 	X509 *signer = NULL, *rsigner = NULL;
111 	EVP_PKEY *key = NULL, *rkey = NULL;
112 	BIO *acbio = NULL, *cbio = NULL;
113 	BIO *derbio = NULL;
114 	BIO *out = NULL;
115 	int req_text = 0, resp_text = 0;
116 	long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
117 	char *CAfile = NULL, *CApath = NULL;
118 	X509_STORE *store = NULL;
119 	SSL_CTX *ctx = NULL;
120 	STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
121 	char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
122 	unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
123 	int ret = 1;
124 	int accept_count = -1;
125 	int badarg = 0;
126 	int i;
127 	int ignore_err = 0;
128 	STACK *reqnames = NULL;
129 	STACK_OF(OCSP_CERTID) *ids = NULL;
130 
131 	X509 *rca_cert = NULL;
132 	char *ridx_filename = NULL;
133 	char *rca_filename = NULL;
134 	CA_DB *rdb = NULL;
135 	int nmin = 0, ndays = -1;
136 
137 	if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
138 
139 	if (!load_config(bio_err, NULL))
140 		goto end;
141 	SSL_load_error_strings();
142 	args = argv + 1;
143 	reqnames = sk_new_null();
144 	ids = sk_OCSP_CERTID_new_null();
145 	while (!badarg && *args && *args[0] == '-')
146 		{
147 		if (!strcmp(*args, "-out"))
148 			{
149 			if (args[1])
150 				{
151 				args++;
152 				outfile = *args;
153 				}
154 			else badarg = 1;
155 			}
156 		else if (!strcmp(*args, "-url"))
157 			{
158 			if (args[1])
159 				{
160 				args++;
161 				if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl))
162 					{
163 					BIO_printf(bio_err, "Error parsing URL\n");
164 					badarg = 1;
165 					}
166 				}
167 			else badarg = 1;
168 			}
169 		else if (!strcmp(*args, "-host"))
170 			{
171 			if (args[1])
172 				{
173 				args++;
174 				host = *args;
175 				}
176 			else badarg = 1;
177 			}
178 		else if (!strcmp(*args, "-port"))
179 			{
180 			if (args[1])
181 				{
182 				args++;
183 				port = *args;
184 				}
185 			else badarg = 1;
186 			}
187 		else if (!strcmp(*args, "-ignore_err"))
188 			ignore_err = 1;
189 		else if (!strcmp(*args, "-noverify"))
190 			noverify = 1;
191 		else if (!strcmp(*args, "-nonce"))
192 			add_nonce = 2;
193 		else if (!strcmp(*args, "-no_nonce"))
194 			add_nonce = 0;
195 		else if (!strcmp(*args, "-resp_no_certs"))
196 			rflags |= OCSP_NOCERTS;
197 		else if (!strcmp(*args, "-resp_key_id"))
198 			rflags |= OCSP_RESPID_KEY;
199 		else if (!strcmp(*args, "-no_certs"))
200 			sign_flags |= OCSP_NOCERTS;
201 		else if (!strcmp(*args, "-no_signature_verify"))
202 			verify_flags |= OCSP_NOSIGS;
203 		else if (!strcmp(*args, "-no_cert_verify"))
204 			verify_flags |= OCSP_NOVERIFY;
205 		else if (!strcmp(*args, "-no_chain"))
206 			verify_flags |= OCSP_NOCHAIN;
207 		else if (!strcmp(*args, "-no_cert_checks"))
208 			verify_flags |= OCSP_NOCHECKS;
209 		else if (!strcmp(*args, "-no_explicit"))
210 			verify_flags |= OCSP_NOEXPLICIT;
211 		else if (!strcmp(*args, "-trust_other"))
212 			verify_flags |= OCSP_TRUSTOTHER;
213 		else if (!strcmp(*args, "-no_intern"))
214 			verify_flags |= OCSP_NOINTERN;
215 		else if (!strcmp(*args, "-text"))
216 			{
217 			req_text = 1;
218 			resp_text = 1;
219 			}
220 		else if (!strcmp(*args, "-req_text"))
221 			req_text = 1;
222 		else if (!strcmp(*args, "-resp_text"))
223 			resp_text = 1;
224 		else if (!strcmp(*args, "-reqin"))
225 			{
226 			if (args[1])
227 				{
228 				args++;
229 				reqin = *args;
230 				}
231 			else badarg = 1;
232 			}
233 		else if (!strcmp(*args, "-respin"))
234 			{
235 			if (args[1])
236 				{
237 				args++;
238 				respin = *args;
239 				}
240 			else badarg = 1;
241 			}
242 		else if (!strcmp(*args, "-signer"))
243 			{
244 			if (args[1])
245 				{
246 				args++;
247 				signfile = *args;
248 				}
249 			else badarg = 1;
250 			}
251 		else if (!strcmp (*args, "-VAfile"))
252 			{
253 			if (args[1])
254 				{
255 				args++;
256 				verify_certfile = *args;
257 				verify_flags |= OCSP_TRUSTOTHER;
258 				}
259 			else badarg = 1;
260 			}
261 		else if (!strcmp(*args, "-sign_other"))
262 			{
263 			if (args[1])
264 				{
265 				args++;
266 				sign_certfile = *args;
267 				}
268 			else badarg = 1;
269 			}
270 		else if (!strcmp(*args, "-verify_other"))
271 			{
272 			if (args[1])
273 				{
274 				args++;
275 				verify_certfile = *args;
276 				}
277 			else badarg = 1;
278 			}
279 		else if (!strcmp (*args, "-CAfile"))
280 			{
281 			if (args[1])
282 				{
283 				args++;
284 				CAfile = *args;
285 				}
286 			else badarg = 1;
287 			}
288 		else if (!strcmp (*args, "-CApath"))
289 			{
290 			if (args[1])
291 				{
292 				args++;
293 				CApath = *args;
294 				}
295 			else badarg = 1;
296 			}
297 		else if (!strcmp (*args, "-validity_period"))
298 			{
299 			if (args[1])
300 				{
301 				args++;
302 				nsec = atol(*args);
303 				if (nsec < 0)
304 					{
305 					BIO_printf(bio_err,
306 						"Illegal validity period %s\n",
307 						*args);
308 					badarg = 1;
309 					}
310 				}
311 			else badarg = 1;
312 			}
313 		else if (!strcmp (*args, "-status_age"))
314 			{
315 			if (args[1])
316 				{
317 				args++;
318 				maxage = atol(*args);
319 				if (maxage < 0)
320 					{
321 					BIO_printf(bio_err,
322 						"Illegal validity age %s\n",
323 						*args);
324 					badarg = 1;
325 					}
326 				}
327 			else badarg = 1;
328 			}
329 		 else if (!strcmp(*args, "-signkey"))
330 			{
331 			if (args[1])
332 				{
333 				args++;
334 				keyfile = *args;
335 				}
336 			else badarg = 1;
337 			}
338 		else if (!strcmp(*args, "-reqout"))
339 			{
340 			if (args[1])
341 				{
342 				args++;
343 				reqout = *args;
344 				}
345 			else badarg = 1;
346 			}
347 		else if (!strcmp(*args, "-respout"))
348 			{
349 			if (args[1])
350 				{
351 				args++;
352 				respout = *args;
353 				}
354 			else badarg = 1;
355 			}
356 		 else if (!strcmp(*args, "-path"))
357 			{
358 			if (args[1])
359 				{
360 				args++;
361 				path = *args;
362 				}
363 			else badarg = 1;
364 			}
365 		else if (!strcmp(*args, "-issuer"))
366 			{
367 			if (args[1])
368 				{
369 				args++;
370 				X509_free(issuer);
371 				issuer = load_cert(bio_err, *args, FORMAT_PEM,
372 					NULL, e, "issuer certificate");
373 				if(!issuer) goto end;
374 				}
375 			else badarg = 1;
376 			}
377 		else if (!strcmp (*args, "-cert"))
378 			{
379 			if (args[1])
380 				{
381 				args++;
382 				X509_free(cert);
383 				cert = load_cert(bio_err, *args, FORMAT_PEM,
384 					NULL, e, "certificate");
385 				if(!cert) goto end;
386 				if(!add_ocsp_cert(&req, cert, issuer, ids))
387 					goto end;
388 				if(!sk_push(reqnames, *args))
389 					goto end;
390 				}
391 			else badarg = 1;
392 			}
393 		else if (!strcmp(*args, "-serial"))
394 			{
395 			if (args[1])
396 				{
397 				args++;
398 				if(!add_ocsp_serial(&req, *args, issuer, ids))
399 					goto end;
400 				if(!sk_push(reqnames, *args))
401 					goto end;
402 				}
403 			else badarg = 1;
404 			}
405 		else if (!strcmp(*args, "-index"))
406 			{
407 			if (args[1])
408 				{
409 				args++;
410 				ridx_filename = *args;
411 				}
412 			else badarg = 1;
413 			}
414 		else if (!strcmp(*args, "-CA"))
415 			{
416 			if (args[1])
417 				{
418 				args++;
419 				rca_filename = *args;
420 				}
421 			else badarg = 1;
422 			}
423 		else if (!strcmp (*args, "-nmin"))
424 			{
425 			if (args[1])
426 				{
427 				args++;
428 				nmin = atol(*args);
429 				if (nmin < 0)
430 					{
431 					BIO_printf(bio_err,
432 						"Illegal update period %s\n",
433 						*args);
434 					badarg = 1;
435 					}
436 				}
437 				if (ndays == -1)
438 					ndays = 0;
439 			else badarg = 1;
440 			}
441 		else if (!strcmp (*args, "-nrequest"))
442 			{
443 			if (args[1])
444 				{
445 				args++;
446 				accept_count = atol(*args);
447 				if (accept_count < 0)
448 					{
449 					BIO_printf(bio_err,
450 						"Illegal accept count %s\n",
451 						*args);
452 					badarg = 1;
453 					}
454 				}
455 			else badarg = 1;
456 			}
457 		else if (!strcmp (*args, "-ndays"))
458 			{
459 			if (args[1])
460 				{
461 				args++;
462 				ndays = atol(*args);
463 				if (ndays < 0)
464 					{
465 					BIO_printf(bio_err,
466 						"Illegal update period %s\n",
467 						*args);
468 					badarg = 1;
469 					}
470 				}
471 			else badarg = 1;
472 			}
473 		else if (!strcmp(*args, "-rsigner"))
474 			{
475 			if (args[1])
476 				{
477 				args++;
478 				rsignfile = *args;
479 				}
480 			else badarg = 1;
481 			}
482 		else if (!strcmp(*args, "-rkey"))
483 			{
484 			if (args[1])
485 				{
486 				args++;
487 				rkeyfile = *args;
488 				}
489 			else badarg = 1;
490 			}
491 		else if (!strcmp(*args, "-rother"))
492 			{
493 			if (args[1])
494 				{
495 				args++;
496 				rcertfile = *args;
497 				}
498 			else badarg = 1;
499 			}
500 		else badarg = 1;
501 		args++;
502 		}
503 
504 	/* Have we anything to do? */
505 	if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1;
506 
507 	if (badarg)
508 		{
509 		BIO_printf (bio_err, "OCSP utility\n");
510 		BIO_printf (bio_err, "Usage ocsp [options]\n");
511 		BIO_printf (bio_err, "where options are\n");
512 		BIO_printf (bio_err, "-out file          output filename\n");
513 		BIO_printf (bio_err, "-issuer file       issuer certificate\n");
514 		BIO_printf (bio_err, "-cert file         certificate to check\n");
515 		BIO_printf (bio_err, "-serial n          serial number to check\n");
516 		BIO_printf (bio_err, "-signer file       certificate to sign OCSP request with\n");
517 		BIO_printf (bio_err, "-signkey file      private key to sign OCSP request with\n");
518 		BIO_printf (bio_err, "-sign_other file   additional certificates to include in signed request\n");
519 		BIO_printf (bio_err, "-no_certs          don't include any certificates in signed request\n");
520 		BIO_printf (bio_err, "-req_text          print text form of request\n");
521 		BIO_printf (bio_err, "-resp_text         print text form of response\n");
522 		BIO_printf (bio_err, "-text              print text form of request and response\n");
523 		BIO_printf (bio_err, "-reqout file       write DER encoded OCSP request to \"file\"\n");
524 		BIO_printf (bio_err, "-respout file      write DER encoded OCSP reponse to \"file\"\n");
525 		BIO_printf (bio_err, "-reqin file        read DER encoded OCSP request from \"file\"\n");
526 		BIO_printf (bio_err, "-respin file       read DER encoded OCSP reponse from \"file\"\n");
527 		BIO_printf (bio_err, "-nonce             add OCSP nonce to request\n");
528 		BIO_printf (bio_err, "-no_nonce          don't add OCSP nonce to request\n");
529 		BIO_printf (bio_err, "-url URL           OCSP responder URL\n");
530 		BIO_printf (bio_err, "-host host:n       send OCSP request to host on port n\n");
531 		BIO_printf (bio_err, "-path              path to use in OCSP request\n");
532 		BIO_printf (bio_err, "-CApath dir        trusted certificates directory\n");
533 		BIO_printf (bio_err, "-CAfile file       trusted certificates file\n");
534 		BIO_printf (bio_err, "-VAfile file       validator certificates file\n");
535 		BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
536 		BIO_printf (bio_err, "-status_age n      maximum status age in seconds\n");
537 		BIO_printf (bio_err, "-noverify          don't verify response at all\n");
538 		BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n");
539 		BIO_printf (bio_err, "-trust_other       don't verify additional certificates\n");
540 		BIO_printf (bio_err, "-no_intern         don't search certificates contained in response for signer\n");
541 		BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n");
542 		BIO_printf (bio_err, "-no_cert_verify    don't check signing certificate\n");
543 		BIO_printf (bio_err, "-no_chain          don't chain verify response\n");
544 		BIO_printf (bio_err, "-no_cert_checks    don't do additional checks on signing certificate\n");
545 		BIO_printf (bio_err, "-port num		 port to run responder on\n");
546 		BIO_printf (bio_err, "-index file	 certificate status index file\n");
547 		BIO_printf (bio_err, "-CA file		 CA certificate\n");
548 		BIO_printf (bio_err, "-rsigner file	 responder certificate to sign responses with\n");
549 		BIO_printf (bio_err, "-rkey file	 responder key to sign responses with\n");
550 		BIO_printf (bio_err, "-rother file	 other certificates to include in response\n");
551 		BIO_printf (bio_err, "-resp_no_certs     don't include any certificates in response\n");
552 		BIO_printf (bio_err, "-nmin n	 	 number of minutes before next update\n");
553 		BIO_printf (bio_err, "-ndays n	 	 number of days before next update\n");
554 		BIO_printf (bio_err, "-resp_key_id       identify reponse by signing certificate key ID\n");
555 		BIO_printf (bio_err, "-nrequest n        number of requests to accept (default unlimited)\n");
556 		goto end;
557 		}
558 
559 	if(outfile) out = BIO_new_file(outfile, "w");
560 	else out = BIO_new_fp(stdout, BIO_NOCLOSE);
561 
562 	if(!out)
563 		{
564 		BIO_printf(bio_err, "Error opening output file\n");
565 		goto end;
566 		}
567 
568 	if (!req && (add_nonce != 2)) add_nonce = 0;
569 
570 	if (!req && reqin)
571 		{
572 		derbio = BIO_new_file(reqin, "rb");
573 		if (!derbio)
574 			{
575 			BIO_printf(bio_err, "Error Opening OCSP request file\n");
576 			goto end;
577 			}
578 		req = d2i_OCSP_REQUEST_bio(derbio, NULL);
579 		BIO_free(derbio);
580 		if(!req)
581 			{
582 			BIO_printf(bio_err, "Error reading OCSP request\n");
583 			goto end;
584 			}
585 		}
586 
587 	if (!req && port)
588 		{
589 		acbio = init_responder(port);
590 		if (!acbio)
591 			goto end;
592 		}
593 
594 	if (rsignfile && !rdb)
595 		{
596 		if (!rkeyfile) rkeyfile = rsignfile;
597 		rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,
598 			NULL, e, "responder certificate");
599 		if (!rsigner)
600 			{
601 			BIO_printf(bio_err, "Error loading responder certificate\n");
602 			goto end;
603 			}
604 		rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,
605 			NULL, e, "CA certificate");
606 		if (rcertfile)
607 			{
608 			rother = load_certs(bio_err, rcertfile, FORMAT_PEM,
609 				NULL, e, "responder other certificates");
610 			if (!rother) goto end;
611 			}
612 		rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL,
613 			"responder private key");
614 		if (!rkey)
615 			goto end;
616 		}
617 	if(acbio)
618 		BIO_printf(bio_err, "Waiting for OCSP client connections...\n");
619 
620 	redo_accept:
621 
622 	if (acbio)
623 		{
624 		if (!do_responder(&req, &cbio, acbio, port))
625 			goto end;
626 		if (!req)
627 			{
628 			resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
629 			send_ocsp_response(cbio, resp);
630 			goto done_resp;
631 			}
632 		}
633 
634 	if (!req && (signfile || reqout || host || add_nonce || ridx_filename))
635 		{
636 		BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
637 		goto end;
638 		}
639 
640 	if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1);
641 
642 	if (signfile)
643 		{
644 		if (!keyfile) keyfile = signfile;
645 		signer = load_cert(bio_err, signfile, FORMAT_PEM,
646 			NULL, e, "signer certificate");
647 		if (!signer)
648 			{
649 			BIO_printf(bio_err, "Error loading signer certificate\n");
650 			goto end;
651 			}
652 		if (sign_certfile)
653 			{
654 			sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,
655 				NULL, e, "signer certificates");
656 			if (!sign_other) goto end;
657 			}
658 		key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL,
659 			"signer private key");
660 		if (!key)
661 			goto end;
662 		if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags))
663 			{
664 			BIO_printf(bio_err, "Error signing OCSP request\n");
665 			goto end;
666 			}
667 		}
668 
669 	if (req_text && req) OCSP_REQUEST_print(out, req, 0);
670 
671 	if (reqout)
672 		{
673 		derbio = BIO_new_file(reqout, "wb");
674 		if(!derbio)
675 			{
676 			BIO_printf(bio_err, "Error opening file %s\n", reqout);
677 			goto end;
678 			}
679 		i2d_OCSP_REQUEST_bio(derbio, req);
680 		BIO_free(derbio);
681 		}
682 
683 	if (ridx_filename && (!rkey || !rsigner || !rca_cert))
684 		{
685 		BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n");
686 		goto end;
687 		}
688 
689 	if (ridx_filename && !rdb)
690 		{
691 		rdb = load_index(ridx_filename, NULL);
692 		if (!rdb) goto end;
693 		if (!index_index(rdb)) goto end;
694 		}
695 
696 	if (rdb)
697 		{
698 		i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays);
699 		if (cbio)
700 			send_ocsp_response(cbio, resp);
701 		}
702 	else if (host)
703 		{
704 #ifndef OPENSSL_NO_SOCK
705 		cbio = BIO_new_connect(host);
706 #else
707 		BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n");
708 		goto end;
709 #endif
710 		if (!cbio)
711 			{
712 			BIO_printf(bio_err, "Error creating connect BIO\n");
713 			goto end;
714 			}
715 		if (port) BIO_set_conn_port(cbio, port);
716 		if (use_ssl == 1)
717 			{
718 			BIO *sbio;
719 #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
720 			ctx = SSL_CTX_new(SSLv23_client_method());
721 #elif !defined(OPENSSL_NO_SSL3)
722 			ctx = SSL_CTX_new(SSLv3_client_method());
723 #elif !defined(OPENSSL_NO_SSL2)
724 			ctx = SSL_CTX_new(SSLv2_client_method());
725 #else
726 			BIO_printf(bio_err, "SSL is disabled\n");
727 			goto end;
728 #endif
729 			SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
730 			sbio = BIO_new_ssl(ctx, 1);
731 			cbio = BIO_push(sbio, cbio);
732 			}
733 		if (BIO_do_connect(cbio) <= 0)
734 			{
735 			BIO_printf(bio_err, "Error connecting BIO\n");
736 			goto end;
737 			}
738 		resp = OCSP_sendreq_bio(cbio, path, req);
739 		BIO_free_all(cbio);
740 		cbio = NULL;
741 		if (!resp)
742 			{
743 			BIO_printf(bio_err, "Error querying OCSP responsder\n");
744 			goto end;
745 			}
746 		}
747 	else if (respin)
748 		{
749 		derbio = BIO_new_file(respin, "rb");
750 		if (!derbio)
751 			{
752 			BIO_printf(bio_err, "Error Opening OCSP response file\n");
753 			goto end;
754 			}
755 		resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
756 		BIO_free(derbio);
757 		if(!resp)
758 			{
759 			BIO_printf(bio_err, "Error reading OCSP response\n");
760 			goto end;
761 			}
762 
763 		}
764 	else
765 		{
766 		ret = 0;
767 		goto end;
768 		}
769 
770 	done_resp:
771 
772 	if (respout)
773 		{
774 		derbio = BIO_new_file(respout, "wb");
775 		if(!derbio)
776 			{
777 			BIO_printf(bio_err, "Error opening file %s\n", respout);
778 			goto end;
779 			}
780 		i2d_OCSP_RESPONSE_bio(derbio, resp);
781 		BIO_free(derbio);
782 		}
783 
784 	i = OCSP_response_status(resp);
785 
786 	if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL)
787 		{
788 		BIO_printf(out, "Responder Error: %s (%d)\n",
789 				OCSP_response_status_str(i), i);
790 		if (ignore_err)
791 			goto redo_accept;
792 		ret = 0;
793 		goto end;
794 		}
795 
796 	if (resp_text) OCSP_RESPONSE_print(out, resp, 0);
797 
798 	/* If running as responder don't verify our own response */
799 	if (cbio)
800 		{
801 		if (accept_count > 0)
802 			accept_count--;
803 		/* Redo if more connections needed */
804 		if (accept_count)
805 			{
806 			BIO_free_all(cbio);
807 			cbio = NULL;
808 			OCSP_REQUEST_free(req);
809 			req = NULL;
810 			OCSP_RESPONSE_free(resp);
811 			resp = NULL;
812 			goto redo_accept;
813 			}
814 		goto end;
815 		}
816 
817 	if (!store)
818 		store = setup_verify(bio_err, CAfile, CApath);
819 	if (!store)
820 		goto end;
821 	if (verify_certfile)
822 		{
823 		verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,
824 			NULL, e, "validator certificate");
825 		if (!verify_other) goto end;
826 		}
827 
828 	bs = OCSP_response_get1_basic(resp);
829 
830 	if (!bs)
831 		{
832 		BIO_printf(bio_err, "Error parsing response\n");
833 		goto end;
834 		}
835 
836 	if (!noverify)
837 		{
838 		if (req && ((i = OCSP_check_nonce(req, bs)) <= 0))
839 			{
840 			if (i == -1)
841 				BIO_printf(bio_err, "WARNING: no nonce in response\n");
842 			else
843 				{
844 				BIO_printf(bio_err, "Nonce Verify error\n");
845 				goto end;
846 				}
847 			}
848 
849 		i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
850                 if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0);
851 
852 		if(i <= 0)
853 			{
854 			BIO_printf(bio_err, "Response Verify Failure\n");
855 			ERR_print_errors(bio_err);
856 			}
857 		else
858 			BIO_printf(bio_err, "Response verify OK\n");
859 
860 		}
861 
862 	if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage))
863 		goto end;
864 
865 	ret = 0;
866 
867 end:
868 	ERR_print_errors(bio_err);
869 	X509_free(signer);
870 	X509_STORE_free(store);
871 	EVP_PKEY_free(key);
872 	EVP_PKEY_free(rkey);
873 	X509_free(issuer);
874 	X509_free(cert);
875 	X509_free(rsigner);
876 	X509_free(rca_cert);
877 	free_index(rdb);
878 	BIO_free_all(cbio);
879 	BIO_free_all(acbio);
880 	BIO_free(out);
881 	OCSP_REQUEST_free(req);
882 	OCSP_RESPONSE_free(resp);
883 	OCSP_BASICRESP_free(bs);
884 	sk_free(reqnames);
885 	sk_OCSP_CERTID_free(ids);
886 	sk_X509_pop_free(sign_other, X509_free);
887 	sk_X509_pop_free(verify_other, X509_free);
888 
889 	if (use_ssl != -1)
890 		{
891 		OPENSSL_free(host);
892 		OPENSSL_free(port);
893 		OPENSSL_free(path);
894 		SSL_CTX_free(ctx);
895 		}
896 
897 	OPENSSL_EXIT(ret);
898 }
899 
900 static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
901 				STACK_OF(OCSP_CERTID) *ids)
902 	{
903 	OCSP_CERTID *id;
904 	if(!issuer)
905 		{
906 		BIO_printf(bio_err, "No issuer certificate specified\n");
907 		return 0;
908 		}
909 	if(!*req) *req = OCSP_REQUEST_new();
910 	if(!*req) goto err;
911 	id = OCSP_cert_to_id(NULL, cert, issuer);
912 	if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
913 	if(!OCSP_request_add0_id(*req, id)) goto err;
914 	return 1;
915 
916 	err:
917 	BIO_printf(bio_err, "Error Creating OCSP request\n");
918 	return 0;
919 	}
920 
921 static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
922 				STACK_OF(OCSP_CERTID) *ids)
923 	{
924 	OCSP_CERTID *id;
925 	X509_NAME *iname;
926 	ASN1_BIT_STRING *ikey;
927 	ASN1_INTEGER *sno;
928 	if(!issuer)
929 		{
930 		BIO_printf(bio_err, "No issuer certificate specified\n");
931 		return 0;
932 		}
933 	if(!*req) *req = OCSP_REQUEST_new();
934 	if(!*req) goto err;
935 	iname = X509_get_subject_name(issuer);
936 	ikey = X509_get0_pubkey_bitstr(issuer);
937 	sno = s2i_ASN1_INTEGER(NULL, serial);
938 	if(!sno)
939 		{
940 		BIO_printf(bio_err, "Error converting serial number %s\n", serial);
941 		return 0;
942 		}
943 	id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno);
944 	ASN1_INTEGER_free(sno);
945 	if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
946 	if(!OCSP_request_add0_id(*req, id)) goto err;
947 	return 1;
948 
949 	err:
950 	BIO_printf(bio_err, "Error Creating OCSP request\n");
951 	return 0;
952 	}
953 
954 static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
955 					STACK *names, STACK_OF(OCSP_CERTID) *ids,
956 					long nsec, long maxage)
957 	{
958 	OCSP_CERTID *id;
959 	char *name;
960 	int i;
961 
962 	int status, reason;
963 
964 	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
965 
966 	if (!bs || !req || !sk_num(names) || !sk_OCSP_CERTID_num(ids))
967 		return 1;
968 
969 	for (i = 0; i < sk_OCSP_CERTID_num(ids); i++)
970 		{
971 		id = sk_OCSP_CERTID_value(ids, i);
972 		name = sk_value(names, i);
973 		BIO_printf(out, "%s: ", name);
974 
975 		if(!OCSP_resp_find_status(bs, id, &status, &reason,
976 					&rev, &thisupd, &nextupd))
977 			{
978 			BIO_puts(out, "ERROR: No Status found.\n");
979 			continue;
980 			}
981 
982 		/* Check validity: if invalid write to output BIO so we
983 		 * know which response this refers to.
984 		 */
985 		if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage))
986 			{
987 			BIO_puts(out, "WARNING: Status times invalid.\n");
988 			ERR_print_errors(out);
989 			}
990 		BIO_printf(out, "%s\n", OCSP_cert_status_str(status));
991 
992 		BIO_puts(out, "\tThis Update: ");
993 		ASN1_GENERALIZEDTIME_print(out, thisupd);
994 		BIO_puts(out, "\n");
995 
996 		if(nextupd)
997 			{
998 			BIO_puts(out, "\tNext Update: ");
999 			ASN1_GENERALIZEDTIME_print(out, nextupd);
1000 			BIO_puts(out, "\n");
1001 			}
1002 
1003 		if (status != V_OCSP_CERTSTATUS_REVOKED)
1004 			continue;
1005 
1006 		if (reason != -1)
1007 			BIO_printf(out, "\tReason: %s\n",
1008 				OCSP_crl_reason_str(reason));
1009 
1010 		BIO_puts(out, "\tRevocation Time: ");
1011 		ASN1_GENERALIZEDTIME_print(out, rev);
1012 		BIO_puts(out, "\n");
1013 		}
1014 
1015 	return 1;
1016 	}
1017 
1018 
1019 static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
1020 			X509 *ca, X509 *rcert, EVP_PKEY *rkey,
1021 			STACK_OF(X509) *rother, unsigned long flags,
1022 			int nmin, int ndays)
1023 	{
1024 	ASN1_TIME *thisupd = NULL, *nextupd = NULL;
1025 	OCSP_CERTID *cid, *ca_id = NULL;
1026 	OCSP_BASICRESP *bs = NULL;
1027 	int i, id_count, ret = 1;
1028 
1029 
1030 	id_count = OCSP_request_onereq_count(req);
1031 
1032 	if (id_count <= 0)
1033 		{
1034 		*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
1035 		goto end;
1036 		}
1037 
1038 	ca_id = OCSP_cert_to_id(EVP_sha1(), NULL, ca);
1039 
1040 	bs = OCSP_BASICRESP_new();
1041 	thisupd = X509_gmtime_adj(NULL, 0);
1042 	if (ndays != -1)
1043 		nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24 );
1044 
1045 	/* Examine each certificate id in the request */
1046 	for (i = 0; i < id_count; i++)
1047 		{
1048 		OCSP_ONEREQ *one;
1049 		ASN1_INTEGER *serial;
1050 		char **inf;
1051 		one = OCSP_request_onereq_get0(req, i);
1052 		cid = OCSP_onereq_get0_id(one);
1053 		/* Is this request about our CA? */
1054 		if (OCSP_id_issuer_cmp(ca_id, cid))
1055 			{
1056 			OCSP_basic_add1_status(bs, cid,
1057 						V_OCSP_CERTSTATUS_UNKNOWN,
1058 						0, NULL,
1059 						thisupd, nextupd);
1060 			continue;
1061 			}
1062 		OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
1063 		inf = lookup_serial(db, serial);
1064 		if (!inf)
1065 			OCSP_basic_add1_status(bs, cid,
1066 						V_OCSP_CERTSTATUS_UNKNOWN,
1067 						0, NULL,
1068 						thisupd, nextupd);
1069 		else if (inf[DB_type][0] == DB_TYPE_VAL)
1070 			OCSP_basic_add1_status(bs, cid,
1071 						V_OCSP_CERTSTATUS_GOOD,
1072 						0, NULL,
1073 						thisupd, nextupd);
1074 		else if (inf[DB_type][0] == DB_TYPE_REV)
1075 			{
1076 			ASN1_OBJECT *inst = NULL;
1077 			ASN1_TIME *revtm = NULL;
1078 			ASN1_GENERALIZEDTIME *invtm = NULL;
1079 			OCSP_SINGLERESP *single;
1080 			int reason = -1;
1081 			unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]);
1082 			single = OCSP_basic_add1_status(bs, cid,
1083 						V_OCSP_CERTSTATUS_REVOKED,
1084 						reason, revtm,
1085 						thisupd, nextupd);
1086 			if (invtm)
1087 				OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0);
1088 			else if (inst)
1089 				OCSP_SINGLERESP_add1_ext_i2d(single, NID_hold_instruction_code, inst, 0, 0);
1090 			ASN1_OBJECT_free(inst);
1091 			ASN1_TIME_free(revtm);
1092 			ASN1_GENERALIZEDTIME_free(invtm);
1093 			}
1094 		}
1095 
1096 	OCSP_copy_nonce(bs, req);
1097 
1098 	OCSP_basic_sign(bs, rcert, rkey, EVP_sha1(), rother, flags);
1099 
1100 	*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
1101 
1102 	end:
1103 	ASN1_TIME_free(thisupd);
1104 	ASN1_TIME_free(nextupd);
1105 	OCSP_CERTID_free(ca_id);
1106 	OCSP_BASICRESP_free(bs);
1107 	return ret;
1108 
1109 	}
1110 
1111 static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser)
1112 	{
1113 	int i;
1114 	BIGNUM *bn = NULL;
1115 	char *itmp, *row[DB_NUMBER],**rrow;
1116 	for (i = 0; i < DB_NUMBER; i++) row[i] = NULL;
1117 	bn = ASN1_INTEGER_to_BN(ser,NULL);
1118 	if (BN_is_zero(bn))
1119 		itmp = BUF_strdup("00");
1120 	else
1121 		itmp = BN_bn2hex(bn);
1122 	row[DB_serial] = itmp;
1123 	BN_free(bn);
1124 	rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
1125 	OPENSSL_free(itmp);
1126 	return rrow;
1127 	}
1128 
1129 /* Quick and dirty OCSP server: read in and parse input request */
1130 
1131 static BIO *init_responder(char *port)
1132 	{
1133 	BIO *acbio = NULL, *bufbio = NULL;
1134 	bufbio = BIO_new(BIO_f_buffer());
1135 	if (!bufbio)
1136 		goto err;
1137 #ifndef OPENSSL_NO_SOCK
1138 	acbio = BIO_new_accept(port);
1139 #else
1140 	BIO_printf(bio_err, "Error setting up accept BIO - sockets not supported.\n");
1141 #endif
1142 	if (!acbio)
1143 		goto err;
1144 	BIO_set_accept_bios(acbio, bufbio);
1145 	bufbio = NULL;
1146 
1147 	if (BIO_do_accept(acbio) <= 0)
1148 		{
1149 			BIO_printf(bio_err, "Error setting up accept BIO\n");
1150 			ERR_print_errors(bio_err);
1151 			goto err;
1152 		}
1153 
1154 	return acbio;
1155 
1156 	err:
1157 	BIO_free_all(acbio);
1158 	BIO_free(bufbio);
1159 	return NULL;
1160 	}
1161 
1162 static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port)
1163 	{
1164 	int have_post = 0, len;
1165 	OCSP_REQUEST *req = NULL;
1166 	char inbuf[1024];
1167 	BIO *cbio = NULL;
1168 
1169 	if (BIO_do_accept(acbio) <= 0)
1170 		{
1171 			BIO_printf(bio_err, "Error accepting connection\n");
1172 			ERR_print_errors(bio_err);
1173 			return 0;
1174 		}
1175 
1176 	cbio = BIO_pop(acbio);
1177 	*pcbio = cbio;
1178 
1179 	for(;;)
1180 		{
1181 		len = BIO_gets(cbio, inbuf, sizeof inbuf);
1182 		if (len <= 0)
1183 			return 1;
1184 		/* Look for "POST" signalling start of query */
1185 		if (!have_post)
1186 			{
1187 			if(strncmp(inbuf, "POST", 4))
1188 				{
1189 				BIO_printf(bio_err, "Invalid request\n");
1190 				return 1;
1191 				}
1192 			have_post = 1;
1193 			}
1194 		/* Look for end of headers */
1195 		if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
1196 			break;
1197 		}
1198 
1199 	/* Try to read OCSP request */
1200 
1201 	req = d2i_OCSP_REQUEST_bio(cbio, NULL);
1202 
1203 	if (!req)
1204 		{
1205 		BIO_printf(bio_err, "Error parsing OCSP request\n");
1206 		ERR_print_errors(bio_err);
1207 		}
1208 
1209 	*preq = req;
1210 
1211 	return 1;
1212 
1213 	}
1214 
1215 static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
1216 	{
1217 	char http_resp[] =
1218 		"HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n"
1219 		"Content-Length: %d\r\n\r\n";
1220 	if (!cbio)
1221 		return 0;
1222 	BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL));
1223 	i2d_OCSP_RESPONSE_bio(cbio, resp);
1224 	BIO_flush(cbio);
1225 	return 1;
1226 	}
1227 
1228 #endif
1229