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