xref: /onnv-gate/usr/src/common/openssl/apps/ocsp.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* ocsp.c */
20Sstevel@tonic-gate /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
30Sstevel@tonic-gate  * project 2000.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate /* ====================================================================
60Sstevel@tonic-gate  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
90Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
100Sstevel@tonic-gate  * are met:
110Sstevel@tonic-gate  *
120Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
130Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
140Sstevel@tonic-gate  *
150Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
160Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in
170Sstevel@tonic-gate  *    the documentation and/or other materials provided with the
180Sstevel@tonic-gate  *    distribution.
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this
210Sstevel@tonic-gate  *    software must display the following acknowledgment:
220Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
230Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
240Sstevel@tonic-gate  *
250Sstevel@tonic-gate  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
260Sstevel@tonic-gate  *    endorse or promote products derived from this software without
270Sstevel@tonic-gate  *    prior written permission. For written permission, please contact
280Sstevel@tonic-gate  *    licensing@OpenSSL.org.
290Sstevel@tonic-gate  *
300Sstevel@tonic-gate  * 5. Products derived from this software may not be called "OpenSSL"
310Sstevel@tonic-gate  *    nor may "OpenSSL" appear in their names without prior written
320Sstevel@tonic-gate  *    permission of the OpenSSL Project.
330Sstevel@tonic-gate  *
340Sstevel@tonic-gate  * 6. Redistributions of any form whatsoever must retain the following
350Sstevel@tonic-gate  *    acknowledgment:
360Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
370Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
380Sstevel@tonic-gate  *
390Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
400Sstevel@tonic-gate  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
410Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
420Sstevel@tonic-gate  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
430Sstevel@tonic-gate  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
440Sstevel@tonic-gate  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
450Sstevel@tonic-gate  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
460Sstevel@tonic-gate  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
470Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
480Sstevel@tonic-gate  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
490Sstevel@tonic-gate  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
500Sstevel@tonic-gate  * OF THE POSSIBILITY OF SUCH DAMAGE.
510Sstevel@tonic-gate  * ====================================================================
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * This product includes cryptographic software written by Eric Young
540Sstevel@tonic-gate  * (eay@cryptsoft.com).  This product includes software written by Tim
550Sstevel@tonic-gate  * Hudson (tjh@cryptsoft.com).
560Sstevel@tonic-gate  *
570Sstevel@tonic-gate  */
580Sstevel@tonic-gate #ifndef OPENSSL_NO_OCSP
590Sstevel@tonic-gate 
600Sstevel@tonic-gate #include <stdio.h>
610Sstevel@tonic-gate #include <string.h>
620Sstevel@tonic-gate #include "apps.h"
630Sstevel@tonic-gate #include <openssl/pem.h>
640Sstevel@tonic-gate #include <openssl/ocsp.h>
650Sstevel@tonic-gate #include <openssl/err.h>
660Sstevel@tonic-gate #include <openssl/ssl.h>
67*2139Sjp161948 #include <openssl/bn.h>
680Sstevel@tonic-gate 
690Sstevel@tonic-gate /* Maximum leeway in validity period: default 5 minutes */
700Sstevel@tonic-gate #define MAX_VALIDITY_PERIOD	(5 * 60)
710Sstevel@tonic-gate 
720Sstevel@tonic-gate static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
730Sstevel@tonic-gate 				STACK_OF(OCSP_CERTID) *ids);
740Sstevel@tonic-gate static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
750Sstevel@tonic-gate 				STACK_OF(OCSP_CERTID) *ids);
760Sstevel@tonic-gate static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
770Sstevel@tonic-gate 				STACK *names, STACK_OF(OCSP_CERTID) *ids,
780Sstevel@tonic-gate 				long nsec, long maxage);
790Sstevel@tonic-gate 
800Sstevel@tonic-gate static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
810Sstevel@tonic-gate 			X509 *ca, X509 *rcert, EVP_PKEY *rkey,
820Sstevel@tonic-gate 			STACK_OF(X509) *rother, unsigned long flags,
830Sstevel@tonic-gate 			int nmin, int ndays);
840Sstevel@tonic-gate 
850Sstevel@tonic-gate static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
860Sstevel@tonic-gate static BIO *init_responder(char *port);
870Sstevel@tonic-gate static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port);
880Sstevel@tonic-gate static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
890Sstevel@tonic-gate 
900Sstevel@tonic-gate #undef PROG
910Sstevel@tonic-gate #define PROG ocsp_main
920Sstevel@tonic-gate 
930Sstevel@tonic-gate int MAIN(int, char **);
940Sstevel@tonic-gate 
MAIN(int argc,char ** argv)950Sstevel@tonic-gate int MAIN(int argc, char **argv)
960Sstevel@tonic-gate 	{
970Sstevel@tonic-gate 	ENGINE *e = NULL;
980Sstevel@tonic-gate 	char **args;
990Sstevel@tonic-gate 	char *host = NULL, *port = NULL, *path = "/";
1000Sstevel@tonic-gate 	char *reqin = NULL, *respin = NULL;
1010Sstevel@tonic-gate 	char *reqout = NULL, *respout = NULL;
1020Sstevel@tonic-gate 	char *signfile = NULL, *keyfile = NULL;
1030Sstevel@tonic-gate 	char *rsignfile = NULL, *rkeyfile = NULL;
1040Sstevel@tonic-gate 	char *outfile = NULL;
1050Sstevel@tonic-gate 	int add_nonce = 1, noverify = 0, use_ssl = -1;
1060Sstevel@tonic-gate 	OCSP_REQUEST *req = NULL;
1070Sstevel@tonic-gate 	OCSP_RESPONSE *resp = NULL;
1080Sstevel@tonic-gate 	OCSP_BASICRESP *bs = NULL;
1090Sstevel@tonic-gate 	X509 *issuer = NULL, *cert = NULL;
1100Sstevel@tonic-gate 	X509 *signer = NULL, *rsigner = NULL;
1110Sstevel@tonic-gate 	EVP_PKEY *key = NULL, *rkey = NULL;
1120Sstevel@tonic-gate 	BIO *acbio = NULL, *cbio = NULL;
1130Sstevel@tonic-gate 	BIO *derbio = NULL;
1140Sstevel@tonic-gate 	BIO *out = NULL;
1150Sstevel@tonic-gate 	int req_text = 0, resp_text = 0;
1160Sstevel@tonic-gate 	long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
1170Sstevel@tonic-gate 	char *CAfile = NULL, *CApath = NULL;
1180Sstevel@tonic-gate 	X509_STORE *store = NULL;
1190Sstevel@tonic-gate 	SSL_CTX *ctx = NULL;
1200Sstevel@tonic-gate 	STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
1210Sstevel@tonic-gate 	char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
1220Sstevel@tonic-gate 	unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
1230Sstevel@tonic-gate 	int ret = 1;
1240Sstevel@tonic-gate 	int accept_count = -1;
1250Sstevel@tonic-gate 	int badarg = 0;
1260Sstevel@tonic-gate 	int i;
1270Sstevel@tonic-gate 	int ignore_err = 0;
1280Sstevel@tonic-gate 	STACK *reqnames = NULL;
1290Sstevel@tonic-gate 	STACK_OF(OCSP_CERTID) *ids = NULL;
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 	X509 *rca_cert = NULL;
1320Sstevel@tonic-gate 	char *ridx_filename = NULL;
1330Sstevel@tonic-gate 	char *rca_filename = NULL;
1340Sstevel@tonic-gate 	CA_DB *rdb = NULL;
1350Sstevel@tonic-gate 	int nmin = 0, ndays = -1;
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate 	if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate 	if (!load_config(bio_err, NULL))
1400Sstevel@tonic-gate 		goto end;
1410Sstevel@tonic-gate 	SSL_load_error_strings();
1420Sstevel@tonic-gate 	args = argv + 1;
1430Sstevel@tonic-gate 	reqnames = sk_new_null();
1440Sstevel@tonic-gate 	ids = sk_OCSP_CERTID_new_null();
1450Sstevel@tonic-gate 	while (!badarg && *args && *args[0] == '-')
1460Sstevel@tonic-gate 		{
1470Sstevel@tonic-gate 		if (!strcmp(*args, "-out"))
1480Sstevel@tonic-gate 			{
1490Sstevel@tonic-gate 			if (args[1])
1500Sstevel@tonic-gate 				{
1510Sstevel@tonic-gate 				args++;
1520Sstevel@tonic-gate 				outfile = *args;
1530Sstevel@tonic-gate 				}
1540Sstevel@tonic-gate 			else badarg = 1;
1550Sstevel@tonic-gate 			}
1560Sstevel@tonic-gate 		else if (!strcmp(*args, "-url"))
1570Sstevel@tonic-gate 			{
1580Sstevel@tonic-gate 			if (args[1])
1590Sstevel@tonic-gate 				{
1600Sstevel@tonic-gate 				args++;
1610Sstevel@tonic-gate 				if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl))
1620Sstevel@tonic-gate 					{
1630Sstevel@tonic-gate 					BIO_printf(bio_err, "Error parsing URL\n");
1640Sstevel@tonic-gate 					badarg = 1;
1650Sstevel@tonic-gate 					}
1660Sstevel@tonic-gate 				}
1670Sstevel@tonic-gate 			else badarg = 1;
1680Sstevel@tonic-gate 			}
1690Sstevel@tonic-gate 		else if (!strcmp(*args, "-host"))
1700Sstevel@tonic-gate 			{
1710Sstevel@tonic-gate 			if (args[1])
1720Sstevel@tonic-gate 				{
1730Sstevel@tonic-gate 				args++;
1740Sstevel@tonic-gate 				host = *args;
1750Sstevel@tonic-gate 				}
1760Sstevel@tonic-gate 			else badarg = 1;
1770Sstevel@tonic-gate 			}
1780Sstevel@tonic-gate 		else if (!strcmp(*args, "-port"))
1790Sstevel@tonic-gate 			{
1800Sstevel@tonic-gate 			if (args[1])
1810Sstevel@tonic-gate 				{
1820Sstevel@tonic-gate 				args++;
1830Sstevel@tonic-gate 				port = *args;
1840Sstevel@tonic-gate 				}
1850Sstevel@tonic-gate 			else badarg = 1;
1860Sstevel@tonic-gate 			}
1870Sstevel@tonic-gate 		else if (!strcmp(*args, "-ignore_err"))
1880Sstevel@tonic-gate 			ignore_err = 1;
1890Sstevel@tonic-gate 		else if (!strcmp(*args, "-noverify"))
1900Sstevel@tonic-gate 			noverify = 1;
1910Sstevel@tonic-gate 		else if (!strcmp(*args, "-nonce"))
1920Sstevel@tonic-gate 			add_nonce = 2;
1930Sstevel@tonic-gate 		else if (!strcmp(*args, "-no_nonce"))
1940Sstevel@tonic-gate 			add_nonce = 0;
1950Sstevel@tonic-gate 		else if (!strcmp(*args, "-resp_no_certs"))
1960Sstevel@tonic-gate 			rflags |= OCSP_NOCERTS;
1970Sstevel@tonic-gate 		else if (!strcmp(*args, "-resp_key_id"))
1980Sstevel@tonic-gate 			rflags |= OCSP_RESPID_KEY;
1990Sstevel@tonic-gate 		else if (!strcmp(*args, "-no_certs"))
2000Sstevel@tonic-gate 			sign_flags |= OCSP_NOCERTS;
2010Sstevel@tonic-gate 		else if (!strcmp(*args, "-no_signature_verify"))
2020Sstevel@tonic-gate 			verify_flags |= OCSP_NOSIGS;
2030Sstevel@tonic-gate 		else if (!strcmp(*args, "-no_cert_verify"))
2040Sstevel@tonic-gate 			verify_flags |= OCSP_NOVERIFY;
2050Sstevel@tonic-gate 		else if (!strcmp(*args, "-no_chain"))
2060Sstevel@tonic-gate 			verify_flags |= OCSP_NOCHAIN;
2070Sstevel@tonic-gate 		else if (!strcmp(*args, "-no_cert_checks"))
2080Sstevel@tonic-gate 			verify_flags |= OCSP_NOCHECKS;
2090Sstevel@tonic-gate 		else if (!strcmp(*args, "-no_explicit"))
2100Sstevel@tonic-gate 			verify_flags |= OCSP_NOEXPLICIT;
2110Sstevel@tonic-gate 		else if (!strcmp(*args, "-trust_other"))
2120Sstevel@tonic-gate 			verify_flags |= OCSP_TRUSTOTHER;
2130Sstevel@tonic-gate 		else if (!strcmp(*args, "-no_intern"))
2140Sstevel@tonic-gate 			verify_flags |= OCSP_NOINTERN;
2150Sstevel@tonic-gate 		else if (!strcmp(*args, "-text"))
2160Sstevel@tonic-gate 			{
2170Sstevel@tonic-gate 			req_text = 1;
2180Sstevel@tonic-gate 			resp_text = 1;
2190Sstevel@tonic-gate 			}
2200Sstevel@tonic-gate 		else if (!strcmp(*args, "-req_text"))
2210Sstevel@tonic-gate 			req_text = 1;
2220Sstevel@tonic-gate 		else if (!strcmp(*args, "-resp_text"))
2230Sstevel@tonic-gate 			resp_text = 1;
2240Sstevel@tonic-gate 		else if (!strcmp(*args, "-reqin"))
2250Sstevel@tonic-gate 			{
2260Sstevel@tonic-gate 			if (args[1])
2270Sstevel@tonic-gate 				{
2280Sstevel@tonic-gate 				args++;
2290Sstevel@tonic-gate 				reqin = *args;
2300Sstevel@tonic-gate 				}
2310Sstevel@tonic-gate 			else badarg = 1;
2320Sstevel@tonic-gate 			}
2330Sstevel@tonic-gate 		else if (!strcmp(*args, "-respin"))
2340Sstevel@tonic-gate 			{
2350Sstevel@tonic-gate 			if (args[1])
2360Sstevel@tonic-gate 				{
2370Sstevel@tonic-gate 				args++;
2380Sstevel@tonic-gate 				respin = *args;
2390Sstevel@tonic-gate 				}
2400Sstevel@tonic-gate 			else badarg = 1;
2410Sstevel@tonic-gate 			}
2420Sstevel@tonic-gate 		else if (!strcmp(*args, "-signer"))
2430Sstevel@tonic-gate 			{
2440Sstevel@tonic-gate 			if (args[1])
2450Sstevel@tonic-gate 				{
2460Sstevel@tonic-gate 				args++;
2470Sstevel@tonic-gate 				signfile = *args;
2480Sstevel@tonic-gate 				}
2490Sstevel@tonic-gate 			else badarg = 1;
2500Sstevel@tonic-gate 			}
2510Sstevel@tonic-gate 		else if (!strcmp (*args, "-VAfile"))
2520Sstevel@tonic-gate 			{
2530Sstevel@tonic-gate 			if (args[1])
2540Sstevel@tonic-gate 				{
2550Sstevel@tonic-gate 				args++;
2560Sstevel@tonic-gate 				verify_certfile = *args;
2570Sstevel@tonic-gate 				verify_flags |= OCSP_TRUSTOTHER;
2580Sstevel@tonic-gate 				}
2590Sstevel@tonic-gate 			else badarg = 1;
2600Sstevel@tonic-gate 			}
2610Sstevel@tonic-gate 		else if (!strcmp(*args, "-sign_other"))
2620Sstevel@tonic-gate 			{
2630Sstevel@tonic-gate 			if (args[1])
2640Sstevel@tonic-gate 				{
2650Sstevel@tonic-gate 				args++;
2660Sstevel@tonic-gate 				sign_certfile = *args;
2670Sstevel@tonic-gate 				}
2680Sstevel@tonic-gate 			else badarg = 1;
2690Sstevel@tonic-gate 			}
2700Sstevel@tonic-gate 		else if (!strcmp(*args, "-verify_other"))
2710Sstevel@tonic-gate 			{
2720Sstevel@tonic-gate 			if (args[1])
2730Sstevel@tonic-gate 				{
2740Sstevel@tonic-gate 				args++;
2750Sstevel@tonic-gate 				verify_certfile = *args;
2760Sstevel@tonic-gate 				}
2770Sstevel@tonic-gate 			else badarg = 1;
2780Sstevel@tonic-gate 			}
2790Sstevel@tonic-gate 		else if (!strcmp (*args, "-CAfile"))
2800Sstevel@tonic-gate 			{
2810Sstevel@tonic-gate 			if (args[1])
2820Sstevel@tonic-gate 				{
2830Sstevel@tonic-gate 				args++;
2840Sstevel@tonic-gate 				CAfile = *args;
2850Sstevel@tonic-gate 				}
2860Sstevel@tonic-gate 			else badarg = 1;
2870Sstevel@tonic-gate 			}
2880Sstevel@tonic-gate 		else if (!strcmp (*args, "-CApath"))
2890Sstevel@tonic-gate 			{
2900Sstevel@tonic-gate 			if (args[1])
2910Sstevel@tonic-gate 				{
2920Sstevel@tonic-gate 				args++;
2930Sstevel@tonic-gate 				CApath = *args;
2940Sstevel@tonic-gate 				}
2950Sstevel@tonic-gate 			else badarg = 1;
2960Sstevel@tonic-gate 			}
2970Sstevel@tonic-gate 		else if (!strcmp (*args, "-validity_period"))
2980Sstevel@tonic-gate 			{
2990Sstevel@tonic-gate 			if (args[1])
3000Sstevel@tonic-gate 				{
3010Sstevel@tonic-gate 				args++;
3020Sstevel@tonic-gate 				nsec = atol(*args);
3030Sstevel@tonic-gate 				if (nsec < 0)
3040Sstevel@tonic-gate 					{
3050Sstevel@tonic-gate 					BIO_printf(bio_err,
3060Sstevel@tonic-gate 						"Illegal validity period %s\n",
3070Sstevel@tonic-gate 						*args);
3080Sstevel@tonic-gate 					badarg = 1;
3090Sstevel@tonic-gate 					}
3100Sstevel@tonic-gate 				}
3110Sstevel@tonic-gate 			else badarg = 1;
3120Sstevel@tonic-gate 			}
3130Sstevel@tonic-gate 		else if (!strcmp (*args, "-status_age"))
3140Sstevel@tonic-gate 			{
3150Sstevel@tonic-gate 			if (args[1])
3160Sstevel@tonic-gate 				{
3170Sstevel@tonic-gate 				args++;
3180Sstevel@tonic-gate 				maxage = atol(*args);
3190Sstevel@tonic-gate 				if (maxage < 0)
3200Sstevel@tonic-gate 					{
3210Sstevel@tonic-gate 					BIO_printf(bio_err,
3220Sstevel@tonic-gate 						"Illegal validity age %s\n",
3230Sstevel@tonic-gate 						*args);
3240Sstevel@tonic-gate 					badarg = 1;
3250Sstevel@tonic-gate 					}
3260Sstevel@tonic-gate 				}
3270Sstevel@tonic-gate 			else badarg = 1;
3280Sstevel@tonic-gate 			}
3290Sstevel@tonic-gate 		 else if (!strcmp(*args, "-signkey"))
3300Sstevel@tonic-gate 			{
3310Sstevel@tonic-gate 			if (args[1])
3320Sstevel@tonic-gate 				{
3330Sstevel@tonic-gate 				args++;
3340Sstevel@tonic-gate 				keyfile = *args;
3350Sstevel@tonic-gate 				}
3360Sstevel@tonic-gate 			else badarg = 1;
3370Sstevel@tonic-gate 			}
3380Sstevel@tonic-gate 		else if (!strcmp(*args, "-reqout"))
3390Sstevel@tonic-gate 			{
3400Sstevel@tonic-gate 			if (args[1])
3410Sstevel@tonic-gate 				{
3420Sstevel@tonic-gate 				args++;
3430Sstevel@tonic-gate 				reqout = *args;
3440Sstevel@tonic-gate 				}
3450Sstevel@tonic-gate 			else badarg = 1;
3460Sstevel@tonic-gate 			}
3470Sstevel@tonic-gate 		else if (!strcmp(*args, "-respout"))
3480Sstevel@tonic-gate 			{
3490Sstevel@tonic-gate 			if (args[1])
3500Sstevel@tonic-gate 				{
3510Sstevel@tonic-gate 				args++;
3520Sstevel@tonic-gate 				respout = *args;
3530Sstevel@tonic-gate 				}
3540Sstevel@tonic-gate 			else badarg = 1;
3550Sstevel@tonic-gate 			}
3560Sstevel@tonic-gate 		 else if (!strcmp(*args, "-path"))
3570Sstevel@tonic-gate 			{
3580Sstevel@tonic-gate 			if (args[1])
3590Sstevel@tonic-gate 				{
3600Sstevel@tonic-gate 				args++;
3610Sstevel@tonic-gate 				path = *args;
3620Sstevel@tonic-gate 				}
3630Sstevel@tonic-gate 			else badarg = 1;
3640Sstevel@tonic-gate 			}
3650Sstevel@tonic-gate 		else if (!strcmp(*args, "-issuer"))
3660Sstevel@tonic-gate 			{
3670Sstevel@tonic-gate 			if (args[1])
3680Sstevel@tonic-gate 				{
3690Sstevel@tonic-gate 				args++;
3700Sstevel@tonic-gate 				X509_free(issuer);
3710Sstevel@tonic-gate 				issuer = load_cert(bio_err, *args, FORMAT_PEM,
3720Sstevel@tonic-gate 					NULL, e, "issuer certificate");
3730Sstevel@tonic-gate 				if(!issuer) goto end;
3740Sstevel@tonic-gate 				}
3750Sstevel@tonic-gate 			else badarg = 1;
3760Sstevel@tonic-gate 			}
3770Sstevel@tonic-gate 		else if (!strcmp (*args, "-cert"))
3780Sstevel@tonic-gate 			{
3790Sstevel@tonic-gate 			if (args[1])
3800Sstevel@tonic-gate 				{
3810Sstevel@tonic-gate 				args++;
3820Sstevel@tonic-gate 				X509_free(cert);
3830Sstevel@tonic-gate 				cert = load_cert(bio_err, *args, FORMAT_PEM,
3840Sstevel@tonic-gate 					NULL, e, "certificate");
3850Sstevel@tonic-gate 				if(!cert) goto end;
3860Sstevel@tonic-gate 				if(!add_ocsp_cert(&req, cert, issuer, ids))
3870Sstevel@tonic-gate 					goto end;
3880Sstevel@tonic-gate 				if(!sk_push(reqnames, *args))
3890Sstevel@tonic-gate 					goto end;
3900Sstevel@tonic-gate 				}
3910Sstevel@tonic-gate 			else badarg = 1;
3920Sstevel@tonic-gate 			}
3930Sstevel@tonic-gate 		else if (!strcmp(*args, "-serial"))
3940Sstevel@tonic-gate 			{
3950Sstevel@tonic-gate 			if (args[1])
3960Sstevel@tonic-gate 				{
3970Sstevel@tonic-gate 				args++;
3980Sstevel@tonic-gate 				if(!add_ocsp_serial(&req, *args, issuer, ids))
3990Sstevel@tonic-gate 					goto end;
4000Sstevel@tonic-gate 				if(!sk_push(reqnames, *args))
4010Sstevel@tonic-gate 					goto end;
4020Sstevel@tonic-gate 				}
4030Sstevel@tonic-gate 			else badarg = 1;
4040Sstevel@tonic-gate 			}
4050Sstevel@tonic-gate 		else if (!strcmp(*args, "-index"))
4060Sstevel@tonic-gate 			{
4070Sstevel@tonic-gate 			if (args[1])
4080Sstevel@tonic-gate 				{
4090Sstevel@tonic-gate 				args++;
4100Sstevel@tonic-gate 				ridx_filename = *args;
4110Sstevel@tonic-gate 				}
4120Sstevel@tonic-gate 			else badarg = 1;
4130Sstevel@tonic-gate 			}
4140Sstevel@tonic-gate 		else if (!strcmp(*args, "-CA"))
4150Sstevel@tonic-gate 			{
4160Sstevel@tonic-gate 			if (args[1])
4170Sstevel@tonic-gate 				{
4180Sstevel@tonic-gate 				args++;
4190Sstevel@tonic-gate 				rca_filename = *args;
4200Sstevel@tonic-gate 				}
4210Sstevel@tonic-gate 			else badarg = 1;
4220Sstevel@tonic-gate 			}
4230Sstevel@tonic-gate 		else if (!strcmp (*args, "-nmin"))
4240Sstevel@tonic-gate 			{
4250Sstevel@tonic-gate 			if (args[1])
4260Sstevel@tonic-gate 				{
4270Sstevel@tonic-gate 				args++;
4280Sstevel@tonic-gate 				nmin = atol(*args);
4290Sstevel@tonic-gate 				if (nmin < 0)
4300Sstevel@tonic-gate 					{
4310Sstevel@tonic-gate 					BIO_printf(bio_err,
4320Sstevel@tonic-gate 						"Illegal update period %s\n",
4330Sstevel@tonic-gate 						*args);
4340Sstevel@tonic-gate 					badarg = 1;
4350Sstevel@tonic-gate 					}
4360Sstevel@tonic-gate 				}
4370Sstevel@tonic-gate 				if (ndays == -1)
4380Sstevel@tonic-gate 					ndays = 0;
4390Sstevel@tonic-gate 			else badarg = 1;
4400Sstevel@tonic-gate 			}
4410Sstevel@tonic-gate 		else if (!strcmp (*args, "-nrequest"))
4420Sstevel@tonic-gate 			{
4430Sstevel@tonic-gate 			if (args[1])
4440Sstevel@tonic-gate 				{
4450Sstevel@tonic-gate 				args++;
4460Sstevel@tonic-gate 				accept_count = atol(*args);
4470Sstevel@tonic-gate 				if (accept_count < 0)
4480Sstevel@tonic-gate 					{
4490Sstevel@tonic-gate 					BIO_printf(bio_err,
4500Sstevel@tonic-gate 						"Illegal accept count %s\n",
4510Sstevel@tonic-gate 						*args);
4520Sstevel@tonic-gate 					badarg = 1;
4530Sstevel@tonic-gate 					}
4540Sstevel@tonic-gate 				}
4550Sstevel@tonic-gate 			else badarg = 1;
4560Sstevel@tonic-gate 			}
4570Sstevel@tonic-gate 		else if (!strcmp (*args, "-ndays"))
4580Sstevel@tonic-gate 			{
4590Sstevel@tonic-gate 			if (args[1])
4600Sstevel@tonic-gate 				{
4610Sstevel@tonic-gate 				args++;
4620Sstevel@tonic-gate 				ndays = atol(*args);
4630Sstevel@tonic-gate 				if (ndays < 0)
4640Sstevel@tonic-gate 					{
4650Sstevel@tonic-gate 					BIO_printf(bio_err,
4660Sstevel@tonic-gate 						"Illegal update period %s\n",
4670Sstevel@tonic-gate 						*args);
4680Sstevel@tonic-gate 					badarg = 1;
4690Sstevel@tonic-gate 					}
4700Sstevel@tonic-gate 				}
4710Sstevel@tonic-gate 			else badarg = 1;
4720Sstevel@tonic-gate 			}
4730Sstevel@tonic-gate 		else if (!strcmp(*args, "-rsigner"))
4740Sstevel@tonic-gate 			{
4750Sstevel@tonic-gate 			if (args[1])
4760Sstevel@tonic-gate 				{
4770Sstevel@tonic-gate 				args++;
4780Sstevel@tonic-gate 				rsignfile = *args;
4790Sstevel@tonic-gate 				}
4800Sstevel@tonic-gate 			else badarg = 1;
4810Sstevel@tonic-gate 			}
4820Sstevel@tonic-gate 		else if (!strcmp(*args, "-rkey"))
4830Sstevel@tonic-gate 			{
4840Sstevel@tonic-gate 			if (args[1])
4850Sstevel@tonic-gate 				{
4860Sstevel@tonic-gate 				args++;
4870Sstevel@tonic-gate 				rkeyfile = *args;
4880Sstevel@tonic-gate 				}
4890Sstevel@tonic-gate 			else badarg = 1;
4900Sstevel@tonic-gate 			}
4910Sstevel@tonic-gate 		else if (!strcmp(*args, "-rother"))
4920Sstevel@tonic-gate 			{
4930Sstevel@tonic-gate 			if (args[1])
4940Sstevel@tonic-gate 				{
4950Sstevel@tonic-gate 				args++;
4960Sstevel@tonic-gate 				rcertfile = *args;
4970Sstevel@tonic-gate 				}
4980Sstevel@tonic-gate 			else badarg = 1;
4990Sstevel@tonic-gate 			}
5000Sstevel@tonic-gate 		else badarg = 1;
5010Sstevel@tonic-gate 		args++;
5020Sstevel@tonic-gate 		}
5030Sstevel@tonic-gate 
5040Sstevel@tonic-gate 	/* Have we anything to do? */
5050Sstevel@tonic-gate 	if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1;
5060Sstevel@tonic-gate 
5070Sstevel@tonic-gate 	if (badarg)
5080Sstevel@tonic-gate 		{
5090Sstevel@tonic-gate 		BIO_printf (bio_err, "OCSP utility\n");
5100Sstevel@tonic-gate 		BIO_printf (bio_err, "Usage ocsp [options]\n");
5110Sstevel@tonic-gate 		BIO_printf (bio_err, "where options are\n");
5120Sstevel@tonic-gate 		BIO_printf (bio_err, "-out file          output filename\n");
5130Sstevel@tonic-gate 		BIO_printf (bio_err, "-issuer file       issuer certificate\n");
5140Sstevel@tonic-gate 		BIO_printf (bio_err, "-cert file         certificate to check\n");
5150Sstevel@tonic-gate 		BIO_printf (bio_err, "-serial n          serial number to check\n");
5160Sstevel@tonic-gate 		BIO_printf (bio_err, "-signer file       certificate to sign OCSP request with\n");
5170Sstevel@tonic-gate 		BIO_printf (bio_err, "-signkey file      private key to sign OCSP request with\n");
5180Sstevel@tonic-gate 		BIO_printf (bio_err, "-sign_other file   additional certificates to include in signed request\n");
5190Sstevel@tonic-gate 		BIO_printf (bio_err, "-no_certs          don't include any certificates in signed request\n");
5200Sstevel@tonic-gate 		BIO_printf (bio_err, "-req_text          print text form of request\n");
5210Sstevel@tonic-gate 		BIO_printf (bio_err, "-resp_text         print text form of response\n");
5220Sstevel@tonic-gate 		BIO_printf (bio_err, "-text              print text form of request and response\n");
5230Sstevel@tonic-gate 		BIO_printf (bio_err, "-reqout file       write DER encoded OCSP request to \"file\"\n");
5240Sstevel@tonic-gate 		BIO_printf (bio_err, "-respout file      write DER encoded OCSP reponse to \"file\"\n");
5250Sstevel@tonic-gate 		BIO_printf (bio_err, "-reqin file        read DER encoded OCSP request from \"file\"\n");
5260Sstevel@tonic-gate 		BIO_printf (bio_err, "-respin file       read DER encoded OCSP reponse from \"file\"\n");
5270Sstevel@tonic-gate 		BIO_printf (bio_err, "-nonce             add OCSP nonce to request\n");
5280Sstevel@tonic-gate 		BIO_printf (bio_err, "-no_nonce          don't add OCSP nonce to request\n");
5290Sstevel@tonic-gate 		BIO_printf (bio_err, "-url URL           OCSP responder URL\n");
5300Sstevel@tonic-gate 		BIO_printf (bio_err, "-host host:n       send OCSP request to host on port n\n");
5310Sstevel@tonic-gate 		BIO_printf (bio_err, "-path              path to use in OCSP request\n");
5320Sstevel@tonic-gate 		BIO_printf (bio_err, "-CApath dir        trusted certificates directory\n");
5330Sstevel@tonic-gate 		BIO_printf (bio_err, "-CAfile file       trusted certificates file\n");
5340Sstevel@tonic-gate 		BIO_printf (bio_err, "-VAfile file       validator certificates file\n");
5350Sstevel@tonic-gate 		BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
5360Sstevel@tonic-gate 		BIO_printf (bio_err, "-status_age n      maximum status age in seconds\n");
5370Sstevel@tonic-gate 		BIO_printf (bio_err, "-noverify          don't verify response at all\n");
5380Sstevel@tonic-gate 		BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n");
5390Sstevel@tonic-gate 		BIO_printf (bio_err, "-trust_other       don't verify additional certificates\n");
5400Sstevel@tonic-gate 		BIO_printf (bio_err, "-no_intern         don't search certificates contained in response for signer\n");
5410Sstevel@tonic-gate 		BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n");
5420Sstevel@tonic-gate 		BIO_printf (bio_err, "-no_cert_verify    don't check signing certificate\n");
5430Sstevel@tonic-gate 		BIO_printf (bio_err, "-no_chain          don't chain verify response\n");
5440Sstevel@tonic-gate 		BIO_printf (bio_err, "-no_cert_checks    don't do additional checks on signing certificate\n");
5450Sstevel@tonic-gate 		BIO_printf (bio_err, "-port num		 port to run responder on\n");
5460Sstevel@tonic-gate 		BIO_printf (bio_err, "-index file	 certificate status index file\n");
5470Sstevel@tonic-gate 		BIO_printf (bio_err, "-CA file		 CA certificate\n");
5480Sstevel@tonic-gate 		BIO_printf (bio_err, "-rsigner file	 responder certificate to sign responses with\n");
5490Sstevel@tonic-gate 		BIO_printf (bio_err, "-rkey file	 responder key to sign responses with\n");
5500Sstevel@tonic-gate 		BIO_printf (bio_err, "-rother file	 other certificates to include in response\n");
5510Sstevel@tonic-gate 		BIO_printf (bio_err, "-resp_no_certs     don't include any certificates in response\n");
5520Sstevel@tonic-gate 		BIO_printf (bio_err, "-nmin n	 	 number of minutes before next update\n");
5530Sstevel@tonic-gate 		BIO_printf (bio_err, "-ndays n	 	 number of days before next update\n");
5540Sstevel@tonic-gate 		BIO_printf (bio_err, "-resp_key_id       identify reponse by signing certificate key ID\n");
5550Sstevel@tonic-gate 		BIO_printf (bio_err, "-nrequest n        number of requests to accept (default unlimited)\n");
5560Sstevel@tonic-gate 		goto end;
5570Sstevel@tonic-gate 		}
5580Sstevel@tonic-gate 
5590Sstevel@tonic-gate 	if(outfile) out = BIO_new_file(outfile, "w");
5600Sstevel@tonic-gate 	else out = BIO_new_fp(stdout, BIO_NOCLOSE);
5610Sstevel@tonic-gate 
5620Sstevel@tonic-gate 	if(!out)
5630Sstevel@tonic-gate 		{
5640Sstevel@tonic-gate 		BIO_printf(bio_err, "Error opening output file\n");
5650Sstevel@tonic-gate 		goto end;
5660Sstevel@tonic-gate 		}
5670Sstevel@tonic-gate 
5680Sstevel@tonic-gate 	if (!req && (add_nonce != 2)) add_nonce = 0;
5690Sstevel@tonic-gate 
5700Sstevel@tonic-gate 	if (!req && reqin)
5710Sstevel@tonic-gate 		{
5720Sstevel@tonic-gate 		derbio = BIO_new_file(reqin, "rb");
5730Sstevel@tonic-gate 		if (!derbio)
5740Sstevel@tonic-gate 			{
5750Sstevel@tonic-gate 			BIO_printf(bio_err, "Error Opening OCSP request file\n");
5760Sstevel@tonic-gate 			goto end;
5770Sstevel@tonic-gate 			}
5780Sstevel@tonic-gate 		req = d2i_OCSP_REQUEST_bio(derbio, NULL);
5790Sstevel@tonic-gate 		BIO_free(derbio);
5800Sstevel@tonic-gate 		if(!req)
5810Sstevel@tonic-gate 			{
5820Sstevel@tonic-gate 			BIO_printf(bio_err, "Error reading OCSP request\n");
5830Sstevel@tonic-gate 			goto end;
5840Sstevel@tonic-gate 			}
5850Sstevel@tonic-gate 		}
5860Sstevel@tonic-gate 
5870Sstevel@tonic-gate 	if (!req && port)
5880Sstevel@tonic-gate 		{
5890Sstevel@tonic-gate 		acbio = init_responder(port);
5900Sstevel@tonic-gate 		if (!acbio)
5910Sstevel@tonic-gate 			goto end;
5920Sstevel@tonic-gate 		}
5930Sstevel@tonic-gate 
5940Sstevel@tonic-gate 	if (rsignfile && !rdb)
5950Sstevel@tonic-gate 		{
5960Sstevel@tonic-gate 		if (!rkeyfile) rkeyfile = rsignfile;
5970Sstevel@tonic-gate 		rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,
5980Sstevel@tonic-gate 			NULL, e, "responder certificate");
5990Sstevel@tonic-gate 		if (!rsigner)
6000Sstevel@tonic-gate 			{
6010Sstevel@tonic-gate 			BIO_printf(bio_err, "Error loading responder certificate\n");
6020Sstevel@tonic-gate 			goto end;
6030Sstevel@tonic-gate 			}
6040Sstevel@tonic-gate 		rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,
6050Sstevel@tonic-gate 			NULL, e, "CA certificate");
6060Sstevel@tonic-gate 		if (rcertfile)
6070Sstevel@tonic-gate 			{
6080Sstevel@tonic-gate 			rother = load_certs(bio_err, rcertfile, FORMAT_PEM,
6090Sstevel@tonic-gate 				NULL, e, "responder other certificates");
6100Sstevel@tonic-gate 			if (!rother) goto end;
6110Sstevel@tonic-gate 			}
6120Sstevel@tonic-gate 		rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL,
6130Sstevel@tonic-gate 			"responder private key");
6140Sstevel@tonic-gate 		if (!rkey)
6150Sstevel@tonic-gate 			goto end;
6160Sstevel@tonic-gate 		}
6170Sstevel@tonic-gate 	if(acbio)
6180Sstevel@tonic-gate 		BIO_printf(bio_err, "Waiting for OCSP client connections...\n");
6190Sstevel@tonic-gate 
6200Sstevel@tonic-gate 	redo_accept:
6210Sstevel@tonic-gate 
6220Sstevel@tonic-gate 	if (acbio)
6230Sstevel@tonic-gate 		{
6240Sstevel@tonic-gate 		if (!do_responder(&req, &cbio, acbio, port))
6250Sstevel@tonic-gate 			goto end;
6260Sstevel@tonic-gate 		if (!req)
6270Sstevel@tonic-gate 			{
6280Sstevel@tonic-gate 			resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
6290Sstevel@tonic-gate 			send_ocsp_response(cbio, resp);
6300Sstevel@tonic-gate 			goto done_resp;
6310Sstevel@tonic-gate 			}
6320Sstevel@tonic-gate 		}
6330Sstevel@tonic-gate 
6340Sstevel@tonic-gate 	if (!req && (signfile || reqout || host || add_nonce || ridx_filename))
6350Sstevel@tonic-gate 		{
6360Sstevel@tonic-gate 		BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
6370Sstevel@tonic-gate 		goto end;
6380Sstevel@tonic-gate 		}
6390Sstevel@tonic-gate 
6400Sstevel@tonic-gate 	if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1);
6410Sstevel@tonic-gate 
6420Sstevel@tonic-gate 	if (signfile)
6430Sstevel@tonic-gate 		{
6440Sstevel@tonic-gate 		if (!keyfile) keyfile = signfile;
6450Sstevel@tonic-gate 		signer = load_cert(bio_err, signfile, FORMAT_PEM,
6460Sstevel@tonic-gate 			NULL, e, "signer certificate");
6470Sstevel@tonic-gate 		if (!signer)
6480Sstevel@tonic-gate 			{
6490Sstevel@tonic-gate 			BIO_printf(bio_err, "Error loading signer certificate\n");
6500Sstevel@tonic-gate 			goto end;
6510Sstevel@tonic-gate 			}
6520Sstevel@tonic-gate 		if (sign_certfile)
6530Sstevel@tonic-gate 			{
6540Sstevel@tonic-gate 			sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,
6550Sstevel@tonic-gate 				NULL, e, "signer certificates");
6560Sstevel@tonic-gate 			if (!sign_other) goto end;
6570Sstevel@tonic-gate 			}
6580Sstevel@tonic-gate 		key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL,
6590Sstevel@tonic-gate 			"signer private key");
6600Sstevel@tonic-gate 		if (!key)
6610Sstevel@tonic-gate 			goto end;
6620Sstevel@tonic-gate 		if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags))
6630Sstevel@tonic-gate 			{
6640Sstevel@tonic-gate 			BIO_printf(bio_err, "Error signing OCSP request\n");
6650Sstevel@tonic-gate 			goto end;
6660Sstevel@tonic-gate 			}
6670Sstevel@tonic-gate 		}
6680Sstevel@tonic-gate 
6690Sstevel@tonic-gate 	if (req_text && req) OCSP_REQUEST_print(out, req, 0);
6700Sstevel@tonic-gate 
6710Sstevel@tonic-gate 	if (reqout)
6720Sstevel@tonic-gate 		{
6730Sstevel@tonic-gate 		derbio = BIO_new_file(reqout, "wb");
6740Sstevel@tonic-gate 		if(!derbio)
6750Sstevel@tonic-gate 			{
6760Sstevel@tonic-gate 			BIO_printf(bio_err, "Error opening file %s\n", reqout);
6770Sstevel@tonic-gate 			goto end;
6780Sstevel@tonic-gate 			}
6790Sstevel@tonic-gate 		i2d_OCSP_REQUEST_bio(derbio, req);
6800Sstevel@tonic-gate 		BIO_free(derbio);
6810Sstevel@tonic-gate 		}
6820Sstevel@tonic-gate 
6830Sstevel@tonic-gate 	if (ridx_filename && (!rkey || !rsigner || !rca_cert))
6840Sstevel@tonic-gate 		{
6850Sstevel@tonic-gate 		BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n");
6860Sstevel@tonic-gate 		goto end;
6870Sstevel@tonic-gate 		}
6880Sstevel@tonic-gate 
6890Sstevel@tonic-gate 	if (ridx_filename && !rdb)
6900Sstevel@tonic-gate 		{
6910Sstevel@tonic-gate 		rdb = load_index(ridx_filename, NULL);
6920Sstevel@tonic-gate 		if (!rdb) goto end;
6930Sstevel@tonic-gate 		if (!index_index(rdb)) goto end;
6940Sstevel@tonic-gate 		}
6950Sstevel@tonic-gate 
6960Sstevel@tonic-gate 	if (rdb)
6970Sstevel@tonic-gate 		{
6980Sstevel@tonic-gate 		i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays);
6990Sstevel@tonic-gate 		if (cbio)
7000Sstevel@tonic-gate 			send_ocsp_response(cbio, resp);
7010Sstevel@tonic-gate 		}
7020Sstevel@tonic-gate 	else if (host)
7030Sstevel@tonic-gate 		{
7040Sstevel@tonic-gate #ifndef OPENSSL_NO_SOCK
7050Sstevel@tonic-gate 		cbio = BIO_new_connect(host);
7060Sstevel@tonic-gate #else
7070Sstevel@tonic-gate 		BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n");
7080Sstevel@tonic-gate 		goto end;
7090Sstevel@tonic-gate #endif
7100Sstevel@tonic-gate 		if (!cbio)
7110Sstevel@tonic-gate 			{
7120Sstevel@tonic-gate 			BIO_printf(bio_err, "Error creating connect BIO\n");
7130Sstevel@tonic-gate 			goto end;
7140Sstevel@tonic-gate 			}
7150Sstevel@tonic-gate 		if (port) BIO_set_conn_port(cbio, port);
7160Sstevel@tonic-gate 		if (use_ssl == 1)
7170Sstevel@tonic-gate 			{
7180Sstevel@tonic-gate 			BIO *sbio;
7190Sstevel@tonic-gate #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
7200Sstevel@tonic-gate 			ctx = SSL_CTX_new(SSLv23_client_method());
7210Sstevel@tonic-gate #elif !defined(OPENSSL_NO_SSL3)
7220Sstevel@tonic-gate 			ctx = SSL_CTX_new(SSLv3_client_method());
7230Sstevel@tonic-gate #elif !defined(OPENSSL_NO_SSL2)
7240Sstevel@tonic-gate 			ctx = SSL_CTX_new(SSLv2_client_method());
7250Sstevel@tonic-gate #else
7260Sstevel@tonic-gate 			BIO_printf(bio_err, "SSL is disabled\n");
7270Sstevel@tonic-gate 			goto end;
7280Sstevel@tonic-gate #endif
7290Sstevel@tonic-gate 			SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
7300Sstevel@tonic-gate 			sbio = BIO_new_ssl(ctx, 1);
7310Sstevel@tonic-gate 			cbio = BIO_push(sbio, cbio);
7320Sstevel@tonic-gate 			}
7330Sstevel@tonic-gate 		if (BIO_do_connect(cbio) <= 0)
7340Sstevel@tonic-gate 			{
7350Sstevel@tonic-gate 			BIO_printf(bio_err, "Error connecting BIO\n");
7360Sstevel@tonic-gate 			goto end;
7370Sstevel@tonic-gate 			}
7380Sstevel@tonic-gate 		resp = OCSP_sendreq_bio(cbio, path, req);
7390Sstevel@tonic-gate 		BIO_free_all(cbio);
7400Sstevel@tonic-gate 		cbio = NULL;
7410Sstevel@tonic-gate 		if (!resp)
7420Sstevel@tonic-gate 			{
7430Sstevel@tonic-gate 			BIO_printf(bio_err, "Error querying OCSP responsder\n");
7440Sstevel@tonic-gate 			goto end;
7450Sstevel@tonic-gate 			}
7460Sstevel@tonic-gate 		}
7470Sstevel@tonic-gate 	else if (respin)
7480Sstevel@tonic-gate 		{
7490Sstevel@tonic-gate 		derbio = BIO_new_file(respin, "rb");
7500Sstevel@tonic-gate 		if (!derbio)
7510Sstevel@tonic-gate 			{
7520Sstevel@tonic-gate 			BIO_printf(bio_err, "Error Opening OCSP response file\n");
7530Sstevel@tonic-gate 			goto end;
7540Sstevel@tonic-gate 			}
7550Sstevel@tonic-gate 		resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
7560Sstevel@tonic-gate 		BIO_free(derbio);
7570Sstevel@tonic-gate 		if(!resp)
7580Sstevel@tonic-gate 			{
7590Sstevel@tonic-gate 			BIO_printf(bio_err, "Error reading OCSP response\n");
7600Sstevel@tonic-gate 			goto end;
7610Sstevel@tonic-gate 			}
7620Sstevel@tonic-gate 
7630Sstevel@tonic-gate 		}
7640Sstevel@tonic-gate 	else
7650Sstevel@tonic-gate 		{
7660Sstevel@tonic-gate 		ret = 0;
7670Sstevel@tonic-gate 		goto end;
7680Sstevel@tonic-gate 		}
7690Sstevel@tonic-gate 
7700Sstevel@tonic-gate 	done_resp:
7710Sstevel@tonic-gate 
7720Sstevel@tonic-gate 	if (respout)
7730Sstevel@tonic-gate 		{
7740Sstevel@tonic-gate 		derbio = BIO_new_file(respout, "wb");
7750Sstevel@tonic-gate 		if(!derbio)
7760Sstevel@tonic-gate 			{
7770Sstevel@tonic-gate 			BIO_printf(bio_err, "Error opening file %s\n", respout);
7780Sstevel@tonic-gate 			goto end;
7790Sstevel@tonic-gate 			}
7800Sstevel@tonic-gate 		i2d_OCSP_RESPONSE_bio(derbio, resp);
7810Sstevel@tonic-gate 		BIO_free(derbio);
7820Sstevel@tonic-gate 		}
7830Sstevel@tonic-gate 
7840Sstevel@tonic-gate 	i = OCSP_response_status(resp);
7850Sstevel@tonic-gate 
7860Sstevel@tonic-gate 	if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL)
7870Sstevel@tonic-gate 		{
788*2139Sjp161948 		BIO_printf(out, "Responder Error: %s (%d)\n",
7890Sstevel@tonic-gate 				OCSP_response_status_str(i), i);
7900Sstevel@tonic-gate 		if (ignore_err)
7910Sstevel@tonic-gate 			goto redo_accept;
7920Sstevel@tonic-gate 		ret = 0;
7930Sstevel@tonic-gate 		goto end;
7940Sstevel@tonic-gate 		}
7950Sstevel@tonic-gate 
7960Sstevel@tonic-gate 	if (resp_text) OCSP_RESPONSE_print(out, resp, 0);
7970Sstevel@tonic-gate 
7980Sstevel@tonic-gate 	/* If running as responder don't verify our own response */
7990Sstevel@tonic-gate 	if (cbio)
8000Sstevel@tonic-gate 		{
8010Sstevel@tonic-gate 		if (accept_count > 0)
8020Sstevel@tonic-gate 			accept_count--;
8030Sstevel@tonic-gate 		/* Redo if more connections needed */
8040Sstevel@tonic-gate 		if (accept_count)
8050Sstevel@tonic-gate 			{
8060Sstevel@tonic-gate 			BIO_free_all(cbio);
8070Sstevel@tonic-gate 			cbio = NULL;
8080Sstevel@tonic-gate 			OCSP_REQUEST_free(req);
8090Sstevel@tonic-gate 			req = NULL;
8100Sstevel@tonic-gate 			OCSP_RESPONSE_free(resp);
8110Sstevel@tonic-gate 			resp = NULL;
8120Sstevel@tonic-gate 			goto redo_accept;
8130Sstevel@tonic-gate 			}
8140Sstevel@tonic-gate 		goto end;
8150Sstevel@tonic-gate 		}
8160Sstevel@tonic-gate 
8170Sstevel@tonic-gate 	if (!store)
8180Sstevel@tonic-gate 		store = setup_verify(bio_err, CAfile, CApath);
8190Sstevel@tonic-gate 	if (!store)
8200Sstevel@tonic-gate 		goto end;
8210Sstevel@tonic-gate 	if (verify_certfile)
8220Sstevel@tonic-gate 		{
8230Sstevel@tonic-gate 		verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,
8240Sstevel@tonic-gate 			NULL, e, "validator certificate");
8250Sstevel@tonic-gate 		if (!verify_other) goto end;
8260Sstevel@tonic-gate 		}
8270Sstevel@tonic-gate 
8280Sstevel@tonic-gate 	bs = OCSP_response_get1_basic(resp);
8290Sstevel@tonic-gate 
8300Sstevel@tonic-gate 	if (!bs)
8310Sstevel@tonic-gate 		{
8320Sstevel@tonic-gate 		BIO_printf(bio_err, "Error parsing response\n");
8330Sstevel@tonic-gate 		goto end;
8340Sstevel@tonic-gate 		}
8350Sstevel@tonic-gate 
8360Sstevel@tonic-gate 	if (!noverify)
8370Sstevel@tonic-gate 		{
8380Sstevel@tonic-gate 		if (req && ((i = OCSP_check_nonce(req, bs)) <= 0))
8390Sstevel@tonic-gate 			{
8400Sstevel@tonic-gate 			if (i == -1)
8410Sstevel@tonic-gate 				BIO_printf(bio_err, "WARNING: no nonce in response\n");
8420Sstevel@tonic-gate 			else
8430Sstevel@tonic-gate 				{
8440Sstevel@tonic-gate 				BIO_printf(bio_err, "Nonce Verify error\n");
8450Sstevel@tonic-gate 				goto end;
8460Sstevel@tonic-gate 				}
8470Sstevel@tonic-gate 			}
8480Sstevel@tonic-gate 
8490Sstevel@tonic-gate 		i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
8500Sstevel@tonic-gate                 if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0);
8510Sstevel@tonic-gate 
8520Sstevel@tonic-gate 		if(i <= 0)
8530Sstevel@tonic-gate 			{
854*2139Sjp161948 			BIO_printf(bio_err, "Response Verify Failure\n");
8550Sstevel@tonic-gate 			ERR_print_errors(bio_err);
8560Sstevel@tonic-gate 			}
8570Sstevel@tonic-gate 		else
8580Sstevel@tonic-gate 			BIO_printf(bio_err, "Response verify OK\n");
8590Sstevel@tonic-gate 
8600Sstevel@tonic-gate 		}
8610Sstevel@tonic-gate 
8620Sstevel@tonic-gate 	if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage))
8630Sstevel@tonic-gate 		goto end;
8640Sstevel@tonic-gate 
8650Sstevel@tonic-gate 	ret = 0;
8660Sstevel@tonic-gate 
8670Sstevel@tonic-gate end:
8680Sstevel@tonic-gate 	ERR_print_errors(bio_err);
8690Sstevel@tonic-gate 	X509_free(signer);
8700Sstevel@tonic-gate 	X509_STORE_free(store);
8710Sstevel@tonic-gate 	EVP_PKEY_free(key);
8720Sstevel@tonic-gate 	EVP_PKEY_free(rkey);
8730Sstevel@tonic-gate 	X509_free(issuer);
8740Sstevel@tonic-gate 	X509_free(cert);
8750Sstevel@tonic-gate 	X509_free(rsigner);
8760Sstevel@tonic-gate 	X509_free(rca_cert);
8770Sstevel@tonic-gate 	free_index(rdb);
8780Sstevel@tonic-gate 	BIO_free_all(cbio);
8790Sstevel@tonic-gate 	BIO_free_all(acbio);
8800Sstevel@tonic-gate 	BIO_free(out);
8810Sstevel@tonic-gate 	OCSP_REQUEST_free(req);
8820Sstevel@tonic-gate 	OCSP_RESPONSE_free(resp);
8830Sstevel@tonic-gate 	OCSP_BASICRESP_free(bs);
8840Sstevel@tonic-gate 	sk_free(reqnames);
8850Sstevel@tonic-gate 	sk_OCSP_CERTID_free(ids);
8860Sstevel@tonic-gate 	sk_X509_pop_free(sign_other, X509_free);
8870Sstevel@tonic-gate 	sk_X509_pop_free(verify_other, X509_free);
8880Sstevel@tonic-gate 
8890Sstevel@tonic-gate 	if (use_ssl != -1)
8900Sstevel@tonic-gate 		{
8910Sstevel@tonic-gate 		OPENSSL_free(host);
8920Sstevel@tonic-gate 		OPENSSL_free(port);
8930Sstevel@tonic-gate 		OPENSSL_free(path);
8940Sstevel@tonic-gate 		SSL_CTX_free(ctx);
8950Sstevel@tonic-gate 		}
8960Sstevel@tonic-gate 
8970Sstevel@tonic-gate 	OPENSSL_EXIT(ret);
8980Sstevel@tonic-gate }
8990Sstevel@tonic-gate 
add_ocsp_cert(OCSP_REQUEST ** req,X509 * cert,X509 * issuer,STACK_OF (OCSP_CERTID)* ids)9000Sstevel@tonic-gate static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
9010Sstevel@tonic-gate 				STACK_OF(OCSP_CERTID) *ids)
9020Sstevel@tonic-gate 	{
9030Sstevel@tonic-gate 	OCSP_CERTID *id;
9040Sstevel@tonic-gate 	if(!issuer)
9050Sstevel@tonic-gate 		{
9060Sstevel@tonic-gate 		BIO_printf(bio_err, "No issuer certificate specified\n");
9070Sstevel@tonic-gate 		return 0;
9080Sstevel@tonic-gate 		}
9090Sstevel@tonic-gate 	if(!*req) *req = OCSP_REQUEST_new();
9100Sstevel@tonic-gate 	if(!*req) goto err;
9110Sstevel@tonic-gate 	id = OCSP_cert_to_id(NULL, cert, issuer);
9120Sstevel@tonic-gate 	if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
9130Sstevel@tonic-gate 	if(!OCSP_request_add0_id(*req, id)) goto err;
9140Sstevel@tonic-gate 	return 1;
9150Sstevel@tonic-gate 
9160Sstevel@tonic-gate 	err:
9170Sstevel@tonic-gate 	BIO_printf(bio_err, "Error Creating OCSP request\n");
9180Sstevel@tonic-gate 	return 0;
9190Sstevel@tonic-gate 	}
9200Sstevel@tonic-gate 
add_ocsp_serial(OCSP_REQUEST ** req,char * serial,X509 * issuer,STACK_OF (OCSP_CERTID)* ids)9210Sstevel@tonic-gate static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
9220Sstevel@tonic-gate 				STACK_OF(OCSP_CERTID) *ids)
9230Sstevel@tonic-gate 	{
9240Sstevel@tonic-gate 	OCSP_CERTID *id;
9250Sstevel@tonic-gate 	X509_NAME *iname;
9260Sstevel@tonic-gate 	ASN1_BIT_STRING *ikey;
9270Sstevel@tonic-gate 	ASN1_INTEGER *sno;
9280Sstevel@tonic-gate 	if(!issuer)
9290Sstevel@tonic-gate 		{
9300Sstevel@tonic-gate 		BIO_printf(bio_err, "No issuer certificate specified\n");
9310Sstevel@tonic-gate 		return 0;
9320Sstevel@tonic-gate 		}
9330Sstevel@tonic-gate 	if(!*req) *req = OCSP_REQUEST_new();
9340Sstevel@tonic-gate 	if(!*req) goto err;
9350Sstevel@tonic-gate 	iname = X509_get_subject_name(issuer);
9360Sstevel@tonic-gate 	ikey = X509_get0_pubkey_bitstr(issuer);
9370Sstevel@tonic-gate 	sno = s2i_ASN1_INTEGER(NULL, serial);
9380Sstevel@tonic-gate 	if(!sno)
9390Sstevel@tonic-gate 		{
9400Sstevel@tonic-gate 		BIO_printf(bio_err, "Error converting serial number %s\n", serial);
9410Sstevel@tonic-gate 		return 0;
9420Sstevel@tonic-gate 		}
9430Sstevel@tonic-gate 	id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno);
9440Sstevel@tonic-gate 	ASN1_INTEGER_free(sno);
9450Sstevel@tonic-gate 	if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
9460Sstevel@tonic-gate 	if(!OCSP_request_add0_id(*req, id)) goto err;
9470Sstevel@tonic-gate 	return 1;
9480Sstevel@tonic-gate 
9490Sstevel@tonic-gate 	err:
9500Sstevel@tonic-gate 	BIO_printf(bio_err, "Error Creating OCSP request\n");
9510Sstevel@tonic-gate 	return 0;
9520Sstevel@tonic-gate 	}
9530Sstevel@tonic-gate 
print_ocsp_summary(BIO * out,OCSP_BASICRESP * bs,OCSP_REQUEST * req,STACK * names,STACK_OF (OCSP_CERTID)* ids,long nsec,long maxage)9540Sstevel@tonic-gate static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
9550Sstevel@tonic-gate 					STACK *names, STACK_OF(OCSP_CERTID) *ids,
9560Sstevel@tonic-gate 					long nsec, long maxage)
9570Sstevel@tonic-gate 	{
9580Sstevel@tonic-gate 	OCSP_CERTID *id;
9590Sstevel@tonic-gate 	char *name;
9600Sstevel@tonic-gate 	int i;
9610Sstevel@tonic-gate 
9620Sstevel@tonic-gate 	int status, reason;
9630Sstevel@tonic-gate 
9640Sstevel@tonic-gate 	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
9650Sstevel@tonic-gate 
9660Sstevel@tonic-gate 	if (!bs || !req || !sk_num(names) || !sk_OCSP_CERTID_num(ids))
9670Sstevel@tonic-gate 		return 1;
9680Sstevel@tonic-gate 
9690Sstevel@tonic-gate 	for (i = 0; i < sk_OCSP_CERTID_num(ids); i++)
9700Sstevel@tonic-gate 		{
9710Sstevel@tonic-gate 		id = sk_OCSP_CERTID_value(ids, i);
9720Sstevel@tonic-gate 		name = sk_value(names, i);
9730Sstevel@tonic-gate 		BIO_printf(out, "%s: ", name);
9740Sstevel@tonic-gate 
9750Sstevel@tonic-gate 		if(!OCSP_resp_find_status(bs, id, &status, &reason,
9760Sstevel@tonic-gate 					&rev, &thisupd, &nextupd))
9770Sstevel@tonic-gate 			{
9780Sstevel@tonic-gate 			BIO_puts(out, "ERROR: No Status found.\n");
9790Sstevel@tonic-gate 			continue;
9800Sstevel@tonic-gate 			}
9810Sstevel@tonic-gate 
9820Sstevel@tonic-gate 		/* Check validity: if invalid write to output BIO so we
9830Sstevel@tonic-gate 		 * know which response this refers to.
9840Sstevel@tonic-gate 		 */
9850Sstevel@tonic-gate 		if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage))
9860Sstevel@tonic-gate 			{
9870Sstevel@tonic-gate 			BIO_puts(out, "WARNING: Status times invalid.\n");
9880Sstevel@tonic-gate 			ERR_print_errors(out);
9890Sstevel@tonic-gate 			}
9900Sstevel@tonic-gate 		BIO_printf(out, "%s\n", OCSP_cert_status_str(status));
9910Sstevel@tonic-gate 
9920Sstevel@tonic-gate 		BIO_puts(out, "\tThis Update: ");
9930Sstevel@tonic-gate 		ASN1_GENERALIZEDTIME_print(out, thisupd);
9940Sstevel@tonic-gate 		BIO_puts(out, "\n");
9950Sstevel@tonic-gate 
9960Sstevel@tonic-gate 		if(nextupd)
9970Sstevel@tonic-gate 			{
9980Sstevel@tonic-gate 			BIO_puts(out, "\tNext Update: ");
9990Sstevel@tonic-gate 			ASN1_GENERALIZEDTIME_print(out, nextupd);
10000Sstevel@tonic-gate 			BIO_puts(out, "\n");
10010Sstevel@tonic-gate 			}
10020Sstevel@tonic-gate 
10030Sstevel@tonic-gate 		if (status != V_OCSP_CERTSTATUS_REVOKED)
10040Sstevel@tonic-gate 			continue;
10050Sstevel@tonic-gate 
10060Sstevel@tonic-gate 		if (reason != -1)
10070Sstevel@tonic-gate 			BIO_printf(out, "\tReason: %s\n",
10080Sstevel@tonic-gate 				OCSP_crl_reason_str(reason));
10090Sstevel@tonic-gate 
10100Sstevel@tonic-gate 		BIO_puts(out, "\tRevocation Time: ");
10110Sstevel@tonic-gate 		ASN1_GENERALIZEDTIME_print(out, rev);
10120Sstevel@tonic-gate 		BIO_puts(out, "\n");
10130Sstevel@tonic-gate 		}
10140Sstevel@tonic-gate 
10150Sstevel@tonic-gate 	return 1;
10160Sstevel@tonic-gate 	}
10170Sstevel@tonic-gate 
10180Sstevel@tonic-gate 
make_ocsp_response(OCSP_RESPONSE ** resp,OCSP_REQUEST * req,CA_DB * db,X509 * ca,X509 * rcert,EVP_PKEY * rkey,STACK_OF (X509)* rother,unsigned long flags,int nmin,int ndays)10190Sstevel@tonic-gate static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
10200Sstevel@tonic-gate 			X509 *ca, X509 *rcert, EVP_PKEY *rkey,
10210Sstevel@tonic-gate 			STACK_OF(X509) *rother, unsigned long flags,
10220Sstevel@tonic-gate 			int nmin, int ndays)
10230Sstevel@tonic-gate 	{
10240Sstevel@tonic-gate 	ASN1_TIME *thisupd = NULL, *nextupd = NULL;
10250Sstevel@tonic-gate 	OCSP_CERTID *cid, *ca_id = NULL;
10260Sstevel@tonic-gate 	OCSP_BASICRESP *bs = NULL;
10270Sstevel@tonic-gate 	int i, id_count, ret = 1;
10280Sstevel@tonic-gate 
10290Sstevel@tonic-gate 
10300Sstevel@tonic-gate 	id_count = OCSP_request_onereq_count(req);
10310Sstevel@tonic-gate 
10320Sstevel@tonic-gate 	if (id_count <= 0)
10330Sstevel@tonic-gate 		{
10340Sstevel@tonic-gate 		*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
10350Sstevel@tonic-gate 		goto end;
10360Sstevel@tonic-gate 		}
10370Sstevel@tonic-gate 
10380Sstevel@tonic-gate 	ca_id = OCSP_cert_to_id(EVP_sha1(), NULL, ca);
10390Sstevel@tonic-gate 
10400Sstevel@tonic-gate 	bs = OCSP_BASICRESP_new();
10410Sstevel@tonic-gate 	thisupd = X509_gmtime_adj(NULL, 0);
10420Sstevel@tonic-gate 	if (ndays != -1)
10430Sstevel@tonic-gate 		nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24 );
10440Sstevel@tonic-gate 
10450Sstevel@tonic-gate 	/* Examine each certificate id in the request */
10460Sstevel@tonic-gate 	for (i = 0; i < id_count; i++)
10470Sstevel@tonic-gate 		{
10480Sstevel@tonic-gate 		OCSP_ONEREQ *one;
10490Sstevel@tonic-gate 		ASN1_INTEGER *serial;
10500Sstevel@tonic-gate 		char **inf;
10510Sstevel@tonic-gate 		one = OCSP_request_onereq_get0(req, i);
10520Sstevel@tonic-gate 		cid = OCSP_onereq_get0_id(one);
10530Sstevel@tonic-gate 		/* Is this request about our CA? */
10540Sstevel@tonic-gate 		if (OCSP_id_issuer_cmp(ca_id, cid))
10550Sstevel@tonic-gate 			{
10560Sstevel@tonic-gate 			OCSP_basic_add1_status(bs, cid,
10570Sstevel@tonic-gate 						V_OCSP_CERTSTATUS_UNKNOWN,
10580Sstevel@tonic-gate 						0, NULL,
10590Sstevel@tonic-gate 						thisupd, nextupd);
10600Sstevel@tonic-gate 			continue;
10610Sstevel@tonic-gate 			}
10620Sstevel@tonic-gate 		OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
10630Sstevel@tonic-gate 		inf = lookup_serial(db, serial);
10640Sstevel@tonic-gate 		if (!inf)
10650Sstevel@tonic-gate 			OCSP_basic_add1_status(bs, cid,
10660Sstevel@tonic-gate 						V_OCSP_CERTSTATUS_UNKNOWN,
10670Sstevel@tonic-gate 						0, NULL,
10680Sstevel@tonic-gate 						thisupd, nextupd);
10690Sstevel@tonic-gate 		else if (inf[DB_type][0] == DB_TYPE_VAL)
10700Sstevel@tonic-gate 			OCSP_basic_add1_status(bs, cid,
10710Sstevel@tonic-gate 						V_OCSP_CERTSTATUS_GOOD,
10720Sstevel@tonic-gate 						0, NULL,
10730Sstevel@tonic-gate 						thisupd, nextupd);
10740Sstevel@tonic-gate 		else if (inf[DB_type][0] == DB_TYPE_REV)
10750Sstevel@tonic-gate 			{
10760Sstevel@tonic-gate 			ASN1_OBJECT *inst = NULL;
10770Sstevel@tonic-gate 			ASN1_TIME *revtm = NULL;
10780Sstevel@tonic-gate 			ASN1_GENERALIZEDTIME *invtm = NULL;
10790Sstevel@tonic-gate 			OCSP_SINGLERESP *single;
10800Sstevel@tonic-gate 			int reason = -1;
10810Sstevel@tonic-gate 			unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]);
10820Sstevel@tonic-gate 			single = OCSP_basic_add1_status(bs, cid,
10830Sstevel@tonic-gate 						V_OCSP_CERTSTATUS_REVOKED,
10840Sstevel@tonic-gate 						reason, revtm,
10850Sstevel@tonic-gate 						thisupd, nextupd);
10860Sstevel@tonic-gate 			if (invtm)
10870Sstevel@tonic-gate 				OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0);
10880Sstevel@tonic-gate 			else if (inst)
10890Sstevel@tonic-gate 				OCSP_SINGLERESP_add1_ext_i2d(single, NID_hold_instruction_code, inst, 0, 0);
10900Sstevel@tonic-gate 			ASN1_OBJECT_free(inst);
10910Sstevel@tonic-gate 			ASN1_TIME_free(revtm);
10920Sstevel@tonic-gate 			ASN1_GENERALIZEDTIME_free(invtm);
10930Sstevel@tonic-gate 			}
10940Sstevel@tonic-gate 		}
10950Sstevel@tonic-gate 
10960Sstevel@tonic-gate 	OCSP_copy_nonce(bs, req);
10970Sstevel@tonic-gate 
10980Sstevel@tonic-gate 	OCSP_basic_sign(bs, rcert, rkey, EVP_sha1(), rother, flags);
10990Sstevel@tonic-gate 
11000Sstevel@tonic-gate 	*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
11010Sstevel@tonic-gate 
11020Sstevel@tonic-gate 	end:
11030Sstevel@tonic-gate 	ASN1_TIME_free(thisupd);
11040Sstevel@tonic-gate 	ASN1_TIME_free(nextupd);
11050Sstevel@tonic-gate 	OCSP_CERTID_free(ca_id);
11060Sstevel@tonic-gate 	OCSP_BASICRESP_free(bs);
11070Sstevel@tonic-gate 	return ret;
11080Sstevel@tonic-gate 
11090Sstevel@tonic-gate 	}
11100Sstevel@tonic-gate 
lookup_serial(CA_DB * db,ASN1_INTEGER * ser)11110Sstevel@tonic-gate static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser)
11120Sstevel@tonic-gate 	{
11130Sstevel@tonic-gate 	int i;
11140Sstevel@tonic-gate 	BIGNUM *bn = NULL;
11150Sstevel@tonic-gate 	char *itmp, *row[DB_NUMBER],**rrow;
11160Sstevel@tonic-gate 	for (i = 0; i < DB_NUMBER; i++) row[i] = NULL;
11170Sstevel@tonic-gate 	bn = ASN1_INTEGER_to_BN(ser,NULL);
11180Sstevel@tonic-gate 	if (BN_is_zero(bn))
11190Sstevel@tonic-gate 		itmp = BUF_strdup("00");
11200Sstevel@tonic-gate 	else
11210Sstevel@tonic-gate 		itmp = BN_bn2hex(bn);
11220Sstevel@tonic-gate 	row[DB_serial] = itmp;
11230Sstevel@tonic-gate 	BN_free(bn);
11240Sstevel@tonic-gate 	rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
11250Sstevel@tonic-gate 	OPENSSL_free(itmp);
11260Sstevel@tonic-gate 	return rrow;
11270Sstevel@tonic-gate 	}
11280Sstevel@tonic-gate 
11290Sstevel@tonic-gate /* Quick and dirty OCSP server: read in and parse input request */
11300Sstevel@tonic-gate 
init_responder(char * port)11310Sstevel@tonic-gate static BIO *init_responder(char *port)
11320Sstevel@tonic-gate 	{
11330Sstevel@tonic-gate 	BIO *acbio = NULL, *bufbio = NULL;
11340Sstevel@tonic-gate 	bufbio = BIO_new(BIO_f_buffer());
11350Sstevel@tonic-gate 	if (!bufbio)
11360Sstevel@tonic-gate 		goto err;
11370Sstevel@tonic-gate #ifndef OPENSSL_NO_SOCK
11380Sstevel@tonic-gate 	acbio = BIO_new_accept(port);
11390Sstevel@tonic-gate #else
11400Sstevel@tonic-gate 	BIO_printf(bio_err, "Error setting up accept BIO - sockets not supported.\n");
11410Sstevel@tonic-gate #endif
11420Sstevel@tonic-gate 	if (!acbio)
11430Sstevel@tonic-gate 		goto err;
11440Sstevel@tonic-gate 	BIO_set_accept_bios(acbio, bufbio);
11450Sstevel@tonic-gate 	bufbio = NULL;
11460Sstevel@tonic-gate 
11470Sstevel@tonic-gate 	if (BIO_do_accept(acbio) <= 0)
11480Sstevel@tonic-gate 		{
11490Sstevel@tonic-gate 			BIO_printf(bio_err, "Error setting up accept BIO\n");
11500Sstevel@tonic-gate 			ERR_print_errors(bio_err);
11510Sstevel@tonic-gate 			goto err;
11520Sstevel@tonic-gate 		}
11530Sstevel@tonic-gate 
11540Sstevel@tonic-gate 	return acbio;
11550Sstevel@tonic-gate 
11560Sstevel@tonic-gate 	err:
11570Sstevel@tonic-gate 	BIO_free_all(acbio);
11580Sstevel@tonic-gate 	BIO_free(bufbio);
11590Sstevel@tonic-gate 	return NULL;
11600Sstevel@tonic-gate 	}
11610Sstevel@tonic-gate 
do_responder(OCSP_REQUEST ** preq,BIO ** pcbio,BIO * acbio,char * port)11620Sstevel@tonic-gate static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port)
11630Sstevel@tonic-gate 	{
11640Sstevel@tonic-gate 	int have_post = 0, len;
11650Sstevel@tonic-gate 	OCSP_REQUEST *req = NULL;
11660Sstevel@tonic-gate 	char inbuf[1024];
11670Sstevel@tonic-gate 	BIO *cbio = NULL;
11680Sstevel@tonic-gate 
11690Sstevel@tonic-gate 	if (BIO_do_accept(acbio) <= 0)
11700Sstevel@tonic-gate 		{
11710Sstevel@tonic-gate 			BIO_printf(bio_err, "Error accepting connection\n");
11720Sstevel@tonic-gate 			ERR_print_errors(bio_err);
11730Sstevel@tonic-gate 			return 0;
11740Sstevel@tonic-gate 		}
11750Sstevel@tonic-gate 
11760Sstevel@tonic-gate 	cbio = BIO_pop(acbio);
11770Sstevel@tonic-gate 	*pcbio = cbio;
11780Sstevel@tonic-gate 
11790Sstevel@tonic-gate 	for(;;)
11800Sstevel@tonic-gate 		{
11810Sstevel@tonic-gate 		len = BIO_gets(cbio, inbuf, sizeof inbuf);
11820Sstevel@tonic-gate 		if (len <= 0)
11830Sstevel@tonic-gate 			return 1;
11840Sstevel@tonic-gate 		/* Look for "POST" signalling start of query */
11850Sstevel@tonic-gate 		if (!have_post)
11860Sstevel@tonic-gate 			{
11870Sstevel@tonic-gate 			if(strncmp(inbuf, "POST", 4))
11880Sstevel@tonic-gate 				{
11890Sstevel@tonic-gate 				BIO_printf(bio_err, "Invalid request\n");
11900Sstevel@tonic-gate 				return 1;
11910Sstevel@tonic-gate 				}
11920Sstevel@tonic-gate 			have_post = 1;
11930Sstevel@tonic-gate 			}
11940Sstevel@tonic-gate 		/* Look for end of headers */
11950Sstevel@tonic-gate 		if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
11960Sstevel@tonic-gate 			break;
11970Sstevel@tonic-gate 		}
11980Sstevel@tonic-gate 
11990Sstevel@tonic-gate 	/* Try to read OCSP request */
12000Sstevel@tonic-gate 
12010Sstevel@tonic-gate 	req = d2i_OCSP_REQUEST_bio(cbio, NULL);
12020Sstevel@tonic-gate 
12030Sstevel@tonic-gate 	if (!req)
12040Sstevel@tonic-gate 		{
12050Sstevel@tonic-gate 		BIO_printf(bio_err, "Error parsing OCSP request\n");
12060Sstevel@tonic-gate 		ERR_print_errors(bio_err);
12070Sstevel@tonic-gate 		}
12080Sstevel@tonic-gate 
12090Sstevel@tonic-gate 	*preq = req;
12100Sstevel@tonic-gate 
12110Sstevel@tonic-gate 	return 1;
12120Sstevel@tonic-gate 
12130Sstevel@tonic-gate 	}
12140Sstevel@tonic-gate 
send_ocsp_response(BIO * cbio,OCSP_RESPONSE * resp)12150Sstevel@tonic-gate static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
12160Sstevel@tonic-gate 	{
12170Sstevel@tonic-gate 	char http_resp[] =
12180Sstevel@tonic-gate 		"HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n"
12190Sstevel@tonic-gate 		"Content-Length: %d\r\n\r\n";
12200Sstevel@tonic-gate 	if (!cbio)
12210Sstevel@tonic-gate 		return 0;
12220Sstevel@tonic-gate 	BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL));
12230Sstevel@tonic-gate 	i2d_OCSP_RESPONSE_bio(cbio, resp);
12240Sstevel@tonic-gate 	BIO_flush(cbio);
12250Sstevel@tonic-gate 	return 1;
12260Sstevel@tonic-gate 	}
12270Sstevel@tonic-gate 
12280Sstevel@tonic-gate #endif
1229