15c87c606SMark Murray /* ocsp.c */ 2db522d3aSSimon L. B. Nielsen /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 35c87c606SMark Murray * project 2000. 45c87c606SMark Murray */ 55c87c606SMark Murray /* ==================================================================== 65c87c606SMark Murray * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 75c87c606SMark Murray * 85c87c606SMark Murray * Redistribution and use in source and binary forms, with or without 95c87c606SMark Murray * modification, are permitted provided that the following conditions 105c87c606SMark Murray * are met: 115c87c606SMark Murray * 125c87c606SMark Murray * 1. Redistributions of source code must retain the above copyright 135c87c606SMark Murray * notice, this list of conditions and the following disclaimer. 145c87c606SMark Murray * 155c87c606SMark Murray * 2. Redistributions in binary form must reproduce the above copyright 165c87c606SMark Murray * notice, this list of conditions and the following disclaimer in 175c87c606SMark Murray * the documentation and/or other materials provided with the 185c87c606SMark Murray * distribution. 195c87c606SMark Murray * 205c87c606SMark Murray * 3. All advertising materials mentioning features or use of this 215c87c606SMark Murray * software must display the following acknowledgment: 225c87c606SMark Murray * "This product includes software developed by the OpenSSL Project 235c87c606SMark Murray * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 245c87c606SMark Murray * 255c87c606SMark Murray * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 265c87c606SMark Murray * endorse or promote products derived from this software without 275c87c606SMark Murray * prior written permission. For written permission, please contact 285c87c606SMark Murray * licensing@OpenSSL.org. 295c87c606SMark Murray * 305c87c606SMark Murray * 5. Products derived from this software may not be called "OpenSSL" 315c87c606SMark Murray * nor may "OpenSSL" appear in their names without prior written 325c87c606SMark Murray * permission of the OpenSSL Project. 335c87c606SMark Murray * 345c87c606SMark Murray * 6. Redistributions of any form whatsoever must retain the following 355c87c606SMark Murray * acknowledgment: 365c87c606SMark Murray * "This product includes software developed by the OpenSSL Project 375c87c606SMark Murray * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 385c87c606SMark Murray * 395c87c606SMark Murray * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 405c87c606SMark Murray * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 415c87c606SMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 425c87c606SMark Murray * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 435c87c606SMark Murray * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 445c87c606SMark Murray * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 455c87c606SMark Murray * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 465c87c606SMark Murray * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 475c87c606SMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 485c87c606SMark Murray * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 495c87c606SMark Murray * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 505c87c606SMark Murray * OF THE POSSIBILITY OF SUCH DAMAGE. 515c87c606SMark Murray * ==================================================================== 525c87c606SMark Murray * 535c87c606SMark Murray * This product includes cryptographic software written by Eric Young 545c87c606SMark Murray * (eay@cryptsoft.com). This product includes software written by Tim 555c87c606SMark Murray * Hudson (tjh@cryptsoft.com). 565c87c606SMark Murray * 575c87c606SMark Murray */ 58fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_OCSP 59db522d3aSSimon L. B. Nielsen #define USE_SOCKETS 605c87c606SMark Murray #include <stdio.h> 61db522d3aSSimon L. B. Nielsen #include <stdlib.h> 625c87c606SMark Murray #include <string.h> 63db522d3aSSimon L. B. Nielsen #include "apps.h" /* needs to be included before the openssl headers! */ 64db522d3aSSimon L. B. Nielsen #include <openssl/e_os2.h> 655c87c606SMark Murray #include <openssl/ssl.h> 66db522d3aSSimon L. B. Nielsen #include <openssl/err.h> 675c87c606SMark Murray 685c87c606SMark Murray /* Maximum leeway in validity period: default 5 minutes */ 695c87c606SMark Murray #define MAX_VALIDITY_PERIOD (5 * 60) 705c87c606SMark Murray 715c87c606SMark Murray static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer, 725c87c606SMark Murray STACK_OF(OCSP_CERTID) *ids); 735c87c606SMark Murray static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer, 745c87c606SMark Murray STACK_OF(OCSP_CERTID) *ids); 755c87c606SMark Murray static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, 765c87c606SMark Murray STACK *names, STACK_OF(OCSP_CERTID) *ids, 775c87c606SMark Murray long nsec, long maxage); 785c87c606SMark Murray 79ced566fdSJacques Vidrine static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db, 805c87c606SMark Murray X509 *ca, X509 *rcert, EVP_PKEY *rkey, 815c87c606SMark Murray STACK_OF(X509) *rother, unsigned long flags, 825c87c606SMark Murray int nmin, int ndays); 835c87c606SMark Murray 84ced566fdSJacques Vidrine static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser); 855c87c606SMark Murray static BIO *init_responder(char *port); 865c87c606SMark Murray static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port); 875c87c606SMark Murray static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp); 88db522d3aSSimon L. B. Nielsen static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path, 89db522d3aSSimon L. B. Nielsen OCSP_REQUEST *req, int req_timeout); 905c87c606SMark Murray 915c87c606SMark Murray #undef PROG 925c87c606SMark Murray #define PROG ocsp_main 935c87c606SMark Murray 945c87c606SMark Murray int MAIN(int, char **); 955c87c606SMark Murray 965c87c606SMark Murray int MAIN(int argc, char **argv) 975c87c606SMark Murray { 985c87c606SMark Murray ENGINE *e = NULL; 995c87c606SMark Murray char **args; 1005c87c606SMark Murray char *host = NULL, *port = NULL, *path = "/"; 1015c87c606SMark Murray char *reqin = NULL, *respin = NULL; 1025c87c606SMark Murray char *reqout = NULL, *respout = NULL; 1035c87c606SMark Murray char *signfile = NULL, *keyfile = NULL; 1045c87c606SMark Murray char *rsignfile = NULL, *rkeyfile = NULL; 1055c87c606SMark Murray char *outfile = NULL; 1065c87c606SMark Murray int add_nonce = 1, noverify = 0, use_ssl = -1; 1075c87c606SMark Murray OCSP_REQUEST *req = NULL; 1085c87c606SMark Murray OCSP_RESPONSE *resp = NULL; 1095c87c606SMark Murray OCSP_BASICRESP *bs = NULL; 1105c87c606SMark Murray X509 *issuer = NULL, *cert = NULL; 1115c87c606SMark Murray X509 *signer = NULL, *rsigner = NULL; 1125c87c606SMark Murray EVP_PKEY *key = NULL, *rkey = NULL; 1135c87c606SMark Murray BIO *acbio = NULL, *cbio = NULL; 1145c87c606SMark Murray BIO *derbio = NULL; 1155c87c606SMark Murray BIO *out = NULL; 116db522d3aSSimon L. B. Nielsen int req_timeout = -1; 1175c87c606SMark Murray int req_text = 0, resp_text = 0; 1185c87c606SMark Murray long nsec = MAX_VALIDITY_PERIOD, maxage = -1; 1195c87c606SMark Murray char *CAfile = NULL, *CApath = NULL; 1205c87c606SMark Murray X509_STORE *store = NULL; 1215c87c606SMark Murray STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL; 1225c87c606SMark Murray char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL; 1235c87c606SMark Murray unsigned long sign_flags = 0, verify_flags = 0, rflags = 0; 1245c87c606SMark Murray int ret = 1; 1255c87c606SMark Murray int accept_count = -1; 1265c87c606SMark Murray int badarg = 0; 1275c87c606SMark Murray int i; 12850ef0093SJacques Vidrine int ignore_err = 0; 1295c87c606SMark Murray STACK *reqnames = NULL; 1305c87c606SMark Murray STACK_OF(OCSP_CERTID) *ids = NULL; 1315c87c606SMark Murray 1325c87c606SMark Murray X509 *rca_cert = NULL; 1335c87c606SMark Murray char *ridx_filename = NULL; 1345c87c606SMark Murray char *rca_filename = NULL; 135ced566fdSJacques Vidrine CA_DB *rdb = NULL; 1365c87c606SMark Murray int nmin = 0, ndays = -1; 1375c87c606SMark Murray 1385c87c606SMark Murray if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 1395c87c606SMark Murray 1405c87c606SMark Murray if (!load_config(bio_err, NULL)) 1415c87c606SMark Murray goto end; 1425c87c606SMark Murray SSL_load_error_strings(); 1435471f83eSSimon L. B. Nielsen OpenSSL_add_ssl_algorithms(); 1445c87c606SMark Murray args = argv + 1; 1455c87c606SMark Murray reqnames = sk_new_null(); 1465c87c606SMark Murray ids = sk_OCSP_CERTID_new_null(); 1475c87c606SMark Murray while (!badarg && *args && *args[0] == '-') 1485c87c606SMark Murray { 1495c87c606SMark Murray if (!strcmp(*args, "-out")) 1505c87c606SMark Murray { 1515c87c606SMark Murray if (args[1]) 1525c87c606SMark Murray { 1535c87c606SMark Murray args++; 1545c87c606SMark Murray outfile = *args; 1555c87c606SMark Murray } 1565c87c606SMark Murray else badarg = 1; 1575c87c606SMark Murray } 158db522d3aSSimon L. B. Nielsen else if (!strcmp(*args, "-timeout")) 159db522d3aSSimon L. B. Nielsen { 160db522d3aSSimon L. B. Nielsen if (args[1]) 161db522d3aSSimon L. B. Nielsen { 162db522d3aSSimon L. B. Nielsen args++; 163db522d3aSSimon L. B. Nielsen req_timeout = atol(*args); 164db522d3aSSimon L. B. Nielsen if (req_timeout < 0) 165db522d3aSSimon L. B. Nielsen { 166db522d3aSSimon L. B. Nielsen BIO_printf(bio_err, 167db522d3aSSimon L. B. Nielsen "Illegal timeout value %s\n", 168db522d3aSSimon L. B. Nielsen *args); 169db522d3aSSimon L. B. Nielsen badarg = 1; 170db522d3aSSimon L. B. Nielsen } 171db522d3aSSimon L. B. Nielsen } 172db522d3aSSimon L. B. Nielsen else badarg = 1; 173db522d3aSSimon L. B. Nielsen } 1745c87c606SMark Murray else if (!strcmp(*args, "-url")) 1755c87c606SMark Murray { 1765c87c606SMark Murray if (args[1]) 1775c87c606SMark Murray { 1785c87c606SMark Murray args++; 1795c87c606SMark Murray if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl)) 1805c87c606SMark Murray { 1815c87c606SMark Murray BIO_printf(bio_err, "Error parsing URL\n"); 1825c87c606SMark Murray badarg = 1; 1835c87c606SMark Murray } 1845c87c606SMark Murray } 1855c87c606SMark Murray else badarg = 1; 1865c87c606SMark Murray } 1875c87c606SMark Murray else if (!strcmp(*args, "-host")) 1885c87c606SMark Murray { 1895c87c606SMark Murray if (args[1]) 1905c87c606SMark Murray { 1915c87c606SMark Murray args++; 1925c87c606SMark Murray host = *args; 1935c87c606SMark Murray } 1945c87c606SMark Murray else badarg = 1; 1955c87c606SMark Murray } 1965c87c606SMark Murray else if (!strcmp(*args, "-port")) 1975c87c606SMark Murray { 1985c87c606SMark Murray if (args[1]) 1995c87c606SMark Murray { 2005c87c606SMark Murray args++; 2015c87c606SMark Murray port = *args; 2025c87c606SMark Murray } 2035c87c606SMark Murray else badarg = 1; 2045c87c606SMark Murray } 20550ef0093SJacques Vidrine else if (!strcmp(*args, "-ignore_err")) 20650ef0093SJacques Vidrine ignore_err = 1; 2075c87c606SMark Murray else if (!strcmp(*args, "-noverify")) 2085c87c606SMark Murray noverify = 1; 2095c87c606SMark Murray else if (!strcmp(*args, "-nonce")) 2105c87c606SMark Murray add_nonce = 2; 2115c87c606SMark Murray else if (!strcmp(*args, "-no_nonce")) 2125c87c606SMark Murray add_nonce = 0; 2135c87c606SMark Murray else if (!strcmp(*args, "-resp_no_certs")) 2145c87c606SMark Murray rflags |= OCSP_NOCERTS; 2155c87c606SMark Murray else if (!strcmp(*args, "-resp_key_id")) 2165c87c606SMark Murray rflags |= OCSP_RESPID_KEY; 2175c87c606SMark Murray else if (!strcmp(*args, "-no_certs")) 2185c87c606SMark Murray sign_flags |= OCSP_NOCERTS; 2195c87c606SMark Murray else if (!strcmp(*args, "-no_signature_verify")) 2205c87c606SMark Murray verify_flags |= OCSP_NOSIGS; 2215c87c606SMark Murray else if (!strcmp(*args, "-no_cert_verify")) 2225c87c606SMark Murray verify_flags |= OCSP_NOVERIFY; 2235c87c606SMark Murray else if (!strcmp(*args, "-no_chain")) 2245c87c606SMark Murray verify_flags |= OCSP_NOCHAIN; 2255c87c606SMark Murray else if (!strcmp(*args, "-no_cert_checks")) 2265c87c606SMark Murray verify_flags |= OCSP_NOCHECKS; 2275c87c606SMark Murray else if (!strcmp(*args, "-no_explicit")) 2285c87c606SMark Murray verify_flags |= OCSP_NOEXPLICIT; 2295c87c606SMark Murray else if (!strcmp(*args, "-trust_other")) 2305c87c606SMark Murray verify_flags |= OCSP_TRUSTOTHER; 2315c87c606SMark Murray else if (!strcmp(*args, "-no_intern")) 2325c87c606SMark Murray verify_flags |= OCSP_NOINTERN; 2335c87c606SMark Murray else if (!strcmp(*args, "-text")) 2345c87c606SMark Murray { 2355c87c606SMark Murray req_text = 1; 2365c87c606SMark Murray resp_text = 1; 2375c87c606SMark Murray } 2385c87c606SMark Murray else if (!strcmp(*args, "-req_text")) 2395c87c606SMark Murray req_text = 1; 2405c87c606SMark Murray else if (!strcmp(*args, "-resp_text")) 2415c87c606SMark Murray resp_text = 1; 2425c87c606SMark Murray else if (!strcmp(*args, "-reqin")) 2435c87c606SMark Murray { 2445c87c606SMark Murray if (args[1]) 2455c87c606SMark Murray { 2465c87c606SMark Murray args++; 2475c87c606SMark Murray reqin = *args; 2485c87c606SMark Murray } 2495c87c606SMark Murray else badarg = 1; 2505c87c606SMark Murray } 2515c87c606SMark Murray else if (!strcmp(*args, "-respin")) 2525c87c606SMark Murray { 2535c87c606SMark Murray if (args[1]) 2545c87c606SMark Murray { 2555c87c606SMark Murray args++; 2565c87c606SMark Murray respin = *args; 2575c87c606SMark Murray } 2585c87c606SMark Murray else badarg = 1; 2595c87c606SMark Murray } 2605c87c606SMark Murray else if (!strcmp(*args, "-signer")) 2615c87c606SMark Murray { 2625c87c606SMark Murray if (args[1]) 2635c87c606SMark Murray { 2645c87c606SMark Murray args++; 2655c87c606SMark Murray signfile = *args; 2665c87c606SMark Murray } 2675c87c606SMark Murray else badarg = 1; 2685c87c606SMark Murray } 2695c87c606SMark Murray else if (!strcmp (*args, "-VAfile")) 2705c87c606SMark Murray { 2715c87c606SMark Murray if (args[1]) 2725c87c606SMark Murray { 2735c87c606SMark Murray args++; 2745c87c606SMark Murray verify_certfile = *args; 2755c87c606SMark Murray verify_flags |= OCSP_TRUSTOTHER; 2765c87c606SMark Murray } 2775c87c606SMark Murray else badarg = 1; 2785c87c606SMark Murray } 2795c87c606SMark Murray else if (!strcmp(*args, "-sign_other")) 2805c87c606SMark Murray { 2815c87c606SMark Murray if (args[1]) 2825c87c606SMark Murray { 2835c87c606SMark Murray args++; 2845c87c606SMark Murray sign_certfile = *args; 2855c87c606SMark Murray } 2865c87c606SMark Murray else badarg = 1; 2875c87c606SMark Murray } 2885c87c606SMark Murray else if (!strcmp(*args, "-verify_other")) 2895c87c606SMark Murray { 2905c87c606SMark Murray if (args[1]) 2915c87c606SMark Murray { 2925c87c606SMark Murray args++; 2935c87c606SMark Murray verify_certfile = *args; 2945c87c606SMark Murray } 2955c87c606SMark Murray else badarg = 1; 2965c87c606SMark Murray } 2975c87c606SMark Murray else if (!strcmp (*args, "-CAfile")) 2985c87c606SMark Murray { 2995c87c606SMark Murray if (args[1]) 3005c87c606SMark Murray { 3015c87c606SMark Murray args++; 3025c87c606SMark Murray CAfile = *args; 3035c87c606SMark Murray } 3045c87c606SMark Murray else badarg = 1; 3055c87c606SMark Murray } 3065c87c606SMark Murray else if (!strcmp (*args, "-CApath")) 3075c87c606SMark Murray { 3085c87c606SMark Murray if (args[1]) 3095c87c606SMark Murray { 3105c87c606SMark Murray args++; 3115c87c606SMark Murray CApath = *args; 3125c87c606SMark Murray } 3135c87c606SMark Murray else badarg = 1; 3145c87c606SMark Murray } 3155c87c606SMark Murray else if (!strcmp (*args, "-validity_period")) 3165c87c606SMark Murray { 3175c87c606SMark Murray if (args[1]) 3185c87c606SMark Murray { 3195c87c606SMark Murray args++; 3205c87c606SMark Murray nsec = atol(*args); 3215c87c606SMark Murray if (nsec < 0) 3225c87c606SMark Murray { 3235c87c606SMark Murray BIO_printf(bio_err, 3245c87c606SMark Murray "Illegal validity period %s\n", 3255c87c606SMark Murray *args); 3265c87c606SMark Murray badarg = 1; 3275c87c606SMark Murray } 3285c87c606SMark Murray } 3295c87c606SMark Murray else badarg = 1; 3305c87c606SMark Murray } 3315c87c606SMark Murray else if (!strcmp (*args, "-status_age")) 3325c87c606SMark Murray { 3335c87c606SMark Murray if (args[1]) 3345c87c606SMark Murray { 3355c87c606SMark Murray args++; 3365c87c606SMark Murray maxage = atol(*args); 3375c87c606SMark Murray if (maxage < 0) 3385c87c606SMark Murray { 3395c87c606SMark Murray BIO_printf(bio_err, 3405c87c606SMark Murray "Illegal validity age %s\n", 3415c87c606SMark Murray *args); 3425c87c606SMark Murray badarg = 1; 3435c87c606SMark Murray } 3445c87c606SMark Murray } 3455c87c606SMark Murray else badarg = 1; 3465c87c606SMark Murray } 3475c87c606SMark Murray else if (!strcmp(*args, "-signkey")) 3485c87c606SMark Murray { 3495c87c606SMark Murray if (args[1]) 3505c87c606SMark Murray { 3515c87c606SMark Murray args++; 3525c87c606SMark Murray keyfile = *args; 3535c87c606SMark Murray } 3545c87c606SMark Murray else badarg = 1; 3555c87c606SMark Murray } 3565c87c606SMark Murray else if (!strcmp(*args, "-reqout")) 3575c87c606SMark Murray { 3585c87c606SMark Murray if (args[1]) 3595c87c606SMark Murray { 3605c87c606SMark Murray args++; 3615c87c606SMark Murray reqout = *args; 3625c87c606SMark Murray } 3635c87c606SMark Murray else badarg = 1; 3645c87c606SMark Murray } 3655c87c606SMark Murray else if (!strcmp(*args, "-respout")) 3665c87c606SMark Murray { 3675c87c606SMark Murray if (args[1]) 3685c87c606SMark Murray { 3695c87c606SMark Murray args++; 3705c87c606SMark Murray respout = *args; 3715c87c606SMark Murray } 3725c87c606SMark Murray else badarg = 1; 3735c87c606SMark Murray } 3745c87c606SMark Murray else if (!strcmp(*args, "-path")) 3755c87c606SMark Murray { 3765c87c606SMark Murray if (args[1]) 3775c87c606SMark Murray { 3785c87c606SMark Murray args++; 3795c87c606SMark Murray path = *args; 3805c87c606SMark Murray } 3815c87c606SMark Murray else badarg = 1; 3825c87c606SMark Murray } 3835c87c606SMark Murray else if (!strcmp(*args, "-issuer")) 3845c87c606SMark Murray { 3855c87c606SMark Murray if (args[1]) 3865c87c606SMark Murray { 3875c87c606SMark Murray args++; 3885c87c606SMark Murray X509_free(issuer); 3895c87c606SMark Murray issuer = load_cert(bio_err, *args, FORMAT_PEM, 3905c87c606SMark Murray NULL, e, "issuer certificate"); 3915c87c606SMark Murray if(!issuer) goto end; 3925c87c606SMark Murray } 3935c87c606SMark Murray else badarg = 1; 3945c87c606SMark Murray } 3955c87c606SMark Murray else if (!strcmp (*args, "-cert")) 3965c87c606SMark Murray { 3975c87c606SMark Murray if (args[1]) 3985c87c606SMark Murray { 3995c87c606SMark Murray args++; 4005c87c606SMark Murray X509_free(cert); 4015c87c606SMark Murray cert = load_cert(bio_err, *args, FORMAT_PEM, 4025c87c606SMark Murray NULL, e, "certificate"); 4035c87c606SMark Murray if(!cert) goto end; 4045c87c606SMark Murray if(!add_ocsp_cert(&req, cert, issuer, ids)) 4055c87c606SMark Murray goto end; 4065c87c606SMark Murray if(!sk_push(reqnames, *args)) 4075c87c606SMark Murray goto end; 4085c87c606SMark Murray } 4095c87c606SMark Murray else badarg = 1; 4105c87c606SMark Murray } 4115c87c606SMark Murray else if (!strcmp(*args, "-serial")) 4125c87c606SMark Murray { 4135c87c606SMark Murray if (args[1]) 4145c87c606SMark Murray { 4155c87c606SMark Murray args++; 4165c87c606SMark Murray if(!add_ocsp_serial(&req, *args, issuer, ids)) 4175c87c606SMark Murray goto end; 4185c87c606SMark Murray if(!sk_push(reqnames, *args)) 4195c87c606SMark Murray goto end; 4205c87c606SMark Murray } 4215c87c606SMark Murray else badarg = 1; 4225c87c606SMark Murray } 4235c87c606SMark Murray else if (!strcmp(*args, "-index")) 4245c87c606SMark Murray { 4255c87c606SMark Murray if (args[1]) 4265c87c606SMark Murray { 4275c87c606SMark Murray args++; 4285c87c606SMark Murray ridx_filename = *args; 4295c87c606SMark Murray } 4305c87c606SMark Murray else badarg = 1; 4315c87c606SMark Murray } 4325c87c606SMark Murray else if (!strcmp(*args, "-CA")) 4335c87c606SMark Murray { 4345c87c606SMark Murray if (args[1]) 4355c87c606SMark Murray { 4365c87c606SMark Murray args++; 4375c87c606SMark Murray rca_filename = *args; 4385c87c606SMark Murray } 4395c87c606SMark Murray else badarg = 1; 4405c87c606SMark Murray } 4415c87c606SMark Murray else if (!strcmp (*args, "-nmin")) 4425c87c606SMark Murray { 4435c87c606SMark Murray if (args[1]) 4445c87c606SMark Murray { 4455c87c606SMark Murray args++; 4465c87c606SMark Murray nmin = atol(*args); 4475c87c606SMark Murray if (nmin < 0) 4485c87c606SMark Murray { 4495c87c606SMark Murray BIO_printf(bio_err, 4505c87c606SMark Murray "Illegal update period %s\n", 4515c87c606SMark Murray *args); 4525c87c606SMark Murray badarg = 1; 4535c87c606SMark Murray } 4545c87c606SMark Murray } 4555c87c606SMark Murray if (ndays == -1) 4565c87c606SMark Murray ndays = 0; 4575c87c606SMark Murray else badarg = 1; 4585c87c606SMark Murray } 4595c87c606SMark Murray else if (!strcmp (*args, "-nrequest")) 4605c87c606SMark Murray { 4615c87c606SMark Murray if (args[1]) 4625c87c606SMark Murray { 4635c87c606SMark Murray args++; 4645c87c606SMark Murray accept_count = atol(*args); 4655c87c606SMark Murray if (accept_count < 0) 4665c87c606SMark Murray { 4675c87c606SMark Murray BIO_printf(bio_err, 4685c87c606SMark Murray "Illegal accept count %s\n", 4695c87c606SMark Murray *args); 4705c87c606SMark Murray badarg = 1; 4715c87c606SMark Murray } 4725c87c606SMark Murray } 4735c87c606SMark Murray else badarg = 1; 4745c87c606SMark Murray } 4755c87c606SMark Murray else if (!strcmp (*args, "-ndays")) 4765c87c606SMark Murray { 4775c87c606SMark Murray if (args[1]) 4785c87c606SMark Murray { 4795c87c606SMark Murray args++; 4805c87c606SMark Murray ndays = atol(*args); 4815c87c606SMark Murray if (ndays < 0) 4825c87c606SMark Murray { 4835c87c606SMark Murray BIO_printf(bio_err, 4845c87c606SMark Murray "Illegal update period %s\n", 4855c87c606SMark Murray *args); 4865c87c606SMark Murray badarg = 1; 4875c87c606SMark Murray } 4885c87c606SMark Murray } 4895c87c606SMark Murray else badarg = 1; 4905c87c606SMark Murray } 4915c87c606SMark Murray else if (!strcmp(*args, "-rsigner")) 4925c87c606SMark Murray { 4935c87c606SMark Murray if (args[1]) 4945c87c606SMark Murray { 4955c87c606SMark Murray args++; 4965c87c606SMark Murray rsignfile = *args; 4975c87c606SMark Murray } 4985c87c606SMark Murray else badarg = 1; 4995c87c606SMark Murray } 5005c87c606SMark Murray else if (!strcmp(*args, "-rkey")) 5015c87c606SMark Murray { 5025c87c606SMark Murray if (args[1]) 5035c87c606SMark Murray { 5045c87c606SMark Murray args++; 5055c87c606SMark Murray rkeyfile = *args; 5065c87c606SMark Murray } 5075c87c606SMark Murray else badarg = 1; 5085c87c606SMark Murray } 5095c87c606SMark Murray else if (!strcmp(*args, "-rother")) 5105c87c606SMark Murray { 5115c87c606SMark Murray if (args[1]) 5125c87c606SMark Murray { 5135c87c606SMark Murray args++; 5145c87c606SMark Murray rcertfile = *args; 5155c87c606SMark Murray } 5165c87c606SMark Murray else badarg = 1; 5175c87c606SMark Murray } 5185c87c606SMark Murray else badarg = 1; 5195c87c606SMark Murray args++; 5205c87c606SMark Murray } 5215c87c606SMark Murray 5225c87c606SMark Murray /* Have we anything to do? */ 5235c87c606SMark Murray if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1; 5245c87c606SMark Murray 5255c87c606SMark Murray if (badarg) 5265c87c606SMark Murray { 5275c87c606SMark Murray BIO_printf (bio_err, "OCSP utility\n"); 5285c87c606SMark Murray BIO_printf (bio_err, "Usage ocsp [options]\n"); 5295c87c606SMark Murray BIO_printf (bio_err, "where options are\n"); 5305c87c606SMark Murray BIO_printf (bio_err, "-out file output filename\n"); 5315c87c606SMark Murray BIO_printf (bio_err, "-issuer file issuer certificate\n"); 5325c87c606SMark Murray BIO_printf (bio_err, "-cert file certificate to check\n"); 5335c87c606SMark Murray BIO_printf (bio_err, "-serial n serial number to check\n"); 5345c87c606SMark Murray BIO_printf (bio_err, "-signer file certificate to sign OCSP request with\n"); 5355c87c606SMark Murray BIO_printf (bio_err, "-signkey file private key to sign OCSP request with\n"); 53650ef0093SJacques Vidrine BIO_printf (bio_err, "-sign_other file additional certificates to include in signed request\n"); 5375c87c606SMark Murray BIO_printf (bio_err, "-no_certs don't include any certificates in signed request\n"); 5385c87c606SMark Murray BIO_printf (bio_err, "-req_text print text form of request\n"); 5395c87c606SMark Murray BIO_printf (bio_err, "-resp_text print text form of response\n"); 5405c87c606SMark Murray BIO_printf (bio_err, "-text print text form of request and response\n"); 5415c87c606SMark Murray BIO_printf (bio_err, "-reqout file write DER encoded OCSP request to \"file\"\n"); 5425c87c606SMark Murray BIO_printf (bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n"); 5435c87c606SMark Murray BIO_printf (bio_err, "-reqin file read DER encoded OCSP request from \"file\"\n"); 5445c87c606SMark Murray BIO_printf (bio_err, "-respin file read DER encoded OCSP reponse from \"file\"\n"); 5455c87c606SMark Murray BIO_printf (bio_err, "-nonce add OCSP nonce to request\n"); 5465c87c606SMark Murray BIO_printf (bio_err, "-no_nonce don't add OCSP nonce to request\n"); 5475c87c606SMark Murray BIO_printf (bio_err, "-url URL OCSP responder URL\n"); 5485c87c606SMark Murray BIO_printf (bio_err, "-host host:n send OCSP request to host on port n\n"); 5495c87c606SMark Murray BIO_printf (bio_err, "-path path to use in OCSP request\n"); 5505c87c606SMark Murray BIO_printf (bio_err, "-CApath dir trusted certificates directory\n"); 5515c87c606SMark Murray BIO_printf (bio_err, "-CAfile file trusted certificates file\n"); 5525c87c606SMark Murray BIO_printf (bio_err, "-VAfile file validator certificates file\n"); 5535c87c606SMark Murray BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n"); 5545c87c606SMark Murray BIO_printf (bio_err, "-status_age n maximum status age in seconds\n"); 5555c87c606SMark Murray BIO_printf (bio_err, "-noverify don't verify response at all\n"); 55650ef0093SJacques Vidrine BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n"); 5575c87c606SMark Murray BIO_printf (bio_err, "-trust_other don't verify additional certificates\n"); 5585c87c606SMark Murray BIO_printf (bio_err, "-no_intern don't search certificates contained in response for signer\n"); 55950ef0093SJacques Vidrine BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n"); 5605c87c606SMark Murray BIO_printf (bio_err, "-no_cert_verify don't check signing certificate\n"); 5615c87c606SMark Murray BIO_printf (bio_err, "-no_chain don't chain verify response\n"); 5625c87c606SMark Murray BIO_printf (bio_err, "-no_cert_checks don't do additional checks on signing certificate\n"); 5635c87c606SMark Murray BIO_printf (bio_err, "-port num port to run responder on\n"); 5645c87c606SMark Murray BIO_printf (bio_err, "-index file certificate status index file\n"); 5655c87c606SMark Murray BIO_printf (bio_err, "-CA file CA certificate\n"); 5665c87c606SMark Murray BIO_printf (bio_err, "-rsigner file responder certificate to sign responses with\n"); 5675c87c606SMark Murray BIO_printf (bio_err, "-rkey file responder key to sign responses with\n"); 5685c87c606SMark Murray BIO_printf (bio_err, "-rother file other certificates to include in response\n"); 5695c87c606SMark Murray BIO_printf (bio_err, "-resp_no_certs don't include any certificates in response\n"); 5705c87c606SMark Murray BIO_printf (bio_err, "-nmin n number of minutes before next update\n"); 5715c87c606SMark Murray BIO_printf (bio_err, "-ndays n number of days before next update\n"); 5725c87c606SMark Murray BIO_printf (bio_err, "-resp_key_id identify reponse by signing certificate key ID\n"); 5735c87c606SMark Murray BIO_printf (bio_err, "-nrequest n number of requests to accept (default unlimited)\n"); 5745c87c606SMark Murray goto end; 5755c87c606SMark Murray } 5765c87c606SMark Murray 5775c87c606SMark Murray if(outfile) out = BIO_new_file(outfile, "w"); 5785c87c606SMark Murray else out = BIO_new_fp(stdout, BIO_NOCLOSE); 5795c87c606SMark Murray 5805c87c606SMark Murray if(!out) 5815c87c606SMark Murray { 5825c87c606SMark Murray BIO_printf(bio_err, "Error opening output file\n"); 5835c87c606SMark Murray goto end; 5845c87c606SMark Murray } 5855c87c606SMark Murray 5865c87c606SMark Murray if (!req && (add_nonce != 2)) add_nonce = 0; 5875c87c606SMark Murray 5885c87c606SMark Murray if (!req && reqin) 5895c87c606SMark Murray { 5905c87c606SMark Murray derbio = BIO_new_file(reqin, "rb"); 5915c87c606SMark Murray if (!derbio) 5925c87c606SMark Murray { 5935c87c606SMark Murray BIO_printf(bio_err, "Error Opening OCSP request file\n"); 5945c87c606SMark Murray goto end; 5955c87c606SMark Murray } 5965c87c606SMark Murray req = d2i_OCSP_REQUEST_bio(derbio, NULL); 5975c87c606SMark Murray BIO_free(derbio); 5985c87c606SMark Murray if(!req) 5995c87c606SMark Murray { 6005c87c606SMark Murray BIO_printf(bio_err, "Error reading OCSP request\n"); 6015c87c606SMark Murray goto end; 6025c87c606SMark Murray } 6035c87c606SMark Murray } 6045c87c606SMark Murray 6055c87c606SMark Murray if (!req && port) 6065c87c606SMark Murray { 6075c87c606SMark Murray acbio = init_responder(port); 6085c87c606SMark Murray if (!acbio) 6095c87c606SMark Murray goto end; 6105c87c606SMark Murray } 6115c87c606SMark Murray 6125c87c606SMark Murray if (rsignfile && !rdb) 6135c87c606SMark Murray { 6145c87c606SMark Murray if (!rkeyfile) rkeyfile = rsignfile; 6155c87c606SMark Murray rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM, 6165c87c606SMark Murray NULL, e, "responder certificate"); 6175c87c606SMark Murray if (!rsigner) 6185c87c606SMark Murray { 6195c87c606SMark Murray BIO_printf(bio_err, "Error loading responder certificate\n"); 6205c87c606SMark Murray goto end; 6215c87c606SMark Murray } 6225c87c606SMark Murray rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM, 6235c87c606SMark Murray NULL, e, "CA certificate"); 6245c87c606SMark Murray if (rcertfile) 6255c87c606SMark Murray { 6265c87c606SMark Murray rother = load_certs(bio_err, rcertfile, FORMAT_PEM, 6275c87c606SMark Murray NULL, e, "responder other certificates"); 6285c87c606SMark Murray if (!rother) goto end; 6295c87c606SMark Murray } 6305c87c606SMark Murray rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL, 6315c87c606SMark Murray "responder private key"); 6325c87c606SMark Murray if (!rkey) 6335c87c606SMark Murray goto end; 6345c87c606SMark Murray } 6355c87c606SMark Murray if(acbio) 6365c87c606SMark Murray BIO_printf(bio_err, "Waiting for OCSP client connections...\n"); 6375c87c606SMark Murray 6385c87c606SMark Murray redo_accept: 6395c87c606SMark Murray 6405c87c606SMark Murray if (acbio) 6415c87c606SMark Murray { 6425c87c606SMark Murray if (!do_responder(&req, &cbio, acbio, port)) 6435c87c606SMark Murray goto end; 6445c87c606SMark Murray if (!req) 6455c87c606SMark Murray { 6465c87c606SMark Murray resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); 6475c87c606SMark Murray send_ocsp_response(cbio, resp); 6485c87c606SMark Murray goto done_resp; 6495c87c606SMark Murray } 6505c87c606SMark Murray } 6515c87c606SMark Murray 6525c87c606SMark Murray if (!req && (signfile || reqout || host || add_nonce || ridx_filename)) 6535c87c606SMark Murray { 6545c87c606SMark Murray BIO_printf(bio_err, "Need an OCSP request for this operation!\n"); 6555c87c606SMark Murray goto end; 6565c87c606SMark Murray } 6575c87c606SMark Murray 6585c87c606SMark Murray if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1); 6595c87c606SMark Murray 6605c87c606SMark Murray if (signfile) 6615c87c606SMark Murray { 6625c87c606SMark Murray if (!keyfile) keyfile = signfile; 6635c87c606SMark Murray signer = load_cert(bio_err, signfile, FORMAT_PEM, 6645c87c606SMark Murray NULL, e, "signer certificate"); 6655c87c606SMark Murray if (!signer) 6665c87c606SMark Murray { 6675c87c606SMark Murray BIO_printf(bio_err, "Error loading signer certificate\n"); 6685c87c606SMark Murray goto end; 6695c87c606SMark Murray } 6705c87c606SMark Murray if (sign_certfile) 6715c87c606SMark Murray { 6725c87c606SMark Murray sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM, 6735c87c606SMark Murray NULL, e, "signer certificates"); 6745c87c606SMark Murray if (!sign_other) goto end; 6755c87c606SMark Murray } 6765c87c606SMark Murray key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL, 6775c87c606SMark Murray "signer private key"); 6785c87c606SMark Murray if (!key) 6795c87c606SMark Murray goto end; 6805c87c606SMark Murray if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags)) 6815c87c606SMark Murray { 6825c87c606SMark Murray BIO_printf(bio_err, "Error signing OCSP request\n"); 6835c87c606SMark Murray goto end; 6845c87c606SMark Murray } 6855c87c606SMark Murray } 6865c87c606SMark Murray 6875c87c606SMark Murray if (req_text && req) OCSP_REQUEST_print(out, req, 0); 6885c87c606SMark Murray 6895c87c606SMark Murray if (reqout) 6905c87c606SMark Murray { 6915c87c606SMark Murray derbio = BIO_new_file(reqout, "wb"); 6925c87c606SMark Murray if(!derbio) 6935c87c606SMark Murray { 6945c87c606SMark Murray BIO_printf(bio_err, "Error opening file %s\n", reqout); 6955c87c606SMark Murray goto end; 6965c87c606SMark Murray } 6975c87c606SMark Murray i2d_OCSP_REQUEST_bio(derbio, req); 6985c87c606SMark Murray BIO_free(derbio); 6995c87c606SMark Murray } 7005c87c606SMark Murray 7015c87c606SMark Murray if (ridx_filename && (!rkey || !rsigner || !rca_cert)) 7025c87c606SMark Murray { 7035c87c606SMark Murray BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n"); 7045c87c606SMark Murray goto end; 7055c87c606SMark Murray } 7065c87c606SMark Murray 7075c87c606SMark Murray if (ridx_filename && !rdb) 7085c87c606SMark Murray { 709ced566fdSJacques Vidrine rdb = load_index(ridx_filename, NULL); 710ced566fdSJacques Vidrine if (!rdb) goto end; 711ced566fdSJacques Vidrine if (!index_index(rdb)) goto end; 7125c87c606SMark Murray } 7135c87c606SMark Murray 7145c87c606SMark Murray if (rdb) 7155c87c606SMark Murray { 7165c87c606SMark Murray i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays); 7175c87c606SMark Murray if (cbio) 7185c87c606SMark Murray send_ocsp_response(cbio, resp); 7195c87c606SMark Murray } 7205c87c606SMark Murray else if (host) 7215c87c606SMark Murray { 722fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_SOCK 723db522d3aSSimon L. B. Nielsen resp = process_responder(bio_err, req, host, path, 724db522d3aSSimon L. B. Nielsen port, use_ssl, req_timeout); 725db522d3aSSimon L. B. Nielsen if (!resp) 726db522d3aSSimon L. B. Nielsen goto end; 727fceca8a3SJacques Vidrine #else 728fceca8a3SJacques Vidrine BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n"); 729fceca8a3SJacques Vidrine goto end; 730fceca8a3SJacques Vidrine #endif 7315c87c606SMark Murray } 7325c87c606SMark Murray else if (respin) 7335c87c606SMark Murray { 7345c87c606SMark Murray derbio = BIO_new_file(respin, "rb"); 7355c87c606SMark Murray if (!derbio) 7365c87c606SMark Murray { 7375c87c606SMark Murray BIO_printf(bio_err, "Error Opening OCSP response file\n"); 7385c87c606SMark Murray goto end; 7395c87c606SMark Murray } 7405c87c606SMark Murray resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); 7415c87c606SMark Murray BIO_free(derbio); 7425c87c606SMark Murray if(!resp) 7435c87c606SMark Murray { 7445c87c606SMark Murray BIO_printf(bio_err, "Error reading OCSP response\n"); 7455c87c606SMark Murray goto end; 7465c87c606SMark Murray } 7475c87c606SMark Murray 7485c87c606SMark Murray } 7495c87c606SMark Murray else 7505c87c606SMark Murray { 7515c87c606SMark Murray ret = 0; 7525c87c606SMark Murray goto end; 7535c87c606SMark Murray } 7545c87c606SMark Murray 7555c87c606SMark Murray done_resp: 7565c87c606SMark Murray 7575c87c606SMark Murray if (respout) 7585c87c606SMark Murray { 7595c87c606SMark Murray derbio = BIO_new_file(respout, "wb"); 7605c87c606SMark Murray if(!derbio) 7615c87c606SMark Murray { 7625c87c606SMark Murray BIO_printf(bio_err, "Error opening file %s\n", respout); 7635c87c606SMark Murray goto end; 7645c87c606SMark Murray } 7655c87c606SMark Murray i2d_OCSP_RESPONSE_bio(derbio, resp); 7665c87c606SMark Murray BIO_free(derbio); 7675c87c606SMark Murray } 7685c87c606SMark Murray 7695c87c606SMark Murray i = OCSP_response_status(resp); 7705c87c606SMark Murray 7715c87c606SMark Murray if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) 7725c87c606SMark Murray { 7733b4e3dcbSSimon L. B. Nielsen BIO_printf(out, "Responder Error: %s (%d)\n", 7745c87c606SMark Murray OCSP_response_status_str(i), i); 77550ef0093SJacques Vidrine if (ignore_err) 77650ef0093SJacques Vidrine goto redo_accept; 7775c87c606SMark Murray ret = 0; 7785c87c606SMark Murray goto end; 7795c87c606SMark Murray } 7805c87c606SMark Murray 7815c87c606SMark Murray if (resp_text) OCSP_RESPONSE_print(out, resp, 0); 7825c87c606SMark Murray 7835c87c606SMark Murray /* If running as responder don't verify our own response */ 7845c87c606SMark Murray if (cbio) 7855c87c606SMark Murray { 7865c87c606SMark Murray if (accept_count > 0) 7875c87c606SMark Murray accept_count--; 7885c87c606SMark Murray /* Redo if more connections needed */ 7895c87c606SMark Murray if (accept_count) 7905c87c606SMark Murray { 7915c87c606SMark Murray BIO_free_all(cbio); 7925c87c606SMark Murray cbio = NULL; 7935c87c606SMark Murray OCSP_REQUEST_free(req); 7945c87c606SMark Murray req = NULL; 7955c87c606SMark Murray OCSP_RESPONSE_free(resp); 7965c87c606SMark Murray resp = NULL; 7975c87c606SMark Murray goto redo_accept; 7985c87c606SMark Murray } 7995c87c606SMark Murray goto end; 8005c87c606SMark Murray } 8015c87c606SMark Murray 8025c87c606SMark Murray if (!store) 8035c87c606SMark Murray store = setup_verify(bio_err, CAfile, CApath); 8045c87c606SMark Murray if (!store) 8055c87c606SMark Murray goto end; 8065c87c606SMark Murray if (verify_certfile) 8075c87c606SMark Murray { 8085c87c606SMark Murray verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM, 8095c87c606SMark Murray NULL, e, "validator certificate"); 8105c87c606SMark Murray if (!verify_other) goto end; 8115c87c606SMark Murray } 8125c87c606SMark Murray 8135c87c606SMark Murray bs = OCSP_response_get1_basic(resp); 8145c87c606SMark Murray 8155c87c606SMark Murray if (!bs) 8165c87c606SMark Murray { 8175c87c606SMark Murray BIO_printf(bio_err, "Error parsing response\n"); 8185c87c606SMark Murray goto end; 8195c87c606SMark Murray } 8205c87c606SMark Murray 8215c87c606SMark Murray if (!noverify) 8225c87c606SMark Murray { 8235c87c606SMark Murray if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) 8245c87c606SMark Murray { 8255c87c606SMark Murray if (i == -1) 8265c87c606SMark Murray BIO_printf(bio_err, "WARNING: no nonce in response\n"); 8275c87c606SMark Murray else 8285c87c606SMark Murray { 8295c87c606SMark Murray BIO_printf(bio_err, "Nonce Verify error\n"); 8305c87c606SMark Murray goto end; 8315c87c606SMark Murray } 8325c87c606SMark Murray } 8335c87c606SMark Murray 8345c87c606SMark Murray i = OCSP_basic_verify(bs, verify_other, store, verify_flags); 8355c87c606SMark Murray if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0); 8365c87c606SMark Murray 8375c87c606SMark Murray if(i <= 0) 8385c87c606SMark Murray { 8393b4e3dcbSSimon L. B. Nielsen BIO_printf(bio_err, "Response Verify Failure\n"); 8405c87c606SMark Murray ERR_print_errors(bio_err); 8415c87c606SMark Murray } 8425c87c606SMark Murray else 8435c87c606SMark Murray BIO_printf(bio_err, "Response verify OK\n"); 8445c87c606SMark Murray 8455c87c606SMark Murray } 8465c87c606SMark Murray 8475c87c606SMark Murray if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage)) 8485c87c606SMark Murray goto end; 8495c87c606SMark Murray 8505c87c606SMark Murray ret = 0; 8515c87c606SMark Murray 8525c87c606SMark Murray end: 8535c87c606SMark Murray ERR_print_errors(bio_err); 8545c87c606SMark Murray X509_free(signer); 8555c87c606SMark Murray X509_STORE_free(store); 8565c87c606SMark Murray EVP_PKEY_free(key); 8575c87c606SMark Murray EVP_PKEY_free(rkey); 8585c87c606SMark Murray X509_free(issuer); 8595c87c606SMark Murray X509_free(cert); 8605c87c606SMark Murray X509_free(rsigner); 8615c87c606SMark Murray X509_free(rca_cert); 862ced566fdSJacques Vidrine free_index(rdb); 8635c87c606SMark Murray BIO_free_all(cbio); 8645c87c606SMark Murray BIO_free_all(acbio); 8655c87c606SMark Murray BIO_free(out); 8665c87c606SMark Murray OCSP_REQUEST_free(req); 8675c87c606SMark Murray OCSP_RESPONSE_free(resp); 8685c87c606SMark Murray OCSP_BASICRESP_free(bs); 8695c87c606SMark Murray sk_free(reqnames); 8705c87c606SMark Murray sk_OCSP_CERTID_free(ids); 8715c87c606SMark Murray sk_X509_pop_free(sign_other, X509_free); 8725c87c606SMark Murray sk_X509_pop_free(verify_other, X509_free); 8735c87c606SMark Murray 8745c87c606SMark Murray if (use_ssl != -1) 8755c87c606SMark Murray { 8765c87c606SMark Murray OPENSSL_free(host); 8775c87c606SMark Murray OPENSSL_free(port); 8785c87c606SMark Murray OPENSSL_free(path); 8795c87c606SMark Murray } 8805c87c606SMark Murray 8815c87c606SMark Murray OPENSSL_EXIT(ret); 8825c87c606SMark Murray } 8835c87c606SMark Murray 8845c87c606SMark Murray static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer, 8855c87c606SMark Murray STACK_OF(OCSP_CERTID) *ids) 8865c87c606SMark Murray { 8875c87c606SMark Murray OCSP_CERTID *id; 8885c87c606SMark Murray if(!issuer) 8895c87c606SMark Murray { 8905c87c606SMark Murray BIO_printf(bio_err, "No issuer certificate specified\n"); 8915c87c606SMark Murray return 0; 8925c87c606SMark Murray } 8935c87c606SMark Murray if(!*req) *req = OCSP_REQUEST_new(); 8945c87c606SMark Murray if(!*req) goto err; 8955c87c606SMark Murray id = OCSP_cert_to_id(NULL, cert, issuer); 8965c87c606SMark Murray if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err; 8975c87c606SMark Murray if(!OCSP_request_add0_id(*req, id)) goto err; 8985c87c606SMark Murray return 1; 8995c87c606SMark Murray 9005c87c606SMark Murray err: 9015c87c606SMark Murray BIO_printf(bio_err, "Error Creating OCSP request\n"); 9025c87c606SMark Murray return 0; 9035c87c606SMark Murray } 9045c87c606SMark Murray 9055c87c606SMark Murray static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer, 9065c87c606SMark Murray STACK_OF(OCSP_CERTID) *ids) 9075c87c606SMark Murray { 9085c87c606SMark Murray OCSP_CERTID *id; 9095c87c606SMark Murray X509_NAME *iname; 9105c87c606SMark Murray ASN1_BIT_STRING *ikey; 9115c87c606SMark Murray ASN1_INTEGER *sno; 9125c87c606SMark Murray if(!issuer) 9135c87c606SMark Murray { 9145c87c606SMark Murray BIO_printf(bio_err, "No issuer certificate specified\n"); 9155c87c606SMark Murray return 0; 9165c87c606SMark Murray } 9175c87c606SMark Murray if(!*req) *req = OCSP_REQUEST_new(); 9185c87c606SMark Murray if(!*req) goto err; 9195c87c606SMark Murray iname = X509_get_subject_name(issuer); 9205c87c606SMark Murray ikey = X509_get0_pubkey_bitstr(issuer); 9215c87c606SMark Murray sno = s2i_ASN1_INTEGER(NULL, serial); 9225c87c606SMark Murray if(!sno) 9235c87c606SMark Murray { 9245c87c606SMark Murray BIO_printf(bio_err, "Error converting serial number %s\n", serial); 9255c87c606SMark Murray return 0; 9265c87c606SMark Murray } 9275c87c606SMark Murray id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno); 9285c87c606SMark Murray ASN1_INTEGER_free(sno); 9295c87c606SMark Murray if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err; 9305c87c606SMark Murray if(!OCSP_request_add0_id(*req, id)) goto err; 9315c87c606SMark Murray return 1; 9325c87c606SMark Murray 9335c87c606SMark Murray err: 9345c87c606SMark Murray BIO_printf(bio_err, "Error Creating OCSP request\n"); 9355c87c606SMark Murray return 0; 9365c87c606SMark Murray } 9375c87c606SMark Murray 9385c87c606SMark Murray static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, 9395c87c606SMark Murray STACK *names, STACK_OF(OCSP_CERTID) *ids, 9405c87c606SMark Murray long nsec, long maxage) 9415c87c606SMark Murray { 9425c87c606SMark Murray OCSP_CERTID *id; 9435c87c606SMark Murray char *name; 9445c87c606SMark Murray int i; 9455c87c606SMark Murray 9465c87c606SMark Murray int status, reason; 9475c87c606SMark Murray 9485c87c606SMark Murray ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; 9495c87c606SMark Murray 9505c87c606SMark Murray if (!bs || !req || !sk_num(names) || !sk_OCSP_CERTID_num(ids)) 9515c87c606SMark Murray return 1; 9525c87c606SMark Murray 9535c87c606SMark Murray for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) 9545c87c606SMark Murray { 9555c87c606SMark Murray id = sk_OCSP_CERTID_value(ids, i); 9565c87c606SMark Murray name = sk_value(names, i); 9575c87c606SMark Murray BIO_printf(out, "%s: ", name); 9585c87c606SMark Murray 9595c87c606SMark Murray if(!OCSP_resp_find_status(bs, id, &status, &reason, 9605c87c606SMark Murray &rev, &thisupd, &nextupd)) 9615c87c606SMark Murray { 9625c87c606SMark Murray BIO_puts(out, "ERROR: No Status found.\n"); 9635c87c606SMark Murray continue; 9645c87c606SMark Murray } 9655c87c606SMark Murray 9665c87c606SMark Murray /* Check validity: if invalid write to output BIO so we 9675c87c606SMark Murray * know which response this refers to. 9685c87c606SMark Murray */ 9695c87c606SMark Murray if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage)) 9705c87c606SMark Murray { 9715c87c606SMark Murray BIO_puts(out, "WARNING: Status times invalid.\n"); 9725c87c606SMark Murray ERR_print_errors(out); 9735c87c606SMark Murray } 9745c87c606SMark Murray BIO_printf(out, "%s\n", OCSP_cert_status_str(status)); 9755c87c606SMark Murray 9765c87c606SMark Murray BIO_puts(out, "\tThis Update: "); 9775c87c606SMark Murray ASN1_GENERALIZEDTIME_print(out, thisupd); 9785c87c606SMark Murray BIO_puts(out, "\n"); 9795c87c606SMark Murray 9805c87c606SMark Murray if(nextupd) 9815c87c606SMark Murray { 9825c87c606SMark Murray BIO_puts(out, "\tNext Update: "); 9835c87c606SMark Murray ASN1_GENERALIZEDTIME_print(out, nextupd); 9845c87c606SMark Murray BIO_puts(out, "\n"); 9855c87c606SMark Murray } 9865c87c606SMark Murray 9875c87c606SMark Murray if (status != V_OCSP_CERTSTATUS_REVOKED) 9885c87c606SMark Murray continue; 9895c87c606SMark Murray 9905c87c606SMark Murray if (reason != -1) 9915c87c606SMark Murray BIO_printf(out, "\tReason: %s\n", 9925c87c606SMark Murray OCSP_crl_reason_str(reason)); 9935c87c606SMark Murray 9945c87c606SMark Murray BIO_puts(out, "\tRevocation Time: "); 9955c87c606SMark Murray ASN1_GENERALIZEDTIME_print(out, rev); 9965c87c606SMark Murray BIO_puts(out, "\n"); 9975c87c606SMark Murray } 9985c87c606SMark Murray 9995c87c606SMark Murray return 1; 10005c87c606SMark Murray } 10015c87c606SMark Murray 10025c87c606SMark Murray 1003ced566fdSJacques Vidrine static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db, 10045c87c606SMark Murray X509 *ca, X509 *rcert, EVP_PKEY *rkey, 10055c87c606SMark Murray STACK_OF(X509) *rother, unsigned long flags, 10065c87c606SMark Murray int nmin, int ndays) 10075c87c606SMark Murray { 10085c87c606SMark Murray ASN1_TIME *thisupd = NULL, *nextupd = NULL; 10095c87c606SMark Murray OCSP_CERTID *cid, *ca_id = NULL; 10105c87c606SMark Murray OCSP_BASICRESP *bs = NULL; 10115c87c606SMark Murray int i, id_count, ret = 1; 10125c87c606SMark Murray 10135c87c606SMark Murray 10145c87c606SMark Murray id_count = OCSP_request_onereq_count(req); 10155c87c606SMark Murray 10165c87c606SMark Murray if (id_count <= 0) 10175c87c606SMark Murray { 10185c87c606SMark Murray *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); 10195c87c606SMark Murray goto end; 10205c87c606SMark Murray } 10215c87c606SMark Murray 10225c87c606SMark Murray ca_id = OCSP_cert_to_id(EVP_sha1(), NULL, ca); 10235c87c606SMark Murray 10245c87c606SMark Murray bs = OCSP_BASICRESP_new(); 10255c87c606SMark Murray thisupd = X509_gmtime_adj(NULL, 0); 10265c87c606SMark Murray if (ndays != -1) 10275c87c606SMark Murray nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24 ); 10285c87c606SMark Murray 10295c87c606SMark Murray /* Examine each certificate id in the request */ 10305c87c606SMark Murray for (i = 0; i < id_count; i++) 10315c87c606SMark Murray { 10325c87c606SMark Murray OCSP_ONEREQ *one; 10335c87c606SMark Murray ASN1_INTEGER *serial; 10345c87c606SMark Murray char **inf; 10355c87c606SMark Murray one = OCSP_request_onereq_get0(req, i); 10365c87c606SMark Murray cid = OCSP_onereq_get0_id(one); 10375c87c606SMark Murray /* Is this request about our CA? */ 10385c87c606SMark Murray if (OCSP_id_issuer_cmp(ca_id, cid)) 10395c87c606SMark Murray { 10405c87c606SMark Murray OCSP_basic_add1_status(bs, cid, 10415c87c606SMark Murray V_OCSP_CERTSTATUS_UNKNOWN, 10425c87c606SMark Murray 0, NULL, 10435c87c606SMark Murray thisupd, nextupd); 10445c87c606SMark Murray continue; 10455c87c606SMark Murray } 10465c87c606SMark Murray OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid); 10475c87c606SMark Murray inf = lookup_serial(db, serial); 10485c87c606SMark Murray if (!inf) 10495c87c606SMark Murray OCSP_basic_add1_status(bs, cid, 10505c87c606SMark Murray V_OCSP_CERTSTATUS_UNKNOWN, 10515c87c606SMark Murray 0, NULL, 10525c87c606SMark Murray thisupd, nextupd); 10535c87c606SMark Murray else if (inf[DB_type][0] == DB_TYPE_VAL) 10545c87c606SMark Murray OCSP_basic_add1_status(bs, cid, 10555c87c606SMark Murray V_OCSP_CERTSTATUS_GOOD, 10565c87c606SMark Murray 0, NULL, 10575c87c606SMark Murray thisupd, nextupd); 10585c87c606SMark Murray else if (inf[DB_type][0] == DB_TYPE_REV) 10595c87c606SMark Murray { 10605c87c606SMark Murray ASN1_OBJECT *inst = NULL; 10615c87c606SMark Murray ASN1_TIME *revtm = NULL; 10625c87c606SMark Murray ASN1_GENERALIZEDTIME *invtm = NULL; 10635c87c606SMark Murray OCSP_SINGLERESP *single; 10645c87c606SMark Murray int reason = -1; 10655c87c606SMark Murray unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]); 10665c87c606SMark Murray single = OCSP_basic_add1_status(bs, cid, 10675c87c606SMark Murray V_OCSP_CERTSTATUS_REVOKED, 10685c87c606SMark Murray reason, revtm, 10695c87c606SMark Murray thisupd, nextupd); 10705c87c606SMark Murray if (invtm) 10715c87c606SMark Murray OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0); 10725c87c606SMark Murray else if (inst) 10735c87c606SMark Murray OCSP_SINGLERESP_add1_ext_i2d(single, NID_hold_instruction_code, inst, 0, 0); 10745c87c606SMark Murray ASN1_OBJECT_free(inst); 10755c87c606SMark Murray ASN1_TIME_free(revtm); 10765c87c606SMark Murray ASN1_GENERALIZEDTIME_free(invtm); 10775c87c606SMark Murray } 10785c87c606SMark Murray } 10795c87c606SMark Murray 10805c87c606SMark Murray OCSP_copy_nonce(bs, req); 10815c87c606SMark Murray 10825c87c606SMark Murray OCSP_basic_sign(bs, rcert, rkey, EVP_sha1(), rother, flags); 10835c87c606SMark Murray 10845c87c606SMark Murray *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs); 10855c87c606SMark Murray 10865c87c606SMark Murray end: 10875c87c606SMark Murray ASN1_TIME_free(thisupd); 10885c87c606SMark Murray ASN1_TIME_free(nextupd); 10895c87c606SMark Murray OCSP_CERTID_free(ca_id); 10905c87c606SMark Murray OCSP_BASICRESP_free(bs); 10915c87c606SMark Murray return ret; 10925c87c606SMark Murray 10935c87c606SMark Murray } 10945c87c606SMark Murray 1095ced566fdSJacques Vidrine static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser) 10965c87c606SMark Murray { 10975c87c606SMark Murray int i; 10985c87c606SMark Murray BIGNUM *bn = NULL; 10995c87c606SMark Murray char *itmp, *row[DB_NUMBER],**rrow; 11005c87c606SMark Murray for (i = 0; i < DB_NUMBER; i++) row[i] = NULL; 11015c87c606SMark Murray bn = ASN1_INTEGER_to_BN(ser,NULL); 1102db522d3aSSimon L. B. Nielsen OPENSSL_assert(bn); /* FIXME: should report an error at this point and abort */ 11035c87c606SMark Murray if (BN_is_zero(bn)) 11045c87c606SMark Murray itmp = BUF_strdup("00"); 11055c87c606SMark Murray else 11065c87c606SMark Murray itmp = BN_bn2hex(bn); 11075c87c606SMark Murray row[DB_serial] = itmp; 11085c87c606SMark Murray BN_free(bn); 1109ced566fdSJacques Vidrine rrow=TXT_DB_get_by_index(db->db,DB_serial,row); 11105c87c606SMark Murray OPENSSL_free(itmp); 11115c87c606SMark Murray return rrow; 11125c87c606SMark Murray } 11135c87c606SMark Murray 11145c87c606SMark Murray /* Quick and dirty OCSP server: read in and parse input request */ 11155c87c606SMark Murray 11165c87c606SMark Murray static BIO *init_responder(char *port) 11175c87c606SMark Murray { 11185c87c606SMark Murray BIO *acbio = NULL, *bufbio = NULL; 11195c87c606SMark Murray bufbio = BIO_new(BIO_f_buffer()); 11205c87c606SMark Murray if (!bufbio) 11215c87c606SMark Murray goto err; 1122fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_SOCK 11235c87c606SMark Murray acbio = BIO_new_accept(port); 1124fceca8a3SJacques Vidrine #else 1125fceca8a3SJacques Vidrine BIO_printf(bio_err, "Error setting up accept BIO - sockets not supported.\n"); 1126fceca8a3SJacques Vidrine #endif 11275c87c606SMark Murray if (!acbio) 11285c87c606SMark Murray goto err; 11295c87c606SMark Murray BIO_set_accept_bios(acbio, bufbio); 11305c87c606SMark Murray bufbio = NULL; 11315c87c606SMark Murray 11325c87c606SMark Murray if (BIO_do_accept(acbio) <= 0) 11335c87c606SMark Murray { 11345c87c606SMark Murray BIO_printf(bio_err, "Error setting up accept BIO\n"); 11355c87c606SMark Murray ERR_print_errors(bio_err); 11365c87c606SMark Murray goto err; 11375c87c606SMark Murray } 11385c87c606SMark Murray 11395c87c606SMark Murray return acbio; 11405c87c606SMark Murray 11415c87c606SMark Murray err: 11425c87c606SMark Murray BIO_free_all(acbio); 11435c87c606SMark Murray BIO_free(bufbio); 11445c87c606SMark Murray return NULL; 11455c87c606SMark Murray } 11465c87c606SMark Murray 11475c87c606SMark Murray static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port) 11485c87c606SMark Murray { 11495c87c606SMark Murray int have_post = 0, len; 11505c87c606SMark Murray OCSP_REQUEST *req = NULL; 11515c87c606SMark Murray char inbuf[1024]; 11525c87c606SMark Murray BIO *cbio = NULL; 11535c87c606SMark Murray 11545c87c606SMark Murray if (BIO_do_accept(acbio) <= 0) 11555c87c606SMark Murray { 11565c87c606SMark Murray BIO_printf(bio_err, "Error accepting connection\n"); 11575c87c606SMark Murray ERR_print_errors(bio_err); 11585c87c606SMark Murray return 0; 11595c87c606SMark Murray } 11605c87c606SMark Murray 11615c87c606SMark Murray cbio = BIO_pop(acbio); 11625c87c606SMark Murray *pcbio = cbio; 11635c87c606SMark Murray 11645c87c606SMark Murray for(;;) 11655c87c606SMark Murray { 11665c87c606SMark Murray len = BIO_gets(cbio, inbuf, sizeof inbuf); 11675c87c606SMark Murray if (len <= 0) 11685c87c606SMark Murray return 1; 11695c87c606SMark Murray /* Look for "POST" signalling start of query */ 11705c87c606SMark Murray if (!have_post) 11715c87c606SMark Murray { 11725c87c606SMark Murray if(strncmp(inbuf, "POST", 4)) 11735c87c606SMark Murray { 11745c87c606SMark Murray BIO_printf(bio_err, "Invalid request\n"); 11755c87c606SMark Murray return 1; 11765c87c606SMark Murray } 11775c87c606SMark Murray have_post = 1; 11785c87c606SMark Murray } 11795c87c606SMark Murray /* Look for end of headers */ 11805c87c606SMark Murray if ((inbuf[0] == '\r') || (inbuf[0] == '\n')) 11815c87c606SMark Murray break; 11825c87c606SMark Murray } 11835c87c606SMark Murray 11845c87c606SMark Murray /* Try to read OCSP request */ 11855c87c606SMark Murray 11865c87c606SMark Murray req = d2i_OCSP_REQUEST_bio(cbio, NULL); 11875c87c606SMark Murray 11885c87c606SMark Murray if (!req) 11895c87c606SMark Murray { 11905c87c606SMark Murray BIO_printf(bio_err, "Error parsing OCSP request\n"); 11915c87c606SMark Murray ERR_print_errors(bio_err); 11925c87c606SMark Murray } 11935c87c606SMark Murray 11945c87c606SMark Murray *preq = req; 11955c87c606SMark Murray 11965c87c606SMark Murray return 1; 11975c87c606SMark Murray 11985c87c606SMark Murray } 11995c87c606SMark Murray 12005c87c606SMark Murray static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp) 12015c87c606SMark Murray { 12025c87c606SMark Murray char http_resp[] = 12035c87c606SMark Murray "HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n" 12045c87c606SMark Murray "Content-Length: %d\r\n\r\n"; 12055c87c606SMark Murray if (!cbio) 12065c87c606SMark Murray return 0; 12075c87c606SMark Murray BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL)); 12085c87c606SMark Murray i2d_OCSP_RESPONSE_bio(cbio, resp); 1209db522d3aSSimon L. B. Nielsen (void)BIO_flush(cbio); 12105c87c606SMark Murray return 1; 12115c87c606SMark Murray } 12125c87c606SMark Murray 1213db522d3aSSimon L. B. Nielsen static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path, 1214db522d3aSSimon L. B. Nielsen OCSP_REQUEST *req, int req_timeout) 1215db522d3aSSimon L. B. Nielsen { 1216db522d3aSSimon L. B. Nielsen int fd; 1217db522d3aSSimon L. B. Nielsen int rv; 1218db522d3aSSimon L. B. Nielsen OCSP_REQ_CTX *ctx = NULL; 1219db522d3aSSimon L. B. Nielsen OCSP_RESPONSE *rsp = NULL; 1220db522d3aSSimon L. B. Nielsen fd_set confds; 1221db522d3aSSimon L. B. Nielsen struct timeval tv; 1222db522d3aSSimon L. B. Nielsen 1223db522d3aSSimon L. B. Nielsen if (req_timeout != -1) 1224db522d3aSSimon L. B. Nielsen BIO_set_nbio(cbio, 1); 1225db522d3aSSimon L. B. Nielsen 1226db522d3aSSimon L. B. Nielsen rv = BIO_do_connect(cbio); 1227db522d3aSSimon L. B. Nielsen 1228db522d3aSSimon L. B. Nielsen if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio))) 1229db522d3aSSimon L. B. Nielsen { 1230db522d3aSSimon L. B. Nielsen BIO_puts(err, "Error connecting BIO\n"); 1231db522d3aSSimon L. B. Nielsen return NULL; 1232db522d3aSSimon L. B. Nielsen } 1233db522d3aSSimon L. B. Nielsen 1234db522d3aSSimon L. B. Nielsen if (req_timeout == -1) 1235db522d3aSSimon L. B. Nielsen return OCSP_sendreq_bio(cbio, path, req); 1236db522d3aSSimon L. B. Nielsen 1237db522d3aSSimon L. B. Nielsen if (BIO_get_fd(cbio, &fd) <= 0) 1238db522d3aSSimon L. B. Nielsen { 1239db522d3aSSimon L. B. Nielsen BIO_puts(err, "Can't get connection fd\n"); 1240db522d3aSSimon L. B. Nielsen goto err; 1241db522d3aSSimon L. B. Nielsen } 1242db522d3aSSimon L. B. Nielsen 1243db522d3aSSimon L. B. Nielsen if (rv <= 0) 1244db522d3aSSimon L. B. Nielsen { 1245db522d3aSSimon L. B. Nielsen FD_ZERO(&confds); 1246db522d3aSSimon L. B. Nielsen openssl_fdset(fd, &confds); 1247db522d3aSSimon L. B. Nielsen tv.tv_usec = 0; 1248db522d3aSSimon L. B. Nielsen tv.tv_sec = req_timeout; 1249db522d3aSSimon L. B. Nielsen rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); 1250db522d3aSSimon L. B. Nielsen if (rv == 0) 1251db522d3aSSimon L. B. Nielsen { 1252db522d3aSSimon L. B. Nielsen BIO_puts(err, "Timeout on connect\n"); 1253db522d3aSSimon L. B. Nielsen return NULL; 1254db522d3aSSimon L. B. Nielsen } 1255db522d3aSSimon L. B. Nielsen } 1256db522d3aSSimon L. B. Nielsen 1257db522d3aSSimon L. B. Nielsen 1258db522d3aSSimon L. B. Nielsen ctx = OCSP_sendreq_new(cbio, path, req, -1); 1259db522d3aSSimon L. B. Nielsen if (!ctx) 1260db522d3aSSimon L. B. Nielsen return NULL; 1261db522d3aSSimon L. B. Nielsen 1262db522d3aSSimon L. B. Nielsen for (;;) 1263db522d3aSSimon L. B. Nielsen { 1264db522d3aSSimon L. B. Nielsen rv = OCSP_sendreq_nbio(&rsp, ctx); 1265db522d3aSSimon L. B. Nielsen if (rv != -1) 1266db522d3aSSimon L. B. Nielsen break; 1267db522d3aSSimon L. B. Nielsen FD_ZERO(&confds); 1268db522d3aSSimon L. B. Nielsen openssl_fdset(fd, &confds); 1269db522d3aSSimon L. B. Nielsen tv.tv_usec = 0; 1270db522d3aSSimon L. B. Nielsen tv.tv_sec = req_timeout; 1271db522d3aSSimon L. B. Nielsen if (BIO_should_read(cbio)) 1272db522d3aSSimon L. B. Nielsen rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv); 1273db522d3aSSimon L. B. Nielsen else if (BIO_should_write(cbio)) 1274db522d3aSSimon L. B. Nielsen rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); 1275db522d3aSSimon L. B. Nielsen else 1276db522d3aSSimon L. B. Nielsen { 1277db522d3aSSimon L. B. Nielsen BIO_puts(err, "Unexpected retry condition\n"); 1278db522d3aSSimon L. B. Nielsen goto err; 1279db522d3aSSimon L. B. Nielsen } 1280db522d3aSSimon L. B. Nielsen if (rv == 0) 1281db522d3aSSimon L. B. Nielsen { 1282db522d3aSSimon L. B. Nielsen BIO_puts(err, "Timeout on request\n"); 1283db522d3aSSimon L. B. Nielsen break; 1284db522d3aSSimon L. B. Nielsen } 1285db522d3aSSimon L. B. Nielsen if (rv == -1) 1286db522d3aSSimon L. B. Nielsen { 1287db522d3aSSimon L. B. Nielsen BIO_puts(err, "Select error\n"); 1288db522d3aSSimon L. B. Nielsen break; 1289db522d3aSSimon L. B. Nielsen } 1290db522d3aSSimon L. B. Nielsen 1291db522d3aSSimon L. B. Nielsen } 1292db522d3aSSimon L. B. Nielsen err: 1293db522d3aSSimon L. B. Nielsen if (ctx) 1294db522d3aSSimon L. B. Nielsen OCSP_REQ_CTX_free(ctx); 1295db522d3aSSimon L. B. Nielsen 1296db522d3aSSimon L. B. Nielsen return rsp; 1297db522d3aSSimon L. B. Nielsen } 1298db522d3aSSimon L. B. Nielsen 1299db522d3aSSimon L. B. Nielsen OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req, 1300db522d3aSSimon L. B. Nielsen char *host, char *path, char *port, int use_ssl, 1301db522d3aSSimon L. B. Nielsen int req_timeout) 1302db522d3aSSimon L. B. Nielsen { 1303db522d3aSSimon L. B. Nielsen BIO *cbio = NULL; 1304db522d3aSSimon L. B. Nielsen SSL_CTX *ctx = NULL; 1305db522d3aSSimon L. B. Nielsen OCSP_RESPONSE *resp = NULL; 1306db522d3aSSimon L. B. Nielsen cbio = BIO_new_connect(host); 1307db522d3aSSimon L. B. Nielsen if (!cbio) 1308db522d3aSSimon L. B. Nielsen { 1309db522d3aSSimon L. B. Nielsen BIO_printf(err, "Error creating connect BIO\n"); 1310db522d3aSSimon L. B. Nielsen goto end; 1311db522d3aSSimon L. B. Nielsen } 1312db522d3aSSimon L. B. Nielsen if (port) BIO_set_conn_port(cbio, port); 1313db522d3aSSimon L. B. Nielsen if (use_ssl == 1) 1314db522d3aSSimon L. B. Nielsen { 1315db522d3aSSimon L. B. Nielsen BIO *sbio; 1316db522d3aSSimon L. B. Nielsen #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) 1317db522d3aSSimon L. B. Nielsen ctx = SSL_CTX_new(SSLv23_client_method()); 1318db522d3aSSimon L. B. Nielsen #elif !defined(OPENSSL_NO_SSL3) 1319db522d3aSSimon L. B. Nielsen ctx = SSL_CTX_new(SSLv3_client_method()); 1320db522d3aSSimon L. B. Nielsen #elif !defined(OPENSSL_NO_SSL2) 1321db522d3aSSimon L. B. Nielsen ctx = SSL_CTX_new(SSLv2_client_method()); 1322db522d3aSSimon L. B. Nielsen #else 1323db522d3aSSimon L. B. Nielsen BIO_printf(err, "SSL is disabled\n"); 1324db522d3aSSimon L. B. Nielsen goto end; 1325db522d3aSSimon L. B. Nielsen #endif 1326db522d3aSSimon L. B. Nielsen if (ctx == NULL) 1327db522d3aSSimon L. B. Nielsen { 1328db522d3aSSimon L. B. Nielsen BIO_printf(err, "Error creating SSL context.\n"); 1329db522d3aSSimon L. B. Nielsen goto end; 1330db522d3aSSimon L. B. Nielsen } 1331db522d3aSSimon L. B. Nielsen SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); 1332db522d3aSSimon L. B. Nielsen sbio = BIO_new_ssl(ctx, 1); 1333db522d3aSSimon L. B. Nielsen cbio = BIO_push(sbio, cbio); 1334db522d3aSSimon L. B. Nielsen } 1335db522d3aSSimon L. B. Nielsen resp = query_responder(err, cbio, path, req, req_timeout); 1336db522d3aSSimon L. B. Nielsen if (!resp) 1337db522d3aSSimon L. B. Nielsen BIO_printf(bio_err, "Error querying OCSP responsder\n"); 1338db522d3aSSimon L. B. Nielsen end: 1339db522d3aSSimon L. B. Nielsen if (ctx) 1340db522d3aSSimon L. B. Nielsen SSL_CTX_free(ctx); 1341db522d3aSSimon L. B. Nielsen if (cbio) 1342db522d3aSSimon L. B. Nielsen BIO_free_all(cbio); 1343db522d3aSSimon L. B. Nielsen return resp; 1344db522d3aSSimon L. B. Nielsen } 1345db522d3aSSimon L. B. Nielsen 1346fceca8a3SJacques Vidrine #endif 1347