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