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
71static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
72				STACK_OF(OCSP_CERTID) *ids);
73static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
74				STACK_OF(OCSP_CERTID) *ids);
75static 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
79static 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
84static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
85static BIO *init_responder(char *port);
86static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port);
87static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
88
89#undef PROG
90#define PROG ocsp_main
91
92int MAIN(int, char **);
93
94int 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
866end:
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
899static 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
920static 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
953static 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
1018static 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
1110static 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
1130static 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
1161static 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
1214static 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