oops, revert, committed in error
[openssl.git] / apps / ocsp.c
1 /* ocsp.c */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) 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 #ifdef OPENSSL_SYS_VMS
61 #define _XOPEN_SOURCE_EXTENDED  /* So fd_set and friends get properly defined
62                                    on OpenVMS */
63 #endif
64
65 #define USE_SOCKETS
66
67 #include <stdio.h>
68 #include <stdlib.h>
69 #include <string.h>
70 #include <time.h>
71 #include "apps.h" /* needs to be included before the openssl headers! */
72 #include <openssl/e_os2.h>
73 #include <openssl/crypto.h>
74 #include <openssl/err.h>
75 #include <openssl/ssl.h>
76 #include <openssl/evp.h>
77 #include <openssl/bn.h>
78 #include <openssl/x509v3.h>
79
80 #if defined(NETWARE_CLIB)
81 #  ifdef NETWARE_BSDSOCK
82 #    include <sys/socket.h>
83 #    include <sys/bsdskt.h>
84 #  else
85 #    include <novsock2.h>
86 #  endif
87 #elif defined(NETWARE_LIBC)
88 #  ifdef NETWARE_BSDSOCK
89 #    include <sys/select.h>
90 #  else
91 #    include <novsock2.h>
92 #  endif
93 #endif
94   
95 /* Maximum leeway in validity period: default 5 minutes */
96 #define MAX_VALIDITY_PERIOD     (5 * 60)
97
98 static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md, X509 *issuer,
99                                 STACK_OF(OCSP_CERTID) *ids);
100 static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, const EVP_MD * cert_id_md, X509 *issuer,
101                                 STACK_OF(OCSP_CERTID) *ids);
102 static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
103                               STACK_OF(OPENSSL_STRING) *names,
104                               STACK_OF(OCSP_CERTID) *ids, long nsec,
105                               long maxage);
106
107 static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
108                         X509 *ca, X509 *rcert, EVP_PKEY *rkey,
109                         STACK_OF(X509) *rother, unsigned long flags,
110                         int nmin, int ndays, int badsig);
111
112 static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
113 static BIO *init_responder(char *port);
114 static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port);
115 static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
116 static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
117                                 STACK_OF(CONF_VALUE) *headers,
118                                 OCSP_REQUEST *req, int req_timeout);
119
120 #undef PROG
121 #define PROG ocsp_main
122
123 int MAIN(int, char **);
124
125 int MAIN(int argc, char **argv)
126         {
127         ENGINE *e = NULL;
128         char **args;
129         char *host = NULL, *port = NULL, *path = "/";
130         char *reqin = NULL, *respin = NULL;
131         char *reqout = NULL, *respout = NULL;
132         char *signfile = NULL, *keyfile = NULL;
133         char *rsignfile = NULL, *rkeyfile = NULL;
134         char *outfile = NULL;
135         int add_nonce = 1, noverify = 0, use_ssl = -1;
136         STACK_OF(CONF_VALUE) *headers = NULL;
137         OCSP_REQUEST *req = NULL;
138         OCSP_RESPONSE *resp = NULL;
139         OCSP_BASICRESP *bs = NULL;
140         X509 *issuer = NULL, *cert = NULL;
141         X509 *signer = NULL, *rsigner = NULL;
142         EVP_PKEY *key = NULL, *rkey = NULL;
143         BIO *acbio = NULL, *cbio = NULL;
144         BIO *derbio = NULL;
145         BIO *out = NULL;
146         int req_timeout = -1;
147         int req_text = 0, resp_text = 0;
148         long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
149         char *CAfile = NULL, *CApath = NULL;
150         X509_STORE *store = NULL;
151         STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
152         char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
153         unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
154         int ret = 1;
155         int accept_count = -1;
156         int badarg = 0;
157         int badsig = 0;
158         int i;
159         int ignore_err = 0;
160         STACK_OF(OPENSSL_STRING) *reqnames = NULL;
161         STACK_OF(OCSP_CERTID) *ids = NULL;
162
163         X509 *rca_cert = NULL;
164         char *ridx_filename = NULL;
165         char *rca_filename = NULL;
166         CA_DB *rdb = NULL;
167         int nmin = 0, ndays = -1;
168         const EVP_MD *cert_id_md = NULL;
169
170         if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
171
172         if (!load_config(bio_err, NULL))
173                 goto end;
174         SSL_load_error_strings();
175         OpenSSL_add_ssl_algorithms();
176         args = argv + 1;
177         reqnames = sk_OPENSSL_STRING_new_null();
178         ids = sk_OCSP_CERTID_new_null();
179         while (!badarg && *args && *args[0] == '-')
180                 {
181                 if (!strcmp(*args, "-out"))
182                         {
183                         if (args[1])
184                                 {
185                                 args++;
186                                 outfile = *args;
187                                 }
188                         else badarg = 1;
189                         }
190                 else if (!strcmp(*args, "-timeout"))
191                         {
192                         if (args[1])
193                                 {
194                                 args++;
195                                 req_timeout = atol(*args);
196                                 if (req_timeout < 0)
197                                         {
198                                         BIO_printf(bio_err,
199                                                 "Illegal timeout value %s\n",
200                                                 *args);
201                                         badarg = 1;
202                                         }
203                                 }
204                         else badarg = 1;
205                         }
206                 else if (!strcmp(*args, "-url"))
207                         {
208                         if (args[1])
209                                 {
210                                 args++;
211                                 if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl))
212                                         {
213                                         BIO_printf(bio_err, "Error parsing URL\n");
214                                         badarg = 1;
215                                         }
216                                 }
217                         else badarg = 1;
218                         }
219                 else if (!strcmp(*args, "-host"))
220                         {
221                         if (args[1])
222                                 {
223                                 args++;
224                                 host = *args;
225                                 }
226                         else badarg = 1;
227                         }
228                 else if (!strcmp(*args, "-port"))
229                         {
230                         if (args[1])
231                                 {
232                                 args++;
233                                 port = *args;
234                                 }
235                         else badarg = 1;
236                         }
237                 else if (!strcmp(*args, "-header"))
238                         {
239                         if (args[1] && args[2])
240                                 {
241                                 if (!X509V3_add_value(args[1], args[2], &headers))
242                                         goto end;
243                                 args += 2;
244                                 }
245                         else badarg = 1;
246                         }
247                 else if (!strcmp(*args, "-ignore_err"))
248                         ignore_err = 1;
249                 else if (!strcmp(*args, "-noverify"))
250                         noverify = 1;
251                 else if (!strcmp(*args, "-nonce"))
252                         add_nonce = 2;
253                 else if (!strcmp(*args, "-no_nonce"))
254                         add_nonce = 0;
255                 else if (!strcmp(*args, "-resp_no_certs"))
256                         rflags |= OCSP_NOCERTS;
257                 else if (!strcmp(*args, "-resp_key_id"))
258                         rflags |= OCSP_RESPID_KEY;
259                 else if (!strcmp(*args, "-no_certs"))
260                         sign_flags |= OCSP_NOCERTS;
261                 else if (!strcmp(*args, "-no_signature_verify"))
262                         verify_flags |= OCSP_NOSIGS;
263                 else if (!strcmp(*args, "-no_cert_verify"))
264                         verify_flags |= OCSP_NOVERIFY;
265                 else if (!strcmp(*args, "-no_chain"))
266                         verify_flags |= OCSP_NOCHAIN;
267                 else if (!strcmp(*args, "-no_cert_checks"))
268                         verify_flags |= OCSP_NOCHECKS;
269                 else if (!strcmp(*args, "-no_explicit"))
270                         verify_flags |= OCSP_NOEXPLICIT;
271                 else if (!strcmp(*args, "-trust_other"))
272                         verify_flags |= OCSP_TRUSTOTHER;
273                 else if (!strcmp(*args, "-no_intern"))
274                         verify_flags |= OCSP_NOINTERN;
275                 else if (!strcmp(*args, "-badsig"))
276                         badsig = 1;
277                 else if (!strcmp(*args, "-text"))
278                         {
279                         req_text = 1;
280                         resp_text = 1;
281                         }
282                 else if (!strcmp(*args, "-req_text"))
283                         req_text = 1;
284                 else if (!strcmp(*args, "-resp_text"))
285                         resp_text = 1;
286                 else if (!strcmp(*args, "-reqin"))
287                         {
288                         if (args[1])
289                                 {
290                                 args++;
291                                 reqin = *args;
292                                 }
293                         else badarg = 1;
294                         }
295                 else if (!strcmp(*args, "-respin"))
296                         {
297                         if (args[1])
298                                 {
299                                 args++;
300                                 respin = *args;
301                                 }
302                         else badarg = 1;
303                         }
304                 else if (!strcmp(*args, "-signer"))
305                         {
306                         if (args[1])
307                                 {
308                                 args++;
309                                 signfile = *args;
310                                 }
311                         else badarg = 1;
312                         }
313                 else if (!strcmp (*args, "-VAfile"))
314                         {
315                         if (args[1])
316                                 {
317                                 args++;
318                                 verify_certfile = *args;
319                                 verify_flags |= OCSP_TRUSTOTHER;
320                                 }
321                         else badarg = 1;
322                         }
323                 else if (!strcmp(*args, "-sign_other"))
324                         {
325                         if (args[1])
326                                 {
327                                 args++;
328                                 sign_certfile = *args;
329                                 }
330                         else badarg = 1;
331                         }
332                 else if (!strcmp(*args, "-verify_other"))
333                         {
334                         if (args[1])
335                                 {
336                                 args++;
337                                 verify_certfile = *args;
338                                 }
339                         else badarg = 1;
340                         }
341                 else if (!strcmp (*args, "-CAfile"))
342                         {
343                         if (args[1])
344                                 {
345                                 args++;
346                                 CAfile = *args;
347                                 }
348                         else badarg = 1;
349                         }
350                 else if (!strcmp (*args, "-CApath"))
351                         {
352                         if (args[1])
353                                 {
354                                 args++;
355                                 CApath = *args;
356                                 }
357                         else badarg = 1;
358                         }
359                 else if (!strcmp (*args, "-validity_period"))
360                         {
361                         if (args[1])
362                                 {
363                                 args++;
364                                 nsec = atol(*args);
365                                 if (nsec < 0)
366                                         {
367                                         BIO_printf(bio_err,
368                                                 "Illegal validity period %s\n",
369                                                 *args);
370                                         badarg = 1;
371                                         }
372                                 }
373                         else badarg = 1;
374                         }
375                 else if (!strcmp (*args, "-status_age"))
376                         {
377                         if (args[1])
378                                 {
379                                 args++;
380                                 maxage = atol(*args);
381                                 if (maxage < 0)
382                                         {
383                                         BIO_printf(bio_err,
384                                                 "Illegal validity age %s\n",
385                                                 *args);
386                                         badarg = 1;
387                                         }
388                                 }
389                         else badarg = 1;
390                         }
391                  else if (!strcmp(*args, "-signkey"))
392                         {
393                         if (args[1])
394                                 {
395                                 args++;
396                                 keyfile = *args;
397                                 }
398                         else badarg = 1;
399                         }
400                 else if (!strcmp(*args, "-reqout"))
401                         {
402                         if (args[1])
403                                 {
404                                 args++;
405                                 reqout = *args;
406                                 }
407                         else badarg = 1;
408                         }
409                 else if (!strcmp(*args, "-respout"))
410                         {
411                         if (args[1])
412                                 {
413                                 args++;
414                                 respout = *args;
415                                 }
416                         else badarg = 1;
417                         }
418                  else if (!strcmp(*args, "-path"))
419                         {
420                         if (args[1])
421                                 {
422                                 args++;
423                                 path = *args;
424                                 }
425                         else badarg = 1;
426                         }
427                 else if (!strcmp(*args, "-issuer"))
428                         {
429                         if (args[1])
430                                 {
431                                 args++;
432                                 X509_free(issuer);
433                                 issuer = load_cert(bio_err, *args, FORMAT_PEM,
434                                         NULL, e, "issuer certificate");
435                                 if(!issuer) goto end;
436                                 }
437                         else badarg = 1;
438                         }
439                 else if (!strcmp (*args, "-cert"))
440                         {
441                         if (args[1])
442                                 {
443                                 args++;
444                                 X509_free(cert);
445                                 cert = load_cert(bio_err, *args, FORMAT_PEM,
446                                         NULL, e, "certificate");
447                                 if(!cert) goto end;
448                                 if (!cert_id_md) cert_id_md = EVP_sha1();
449                                 if(!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids))
450                                         goto end;
451                                 if(!sk_OPENSSL_STRING_push(reqnames, *args))
452                                         goto end;
453                                 }
454                         else badarg = 1;
455                         }
456                 else if (!strcmp(*args, "-serial"))
457                         {
458                         if (args[1])
459                                 {
460                                 args++;
461                                 if (!cert_id_md) cert_id_md = EVP_sha1();
462                                 if(!add_ocsp_serial(&req, *args, cert_id_md, issuer, ids))
463                                         goto end;
464                                 if(!sk_OPENSSL_STRING_push(reqnames, *args))
465                                         goto end;
466                                 }
467                         else badarg = 1;
468                         }
469                 else if (!strcmp(*args, "-index"))
470                         {
471                         if (args[1])
472                                 {
473                                 args++;
474                                 ridx_filename = *args;
475                                 }
476                         else badarg = 1;
477                         }
478                 else if (!strcmp(*args, "-CA"))
479                         {
480                         if (args[1])
481                                 {
482                                 args++;
483                                 rca_filename = *args;
484                                 }
485                         else badarg = 1;
486                         }
487                 else if (!strcmp (*args, "-nmin"))
488                         {
489                         if (args[1])
490                                 {
491                                 args++;
492                                 nmin = atol(*args);
493                                 if (nmin < 0)
494                                         {
495                                         BIO_printf(bio_err,
496                                                 "Illegal update period %s\n",
497                                                 *args);
498                                         badarg = 1;
499                                         }
500                                 }
501                                 if (ndays == -1)
502                                         ndays = 0;
503                         else badarg = 1;
504                         }
505                 else if (!strcmp (*args, "-nrequest"))
506                         {
507                         if (args[1])
508                                 {
509                                 args++;
510                                 accept_count = atol(*args);
511                                 if (accept_count < 0)
512                                         {
513                                         BIO_printf(bio_err,
514                                                 "Illegal accept count %s\n",
515                                                 *args);
516                                         badarg = 1;
517                                         }
518                                 }
519                         else badarg = 1;
520                         }
521                 else if (!strcmp (*args, "-ndays"))
522                         {
523                         if (args[1])
524                                 {
525                                 args++;
526                                 ndays = atol(*args);
527                                 if (ndays < 0)
528                                         {
529                                         BIO_printf(bio_err,
530                                                 "Illegal update period %s\n",
531                                                 *args);
532                                         badarg = 1;
533                                         }
534                                 }
535                         else badarg = 1;
536                         }
537                 else if (!strcmp(*args, "-rsigner"))
538                         {
539                         if (args[1])
540                                 {
541                                 args++;
542                                 rsignfile = *args;
543                                 }
544                         else badarg = 1;
545                         }
546                 else if (!strcmp(*args, "-rkey"))
547                         {
548                         if (args[1])
549                                 {
550                                 args++;
551                                 rkeyfile = *args;
552                                 }
553                         else badarg = 1;
554                         }
555                 else if (!strcmp(*args, "-rother"))
556                         {
557                         if (args[1])
558                                 {
559                                 args++;
560                                 rcertfile = *args;
561                                 }
562                         else badarg = 1;
563                         }
564                 else if ((cert_id_md = EVP_get_digestbyname((*args)+1))==NULL)
565                         {
566                         badarg = 1;
567                         }
568                 args++;
569                 }
570
571         /* Have we anything to do? */
572         if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1;
573
574         if (badarg)
575                 {
576                 BIO_printf (bio_err, "OCSP utility\n");
577                 BIO_printf (bio_err, "Usage ocsp [options]\n");
578                 BIO_printf (bio_err, "where options are\n");
579                 BIO_printf (bio_err, "-out file          output filename\n");
580                 BIO_printf (bio_err, "-issuer file       issuer certificate\n");
581                 BIO_printf (bio_err, "-cert file         certificate to check\n");
582                 BIO_printf (bio_err, "-serial n          serial number to check\n");
583                 BIO_printf (bio_err, "-signer file       certificate to sign OCSP request with\n");
584                 BIO_printf (bio_err, "-signkey file      private key to sign OCSP request with\n");
585                 BIO_printf (bio_err, "-sign_other file   additional certificates to include in signed request\n");
586                 BIO_printf (bio_err, "-no_certs          don't include any certificates in signed request\n");
587                 BIO_printf (bio_err, "-req_text          print text form of request\n");
588                 BIO_printf (bio_err, "-resp_text         print text form of response\n");
589                 BIO_printf (bio_err, "-text              print text form of request and response\n");
590                 BIO_printf (bio_err, "-reqout file       write DER encoded OCSP request to \"file\"\n");
591                 BIO_printf (bio_err, "-respout file      write DER encoded OCSP reponse to \"file\"\n");
592                 BIO_printf (bio_err, "-reqin file        read DER encoded OCSP request from \"file\"\n");
593                 BIO_printf (bio_err, "-respin file       read DER encoded OCSP reponse from \"file\"\n");
594                 BIO_printf (bio_err, "-nonce             add OCSP nonce to request\n");
595                 BIO_printf (bio_err, "-no_nonce          don't add OCSP nonce to request\n");
596                 BIO_printf (bio_err, "-url URL           OCSP responder URL\n");
597                 BIO_printf (bio_err, "-host host:n       send OCSP request to host on port n\n");
598                 BIO_printf (bio_err, "-path              path to use in OCSP request\n");
599                 BIO_printf (bio_err, "-CApath dir        trusted certificates directory\n");
600                 BIO_printf (bio_err, "-CAfile file       trusted certificates file\n");
601                 BIO_printf (bio_err, "-VAfile file       validator certificates file\n");
602                 BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
603                 BIO_printf (bio_err, "-status_age n      maximum status age in seconds\n");
604                 BIO_printf (bio_err, "-noverify          don't verify response at all\n");
605                 BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n");
606                 BIO_printf (bio_err, "-trust_other       don't verify additional certificates\n");
607                 BIO_printf (bio_err, "-no_intern         don't search certificates contained in response for signer\n");
608                 BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n");
609                 BIO_printf (bio_err, "-no_cert_verify    don't check signing certificate\n");
610                 BIO_printf (bio_err, "-no_chain          don't chain verify response\n");
611                 BIO_printf (bio_err, "-no_cert_checks    don't do additional checks on signing certificate\n");
612                 BIO_printf (bio_err, "-port num          port to run responder on\n");
613                 BIO_printf (bio_err, "-index file        certificate status index file\n");
614                 BIO_printf (bio_err, "-CA file           CA certificate\n");
615                 BIO_printf (bio_err, "-rsigner file      responder certificate to sign responses with\n");
616                 BIO_printf (bio_err, "-rkey file         responder key to sign responses with\n");
617                 BIO_printf (bio_err, "-rother file       other certificates to include in response\n");
618                 BIO_printf (bio_err, "-resp_no_certs     don't include any certificates in response\n");
619                 BIO_printf (bio_err, "-nmin n            number of minutes before next update\n");
620                 BIO_printf (bio_err, "-ndays n           number of days before next update\n");
621                 BIO_printf (bio_err, "-resp_key_id       identify reponse by signing certificate key ID\n");
622                 BIO_printf (bio_err, "-nrequest n        number of requests to accept (default unlimited)\n");
623                 BIO_printf (bio_err, "-<dgst alg>     use specified digest in the request");
624                 goto end;
625                 }
626
627         if(outfile) out = BIO_new_file(outfile, "w");
628         else out = BIO_new_fp(stdout, BIO_NOCLOSE);
629
630         if(!out)
631                 {
632                 BIO_printf(bio_err, "Error opening output file\n");
633                 goto end;
634                 }
635
636         if (!req && (add_nonce != 2)) add_nonce = 0;
637
638         if (!req && reqin)
639                 {
640                 derbio = BIO_new_file(reqin, "rb");
641                 if (!derbio)
642                         {
643                         BIO_printf(bio_err, "Error Opening OCSP request file\n");
644                         goto end;
645                         }
646                 req = d2i_OCSP_REQUEST_bio(derbio, NULL);
647                 BIO_free(derbio);
648                 if(!req)
649                         {
650                         BIO_printf(bio_err, "Error reading OCSP request\n");
651                         goto end;
652                         }
653                 }
654
655         if (!req && port)
656                 {
657                 acbio = init_responder(port);
658                 if (!acbio)
659                         goto end;
660                 }
661
662         if (rsignfile && !rdb)
663                 {
664                 if (!rkeyfile) rkeyfile = rsignfile;
665                 rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,
666                         NULL, e, "responder certificate");
667                 if (!rsigner)
668                         {
669                         BIO_printf(bio_err, "Error loading responder certificate\n");
670                         goto end;
671                         }
672                 rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,
673                         NULL, e, "CA certificate");
674                 if (rcertfile)
675                         {
676                         rother = load_certs(bio_err, rcertfile, FORMAT_PEM,
677                                 NULL, e, "responder other certificates");
678                         if (!rother) goto end;
679                         }
680                 rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL,
681                         "responder private key");
682                 if (!rkey)
683                         goto end;
684                 }
685         if(acbio)
686                 BIO_printf(bio_err, "Waiting for OCSP client connections...\n");
687
688         redo_accept:
689
690         if (acbio)
691                 {
692                 if (!do_responder(&req, &cbio, acbio, port))
693                         goto end;
694                 if (!req)
695                         {
696                         resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
697                         send_ocsp_response(cbio, resp);
698                         goto done_resp;
699                         }
700                 }
701
702         if (!req && (signfile || reqout || host || add_nonce || ridx_filename))
703                 {
704                 BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
705                 goto end;
706                 }
707
708         if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1);
709
710         if (signfile)
711                 {
712                 if (!keyfile) keyfile = signfile;
713                 signer = load_cert(bio_err, signfile, FORMAT_PEM,
714                         NULL, e, "signer certificate");
715                 if (!signer)
716                         {
717                         BIO_printf(bio_err, "Error loading signer certificate\n");
718                         goto end;
719                         }
720                 if (sign_certfile)
721                         {
722                         sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,
723                                 NULL, e, "signer certificates");
724                         if (!sign_other) goto end;
725                         }
726                 key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL,
727                         "signer private key");
728                 if (!key)
729                         goto end;
730
731                 if (!OCSP_request_sign(req, signer, key, NULL, sign_other, sign_flags))
732                         {
733                         BIO_printf(bio_err, "Error signing OCSP request\n");
734                         goto end;
735                         }
736                 }
737
738         if (req_text && req) OCSP_REQUEST_print(out, req, 0);
739
740         if (reqout)
741                 {
742                 derbio = BIO_new_file(reqout, "wb");
743                 if(!derbio)
744                         {
745                         BIO_printf(bio_err, "Error opening file %s\n", reqout);
746                         goto end;
747                         }
748                 i2d_OCSP_REQUEST_bio(derbio, req);
749                 BIO_free(derbio);
750                 }
751
752         if (ridx_filename && (!rkey || !rsigner || !rca_cert))
753                 {
754                 BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n");
755                 goto end;
756                 }
757
758         if (ridx_filename && !rdb)
759                 {
760                 rdb = load_index(ridx_filename, NULL);
761                 if (!rdb) goto end;
762                 if (!index_index(rdb)) goto end;
763                 }
764
765         if (rdb)
766                 {
767                 i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays, badsig);
768                 if (cbio)
769                         send_ocsp_response(cbio, resp);
770                 }
771         else if (host)
772                 {
773 #ifndef OPENSSL_NO_SOCK
774                 resp = process_responder(bio_err, req, host, path,
775                                         port, use_ssl, headers, req_timeout);
776                 if (!resp)
777                         goto end;
778 #else
779                 BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n");
780                 goto end;
781 #endif
782                 }
783         else if (respin)
784                 {
785                 derbio = BIO_new_file(respin, "rb");
786                 if (!derbio)
787                         {
788                         BIO_printf(bio_err, "Error Opening OCSP response file\n");
789                         goto end;
790                         }
791                 resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
792                 BIO_free(derbio);
793                 if(!resp)
794                         {
795                         BIO_printf(bio_err, "Error reading OCSP response\n");
796                         goto end;
797                         }
798         
799                 }
800         else
801                 {
802                 ret = 0;
803                 goto end;
804                 }
805
806         done_resp:
807
808         if (respout)
809                 {
810                 derbio = BIO_new_file(respout, "wb");
811                 if(!derbio)
812                         {
813                         BIO_printf(bio_err, "Error opening file %s\n", respout);
814                         goto end;
815                         }
816                 i2d_OCSP_RESPONSE_bio(derbio, resp);
817                 BIO_free(derbio);
818                 }
819
820         i = OCSP_response_status(resp);
821
822         if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL)
823                 {
824                 BIO_printf(out, "Responder Error: %s (%d)\n",
825                                 OCSP_response_status_str(i), i);
826                 if (ignore_err)
827                         goto redo_accept;
828                 ret = 0;
829                 goto end;
830                 }
831
832         if (resp_text) OCSP_RESPONSE_print(out, resp, 0);
833
834         /* If running as responder don't verify our own response */
835         if (cbio)
836                 {
837                 if (accept_count > 0)
838                         accept_count--;
839                 /* Redo if more connections needed */
840                 if (accept_count)
841                         {
842                         BIO_free_all(cbio);
843                         cbio = NULL;
844                         OCSP_REQUEST_free(req);
845                         req = NULL;
846                         OCSP_RESPONSE_free(resp);
847                         resp = NULL;
848                         goto redo_accept;
849                         }
850                 goto end;
851                 }
852
853         if (!store)
854                 store = setup_verify(bio_err, CAfile, CApath);
855         if (!store)
856                 goto end;
857         if (verify_certfile)
858                 {
859                 verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,
860                         NULL, e, "validator certificate");
861                 if (!verify_other) goto end;
862                 }
863
864         bs = OCSP_response_get1_basic(resp);
865
866         if (!bs)
867                 {
868                 BIO_printf(bio_err, "Error parsing response\n");
869                 goto end;
870                 }
871
872         ret = 0;
873
874         if (!noverify)
875                 {
876                 if (req && ((i = OCSP_check_nonce(req, bs)) <= 0))
877                         {
878                         if (i == -1)
879                                 BIO_printf(bio_err, "WARNING: no nonce in response\n");
880                         else
881                                 {
882                                 BIO_printf(bio_err, "Nonce Verify error\n");
883                                 ret = 1;
884                                 goto end;
885                                 }
886                         }
887
888                 i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
889                 if(i <= 0)
890                         {
891                         BIO_printf(bio_err, "Response Verify Failure\n");
892                         ERR_print_errors(bio_err);
893                         ret = 1;
894                         }
895                 else
896                         BIO_printf(bio_err, "Response verify OK\n");
897
898                 }
899
900         if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage))
901                 ret = 1;
902
903 end:
904         ERR_print_errors(bio_err);
905         X509_free(signer);
906         X509_STORE_free(store);
907         EVP_PKEY_free(key);
908         EVP_PKEY_free(rkey);
909         X509_free(issuer);
910         X509_free(cert);
911         X509_free(rsigner);
912         X509_free(rca_cert);
913         free_index(rdb);
914         BIO_free_all(cbio);
915         BIO_free_all(acbio);
916         BIO_free(out);
917         OCSP_REQUEST_free(req);
918         OCSP_RESPONSE_free(resp);
919         OCSP_BASICRESP_free(bs);
920         sk_OPENSSL_STRING_free(reqnames);
921         sk_OCSP_CERTID_free(ids);
922         sk_X509_pop_free(sign_other, X509_free);
923         sk_X509_pop_free(verify_other, X509_free);
924         sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
925
926         if (use_ssl != -1)
927                 {
928                 OPENSSL_free(host);
929                 OPENSSL_free(port);
930                 OPENSSL_free(path);
931                 }
932
933         OPENSSL_EXIT(ret);
934 }
935
936 static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md,X509 *issuer,
937                                 STACK_OF(OCSP_CERTID) *ids)
938         {
939         OCSP_CERTID *id;
940         if(!issuer)
941                 {
942                 BIO_printf(bio_err, "No issuer certificate specified\n");
943                 return 0;
944                 }
945         if(!*req) *req = OCSP_REQUEST_new();
946         if(!*req) goto err;
947         id = OCSP_cert_to_id(cert_id_md, cert, issuer);
948         if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
949         if(!OCSP_request_add0_id(*req, id)) goto err;
950         return 1;
951
952         err:
953         BIO_printf(bio_err, "Error Creating OCSP request\n");
954         return 0;
955         }
956
957 static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,const EVP_MD *cert_id_md, X509 *issuer,
958                                 STACK_OF(OCSP_CERTID) *ids)
959         {
960         OCSP_CERTID *id;
961         X509_NAME *iname;
962         ASN1_BIT_STRING *ikey;
963         ASN1_INTEGER *sno;
964         if(!issuer)
965                 {
966                 BIO_printf(bio_err, "No issuer certificate specified\n");
967                 return 0;
968                 }
969         if(!*req) *req = OCSP_REQUEST_new();
970         if(!*req) goto err;
971         iname = X509_get_subject_name(issuer);
972         ikey = X509_get0_pubkey_bitstr(issuer);
973         sno = s2i_ASN1_INTEGER(NULL, serial);
974         if(!sno)
975                 {
976                 BIO_printf(bio_err, "Error converting serial number %s\n", serial);
977                 return 0;
978                 }
979         id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno);
980         ASN1_INTEGER_free(sno);
981         if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
982         if(!OCSP_request_add0_id(*req, id)) goto err;
983         return 1;
984
985         err:
986         BIO_printf(bio_err, "Error Creating OCSP request\n");
987         return 0;
988         }
989
990 static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
991                               STACK_OF(OPENSSL_STRING) *names,
992                               STACK_OF(OCSP_CERTID) *ids, long nsec,
993                               long maxage)
994         {
995         OCSP_CERTID *id;
996         char *name;
997         int i;
998
999         int status, reason;
1000
1001         ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
1002
1003         if (!bs || !req || !sk_OPENSSL_STRING_num(names) || !sk_OCSP_CERTID_num(ids))
1004                 return 1;
1005
1006         for (i = 0; i < sk_OCSP_CERTID_num(ids); i++)
1007                 {
1008                 id = sk_OCSP_CERTID_value(ids, i);
1009                 name = sk_OPENSSL_STRING_value(names, i);
1010                 BIO_printf(out, "%s: ", name);
1011
1012                 if(!OCSP_resp_find_status(bs, id, &status, &reason,
1013                                         &rev, &thisupd, &nextupd))
1014                         {
1015                         BIO_puts(out, "ERROR: No Status found.\n");
1016                         continue;
1017                         }
1018
1019                 /* Check validity: if invalid write to output BIO so we
1020                  * know which response this refers to.
1021                  */
1022                 if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage))
1023                         {
1024                         BIO_puts(out, "WARNING: Status times invalid.\n");
1025                         ERR_print_errors(out);
1026                         }
1027                 BIO_printf(out, "%s\n", OCSP_cert_status_str(status));
1028
1029                 BIO_puts(out, "\tThis Update: ");
1030                 ASN1_GENERALIZEDTIME_print(out, thisupd);
1031                 BIO_puts(out, "\n");
1032
1033                 if(nextupd)
1034                         {
1035                         BIO_puts(out, "\tNext Update: ");
1036                         ASN1_GENERALIZEDTIME_print(out, nextupd);
1037                         BIO_puts(out, "\n");
1038                         }
1039
1040                 if (status != V_OCSP_CERTSTATUS_REVOKED)
1041                         continue;
1042
1043                 if (reason != -1)
1044                         BIO_printf(out, "\tReason: %s\n",
1045                                 OCSP_crl_reason_str(reason));
1046
1047                 BIO_puts(out, "\tRevocation Time: ");
1048                 ASN1_GENERALIZEDTIME_print(out, rev);
1049                 BIO_puts(out, "\n");
1050                 }
1051
1052         return 1;
1053         }
1054
1055
1056 static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
1057                         X509 *ca, X509 *rcert, EVP_PKEY *rkey,
1058                         STACK_OF(X509) *rother, unsigned long flags,
1059                         int nmin, int ndays, int badsig)
1060         {
1061         ASN1_TIME *thisupd = NULL, *nextupd = NULL;
1062         OCSP_CERTID *cid, *ca_id = NULL;
1063         OCSP_BASICRESP *bs = NULL;
1064         int i, id_count, ret = 1;
1065
1066         id_count = OCSP_request_onereq_count(req);
1067
1068         if (id_count <= 0)
1069                 {
1070                 *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
1071                 goto end;
1072                 }
1073
1074
1075         bs = OCSP_BASICRESP_new();
1076         thisupd = X509_gmtime_adj(NULL, 0);
1077         if (ndays != -1)
1078                 nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24 );
1079
1080         /* Examine each certificate id in the request */
1081         for (i = 0; i < id_count; i++)
1082                 {
1083                 OCSP_ONEREQ *one;
1084                 ASN1_INTEGER *serial;
1085                 char **inf;
1086                 ASN1_OBJECT *cert_id_md_oid;
1087                 const EVP_MD *cert_id_md;
1088                 one = OCSP_request_onereq_get0(req, i);
1089                 cid = OCSP_onereq_get0_id(one);
1090
1091                 OCSP_id_get0_info(NULL,&cert_id_md_oid, NULL,NULL, cid);
1092
1093                 cert_id_md = EVP_get_digestbyobj(cert_id_md_oid);       
1094                 if (! cert_id_md) 
1095                         {
1096                         *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR,
1097                                 NULL);
1098                                 goto end;
1099                         }       
1100                 if (ca_id) OCSP_CERTID_free(ca_id);
1101                 ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca);
1102
1103                 /* Is this request about our CA? */
1104                 if (OCSP_id_issuer_cmp(ca_id, cid))
1105                         {
1106                         OCSP_basic_add1_status(bs, cid,
1107                                                 V_OCSP_CERTSTATUS_UNKNOWN,
1108                                                 0, NULL,
1109                                                 thisupd, nextupd);
1110                         continue;
1111                         }
1112                 OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
1113                 inf = lookup_serial(db, serial);
1114                 if (!inf)
1115                         OCSP_basic_add1_status(bs, cid,
1116                                                 V_OCSP_CERTSTATUS_UNKNOWN,
1117                                                 0, NULL,
1118                                                 thisupd, nextupd);
1119                 else if (inf[DB_type][0] == DB_TYPE_VAL)
1120                         OCSP_basic_add1_status(bs, cid,
1121                                                 V_OCSP_CERTSTATUS_GOOD,
1122                                                 0, NULL,
1123                                                 thisupd, nextupd);
1124                 else if (inf[DB_type][0] == DB_TYPE_REV)
1125                         {
1126                         ASN1_OBJECT *inst = NULL;
1127                         ASN1_TIME *revtm = NULL;
1128                         ASN1_GENERALIZEDTIME *invtm = NULL;
1129                         OCSP_SINGLERESP *single;
1130                         int reason = -1;
1131                         unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]);
1132                         single = OCSP_basic_add1_status(bs, cid,
1133                                                 V_OCSP_CERTSTATUS_REVOKED,
1134                                                 reason, revtm,
1135                                                 thisupd, nextupd);
1136                         if (invtm)
1137                                 OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0);
1138                         else if (inst)
1139                                 OCSP_SINGLERESP_add1_ext_i2d(single, NID_hold_instruction_code, inst, 0, 0);
1140                         ASN1_OBJECT_free(inst);
1141                         ASN1_TIME_free(revtm);
1142                         ASN1_GENERALIZEDTIME_free(invtm);
1143                         }
1144                 }
1145
1146         OCSP_copy_nonce(bs, req);
1147         
1148         OCSP_basic_sign(bs, rcert, rkey, NULL, rother, flags);
1149
1150         if (badsig)
1151                 bs->signature->data[bs->signature->length -1] ^= 0x1;
1152
1153         *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
1154
1155         end:
1156         ASN1_TIME_free(thisupd);
1157         ASN1_TIME_free(nextupd);
1158         OCSP_CERTID_free(ca_id);
1159         OCSP_BASICRESP_free(bs);
1160         return ret;
1161
1162         }
1163
1164 static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser)
1165         {
1166         int i;
1167         BIGNUM *bn = NULL;
1168         char *itmp, *row[DB_NUMBER],**rrow;
1169         for (i = 0; i < DB_NUMBER; i++) row[i] = NULL;
1170         bn = ASN1_INTEGER_to_BN(ser,NULL);
1171         OPENSSL_assert(bn); /* FIXME: should report an error at this point and abort */
1172         if (BN_is_zero(bn))
1173                 itmp = BUF_strdup("00");
1174         else
1175                 itmp = BN_bn2hex(bn);
1176         row[DB_serial] = itmp;
1177         BN_free(bn);
1178         rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
1179         OPENSSL_free(itmp);
1180         return rrow;
1181         }
1182
1183 /* Quick and dirty OCSP server: read in and parse input request */
1184
1185 static BIO *init_responder(char *port)
1186         {
1187         BIO *acbio = NULL, *bufbio = NULL;
1188         bufbio = BIO_new(BIO_f_buffer());
1189         if (!bufbio) 
1190                 goto err;
1191 #ifndef OPENSSL_NO_SOCK
1192         acbio = BIO_new_accept(port);
1193 #else
1194         BIO_printf(bio_err, "Error setting up accept BIO - sockets not supported.\n");
1195 #endif
1196         if (!acbio)
1197                 goto err;
1198         BIO_set_accept_bios(acbio, bufbio);
1199         bufbio = NULL;
1200
1201         if (BIO_do_accept(acbio) <= 0)
1202                 {
1203                         BIO_printf(bio_err, "Error setting up accept BIO\n");
1204                         ERR_print_errors(bio_err);
1205                         goto err;
1206                 }
1207
1208         return acbio;
1209
1210         err:
1211         BIO_free_all(acbio);
1212         BIO_free(bufbio);
1213         return NULL;
1214         }
1215
1216 static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port)
1217         {
1218         int have_post = 0, len;
1219         OCSP_REQUEST *req = NULL;
1220         char inbuf[1024];
1221         BIO *cbio = NULL;
1222
1223         if (BIO_do_accept(acbio) <= 0)
1224                 {
1225                         BIO_printf(bio_err, "Error accepting connection\n");
1226                         ERR_print_errors(bio_err);
1227                         return 0;
1228                 }
1229
1230         cbio = BIO_pop(acbio);
1231         *pcbio = cbio;
1232
1233         for(;;)
1234                 {
1235                 len = BIO_gets(cbio, inbuf, sizeof inbuf);
1236                 if (len <= 0)
1237                         return 1;
1238                 /* Look for "POST" signalling start of query */
1239                 if (!have_post)
1240                         {
1241                         if(strncmp(inbuf, "POST", 4))
1242                                 {
1243                                 BIO_printf(bio_err, "Invalid request\n");
1244                                 return 1;
1245                                 }
1246                         have_post = 1;
1247                         }
1248                 /* Look for end of headers */
1249                 if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
1250                         break;
1251                 }
1252
1253         /* Try to read OCSP request */
1254
1255         req = d2i_OCSP_REQUEST_bio(cbio, NULL);
1256
1257         if (!req)
1258                 {
1259                 BIO_printf(bio_err, "Error parsing OCSP request\n");
1260                 ERR_print_errors(bio_err);
1261                 }
1262
1263         *preq = req;
1264
1265         return 1;
1266
1267         }
1268
1269 static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
1270         {
1271         char http_resp[] = 
1272                 "HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n"
1273                 "Content-Length: %d\r\n\r\n";
1274         if (!cbio)
1275                 return 0;
1276         BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL));
1277         i2d_OCSP_RESPONSE_bio(cbio, resp);
1278         (void)BIO_flush(cbio);
1279         return 1;
1280         }
1281
1282 static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
1283                                 STACK_OF(CONF_VALUE) *headers,
1284                                 OCSP_REQUEST *req, int req_timeout)
1285         {
1286         int fd;
1287         int rv;
1288         int i;
1289         OCSP_REQ_CTX *ctx = NULL;
1290         OCSP_RESPONSE *rsp = NULL;
1291         fd_set confds;
1292         struct timeval tv;
1293
1294         if (req_timeout != -1)
1295                 BIO_set_nbio(cbio, 1);
1296
1297         rv = BIO_do_connect(cbio);
1298
1299         if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio)))
1300                 {
1301                 BIO_puts(err, "Error connecting BIO\n");
1302                 return NULL;
1303                 }
1304
1305         if (BIO_get_fd(cbio, &fd) <= 0)
1306                 {
1307                 BIO_puts(err, "Can't get connection fd\n");
1308                 goto err;
1309                 }
1310
1311         if (req_timeout != -1 && rv <= 0)
1312                 {
1313                 FD_ZERO(&confds);
1314                 openssl_fdset(fd, &confds);
1315                 tv.tv_usec = 0;
1316                 tv.tv_sec = req_timeout;
1317                 rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
1318                 if (rv == 0)
1319                         {
1320                         BIO_puts(err, "Timeout on connect\n");
1321                         return NULL;
1322                         }
1323                 }
1324
1325
1326         ctx = OCSP_sendreq_new(cbio, path, NULL, -1);
1327         if (!ctx)
1328                 return NULL;
1329
1330         for (i = 0; i < sk_CONF_VALUE_num(headers); i++)
1331                 {
1332                 CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i);
1333                 if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value))
1334                         goto err;
1335                 }
1336
1337         if (!OCSP_REQ_CTX_set1_req(ctx, req))
1338                 goto err;
1339         
1340         for (;;)
1341                 {
1342                 rv = OCSP_sendreq_nbio(&rsp, ctx);
1343                 if (rv != -1)
1344                         break;
1345                 if (req_timeout == -1)
1346                         continue;
1347                 FD_ZERO(&confds);
1348                 openssl_fdset(fd, &confds);
1349                 tv.tv_usec = 0;
1350                 tv.tv_sec = req_timeout;
1351                 if (BIO_should_read(cbio))
1352                         rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv);
1353                 else if (BIO_should_write(cbio))
1354                         rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
1355                 else
1356                         {
1357                         BIO_puts(err, "Unexpected retry condition\n");
1358                         goto err;
1359                         }
1360                 if (rv == 0)
1361                         {
1362                         BIO_puts(err, "Timeout on request\n");
1363                         break;
1364                         }
1365                 if (rv == -1)
1366                         {
1367                         BIO_puts(err, "Select error\n");
1368                         break;
1369                         }
1370
1371                 }
1372         err:
1373         if (ctx)
1374                 OCSP_REQ_CTX_free(ctx);
1375
1376         return rsp;
1377         }
1378
1379 OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
1380                         char *host, char *path, char *port, int use_ssl,
1381                         STACK_OF(CONF_VALUE) *headers,
1382                         int req_timeout)
1383         {
1384         BIO *cbio = NULL;
1385         SSL_CTX *ctx = NULL;
1386         OCSP_RESPONSE *resp = NULL;
1387         cbio = BIO_new_connect(host);
1388         if (!cbio)
1389                 {
1390                 BIO_printf(err, "Error creating connect BIO\n");
1391                 goto end;
1392                 }
1393         if (port) BIO_set_conn_port(cbio, port);
1394         if (use_ssl == 1)
1395                 {
1396                 BIO *sbio;
1397 #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
1398                 ctx = SSL_CTX_new(SSLv23_client_method());
1399 #elif !defined(OPENSSL_NO_SSL3)
1400                 ctx = SSL_CTX_new(SSLv3_client_method());
1401 #elif !defined(OPENSSL_NO_SSL2)
1402                 ctx = SSL_CTX_new(SSLv2_client_method());
1403 #else
1404                 BIO_printf(err, "SSL is disabled\n");
1405                         goto end;
1406 #endif
1407                 if (ctx == NULL)
1408                         {
1409                         BIO_printf(err, "Error creating SSL context.\n");
1410                         goto end;
1411                         }
1412                 SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
1413                 sbio = BIO_new_ssl(ctx, 1);
1414                 cbio = BIO_push(sbio, cbio);
1415                 }
1416         resp = query_responder(err, cbio, path, headers, req, req_timeout);
1417         if (!resp)
1418                 BIO_printf(bio_err, "Error querying OCSP responsder\n");
1419         end:
1420         if (cbio)
1421                 BIO_free_all(cbio);
1422         if (ctx)
1423                 SSL_CTX_free(ctx);
1424         return resp;
1425         }
1426
1427 #endif