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