X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Focsp.c;h=1cb11b289bb52ba4464f8690a6fde0b8936c85f6;hp=5d3e646f81339ad8ffed7fb99a7199748876844c;hb=3067095e8a2cca3d33fa0af77788bc45da68b76b;hpb=366e2a60b2fcc727b061f1459343245476ad6c3b diff --git a/apps/ocsp.c b/apps/ocsp.c index 5d3e646f81..1cb11b289b 100644 --- a/apps/ocsp.c +++ b/apps/ocsp.c @@ -1,62 +1,17 @@ /* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). + * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved. * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ -#ifndef OPENSSL_NO_OCSP +#include + +#ifdef OPENSSL_NO_OCSP +NON_EMPTY_TRANSLATION_UNIT +#else # ifdef OPENSSL_SYS_VMS # define _XOPEN_SOURCE_EXTENDED/* So fd_set and friends get properly defined * on OpenVMS */ @@ -69,8 +24,9 @@ # include # include # include -# include "apps.h" /* needs to be included before the openssl - * headers! */ + +/* Needs to be included before the openssl headers */ +# include "apps.h" # include # include # include @@ -115,12 +71,15 @@ static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser); static BIO *init_responder(const char *port); -static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, - const char *port); +static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio); static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp); -static OCSP_RESPONSE *query_responder(BIO *cbio, const char *path, + +# ifndef OPENSSL_NO_SOCK +static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host, + const char *path, const STACK_OF(CONF_VALUE) *headers, OCSP_REQUEST *req, int req_timeout); +# endif typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, @@ -131,7 +90,7 @@ typedef enum OPTION_choice { OPT_NO_CERT_CHECKS, OPT_NO_EXPLICIT, OPT_TRUST_OTHER, OPT_NO_INTERN, OPT_BADSIG, OPT_TEXT, OPT_REQ_TEXT, OPT_RESP_TEXT, OPT_REQIN, OPT_RESPIN, OPT_SIGNER, OPT_VAFILE, OPT_SIGN_OTHER, - OPT_VERIFY_OTHER, OPT_CAFILE, OPT_CAPATH, + OPT_VERIFY_OTHER, OPT_CAFILE, OPT_CAPATH, OPT_NOCAFILE, OPT_NOCAPATH, OPT_VALIDITY_PERIOD, OPT_STATUS_AGE, OPT_SIGNKEY, OPT_REQOUT, OPT_RESPOUT, OPT_PATH, OPT_ISSUER, OPT_CERT, OPT_SERIAL, OPT_INDEX, OPT_CA, OPT_NMIN, OPT_REQUEST, OPT_NDAYS, OPT_RSIGNER, @@ -143,9 +102,10 @@ typedef enum OPTION_choice { OPTIONS ocsp_options[] = { {"help", OPT_HELP, '-', "Display this summary"}, {"out", OPT_OUTFILE, '>', "Output filename"}, - {"timeout", OPT_TIMEOUT, 'p'}, + {"timeout", OPT_TIMEOUT, 'p', + "Connection timeout (in seconds) to the OCSP responder"}, {"url", OPT_URL, 's', "Responder URL"}, - {"host", OPT_HOST, 's', "host:prot top to connect to"}, + {"host", OPT_HOST, 's', "TCP/IP hostname:port to connect to"}, {"port", OPT_PORT, 'p', "Port to run responder on"}, {"ignore_err", OPT_IGNORE_ERR, '-'}, {"noverify", OPT_NOVERIFY, '-', "Don't verify response at all"}, @@ -154,7 +114,7 @@ OPTIONS ocsp_options[] = { {"resp_no_certs", OPT_RESP_NO_CERTS, '-', "Don't include any certificates in response"}, {"resp_key_id", OPT_RESP_KEY_ID, '-', - "Identify reponse by signing certificate key ID"}, + "Identify response by signing certificate key ID"}, {"no_certs", OPT_NO_CERTS, '-', "Don't include any certificates in signed request"}, {"no_signature_verify", OPT_NO_SIGNATURE_VERIFY, '-', @@ -169,7 +129,8 @@ OPTIONS ocsp_options[] = { "Don't verify additional certificates"}, {"no_intern", OPT_NO_INTERN, '-', "Don't search certificates contained in response for signer"}, - {"badsig", OPT_BADSIG, '-'}, + {"badsig", OPT_BADSIG, '-', + "Corrupt last byte of loaded OSCP response signature (for test)"}, {"text", OPT_TEXT, '-', "Print text form of request and response"}, {"req_text", OPT_REQ_TEXT, '-', "Print text form of request"}, {"resp_text", OPT_RESP_TEXT, '-', "Print text form of response"}, @@ -183,6 +144,10 @@ OPTIONS ocsp_options[] = { "Additional certificates to search for signer"}, {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"}, {"CApath", OPT_CAPATH, '<', "Trusted certificates directory"}, + {"no-CAfile", OPT_NOCAFILE, '-', + "Do not load the default certificates file"}, + {"no-CApath", OPT_NOCAPATH, '-', + "Do not load certificates from the default certificates directory"}, {"validity_period", OPT_VALIDITY_PERIOD, 'u', "Maximum validity discrepancy in seconds"}, {"status_age", OPT_STATUS_AGE, 'p', "Maximum status age in seconds"}, @@ -192,7 +157,7 @@ OPTIONS ocsp_options[] = { {"path", OPT_PATH, 's', "Path to use in OCSP request"}, {"issuer", OPT_ISSUER, '<', "Issuer certificate"}, {"cert", OPT_CERT, '<', "Certificate to check"}, - {"serial", OPT_SERIAL, 's', "Nerial number to check"}, + {"serial", OPT_SERIAL, 's', "Serial number to check"}, {"index", OPT_INDEX, '<', "Certificate status index file"}, {"CA", OPT_CA, '<', "CA certificate"}, {"nmin", OPT_NMIN, 'p', "Number of minutes before next update"}, @@ -200,12 +165,12 @@ OPTIONS ocsp_options[] = { "Number of requests to accept (default unlimited)"}, {"ndays", OPT_NDAYS, 'p', "Number of days before next update"}, {"rsigner", OPT_RSIGNER, '<', - "Sesponder certificate to sign responses with"}, + "Responder certificate to sign responses with"}, {"rkey", OPT_RKEY, '<', "Responder key to sign responses with"}, {"rother", OPT_ROTHER, '<', "Other certificates to include in response"}, - {"rmd", OPT_RMD, 's'}, + {"rmd", OPT_RMD, 's', "Digest Algorithm to use in signature of OCSP response"}, {"header", OPT_HEADER, 's', "key=value header to add"}, - {"", OPT_MD, '-', "Any supported digest"}, + {"", OPT_MD, '-', "Any supported digest algorithm (sha1,sha256, ... )"}, OPT_V_OPTIONS, {NULL} }; @@ -214,6 +179,7 @@ int ocsp_main(int argc, char **argv) { BIO *acbio = NULL, *cbio = NULL, *derbio = NULL, *out = NULL; const EVP_MD *cert_id_md = NULL, *rsign_md = NULL; + int trailing_md = 0; CA_DB *rdb = NULL; EVP_PKEY *key = NULL, *rkey = NULL; OCSP_BASICRESP *bs = NULL; @@ -236,9 +202,13 @@ int ocsp_main(int argc, char **argv) char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL; char *signfile = NULL, *keyfile = NULL; char *thost = NULL, *tport = NULL, *tpath = NULL; + int noCAfile = 0, noCApath = 0; int accept_count = -1, add_nonce = 1, noverify = 0, use_ssl = -1; int vpmtouched = 0, badsig = 0, i, ignore_err = 0, nmin = 0, ndays = -1; - int req_text = 0, resp_text = 0, req_timeout = -1, ret = 1; + int req_text = 0, resp_text = 0, ret = 1; +#ifndef OPENSSL_NO_SOCK + int req_timeout = -1; +#endif long nsec = MAX_VALIDITY_PERIOD, maxage = -1; unsigned long sign_flags = 0, verify_flags = 0, rflags = 0; OPTION_CHOICE o; @@ -269,12 +239,15 @@ int ocsp_main(int argc, char **argv) outfile = opt_arg(); break; case OPT_TIMEOUT: +#ifndef OPENSSL_NO_SOCK req_timeout = atoi(opt_arg()); +#endif break; case OPT_URL: OPENSSL_free(thost); OPENSSL_free(tport); OPENSSL_free(tpath); + thost = tport = tpath = NULL; if (!OCSP_parse_url(opt_arg(), &host, &port, &path, &use_ssl)) { BIO_printf(bio_err, "%s Error parsing URL\n", prog); goto end; @@ -368,6 +341,12 @@ int ocsp_main(int argc, char **argv) case OPT_CAPATH: CApath = opt_arg(); break; + case OPT_NOCAFILE: + noCAfile = 1; + break; + case OPT_NOCAPATH: + noCApath = 1; + break; case OPT_V_CASES: if (!opt_verify(o, vpm)) goto end; @@ -392,19 +371,18 @@ int ocsp_main(int argc, char **argv) path = opt_arg(); break; case OPT_ISSUER: - X509_free(issuer); - issuer = load_cert(opt_arg(), FORMAT_PEM, - NULL, NULL, "issuer certificate"); + issuer = load_cert(opt_arg(), FORMAT_PEM, "issuer certificate"); if (issuer == NULL) goto end; - if ((issuers = sk_X509_new_null()) == NULL) - goto end; + if (issuers == NULL) { + if ((issuers = sk_X509_new_null()) == NULL) + goto end; + } sk_X509_push(issuers, issuer); break; case OPT_CERT: X509_free(cert); - cert = load_cert(opt_arg(), FORMAT_PEM, - NULL, NULL, "certificate"); + cert = load_cert(opt_arg(), FORMAT_PEM, "certificate"); if (cert == NULL) goto end; if (cert_id_md == NULL) @@ -413,6 +391,7 @@ int ocsp_main(int argc, char **argv) goto end; if (!sk_OPENSSL_STRING_push(reqnames, opt_arg())) goto end; + trailing_md = 0; break; case OPT_SERIAL: if (cert_id_md == NULL) @@ -421,6 +400,7 @@ int ocsp_main(int argc, char **argv) goto end; if (!sk_OPENSSL_STRING_push(reqnames, opt_arg())) goto end; + trailing_md = 0; break; case OPT_INDEX: ridx_filename = opt_arg(); @@ -448,7 +428,7 @@ int ocsp_main(int argc, char **argv) case OPT_ROTHER: rcertfile = opt_arg(); break; - case OPT_RMD: + case OPT_RMD: /* Response MessageDigest */ if (!opt_md(opt_arg(), &rsign_md)) goto end; break; @@ -464,7 +444,7 @@ int ocsp_main(int argc, char **argv) goto end; break; case OPT_MD: - if (cert_id_md != NULL) { + if (trailing_md) { BIO_printf(bio_err, "%s: Digest must be before -cert or -serial\n", prog); @@ -472,20 +452,25 @@ int ocsp_main(int argc, char **argv) } if (!opt_md(opt_unknown(), &cert_id_md)) goto opthelp; + trailing_md = 1; break; } } + + if (trailing_md) { + BIO_printf(bio_err, "%s: Digest must be before -cert or -serial\n", + prog); + goto opthelp; + } argc = opt_num_rest(); - argv = opt_rest(); + if (argc != 0) + goto opthelp; /* Have we anything to do? */ if (!req && !reqin && !respin && !(port && ridx_filename)) goto opthelp; - if (!app_load_modules(NULL)) - goto end; - - out = bio_open_default(outfile, "w"); + out = bio_open_default(outfile, 'w', FORMAT_TEXT); if (out == NULL) goto end; @@ -493,7 +478,7 @@ int ocsp_main(int argc, char **argv) add_nonce = 0; if (!req && reqin) { - derbio = bio_open_default(reqin, "rb"); + derbio = bio_open_default(reqin, 'r', FORMAT_ASN1); if (derbio == NULL) goto end; req = d2i_OCSP_REQUEST_bio(derbio, NULL); @@ -510,21 +495,18 @@ int ocsp_main(int argc, char **argv) goto end; } - if (rsignfile && !rdb) { + if (rsignfile) { if (!rkeyfile) rkeyfile = rsignfile; - rsigner = load_cert(rsignfile, FORMAT_PEM, - NULL, NULL, "responder certificate"); + rsigner = load_cert(rsignfile, FORMAT_PEM, "responder certificate"); if (!rsigner) { BIO_printf(bio_err, "Error loading responder certificate\n"); goto end; } - rca_cert = load_cert(rca_filename, FORMAT_PEM, - NULL, NULL, "CA certificate"); + rca_cert = load_cert(rca_filename, FORMAT_PEM, "CA certificate"); if (rcertfile) { - rother = load_certs(rcertfile, FORMAT_PEM, - NULL, NULL, "responder other certificates"); - if (!rother) + if (!load_certs(rcertfile, &rother, FORMAT_PEM, NULL, + "responder other certificates")) goto end; } rkey = load_key(rkeyfile, FORMAT_PEM, 0, NULL, NULL, @@ -538,7 +520,7 @@ int ocsp_main(int argc, char **argv) redo_accept: if (acbio) { - if (!do_responder(&req, &cbio, acbio, port)) + if (!do_responder(&req, &cbio, acbio)) goto end; if (!req) { resp = @@ -560,16 +542,14 @@ int ocsp_main(int argc, char **argv) if (signfile) { if (!keyfile) keyfile = signfile; - signer = load_cert(signfile, FORMAT_PEM, - NULL, NULL, "signer certificate"); + signer = load_cert(signfile, FORMAT_PEM, "signer certificate"); if (!signer) { BIO_printf(bio_err, "Error loading signer certificate\n"); goto end; } if (sign_certfile) { - sign_other = load_certs(sign_certfile, FORMAT_PEM, - NULL, NULL, "signer certificates"); - if (!sign_other) + if (!load_certs(sign_certfile, &sign_other, FORMAT_PEM, NULL, + "signer certificates")) goto end; } key = load_key(keyfile, FORMAT_PEM, 0, NULL, NULL, @@ -588,7 +568,7 @@ int ocsp_main(int argc, char **argv) OCSP_REQUEST_print(out, req, 0); if (reqout) { - derbio = bio_open_default(reqout, "wb"); + derbio = bio_open_default(reqout, 'w', FORMAT_ASN1); if (derbio == NULL) goto end; i2d_OCSP_REQUEST_bio(derbio, req); @@ -626,7 +606,7 @@ int ocsp_main(int argc, char **argv) goto end; # endif } else if (respin) { - derbio = bio_open_default(respin, "rb"); + derbio = bio_open_default(respin, 'r', FORMAT_ASN1); if (derbio == NULL) goto end; resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); @@ -643,7 +623,7 @@ int ocsp_main(int argc, char **argv) done_resp: if (respout) { - derbio = bio_open_default(respout, "wb"); + derbio = bio_open_default(respout, 'w', FORMAT_ASN1); if (derbio == NULL) goto end; i2d_OCSP_RESPONSE_bio(derbio, resp); @@ -665,7 +645,8 @@ int ocsp_main(int argc, char **argv) /* If running as responder don't verify our own response */ if (cbio) { - if (--accept_count <= 0) { + /* If not unlimited, see if we took all we should. */ + if (accept_count != -1 && --accept_count <= 0) { ret = 0; goto end; } @@ -683,16 +664,15 @@ int ocsp_main(int argc, char **argv) } if (!store) { - store = setup_verify(CAfile, CApath); + store = setup_verify(CAfile, CApath, noCAfile, noCApath); if (!store) goto end; } if (vpmtouched) X509_STORE_set1_param(store, vpm); if (verify_certfile) { - verify_other = load_certs(verify_certfile, FORMAT_PEM, - NULL, NULL, "validator certificate"); - if (!verify_other) + if (!load_certs(verify_certfile, &verify_other, FORMAT_PEM, NULL, + "validator certificate")) goto end; } @@ -740,6 +720,7 @@ int ocsp_main(int argc, char **argv) EVP_PKEY_free(key); EVP_PKEY_free(rkey); X509_free(cert); + sk_X509_pop_free(issuers, X509_free); X509_free(rsigner); X509_free(rca_cert); free_index(rdb); @@ -770,9 +751,9 @@ static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, BIO_printf(bio_err, "No issuer certificate specified\n"); return 0; } - if (!*req) + if (*req == NULL) *req = OCSP_REQUEST_new(); - if (!*req) + if (*req == NULL) goto err; id = OCSP_cert_to_id(cert_id_md, cert, issuer); if (!id || !sk_OCSP_CERTID_push(ids, id)) @@ -798,9 +779,9 @@ static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, BIO_printf(bio_err, "No issuer certificate specified\n"); return 0; } - if (!*req) + if (*req == NULL) *req = OCSP_REQUEST_new(); - if (!*req) + if (*req == NULL) goto err; iname = X509_get_subject_name(issuer); ikey = X509_get0_pubkey_bitstr(issuer); @@ -811,7 +792,7 @@ static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, } id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno); ASN1_INTEGER_free(sno); - if (!id || !sk_OCSP_CERTID_push(ids, id)) + if (id == NULL || !sk_OCSP_CERTID_push(ids, id)) goto err; if (!OCSP_request_add0_id(*req, id)) goto err; @@ -901,7 +882,7 @@ static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, bs = OCSP_BASICRESP_new(); thisupd = X509_gmtime_adj(NULL, 0); if (ndays != -1) - nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24); + nextupd = X509_time_adj_ex(NULL, ndays, nmin * 60, NULL); /* Examine each certificate id in the request */ for (i = 0; i < id_count; i++) { @@ -994,7 +975,7 @@ static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser) OPENSSL_assert(bn); /* FIXME: should report an error at this * point and abort */ if (BN_is_zero(bn)) - itmp = BUF_strdup("00"); + itmp = OPENSSL_strdup("00"); else itmp = BN_bn2hex(bn); row[DB_serial] = itmp; @@ -1008,15 +989,15 @@ static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser) static BIO *init_responder(const char *port) { - BIO *acbio = NULL, *bufbio = NULL; - # ifdef OPENSSL_NO_SOCK BIO_printf(bio_err, "Error setting up accept BIO - sockets not supported.\n"); return NULL; -# endif +# else + BIO *acbio = NULL, *bufbio = NULL; + bufbio = BIO_new(BIO_f_buffer()); - if (!bufbio) + if (bufbio == NULL) goto err; acbio = BIO_new(BIO_s_accept()); if (acbio == NULL @@ -1041,9 +1022,10 @@ static BIO *init_responder(const char *port) BIO_free_all(acbio); BIO_free(bufbio); return NULL; +# endif } - +# ifndef OPENSSL_NO_SOCK /* * Decode %xx URL-decoding in-place. Ignores mal-formed sequences. */ @@ -1055,8 +1037,10 @@ static int urldecode(char *p) for (; *p; p++) { if (*p != '%') *out++ = *p; - else if (isxdigit(p[1]) && isxdigit(p[2])) { - *out++ = (app_hex(p[1]) << 4) | app_hex(p[2]); + else if (isxdigit(_UC(p[1])) && isxdigit(_UC(p[2]))) { + /* Don't check, can't fail because of ixdigit() call. */ + *out++ = (OPENSSL_hexchar2int(p[1]) << 4) + | OPENSSL_hexchar2int(p[2]); p += 2; } else @@ -1065,10 +1049,13 @@ static int urldecode(char *p) *out = '\0'; return (int)(out - save); } +# endif -static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, - const char *port) +static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio) { +# ifdef OPENSSL_NO_SOCK + return 0; +# else int len; OCSP_REQUEST *req = NULL; char inbuf[2048], reqbuf[2048]; @@ -1149,7 +1136,7 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, *preq = req; return 1; - +# endif } static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp) @@ -1165,13 +1152,16 @@ static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp) return 1; } -static OCSP_RESPONSE *query_responder(BIO *cbio, const char *path, +# ifndef OPENSSL_NO_SOCK +static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host, + const char *path, const STACK_OF(CONF_VALUE) *headers, OCSP_REQUEST *req, int req_timeout) { int fd; int rv; int i; + int add_host = 1; OCSP_REQ_CTX *ctx = NULL; OCSP_RESPONSE *rsp = NULL; fd_set confds; @@ -1187,7 +1177,7 @@ static OCSP_RESPONSE *query_responder(BIO *cbio, const char *path, return NULL; } - if (BIO_get_fd(cbio, &fd) <= 0) { + if (BIO_get_fd(cbio, &fd) < 0) { BIO_puts(bio_err, "Can't get connection fd\n"); goto err; } @@ -1205,15 +1195,20 @@ static OCSP_RESPONSE *query_responder(BIO *cbio, const char *path, } ctx = OCSP_sendreq_new(cbio, path, NULL, -1); - if (!ctx) + if (ctx == NULL) return NULL; for (i = 0; i < sk_CONF_VALUE_num(headers); i++) { CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i); + if (add_host == 1 && strcasecmp("host", hdr->name) == 0) + add_host = 0; if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value)) goto err; } + if (add_host == 1 && OCSP_REQ_CTX_add1_header(ctx, "Host", host) == 0) + goto err; + if (!OCSP_REQ_CTX_set1_req(ctx, req)) goto err; @@ -1254,12 +1249,13 @@ static OCSP_RESPONSE *query_responder(BIO *cbio, const char *path, OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, const char *host, const char *path, const char *port, int use_ssl, - const STACK_OF(CONF_VALUE) *headers, + STACK_OF(CONF_VALUE) *headers, int req_timeout) { BIO *cbio = NULL; SSL_CTX *ctx = NULL; OCSP_RESPONSE *resp = NULL; + cbio = BIO_new_connect(host); if (!cbio) { BIO_printf(bio_err, "Error creating connect BIO\n"); @@ -1278,7 +1274,8 @@ OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, sbio = BIO_new_ssl(ctx, 1); cbio = BIO_push(sbio, cbio); } - resp = query_responder(cbio, path, headers, req, req_timeout); + + resp = query_responder(cbio, host, path, headers, req, req_timeout); if (!resp) BIO_printf(bio_err, "Error querying OCSP responder\n"); end: @@ -1286,5 +1283,6 @@ OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, SSL_CTX_free(ctx); return resp; } +# endif #endif