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