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