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