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