(linenum→info "unix/slp.c:2238")

openssl/0.9.8g/apps/ocsp.c

    1: /* ocsp.c */
    2: /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
    3:  * project 2000.
    4:  */
    5: /* ====================================================================
    6:  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
    7:  *
    8:  * Redistribution and use in source and binary forms, with or without
    9:  * modification, are permitted provided that the following conditions
   10:  * are met:
   11:  *
   12:  * 1. Redistributions of source code must retain the above copyright
   13:  *    notice, this list of conditions and the following disclaimer. 
   14:  *
   15:  * 2. Redistributions in binary form must reproduce the above copyright
   16:  *    notice, this list of conditions and the following disclaimer in
   17:  *    the documentation and/or other materials provided with the
   18:  *    distribution.
   19:  *
   20:  * 3. All advertising materials mentioning features or use of this
   21:  *    software must display the following acknowledgment:
   22:  *    "This product includes software developed by the OpenSSL Project
   23:  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
   24:  *
   25:  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
   26:  *    endorse or promote products derived from this software without
   27:  *    prior written permission. For written permission, please contact
   28:  *    licensing@OpenSSL.org.
   29:  *
   30:  * 5. Products derived from this software may not be called "OpenSSL"
   31:  *    nor may "OpenSSL" appear in their names without prior written
   32:  *    permission of the OpenSSL Project.
   33:  *
   34:  * 6. Redistributions of any form whatsoever must retain the following
   35:  *    acknowledgment:
   36:  *    "This product includes software developed by the OpenSSL Project
   37:  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
   38:  *
   39:  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
   40:  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   41:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   42:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
   43:  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   44:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   45:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   46:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   47:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   48:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   49:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   50:  * OF THE POSSIBILITY OF SUCH DAMAGE.
   51:  * ====================================================================
   52:  *
   53:  * This product includes cryptographic software written by Eric Young
   54:  * (eay@cryptsoft.com).  This product includes software written by Tim
   55:  * Hudson (tjh@cryptsoft.com).
   56:  *
   57:  */
   58: #ifndef OPENSSL_NO_OCSP
   59: 
   60: #include <stdio.h>
   61: #include <string.h>
   62: #include "apps.h"
   63: #include <openssl/pem.h>
   64: #include <openssl/ocsp.h>
   65: #include <openssl/err.h>
   66: #include <openssl/ssl.h>
   67: #include <openssl/bn.h>
   68: 
   69: /* Maximum leeway in validity period: default 5 minutes */
   70: #define MAX_VALIDITY_PERIOD     (5 * 60)
   71: 
   72: static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
   73:                                 STACK_OF(OCSP_CERTID) *ids);
   74: static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
   75:                                 STACK_OF(OCSP_CERTID) *ids);
   76: static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
   77:                                 STACK *names, STACK_OF(OCSP_CERTID) *ids,
   78:                                 long nsec, long maxage);
   79: 
   80: static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
   81:                         X509 *ca, X509 *rcert, EVP_PKEY *rkey,
   82:                         STACK_OF(X509) *rother, unsigned long flags,
   83:                         int nmin, int ndays);
   84: 
   85: static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
   86: static BIO *init_responder(char *port);
   87: static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port);
   88: static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
   89: 
   90: #undef PROG
   91: #define PROG ocsp_main
   92: 
   93: int MAIN(int, char **);
   94: 
   95: int MAIN(int argc, char **argv)
   96:         {
   97:         ENGINE *e = NULL;
   98:         char **args;
   99:         char *host = NULL, *port = NULL, *path = "/";
  100:         char *reqin = NULL, *respin = NULL;
  101:         char *reqout = NULL, *respout = NULL;
  102:         char *signfile = NULL, *keyfile = NULL;
  103:         char *rsignfile = NULL, *rkeyfile = NULL;
  104:         char *outfile = NULL;
  105:         int add_nonce = 1, noverify = 0, use_ssl = -1;
  106:         OCSP_REQUEST *req = NULL;
  107:         OCSP_RESPONSE *resp = NULL;
  108:         OCSP_BASICRESP *bs = NULL;
  109:         X509 *issuer = NULL, *cert = NULL;
  110:         X509 *signer = NULL, *rsigner = NULL;
  111:         EVP_PKEY *key = NULL, *rkey = NULL;
  112:         BIO *acbio = NULL, *cbio = NULL;
  113:         BIO *derbio = NULL;
  114:         BIO *out = NULL;
  115:         int req_text = 0, resp_text = 0;
  116:         long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
  117:         char *CAfile = NULL, *CApath = NULL;
  118:         X509_STORE *store = NULL;
  119:         SSL_CTX *ctx = NULL;
  120:         STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
  121:         char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
  122:         unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
  123:         int ret = 1;
  124:         int accept_count = -1;
  125:         int badarg = 0;
  126:         int i;
  127:         int ignore_err = 0;
  128:         STACK *reqnames = NULL;
  129:         STACK_OF(OCSP_CERTID) *ids = NULL;
  130: 
  131:         X509 *rca_cert = NULL;
  132:         char *ridx_filename = NULL;
  133:         char *rca_filename = NULL;
  134:         CA_DB *rdb = NULL;
  135:         int nmin = 0, ndays = -1;
  136: 
  137:         if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
  138: 
  139:         if (!load_config(bio_err, NULL))
  140:                 goto end;
  141:         SSL_load_error_strings();
  142:         OpenSSL_add_ssl_algorithms();
  143:         args = argv + 1;
  144:         reqnames = sk_new_null();
  145:         ids = sk_OCSP_CERTID_new_null();
  146:         while (!badarg && *args && *args[0] == '-')
  147:                 {
  148:                 if (!strcmp(*args, "-out"))
  149:                         {
  150:                         if (args[1])
  151:                                 {
  152:                                 args++;
  153:                                 outfile = *args;
  154:                                 }
  155:                         else badarg = 1;
  156:                         }
  157:                 else if (!strcmp(*args, "-url"))
  158:                         {
  159:                         if (args[1])
  160:                                 {
  161:                                 args++;
  162:                                 if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl))
  163:                                         {
  164:                                         BIO_printf(bio_err, "Error parsing URL\n");
  165:                                         badarg = 1;
  166:                                         }
  167:                                 }
  168:                         else badarg = 1;
  169:                         }
  170:                 else if (!strcmp(*args, "-host"))
  171:                         {
  172:                         if (args[1])
  173:                                 {
  174:                                 args++;
  175:                                 host = *args;
  176:                                 }
  177:                         else badarg = 1;
  178:                         }
  179:                 else if (!strcmp(*args, "-port"))
  180:                         {
  181:                         if (args[1])
  182:                                 {
  183:                                 args++;
  184:                                 port = *args;
  185:                                 }
  186:                         else badarg = 1;
  187:                         }
  188:                 else if (!strcmp(*args, "-ignore_err"))
  189:                         ignore_err = 1;
  190:                 else if (!strcmp(*args, "-noverify"))
  191:                         noverify = 1;
  192:                 else if (!strcmp(*args, "-nonce"))
  193:                         add_nonce = 2;
  194:                 else if (!strcmp(*args, "-no_nonce"))
  195:                         add_nonce = 0;
  196:                 else if (!strcmp(*args, "-resp_no_certs"))
  197:                         rflags |= OCSP_NOCERTS;
  198:                 else if (!strcmp(*args, "-resp_key_id"))
  199:                         rflags |= OCSP_RESPID_KEY;
  200:                 else if (!strcmp(*args, "-no_certs"))
  201:                         sign_flags |= OCSP_NOCERTS;
  202:                 else if (!strcmp(*args, "-no_signature_verify"))
  203:                         verify_flags |= OCSP_NOSIGS;
  204:                 else if (!strcmp(*args, "-no_cert_verify"))
  205:                         verify_flags |= OCSP_NOVERIFY;
  206:                 else if (!strcmp(*args, "-no_chain"))
  207:                         verify_flags |= OCSP_NOCHAIN;
  208:                 else if (!strcmp(*args, "-no_cert_checks"))
  209:                         verify_flags |= OCSP_NOCHECKS;
  210:                 else if (!strcmp(*args, "-no_explicit"))
  211:                         verify_flags |= OCSP_NOEXPLICIT;
  212:                 else if (!strcmp(*args, "-trust_other"))
  213:                         verify_flags |= OCSP_TRUSTOTHER;
  214:                 else if (!strcmp(*args, "-no_intern"))
  215:                         verify_flags |= OCSP_NOINTERN;
  216:                 else if (!strcmp(*args, "-text"))
  217:                         {
  218:                         req_text = 1;
  219:                         resp_text = 1;
  220:                         }
  221:                 else if (!strcmp(*args, "-req_text"))
  222:                         req_text = 1;
  223:                 else if (!strcmp(*args, "-resp_text"))
  224:                         resp_text = 1;
  225:                 else if (!strcmp(*args, "-reqin"))
  226:                         {
  227:                         if (args[1])
  228:                                 {
  229:                                 args++;
  230:                                 reqin = *args;
  231:                                 }
  232:                         else badarg = 1;
  233:                         }
  234:                 else if (!strcmp(*args, "-respin"))
  235:                         {
  236:                         if (args[1])
  237:                                 {
  238:                                 args++;
  239:                                 respin = *args;
  240:                                 }
  241:                         else badarg = 1;
  242:                         }
  243:                 else if (!strcmp(*args, "-signer"))
  244:                         {
  245:                         if (args[1])
  246:                                 {
  247:                                 args++;
  248:                                 signfile = *args;
  249:                                 }
  250:                         else badarg = 1;
  251:                         }
  252:                 else if (!strcmp (*args, "-VAfile"))
  253:                         {
  254:                         if (args[1])
  255:                                 {
  256:                                 args++;
  257:                                 verify_certfile = *args;
  258:                                 verify_flags |= OCSP_TRUSTOTHER;
  259:                                 }
  260:                         else badarg = 1;
  261:                         }
  262:                 else if (!strcmp(*args, "-sign_other"))
  263:                         {
  264:                         if (args[1])
  265:                                 {
  266:                                 args++;
  267:                                 sign_certfile = *args;
  268:                                 }
  269:                         else badarg = 1;
  270:                         }
  271:                 else if (!strcmp(*args, "-verify_other"))
  272:                         {
  273:                         if (args[1])
  274:                                 {
  275:                                 args++;
  276:                                 verify_certfile = *args;
  277:                                 }
  278:                         else badarg = 1;
  279:                         }
  280:                 else if (!strcmp (*args, "-CAfile"))
  281:                         {
  282:                         if (args[1])
  283:                                 {
  284:                                 args++;
  285:                                 CAfile = *args;
  286:                                 }
  287:                         else badarg = 1;
  288:                         }
  289:                 else if (!strcmp (*args, "-CApath"))
  290:                         {
  291:                         if (args[1])
  292:                                 {
  293:                                 args++;
  294:                                 CApath = *args;
  295:                                 }
  296:                         else badarg = 1;
  297:                         }
  298:                 else if (!strcmp (*args, "-validity_period"))
  299:                         {
  300:                         if (args[1])
  301:                                 {
  302:                                 args++;
  303:                                 nsec = atol(*args);
  304:                                 if (nsec < 0)
  305:                                         {
  306:                                         BIO_printf(bio_err,
  307:                                                 "Illegal validity period %s\n",
  308:                                                 *args);
  309:                                         badarg = 1;
  310:                                         }
  311:                                 }
  312:                         else badarg = 1;
  313:                         }
  314:                 else if (!strcmp (*args, "-status_age"))
  315:                         {
  316:                         if (args[1])
  317:                                 {
  318:                                 args++;
  319:                                 maxage = atol(*args);
  320:                                 if (maxage < 0)
  321:                                         {
  322:                                         BIO_printf(bio_err,
  323:                                                 "Illegal validity age %s\n",
  324:                                                 *args);
  325:                                         badarg = 1;
  326:                                         }
  327:                                 }
  328:                         else badarg = 1;
  329:                         }
  330:                  else if (!strcmp(*args, "-signkey"))
  331:                         {
  332:                         if (args[1])
  333:                                 {
  334:                                 args++;
  335:                                 keyfile = *args;
  336:                                 }
  337:                         else badarg = 1;
  338:                         }
  339:                 else if (!strcmp(*args, "-reqout"))
  340:                         {
  341:                         if (args[1])
  342:                                 {
  343:                                 args++;
  344:                                 reqout = *args;
  345:                                 }
  346:                         else badarg = 1;
  347:                         }
  348:                 else if (!strcmp(*args, "-respout"))
  349:                         {
  350:                         if (args[1])
  351:                                 {
  352:                                 args++;
  353:                                 respout = *args;
  354:                                 }
  355:                         else badarg = 1;
  356:                         }
  357:                  else if (!strcmp(*args, "-path"))
  358:                         {
  359:                         if (args[1])
  360:                                 {
  361:                                 args++;
  362:                                 path = *args;
  363:                                 }
  364:                         else badarg = 1;
  365:                         }
  366:                 else if (!strcmp(*args, "-issuer"))
  367:                         {
  368:                         if (args[1])
  369:                                 {
  370:                                 args++;
  371:                                 X509_free(issuer);
  372:                                 issuer = load_cert(bio_err, *args, FORMAT_PEM,
  373:                                         NULL, e, "issuer certificate");
  374:                                 if(!issuer) goto end;
  375:                                 }
  376:                         else badarg = 1;
  377:                         }
  378:                 else if (!strcmp (*args, "-cert"))
  379:                         {
  380:                         if (args[1])
  381:                                 {
  382:                                 args++;
  383:                                 X509_free(cert);
  384:                                 cert = load_cert(bio_err, *args, FORMAT_PEM,
  385:                                         NULL, e, "certificate");
  386:                                 if(!cert) goto end;
  387:                                 if(!add_ocsp_cert(&req, cert, issuer, ids))
  388:                                         goto end;
  389:                                 if(!sk_push(reqnames, *args))
  390:                                         goto end;
  391:                                 }
  392:                         else badarg = 1;
  393:                         }
  394:                 else if (!strcmp(*args, "-serial"))
  395:                         {
  396:                         if (args[1])
  397:                                 {
  398:                                 args++;
  399:                                 if(!add_ocsp_serial(&req, *args, issuer, ids))
  400:                                         goto end;
  401:                                 if(!sk_push(reqnames, *args))
  402:                                         goto end;
  403:                                 }
  404:                         else badarg = 1;
  405:                         }
  406:                 else if (!strcmp(*args, "-index"))
  407:                         {
  408:                         if (args[1])
  409:                                 {
  410:                                 args++;
  411:                                 ridx_filename = *args;
  412:                                 }
  413:                         else badarg = 1;
  414:                         }
  415:                 else if (!strcmp(*args, "-CA"))
  416:                         {
  417:                         if (args[1])
  418:                                 {
  419:                                 args++;
  420:                                 rca_filename = *args;
  421:                                 }
  422:                         else badarg = 1;
  423:                         }
  424:                 else if (!strcmp (*args, "-nmin"))
  425:                         {
  426:                         if (args[1])
  427:                                 {
  428:                                 args++;
  429:                                 nmin = atol(*args);
  430:                                 if (nmin < 0)
  431:                                         {
  432:                                         BIO_printf(bio_err,
  433:                                                 "Illegal update period %s\n",
  434:                                                 *args);
  435:                                         badarg = 1;
  436:                                         }
  437:                                 }
  438:                                 if (ndays == -1)
  439:                                         ndays = 0;
  440:                         else badarg = 1;
  441:                         }
  442:                 else if (!strcmp (*args, "-nrequest"))
  443:                         {
  444:                         if (args[1])
  445:                                 {
  446:                                 args++;
  447:                                 accept_count = atol(*args);
  448:                                 if (accept_count < 0)
  449:                                         {
  450:                                         BIO_printf(bio_err,
  451:                                                 "Illegal accept count %s\n",
  452:                                                 *args);
  453:                                         badarg = 1;
  454:                                         }
  455:                                 }
  456:                         else badarg = 1;
  457:                         }
  458:                 else if (!strcmp (*args, "-ndays"))
  459:                         {
  460:                         if (args[1])
  461:                                 {
  462:                                 args++;
  463:                                 ndays = atol(*args);
  464:                                 if (ndays < 0)
  465:                                         {
  466:                                         BIO_printf(bio_err,
  467:                                                 "Illegal update period %s\n",
  468:                                                 *args);
  469:                                         badarg = 1;
  470:                                         }
  471:                                 }
  472:                         else badarg = 1;
  473:                         }
  474:                 else if (!strcmp(*args, "-rsigner"))
  475:                         {
  476:                         if (args[1])
  477:                                 {
  478:                                 args++;
  479:                                 rsignfile = *args;
  480:                                 }
  481:                         else badarg = 1;
  482:                         }
  483:                 else if (!strcmp(*args, "-rkey"))
  484:                         {
  485:                         if (args[1])
  486:                                 {
  487:                                 args++;
  488:                                 rkeyfile = *args;
  489:                                 }
  490:                         else badarg = 1;
  491:                         }
  492:                 else if (!strcmp(*args, "-rother"))
  493:                         {
  494:                         if (args[1])
  495:                                 {
  496:                                 args++;
  497:                                 rcertfile = *args;
  498:                                 }
  499:                         else badarg = 1;
  500:                         }
  501:                 else badarg = 1;
  502:                 args++;
  503:                 }
  504: 
  505:         /* Have we anything to do? */
  506:         if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1;
  507: 
  508:         if (badarg)
  509:                 {
  510:                 BIO_printf (bio_err, "OCSP utility\n");
  511:                 BIO_printf (bio_err, "Usage ocsp [options]\n");
  512:                 BIO_printf (bio_err, "where options are\n");
  513:                 BIO_printf (bio_err, "-out file          output filename\n");
  514:                 BIO_printf (bio_err, "-issuer file       issuer certificate\n");
  515:                 BIO_printf (bio_err, "-cert file         certificate to check\n");
  516:                 BIO_printf (bio_err, "-serial n          serial number to check\n");
  517:                 BIO_printf (bio_err, "-signer file       certificate to sign OCSP request with\n");
  518:                 BIO_printf (bio_err, "-signkey file      private key to sign OCSP request with\n");
  519:                 BIO_printf (bio_err, "-sign_other file   additional certificates to include in signed request\n");
  520:                 BIO_printf (bio_err, "-no_certs          don't include any certificates in signed request\n");
  521:                 BIO_printf (bio_err, "-req_text          print text form of request\n");
  522:                 BIO_printf (bio_err, "-resp_text         print text form of response\n");
  523:                 BIO_printf (bio_err, "-text              print text form of request and response\n");
  524:                 BIO_printf (bio_err, "-reqout file       write DER encoded OCSP request to \"file\"\n");
  525:                 BIO_printf (bio_err, "-respout file      write DER encoded OCSP reponse to \"file\"\n");
  526:                 BIO_printf (bio_err, "-reqin file        read DER encoded OCSP request from \"file\"\n");
  527:                 BIO_printf (bio_err, "-respin file       read DER encoded OCSP reponse from \"file\"\n");
  528:                 BIO_printf (bio_err, "-nonce             add OCSP nonce to request\n");
  529:                 BIO_printf (bio_err, "-no_nonce          don't add OCSP nonce to request\n");
  530:                 BIO_printf (bio_err, "-url URL           OCSP responder URL\n");
  531:                 BIO_printf (bio_err, "-host host:n       send OCSP request to host on port n\n");
  532:                 BIO_printf (bio_err, "-path              path to use in OCSP request\n");
  533:                 BIO_printf (bio_err, "-CApath dir        trusted certificates directory\n");
  534:                 BIO_printf (bio_err, "-CAfile file       trusted certificates file\n");
  535:                 BIO_printf (bio_err, "-VAfile file       validator certificates file\n");
  536:                 BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
  537:                 BIO_printf (bio_err, "-status_age n      maximum status age in seconds\n");
  538:                 BIO_printf (bio_err, "-noverify          don't verify response at all\n");
  539:                 BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n");
  540:                 BIO_printf (bio_err, "-trust_other       don't verify additional certificates\n");
  541:                 BIO_printf (bio_err, "-no_intern         don't search certificates contained in response for signer\n");
  542:                 BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n");
  543:                 BIO_printf (bio_err, "-no_cert_verify    don't check signing certificate\n");
  544:                 BIO_printf (bio_err, "-no_chain          don't chain verify response\n");
  545:                 BIO_printf (bio_err, "-no_cert_checks    don't do additional checks on signing certificate\n");
  546:                 BIO_printf (bio_err