ocsp.c revision 296341
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                   "-no_alt_chains       only ever use the first certificate chain found\n");
523        BIO_printf(bio_err,
524                   "-VAfile file         validator certificates file\n");
525        BIO_printf(bio_err,
526                   "-validity_period n   maximum validity discrepancy in seconds\n");
527        BIO_printf(bio_err,
528                   "-status_age n        maximum status age in seconds\n");
529        BIO_printf(bio_err,
530                   "-noverify            don't verify response at all\n");
531        BIO_printf(bio_err,
532                   "-verify_other file   additional certificates to search for signer\n");
533        BIO_printf(bio_err,
534                   "-trust_other         don't verify additional certificates\n");
535        BIO_printf(bio_err,
536                   "-no_intern           don't search certificates contained in response for signer\n");
537        BIO_printf(bio_err,
538                   "-no_signature_verify don't check signature on response\n");
539        BIO_printf(bio_err,
540                   "-no_cert_verify      don't check signing certificate\n");
541        BIO_printf(bio_err,
542                   "-no_chain            don't chain verify response\n");
543        BIO_printf(bio_err,
544                   "-no_cert_checks      don't do additional checks on signing certificate\n");
545        BIO_printf(bio_err,
546                   "-port num            port to run responder on\n");
547        BIO_printf(bio_err,
548                   "-index file          certificate status index file\n");
549        BIO_printf(bio_err, "-CA file             CA certificate\n");
550        BIO_printf(bio_err,
551                   "-rsigner file        responder certificate to sign responses with\n");
552        BIO_printf(bio_err,
553                   "-rkey file           responder key to sign responses with\n");
554        BIO_printf(bio_err,
555                   "-rother file         other certificates to include in response\n");
556        BIO_printf(bio_err,
557                   "-resp_no_certs       don't include any certificates in response\n");
558        BIO_printf(bio_err,
559                   "-nmin n              number of minutes before next update\n");
560        BIO_printf(bio_err,
561                   "-ndays n             number of days before next update\n");
562        BIO_printf(bio_err,
563                   "-resp_key_id         identify reponse by signing certificate key ID\n");
564        BIO_printf(bio_err,
565                   "-nrequest n          number of requests to accept (default unlimited)\n");
566        BIO_printf(bio_err,
567                   "-<dgst alg>          use specified digest in the request\n");
568        BIO_printf(bio_err,
569                   "-timeout n           timeout connection to OCSP responder after n seconds\n");
570        goto end;
571    }
572
573    if (outfile)
574        out = BIO_new_file(outfile, "w");
575    else
576        out = BIO_new_fp(stdout, BIO_NOCLOSE);
577
578    if (!out) {
579        BIO_printf(bio_err, "Error opening output file\n");
580        goto end;
581    }
582
583    if (!req && (add_nonce != 2))
584        add_nonce = 0;
585
586    if (!req && reqin) {
587        derbio = BIO_new_file(reqin, "rb");
588        if (!derbio) {
589            BIO_printf(bio_err, "Error Opening OCSP request file\n");
590            goto end;
591        }
592        req = d2i_OCSP_REQUEST_bio(derbio, NULL);
593        BIO_free(derbio);
594        if (!req) {
595            BIO_printf(bio_err, "Error reading OCSP request\n");
596            goto end;
597        }
598    }
599
600    if (!req && port) {
601        acbio = init_responder(port);
602        if (!acbio)
603            goto end;
604    }
605
606    if (rsignfile && !rdb) {
607        if (!rkeyfile)
608            rkeyfile = rsignfile;
609        rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,
610                            NULL, e, "responder certificate");
611        if (!rsigner) {
612            BIO_printf(bio_err, "Error loading responder certificate\n");
613            goto end;
614        }
615        rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,
616                             NULL, e, "CA certificate");
617        if (rcertfile) {
618            rother = load_certs(bio_err, rcertfile, FORMAT_PEM,
619                                NULL, e, "responder other certificates");
620            if (!rother)
621                goto end;
622        }
623        rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL,
624                        "responder private key");
625        if (!rkey)
626            goto end;
627    }
628    if (acbio)
629        BIO_printf(bio_err, "Waiting for OCSP client connections...\n");
630
631 redo_accept:
632
633    if (acbio) {
634        if (!do_responder(&req, &cbio, acbio, port))
635            goto end;
636        if (!req) {
637            resp =
638                OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST,
639                                     NULL);
640            send_ocsp_response(cbio, resp);
641            goto done_resp;
642        }
643    }
644
645    if (!req && (signfile || reqout || host || add_nonce || ridx_filename)) {
646        BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
647        goto end;
648    }
649
650    if (req && add_nonce)
651        OCSP_request_add1_nonce(req, NULL, -1);
652
653    if (signfile) {
654        if (!keyfile)
655            keyfile = signfile;
656        signer = load_cert(bio_err, signfile, FORMAT_PEM,
657                           NULL, e, "signer certificate");
658        if (!signer) {
659            BIO_printf(bio_err, "Error loading signer certificate\n");
660            goto end;
661        }
662        if (sign_certfile) {
663            sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,
664                                    NULL, e, "signer certificates");
665            if (!sign_other)
666                goto end;
667        }
668        key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL,
669                       "signer private key");
670        if (!key)
671            goto end;
672
673        if (!OCSP_request_sign
674            (req, signer, key, NULL, sign_other, sign_flags)) {
675            BIO_printf(bio_err, "Error signing OCSP request\n");
676            goto end;
677        }
678    }
679
680    if (req_text && req)
681        OCSP_REQUEST_print(out, req, 0);
682
683    if (reqout) {
684        derbio = BIO_new_file(reqout, "wb");
685        if (!derbio) {
686            BIO_printf(bio_err, "Error opening file %s\n", reqout);
687            goto end;
688        }
689        i2d_OCSP_REQUEST_bio(derbio, req);
690        BIO_free(derbio);
691    }
692
693    if (ridx_filename && (!rkey || !rsigner || !rca_cert)) {
694        BIO_printf(bio_err,
695                   "Need a responder certificate, key and CA for this operation!\n");
696        goto end;
697    }
698
699    if (ridx_filename && !rdb) {
700        rdb = load_index(ridx_filename, NULL);
701        if (!rdb)
702            goto end;
703        if (!index_index(rdb))
704            goto end;
705    }
706
707    if (rdb) {
708        i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey,
709                               rother, rflags, nmin, ndays);
710        if (cbio)
711            send_ocsp_response(cbio, resp);
712    } else if (host) {
713# ifndef OPENSSL_NO_SOCK
714        resp = process_responder(bio_err, req, host, path,
715                                 port, use_ssl, headers, req_timeout);
716        if (!resp)
717            goto end;
718# else
719        BIO_printf(bio_err,
720                   "Error creating connect BIO - sockets not supported.\n");
721        goto end;
722# endif
723    } else if (respin) {
724        derbio = BIO_new_file(respin, "rb");
725        if (!derbio) {
726            BIO_printf(bio_err, "Error Opening OCSP response file\n");
727            goto end;
728        }
729        resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
730        BIO_free(derbio);
731        if (!resp) {
732            BIO_printf(bio_err, "Error reading OCSP response\n");
733            goto end;
734        }
735
736    } else {
737        ret = 0;
738        goto end;
739    }
740
741 done_resp:
742
743    if (respout) {
744        derbio = BIO_new_file(respout, "wb");
745        if (!derbio) {
746            BIO_printf(bio_err, "Error opening file %s\n", respout);
747            goto end;
748        }
749        i2d_OCSP_RESPONSE_bio(derbio, resp);
750        BIO_free(derbio);
751    }
752
753    i = OCSP_response_status(resp);
754
755    if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
756        BIO_printf(out, "Responder Error: %s (%d)\n",
757                   OCSP_response_status_str(i), i);
758        if (ignore_err)
759            goto redo_accept;
760        ret = 0;
761        goto end;
762    }
763
764    if (resp_text)
765        OCSP_RESPONSE_print(out, resp, 0);
766
767    /* If running as responder don't verify our own response */
768    if (cbio) {
769        if (accept_count > 0)
770            accept_count--;
771        /* Redo if more connections needed */
772        if (accept_count) {
773            BIO_free_all(cbio);
774            cbio = NULL;
775            OCSP_REQUEST_free(req);
776            req = NULL;
777            OCSP_RESPONSE_free(resp);
778            resp = NULL;
779            goto redo_accept;
780        }
781        goto end;
782    }
783
784    if (!store)
785        store = setup_verify(bio_err, CAfile, CApath);
786    if (!store)
787        goto end;
788    if (verify_certfile) {
789        verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,
790                                  NULL, e, "validator certificate");
791        if (!verify_other)
792            goto end;
793    }
794
795    bs = OCSP_response_get1_basic(resp);
796
797    if (!bs) {
798        BIO_printf(bio_err, "Error parsing response\n");
799        goto end;
800    }
801
802    if (!noverify) {
803        if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) {
804            if (i == -1)
805                BIO_printf(bio_err, "WARNING: no nonce in response\n");
806            else {
807                BIO_printf(bio_err, "Nonce Verify error\n");
808                goto end;
809            }
810        }
811
812        i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
813        if (i < 0)
814            i = OCSP_basic_verify(bs, NULL, store, 0);
815
816        if (i <= 0) {
817            BIO_printf(bio_err, "Response Verify Failure\n");
818            ERR_print_errors(bio_err);
819        } else
820            BIO_printf(bio_err, "Response verify OK\n");
821
822    }
823
824    if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage))
825        goto end;
826
827    ret = 0;
828
829 end:
830    ERR_print_errors(bio_err);
831    X509_free(signer);
832    X509_STORE_free(store);
833    EVP_PKEY_free(key);
834    EVP_PKEY_free(rkey);
835    X509_free(issuer);
836    X509_free(cert);
837    X509_free(rsigner);
838    X509_free(rca_cert);
839    free_index(rdb);
840    BIO_free_all(cbio);
841    BIO_free_all(acbio);
842    BIO_free(out);
843    OCSP_REQUEST_free(req);
844    OCSP_RESPONSE_free(resp);
845    OCSP_BASICRESP_free(bs);
846    sk_OPENSSL_STRING_free(reqnames);
847    sk_OCSP_CERTID_free(ids);
848    sk_X509_pop_free(sign_other, X509_free);
849    sk_X509_pop_free(verify_other, X509_free);
850    sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
851
852    if (thost)
853        OPENSSL_free(thost);
854    if (tport)
855        OPENSSL_free(tport);
856    if (tpath)
857        OPENSSL_free(tpath);
858
859    OPENSSL_EXIT(ret);
860}
861
862static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert,
863                         const EVP_MD *cert_id_md, X509 *issuer,
864                         STACK_OF(OCSP_CERTID) *ids)
865{
866    OCSP_CERTID *id;
867    if (!issuer) {
868        BIO_printf(bio_err, "No issuer certificate specified\n");
869        return 0;
870    }
871    if (!*req)
872        *req = OCSP_REQUEST_new();
873    if (!*req)
874        goto err;
875    id = OCSP_cert_to_id(cert_id_md, cert, issuer);
876    if (!id || !sk_OCSP_CERTID_push(ids, id))
877        goto err;
878    if (!OCSP_request_add0_id(*req, id))
879        goto err;
880    return 1;
881
882 err:
883    BIO_printf(bio_err, "Error Creating OCSP request\n");
884    return 0;
885}
886
887static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,
888                           const EVP_MD *cert_id_md, X509 *issuer,
889                           STACK_OF(OCSP_CERTID) *ids)
890{
891    OCSP_CERTID *id;
892    X509_NAME *iname;
893    ASN1_BIT_STRING *ikey;
894    ASN1_INTEGER *sno;
895    if (!issuer) {
896        BIO_printf(bio_err, "No issuer certificate specified\n");
897        return 0;
898    }
899    if (!*req)
900        *req = OCSP_REQUEST_new();
901    if (!*req)
902        goto err;
903    iname = X509_get_subject_name(issuer);
904    ikey = X509_get0_pubkey_bitstr(issuer);
905    sno = s2i_ASN1_INTEGER(NULL, serial);
906    if (!sno) {
907        BIO_printf(bio_err, "Error converting serial number %s\n", serial);
908        return 0;
909    }
910    id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno);
911    ASN1_INTEGER_free(sno);
912    if (!id || !sk_OCSP_CERTID_push(ids, id))
913        goto err;
914    if (!OCSP_request_add0_id(*req, id))
915        goto err;
916    return 1;
917
918 err:
919    BIO_printf(bio_err, "Error Creating OCSP request\n");
920    return 0;
921}
922
923static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
924                              STACK_OF(OPENSSL_STRING) *names,
925                              STACK_OF(OCSP_CERTID) *ids, long nsec,
926                              long maxage)
927{
928    OCSP_CERTID *id;
929    char *name;
930    int i;
931
932    int status, reason;
933
934    ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
935
936    if (!bs || !req || !sk_OPENSSL_STRING_num(names)
937        || !sk_OCSP_CERTID_num(ids))
938        return 1;
939
940    for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) {
941        id = sk_OCSP_CERTID_value(ids, i);
942        name = sk_OPENSSL_STRING_value(names, i);
943        BIO_printf(out, "%s: ", name);
944
945        if (!OCSP_resp_find_status(bs, id, &status, &reason,
946                                   &rev, &thisupd, &nextupd)) {
947            BIO_puts(out, "ERROR: No Status found.\n");
948            continue;
949        }
950
951        /*
952         * Check validity: if invalid write to output BIO so we know which
953         * response this refers to.
954         */
955        if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage)) {
956            BIO_puts(out, "WARNING: Status times invalid.\n");
957            ERR_print_errors(out);
958        }
959        BIO_printf(out, "%s\n", OCSP_cert_status_str(status));
960
961        BIO_puts(out, "\tThis Update: ");
962        ASN1_GENERALIZEDTIME_print(out, thisupd);
963        BIO_puts(out, "\n");
964
965        if (nextupd) {
966            BIO_puts(out, "\tNext Update: ");
967            ASN1_GENERALIZEDTIME_print(out, nextupd);
968            BIO_puts(out, "\n");
969        }
970
971        if (status != V_OCSP_CERTSTATUS_REVOKED)
972            continue;
973
974        if (reason != -1)
975            BIO_printf(out, "\tReason: %s\n", OCSP_crl_reason_str(reason));
976
977        BIO_puts(out, "\tRevocation Time: ");
978        ASN1_GENERALIZEDTIME_print(out, rev);
979        BIO_puts(out, "\n");
980    }
981
982    return 1;
983}
984
985static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req,
986                              CA_DB *db, X509 *ca, X509 *rcert,
987                              EVP_PKEY *rkey, STACK_OF(X509) *rother,
988                              unsigned long flags, int nmin, int ndays)
989{
990    ASN1_TIME *thisupd = NULL, *nextupd = NULL;
991    OCSP_CERTID *cid, *ca_id = NULL;
992    OCSP_BASICRESP *bs = NULL;
993    int i, id_count, ret = 1;
994
995    id_count = OCSP_request_onereq_count(req);
996
997    if (id_count <= 0) {
998        *resp =
999            OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
1000        goto end;
1001    }
1002
1003    bs = OCSP_BASICRESP_new();
1004    thisupd = X509_gmtime_adj(NULL, 0);
1005    if (ndays != -1)
1006        nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24);
1007
1008    /* Examine each certificate id in the request */
1009    for (i = 0; i < id_count; i++) {
1010        OCSP_ONEREQ *one;
1011        ASN1_INTEGER *serial;
1012        char **inf;
1013        ASN1_OBJECT *cert_id_md_oid;
1014        const EVP_MD *cert_id_md;
1015        one = OCSP_request_onereq_get0(req, i);
1016        cid = OCSP_onereq_get0_id(one);
1017
1018        OCSP_id_get0_info(NULL, &cert_id_md_oid, NULL, NULL, cid);
1019
1020        cert_id_md = EVP_get_digestbyobj(cert_id_md_oid);
1021        if (!cert_id_md) {
1022            *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR,
1023                                         NULL);
1024            goto end;
1025        }
1026        if (ca_id)
1027            OCSP_CERTID_free(ca_id);
1028        ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca);
1029
1030        /* Is this request about our CA? */
1031        if (OCSP_id_issuer_cmp(ca_id, cid)) {
1032            OCSP_basic_add1_status(bs, cid,
1033                                   V_OCSP_CERTSTATUS_UNKNOWN,
1034                                   0, NULL, thisupd, nextupd);
1035            continue;
1036        }
1037        OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
1038        inf = lookup_serial(db, serial);
1039        if (!inf)
1040            OCSP_basic_add1_status(bs, cid,
1041                                   V_OCSP_CERTSTATUS_UNKNOWN,
1042                                   0, NULL, thisupd, nextupd);
1043        else if (inf[DB_type][0] == DB_TYPE_VAL)
1044            OCSP_basic_add1_status(bs, cid,
1045                                   V_OCSP_CERTSTATUS_GOOD,
1046                                   0, NULL, thisupd, nextupd);
1047        else if (inf[DB_type][0] == DB_TYPE_REV) {
1048            ASN1_OBJECT *inst = NULL;
1049            ASN1_TIME *revtm = NULL;
1050            ASN1_GENERALIZEDTIME *invtm = NULL;
1051            OCSP_SINGLERESP *single;
1052            int reason = -1;
1053            unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]);
1054            single = OCSP_basic_add1_status(bs, cid,
1055                                            V_OCSP_CERTSTATUS_REVOKED,
1056                                            reason, revtm, thisupd, nextupd);
1057            if (invtm)
1058                OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date,
1059                                             invtm, 0, 0);
1060            else if (inst)
1061                OCSP_SINGLERESP_add1_ext_i2d(single,
1062                                             NID_hold_instruction_code, inst,
1063                                             0, 0);
1064            ASN1_OBJECT_free(inst);
1065            ASN1_TIME_free(revtm);
1066            ASN1_GENERALIZEDTIME_free(invtm);
1067        }
1068    }
1069
1070    OCSP_copy_nonce(bs, req);
1071
1072    OCSP_basic_sign(bs, rcert, rkey, NULL, rother, flags);
1073
1074    *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
1075
1076 end:
1077    ASN1_TIME_free(thisupd);
1078    ASN1_TIME_free(nextupd);
1079    OCSP_CERTID_free(ca_id);
1080    OCSP_BASICRESP_free(bs);
1081    return ret;
1082
1083}
1084
1085static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser)
1086{
1087    int i;
1088    BIGNUM *bn = NULL;
1089    char *itmp, *row[DB_NUMBER], **rrow;
1090    for (i = 0; i < DB_NUMBER; i++)
1091        row[i] = NULL;
1092    bn = ASN1_INTEGER_to_BN(ser, NULL);
1093    OPENSSL_assert(bn);         /* FIXME: should report an error at this
1094                                 * point and abort */
1095    if (BN_is_zero(bn))
1096        itmp = BUF_strdup("00");
1097    else
1098        itmp = BN_bn2hex(bn);
1099    row[DB_serial] = itmp;
1100    BN_free(bn);
1101    rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
1102    OPENSSL_free(itmp);
1103    return rrow;
1104}
1105
1106/* Quick and dirty OCSP server: read in and parse input request */
1107
1108static BIO *init_responder(char *port)
1109{
1110    BIO *acbio = NULL, *bufbio = NULL;
1111    bufbio = BIO_new(BIO_f_buffer());
1112    if (!bufbio)
1113        goto err;
1114# ifndef OPENSSL_NO_SOCK
1115    acbio = BIO_new_accept(port);
1116# else
1117    BIO_printf(bio_err,
1118               "Error setting up accept BIO - sockets not supported.\n");
1119# endif
1120    if (!acbio)
1121        goto err;
1122    BIO_set_accept_bios(acbio, bufbio);
1123    bufbio = NULL;
1124
1125    if (BIO_do_accept(acbio) <= 0) {
1126        BIO_printf(bio_err, "Error setting up accept BIO\n");
1127        ERR_print_errors(bio_err);
1128        goto err;
1129    }
1130
1131    return acbio;
1132
1133 err:
1134    BIO_free_all(acbio);
1135    BIO_free(bufbio);
1136    return NULL;
1137}
1138
1139static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio,
1140                        char *port)
1141{
1142    int have_post = 0, len;
1143    OCSP_REQUEST *req = NULL;
1144    char inbuf[1024];
1145    BIO *cbio = NULL;
1146
1147    if (BIO_do_accept(acbio) <= 0) {
1148        BIO_printf(bio_err, "Error accepting connection\n");
1149        ERR_print_errors(bio_err);
1150        return 0;
1151    }
1152
1153    cbio = BIO_pop(acbio);
1154    *pcbio = cbio;
1155
1156    for (;;) {
1157        len = BIO_gets(cbio, inbuf, sizeof inbuf);
1158        if (len <= 0)
1159            return 1;
1160        /* Look for "POST" signalling start of query */
1161        if (!have_post) {
1162            if (strncmp(inbuf, "POST", 4)) {
1163                BIO_printf(bio_err, "Invalid request\n");
1164                return 1;
1165            }
1166            have_post = 1;
1167        }
1168        /* Look for end of headers */
1169        if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
1170            break;
1171    }
1172
1173    /* Try to read OCSP request */
1174
1175    req = d2i_OCSP_REQUEST_bio(cbio, NULL);
1176
1177    if (!req) {
1178        BIO_printf(bio_err, "Error parsing OCSP request\n");
1179        ERR_print_errors(bio_err);
1180    }
1181
1182    *preq = req;
1183
1184    return 1;
1185
1186}
1187
1188static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
1189{
1190    char http_resp[] =
1191        "HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n"
1192        "Content-Length: %d\r\n\r\n";
1193    if (!cbio)
1194        return 0;
1195    BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL));
1196    i2d_OCSP_RESPONSE_bio(cbio, resp);
1197    (void)BIO_flush(cbio);
1198    return 1;
1199}
1200
1201static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
1202                                      STACK_OF(CONF_VALUE) *headers,
1203                                      OCSP_REQUEST *req, int req_timeout)
1204{
1205    int fd;
1206    int rv;
1207    int i;
1208    OCSP_REQ_CTX *ctx = NULL;
1209    OCSP_RESPONSE *rsp = NULL;
1210    fd_set confds;
1211    struct timeval tv;
1212
1213    if (req_timeout != -1)
1214        BIO_set_nbio(cbio, 1);
1215
1216    rv = BIO_do_connect(cbio);
1217
1218    if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio))) {
1219        BIO_puts(err, "Error connecting BIO\n");
1220        return NULL;
1221    }
1222
1223    if (BIO_get_fd(cbio, &fd) <= 0) {
1224        BIO_puts(err, "Can't get connection fd\n");
1225        goto err;
1226    }
1227
1228    if (req_timeout != -1 && rv <= 0) {
1229        FD_ZERO(&confds);
1230        openssl_fdset(fd, &confds);
1231        tv.tv_usec = 0;
1232        tv.tv_sec = req_timeout;
1233        rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
1234        if (rv == 0) {
1235            BIO_puts(err, "Timeout on connect\n");
1236            return NULL;
1237        }
1238    }
1239
1240    ctx = OCSP_sendreq_new(cbio, path, NULL, -1);
1241    if (!ctx)
1242        return NULL;
1243
1244    for (i = 0; i < sk_CONF_VALUE_num(headers); i++) {
1245        CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i);
1246        if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value))
1247            goto err;
1248    }
1249
1250    if (!OCSP_REQ_CTX_set1_req(ctx, req))
1251        goto err;
1252
1253    for (;;) {
1254        rv = OCSP_sendreq_nbio(&rsp, ctx);
1255        if (rv != -1)
1256            break;
1257        if (req_timeout == -1)
1258            continue;
1259        FD_ZERO(&confds);
1260        openssl_fdset(fd, &confds);
1261        tv.tv_usec = 0;
1262        tv.tv_sec = req_timeout;
1263        if (BIO_should_read(cbio))
1264            rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv);
1265        else if (BIO_should_write(cbio))
1266            rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
1267        else {
1268            BIO_puts(err, "Unexpected retry condition\n");
1269            goto err;
1270        }
1271        if (rv == 0) {
1272            BIO_puts(err, "Timeout on request\n");
1273            break;
1274        }
1275        if (rv == -1) {
1276            BIO_puts(err, "Select error\n");
1277            break;
1278        }
1279
1280    }
1281 err:
1282    if (ctx)
1283        OCSP_REQ_CTX_free(ctx);
1284
1285    return rsp;
1286}
1287
1288OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
1289                                 char *host, char *path, char *port,
1290                                 int use_ssl, STACK_OF(CONF_VALUE) *headers,
1291                                 int req_timeout)
1292{
1293    BIO *cbio = NULL;
1294    SSL_CTX *ctx = NULL;
1295    OCSP_RESPONSE *resp = NULL;
1296    cbio = BIO_new_connect(host);
1297    if (!cbio) {
1298        BIO_printf(err, "Error creating connect BIO\n");
1299        goto end;
1300    }
1301    if (port)
1302        BIO_set_conn_port(cbio, port);
1303    if (use_ssl == 1) {
1304        BIO *sbio;
1305        ctx = SSL_CTX_new(SSLv23_client_method());
1306        if (ctx == NULL) {
1307            BIO_printf(err, "Error creating SSL context.\n");
1308            goto end;
1309        }
1310        SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
1311        sbio = BIO_new_ssl(ctx, 1);
1312        cbio = BIO_push(sbio, cbio);
1313    }
1314    resp = query_responder(err, cbio, path, headers, req, req_timeout);
1315    if (!resp)
1316        BIO_printf(bio_err, "Error querying OCSP responder\n");
1317 end:
1318    if (cbio)
1319        BIO_free_all(cbio);
1320    if (ctx)
1321        SSL_CTX_free(ctx);
1322    return resp;
1323}
1324
1325#endif
1326