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