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