xref: /freebsd/crypto/openssl/apps/ocsp.c (revision fceca8a37790004b7d28e0ba02bd2d47101a818f)
15c87c606SMark Murray /* ocsp.c */
25c87c606SMark Murray /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
35c87c606SMark Murray  * project 2000.
45c87c606SMark Murray  */
55c87c606SMark Murray /* ====================================================================
65c87c606SMark Murray  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
75c87c606SMark Murray  *
85c87c606SMark Murray  * Redistribution and use in source and binary forms, with or without
95c87c606SMark Murray  * modification, are permitted provided that the following conditions
105c87c606SMark Murray  * are met:
115c87c606SMark Murray  *
125c87c606SMark Murray  * 1. Redistributions of source code must retain the above copyright
135c87c606SMark Murray  *    notice, this list of conditions and the following disclaimer.
145c87c606SMark Murray  *
155c87c606SMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
165c87c606SMark Murray  *    notice, this list of conditions and the following disclaimer in
175c87c606SMark Murray  *    the documentation and/or other materials provided with the
185c87c606SMark Murray  *    distribution.
195c87c606SMark Murray  *
205c87c606SMark Murray  * 3. All advertising materials mentioning features or use of this
215c87c606SMark Murray  *    software must display the following acknowledgment:
225c87c606SMark Murray  *    "This product includes software developed by the OpenSSL Project
235c87c606SMark Murray  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
245c87c606SMark Murray  *
255c87c606SMark Murray  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
265c87c606SMark Murray  *    endorse or promote products derived from this software without
275c87c606SMark Murray  *    prior written permission. For written permission, please contact
285c87c606SMark Murray  *    licensing@OpenSSL.org.
295c87c606SMark Murray  *
305c87c606SMark Murray  * 5. Products derived from this software may not be called "OpenSSL"
315c87c606SMark Murray  *    nor may "OpenSSL" appear in their names without prior written
325c87c606SMark Murray  *    permission of the OpenSSL Project.
335c87c606SMark Murray  *
345c87c606SMark Murray  * 6. Redistributions of any form whatsoever must retain the following
355c87c606SMark Murray  *    acknowledgment:
365c87c606SMark Murray  *    "This product includes software developed by the OpenSSL Project
375c87c606SMark Murray  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
385c87c606SMark Murray  *
395c87c606SMark Murray  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
405c87c606SMark Murray  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
415c87c606SMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
425c87c606SMark Murray  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
435c87c606SMark Murray  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
445c87c606SMark Murray  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
455c87c606SMark Murray  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
465c87c606SMark Murray  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
475c87c606SMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
485c87c606SMark Murray  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
495c87c606SMark Murray  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
505c87c606SMark Murray  * OF THE POSSIBILITY OF SUCH DAMAGE.
515c87c606SMark Murray  * ====================================================================
525c87c606SMark Murray  *
535c87c606SMark Murray  * This product includes cryptographic software written by Eric Young
545c87c606SMark Murray  * (eay@cryptsoft.com).  This product includes software written by Tim
555c87c606SMark Murray  * Hudson (tjh@cryptsoft.com).
565c87c606SMark Murray  *
575c87c606SMark Murray  */
58fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_OCSP
595c87c606SMark Murray 
605c87c606SMark Murray #include <stdio.h>
615c87c606SMark Murray #include <string.h>
625c87c606SMark Murray #include "apps.h"
635c87c606SMark Murray #include <openssl/pem.h>
645c87c606SMark Murray #include <openssl/ocsp.h>
655c87c606SMark Murray #include <openssl/err.h>
665c87c606SMark Murray #include <openssl/ssl.h>
675c87c606SMark Murray 
685c87c606SMark Murray /* Maximum leeway in validity period: default 5 minutes */
695c87c606SMark Murray #define MAX_VALIDITY_PERIOD	(5 * 60)
705c87c606SMark Murray 
715c87c606SMark Murray /* CA index.txt definitions */
725c87c606SMark Murray #define DB_type         0
735c87c606SMark Murray #define DB_exp_date     1
745c87c606SMark Murray #define DB_rev_date     2
755c87c606SMark Murray #define DB_serial       3       /* index - unique */
765c87c606SMark Murray #define DB_file         4
775c87c606SMark Murray #define DB_name         5       /* index - unique for active */
785c87c606SMark Murray #define DB_NUMBER       6
795c87c606SMark Murray 
805c87c606SMark Murray #define DB_TYPE_REV	'R'
815c87c606SMark Murray #define DB_TYPE_EXP	'E'
825c87c606SMark Murray #define DB_TYPE_VAL	'V'
835c87c606SMark Murray 
845c87c606SMark Murray static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
855c87c606SMark Murray 				STACK_OF(OCSP_CERTID) *ids);
865c87c606SMark Murray static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
875c87c606SMark Murray 				STACK_OF(OCSP_CERTID) *ids);
885c87c606SMark Murray static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
895c87c606SMark Murray 				STACK *names, STACK_OF(OCSP_CERTID) *ids,
905c87c606SMark Murray 				long nsec, long maxage);
915c87c606SMark Murray 
925c87c606SMark Murray static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, TXT_DB *db,
935c87c606SMark Murray 			X509 *ca, X509 *rcert, EVP_PKEY *rkey,
945c87c606SMark Murray 			STACK_OF(X509) *rother, unsigned long flags,
955c87c606SMark Murray 			int nmin, int ndays);
965c87c606SMark Murray 
975c87c606SMark Murray static char **lookup_serial(TXT_DB *db, ASN1_INTEGER *ser);
985c87c606SMark Murray static BIO *init_responder(char *port);
995c87c606SMark Murray static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port);
1005c87c606SMark Murray static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
1015c87c606SMark Murray 
1025c87c606SMark Murray #undef PROG
1035c87c606SMark Murray #define PROG ocsp_main
1045c87c606SMark Murray 
1055c87c606SMark Murray int MAIN(int, char **);
1065c87c606SMark Murray 
1075c87c606SMark Murray int MAIN(int argc, char **argv)
1085c87c606SMark Murray 	{
1095c87c606SMark Murray 	ENGINE *e = NULL;
1105c87c606SMark Murray 	char **args;
1115c87c606SMark Murray 	char *host = NULL, *port = NULL, *path = "/";
1125c87c606SMark Murray 	char *reqin = NULL, *respin = NULL;
1135c87c606SMark Murray 	char *reqout = NULL, *respout = NULL;
1145c87c606SMark Murray 	char *signfile = NULL, *keyfile = NULL;
1155c87c606SMark Murray 	char *rsignfile = NULL, *rkeyfile = NULL;
1165c87c606SMark Murray 	char *outfile = NULL;
1175c87c606SMark Murray 	int add_nonce = 1, noverify = 0, use_ssl = -1;
1185c87c606SMark Murray 	OCSP_REQUEST *req = NULL;
1195c87c606SMark Murray 	OCSP_RESPONSE *resp = NULL;
1205c87c606SMark Murray 	OCSP_BASICRESP *bs = NULL;
1215c87c606SMark Murray 	X509 *issuer = NULL, *cert = NULL;
1225c87c606SMark Murray 	X509 *signer = NULL, *rsigner = NULL;
1235c87c606SMark Murray 	EVP_PKEY *key = NULL, *rkey = NULL;
1245c87c606SMark Murray 	BIO *acbio = NULL, *cbio = NULL;
1255c87c606SMark Murray 	BIO *derbio = NULL;
1265c87c606SMark Murray 	BIO *out = NULL;
1275c87c606SMark Murray 	int req_text = 0, resp_text = 0;
1285c87c606SMark Murray 	long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
1295c87c606SMark Murray 	char *CAfile = NULL, *CApath = NULL;
1305c87c606SMark Murray 	X509_STORE *store = NULL;
1315c87c606SMark Murray 	SSL_CTX *ctx = NULL;
1325c87c606SMark Murray 	STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
1335c87c606SMark Murray 	char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
1345c87c606SMark Murray 	unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
1355c87c606SMark Murray 	int ret = 1;
1365c87c606SMark Murray 	int accept_count = -1;
1375c87c606SMark Murray 	int badarg = 0;
1385c87c606SMark Murray 	int i;
1395c87c606SMark Murray 	STACK *reqnames = NULL;
1405c87c606SMark Murray 	STACK_OF(OCSP_CERTID) *ids = NULL;
1415c87c606SMark Murray 
1425c87c606SMark Murray 	X509 *rca_cert = NULL;
1435c87c606SMark Murray 	char *ridx_filename = NULL;
1445c87c606SMark Murray 	char *rca_filename = NULL;
1455c87c606SMark Murray 	TXT_DB *rdb = NULL;
1465c87c606SMark Murray 	int nmin = 0, ndays = -1;
1475c87c606SMark Murray 
1485c87c606SMark Murray 	if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
1495c87c606SMark Murray 
1505c87c606SMark Murray 	if (!load_config(bio_err, NULL))
1515c87c606SMark Murray 		goto end;
1525c87c606SMark Murray 	SSL_load_error_strings();
1535c87c606SMark Murray 	args = argv + 1;
1545c87c606SMark Murray 	reqnames = sk_new_null();
1555c87c606SMark Murray 	ids = sk_OCSP_CERTID_new_null();
1565c87c606SMark Murray 	while (!badarg && *args && *args[0] == '-')
1575c87c606SMark Murray 		{
1585c87c606SMark Murray 		if (!strcmp(*args, "-out"))
1595c87c606SMark Murray 			{
1605c87c606SMark Murray 			if (args[1])
1615c87c606SMark Murray 				{
1625c87c606SMark Murray 				args++;
1635c87c606SMark Murray 				outfile = *args;
1645c87c606SMark Murray 				}
1655c87c606SMark Murray 			else badarg = 1;
1665c87c606SMark Murray 			}
1675c87c606SMark Murray 		else if (!strcmp(*args, "-url"))
1685c87c606SMark Murray 			{
1695c87c606SMark Murray 			if (args[1])
1705c87c606SMark Murray 				{
1715c87c606SMark Murray 				args++;
1725c87c606SMark Murray 				if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl))
1735c87c606SMark Murray 					{
1745c87c606SMark Murray 					BIO_printf(bio_err, "Error parsing URL\n");
1755c87c606SMark Murray 					badarg = 1;
1765c87c606SMark Murray 					}
1775c87c606SMark Murray 				}
1785c87c606SMark Murray 			else badarg = 1;
1795c87c606SMark Murray 			}
1805c87c606SMark Murray 		else if (!strcmp(*args, "-host"))
1815c87c606SMark Murray 			{
1825c87c606SMark Murray 			if (args[1])
1835c87c606SMark Murray 				{
1845c87c606SMark Murray 				args++;
1855c87c606SMark Murray 				host = *args;
1865c87c606SMark Murray 				}
1875c87c606SMark Murray 			else badarg = 1;
1885c87c606SMark Murray 			}
1895c87c606SMark Murray 		else if (!strcmp(*args, "-port"))
1905c87c606SMark Murray 			{
1915c87c606SMark Murray 			if (args[1])
1925c87c606SMark Murray 				{
1935c87c606SMark Murray 				args++;
1945c87c606SMark Murray 				port = *args;
1955c87c606SMark Murray 				}
1965c87c606SMark Murray 			else badarg = 1;
1975c87c606SMark Murray 			}
1985c87c606SMark Murray 		else if (!strcmp(*args, "-noverify"))
1995c87c606SMark Murray 			noverify = 1;
2005c87c606SMark Murray 		else if (!strcmp(*args, "-nonce"))
2015c87c606SMark Murray 			add_nonce = 2;
2025c87c606SMark Murray 		else if (!strcmp(*args, "-no_nonce"))
2035c87c606SMark Murray 			add_nonce = 0;
2045c87c606SMark Murray 		else if (!strcmp(*args, "-resp_no_certs"))
2055c87c606SMark Murray 			rflags |= OCSP_NOCERTS;
2065c87c606SMark Murray 		else if (!strcmp(*args, "-resp_key_id"))
2075c87c606SMark Murray 			rflags |= OCSP_RESPID_KEY;
2085c87c606SMark Murray 		else if (!strcmp(*args, "-no_certs"))
2095c87c606SMark Murray 			sign_flags |= OCSP_NOCERTS;
2105c87c606SMark Murray 		else if (!strcmp(*args, "-no_signature_verify"))
2115c87c606SMark Murray 			verify_flags |= OCSP_NOSIGS;
2125c87c606SMark Murray 		else if (!strcmp(*args, "-no_cert_verify"))
2135c87c606SMark Murray 			verify_flags |= OCSP_NOVERIFY;
2145c87c606SMark Murray 		else if (!strcmp(*args, "-no_chain"))
2155c87c606SMark Murray 			verify_flags |= OCSP_NOCHAIN;
2165c87c606SMark Murray 		else if (!strcmp(*args, "-no_cert_checks"))
2175c87c606SMark Murray 			verify_flags |= OCSP_NOCHECKS;
2185c87c606SMark Murray 		else if (!strcmp(*args, "-no_explicit"))
2195c87c606SMark Murray 			verify_flags |= OCSP_NOEXPLICIT;
2205c87c606SMark Murray 		else if (!strcmp(*args, "-trust_other"))
2215c87c606SMark Murray 			verify_flags |= OCSP_TRUSTOTHER;
2225c87c606SMark Murray 		else if (!strcmp(*args, "-no_intern"))
2235c87c606SMark Murray 			verify_flags |= OCSP_NOINTERN;
2245c87c606SMark Murray 		else if (!strcmp(*args, "-text"))
2255c87c606SMark Murray 			{
2265c87c606SMark Murray 			req_text = 1;
2275c87c606SMark Murray 			resp_text = 1;
2285c87c606SMark Murray 			}
2295c87c606SMark Murray 		else if (!strcmp(*args, "-req_text"))
2305c87c606SMark Murray 			req_text = 1;
2315c87c606SMark Murray 		else if (!strcmp(*args, "-resp_text"))
2325c87c606SMark Murray 			resp_text = 1;
2335c87c606SMark Murray 		else if (!strcmp(*args, "-reqin"))
2345c87c606SMark Murray 			{
2355c87c606SMark Murray 			if (args[1])
2365c87c606SMark Murray 				{
2375c87c606SMark Murray 				args++;
2385c87c606SMark Murray 				reqin = *args;
2395c87c606SMark Murray 				}
2405c87c606SMark Murray 			else badarg = 1;
2415c87c606SMark Murray 			}
2425c87c606SMark Murray 		else if (!strcmp(*args, "-respin"))
2435c87c606SMark Murray 			{
2445c87c606SMark Murray 			if (args[1])
2455c87c606SMark Murray 				{
2465c87c606SMark Murray 				args++;
2475c87c606SMark Murray 				respin = *args;
2485c87c606SMark Murray 				}
2495c87c606SMark Murray 			else badarg = 1;
2505c87c606SMark Murray 			}
2515c87c606SMark Murray 		else if (!strcmp(*args, "-signer"))
2525c87c606SMark Murray 			{
2535c87c606SMark Murray 			if (args[1])
2545c87c606SMark Murray 				{
2555c87c606SMark Murray 				args++;
2565c87c606SMark Murray 				signfile = *args;
2575c87c606SMark Murray 				}
2585c87c606SMark Murray 			else badarg = 1;
2595c87c606SMark Murray 			}
2605c87c606SMark Murray 		else if (!strcmp (*args, "-VAfile"))
2615c87c606SMark Murray 			{
2625c87c606SMark Murray 			if (args[1])
2635c87c606SMark Murray 				{
2645c87c606SMark Murray 				args++;
2655c87c606SMark Murray 				verify_certfile = *args;
2665c87c606SMark Murray 				verify_flags |= OCSP_TRUSTOTHER;
2675c87c606SMark Murray 				}
2685c87c606SMark Murray 			else badarg = 1;
2695c87c606SMark Murray 			}
2705c87c606SMark Murray 		else if (!strcmp(*args, "-sign_other"))
2715c87c606SMark Murray 			{
2725c87c606SMark Murray 			if (args[1])
2735c87c606SMark Murray 				{
2745c87c606SMark Murray 				args++;
2755c87c606SMark Murray 				sign_certfile = *args;
2765c87c606SMark Murray 				}
2775c87c606SMark Murray 			else badarg = 1;
2785c87c606SMark Murray 			}
2795c87c606SMark Murray 		else if (!strcmp(*args, "-verify_other"))
2805c87c606SMark Murray 			{
2815c87c606SMark Murray 			if (args[1])
2825c87c606SMark Murray 				{
2835c87c606SMark Murray 				args++;
2845c87c606SMark Murray 				verify_certfile = *args;
2855c87c606SMark Murray 				}
2865c87c606SMark Murray 			else badarg = 1;
2875c87c606SMark Murray 			}
2885c87c606SMark Murray 		else if (!strcmp (*args, "-CAfile"))
2895c87c606SMark Murray 			{
2905c87c606SMark Murray 			if (args[1])
2915c87c606SMark Murray 				{
2925c87c606SMark Murray 				args++;
2935c87c606SMark Murray 				CAfile = *args;
2945c87c606SMark Murray 				}
2955c87c606SMark Murray 			else badarg = 1;
2965c87c606SMark Murray 			}
2975c87c606SMark Murray 		else if (!strcmp (*args, "-CApath"))
2985c87c606SMark Murray 			{
2995c87c606SMark Murray 			if (args[1])
3005c87c606SMark Murray 				{
3015c87c606SMark Murray 				args++;
3025c87c606SMark Murray 				CApath = *args;
3035c87c606SMark Murray 				}
3045c87c606SMark Murray 			else badarg = 1;
3055c87c606SMark Murray 			}
3065c87c606SMark Murray 		else if (!strcmp (*args, "-validity_period"))
3075c87c606SMark Murray 			{
3085c87c606SMark Murray 			if (args[1])
3095c87c606SMark Murray 				{
3105c87c606SMark Murray 				args++;
3115c87c606SMark Murray 				nsec = atol(*args);
3125c87c606SMark Murray 				if (nsec < 0)
3135c87c606SMark Murray 					{
3145c87c606SMark Murray 					BIO_printf(bio_err,
3155c87c606SMark Murray 						"Illegal validity period %s\n",
3165c87c606SMark Murray 						*args);
3175c87c606SMark Murray 					badarg = 1;
3185c87c606SMark Murray 					}
3195c87c606SMark Murray 				}
3205c87c606SMark Murray 			else badarg = 1;
3215c87c606SMark Murray 			}
3225c87c606SMark Murray 		else if (!strcmp (*args, "-status_age"))
3235c87c606SMark Murray 			{
3245c87c606SMark Murray 			if (args[1])
3255c87c606SMark Murray 				{
3265c87c606SMark Murray 				args++;
3275c87c606SMark Murray 				maxage = atol(*args);
3285c87c606SMark Murray 				if (maxage < 0)
3295c87c606SMark Murray 					{
3305c87c606SMark Murray 					BIO_printf(bio_err,
3315c87c606SMark Murray 						"Illegal validity age %s\n",
3325c87c606SMark Murray 						*args);
3335c87c606SMark Murray 					badarg = 1;
3345c87c606SMark Murray 					}
3355c87c606SMark Murray 				}
3365c87c606SMark Murray 			else badarg = 1;
3375c87c606SMark Murray 			}
3385c87c606SMark Murray 		 else if (!strcmp(*args, "-signkey"))
3395c87c606SMark Murray 			{
3405c87c606SMark Murray 			if (args[1])
3415c87c606SMark Murray 				{
3425c87c606SMark Murray 				args++;
3435c87c606SMark Murray 				keyfile = *args;
3445c87c606SMark Murray 				}
3455c87c606SMark Murray 			else badarg = 1;
3465c87c606SMark Murray 			}
3475c87c606SMark Murray 		else if (!strcmp(*args, "-reqout"))
3485c87c606SMark Murray 			{
3495c87c606SMark Murray 			if (args[1])
3505c87c606SMark Murray 				{
3515c87c606SMark Murray 				args++;
3525c87c606SMark Murray 				reqout = *args;
3535c87c606SMark Murray 				}
3545c87c606SMark Murray 			else badarg = 1;
3555c87c606SMark Murray 			}
3565c87c606SMark Murray 		else if (!strcmp(*args, "-respout"))
3575c87c606SMark Murray 			{
3585c87c606SMark Murray 			if (args[1])
3595c87c606SMark Murray 				{
3605c87c606SMark Murray 				args++;
3615c87c606SMark Murray 				respout = *args;
3625c87c606SMark Murray 				}
3635c87c606SMark Murray 			else badarg = 1;
3645c87c606SMark Murray 			}
3655c87c606SMark Murray 		 else if (!strcmp(*args, "-path"))
3665c87c606SMark Murray 			{
3675c87c606SMark Murray 			if (args[1])
3685c87c606SMark Murray 				{
3695c87c606SMark Murray 				args++;
3705c87c606SMark Murray 				path = *args;
3715c87c606SMark Murray 				}
3725c87c606SMark Murray 			else badarg = 1;
3735c87c606SMark Murray 			}
3745c87c606SMark Murray 		else if (!strcmp(*args, "-issuer"))
3755c87c606SMark Murray 			{
3765c87c606SMark Murray 			if (args[1])
3775c87c606SMark Murray 				{
3785c87c606SMark Murray 				args++;
3795c87c606SMark Murray 				X509_free(issuer);
3805c87c606SMark Murray 				issuer = load_cert(bio_err, *args, FORMAT_PEM,
3815c87c606SMark Murray 					NULL, e, "issuer certificate");
3825c87c606SMark Murray 				if(!issuer) goto end;
3835c87c606SMark Murray 				}
3845c87c606SMark Murray 			else badarg = 1;
3855c87c606SMark Murray 			}
3865c87c606SMark Murray 		else if (!strcmp (*args, "-cert"))
3875c87c606SMark Murray 			{
3885c87c606SMark Murray 			if (args[1])
3895c87c606SMark Murray 				{
3905c87c606SMark Murray 				args++;
3915c87c606SMark Murray 				X509_free(cert);
3925c87c606SMark Murray 				cert = load_cert(bio_err, *args, FORMAT_PEM,
3935c87c606SMark Murray 					NULL, e, "certificate");
3945c87c606SMark Murray 				if(!cert) goto end;
3955c87c606SMark Murray 				if(!add_ocsp_cert(&req, cert, issuer, ids))
3965c87c606SMark Murray 					goto end;
3975c87c606SMark Murray 				if(!sk_push(reqnames, *args))
3985c87c606SMark Murray 					goto end;
3995c87c606SMark Murray 				}
4005c87c606SMark Murray 			else badarg = 1;
4015c87c606SMark Murray 			}
4025c87c606SMark Murray 		else if (!strcmp(*args, "-serial"))
4035c87c606SMark Murray 			{
4045c87c606SMark Murray 			if (args[1])
4055c87c606SMark Murray 				{
4065c87c606SMark Murray 				args++;
4075c87c606SMark Murray 				if(!add_ocsp_serial(&req, *args, issuer, ids))
4085c87c606SMark Murray 					goto end;
4095c87c606SMark Murray 				if(!sk_push(reqnames, *args))
4105c87c606SMark Murray 					goto end;
4115c87c606SMark Murray 				}
4125c87c606SMark Murray 			else badarg = 1;
4135c87c606SMark Murray 			}
4145c87c606SMark Murray 		else if (!strcmp(*args, "-index"))
4155c87c606SMark Murray 			{
4165c87c606SMark Murray 			if (args[1])
4175c87c606SMark Murray 				{
4185c87c606SMark Murray 				args++;
4195c87c606SMark Murray 				ridx_filename = *args;
4205c87c606SMark Murray 				}
4215c87c606SMark Murray 			else badarg = 1;
4225c87c606SMark Murray 			}
4235c87c606SMark Murray 		else if (!strcmp(*args, "-CA"))
4245c87c606SMark Murray 			{
4255c87c606SMark Murray 			if (args[1])
4265c87c606SMark Murray 				{
4275c87c606SMark Murray 				args++;
4285c87c606SMark Murray 				rca_filename = *args;
4295c87c606SMark Murray 				}
4305c87c606SMark Murray 			else badarg = 1;
4315c87c606SMark Murray 			}
4325c87c606SMark Murray 		else if (!strcmp (*args, "-nmin"))
4335c87c606SMark Murray 			{
4345c87c606SMark Murray 			if (args[1])
4355c87c606SMark Murray 				{
4365c87c606SMark Murray 				args++;
4375c87c606SMark Murray 				nmin = atol(*args);
4385c87c606SMark Murray 				if (nmin < 0)
4395c87c606SMark Murray 					{
4405c87c606SMark Murray 					BIO_printf(bio_err,
4415c87c606SMark Murray 						"Illegal update period %s\n",
4425c87c606SMark Murray 						*args);
4435c87c606SMark Murray 					badarg = 1;
4445c87c606SMark Murray 					}
4455c87c606SMark Murray 				}
4465c87c606SMark Murray 				if (ndays == -1)
4475c87c606SMark Murray 					ndays = 0;
4485c87c606SMark Murray 			else badarg = 1;
4495c87c606SMark Murray 			}
4505c87c606SMark Murray 		else if (!strcmp (*args, "-nrequest"))
4515c87c606SMark Murray 			{
4525c87c606SMark Murray 			if (args[1])
4535c87c606SMark Murray 				{
4545c87c606SMark Murray 				args++;
4555c87c606SMark Murray 				accept_count = atol(*args);
4565c87c606SMark Murray 				if (accept_count < 0)
4575c87c606SMark Murray 					{
4585c87c606SMark Murray 					BIO_printf(bio_err,
4595c87c606SMark Murray 						"Illegal accept count %s\n",
4605c87c606SMark Murray 						*args);
4615c87c606SMark Murray 					badarg = 1;
4625c87c606SMark Murray 					}
4635c87c606SMark Murray 				}
4645c87c606SMark Murray 			else badarg = 1;
4655c87c606SMark Murray 			}
4665c87c606SMark Murray 		else if (!strcmp (*args, "-ndays"))
4675c87c606SMark Murray 			{
4685c87c606SMark Murray 			if (args[1])
4695c87c606SMark Murray 				{
4705c87c606SMark Murray 				args++;
4715c87c606SMark Murray 				ndays = atol(*args);
4725c87c606SMark Murray 				if (ndays < 0)
4735c87c606SMark Murray 					{
4745c87c606SMark Murray 					BIO_printf(bio_err,
4755c87c606SMark Murray 						"Illegal update period %s\n",
4765c87c606SMark Murray 						*args);
4775c87c606SMark Murray 					badarg = 1;
4785c87c606SMark Murray 					}
4795c87c606SMark Murray 				}
4805c87c606SMark Murray 			else badarg = 1;
4815c87c606SMark Murray 			}
4825c87c606SMark Murray 		else if (!strcmp(*args, "-rsigner"))
4835c87c606SMark Murray 			{
4845c87c606SMark Murray 			if (args[1])
4855c87c606SMark Murray 				{
4865c87c606SMark Murray 				args++;
4875c87c606SMark Murray 				rsignfile = *args;
4885c87c606SMark Murray 				}
4895c87c606SMark Murray 			else badarg = 1;
4905c87c606SMark Murray 			}
4915c87c606SMark Murray 		else if (!strcmp(*args, "-rkey"))
4925c87c606SMark Murray 			{
4935c87c606SMark Murray 			if (args[1])
4945c87c606SMark Murray 				{
4955c87c606SMark Murray 				args++;
4965c87c606SMark Murray 				rkeyfile = *args;
4975c87c606SMark Murray 				}
4985c87c606SMark Murray 			else badarg = 1;
4995c87c606SMark Murray 			}
5005c87c606SMark Murray 		else if (!strcmp(*args, "-rother"))
5015c87c606SMark Murray 			{
5025c87c606SMark Murray 			if (args[1])
5035c87c606SMark Murray 				{
5045c87c606SMark Murray 				args++;
5055c87c606SMark Murray 				rcertfile = *args;
5065c87c606SMark Murray 				}
5075c87c606SMark Murray 			else badarg = 1;
5085c87c606SMark Murray 			}
5095c87c606SMark Murray 		else badarg = 1;
5105c87c606SMark Murray 		args++;
5115c87c606SMark Murray 		}
5125c87c606SMark Murray 
5135c87c606SMark Murray 	/* Have we anything to do? */
5145c87c606SMark Murray 	if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1;
5155c87c606SMark Murray 
5165c87c606SMark Murray 	if (badarg)
5175c87c606SMark Murray 		{
5185c87c606SMark Murray 		BIO_printf (bio_err, "OCSP utility\n");
5195c87c606SMark Murray 		BIO_printf (bio_err, "Usage ocsp [options]\n");
5205c87c606SMark Murray 		BIO_printf (bio_err, "where options are\n");
5215c87c606SMark Murray 		BIO_printf (bio_err, "-out file          output filename\n");
5225c87c606SMark Murray 		BIO_printf (bio_err, "-issuer file       issuer certificate\n");
5235c87c606SMark Murray 		BIO_printf (bio_err, "-cert file         certificate to check\n");
5245c87c606SMark Murray 		BIO_printf (bio_err, "-serial n          serial number to check\n");
5255c87c606SMark Murray 		BIO_printf (bio_err, "-signer file       certificate to sign OCSP request with\n");
5265c87c606SMark Murray 		BIO_printf (bio_err, "-signkey file      private key to sign OCSP request with\n");
5275c87c606SMark Murray 		BIO_printf (bio_err, "-sign_certs file   additional certificates to include in signed request\n");
5285c87c606SMark Murray 		BIO_printf (bio_err, "-no_certs          don't include any certificates in signed request\n");
5295c87c606SMark Murray 		BIO_printf (bio_err, "-req_text          print text form of request\n");
5305c87c606SMark Murray 		BIO_printf (bio_err, "-resp_text         print text form of response\n");
5315c87c606SMark Murray 		BIO_printf (bio_err, "-text              print text form of request and response\n");
5325c87c606SMark Murray 		BIO_printf (bio_err, "-reqout file       write DER encoded OCSP request to \"file\"\n");
5335c87c606SMark Murray 		BIO_printf (bio_err, "-respout file      write DER encoded OCSP reponse to \"file\"\n");
5345c87c606SMark Murray 		BIO_printf (bio_err, "-reqin file        read DER encoded OCSP request from \"file\"\n");
5355c87c606SMark Murray 		BIO_printf (bio_err, "-respin file       read DER encoded OCSP reponse from \"file\"\n");
5365c87c606SMark Murray 		BIO_printf (bio_err, "-nonce             add OCSP nonce to request\n");
5375c87c606SMark Murray 		BIO_printf (bio_err, "-no_nonce          don't add OCSP nonce to request\n");
5385c87c606SMark Murray 		BIO_printf (bio_err, "-url URL           OCSP responder URL\n");
5395c87c606SMark Murray 		BIO_printf (bio_err, "-host host:n       send OCSP request to host on port n\n");
5405c87c606SMark Murray 		BIO_printf (bio_err, "-path              path to use in OCSP request\n");
5415c87c606SMark Murray 		BIO_printf (bio_err, "-CApath dir        trusted certificates directory\n");
5425c87c606SMark Murray 		BIO_printf (bio_err, "-CAfile file       trusted certificates file\n");
5435c87c606SMark Murray 		BIO_printf (bio_err, "-VAfile file       validator certificates file\n");
5445c87c606SMark Murray 		BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
5455c87c606SMark Murray 		BIO_printf (bio_err, "-status_age n      maximum status age in seconds\n");
5465c87c606SMark Murray 		BIO_printf (bio_err, "-noverify          don't verify response at all\n");
5475c87c606SMark Murray 		BIO_printf (bio_err, "-verify_certs file additional certificates to search for signer\n");
5485c87c606SMark Murray 		BIO_printf (bio_err, "-trust_other       don't verify additional certificates\n");
5495c87c606SMark Murray 		BIO_printf (bio_err, "-no_intern         don't search certificates contained in response for signer\n");
5505c87c606SMark Murray 		BIO_printf (bio_err, "-no_sig_verify     don't check signature on response\n");
5515c87c606SMark Murray 		BIO_printf (bio_err, "-no_cert_verify    don't check signing certificate\n");
5525c87c606SMark Murray 		BIO_printf (bio_err, "-no_chain          don't chain verify response\n");
5535c87c606SMark Murray 		BIO_printf (bio_err, "-no_cert_checks    don't do additional checks on signing certificate\n");
5545c87c606SMark Murray 		BIO_printf (bio_err, "-port num		 port to run responder on\n");
5555c87c606SMark Murray 		BIO_printf (bio_err, "-index file	 certificate status index file\n");
5565c87c606SMark Murray 		BIO_printf (bio_err, "-CA file		 CA certificate\n");
5575c87c606SMark Murray 		BIO_printf (bio_err, "-rsigner file	 responder certificate to sign responses with\n");
5585c87c606SMark Murray 		BIO_printf (bio_err, "-rkey file	 responder key to sign responses with\n");
5595c87c606SMark Murray 		BIO_printf (bio_err, "-rother file	 other certificates to include in response\n");
5605c87c606SMark Murray 		BIO_printf (bio_err, "-resp_no_certs     don't include any certificates in response\n");
5615c87c606SMark Murray 		BIO_printf (bio_err, "-nmin n	 	 number of minutes before next update\n");
5625c87c606SMark Murray 		BIO_printf (bio_err, "-ndays n	 	 number of days before next update\n");
5635c87c606SMark Murray 		BIO_printf (bio_err, "-resp_key_id       identify reponse by signing certificate key ID\n");
5645c87c606SMark Murray 		BIO_printf (bio_err, "-nrequest n        number of requests to accept (default unlimited)\n");
5655c87c606SMark Murray 		goto end;
5665c87c606SMark Murray 		}
5675c87c606SMark Murray 
5685c87c606SMark Murray 	if(outfile) out = BIO_new_file(outfile, "w");
5695c87c606SMark Murray 	else out = BIO_new_fp(stdout, BIO_NOCLOSE);
5705c87c606SMark Murray 
5715c87c606SMark Murray 	if(!out)
5725c87c606SMark Murray 		{
5735c87c606SMark Murray 		BIO_printf(bio_err, "Error opening output file\n");
5745c87c606SMark Murray 		goto end;
5755c87c606SMark Murray 		}
5765c87c606SMark Murray 
5775c87c606SMark Murray 	if (!req && (add_nonce != 2)) add_nonce = 0;
5785c87c606SMark Murray 
5795c87c606SMark Murray 	if (!req && reqin)
5805c87c606SMark Murray 		{
5815c87c606SMark Murray 		derbio = BIO_new_file(reqin, "rb");
5825c87c606SMark Murray 		if (!derbio)
5835c87c606SMark Murray 			{
5845c87c606SMark Murray 			BIO_printf(bio_err, "Error Opening OCSP request file\n");
5855c87c606SMark Murray 			goto end;
5865c87c606SMark Murray 			}
5875c87c606SMark Murray 		req = d2i_OCSP_REQUEST_bio(derbio, NULL);
5885c87c606SMark Murray 		BIO_free(derbio);
5895c87c606SMark Murray 		if(!req)
5905c87c606SMark Murray 			{
5915c87c606SMark Murray 			BIO_printf(bio_err, "Error reading OCSP request\n");
5925c87c606SMark Murray 			goto end;
5935c87c606SMark Murray 			}
5945c87c606SMark Murray 		}
5955c87c606SMark Murray 
5965c87c606SMark Murray 	if (!req && port)
5975c87c606SMark Murray 		{
5985c87c606SMark Murray 		acbio = init_responder(port);
5995c87c606SMark Murray 		if (!acbio)
6005c87c606SMark Murray 			goto end;
6015c87c606SMark Murray 		}
6025c87c606SMark Murray 
6035c87c606SMark Murray 	if (rsignfile && !rdb)
6045c87c606SMark Murray 		{
6055c87c606SMark Murray 		if (!rkeyfile) rkeyfile = rsignfile;
6065c87c606SMark Murray 		rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,
6075c87c606SMark Murray 			NULL, e, "responder certificate");
6085c87c606SMark Murray 		if (!rsigner)
6095c87c606SMark Murray 			{
6105c87c606SMark Murray 			BIO_printf(bio_err, "Error loading responder certificate\n");
6115c87c606SMark Murray 			goto end;
6125c87c606SMark Murray 			}
6135c87c606SMark Murray 		rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,
6145c87c606SMark Murray 			NULL, e, "CA certificate");
6155c87c606SMark Murray 		if (rcertfile)
6165c87c606SMark Murray 			{
6175c87c606SMark Murray 			rother = load_certs(bio_err, rcertfile, FORMAT_PEM,
6185c87c606SMark Murray 				NULL, e, "responder other certificates");
6195c87c606SMark Murray 			if (!rother) goto end;
6205c87c606SMark Murray 			}
6215c87c606SMark Murray 		rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL,
6225c87c606SMark Murray 			"responder private key");
6235c87c606SMark Murray 		if (!rkey)
6245c87c606SMark Murray 			goto end;
6255c87c606SMark Murray 		}
6265c87c606SMark Murray 	if(acbio)
6275c87c606SMark Murray 		BIO_printf(bio_err, "Waiting for OCSP client connections...\n");
6285c87c606SMark Murray 
6295c87c606SMark Murray 	redo_accept:
6305c87c606SMark Murray 
6315c87c606SMark Murray 	if (acbio)
6325c87c606SMark Murray 		{
6335c87c606SMark Murray 		if (!do_responder(&req, &cbio, acbio, port))
6345c87c606SMark Murray 			goto end;
6355c87c606SMark Murray 		if (!req)
6365c87c606SMark Murray 			{
6375c87c606SMark Murray 			resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
6385c87c606SMark Murray 			send_ocsp_response(cbio, resp);
6395c87c606SMark Murray 			goto done_resp;
6405c87c606SMark Murray 			}
6415c87c606SMark Murray 		}
6425c87c606SMark Murray 
6435c87c606SMark Murray 	if (!req && (signfile || reqout || host || add_nonce || ridx_filename))
6445c87c606SMark Murray 		{
6455c87c606SMark Murray 		BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
6465c87c606SMark Murray 		goto end;
6475c87c606SMark Murray 		}
6485c87c606SMark Murray 
6495c87c606SMark Murray 	if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1);
6505c87c606SMark Murray 
6515c87c606SMark Murray 	if (signfile)
6525c87c606SMark Murray 		{
6535c87c606SMark Murray 		if (!keyfile) keyfile = signfile;
6545c87c606SMark Murray 		signer = load_cert(bio_err, signfile, FORMAT_PEM,
6555c87c606SMark Murray 			NULL, e, "signer certificate");
6565c87c606SMark Murray 		if (!signer)
6575c87c606SMark Murray 			{
6585c87c606SMark Murray 			BIO_printf(bio_err, "Error loading signer certificate\n");
6595c87c606SMark Murray 			goto end;
6605c87c606SMark Murray 			}
6615c87c606SMark Murray 		if (sign_certfile)
6625c87c606SMark Murray 			{
6635c87c606SMark Murray 			sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,
6645c87c606SMark Murray 				NULL, e, "signer certificates");
6655c87c606SMark Murray 			if (!sign_other) goto end;
6665c87c606SMark Murray 			}
6675c87c606SMark Murray 		key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL,
6685c87c606SMark Murray 			"signer private key");
6695c87c606SMark Murray 		if (!key)
6705c87c606SMark Murray 			goto end;
6715c87c606SMark Murray 		if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags))
6725c87c606SMark Murray 			{
6735c87c606SMark Murray 			BIO_printf(bio_err, "Error signing OCSP request\n");
6745c87c606SMark Murray 			goto end;
6755c87c606SMark Murray 			}
6765c87c606SMark Murray 		}
6775c87c606SMark Murray 
6785c87c606SMark Murray 	if (req_text && req) OCSP_REQUEST_print(out, req, 0);
6795c87c606SMark Murray 
6805c87c606SMark Murray 	if (reqout)
6815c87c606SMark Murray 		{
6825c87c606SMark Murray 		derbio = BIO_new_file(reqout, "wb");
6835c87c606SMark Murray 		if(!derbio)
6845c87c606SMark Murray 			{
6855c87c606SMark Murray 			BIO_printf(bio_err, "Error opening file %s\n", reqout);
6865c87c606SMark Murray 			goto end;
6875c87c606SMark Murray 			}
6885c87c606SMark Murray 		i2d_OCSP_REQUEST_bio(derbio, req);
6895c87c606SMark Murray 		BIO_free(derbio);
6905c87c606SMark Murray 		}
6915c87c606SMark Murray 
6925c87c606SMark Murray 	if (ridx_filename && (!rkey || !rsigner || !rca_cert))
6935c87c606SMark Murray 		{
6945c87c606SMark Murray 		BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n");
6955c87c606SMark Murray 		goto end;
6965c87c606SMark Murray 		}
6975c87c606SMark Murray 
6985c87c606SMark Murray 	if (ridx_filename && !rdb)
6995c87c606SMark Murray 		{
7005c87c606SMark Murray 		BIO *db_bio = NULL;
7015c87c606SMark Murray 		db_bio = BIO_new_file(ridx_filename, "r");
7025c87c606SMark Murray 		if (!db_bio)
7035c87c606SMark Murray 			{
7045c87c606SMark Murray 			BIO_printf(bio_err, "Error opening index file %s\n", ridx_filename);
7055c87c606SMark Murray 			goto end;
7065c87c606SMark Murray 			}
7075c87c606SMark Murray 		rdb = TXT_DB_read(db_bio, DB_NUMBER);
7085c87c606SMark Murray 		BIO_free(db_bio);
7095c87c606SMark Murray 		if (!rdb)
7105c87c606SMark Murray 			{
7115c87c606SMark Murray 			BIO_printf(bio_err, "Error reading index file %s\n", ridx_filename);
7125c87c606SMark Murray 			goto end;
7135c87c606SMark Murray 			}
7145c87c606SMark Murray 		if (!make_serial_index(rdb))
7155c87c606SMark Murray 			goto end;
7165c87c606SMark Murray 		}
7175c87c606SMark Murray 
7185c87c606SMark Murray 	if (rdb)
7195c87c606SMark Murray 		{
7205c87c606SMark Murray 		i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays);
7215c87c606SMark Murray 		if (cbio)
7225c87c606SMark Murray 			send_ocsp_response(cbio, resp);
7235c87c606SMark Murray 		}
7245c87c606SMark Murray 	else if (host)
7255c87c606SMark Murray 		{
726fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_SOCK
7275c87c606SMark Murray 		cbio = BIO_new_connect(host);
728fceca8a3SJacques Vidrine #else
729fceca8a3SJacques Vidrine 		BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n");
730fceca8a3SJacques Vidrine 		goto end;
731fceca8a3SJacques Vidrine #endif
7325c87c606SMark Murray 		if (!cbio)
7335c87c606SMark Murray 			{
7345c87c606SMark Murray 			BIO_printf(bio_err, "Error creating connect BIO\n");
7355c87c606SMark Murray 			goto end;
7365c87c606SMark Murray 			}
7375c87c606SMark Murray 		if (port) BIO_set_conn_port(cbio, port);
7385c87c606SMark Murray 		if (use_ssl == 1)
7395c87c606SMark Murray 			{
7405c87c606SMark Murray 			BIO *sbio;
741fceca8a3SJacques Vidrine #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
7425c87c606SMark Murray 			ctx = SSL_CTX_new(SSLv23_client_method());
743fceca8a3SJacques Vidrine #elif !defined(OPENSSL_NO_SSL3)
744fceca8a3SJacques Vidrine 			ctx = SSL_CTX_new(SSLv3_client_method());
745fceca8a3SJacques Vidrine #elif !defined(OPENSSL_NO_SSL2)
746fceca8a3SJacques Vidrine 			ctx = SSL_CTX_new(SSLv2_client_method());
747fceca8a3SJacques Vidrine #else
748fceca8a3SJacques Vidrine 			BIO_printf(bio_err, "SSL is disabled\n");
749fceca8a3SJacques Vidrine 			goto end;
750fceca8a3SJacques Vidrine #endif
7515c87c606SMark Murray 			SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
7525c87c606SMark Murray 			sbio = BIO_new_ssl(ctx, 1);
7535c87c606SMark Murray 			cbio = BIO_push(sbio, cbio);
7545c87c606SMark Murray 			}
7555c87c606SMark Murray 		if (BIO_do_connect(cbio) <= 0)
7565c87c606SMark Murray 			{
7575c87c606SMark Murray 			BIO_printf(bio_err, "Error connecting BIO\n");
7585c87c606SMark Murray 			goto end;
7595c87c606SMark Murray 			}
7605c87c606SMark Murray 		resp = OCSP_sendreq_bio(cbio, path, req);
7615c87c606SMark Murray 		BIO_free_all(cbio);
7625c87c606SMark Murray 		cbio = NULL;
7635c87c606SMark Murray 		if (!resp)
7645c87c606SMark Murray 			{
7655c87c606SMark Murray 			BIO_printf(bio_err, "Error querying OCSP responsder\n");
7665c87c606SMark Murray 			goto end;
7675c87c606SMark Murray 			}
7685c87c606SMark Murray 		}
7695c87c606SMark Murray 	else if (respin)
7705c87c606SMark Murray 		{
7715c87c606SMark Murray 		derbio = BIO_new_file(respin, "rb");
7725c87c606SMark Murray 		if (!derbio)
7735c87c606SMark Murray 			{
7745c87c606SMark Murray 			BIO_printf(bio_err, "Error Opening OCSP response file\n");
7755c87c606SMark Murray 			goto end;
7765c87c606SMark Murray 			}
7775c87c606SMark Murray 		resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
7785c87c606SMark Murray 		BIO_free(derbio);
7795c87c606SMark Murray 		if(!resp)
7805c87c606SMark Murray 			{
7815c87c606SMark Murray 			BIO_printf(bio_err, "Error reading OCSP response\n");
7825c87c606SMark Murray 			goto end;
7835c87c606SMark Murray 			}
7845c87c606SMark Murray 
7855c87c606SMark Murray 		}
7865c87c606SMark Murray 	else
7875c87c606SMark Murray 		{
7885c87c606SMark Murray 		ret = 0;
7895c87c606SMark Murray 		goto end;
7905c87c606SMark Murray 		}
7915c87c606SMark Murray 
7925c87c606SMark Murray 	done_resp:
7935c87c606SMark Murray 
7945c87c606SMark Murray 	if (respout)
7955c87c606SMark Murray 		{
7965c87c606SMark Murray 		derbio = BIO_new_file(respout, "wb");
7975c87c606SMark Murray 		if(!derbio)
7985c87c606SMark Murray 			{
7995c87c606SMark Murray 			BIO_printf(bio_err, "Error opening file %s\n", respout);
8005c87c606SMark Murray 			goto end;
8015c87c606SMark Murray 			}
8025c87c606SMark Murray 		i2d_OCSP_RESPONSE_bio(derbio, resp);
8035c87c606SMark Murray 		BIO_free(derbio);
8045c87c606SMark Murray 		}
8055c87c606SMark Murray 
8065c87c606SMark Murray 	i = OCSP_response_status(resp);
8075c87c606SMark Murray 
8085c87c606SMark Murray 	if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL)
8095c87c606SMark Murray 		{
8105c87c606SMark Murray 		BIO_printf(out, "Responder Error: %s (%ld)\n",
8115c87c606SMark Murray 				OCSP_response_status_str(i), i);
8125c87c606SMark Murray 		ret = 0;
8135c87c606SMark Murray 		goto end;
8145c87c606SMark Murray 		}
8155c87c606SMark Murray 
8165c87c606SMark Murray 	if (resp_text) OCSP_RESPONSE_print(out, resp, 0);
8175c87c606SMark Murray 
8185c87c606SMark Murray 	/* If running as responder don't verify our own response */
8195c87c606SMark Murray 	if (cbio)
8205c87c606SMark Murray 		{
8215c87c606SMark Murray 		if (accept_count > 0)
8225c87c606SMark Murray 			accept_count--;
8235c87c606SMark Murray 		/* Redo if more connections needed */
8245c87c606SMark Murray 		if (accept_count)
8255c87c606SMark Murray 			{
8265c87c606SMark Murray 			BIO_free_all(cbio);
8275c87c606SMark Murray 			cbio = NULL;
8285c87c606SMark Murray 			OCSP_REQUEST_free(req);
8295c87c606SMark Murray 			req = NULL;
8305c87c606SMark Murray 			OCSP_RESPONSE_free(resp);
8315c87c606SMark Murray 			resp = NULL;
8325c87c606SMark Murray 			goto redo_accept;
8335c87c606SMark Murray 			}
8345c87c606SMark Murray 		goto end;
8355c87c606SMark Murray 		}
8365c87c606SMark Murray 
8375c87c606SMark Murray 	if (!store)
8385c87c606SMark Murray 		store = setup_verify(bio_err, CAfile, CApath);
8395c87c606SMark Murray 	if (!store)
8405c87c606SMark Murray 		goto end;
8415c87c606SMark Murray 	if (verify_certfile)
8425c87c606SMark Murray 		{
8435c87c606SMark Murray 		verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,
8445c87c606SMark Murray 			NULL, e, "validator certificate");
8455c87c606SMark Murray 		if (!verify_other) goto end;
8465c87c606SMark Murray 		}
8475c87c606SMark Murray 
8485c87c606SMark Murray 	bs = OCSP_response_get1_basic(resp);
8495c87c606SMark Murray 
8505c87c606SMark Murray 	if (!bs)
8515c87c606SMark Murray 		{
8525c87c606SMark Murray 		BIO_printf(bio_err, "Error parsing response\n");
8535c87c606SMark Murray 		goto end;
8545c87c606SMark Murray 		}
8555c87c606SMark Murray 
8565c87c606SMark Murray 	if (!noverify)
8575c87c606SMark Murray 		{
8585c87c606SMark Murray 		if (req && ((i = OCSP_check_nonce(req, bs)) <= 0))
8595c87c606SMark Murray 			{
8605c87c606SMark Murray 			if (i == -1)
8615c87c606SMark Murray 				BIO_printf(bio_err, "WARNING: no nonce in response\n");
8625c87c606SMark Murray 			else
8635c87c606SMark Murray 				{
8645c87c606SMark Murray 				BIO_printf(bio_err, "Nonce Verify error\n");
8655c87c606SMark Murray 				goto end;
8665c87c606SMark Murray 				}
8675c87c606SMark Murray 			}
8685c87c606SMark Murray 
8695c87c606SMark Murray 		i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
8705c87c606SMark Murray                 if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0);
8715c87c606SMark Murray 
8725c87c606SMark Murray 		if(i <= 0)
8735c87c606SMark Murray 			{
8745c87c606SMark Murray 			BIO_printf(bio_err, "Response Verify Failure\n", i);
8755c87c606SMark Murray 			ERR_print_errors(bio_err);
8765c87c606SMark Murray 			}
8775c87c606SMark Murray 		else
8785c87c606SMark Murray 			BIO_printf(bio_err, "Response verify OK\n");
8795c87c606SMark Murray 
8805c87c606SMark Murray 		}
8815c87c606SMark Murray 
8825c87c606SMark Murray 	if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage))
8835c87c606SMark Murray 		goto end;
8845c87c606SMark Murray 
8855c87c606SMark Murray 	ret = 0;
8865c87c606SMark Murray 
8875c87c606SMark Murray end:
8885c87c606SMark Murray 	ERR_print_errors(bio_err);
8895c87c606SMark Murray 	X509_free(signer);
8905c87c606SMark Murray 	X509_STORE_free(store);
8915c87c606SMark Murray 	EVP_PKEY_free(key);
8925c87c606SMark Murray 	EVP_PKEY_free(rkey);
8935c87c606SMark Murray 	X509_free(issuer);
8945c87c606SMark Murray 	X509_free(cert);
8955c87c606SMark Murray 	X509_free(rsigner);
8965c87c606SMark Murray 	X509_free(rca_cert);
8975c87c606SMark Murray 	TXT_DB_free(rdb);
8985c87c606SMark Murray 	BIO_free_all(cbio);
8995c87c606SMark Murray 	BIO_free_all(acbio);
9005c87c606SMark Murray 	BIO_free(out);
9015c87c606SMark Murray 	OCSP_REQUEST_free(req);
9025c87c606SMark Murray 	OCSP_RESPONSE_free(resp);
9035c87c606SMark Murray 	OCSP_BASICRESP_free(bs);
9045c87c606SMark Murray 	sk_free(reqnames);
9055c87c606SMark Murray 	sk_OCSP_CERTID_free(ids);
9065c87c606SMark Murray 	sk_X509_pop_free(sign_other, X509_free);
9075c87c606SMark Murray 	sk_X509_pop_free(verify_other, X509_free);
9085c87c606SMark Murray 
9095c87c606SMark Murray 	if (use_ssl != -1)
9105c87c606SMark Murray 		{
9115c87c606SMark Murray 		OPENSSL_free(host);
9125c87c606SMark Murray 		OPENSSL_free(port);
9135c87c606SMark Murray 		OPENSSL_free(path);
9145c87c606SMark Murray 		SSL_CTX_free(ctx);
9155c87c606SMark Murray 		}
9165c87c606SMark Murray 
9175c87c606SMark Murray 	OPENSSL_EXIT(ret);
9185c87c606SMark Murray }
9195c87c606SMark Murray 
9205c87c606SMark Murray static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
9215c87c606SMark Murray 				STACK_OF(OCSP_CERTID) *ids)
9225c87c606SMark Murray 	{
9235c87c606SMark Murray 	OCSP_CERTID *id;
9245c87c606SMark Murray 	if(!issuer)
9255c87c606SMark Murray 		{
9265c87c606SMark Murray 		BIO_printf(bio_err, "No issuer certificate specified\n");
9275c87c606SMark Murray 		return 0;
9285c87c606SMark Murray 		}
9295c87c606SMark Murray 	if(!*req) *req = OCSP_REQUEST_new();
9305c87c606SMark Murray 	if(!*req) goto err;
9315c87c606SMark Murray 	id = OCSP_cert_to_id(NULL, cert, issuer);
9325c87c606SMark Murray 	if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
9335c87c606SMark Murray 	if(!OCSP_request_add0_id(*req, id)) goto err;
9345c87c606SMark Murray 	return 1;
9355c87c606SMark Murray 
9365c87c606SMark Murray 	err:
9375c87c606SMark Murray 	BIO_printf(bio_err, "Error Creating OCSP request\n");
9385c87c606SMark Murray 	return 0;
9395c87c606SMark Murray 	}
9405c87c606SMark Murray 
9415c87c606SMark Murray static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
9425c87c606SMark Murray 				STACK_OF(OCSP_CERTID) *ids)
9435c87c606SMark Murray 	{
9445c87c606SMark Murray 	OCSP_CERTID *id;
9455c87c606SMark Murray 	X509_NAME *iname;
9465c87c606SMark Murray 	ASN1_BIT_STRING *ikey;
9475c87c606SMark Murray 	ASN1_INTEGER *sno;
9485c87c606SMark Murray 	if(!issuer)
9495c87c606SMark Murray 		{
9505c87c606SMark Murray 		BIO_printf(bio_err, "No issuer certificate specified\n");
9515c87c606SMark Murray 		return 0;
9525c87c606SMark Murray 		}
9535c87c606SMark Murray 	if(!*req) *req = OCSP_REQUEST_new();
9545c87c606SMark Murray 	if(!*req) goto err;
9555c87c606SMark Murray 	iname = X509_get_subject_name(issuer);
9565c87c606SMark Murray 	ikey = X509_get0_pubkey_bitstr(issuer);
9575c87c606SMark Murray 	sno = s2i_ASN1_INTEGER(NULL, serial);
9585c87c606SMark Murray 	if(!sno)
9595c87c606SMark Murray 		{
9605c87c606SMark Murray 		BIO_printf(bio_err, "Error converting serial number %s\n", serial);
9615c87c606SMark Murray 		return 0;
9625c87c606SMark Murray 		}
9635c87c606SMark Murray 	id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno);
9645c87c606SMark Murray 	ASN1_INTEGER_free(sno);
9655c87c606SMark Murray 	if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
9665c87c606SMark Murray 	if(!OCSP_request_add0_id(*req, id)) goto err;
9675c87c606SMark Murray 	return 1;
9685c87c606SMark Murray 
9695c87c606SMark Murray 	err:
9705c87c606SMark Murray 	BIO_printf(bio_err, "Error Creating OCSP request\n");
9715c87c606SMark Murray 	return 0;
9725c87c606SMark Murray 	}
9735c87c606SMark Murray 
9745c87c606SMark Murray static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
9755c87c606SMark Murray 					STACK *names, STACK_OF(OCSP_CERTID) *ids,
9765c87c606SMark Murray 					long nsec, long maxage)
9775c87c606SMark Murray 	{
9785c87c606SMark Murray 	OCSP_CERTID *id;
9795c87c606SMark Murray 	char *name;
9805c87c606SMark Murray 	int i;
9815c87c606SMark Murray 
9825c87c606SMark Murray 	int status, reason;
9835c87c606SMark Murray 
9845c87c606SMark Murray 	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
9855c87c606SMark Murray 
9865c87c606SMark Murray 	if (!bs || !req || !sk_num(names) || !sk_OCSP_CERTID_num(ids))
9875c87c606SMark Murray 		return 1;
9885c87c606SMark Murray 
9895c87c606SMark Murray 	for (i = 0; i < sk_OCSP_CERTID_num(ids); i++)
9905c87c606SMark Murray 		{
9915c87c606SMark Murray 		id = sk_OCSP_CERTID_value(ids, i);
9925c87c606SMark Murray 		name = sk_value(names, i);
9935c87c606SMark Murray 		BIO_printf(out, "%s: ", name);
9945c87c606SMark Murray 
9955c87c606SMark Murray 		if(!OCSP_resp_find_status(bs, id, &status, &reason,
9965c87c606SMark Murray 					&rev, &thisupd, &nextupd))
9975c87c606SMark Murray 			{
9985c87c606SMark Murray 			BIO_puts(out, "ERROR: No Status found.\n");
9995c87c606SMark Murray 			continue;
10005c87c606SMark Murray 			}
10015c87c606SMark Murray 
10025c87c606SMark Murray 		/* Check validity: if invalid write to output BIO so we
10035c87c606SMark Murray 		 * know which response this refers to.
10045c87c606SMark Murray 		 */
10055c87c606SMark Murray 		if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage))
10065c87c606SMark Murray 			{
10075c87c606SMark Murray 			BIO_puts(out, "WARNING: Status times invalid.\n");
10085c87c606SMark Murray 			ERR_print_errors(out);
10095c87c606SMark Murray 			}
10105c87c606SMark Murray 		BIO_printf(out, "%s\n", OCSP_cert_status_str(status));
10115c87c606SMark Murray 
10125c87c606SMark Murray 		BIO_puts(out, "\tThis Update: ");
10135c87c606SMark Murray 		ASN1_GENERALIZEDTIME_print(out, thisupd);
10145c87c606SMark Murray 		BIO_puts(out, "\n");
10155c87c606SMark Murray 
10165c87c606SMark Murray 		if(nextupd)
10175c87c606SMark Murray 			{
10185c87c606SMark Murray 			BIO_puts(out, "\tNext Update: ");
10195c87c606SMark Murray 			ASN1_GENERALIZEDTIME_print(out, nextupd);
10205c87c606SMark Murray 			BIO_puts(out, "\n");
10215c87c606SMark Murray 			}
10225c87c606SMark Murray 
10235c87c606SMark Murray 		if (status != V_OCSP_CERTSTATUS_REVOKED)
10245c87c606SMark Murray 			continue;
10255c87c606SMark Murray 
10265c87c606SMark Murray 		if (reason != -1)
10275c87c606SMark Murray 			BIO_printf(out, "\tReason: %s\n",
10285c87c606SMark Murray 				OCSP_crl_reason_str(reason));
10295c87c606SMark Murray 
10305c87c606SMark Murray 		BIO_puts(out, "\tRevocation Time: ");
10315c87c606SMark Murray 		ASN1_GENERALIZEDTIME_print(out, rev);
10325c87c606SMark Murray 		BIO_puts(out, "\n");
10335c87c606SMark Murray 		}
10345c87c606SMark Murray 
10355c87c606SMark Murray 	return 1;
10365c87c606SMark Murray 	}
10375c87c606SMark Murray 
10385c87c606SMark Murray 
10395c87c606SMark Murray static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, TXT_DB *db,
10405c87c606SMark Murray 			X509 *ca, X509 *rcert, EVP_PKEY *rkey,
10415c87c606SMark Murray 			STACK_OF(X509) *rother, unsigned long flags,
10425c87c606SMark Murray 			int nmin, int ndays)
10435c87c606SMark Murray 	{
10445c87c606SMark Murray 	ASN1_TIME *thisupd = NULL, *nextupd = NULL;
10455c87c606SMark Murray 	OCSP_CERTID *cid, *ca_id = NULL;
10465c87c606SMark Murray 	OCSP_BASICRESP *bs = NULL;
10475c87c606SMark Murray 	int i, id_count, ret = 1;
10485c87c606SMark Murray 
10495c87c606SMark Murray 
10505c87c606SMark Murray 	id_count = OCSP_request_onereq_count(req);
10515c87c606SMark Murray 
10525c87c606SMark Murray 	if (id_count <= 0)
10535c87c606SMark Murray 		{
10545c87c606SMark Murray 		*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
10555c87c606SMark Murray 		goto end;
10565c87c606SMark Murray 		}
10575c87c606SMark Murray 
10585c87c606SMark Murray 	ca_id = OCSP_cert_to_id(EVP_sha1(), NULL, ca);
10595c87c606SMark Murray 
10605c87c606SMark Murray 	bs = OCSP_BASICRESP_new();
10615c87c606SMark Murray 	thisupd = X509_gmtime_adj(NULL, 0);
10625c87c606SMark Murray 	if (ndays != -1)
10635c87c606SMark Murray 		nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24 );
10645c87c606SMark Murray 
10655c87c606SMark Murray 	/* Examine each certificate id in the request */
10665c87c606SMark Murray 	for (i = 0; i < id_count; i++)
10675c87c606SMark Murray 		{
10685c87c606SMark Murray 		OCSP_ONEREQ *one;
10695c87c606SMark Murray 		ASN1_INTEGER *serial;
10705c87c606SMark Murray 		char **inf;
10715c87c606SMark Murray 		one = OCSP_request_onereq_get0(req, i);
10725c87c606SMark Murray 		cid = OCSP_onereq_get0_id(one);
10735c87c606SMark Murray 		/* Is this request about our CA? */
10745c87c606SMark Murray 		if (OCSP_id_issuer_cmp(ca_id, cid))
10755c87c606SMark Murray 			{
10765c87c606SMark Murray 			OCSP_basic_add1_status(bs, cid,
10775c87c606SMark Murray 						V_OCSP_CERTSTATUS_UNKNOWN,
10785c87c606SMark Murray 						0, NULL,
10795c87c606SMark Murray 						thisupd, nextupd);
10805c87c606SMark Murray 			continue;
10815c87c606SMark Murray 			}
10825c87c606SMark Murray 		OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
10835c87c606SMark Murray 		inf = lookup_serial(db, serial);
10845c87c606SMark Murray 		if (!inf)
10855c87c606SMark Murray 			OCSP_basic_add1_status(bs, cid,
10865c87c606SMark Murray 						V_OCSP_CERTSTATUS_UNKNOWN,
10875c87c606SMark Murray 						0, NULL,
10885c87c606SMark Murray 						thisupd, nextupd);
10895c87c606SMark Murray 		else if (inf[DB_type][0] == DB_TYPE_VAL)
10905c87c606SMark Murray 			OCSP_basic_add1_status(bs, cid,
10915c87c606SMark Murray 						V_OCSP_CERTSTATUS_GOOD,
10925c87c606SMark Murray 						0, NULL,
10935c87c606SMark Murray 						thisupd, nextupd);
10945c87c606SMark Murray 		else if (inf[DB_type][0] == DB_TYPE_REV)
10955c87c606SMark Murray 			{
10965c87c606SMark Murray 			ASN1_OBJECT *inst = NULL;
10975c87c606SMark Murray 			ASN1_TIME *revtm = NULL;
10985c87c606SMark Murray 			ASN1_GENERALIZEDTIME *invtm = NULL;
10995c87c606SMark Murray 			OCSP_SINGLERESP *single;
11005c87c606SMark Murray 			int reason = -1;
11015c87c606SMark Murray 			unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]);
11025c87c606SMark Murray 			single = OCSP_basic_add1_status(bs, cid,
11035c87c606SMark Murray 						V_OCSP_CERTSTATUS_REVOKED,
11045c87c606SMark Murray 						reason, revtm,
11055c87c606SMark Murray 						thisupd, nextupd);
11065c87c606SMark Murray 			if (invtm)
11075c87c606SMark Murray 				OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0);
11085c87c606SMark Murray 			else if (inst)
11095c87c606SMark Murray 				OCSP_SINGLERESP_add1_ext_i2d(single, NID_hold_instruction_code, inst, 0, 0);
11105c87c606SMark Murray 			ASN1_OBJECT_free(inst);
11115c87c606SMark Murray 			ASN1_TIME_free(revtm);
11125c87c606SMark Murray 			ASN1_GENERALIZEDTIME_free(invtm);
11135c87c606SMark Murray 			}
11145c87c606SMark Murray 		}
11155c87c606SMark Murray 
11165c87c606SMark Murray 	OCSP_copy_nonce(bs, req);
11175c87c606SMark Murray 
11185c87c606SMark Murray 	OCSP_basic_sign(bs, rcert, rkey, EVP_sha1(), rother, flags);
11195c87c606SMark Murray 
11205c87c606SMark Murray 	*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
11215c87c606SMark Murray 
11225c87c606SMark Murray 	end:
11235c87c606SMark Murray 	ASN1_TIME_free(thisupd);
11245c87c606SMark Murray 	ASN1_TIME_free(nextupd);
11255c87c606SMark Murray 	OCSP_CERTID_free(ca_id);
11265c87c606SMark Murray 	OCSP_BASICRESP_free(bs);
11275c87c606SMark Murray 	return ret;
11285c87c606SMark Murray 
11295c87c606SMark Murray 	}
11305c87c606SMark Murray 
11315c87c606SMark Murray static char **lookup_serial(TXT_DB *db, ASN1_INTEGER *ser)
11325c87c606SMark Murray 	{
11335c87c606SMark Murray 	int i;
11345c87c606SMark Murray 	BIGNUM *bn = NULL;
11355c87c606SMark Murray 	char *itmp, *row[DB_NUMBER],**rrow;
11365c87c606SMark Murray 	for (i = 0; i < DB_NUMBER; i++) row[i] = NULL;
11375c87c606SMark Murray 	bn = ASN1_INTEGER_to_BN(ser,NULL);
11385c87c606SMark Murray 	if (BN_is_zero(bn))
11395c87c606SMark Murray 		itmp = BUF_strdup("00");
11405c87c606SMark Murray 	else
11415c87c606SMark Murray 		itmp = BN_bn2hex(bn);
11425c87c606SMark Murray 	row[DB_serial] = itmp;
11435c87c606SMark Murray 	BN_free(bn);
11445c87c606SMark Murray 	rrow=TXT_DB_get_by_index(db,DB_serial,row);
11455c87c606SMark Murray 	OPENSSL_free(itmp);
11465c87c606SMark Murray 	return rrow;
11475c87c606SMark Murray 	}
11485c87c606SMark Murray 
11495c87c606SMark Murray /* Quick and dirty OCSP server: read in and parse input request */
11505c87c606SMark Murray 
11515c87c606SMark Murray static BIO *init_responder(char *port)
11525c87c606SMark Murray 	{
11535c87c606SMark Murray 	BIO *acbio = NULL, *bufbio = NULL;
11545c87c606SMark Murray 	bufbio = BIO_new(BIO_f_buffer());
11555c87c606SMark Murray 	if (!bufbio)
11565c87c606SMark Murray 		goto err;
1157fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_SOCK
11585c87c606SMark Murray 	acbio = BIO_new_accept(port);
1159fceca8a3SJacques Vidrine #else
1160fceca8a3SJacques Vidrine 	BIO_printf(bio_err, "Error setting up accept BIO - sockets not supported.\n");
1161fceca8a3SJacques Vidrine #endif
11625c87c606SMark Murray 	if (!acbio)
11635c87c606SMark Murray 		goto err;
11645c87c606SMark Murray 	BIO_set_accept_bios(acbio, bufbio);
11655c87c606SMark Murray 	bufbio = NULL;
11665c87c606SMark Murray 
11675c87c606SMark Murray 	if (BIO_do_accept(acbio) <= 0)
11685c87c606SMark Murray 		{
11695c87c606SMark Murray 			BIO_printf(bio_err, "Error setting up accept BIO\n");
11705c87c606SMark Murray 			ERR_print_errors(bio_err);
11715c87c606SMark Murray 			goto err;
11725c87c606SMark Murray 		}
11735c87c606SMark Murray 
11745c87c606SMark Murray 	return acbio;
11755c87c606SMark Murray 
11765c87c606SMark Murray 	err:
11775c87c606SMark Murray 	BIO_free_all(acbio);
11785c87c606SMark Murray 	BIO_free(bufbio);
11795c87c606SMark Murray 	return NULL;
11805c87c606SMark Murray 	}
11815c87c606SMark Murray 
11825c87c606SMark Murray static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port)
11835c87c606SMark Murray 	{
11845c87c606SMark Murray 	int have_post = 0, len;
11855c87c606SMark Murray 	OCSP_REQUEST *req = NULL;
11865c87c606SMark Murray 	char inbuf[1024];
11875c87c606SMark Murray 	BIO *cbio = NULL;
11885c87c606SMark Murray 
11895c87c606SMark Murray 	if (BIO_do_accept(acbio) <= 0)
11905c87c606SMark Murray 		{
11915c87c606SMark Murray 			BIO_printf(bio_err, "Error accepting connection\n");
11925c87c606SMark Murray 			ERR_print_errors(bio_err);
11935c87c606SMark Murray 			return 0;
11945c87c606SMark Murray 		}
11955c87c606SMark Murray 
11965c87c606SMark Murray 	cbio = BIO_pop(acbio);
11975c87c606SMark Murray 	*pcbio = cbio;
11985c87c606SMark Murray 
11995c87c606SMark Murray 	for(;;)
12005c87c606SMark Murray 		{
12015c87c606SMark Murray 		len = BIO_gets(cbio, inbuf, sizeof inbuf);
12025c87c606SMark Murray 		if (len <= 0)
12035c87c606SMark Murray 			return 1;
12045c87c606SMark Murray 		/* Look for "POST" signalling start of query */
12055c87c606SMark Murray 		if (!have_post)
12065c87c606SMark Murray 			{
12075c87c606SMark Murray 			if(strncmp(inbuf, "POST", 4))
12085c87c606SMark Murray 				{
12095c87c606SMark Murray 				BIO_printf(bio_err, "Invalid request\n");
12105c87c606SMark Murray 				return 1;
12115c87c606SMark Murray 				}
12125c87c606SMark Murray 			have_post = 1;
12135c87c606SMark Murray 			}
12145c87c606SMark Murray 		/* Look for end of headers */
12155c87c606SMark Murray 		if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
12165c87c606SMark Murray 			break;
12175c87c606SMark Murray 		}
12185c87c606SMark Murray 
12195c87c606SMark Murray 	/* Try to read OCSP request */
12205c87c606SMark Murray 
12215c87c606SMark Murray 	req = d2i_OCSP_REQUEST_bio(cbio, NULL);
12225c87c606SMark Murray 
12235c87c606SMark Murray 	if (!req)
12245c87c606SMark Murray 		{
12255c87c606SMark Murray 		BIO_printf(bio_err, "Error parsing OCSP request\n");
12265c87c606SMark Murray 		ERR_print_errors(bio_err);
12275c87c606SMark Murray 		}
12285c87c606SMark Murray 
12295c87c606SMark Murray 	*preq = req;
12305c87c606SMark Murray 
12315c87c606SMark Murray 	return 1;
12325c87c606SMark Murray 
12335c87c606SMark Murray 	}
12345c87c606SMark Murray 
12355c87c606SMark Murray static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
12365c87c606SMark Murray 	{
12375c87c606SMark Murray 	char http_resp[] =
12385c87c606SMark Murray 		"HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n"
12395c87c606SMark Murray 		"Content-Length: %d\r\n\r\n";
12405c87c606SMark Murray 	if (!cbio)
12415c87c606SMark Murray 		return 0;
12425c87c606SMark Murray 	BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL));
12435c87c606SMark Murray 	i2d_OCSP_RESPONSE_bio(cbio, resp);
12445c87c606SMark Murray 	BIO_flush(cbio);
12455c87c606SMark Murray 	return 1;
12465c87c606SMark Murray 	}
12475c87c606SMark Murray 
1248fceca8a3SJacques Vidrine #endif
1249