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