10Sstevel@tonic-gate /* ocsp.c */
20Sstevel@tonic-gate /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
30Sstevel@tonic-gate * project 2000.
40Sstevel@tonic-gate */
50Sstevel@tonic-gate /* ====================================================================
60Sstevel@tonic-gate * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
90Sstevel@tonic-gate * modification, are permitted provided that the following conditions
100Sstevel@tonic-gate * are met:
110Sstevel@tonic-gate *
120Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
130Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
140Sstevel@tonic-gate *
150Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
160Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in
170Sstevel@tonic-gate * the documentation and/or other materials provided with the
180Sstevel@tonic-gate * distribution.
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this
210Sstevel@tonic-gate * software must display the following acknowledgment:
220Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
230Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
240Sstevel@tonic-gate *
250Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
260Sstevel@tonic-gate * endorse or promote products derived from this software without
270Sstevel@tonic-gate * prior written permission. For written permission, please contact
280Sstevel@tonic-gate * licensing@OpenSSL.org.
290Sstevel@tonic-gate *
300Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL"
310Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written
320Sstevel@tonic-gate * permission of the OpenSSL Project.
330Sstevel@tonic-gate *
340Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following
350Sstevel@tonic-gate * acknowledgment:
360Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
370Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
380Sstevel@tonic-gate *
390Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
400Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
410Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
420Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
430Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
440Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
450Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
460Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
470Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
480Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
490Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
500Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE.
510Sstevel@tonic-gate * ====================================================================
520Sstevel@tonic-gate *
530Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young
540Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim
550Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com).
560Sstevel@tonic-gate *
570Sstevel@tonic-gate */
580Sstevel@tonic-gate #ifndef OPENSSL_NO_OCSP
590Sstevel@tonic-gate
600Sstevel@tonic-gate #include <stdio.h>
610Sstevel@tonic-gate #include <string.h>
620Sstevel@tonic-gate #include "apps.h"
630Sstevel@tonic-gate #include <openssl/pem.h>
640Sstevel@tonic-gate #include <openssl/ocsp.h>
650Sstevel@tonic-gate #include <openssl/err.h>
660Sstevel@tonic-gate #include <openssl/ssl.h>
67*2139Sjp161948 #include <openssl/bn.h>
680Sstevel@tonic-gate
690Sstevel@tonic-gate /* Maximum leeway in validity period: default 5 minutes */
700Sstevel@tonic-gate #define MAX_VALIDITY_PERIOD (5 * 60)
710Sstevel@tonic-gate
720Sstevel@tonic-gate static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
730Sstevel@tonic-gate STACK_OF(OCSP_CERTID) *ids);
740Sstevel@tonic-gate static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
750Sstevel@tonic-gate STACK_OF(OCSP_CERTID) *ids);
760Sstevel@tonic-gate static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
770Sstevel@tonic-gate STACK *names, STACK_OF(OCSP_CERTID) *ids,
780Sstevel@tonic-gate long nsec, long maxage);
790Sstevel@tonic-gate
800Sstevel@tonic-gate static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
810Sstevel@tonic-gate X509 *ca, X509 *rcert, EVP_PKEY *rkey,
820Sstevel@tonic-gate STACK_OF(X509) *rother, unsigned long flags,
830Sstevel@tonic-gate int nmin, int ndays);
840Sstevel@tonic-gate
850Sstevel@tonic-gate static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
860Sstevel@tonic-gate static BIO *init_responder(char *port);
870Sstevel@tonic-gate static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port);
880Sstevel@tonic-gate static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
890Sstevel@tonic-gate
900Sstevel@tonic-gate #undef PROG
910Sstevel@tonic-gate #define PROG ocsp_main
920Sstevel@tonic-gate
930Sstevel@tonic-gate int MAIN(int, char **);
940Sstevel@tonic-gate
MAIN(int argc,char ** argv)950Sstevel@tonic-gate int MAIN(int argc, char **argv)
960Sstevel@tonic-gate {
970Sstevel@tonic-gate ENGINE *e = NULL;
980Sstevel@tonic-gate char **args;
990Sstevel@tonic-gate char *host = NULL, *port = NULL, *path = "/";
1000Sstevel@tonic-gate char *reqin = NULL, *respin = NULL;
1010Sstevel@tonic-gate char *reqout = NULL, *respout = NULL;
1020Sstevel@tonic-gate char *signfile = NULL, *keyfile = NULL;
1030Sstevel@tonic-gate char *rsignfile = NULL, *rkeyfile = NULL;
1040Sstevel@tonic-gate char *outfile = NULL;
1050Sstevel@tonic-gate int add_nonce = 1, noverify = 0, use_ssl = -1;
1060Sstevel@tonic-gate OCSP_REQUEST *req = NULL;
1070Sstevel@tonic-gate OCSP_RESPONSE *resp = NULL;
1080Sstevel@tonic-gate OCSP_BASICRESP *bs = NULL;
1090Sstevel@tonic-gate X509 *issuer = NULL, *cert = NULL;
1100Sstevel@tonic-gate X509 *signer = NULL, *rsigner = NULL;
1110Sstevel@tonic-gate EVP_PKEY *key = NULL, *rkey = NULL;
1120Sstevel@tonic-gate BIO *acbio = NULL, *cbio = NULL;
1130Sstevel@tonic-gate BIO *derbio = NULL;
1140Sstevel@tonic-gate BIO *out = NULL;
1150Sstevel@tonic-gate int req_text = 0, resp_text = 0;
1160Sstevel@tonic-gate long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
1170Sstevel@tonic-gate char *CAfile = NULL, *CApath = NULL;
1180Sstevel@tonic-gate X509_STORE *store = NULL;
1190Sstevel@tonic-gate SSL_CTX *ctx = NULL;
1200Sstevel@tonic-gate STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
1210Sstevel@tonic-gate char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
1220Sstevel@tonic-gate unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
1230Sstevel@tonic-gate int ret = 1;
1240Sstevel@tonic-gate int accept_count = -1;
1250Sstevel@tonic-gate int badarg = 0;
1260Sstevel@tonic-gate int i;
1270Sstevel@tonic-gate int ignore_err = 0;
1280Sstevel@tonic-gate STACK *reqnames = NULL;
1290Sstevel@tonic-gate STACK_OF(OCSP_CERTID) *ids = NULL;
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate X509 *rca_cert = NULL;
1320Sstevel@tonic-gate char *ridx_filename = NULL;
1330Sstevel@tonic-gate char *rca_filename = NULL;
1340Sstevel@tonic-gate CA_DB *rdb = NULL;
1350Sstevel@tonic-gate int nmin = 0, ndays = -1;
1360Sstevel@tonic-gate
1370Sstevel@tonic-gate if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate if (!load_config(bio_err, NULL))
1400Sstevel@tonic-gate goto end;
1410Sstevel@tonic-gate SSL_load_error_strings();
1420Sstevel@tonic-gate args = argv + 1;
1430Sstevel@tonic-gate reqnames = sk_new_null();
1440Sstevel@tonic-gate ids = sk_OCSP_CERTID_new_null();
1450Sstevel@tonic-gate while (!badarg && *args && *args[0] == '-')
1460Sstevel@tonic-gate {
1470Sstevel@tonic-gate if (!strcmp(*args, "-out"))
1480Sstevel@tonic-gate {
1490Sstevel@tonic-gate if (args[1])
1500Sstevel@tonic-gate {
1510Sstevel@tonic-gate args++;
1520Sstevel@tonic-gate outfile = *args;
1530Sstevel@tonic-gate }
1540Sstevel@tonic-gate else badarg = 1;
1550Sstevel@tonic-gate }
1560Sstevel@tonic-gate else if (!strcmp(*args, "-url"))
1570Sstevel@tonic-gate {
1580Sstevel@tonic-gate if (args[1])
1590Sstevel@tonic-gate {
1600Sstevel@tonic-gate args++;
1610Sstevel@tonic-gate if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl))
1620Sstevel@tonic-gate {
1630Sstevel@tonic-gate BIO_printf(bio_err, "Error parsing URL\n");
1640Sstevel@tonic-gate badarg = 1;
1650Sstevel@tonic-gate }
1660Sstevel@tonic-gate }
1670Sstevel@tonic-gate else badarg = 1;
1680Sstevel@tonic-gate }
1690Sstevel@tonic-gate else if (!strcmp(*args, "-host"))
1700Sstevel@tonic-gate {
1710Sstevel@tonic-gate if (args[1])
1720Sstevel@tonic-gate {
1730Sstevel@tonic-gate args++;
1740Sstevel@tonic-gate host = *args;
1750Sstevel@tonic-gate }
1760Sstevel@tonic-gate else badarg = 1;
1770Sstevel@tonic-gate }
1780Sstevel@tonic-gate else if (!strcmp(*args, "-port"))
1790Sstevel@tonic-gate {
1800Sstevel@tonic-gate if (args[1])
1810Sstevel@tonic-gate {
1820Sstevel@tonic-gate args++;
1830Sstevel@tonic-gate port = *args;
1840Sstevel@tonic-gate }
1850Sstevel@tonic-gate else badarg = 1;
1860Sstevel@tonic-gate }
1870Sstevel@tonic-gate else if (!strcmp(*args, "-ignore_err"))
1880Sstevel@tonic-gate ignore_err = 1;
1890Sstevel@tonic-gate else if (!strcmp(*args, "-noverify"))
1900Sstevel@tonic-gate noverify = 1;
1910Sstevel@tonic-gate else if (!strcmp(*args, "-nonce"))
1920Sstevel@tonic-gate add_nonce = 2;
1930Sstevel@tonic-gate else if (!strcmp(*args, "-no_nonce"))
1940Sstevel@tonic-gate add_nonce = 0;
1950Sstevel@tonic-gate else if (!strcmp(*args, "-resp_no_certs"))
1960Sstevel@tonic-gate rflags |= OCSP_NOCERTS;
1970Sstevel@tonic-gate else if (!strcmp(*args, "-resp_key_id"))
1980Sstevel@tonic-gate rflags |= OCSP_RESPID_KEY;
1990Sstevel@tonic-gate else if (!strcmp(*args, "-no_certs"))
2000Sstevel@tonic-gate sign_flags |= OCSP_NOCERTS;
2010Sstevel@tonic-gate else if (!strcmp(*args, "-no_signature_verify"))
2020Sstevel@tonic-gate verify_flags |= OCSP_NOSIGS;
2030Sstevel@tonic-gate else if (!strcmp(*args, "-no_cert_verify"))
2040Sstevel@tonic-gate verify_flags |= OCSP_NOVERIFY;
2050Sstevel@tonic-gate else if (!strcmp(*args, "-no_chain"))
2060Sstevel@tonic-gate verify_flags |= OCSP_NOCHAIN;
2070Sstevel@tonic-gate else if (!strcmp(*args, "-no_cert_checks"))
2080Sstevel@tonic-gate verify_flags |= OCSP_NOCHECKS;
2090Sstevel@tonic-gate else if (!strcmp(*args, "-no_explicit"))
2100Sstevel@tonic-gate verify_flags |= OCSP_NOEXPLICIT;
2110Sstevel@tonic-gate else if (!strcmp(*args, "-trust_other"))
2120Sstevel@tonic-gate verify_flags |= OCSP_TRUSTOTHER;
2130Sstevel@tonic-gate else if (!strcmp(*args, "-no_intern"))
2140Sstevel@tonic-gate verify_flags |= OCSP_NOINTERN;
2150Sstevel@tonic-gate else if (!strcmp(*args, "-text"))
2160Sstevel@tonic-gate {
2170Sstevel@tonic-gate req_text = 1;
2180Sstevel@tonic-gate resp_text = 1;
2190Sstevel@tonic-gate }
2200Sstevel@tonic-gate else if (!strcmp(*args, "-req_text"))
2210Sstevel@tonic-gate req_text = 1;
2220Sstevel@tonic-gate else if (!strcmp(*args, "-resp_text"))
2230Sstevel@tonic-gate resp_text = 1;
2240Sstevel@tonic-gate else if (!strcmp(*args, "-reqin"))
2250Sstevel@tonic-gate {
2260Sstevel@tonic-gate if (args[1])
2270Sstevel@tonic-gate {
2280Sstevel@tonic-gate args++;
2290Sstevel@tonic-gate reqin = *args;
2300Sstevel@tonic-gate }
2310Sstevel@tonic-gate else badarg = 1;
2320Sstevel@tonic-gate }
2330Sstevel@tonic-gate else if (!strcmp(*args, "-respin"))
2340Sstevel@tonic-gate {
2350Sstevel@tonic-gate if (args[1])
2360Sstevel@tonic-gate {
2370Sstevel@tonic-gate args++;
2380Sstevel@tonic-gate respin = *args;
2390Sstevel@tonic-gate }
2400Sstevel@tonic-gate else badarg = 1;
2410Sstevel@tonic-gate }
2420Sstevel@tonic-gate else if (!strcmp(*args, "-signer"))
2430Sstevel@tonic-gate {
2440Sstevel@tonic-gate if (args[1])
2450Sstevel@tonic-gate {
2460Sstevel@tonic-gate args++;
2470Sstevel@tonic-gate signfile = *args;
2480Sstevel@tonic-gate }
2490Sstevel@tonic-gate else badarg = 1;
2500Sstevel@tonic-gate }
2510Sstevel@tonic-gate else if (!strcmp (*args, "-VAfile"))
2520Sstevel@tonic-gate {
2530Sstevel@tonic-gate if (args[1])
2540Sstevel@tonic-gate {
2550Sstevel@tonic-gate args++;
2560Sstevel@tonic-gate verify_certfile = *args;
2570Sstevel@tonic-gate verify_flags |= OCSP_TRUSTOTHER;
2580Sstevel@tonic-gate }
2590Sstevel@tonic-gate else badarg = 1;
2600Sstevel@tonic-gate }
2610Sstevel@tonic-gate else if (!strcmp(*args, "-sign_other"))
2620Sstevel@tonic-gate {
2630Sstevel@tonic-gate if (args[1])
2640Sstevel@tonic-gate {
2650Sstevel@tonic-gate args++;
2660Sstevel@tonic-gate sign_certfile = *args;
2670Sstevel@tonic-gate }
2680Sstevel@tonic-gate else badarg = 1;
2690Sstevel@tonic-gate }
2700Sstevel@tonic-gate else if (!strcmp(*args, "-verify_other"))
2710Sstevel@tonic-gate {
2720Sstevel@tonic-gate if (args[1])
2730Sstevel@tonic-gate {
2740Sstevel@tonic-gate args++;
2750Sstevel@tonic-gate verify_certfile = *args;
2760Sstevel@tonic-gate }
2770Sstevel@tonic-gate else badarg = 1;
2780Sstevel@tonic-gate }
2790Sstevel@tonic-gate else if (!strcmp (*args, "-CAfile"))
2800Sstevel@tonic-gate {
2810Sstevel@tonic-gate if (args[1])
2820Sstevel@tonic-gate {
2830Sstevel@tonic-gate args++;
2840Sstevel@tonic-gate CAfile = *args;
2850Sstevel@tonic-gate }
2860Sstevel@tonic-gate else badarg = 1;
2870Sstevel@tonic-gate }
2880Sstevel@tonic-gate else if (!strcmp (*args, "-CApath"))
2890Sstevel@tonic-gate {
2900Sstevel@tonic-gate if (args[1])
2910Sstevel@tonic-gate {
2920Sstevel@tonic-gate args++;
2930Sstevel@tonic-gate CApath = *args;
2940Sstevel@tonic-gate }
2950Sstevel@tonic-gate else badarg = 1;
2960Sstevel@tonic-gate }
2970Sstevel@tonic-gate else if (!strcmp (*args, "-validity_period"))
2980Sstevel@tonic-gate {
2990Sstevel@tonic-gate if (args[1])
3000Sstevel@tonic-gate {
3010Sstevel@tonic-gate args++;
3020Sstevel@tonic-gate nsec = atol(*args);
3030Sstevel@tonic-gate if (nsec < 0)
3040Sstevel@tonic-gate {
3050Sstevel@tonic-gate BIO_printf(bio_err,
3060Sstevel@tonic-gate "Illegal validity period %s\n",
3070Sstevel@tonic-gate *args);
3080Sstevel@tonic-gate badarg = 1;
3090Sstevel@tonic-gate }
3100Sstevel@tonic-gate }
3110Sstevel@tonic-gate else badarg = 1;
3120Sstevel@tonic-gate }
3130Sstevel@tonic-gate else if (!strcmp (*args, "-status_age"))
3140Sstevel@tonic-gate {
3150Sstevel@tonic-gate if (args[1])
3160Sstevel@tonic-gate {
3170Sstevel@tonic-gate args++;
3180Sstevel@tonic-gate maxage = atol(*args);
3190Sstevel@tonic-gate if (maxage < 0)
3200Sstevel@tonic-gate {
3210Sstevel@tonic-gate BIO_printf(bio_err,
3220Sstevel@tonic-gate "Illegal validity age %s\n",
3230Sstevel@tonic-gate *args);
3240Sstevel@tonic-gate badarg = 1;
3250Sstevel@tonic-gate }
3260Sstevel@tonic-gate }
3270Sstevel@tonic-gate else badarg = 1;
3280Sstevel@tonic-gate }
3290Sstevel@tonic-gate else if (!strcmp(*args, "-signkey"))
3300Sstevel@tonic-gate {
3310Sstevel@tonic-gate if (args[1])
3320Sstevel@tonic-gate {
3330Sstevel@tonic-gate args++;
3340Sstevel@tonic-gate keyfile = *args;
3350Sstevel@tonic-gate }
3360Sstevel@tonic-gate else badarg = 1;
3370Sstevel@tonic-gate }
3380Sstevel@tonic-gate else if (!strcmp(*args, "-reqout"))
3390Sstevel@tonic-gate {
3400Sstevel@tonic-gate if (args[1])
3410Sstevel@tonic-gate {
3420Sstevel@tonic-gate args++;
3430Sstevel@tonic-gate reqout = *args;
3440Sstevel@tonic-gate }
3450Sstevel@tonic-gate else badarg = 1;
3460Sstevel@tonic-gate }
3470Sstevel@tonic-gate else if (!strcmp(*args, "-respout"))
3480Sstevel@tonic-gate {
3490Sstevel@tonic-gate if (args[1])
3500Sstevel@tonic-gate {
3510Sstevel@tonic-gate args++;
3520Sstevel@tonic-gate respout = *args;
3530Sstevel@tonic-gate }
3540Sstevel@tonic-gate else badarg = 1;
3550Sstevel@tonic-gate }
3560Sstevel@tonic-gate else if (!strcmp(*args, "-path"))
3570Sstevel@tonic-gate {
3580Sstevel@tonic-gate if (args[1])
3590Sstevel@tonic-gate {
3600Sstevel@tonic-gate args++;
3610Sstevel@tonic-gate path = *args;
3620Sstevel@tonic-gate }
3630Sstevel@tonic-gate else badarg = 1;
3640Sstevel@tonic-gate }
3650Sstevel@tonic-gate else if (!strcmp(*args, "-issuer"))
3660Sstevel@tonic-gate {
3670Sstevel@tonic-gate if (args[1])
3680Sstevel@tonic-gate {
3690Sstevel@tonic-gate args++;
3700Sstevel@tonic-gate X509_free(issuer);
3710Sstevel@tonic-gate issuer = load_cert(bio_err, *args, FORMAT_PEM,
3720Sstevel@tonic-gate NULL, e, "issuer certificate");
3730Sstevel@tonic-gate if(!issuer) goto end;
3740Sstevel@tonic-gate }
3750Sstevel@tonic-gate else badarg = 1;
3760Sstevel@tonic-gate }
3770Sstevel@tonic-gate else if (!strcmp (*args, "-cert"))
3780Sstevel@tonic-gate {
3790Sstevel@tonic-gate if (args[1])
3800Sstevel@tonic-gate {
3810Sstevel@tonic-gate args++;
3820Sstevel@tonic-gate X509_free(cert);
3830Sstevel@tonic-gate cert = load_cert(bio_err, *args, FORMAT_PEM,
3840Sstevel@tonic-gate NULL, e, "certificate");
3850Sstevel@tonic-gate if(!cert) goto end;
3860Sstevel@tonic-gate if(!add_ocsp_cert(&req, cert, issuer, ids))
3870Sstevel@tonic-gate goto end;
3880Sstevel@tonic-gate if(!sk_push(reqnames, *args))
3890Sstevel@tonic-gate goto end;
3900Sstevel@tonic-gate }
3910Sstevel@tonic-gate else badarg = 1;
3920Sstevel@tonic-gate }
3930Sstevel@tonic-gate else if (!strcmp(*args, "-serial"))
3940Sstevel@tonic-gate {
3950Sstevel@tonic-gate if (args[1])
3960Sstevel@tonic-gate {
3970Sstevel@tonic-gate args++;
3980Sstevel@tonic-gate if(!add_ocsp_serial(&req, *args, issuer, ids))
3990Sstevel@tonic-gate goto end;
4000Sstevel@tonic-gate if(!sk_push(reqnames, *args))
4010Sstevel@tonic-gate goto end;
4020Sstevel@tonic-gate }
4030Sstevel@tonic-gate else badarg = 1;
4040Sstevel@tonic-gate }
4050Sstevel@tonic-gate else if (!strcmp(*args, "-index"))
4060Sstevel@tonic-gate {
4070Sstevel@tonic-gate if (args[1])
4080Sstevel@tonic-gate {
4090Sstevel@tonic-gate args++;
4100Sstevel@tonic-gate ridx_filename = *args;
4110Sstevel@tonic-gate }
4120Sstevel@tonic-gate else badarg = 1;
4130Sstevel@tonic-gate }
4140Sstevel@tonic-gate else if (!strcmp(*args, "-CA"))
4150Sstevel@tonic-gate {
4160Sstevel@tonic-gate if (args[1])
4170Sstevel@tonic-gate {
4180Sstevel@tonic-gate args++;
4190Sstevel@tonic-gate rca_filename = *args;
4200Sstevel@tonic-gate }
4210Sstevel@tonic-gate else badarg = 1;
4220Sstevel@tonic-gate }
4230Sstevel@tonic-gate else if (!strcmp (*args, "-nmin"))
4240Sstevel@tonic-gate {
4250Sstevel@tonic-gate if (args[1])
4260Sstevel@tonic-gate {
4270Sstevel@tonic-gate args++;
4280Sstevel@tonic-gate nmin = atol(*args);
4290Sstevel@tonic-gate if (nmin < 0)
4300Sstevel@tonic-gate {
4310Sstevel@tonic-gate BIO_printf(bio_err,
4320Sstevel@tonic-gate "Illegal update period %s\n",
4330Sstevel@tonic-gate *args);
4340Sstevel@tonic-gate badarg = 1;
4350Sstevel@tonic-gate }
4360Sstevel@tonic-gate }
4370Sstevel@tonic-gate if (ndays == -1)
4380Sstevel@tonic-gate ndays = 0;
4390Sstevel@tonic-gate else badarg = 1;
4400Sstevel@tonic-gate }
4410Sstevel@tonic-gate else if (!strcmp (*args, "-nrequest"))
4420Sstevel@tonic-gate {
4430Sstevel@tonic-gate if (args[1])
4440Sstevel@tonic-gate {
4450Sstevel@tonic-gate args++;
4460Sstevel@tonic-gate accept_count = atol(*args);
4470Sstevel@tonic-gate if (accept_count < 0)
4480Sstevel@tonic-gate {
4490Sstevel@tonic-gate BIO_printf(bio_err,
4500Sstevel@tonic-gate "Illegal accept count %s\n",
4510Sstevel@tonic-gate *args);
4520Sstevel@tonic-gate badarg = 1;
4530Sstevel@tonic-gate }
4540Sstevel@tonic-gate }
4550Sstevel@tonic-gate else badarg = 1;
4560Sstevel@tonic-gate }
4570Sstevel@tonic-gate else if (!strcmp (*args, "-ndays"))
4580Sstevel@tonic-gate {
4590Sstevel@tonic-gate if (args[1])
4600Sstevel@tonic-gate {
4610Sstevel@tonic-gate args++;
4620Sstevel@tonic-gate ndays = atol(*args);
4630Sstevel@tonic-gate if (ndays < 0)
4640Sstevel@tonic-gate {
4650Sstevel@tonic-gate BIO_printf(bio_err,
4660Sstevel@tonic-gate "Illegal update period %s\n",
4670Sstevel@tonic-gate *args);
4680Sstevel@tonic-gate badarg = 1;
4690Sstevel@tonic-gate }
4700Sstevel@tonic-gate }
4710Sstevel@tonic-gate else badarg = 1;
4720Sstevel@tonic-gate }
4730Sstevel@tonic-gate else if (!strcmp(*args, "-rsigner"))
4740Sstevel@tonic-gate {
4750Sstevel@tonic-gate if (args[1])
4760Sstevel@tonic-gate {
4770Sstevel@tonic-gate args++;
4780Sstevel@tonic-gate rsignfile = *args;
4790Sstevel@tonic-gate }
4800Sstevel@tonic-gate else badarg = 1;
4810Sstevel@tonic-gate }
4820Sstevel@tonic-gate else if (!strcmp(*args, "-rkey"))
4830Sstevel@tonic-gate {
4840Sstevel@tonic-gate if (args[1])
4850Sstevel@tonic-gate {
4860Sstevel@tonic-gate args++;
4870Sstevel@tonic-gate rkeyfile = *args;
4880Sstevel@tonic-gate }
4890Sstevel@tonic-gate else badarg = 1;
4900Sstevel@tonic-gate }
4910Sstevel@tonic-gate else if (!strcmp(*args, "-rother"))
4920Sstevel@tonic-gate {
4930Sstevel@tonic-gate if (args[1])
4940Sstevel@tonic-gate {
4950Sstevel@tonic-gate args++;
4960Sstevel@tonic-gate rcertfile = *args;
4970Sstevel@tonic-gate }
4980Sstevel@tonic-gate else badarg = 1;
4990Sstevel@tonic-gate }
5000Sstevel@tonic-gate else badarg = 1;
5010Sstevel@tonic-gate args++;
5020Sstevel@tonic-gate }
5030Sstevel@tonic-gate
5040Sstevel@tonic-gate /* Have we anything to do? */
5050Sstevel@tonic-gate if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1;
5060Sstevel@tonic-gate
5070Sstevel@tonic-gate if (badarg)
5080Sstevel@tonic-gate {
5090Sstevel@tonic-gate BIO_printf (bio_err, "OCSP utility\n");
5100Sstevel@tonic-gate BIO_printf (bio_err, "Usage ocsp [options]\n");
5110Sstevel@tonic-gate BIO_printf (bio_err, "where options are\n");
5120Sstevel@tonic-gate BIO_printf (bio_err, "-out file output filename\n");
5130Sstevel@tonic-gate BIO_printf (bio_err, "-issuer file issuer certificate\n");
5140Sstevel@tonic-gate BIO_printf (bio_err, "-cert file certificate to check\n");
5150Sstevel@tonic-gate BIO_printf (bio_err, "-serial n serial number to check\n");
5160Sstevel@tonic-gate BIO_printf (bio_err, "-signer file certificate to sign OCSP request with\n");
5170Sstevel@tonic-gate BIO_printf (bio_err, "-signkey file private key to sign OCSP request with\n");
5180Sstevel@tonic-gate BIO_printf (bio_err, "-sign_other file additional certificates to include in signed request\n");
5190Sstevel@tonic-gate BIO_printf (bio_err, "-no_certs don't include any certificates in signed request\n");
5200Sstevel@tonic-gate BIO_printf (bio_err, "-req_text print text form of request\n");
5210Sstevel@tonic-gate BIO_printf (bio_err, "-resp_text print text form of response\n");
5220Sstevel@tonic-gate BIO_printf (bio_err, "-text print text form of request and response\n");
5230Sstevel@tonic-gate BIO_printf (bio_err, "-reqout file write DER encoded OCSP request to \"file\"\n");
5240Sstevel@tonic-gate BIO_printf (bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n");
5250Sstevel@tonic-gate BIO_printf (bio_err, "-reqin file read DER encoded OCSP request from \"file\"\n");
5260Sstevel@tonic-gate BIO_printf (bio_err, "-respin file read DER encoded OCSP reponse from \"file\"\n");
5270Sstevel@tonic-gate BIO_printf (bio_err, "-nonce add OCSP nonce to request\n");
5280Sstevel@tonic-gate BIO_printf (bio_err, "-no_nonce don't add OCSP nonce to request\n");
5290Sstevel@tonic-gate BIO_printf (bio_err, "-url URL OCSP responder URL\n");
5300Sstevel@tonic-gate BIO_printf (bio_err, "-host host:n send OCSP request to host on port n\n");
5310Sstevel@tonic-gate BIO_printf (bio_err, "-path path to use in OCSP request\n");
5320Sstevel@tonic-gate BIO_printf (bio_err, "-CApath dir trusted certificates directory\n");
5330Sstevel@tonic-gate BIO_printf (bio_err, "-CAfile file trusted certificates file\n");
5340Sstevel@tonic-gate BIO_printf (bio_err, "-VAfile file validator certificates file\n");
5350Sstevel@tonic-gate BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
5360Sstevel@tonic-gate BIO_printf (bio_err, "-status_age n maximum status age in seconds\n");
5370Sstevel@tonic-gate BIO_printf (bio_err, "-noverify don't verify response at all\n");
5380Sstevel@tonic-gate BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n");
5390Sstevel@tonic-gate BIO_printf (bio_err, "-trust_other don't verify additional certificates\n");
5400Sstevel@tonic-gate BIO_printf (bio_err, "-no_intern don't search certificates contained in response for signer\n");
5410Sstevel@tonic-gate BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n");
5420Sstevel@tonic-gate BIO_printf (bio_err, "-no_cert_verify don't check signing certificate\n");
5430Sstevel@tonic-gate BIO_printf (bio_err, "-no_chain don't chain verify response\n");
5440Sstevel@tonic-gate BIO_printf (bio_err, "-no_cert_checks don't do additional checks on signing certificate\n");
5450Sstevel@tonic-gate BIO_printf (bio_err, "-port num port to run responder on\n");
5460Sstevel@tonic-gate BIO_printf (bio_err, "-index file certificate status index file\n");
5470Sstevel@tonic-gate BIO_printf (bio_err, "-CA file CA certificate\n");
5480Sstevel@tonic-gate BIO_printf (bio_err, "-rsigner file responder certificate to sign responses with\n");
5490Sstevel@tonic-gate BIO_printf (bio_err, "-rkey file responder key to sign responses with\n");
5500Sstevel@tonic-gate BIO_printf (bio_err, "-rother file other certificates to include in response\n");
5510Sstevel@tonic-gate BIO_printf (bio_err, "-resp_no_certs don't include any certificates in response\n");
5520Sstevel@tonic-gate BIO_printf (bio_err, "-nmin n number of minutes before next update\n");
5530Sstevel@tonic-gate BIO_printf (bio_err, "-ndays n number of days before next update\n");
5540Sstevel@tonic-gate BIO_printf (bio_err, "-resp_key_id identify reponse by signing certificate key ID\n");
5550Sstevel@tonic-gate BIO_printf (bio_err, "-nrequest n number of requests to accept (default unlimited)\n");
5560Sstevel@tonic-gate goto end;
5570Sstevel@tonic-gate }
5580Sstevel@tonic-gate
5590Sstevel@tonic-gate if(outfile) out = BIO_new_file(outfile, "w");
5600Sstevel@tonic-gate else out = BIO_new_fp(stdout, BIO_NOCLOSE);
5610Sstevel@tonic-gate
5620Sstevel@tonic-gate if(!out)
5630Sstevel@tonic-gate {
5640Sstevel@tonic-gate BIO_printf(bio_err, "Error opening output file\n");
5650Sstevel@tonic-gate goto end;
5660Sstevel@tonic-gate }
5670Sstevel@tonic-gate
5680Sstevel@tonic-gate if (!req && (add_nonce != 2)) add_nonce = 0;
5690Sstevel@tonic-gate
5700Sstevel@tonic-gate if (!req && reqin)
5710Sstevel@tonic-gate {
5720Sstevel@tonic-gate derbio = BIO_new_file(reqin, "rb");
5730Sstevel@tonic-gate if (!derbio)
5740Sstevel@tonic-gate {
5750Sstevel@tonic-gate BIO_printf(bio_err, "Error Opening OCSP request file\n");
5760Sstevel@tonic-gate goto end;
5770Sstevel@tonic-gate }
5780Sstevel@tonic-gate req = d2i_OCSP_REQUEST_bio(derbio, NULL);
5790Sstevel@tonic-gate BIO_free(derbio);
5800Sstevel@tonic-gate if(!req)
5810Sstevel@tonic-gate {
5820Sstevel@tonic-gate BIO_printf(bio_err, "Error reading OCSP request\n");
5830Sstevel@tonic-gate goto end;
5840Sstevel@tonic-gate }
5850Sstevel@tonic-gate }
5860Sstevel@tonic-gate
5870Sstevel@tonic-gate if (!req && port)
5880Sstevel@tonic-gate {
5890Sstevel@tonic-gate acbio = init_responder(port);
5900Sstevel@tonic-gate if (!acbio)
5910Sstevel@tonic-gate goto end;
5920Sstevel@tonic-gate }
5930Sstevel@tonic-gate
5940Sstevel@tonic-gate if (rsignfile && !rdb)
5950Sstevel@tonic-gate {
5960Sstevel@tonic-gate if (!rkeyfile) rkeyfile = rsignfile;
5970Sstevel@tonic-gate rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,
5980Sstevel@tonic-gate NULL, e, "responder certificate");
5990Sstevel@tonic-gate if (!rsigner)
6000Sstevel@tonic-gate {
6010Sstevel@tonic-gate BIO_printf(bio_err, "Error loading responder certificate\n");
6020Sstevel@tonic-gate goto end;
6030Sstevel@tonic-gate }
6040Sstevel@tonic-gate rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,
6050Sstevel@tonic-gate NULL, e, "CA certificate");
6060Sstevel@tonic-gate if (rcertfile)
6070Sstevel@tonic-gate {
6080Sstevel@tonic-gate rother = load_certs(bio_err, rcertfile, FORMAT_PEM,
6090Sstevel@tonic-gate NULL, e, "responder other certificates");
6100Sstevel@tonic-gate if (!rother) goto end;
6110Sstevel@tonic-gate }
6120Sstevel@tonic-gate rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL,
6130Sstevel@tonic-gate "responder private key");
6140Sstevel@tonic-gate if (!rkey)
6150Sstevel@tonic-gate goto end;
6160Sstevel@tonic-gate }
6170Sstevel@tonic-gate if(acbio)
6180Sstevel@tonic-gate BIO_printf(bio_err, "Waiting for OCSP client connections...\n");
6190Sstevel@tonic-gate
6200Sstevel@tonic-gate redo_accept:
6210Sstevel@tonic-gate
6220Sstevel@tonic-gate if (acbio)
6230Sstevel@tonic-gate {
6240Sstevel@tonic-gate if (!do_responder(&req, &cbio, acbio, port))
6250Sstevel@tonic-gate goto end;
6260Sstevel@tonic-gate if (!req)
6270Sstevel@tonic-gate {
6280Sstevel@tonic-gate resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
6290Sstevel@tonic-gate send_ocsp_response(cbio, resp);
6300Sstevel@tonic-gate goto done_resp;
6310Sstevel@tonic-gate }
6320Sstevel@tonic-gate }
6330Sstevel@tonic-gate
6340Sstevel@tonic-gate if (!req && (signfile || reqout || host || add_nonce || ridx_filename))
6350Sstevel@tonic-gate {
6360Sstevel@tonic-gate BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
6370Sstevel@tonic-gate goto end;
6380Sstevel@tonic-gate }
6390Sstevel@tonic-gate
6400Sstevel@tonic-gate if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1);
6410Sstevel@tonic-gate
6420Sstevel@tonic-gate if (signfile)
6430Sstevel@tonic-gate {
6440Sstevel@tonic-gate if (!keyfile) keyfile = signfile;
6450Sstevel@tonic-gate signer = load_cert(bio_err, signfile, FORMAT_PEM,
6460Sstevel@tonic-gate NULL, e, "signer certificate");
6470Sstevel@tonic-gate if (!signer)
6480Sstevel@tonic-gate {
6490Sstevel@tonic-gate BIO_printf(bio_err, "Error loading signer certificate\n");
6500Sstevel@tonic-gate goto end;
6510Sstevel@tonic-gate }
6520Sstevel@tonic-gate if (sign_certfile)
6530Sstevel@tonic-gate {
6540Sstevel@tonic-gate sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,
6550Sstevel@tonic-gate NULL, e, "signer certificates");
6560Sstevel@tonic-gate if (!sign_other) goto end;
6570Sstevel@tonic-gate }
6580Sstevel@tonic-gate key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL,
6590Sstevel@tonic-gate "signer private key");
6600Sstevel@tonic-gate if (!key)
6610Sstevel@tonic-gate goto end;
6620Sstevel@tonic-gate if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags))
6630Sstevel@tonic-gate {
6640Sstevel@tonic-gate BIO_printf(bio_err, "Error signing OCSP request\n");
6650Sstevel@tonic-gate goto end;
6660Sstevel@tonic-gate }
6670Sstevel@tonic-gate }
6680Sstevel@tonic-gate
6690Sstevel@tonic-gate if (req_text && req) OCSP_REQUEST_print(out, req, 0);
6700Sstevel@tonic-gate
6710Sstevel@tonic-gate if (reqout)
6720Sstevel@tonic-gate {
6730Sstevel@tonic-gate derbio = BIO_new_file(reqout, "wb");
6740Sstevel@tonic-gate if(!derbio)
6750Sstevel@tonic-gate {
6760Sstevel@tonic-gate BIO_printf(bio_err, "Error opening file %s\n", reqout);
6770Sstevel@tonic-gate goto end;
6780Sstevel@tonic-gate }
6790Sstevel@tonic-gate i2d_OCSP_REQUEST_bio(derbio, req);
6800Sstevel@tonic-gate BIO_free(derbio);
6810Sstevel@tonic-gate }
6820Sstevel@tonic-gate
6830Sstevel@tonic-gate if (ridx_filename && (!rkey || !rsigner || !rca_cert))
6840Sstevel@tonic-gate {
6850Sstevel@tonic-gate BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n");
6860Sstevel@tonic-gate goto end;
6870Sstevel@tonic-gate }
6880Sstevel@tonic-gate
6890Sstevel@tonic-gate if (ridx_filename && !rdb)
6900Sstevel@tonic-gate {
6910Sstevel@tonic-gate rdb = load_index(ridx_filename, NULL);
6920Sstevel@tonic-gate if (!rdb) goto end;
6930Sstevel@tonic-gate if (!index_index(rdb)) goto end;
6940Sstevel@tonic-gate }
6950Sstevel@tonic-gate
6960Sstevel@tonic-gate if (rdb)
6970Sstevel@tonic-gate {
6980Sstevel@tonic-gate i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays);
6990Sstevel@tonic-gate if (cbio)
7000Sstevel@tonic-gate send_ocsp_response(cbio, resp);
7010Sstevel@tonic-gate }
7020Sstevel@tonic-gate else if (host)
7030Sstevel@tonic-gate {
7040Sstevel@tonic-gate #ifndef OPENSSL_NO_SOCK
7050Sstevel@tonic-gate cbio = BIO_new_connect(host);
7060Sstevel@tonic-gate #else
7070Sstevel@tonic-gate BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n");
7080Sstevel@tonic-gate goto end;
7090Sstevel@tonic-gate #endif
7100Sstevel@tonic-gate if (!cbio)
7110Sstevel@tonic-gate {
7120Sstevel@tonic-gate BIO_printf(bio_err, "Error creating connect BIO\n");
7130Sstevel@tonic-gate goto end;
7140Sstevel@tonic-gate }
7150Sstevel@tonic-gate if (port) BIO_set_conn_port(cbio, port);
7160Sstevel@tonic-gate if (use_ssl == 1)
7170Sstevel@tonic-gate {
7180Sstevel@tonic-gate BIO *sbio;
7190Sstevel@tonic-gate #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
7200Sstevel@tonic-gate ctx = SSL_CTX_new(SSLv23_client_method());
7210Sstevel@tonic-gate #elif !defined(OPENSSL_NO_SSL3)
7220Sstevel@tonic-gate ctx = SSL_CTX_new(SSLv3_client_method());
7230Sstevel@tonic-gate #elif !defined(OPENSSL_NO_SSL2)
7240Sstevel@tonic-gate ctx = SSL_CTX_new(SSLv2_client_method());
7250Sstevel@tonic-gate #else
7260Sstevel@tonic-gate BIO_printf(bio_err, "SSL is disabled\n");
7270Sstevel@tonic-gate goto end;
7280Sstevel@tonic-gate #endif
7290Sstevel@tonic-gate SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
7300Sstevel@tonic-gate sbio = BIO_new_ssl(ctx, 1);
7310Sstevel@tonic-gate cbio = BIO_push(sbio, cbio);
7320Sstevel@tonic-gate }
7330Sstevel@tonic-gate if (BIO_do_connect(cbio) <= 0)
7340Sstevel@tonic-gate {
7350Sstevel@tonic-gate BIO_printf(bio_err, "Error connecting BIO\n");
7360Sstevel@tonic-gate goto end;
7370Sstevel@tonic-gate }
7380Sstevel@tonic-gate resp = OCSP_sendreq_bio(cbio, path, req);
7390Sstevel@tonic-gate BIO_free_all(cbio);
7400Sstevel@tonic-gate cbio = NULL;
7410Sstevel@tonic-gate if (!resp)
7420Sstevel@tonic-gate {
7430Sstevel@tonic-gate BIO_printf(bio_err, "Error querying OCSP responsder\n");
7440Sstevel@tonic-gate goto end;
7450Sstevel@tonic-gate }
7460Sstevel@tonic-gate }
7470Sstevel@tonic-gate else if (respin)
7480Sstevel@tonic-gate {
7490Sstevel@tonic-gate derbio = BIO_new_file(respin, "rb");
7500Sstevel@tonic-gate if (!derbio)
7510Sstevel@tonic-gate {
7520Sstevel@tonic-gate BIO_printf(bio_err, "Error Opening OCSP response file\n");
7530Sstevel@tonic-gate goto end;
7540Sstevel@tonic-gate }
7550Sstevel@tonic-gate resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
7560Sstevel@tonic-gate BIO_free(derbio);
7570Sstevel@tonic-gate if(!resp)
7580Sstevel@tonic-gate {
7590Sstevel@tonic-gate BIO_printf(bio_err, "Error reading OCSP response\n");
7600Sstevel@tonic-gate goto end;
7610Sstevel@tonic-gate }
7620Sstevel@tonic-gate
7630Sstevel@tonic-gate }
7640Sstevel@tonic-gate else
7650Sstevel@tonic-gate {
7660Sstevel@tonic-gate ret = 0;
7670Sstevel@tonic-gate goto end;
7680Sstevel@tonic-gate }
7690Sstevel@tonic-gate
7700Sstevel@tonic-gate done_resp:
7710Sstevel@tonic-gate
7720Sstevel@tonic-gate if (respout)
7730Sstevel@tonic-gate {
7740Sstevel@tonic-gate derbio = BIO_new_file(respout, "wb");
7750Sstevel@tonic-gate if(!derbio)
7760Sstevel@tonic-gate {
7770Sstevel@tonic-gate BIO_printf(bio_err, "Error opening file %s\n", respout);
7780Sstevel@tonic-gate goto end;
7790Sstevel@tonic-gate }
7800Sstevel@tonic-gate i2d_OCSP_RESPONSE_bio(derbio, resp);
7810Sstevel@tonic-gate BIO_free(derbio);
7820Sstevel@tonic-gate }
7830Sstevel@tonic-gate
7840Sstevel@tonic-gate i = OCSP_response_status(resp);
7850Sstevel@tonic-gate
7860Sstevel@tonic-gate if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL)
7870Sstevel@tonic-gate {
788*2139Sjp161948 BIO_printf(out, "Responder Error: %s (%d)\n",
7890Sstevel@tonic-gate OCSP_response_status_str(i), i);
7900Sstevel@tonic-gate if (ignore_err)
7910Sstevel@tonic-gate goto redo_accept;
7920Sstevel@tonic-gate ret = 0;
7930Sstevel@tonic-gate goto end;
7940Sstevel@tonic-gate }
7950Sstevel@tonic-gate
7960Sstevel@tonic-gate if (resp_text) OCSP_RESPONSE_print(out, resp, 0);
7970Sstevel@tonic-gate
7980Sstevel@tonic-gate /* If running as responder don't verify our own response */
7990Sstevel@tonic-gate if (cbio)
8000Sstevel@tonic-gate {
8010Sstevel@tonic-gate if (accept_count > 0)
8020Sstevel@tonic-gate accept_count--;
8030Sstevel@tonic-gate /* Redo if more connections needed */
8040Sstevel@tonic-gate if (accept_count)
8050Sstevel@tonic-gate {
8060Sstevel@tonic-gate BIO_free_all(cbio);
8070Sstevel@tonic-gate cbio = NULL;
8080Sstevel@tonic-gate OCSP_REQUEST_free(req);
8090Sstevel@tonic-gate req = NULL;
8100Sstevel@tonic-gate OCSP_RESPONSE_free(resp);
8110Sstevel@tonic-gate resp = NULL;
8120Sstevel@tonic-gate goto redo_accept;
8130Sstevel@tonic-gate }
8140Sstevel@tonic-gate goto end;
8150Sstevel@tonic-gate }
8160Sstevel@tonic-gate
8170Sstevel@tonic-gate if (!store)
8180Sstevel@tonic-gate store = setup_verify(bio_err, CAfile, CApath);
8190Sstevel@tonic-gate if (!store)
8200Sstevel@tonic-gate goto end;
8210Sstevel@tonic-gate if (verify_certfile)
8220Sstevel@tonic-gate {
8230Sstevel@tonic-gate verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,
8240Sstevel@tonic-gate NULL, e, "validator certificate");
8250Sstevel@tonic-gate if (!verify_other) goto end;
8260Sstevel@tonic-gate }
8270Sstevel@tonic-gate
8280Sstevel@tonic-gate bs = OCSP_response_get1_basic(resp);
8290Sstevel@tonic-gate
8300Sstevel@tonic-gate if (!bs)
8310Sstevel@tonic-gate {
8320Sstevel@tonic-gate BIO_printf(bio_err, "Error parsing response\n");
8330Sstevel@tonic-gate goto end;
8340Sstevel@tonic-gate }
8350Sstevel@tonic-gate
8360Sstevel@tonic-gate if (!noverify)
8370Sstevel@tonic-gate {
8380Sstevel@tonic-gate if (req && ((i = OCSP_check_nonce(req, bs)) <= 0))
8390Sstevel@tonic-gate {
8400Sstevel@tonic-gate if (i == -1)
8410Sstevel@tonic-gate BIO_printf(bio_err, "WARNING: no nonce in response\n");
8420Sstevel@tonic-gate else
8430Sstevel@tonic-gate {
8440Sstevel@tonic-gate BIO_printf(bio_err, "Nonce Verify error\n");
8450Sstevel@tonic-gate goto end;
8460Sstevel@tonic-gate }
8470Sstevel@tonic-gate }
8480Sstevel@tonic-gate
8490Sstevel@tonic-gate i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
8500Sstevel@tonic-gate if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0);
8510Sstevel@tonic-gate
8520Sstevel@tonic-gate if(i <= 0)
8530Sstevel@tonic-gate {
854*2139Sjp161948 BIO_printf(bio_err, "Response Verify Failure\n");
8550Sstevel@tonic-gate ERR_print_errors(bio_err);
8560Sstevel@tonic-gate }
8570Sstevel@tonic-gate else
8580Sstevel@tonic-gate BIO_printf(bio_err, "Response verify OK\n");
8590Sstevel@tonic-gate
8600Sstevel@tonic-gate }
8610Sstevel@tonic-gate
8620Sstevel@tonic-gate if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage))
8630Sstevel@tonic-gate goto end;
8640Sstevel@tonic-gate
8650Sstevel@tonic-gate ret = 0;
8660Sstevel@tonic-gate
8670Sstevel@tonic-gate end:
8680Sstevel@tonic-gate ERR_print_errors(bio_err);
8690Sstevel@tonic-gate X509_free(signer);
8700Sstevel@tonic-gate X509_STORE_free(store);
8710Sstevel@tonic-gate EVP_PKEY_free(key);
8720Sstevel@tonic-gate EVP_PKEY_free(rkey);
8730Sstevel@tonic-gate X509_free(issuer);
8740Sstevel@tonic-gate X509_free(cert);
8750Sstevel@tonic-gate X509_free(rsigner);
8760Sstevel@tonic-gate X509_free(rca_cert);
8770Sstevel@tonic-gate free_index(rdb);
8780Sstevel@tonic-gate BIO_free_all(cbio);
8790Sstevel@tonic-gate BIO_free_all(acbio);
8800Sstevel@tonic-gate BIO_free(out);
8810Sstevel@tonic-gate OCSP_REQUEST_free(req);
8820Sstevel@tonic-gate OCSP_RESPONSE_free(resp);
8830Sstevel@tonic-gate OCSP_BASICRESP_free(bs);
8840Sstevel@tonic-gate sk_free(reqnames);
8850Sstevel@tonic-gate sk_OCSP_CERTID_free(ids);
8860Sstevel@tonic-gate sk_X509_pop_free(sign_other, X509_free);
8870Sstevel@tonic-gate sk_X509_pop_free(verify_other, X509_free);
8880Sstevel@tonic-gate
8890Sstevel@tonic-gate if (use_ssl != -1)
8900Sstevel@tonic-gate {
8910Sstevel@tonic-gate OPENSSL_free(host);
8920Sstevel@tonic-gate OPENSSL_free(port);
8930Sstevel@tonic-gate OPENSSL_free(path);
8940Sstevel@tonic-gate SSL_CTX_free(ctx);
8950Sstevel@tonic-gate }
8960Sstevel@tonic-gate
8970Sstevel@tonic-gate OPENSSL_EXIT(ret);
8980Sstevel@tonic-gate }
8990Sstevel@tonic-gate
add_ocsp_cert(OCSP_REQUEST ** req,X509 * cert,X509 * issuer,STACK_OF (OCSP_CERTID)* ids)9000Sstevel@tonic-gate static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
9010Sstevel@tonic-gate STACK_OF(OCSP_CERTID) *ids)
9020Sstevel@tonic-gate {
9030Sstevel@tonic-gate OCSP_CERTID *id;
9040Sstevel@tonic-gate if(!issuer)
9050Sstevel@tonic-gate {
9060Sstevel@tonic-gate BIO_printf(bio_err, "No issuer certificate specified\n");
9070Sstevel@tonic-gate return 0;
9080Sstevel@tonic-gate }
9090Sstevel@tonic-gate if(!*req) *req = OCSP_REQUEST_new();
9100Sstevel@tonic-gate if(!*req) goto err;
9110Sstevel@tonic-gate id = OCSP_cert_to_id(NULL, cert, issuer);
9120Sstevel@tonic-gate if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
9130Sstevel@tonic-gate if(!OCSP_request_add0_id(*req, id)) goto err;
9140Sstevel@tonic-gate return 1;
9150Sstevel@tonic-gate
9160Sstevel@tonic-gate err:
9170Sstevel@tonic-gate BIO_printf(bio_err, "Error Creating OCSP request\n");
9180Sstevel@tonic-gate return 0;
9190Sstevel@tonic-gate }
9200Sstevel@tonic-gate
add_ocsp_serial(OCSP_REQUEST ** req,char * serial,X509 * issuer,STACK_OF (OCSP_CERTID)* ids)9210Sstevel@tonic-gate static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
9220Sstevel@tonic-gate STACK_OF(OCSP_CERTID) *ids)
9230Sstevel@tonic-gate {
9240Sstevel@tonic-gate OCSP_CERTID *id;
9250Sstevel@tonic-gate X509_NAME *iname;
9260Sstevel@tonic-gate ASN1_BIT_STRING *ikey;
9270Sstevel@tonic-gate ASN1_INTEGER *sno;
9280Sstevel@tonic-gate if(!issuer)
9290Sstevel@tonic-gate {
9300Sstevel@tonic-gate BIO_printf(bio_err, "No issuer certificate specified\n");
9310Sstevel@tonic-gate return 0;
9320Sstevel@tonic-gate }
9330Sstevel@tonic-gate if(!*req) *req = OCSP_REQUEST_new();
9340Sstevel@tonic-gate if(!*req) goto err;
9350Sstevel@tonic-gate iname = X509_get_subject_name(issuer);
9360Sstevel@tonic-gate ikey = X509_get0_pubkey_bitstr(issuer);
9370Sstevel@tonic-gate sno = s2i_ASN1_INTEGER(NULL, serial);
9380Sstevel@tonic-gate if(!sno)
9390Sstevel@tonic-gate {
9400Sstevel@tonic-gate BIO_printf(bio_err, "Error converting serial number %s\n", serial);
9410Sstevel@tonic-gate return 0;
9420Sstevel@tonic-gate }
9430Sstevel@tonic-gate id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno);
9440Sstevel@tonic-gate ASN1_INTEGER_free(sno);
9450Sstevel@tonic-gate if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
9460Sstevel@tonic-gate if(!OCSP_request_add0_id(*req, id)) goto err;
9470Sstevel@tonic-gate return 1;
9480Sstevel@tonic-gate
9490Sstevel@tonic-gate err:
9500Sstevel@tonic-gate BIO_printf(bio_err, "Error Creating OCSP request\n");
9510Sstevel@tonic-gate return 0;
9520Sstevel@tonic-gate }
9530Sstevel@tonic-gate
print_ocsp_summary(BIO * out,OCSP_BASICRESP * bs,OCSP_REQUEST * req,STACK * names,STACK_OF (OCSP_CERTID)* ids,long nsec,long maxage)9540Sstevel@tonic-gate static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
9550Sstevel@tonic-gate STACK *names, STACK_OF(OCSP_CERTID) *ids,
9560Sstevel@tonic-gate long nsec, long maxage)
9570Sstevel@tonic-gate {
9580Sstevel@tonic-gate OCSP_CERTID *id;
9590Sstevel@tonic-gate char *name;
9600Sstevel@tonic-gate int i;
9610Sstevel@tonic-gate
9620Sstevel@tonic-gate int status, reason;
9630Sstevel@tonic-gate
9640Sstevel@tonic-gate ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
9650Sstevel@tonic-gate
9660Sstevel@tonic-gate if (!bs || !req || !sk_num(names) || !sk_OCSP_CERTID_num(ids))
9670Sstevel@tonic-gate return 1;
9680Sstevel@tonic-gate
9690Sstevel@tonic-gate for (i = 0; i < sk_OCSP_CERTID_num(ids); i++)
9700Sstevel@tonic-gate {
9710Sstevel@tonic-gate id = sk_OCSP_CERTID_value(ids, i);
9720Sstevel@tonic-gate name = sk_value(names, i);
9730Sstevel@tonic-gate BIO_printf(out, "%s: ", name);
9740Sstevel@tonic-gate
9750Sstevel@tonic-gate if(!OCSP_resp_find_status(bs, id, &status, &reason,
9760Sstevel@tonic-gate &rev, &thisupd, &nextupd))
9770Sstevel@tonic-gate {
9780Sstevel@tonic-gate BIO_puts(out, "ERROR: No Status found.\n");
9790Sstevel@tonic-gate continue;
9800Sstevel@tonic-gate }
9810Sstevel@tonic-gate
9820Sstevel@tonic-gate /* Check validity: if invalid write to output BIO so we
9830Sstevel@tonic-gate * know which response this refers to.
9840Sstevel@tonic-gate */
9850Sstevel@tonic-gate if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage))
9860Sstevel@tonic-gate {
9870Sstevel@tonic-gate BIO_puts(out, "WARNING: Status times invalid.\n");
9880Sstevel@tonic-gate ERR_print_errors(out);
9890Sstevel@tonic-gate }
9900Sstevel@tonic-gate BIO_printf(out, "%s\n", OCSP_cert_status_str(status));
9910Sstevel@tonic-gate
9920Sstevel@tonic-gate BIO_puts(out, "\tThis Update: ");
9930Sstevel@tonic-gate ASN1_GENERALIZEDTIME_print(out, thisupd);
9940Sstevel@tonic-gate BIO_puts(out, "\n");
9950Sstevel@tonic-gate
9960Sstevel@tonic-gate if(nextupd)
9970Sstevel@tonic-gate {
9980Sstevel@tonic-gate BIO_puts(out, "\tNext Update: ");
9990Sstevel@tonic-gate ASN1_GENERALIZEDTIME_print(out, nextupd);
10000Sstevel@tonic-gate BIO_puts(out, "\n");
10010Sstevel@tonic-gate }
10020Sstevel@tonic-gate
10030Sstevel@tonic-gate if (status != V_OCSP_CERTSTATUS_REVOKED)
10040Sstevel@tonic-gate continue;
10050Sstevel@tonic-gate
10060Sstevel@tonic-gate if (reason != -1)
10070Sstevel@tonic-gate BIO_printf(out, "\tReason: %s\n",
10080Sstevel@tonic-gate OCSP_crl_reason_str(reason));
10090Sstevel@tonic-gate
10100Sstevel@tonic-gate BIO_puts(out, "\tRevocation Time: ");
10110Sstevel@tonic-gate ASN1_GENERALIZEDTIME_print(out, rev);
10120Sstevel@tonic-gate BIO_puts(out, "\n");
10130Sstevel@tonic-gate }
10140Sstevel@tonic-gate
10150Sstevel@tonic-gate return 1;
10160Sstevel@tonic-gate }
10170Sstevel@tonic-gate
10180Sstevel@tonic-gate
make_ocsp_response(OCSP_RESPONSE ** resp,OCSP_REQUEST * req,CA_DB * db,X509 * ca,X509 * rcert,EVP_PKEY * rkey,STACK_OF (X509)* rother,unsigned long flags,int nmin,int ndays)10190Sstevel@tonic-gate static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
10200Sstevel@tonic-gate X509 *ca, X509 *rcert, EVP_PKEY *rkey,
10210Sstevel@tonic-gate STACK_OF(X509) *rother, unsigned long flags,
10220Sstevel@tonic-gate int nmin, int ndays)
10230Sstevel@tonic-gate {
10240Sstevel@tonic-gate ASN1_TIME *thisupd = NULL, *nextupd = NULL;
10250Sstevel@tonic-gate OCSP_CERTID *cid, *ca_id = NULL;
10260Sstevel@tonic-gate OCSP_BASICRESP *bs = NULL;
10270Sstevel@tonic-gate int i, id_count, ret = 1;
10280Sstevel@tonic-gate
10290Sstevel@tonic-gate
10300Sstevel@tonic-gate id_count = OCSP_request_onereq_count(req);
10310Sstevel@tonic-gate
10320Sstevel@tonic-gate if (id_count <= 0)
10330Sstevel@tonic-gate {
10340Sstevel@tonic-gate *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
10350Sstevel@tonic-gate goto end;
10360Sstevel@tonic-gate }
10370Sstevel@tonic-gate
10380Sstevel@tonic-gate ca_id = OCSP_cert_to_id(EVP_sha1(), NULL, ca);
10390Sstevel@tonic-gate
10400Sstevel@tonic-gate bs = OCSP_BASICRESP_new();
10410Sstevel@tonic-gate thisupd = X509_gmtime_adj(NULL, 0);
10420Sstevel@tonic-gate if (ndays != -1)
10430Sstevel@tonic-gate nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24 );
10440Sstevel@tonic-gate
10450Sstevel@tonic-gate /* Examine each certificate id in the request */
10460Sstevel@tonic-gate for (i = 0; i < id_count; i++)
10470Sstevel@tonic-gate {
10480Sstevel@tonic-gate OCSP_ONEREQ *one;
10490Sstevel@tonic-gate ASN1_INTEGER *serial;
10500Sstevel@tonic-gate char **inf;
10510Sstevel@tonic-gate one = OCSP_request_onereq_get0(req, i);
10520Sstevel@tonic-gate cid = OCSP_onereq_get0_id(one);
10530Sstevel@tonic-gate /* Is this request about our CA? */
10540Sstevel@tonic-gate if (OCSP_id_issuer_cmp(ca_id, cid))
10550Sstevel@tonic-gate {
10560Sstevel@tonic-gate OCSP_basic_add1_status(bs, cid,
10570Sstevel@tonic-gate V_OCSP_CERTSTATUS_UNKNOWN,
10580Sstevel@tonic-gate 0, NULL,
10590Sstevel@tonic-gate thisupd, nextupd);
10600Sstevel@tonic-gate continue;
10610Sstevel@tonic-gate }
10620Sstevel@tonic-gate OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
10630Sstevel@tonic-gate inf = lookup_serial(db, serial);
10640Sstevel@tonic-gate if (!inf)
10650Sstevel@tonic-gate OCSP_basic_add1_status(bs, cid,
10660Sstevel@tonic-gate V_OCSP_CERTSTATUS_UNKNOWN,
10670Sstevel@tonic-gate 0, NULL,
10680Sstevel@tonic-gate thisupd, nextupd);
10690Sstevel@tonic-gate else if (inf[DB_type][0] == DB_TYPE_VAL)
10700Sstevel@tonic-gate OCSP_basic_add1_status(bs, cid,
10710Sstevel@tonic-gate V_OCSP_CERTSTATUS_GOOD,
10720Sstevel@tonic-gate 0, NULL,
10730Sstevel@tonic-gate thisupd, nextupd);
10740Sstevel@tonic-gate else if (inf[DB_type][0] == DB_TYPE_REV)
10750Sstevel@tonic-gate {
10760Sstevel@tonic-gate ASN1_OBJECT *inst = NULL;
10770Sstevel@tonic-gate ASN1_TIME *revtm = NULL;
10780Sstevel@tonic-gate ASN1_GENERALIZEDTIME *invtm = NULL;
10790Sstevel@tonic-gate OCSP_SINGLERESP *single;
10800Sstevel@tonic-gate int reason = -1;
10810Sstevel@tonic-gate unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]);
10820Sstevel@tonic-gate single = OCSP_basic_add1_status(bs, cid,
10830Sstevel@tonic-gate V_OCSP_CERTSTATUS_REVOKED,
10840Sstevel@tonic-gate reason, revtm,
10850Sstevel@tonic-gate thisupd, nextupd);
10860Sstevel@tonic-gate if (invtm)
10870Sstevel@tonic-gate OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0);
10880Sstevel@tonic-gate else if (inst)
10890Sstevel@tonic-gate OCSP_SINGLERESP_add1_ext_i2d(single, NID_hold_instruction_code, inst, 0, 0);
10900Sstevel@tonic-gate ASN1_OBJECT_free(inst);
10910Sstevel@tonic-gate ASN1_TIME_free(revtm);
10920Sstevel@tonic-gate ASN1_GENERALIZEDTIME_free(invtm);
10930Sstevel@tonic-gate }
10940Sstevel@tonic-gate }
10950Sstevel@tonic-gate
10960Sstevel@tonic-gate OCSP_copy_nonce(bs, req);
10970Sstevel@tonic-gate
10980Sstevel@tonic-gate OCSP_basic_sign(bs, rcert, rkey, EVP_sha1(), rother, flags);
10990Sstevel@tonic-gate
11000Sstevel@tonic-gate *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
11010Sstevel@tonic-gate
11020Sstevel@tonic-gate end:
11030Sstevel@tonic-gate ASN1_TIME_free(thisupd);
11040Sstevel@tonic-gate ASN1_TIME_free(nextupd);
11050Sstevel@tonic-gate OCSP_CERTID_free(ca_id);
11060Sstevel@tonic-gate OCSP_BASICRESP_free(bs);
11070Sstevel@tonic-gate return ret;
11080Sstevel@tonic-gate
11090Sstevel@tonic-gate }
11100Sstevel@tonic-gate
lookup_serial(CA_DB * db,ASN1_INTEGER * ser)11110Sstevel@tonic-gate static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser)
11120Sstevel@tonic-gate {
11130Sstevel@tonic-gate int i;
11140Sstevel@tonic-gate BIGNUM *bn = NULL;
11150Sstevel@tonic-gate char *itmp, *row[DB_NUMBER],**rrow;
11160Sstevel@tonic-gate for (i = 0; i < DB_NUMBER; i++) row[i] = NULL;
11170Sstevel@tonic-gate bn = ASN1_INTEGER_to_BN(ser,NULL);
11180Sstevel@tonic-gate if (BN_is_zero(bn))
11190Sstevel@tonic-gate itmp = BUF_strdup("00");
11200Sstevel@tonic-gate else
11210Sstevel@tonic-gate itmp = BN_bn2hex(bn);
11220Sstevel@tonic-gate row[DB_serial] = itmp;
11230Sstevel@tonic-gate BN_free(bn);
11240Sstevel@tonic-gate rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
11250Sstevel@tonic-gate OPENSSL_free(itmp);
11260Sstevel@tonic-gate return rrow;
11270Sstevel@tonic-gate }
11280Sstevel@tonic-gate
11290Sstevel@tonic-gate /* Quick and dirty OCSP server: read in and parse input request */
11300Sstevel@tonic-gate
init_responder(char * port)11310Sstevel@tonic-gate static BIO *init_responder(char *port)
11320Sstevel@tonic-gate {
11330Sstevel@tonic-gate BIO *acbio = NULL, *bufbio = NULL;
11340Sstevel@tonic-gate bufbio = BIO_new(BIO_f_buffer());
11350Sstevel@tonic-gate if (!bufbio)
11360Sstevel@tonic-gate goto err;
11370Sstevel@tonic-gate #ifndef OPENSSL_NO_SOCK
11380Sstevel@tonic-gate acbio = BIO_new_accept(port);
11390Sstevel@tonic-gate #else
11400Sstevel@tonic-gate BIO_printf(bio_err, "Error setting up accept BIO - sockets not supported.\n");
11410Sstevel@tonic-gate #endif
11420Sstevel@tonic-gate if (!acbio)
11430Sstevel@tonic-gate goto err;
11440Sstevel@tonic-gate BIO_set_accept_bios(acbio, bufbio);
11450Sstevel@tonic-gate bufbio = NULL;
11460Sstevel@tonic-gate
11470Sstevel@tonic-gate if (BIO_do_accept(acbio) <= 0)
11480Sstevel@tonic-gate {
11490Sstevel@tonic-gate BIO_printf(bio_err, "Error setting up accept BIO\n");
11500Sstevel@tonic-gate ERR_print_errors(bio_err);
11510Sstevel@tonic-gate goto err;
11520Sstevel@tonic-gate }
11530Sstevel@tonic-gate
11540Sstevel@tonic-gate return acbio;
11550Sstevel@tonic-gate
11560Sstevel@tonic-gate err:
11570Sstevel@tonic-gate BIO_free_all(acbio);
11580Sstevel@tonic-gate BIO_free(bufbio);
11590Sstevel@tonic-gate return NULL;
11600Sstevel@tonic-gate }
11610Sstevel@tonic-gate
do_responder(OCSP_REQUEST ** preq,BIO ** pcbio,BIO * acbio,char * port)11620Sstevel@tonic-gate static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port)
11630Sstevel@tonic-gate {
11640Sstevel@tonic-gate int have_post = 0, len;
11650Sstevel@tonic-gate OCSP_REQUEST *req = NULL;
11660Sstevel@tonic-gate char inbuf[1024];
11670Sstevel@tonic-gate BIO *cbio = NULL;
11680Sstevel@tonic-gate
11690Sstevel@tonic-gate if (BIO_do_accept(acbio) <= 0)
11700Sstevel@tonic-gate {
11710Sstevel@tonic-gate BIO_printf(bio_err, "Error accepting connection\n");
11720Sstevel@tonic-gate ERR_print_errors(bio_err);
11730Sstevel@tonic-gate return 0;
11740Sstevel@tonic-gate }
11750Sstevel@tonic-gate
11760Sstevel@tonic-gate cbio = BIO_pop(acbio);
11770Sstevel@tonic-gate *pcbio = cbio;
11780Sstevel@tonic-gate
11790Sstevel@tonic-gate for(;;)
11800Sstevel@tonic-gate {
11810Sstevel@tonic-gate len = BIO_gets(cbio, inbuf, sizeof inbuf);
11820Sstevel@tonic-gate if (len <= 0)
11830Sstevel@tonic-gate return 1;
11840Sstevel@tonic-gate /* Look for "POST" signalling start of query */
11850Sstevel@tonic-gate if (!have_post)
11860Sstevel@tonic-gate {
11870Sstevel@tonic-gate if(strncmp(inbuf, "POST", 4))
11880Sstevel@tonic-gate {
11890Sstevel@tonic-gate BIO_printf(bio_err, "Invalid request\n");
11900Sstevel@tonic-gate return 1;
11910Sstevel@tonic-gate }
11920Sstevel@tonic-gate have_post = 1;
11930Sstevel@tonic-gate }
11940Sstevel@tonic-gate /* Look for end of headers */
11950Sstevel@tonic-gate if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
11960Sstevel@tonic-gate break;
11970Sstevel@tonic-gate }
11980Sstevel@tonic-gate
11990Sstevel@tonic-gate /* Try to read OCSP request */
12000Sstevel@tonic-gate
12010Sstevel@tonic-gate req = d2i_OCSP_REQUEST_bio(cbio, NULL);
12020Sstevel@tonic-gate
12030Sstevel@tonic-gate if (!req)
12040Sstevel@tonic-gate {
12050Sstevel@tonic-gate BIO_printf(bio_err, "Error parsing OCSP request\n");
12060Sstevel@tonic-gate ERR_print_errors(bio_err);
12070Sstevel@tonic-gate }
12080Sstevel@tonic-gate
12090Sstevel@tonic-gate *preq = req;
12100Sstevel@tonic-gate
12110Sstevel@tonic-gate return 1;
12120Sstevel@tonic-gate
12130Sstevel@tonic-gate }
12140Sstevel@tonic-gate
send_ocsp_response(BIO * cbio,OCSP_RESPONSE * resp)12150Sstevel@tonic-gate static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
12160Sstevel@tonic-gate {
12170Sstevel@tonic-gate char http_resp[] =
12180Sstevel@tonic-gate "HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n"
12190Sstevel@tonic-gate "Content-Length: %d\r\n\r\n";
12200Sstevel@tonic-gate if (!cbio)
12210Sstevel@tonic-gate return 0;
12220Sstevel@tonic-gate BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL));
12230Sstevel@tonic-gate i2d_OCSP_RESPONSE_bio(cbio, resp);
12240Sstevel@tonic-gate BIO_flush(cbio);
12250Sstevel@tonic-gate return 1;
12260Sstevel@tonic-gate }
12270Sstevel@tonic-gate
12280Sstevel@tonic-gate #endif
1229