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