X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=apps%2Focsp.c;h=41ea97030786e9b1b3d54a7f46ef0117b6745476;hb=12d56b2992ebd61e1b30c99ca1898dde42345cf7;hp=f9ba4e158ad82b7f21d548b959aff3ebbf943b4b;hpb=18295f0c2db084fe00d935d8506d6e964f652d21;p=openssl.git diff --git a/apps/ocsp.c b/apps/ocsp.c index f9ba4e158a..41ea970307 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,13 +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); + +# 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, @@ -144,18 +102,20 @@ 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, '-'}, + {"ignore_err", OPT_IGNORE_ERR, '-', + "Ignore Error response from OCSP responder, and retry "}, {"noverify", OPT_NOVERIFY, '-', "Don't verify response at all"}, {"nonce", OPT_NONCE, '-', "Add OCSP nonce to request"}, {"no_nonce", OPT_NO_NONCE, '-', "Don't add OCSP nonce to request"}, {"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, '-', @@ -165,12 +125,14 @@ OPTIONS ocsp_options[] = { {"no_chain", OPT_NO_CHAIN, '-', "Don't chain verify response"}, {"no_cert_checks", OPT_NO_CERT_CHECKS, '-', "Don't do additional checks on signing certificate"}, - {"no_explicit", OPT_NO_EXPLICIT, '-'}, + {"no_explicit", OPT_NO_EXPLICIT, '-', + "Do not explicitly check the chain, just verify the root"}, {"trust_other", OPT_TRUST_OTHER, '-', "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"}, @@ -197,7 +159,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"}, @@ -205,12 +167,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} }; @@ -219,6 +181,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; @@ -233,7 +196,8 @@ int ocsp_main(int argc, char **argv) X509 *signer = NULL, *rsigner = NULL; X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; - char *CAfile = NULL, *CApath = NULL, *header, *value; + const char *CAfile = NULL, *CApath = NULL; + char *header, *value; char *host = NULL, *port = NULL, *path = "/", *outfile = NULL; char *rca_filename = NULL, *reqin = NULL, *respin = NULL; char *reqout = NULL, *respout = NULL, *ridx_filename = NULL; @@ -244,7 +208,10 @@ int ocsp_main(int argc, char **argv) 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; @@ -275,7 +242,9 @@ 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); @@ -405,8 +374,7 @@ int ocsp_main(int argc, char **argv) path = opt_arg(); break; case OPT_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 == NULL) { @@ -417,8 +385,7 @@ int ocsp_main(int argc, char **argv) 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) @@ -427,6 +394,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) @@ -435,6 +403,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(); @@ -462,7 +431,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; @@ -478,7 +447,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); @@ -486,11 +455,19 @@ 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)) @@ -524,16 +501,14 @@ int ocsp_main(int argc, char **argv) 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) { - if (!load_certs(rcertfile, &rother, FORMAT_PEM, NULL, NULL, + if (!load_certs(rcertfile, &rother, FORMAT_PEM, NULL, "responder other certificates")) goto end; } @@ -548,7 +523,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 = @@ -570,14 +545,13 @@ 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) { - if (!load_certs(sign_certfile, &sign_other, FORMAT_PEM, NULL, NULL, + if (!load_certs(sign_certfile, &sign_other, FORMAT_PEM, NULL, "signer certificates")) goto end; } @@ -700,7 +674,7 @@ int ocsp_main(int argc, char **argv) if (vpmtouched) X509_STORE_set1_param(store, vpm); if (verify_certfile) { - if (!load_certs(verify_certfile, &verify_other, FORMAT_PEM, NULL, NULL, + if (!load_certs(verify_certfile, &verify_other, FORMAT_PEM, NULL, "validator certificate")) goto end; } @@ -838,7 +812,7 @@ static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, long maxage) { OCSP_CERTID *id; - char *name; + const char *name; int i, status, reason; ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; @@ -979,9 +953,8 @@ static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, OCSP_basic_sign(bs, rcert, rkey, rmd, rother, flags); if (badsig) { - ASN1_OCTET_STRING *sig = OCSP_resp_get0_signature(bs); - unsigned char *sigptr = ASN1_STRING_data(sig); - sigptr[ASN1_STRING_length(sig) - 1] ^= 0x1; + const ASN1_OCTET_STRING *sig = OCSP_resp_get0_signature(bs); + corrupt_signature(sig); } *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs); @@ -1018,13 +991,13 @@ 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 == NULL) goto err; @@ -1051,9 +1024,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. */ @@ -1066,7 +1040,9 @@ static int urldecode(char *p) if (*p != '%') *out++ = *p; else if (isxdigit(_UC(p[1])) && isxdigit(_UC(p[2]))) { - *out++ = (app_hex(p[1]) << 4) | app_hex(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 @@ -1075,10 +1051,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]; @@ -1159,7 +1138,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) @@ -1175,6 +1154,7 @@ static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp) return 1; } +# ifndef OPENSSL_NO_SOCK static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host, const char *path, const STACK_OF(CONF_VALUE) *headers, @@ -1305,5 +1285,6 @@ OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, SSL_CTX_free(ctx); return resp; } +# endif #endif