1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <openssl/opensslconf.h> 11e1051a39Sopenharmony_ci 12e1051a39Sopenharmony_ci#ifdef OPENSSL_SYS_VMS 13e1051a39Sopenharmony_ci /* So fd_set and friends get properly defined on OpenVMS */ 14e1051a39Sopenharmony_ci# define _XOPEN_SOURCE_EXTENDED 15e1051a39Sopenharmony_ci#endif 16e1051a39Sopenharmony_ci 17e1051a39Sopenharmony_ci#include <stdio.h> 18e1051a39Sopenharmony_ci#include <stdlib.h> 19e1051a39Sopenharmony_ci#include <string.h> 20e1051a39Sopenharmony_ci#include <time.h> 21e1051a39Sopenharmony_ci#include <ctype.h> 22e1051a39Sopenharmony_ci 23e1051a39Sopenharmony_ci/* Needs to be included before the openssl headers */ 24e1051a39Sopenharmony_ci#include "apps.h" 25e1051a39Sopenharmony_ci#include "http_server.h" 26e1051a39Sopenharmony_ci#include "progs.h" 27e1051a39Sopenharmony_ci#include "internal/sockets.h" 28e1051a39Sopenharmony_ci#include <openssl/e_os2.h> 29e1051a39Sopenharmony_ci#include <openssl/crypto.h> 30e1051a39Sopenharmony_ci#include <openssl/err.h> 31e1051a39Sopenharmony_ci#include <openssl/ssl.h> 32e1051a39Sopenharmony_ci#include <openssl/evp.h> 33e1051a39Sopenharmony_ci#include <openssl/bn.h> 34e1051a39Sopenharmony_ci#include <openssl/x509v3.h> 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_ci#if defined(__TANDEM) 37e1051a39Sopenharmony_ci# if defined(OPENSSL_TANDEM_FLOSS) 38e1051a39Sopenharmony_ci# include <floss.h(floss_fork)> 39e1051a39Sopenharmony_ci# endif 40e1051a39Sopenharmony_ci#endif 41e1051a39Sopenharmony_ci 42e1051a39Sopenharmony_ci#if defined(OPENSSL_SYS_VXWORKS) 43e1051a39Sopenharmony_ci/* not supported */ 44e1051a39Sopenharmony_ciint setpgid(pid_t pid, pid_t pgid) 45e1051a39Sopenharmony_ci{ 46e1051a39Sopenharmony_ci errno = ENOSYS; 47e1051a39Sopenharmony_ci return 0; 48e1051a39Sopenharmony_ci} 49e1051a39Sopenharmony_ci/* not supported */ 50e1051a39Sopenharmony_cipid_t fork(void) 51e1051a39Sopenharmony_ci{ 52e1051a39Sopenharmony_ci errno = ENOSYS; 53e1051a39Sopenharmony_ci return (pid_t) -1; 54e1051a39Sopenharmony_ci} 55e1051a39Sopenharmony_ci#endif 56e1051a39Sopenharmony_ci/* Maximum leeway in validity period: default 5 minutes */ 57e1051a39Sopenharmony_ci#define MAX_VALIDITY_PERIOD (5 * 60) 58e1051a39Sopenharmony_ci 59e1051a39Sopenharmony_cistatic int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, 60e1051a39Sopenharmony_ci const EVP_MD *cert_id_md, X509 *issuer, 61e1051a39Sopenharmony_ci STACK_OF(OCSP_CERTID) *ids); 62e1051a39Sopenharmony_cistatic int add_ocsp_serial(OCSP_REQUEST **req, char *serial, 63e1051a39Sopenharmony_ci const EVP_MD *cert_id_md, X509 *issuer, 64e1051a39Sopenharmony_ci STACK_OF(OCSP_CERTID) *ids); 65e1051a39Sopenharmony_cistatic int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, 66e1051a39Sopenharmony_ci STACK_OF(OPENSSL_STRING) *names, 67e1051a39Sopenharmony_ci STACK_OF(OCSP_CERTID) *ids, long nsec, 68e1051a39Sopenharmony_ci long maxage); 69e1051a39Sopenharmony_cistatic void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req, 70e1051a39Sopenharmony_ci CA_DB *db, STACK_OF(X509) *ca, X509 *rcert, 71e1051a39Sopenharmony_ci EVP_PKEY *rkey, const EVP_MD *md, 72e1051a39Sopenharmony_ci STACK_OF(OPENSSL_STRING) *sigopts, 73e1051a39Sopenharmony_ci STACK_OF(X509) *rother, unsigned long flags, 74e1051a39Sopenharmony_ci int nmin, int ndays, int badsig, 75e1051a39Sopenharmony_ci const EVP_MD *resp_md); 76e1051a39Sopenharmony_ci 77e1051a39Sopenharmony_cistatic char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser); 78e1051a39Sopenharmony_cistatic int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, 79e1051a39Sopenharmony_ci const char *port, int timeout); 80e1051a39Sopenharmony_cistatic int send_ocsp_response(BIO *cbio, const OCSP_RESPONSE *resp); 81e1051a39Sopenharmony_cistatic char *prog; 82e1051a39Sopenharmony_ci 83e1051a39Sopenharmony_ci#ifdef HTTP_DAEMON 84e1051a39Sopenharmony_cistatic int index_changed(CA_DB *); 85e1051a39Sopenharmony_ci#endif 86e1051a39Sopenharmony_ci 87e1051a39Sopenharmony_citypedef enum OPTION_choice { 88e1051a39Sopenharmony_ci OPT_COMMON, 89e1051a39Sopenharmony_ci OPT_OUTFILE, OPT_TIMEOUT, OPT_URL, OPT_HOST, OPT_PORT, 90e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SOCK 91e1051a39Sopenharmony_ci OPT_PROXY, OPT_NO_PROXY, 92e1051a39Sopenharmony_ci#endif 93e1051a39Sopenharmony_ci OPT_IGNORE_ERR, OPT_NOVERIFY, OPT_NONCE, OPT_NO_NONCE, 94e1051a39Sopenharmony_ci OPT_RESP_NO_CERTS, OPT_RESP_KEY_ID, OPT_NO_CERTS, 95e1051a39Sopenharmony_ci OPT_NO_SIGNATURE_VERIFY, OPT_NO_CERT_VERIFY, OPT_NO_CHAIN, 96e1051a39Sopenharmony_ci OPT_NO_CERT_CHECKS, OPT_NO_EXPLICIT, OPT_TRUST_OTHER, 97e1051a39Sopenharmony_ci OPT_NO_INTERN, OPT_BADSIG, OPT_TEXT, OPT_REQ_TEXT, OPT_RESP_TEXT, 98e1051a39Sopenharmony_ci OPT_REQIN, OPT_RESPIN, OPT_SIGNER, OPT_VAFILE, OPT_SIGN_OTHER, 99e1051a39Sopenharmony_ci OPT_VERIFY_OTHER, OPT_CAFILE, OPT_CAPATH, OPT_CASTORE, OPT_NOCAFILE, 100e1051a39Sopenharmony_ci OPT_NOCAPATH, OPT_NOCASTORE, 101e1051a39Sopenharmony_ci OPT_VALIDITY_PERIOD, OPT_STATUS_AGE, OPT_SIGNKEY, OPT_REQOUT, 102e1051a39Sopenharmony_ci OPT_RESPOUT, OPT_PATH, OPT_ISSUER, OPT_CERT, OPT_SERIAL, 103e1051a39Sopenharmony_ci OPT_INDEX, OPT_CA, OPT_NMIN, OPT_REQUEST, OPT_NDAYS, OPT_RSIGNER, 104e1051a39Sopenharmony_ci OPT_RKEY, OPT_ROTHER, OPT_RMD, OPT_RSIGOPT, OPT_HEADER, 105e1051a39Sopenharmony_ci OPT_PASSIN, 106e1051a39Sopenharmony_ci OPT_RCID, 107e1051a39Sopenharmony_ci OPT_V_ENUM, 108e1051a39Sopenharmony_ci OPT_MD, 109e1051a39Sopenharmony_ci OPT_MULTI, OPT_PROV_ENUM 110e1051a39Sopenharmony_ci} OPTION_CHOICE; 111e1051a39Sopenharmony_ci 112e1051a39Sopenharmony_ciconst OPTIONS ocsp_options[] = { 113e1051a39Sopenharmony_ci OPT_SECTION("General"), 114e1051a39Sopenharmony_ci {"help", OPT_HELP, '-', "Display this summary"}, 115e1051a39Sopenharmony_ci {"ignore_err", OPT_IGNORE_ERR, '-', 116e1051a39Sopenharmony_ci "Ignore error on OCSP request or response and continue running"}, 117e1051a39Sopenharmony_ci {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"}, 118e1051a39Sopenharmony_ci {"CApath", OPT_CAPATH, '<', "Trusted certificates directory"}, 119e1051a39Sopenharmony_ci {"CAstore", OPT_CASTORE, ':', "Trusted certificates store URI"}, 120e1051a39Sopenharmony_ci {"no-CAfile", OPT_NOCAFILE, '-', 121e1051a39Sopenharmony_ci "Do not load the default certificates file"}, 122e1051a39Sopenharmony_ci {"no-CApath", OPT_NOCAPATH, '-', 123e1051a39Sopenharmony_ci "Do not load certificates from the default certificates directory"}, 124e1051a39Sopenharmony_ci {"no-CAstore", OPT_NOCASTORE, '-', 125e1051a39Sopenharmony_ci "Do not load certificates from the default certificates store"}, 126e1051a39Sopenharmony_ci 127e1051a39Sopenharmony_ci OPT_SECTION("Responder"), 128e1051a39Sopenharmony_ci {"timeout", OPT_TIMEOUT, 'p', 129e1051a39Sopenharmony_ci "Connection timeout (in seconds) to the OCSP responder"}, 130e1051a39Sopenharmony_ci {"resp_no_certs", OPT_RESP_NO_CERTS, '-', 131e1051a39Sopenharmony_ci "Don't include any certificates in response"}, 132e1051a39Sopenharmony_ci#ifdef HTTP_DAEMON 133e1051a39Sopenharmony_ci {"multi", OPT_MULTI, 'p', "run multiple responder processes"}, 134e1051a39Sopenharmony_ci#endif 135e1051a39Sopenharmony_ci {"no_certs", OPT_NO_CERTS, '-', 136e1051a39Sopenharmony_ci "Don't include any certificates in signed request"}, 137e1051a39Sopenharmony_ci {"badsig", OPT_BADSIG, '-', 138e1051a39Sopenharmony_ci "Corrupt last byte of loaded OCSP response signature (for test)"}, 139e1051a39Sopenharmony_ci {"CA", OPT_CA, '<', "CA certificate"}, 140e1051a39Sopenharmony_ci {"nmin", OPT_NMIN, 'p', "Number of minutes before next update"}, 141e1051a39Sopenharmony_ci {"nrequest", OPT_REQUEST, 'p', 142e1051a39Sopenharmony_ci "Number of requests to accept (default unlimited)"}, 143e1051a39Sopenharmony_ci {"reqin", OPT_REQIN, 's', "File with the DER-encoded request"}, 144e1051a39Sopenharmony_ci {"signer", OPT_SIGNER, '<', "Certificate to sign OCSP request with"}, 145e1051a39Sopenharmony_ci {"sign_other", OPT_SIGN_OTHER, '<', 146e1051a39Sopenharmony_ci "Additional certificates to include in signed request"}, 147e1051a39Sopenharmony_ci {"index", OPT_INDEX, '<', "Certificate status index file"}, 148e1051a39Sopenharmony_ci {"ndays", OPT_NDAYS, 'p', "Number of days before next update"}, 149e1051a39Sopenharmony_ci {"rsigner", OPT_RSIGNER, '<', 150e1051a39Sopenharmony_ci "Responder certificate to sign responses with"}, 151e1051a39Sopenharmony_ci {"rkey", OPT_RKEY, '<', "Responder key to sign responses with"}, 152e1051a39Sopenharmony_ci {"passin", OPT_PASSIN, 's', "Responder key pass phrase source"}, 153e1051a39Sopenharmony_ci {"rother", OPT_ROTHER, '<', "Other certificates to include in response"}, 154e1051a39Sopenharmony_ci {"rmd", OPT_RMD, 's', "Digest Algorithm to use in signature of OCSP response"}, 155e1051a39Sopenharmony_ci {"rsigopt", OPT_RSIGOPT, 's', "OCSP response signature parameter in n:v form"}, 156e1051a39Sopenharmony_ci {"header", OPT_HEADER, 's', "key=value header to add"}, 157e1051a39Sopenharmony_ci {"rcid", OPT_RCID, 's', "Use specified algorithm for cert id in response"}, 158e1051a39Sopenharmony_ci {"", OPT_MD, '-', "Any supported digest algorithm (sha1,sha256, ... )"}, 159e1051a39Sopenharmony_ci 160e1051a39Sopenharmony_ci OPT_SECTION("Client"), 161e1051a39Sopenharmony_ci {"url", OPT_URL, 's', "Responder URL"}, 162e1051a39Sopenharmony_ci {"host", OPT_HOST, 's', "TCP/IP hostname:port to connect to"}, 163e1051a39Sopenharmony_ci {"port", OPT_PORT, 'N', "Port to run responder on"}, 164e1051a39Sopenharmony_ci {"path", OPT_PATH, 's', "Path to use in OCSP request"}, 165e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SOCK 166e1051a39Sopenharmony_ci {"proxy", OPT_PROXY, 's', 167e1051a39Sopenharmony_ci "[http[s]://]host[:port][/path] of HTTP(S) proxy to use; path is ignored"}, 168e1051a39Sopenharmony_ci {"no_proxy", OPT_NO_PROXY, 's', 169e1051a39Sopenharmony_ci "List of addresses of servers not to use HTTP(S) proxy for"}, 170e1051a39Sopenharmony_ci {OPT_MORE_STR, 0, 0, 171e1051a39Sopenharmony_ci "Default from environment variable 'no_proxy', else 'NO_PROXY', else none"}, 172e1051a39Sopenharmony_ci#endif 173e1051a39Sopenharmony_ci {"out", OPT_OUTFILE, '>', "Output filename"}, 174e1051a39Sopenharmony_ci {"noverify", OPT_NOVERIFY, '-', "Don't verify response at all"}, 175e1051a39Sopenharmony_ci {"nonce", OPT_NONCE, '-', "Add OCSP nonce to request"}, 176e1051a39Sopenharmony_ci {"no_nonce", OPT_NO_NONCE, '-', "Don't add OCSP nonce to request"}, 177e1051a39Sopenharmony_ci {"no_signature_verify", OPT_NO_SIGNATURE_VERIFY, '-', 178e1051a39Sopenharmony_ci "Don't check signature on response"}, 179e1051a39Sopenharmony_ci {"resp_key_id", OPT_RESP_KEY_ID, '-', 180e1051a39Sopenharmony_ci "Identify response by signing certificate key ID"}, 181e1051a39Sopenharmony_ci {"no_cert_verify", OPT_NO_CERT_VERIFY, '-', 182e1051a39Sopenharmony_ci "Don't check signing certificate"}, 183e1051a39Sopenharmony_ci {"text", OPT_TEXT, '-', "Print text form of request and response"}, 184e1051a39Sopenharmony_ci {"req_text", OPT_REQ_TEXT, '-', "Print text form of request"}, 185e1051a39Sopenharmony_ci {"resp_text", OPT_RESP_TEXT, '-', "Print text form of response"}, 186e1051a39Sopenharmony_ci {"no_chain", OPT_NO_CHAIN, '-', "Don't chain verify response"}, 187e1051a39Sopenharmony_ci {"no_cert_checks", OPT_NO_CERT_CHECKS, '-', 188e1051a39Sopenharmony_ci "Don't do additional checks on signing certificate"}, 189e1051a39Sopenharmony_ci {"no_explicit", OPT_NO_EXPLICIT, '-', 190e1051a39Sopenharmony_ci "Do not explicitly check the chain, just verify the root"}, 191e1051a39Sopenharmony_ci {"trust_other", OPT_TRUST_OTHER, '-', 192e1051a39Sopenharmony_ci "Don't verify additional certificates"}, 193e1051a39Sopenharmony_ci {"no_intern", OPT_NO_INTERN, '-', 194e1051a39Sopenharmony_ci "Don't search certificates contained in response for signer"}, 195e1051a39Sopenharmony_ci {"respin", OPT_RESPIN, 's', "File with the DER-encoded response"}, 196e1051a39Sopenharmony_ci {"VAfile", OPT_VAFILE, '<', "Validator certificates file"}, 197e1051a39Sopenharmony_ci {"verify_other", OPT_VERIFY_OTHER, '<', 198e1051a39Sopenharmony_ci "Additional certificates to search for signer"}, 199e1051a39Sopenharmony_ci {"cert", OPT_CERT, '<', "Certificate to check"}, 200e1051a39Sopenharmony_ci {"serial", OPT_SERIAL, 's', "Serial number to check"}, 201e1051a39Sopenharmony_ci {"validity_period", OPT_VALIDITY_PERIOD, 'u', 202e1051a39Sopenharmony_ci "Maximum validity discrepancy in seconds"}, 203e1051a39Sopenharmony_ci {"signkey", OPT_SIGNKEY, 's', "Private key to sign OCSP request with"}, 204e1051a39Sopenharmony_ci {"reqout", OPT_REQOUT, 's', "Output file for the DER-encoded request"}, 205e1051a39Sopenharmony_ci {"respout", OPT_RESPOUT, 's', "Output file for the DER-encoded response"}, 206e1051a39Sopenharmony_ci {"issuer", OPT_ISSUER, '<', "Issuer certificate"}, 207e1051a39Sopenharmony_ci {"status_age", OPT_STATUS_AGE, 'p', "Maximum status age in seconds"}, 208e1051a39Sopenharmony_ci 209e1051a39Sopenharmony_ci OPT_V_OPTIONS, 210e1051a39Sopenharmony_ci OPT_PROV_OPTIONS, 211e1051a39Sopenharmony_ci {NULL} 212e1051a39Sopenharmony_ci}; 213e1051a39Sopenharmony_ci 214e1051a39Sopenharmony_ciint ocsp_main(int argc, char **argv) 215e1051a39Sopenharmony_ci{ 216e1051a39Sopenharmony_ci BIO *acbio = NULL, *cbio = NULL, *derbio = NULL, *out = NULL; 217e1051a39Sopenharmony_ci EVP_MD *cert_id_md = NULL, *rsign_md = NULL; 218e1051a39Sopenharmony_ci STACK_OF(OPENSSL_STRING) *rsign_sigopts = NULL; 219e1051a39Sopenharmony_ci int trailing_md = 0; 220e1051a39Sopenharmony_ci CA_DB *rdb = NULL; 221e1051a39Sopenharmony_ci EVP_PKEY *key = NULL, *rkey = NULL; 222e1051a39Sopenharmony_ci OCSP_BASICRESP *bs = NULL; 223e1051a39Sopenharmony_ci OCSP_REQUEST *req = NULL; 224e1051a39Sopenharmony_ci OCSP_RESPONSE *resp = NULL; 225e1051a39Sopenharmony_ci STACK_OF(CONF_VALUE) *headers = NULL; 226e1051a39Sopenharmony_ci STACK_OF(OCSP_CERTID) *ids = NULL; 227e1051a39Sopenharmony_ci STACK_OF(OPENSSL_STRING) *reqnames = NULL; 228e1051a39Sopenharmony_ci STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL; 229e1051a39Sopenharmony_ci STACK_OF(X509) *issuers = NULL; 230e1051a39Sopenharmony_ci X509 *issuer = NULL, *cert = NULL; 231e1051a39Sopenharmony_ci STACK_OF(X509) *rca_cert = NULL; 232e1051a39Sopenharmony_ci EVP_MD *resp_certid_md = NULL; 233e1051a39Sopenharmony_ci X509 *signer = NULL, *rsigner = NULL; 234e1051a39Sopenharmony_ci X509_STORE *store = NULL; 235e1051a39Sopenharmony_ci X509_VERIFY_PARAM *vpm = NULL; 236e1051a39Sopenharmony_ci const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL; 237e1051a39Sopenharmony_ci char *header, *value, *respdigname = NULL; 238e1051a39Sopenharmony_ci char *host = NULL, *port = NULL, *path = "/", *outfile = NULL; 239e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SOCK 240e1051a39Sopenharmony_ci char *opt_proxy = NULL; 241e1051a39Sopenharmony_ci char *opt_no_proxy = NULL; 242e1051a39Sopenharmony_ci#endif 243e1051a39Sopenharmony_ci char *rca_filename = NULL, *reqin = NULL, *respin = NULL; 244e1051a39Sopenharmony_ci char *reqout = NULL, *respout = NULL, *ridx_filename = NULL; 245e1051a39Sopenharmony_ci char *rsignfile = NULL, *rkeyfile = NULL; 246e1051a39Sopenharmony_ci char *passinarg = NULL, *passin = NULL; 247e1051a39Sopenharmony_ci char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL; 248e1051a39Sopenharmony_ci char *signfile = NULL, *keyfile = NULL; 249e1051a39Sopenharmony_ci char *thost = NULL, *tport = NULL, *tpath = NULL; 250e1051a39Sopenharmony_ci int noCAfile = 0, noCApath = 0, noCAstore = 0; 251e1051a39Sopenharmony_ci int accept_count = -1, add_nonce = 1, noverify = 0, use_ssl = -1; 252e1051a39Sopenharmony_ci int vpmtouched = 0, badsig = 0, i, ignore_err = 0, nmin = 0, ndays = -1; 253e1051a39Sopenharmony_ci int req_text = 0, resp_text = 0, res, ret = 1; 254e1051a39Sopenharmony_ci int req_timeout = -1; 255e1051a39Sopenharmony_ci long nsec = MAX_VALIDITY_PERIOD, maxage = -1; 256e1051a39Sopenharmony_ci unsigned long sign_flags = 0, verify_flags = 0, rflags = 0; 257e1051a39Sopenharmony_ci OPTION_CHOICE o; 258e1051a39Sopenharmony_ci 259e1051a39Sopenharmony_ci if ((reqnames = sk_OPENSSL_STRING_new_null()) == NULL 260e1051a39Sopenharmony_ci || (ids = sk_OCSP_CERTID_new_null()) == NULL 261e1051a39Sopenharmony_ci || (vpm = X509_VERIFY_PARAM_new()) == NULL) 262e1051a39Sopenharmony_ci goto end; 263e1051a39Sopenharmony_ci 264e1051a39Sopenharmony_ci prog = opt_init(argc, argv, ocsp_options); 265e1051a39Sopenharmony_ci while ((o = opt_next()) != OPT_EOF) { 266e1051a39Sopenharmony_ci switch (o) { 267e1051a39Sopenharmony_ci case OPT_EOF: 268e1051a39Sopenharmony_ci case OPT_ERR: 269e1051a39Sopenharmony_ci opthelp: 270e1051a39Sopenharmony_ci BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 271e1051a39Sopenharmony_ci goto end; 272e1051a39Sopenharmony_ci case OPT_HELP: 273e1051a39Sopenharmony_ci ret = 0; 274e1051a39Sopenharmony_ci opt_help(ocsp_options); 275e1051a39Sopenharmony_ci goto end; 276e1051a39Sopenharmony_ci case OPT_OUTFILE: 277e1051a39Sopenharmony_ci outfile = opt_arg(); 278e1051a39Sopenharmony_ci break; 279e1051a39Sopenharmony_ci case OPT_TIMEOUT: 280e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SOCK 281e1051a39Sopenharmony_ci req_timeout = atoi(opt_arg()); 282e1051a39Sopenharmony_ci#endif 283e1051a39Sopenharmony_ci break; 284e1051a39Sopenharmony_ci case OPT_URL: 285e1051a39Sopenharmony_ci OPENSSL_free(thost); 286e1051a39Sopenharmony_ci OPENSSL_free(tport); 287e1051a39Sopenharmony_ci OPENSSL_free(tpath); 288e1051a39Sopenharmony_ci thost = tport = tpath = NULL; 289e1051a39Sopenharmony_ci if (!OSSL_HTTP_parse_url(opt_arg(), &use_ssl, NULL /* userinfo */, 290e1051a39Sopenharmony_ci &host, &port, NULL /* port_num */, 291e1051a39Sopenharmony_ci &path, NULL /* qry */, NULL /* frag */)) { 292e1051a39Sopenharmony_ci BIO_printf(bio_err, "%s Error parsing -url argument\n", prog); 293e1051a39Sopenharmony_ci goto end; 294e1051a39Sopenharmony_ci } 295e1051a39Sopenharmony_ci thost = host; 296e1051a39Sopenharmony_ci tport = port; 297e1051a39Sopenharmony_ci tpath = path; 298e1051a39Sopenharmony_ci break; 299e1051a39Sopenharmony_ci case OPT_HOST: 300e1051a39Sopenharmony_ci host = opt_arg(); 301e1051a39Sopenharmony_ci break; 302e1051a39Sopenharmony_ci case OPT_PORT: 303e1051a39Sopenharmony_ci port = opt_arg(); 304e1051a39Sopenharmony_ci break; 305e1051a39Sopenharmony_ci case OPT_PATH: 306e1051a39Sopenharmony_ci path = opt_arg(); 307e1051a39Sopenharmony_ci break; 308e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SOCK 309e1051a39Sopenharmony_ci case OPT_PROXY: 310e1051a39Sopenharmony_ci opt_proxy = opt_arg(); 311e1051a39Sopenharmony_ci break; 312e1051a39Sopenharmony_ci case OPT_NO_PROXY: 313e1051a39Sopenharmony_ci opt_no_proxy = opt_arg(); 314e1051a39Sopenharmony_ci break; 315e1051a39Sopenharmony_ci#endif 316e1051a39Sopenharmony_ci case OPT_IGNORE_ERR: 317e1051a39Sopenharmony_ci ignore_err = 1; 318e1051a39Sopenharmony_ci break; 319e1051a39Sopenharmony_ci case OPT_NOVERIFY: 320e1051a39Sopenharmony_ci noverify = 1; 321e1051a39Sopenharmony_ci break; 322e1051a39Sopenharmony_ci case OPT_NONCE: 323e1051a39Sopenharmony_ci add_nonce = 2; 324e1051a39Sopenharmony_ci break; 325e1051a39Sopenharmony_ci case OPT_NO_NONCE: 326e1051a39Sopenharmony_ci add_nonce = 0; 327e1051a39Sopenharmony_ci break; 328e1051a39Sopenharmony_ci case OPT_RESP_NO_CERTS: 329e1051a39Sopenharmony_ci rflags |= OCSP_NOCERTS; 330e1051a39Sopenharmony_ci break; 331e1051a39Sopenharmony_ci case OPT_RESP_KEY_ID: 332e1051a39Sopenharmony_ci rflags |= OCSP_RESPID_KEY; 333e1051a39Sopenharmony_ci break; 334e1051a39Sopenharmony_ci case OPT_NO_CERTS: 335e1051a39Sopenharmony_ci sign_flags |= OCSP_NOCERTS; 336e1051a39Sopenharmony_ci break; 337e1051a39Sopenharmony_ci case OPT_NO_SIGNATURE_VERIFY: 338e1051a39Sopenharmony_ci verify_flags |= OCSP_NOSIGS; 339e1051a39Sopenharmony_ci break; 340e1051a39Sopenharmony_ci case OPT_NO_CERT_VERIFY: 341e1051a39Sopenharmony_ci verify_flags |= OCSP_NOVERIFY; 342e1051a39Sopenharmony_ci break; 343e1051a39Sopenharmony_ci case OPT_NO_CHAIN: 344e1051a39Sopenharmony_ci verify_flags |= OCSP_NOCHAIN; 345e1051a39Sopenharmony_ci break; 346e1051a39Sopenharmony_ci case OPT_NO_CERT_CHECKS: 347e1051a39Sopenharmony_ci verify_flags |= OCSP_NOCHECKS; 348e1051a39Sopenharmony_ci break; 349e1051a39Sopenharmony_ci case OPT_NO_EXPLICIT: 350e1051a39Sopenharmony_ci verify_flags |= OCSP_NOEXPLICIT; 351e1051a39Sopenharmony_ci break; 352e1051a39Sopenharmony_ci case OPT_TRUST_OTHER: 353e1051a39Sopenharmony_ci verify_flags |= OCSP_TRUSTOTHER; 354e1051a39Sopenharmony_ci break; 355e1051a39Sopenharmony_ci case OPT_NO_INTERN: 356e1051a39Sopenharmony_ci verify_flags |= OCSP_NOINTERN; 357e1051a39Sopenharmony_ci break; 358e1051a39Sopenharmony_ci case OPT_BADSIG: 359e1051a39Sopenharmony_ci badsig = 1; 360e1051a39Sopenharmony_ci break; 361e1051a39Sopenharmony_ci case OPT_TEXT: 362e1051a39Sopenharmony_ci req_text = resp_text = 1; 363e1051a39Sopenharmony_ci break; 364e1051a39Sopenharmony_ci case OPT_REQ_TEXT: 365e1051a39Sopenharmony_ci req_text = 1; 366e1051a39Sopenharmony_ci break; 367e1051a39Sopenharmony_ci case OPT_RESP_TEXT: 368e1051a39Sopenharmony_ci resp_text = 1; 369e1051a39Sopenharmony_ci break; 370e1051a39Sopenharmony_ci case OPT_REQIN: 371e1051a39Sopenharmony_ci reqin = opt_arg(); 372e1051a39Sopenharmony_ci break; 373e1051a39Sopenharmony_ci case OPT_RESPIN: 374e1051a39Sopenharmony_ci respin = opt_arg(); 375e1051a39Sopenharmony_ci break; 376e1051a39Sopenharmony_ci case OPT_SIGNER: 377e1051a39Sopenharmony_ci signfile = opt_arg(); 378e1051a39Sopenharmony_ci break; 379e1051a39Sopenharmony_ci case OPT_VAFILE: 380e1051a39Sopenharmony_ci verify_certfile = opt_arg(); 381e1051a39Sopenharmony_ci verify_flags |= OCSP_TRUSTOTHER; 382e1051a39Sopenharmony_ci break; 383e1051a39Sopenharmony_ci case OPT_SIGN_OTHER: 384e1051a39Sopenharmony_ci sign_certfile = opt_arg(); 385e1051a39Sopenharmony_ci break; 386e1051a39Sopenharmony_ci case OPT_VERIFY_OTHER: 387e1051a39Sopenharmony_ci verify_certfile = opt_arg(); 388e1051a39Sopenharmony_ci break; 389e1051a39Sopenharmony_ci case OPT_CAFILE: 390e1051a39Sopenharmony_ci CAfile = opt_arg(); 391e1051a39Sopenharmony_ci break; 392e1051a39Sopenharmony_ci case OPT_CAPATH: 393e1051a39Sopenharmony_ci CApath = opt_arg(); 394e1051a39Sopenharmony_ci break; 395e1051a39Sopenharmony_ci case OPT_CASTORE: 396e1051a39Sopenharmony_ci CAstore = opt_arg(); 397e1051a39Sopenharmony_ci break; 398e1051a39Sopenharmony_ci case OPT_NOCAFILE: 399e1051a39Sopenharmony_ci noCAfile = 1; 400e1051a39Sopenharmony_ci break; 401e1051a39Sopenharmony_ci case OPT_NOCAPATH: 402e1051a39Sopenharmony_ci noCApath = 1; 403e1051a39Sopenharmony_ci break; 404e1051a39Sopenharmony_ci case OPT_NOCASTORE: 405e1051a39Sopenharmony_ci noCAstore = 1; 406e1051a39Sopenharmony_ci break; 407e1051a39Sopenharmony_ci case OPT_V_CASES: 408e1051a39Sopenharmony_ci if (!opt_verify(o, vpm)) 409e1051a39Sopenharmony_ci goto end; 410e1051a39Sopenharmony_ci vpmtouched++; 411e1051a39Sopenharmony_ci break; 412e1051a39Sopenharmony_ci case OPT_VALIDITY_PERIOD: 413e1051a39Sopenharmony_ci opt_long(opt_arg(), &nsec); 414e1051a39Sopenharmony_ci break; 415e1051a39Sopenharmony_ci case OPT_STATUS_AGE: 416e1051a39Sopenharmony_ci opt_long(opt_arg(), &maxage); 417e1051a39Sopenharmony_ci break; 418e1051a39Sopenharmony_ci case OPT_SIGNKEY: 419e1051a39Sopenharmony_ci keyfile = opt_arg(); 420e1051a39Sopenharmony_ci break; 421e1051a39Sopenharmony_ci case OPT_REQOUT: 422e1051a39Sopenharmony_ci reqout = opt_arg(); 423e1051a39Sopenharmony_ci break; 424e1051a39Sopenharmony_ci case OPT_RESPOUT: 425e1051a39Sopenharmony_ci respout = opt_arg(); 426e1051a39Sopenharmony_ci break; 427e1051a39Sopenharmony_ci case OPT_ISSUER: 428e1051a39Sopenharmony_ci issuer = load_cert(opt_arg(), FORMAT_UNDEF, "issuer certificate"); 429e1051a39Sopenharmony_ci if (issuer == NULL) 430e1051a39Sopenharmony_ci goto end; 431e1051a39Sopenharmony_ci if (issuers == NULL) { 432e1051a39Sopenharmony_ci if ((issuers = sk_X509_new_null()) == NULL) 433e1051a39Sopenharmony_ci goto end; 434e1051a39Sopenharmony_ci } 435e1051a39Sopenharmony_ci if (!sk_X509_push(issuers, issuer)) 436e1051a39Sopenharmony_ci goto end; 437e1051a39Sopenharmony_ci break; 438e1051a39Sopenharmony_ci case OPT_CERT: 439e1051a39Sopenharmony_ci X509_free(cert); 440e1051a39Sopenharmony_ci cert = load_cert(opt_arg(), FORMAT_UNDEF, "certificate"); 441e1051a39Sopenharmony_ci if (cert == NULL) 442e1051a39Sopenharmony_ci goto end; 443e1051a39Sopenharmony_ci if (cert_id_md == NULL) 444e1051a39Sopenharmony_ci cert_id_md = (EVP_MD *)EVP_sha1(); 445e1051a39Sopenharmony_ci if (!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids)) 446e1051a39Sopenharmony_ci goto end; 447e1051a39Sopenharmony_ci if (!sk_OPENSSL_STRING_push(reqnames, opt_arg())) 448e1051a39Sopenharmony_ci goto end; 449e1051a39Sopenharmony_ci trailing_md = 0; 450e1051a39Sopenharmony_ci break; 451e1051a39Sopenharmony_ci case OPT_SERIAL: 452e1051a39Sopenharmony_ci if (cert_id_md == NULL) 453e1051a39Sopenharmony_ci cert_id_md = (EVP_MD *)EVP_sha1(); 454e1051a39Sopenharmony_ci if (!add_ocsp_serial(&req, opt_arg(), cert_id_md, issuer, ids)) 455e1051a39Sopenharmony_ci goto end; 456e1051a39Sopenharmony_ci if (!sk_OPENSSL_STRING_push(reqnames, opt_arg())) 457e1051a39Sopenharmony_ci goto end; 458e1051a39Sopenharmony_ci trailing_md = 0; 459e1051a39Sopenharmony_ci break; 460e1051a39Sopenharmony_ci case OPT_INDEX: 461e1051a39Sopenharmony_ci ridx_filename = opt_arg(); 462e1051a39Sopenharmony_ci break; 463e1051a39Sopenharmony_ci case OPT_CA: 464e1051a39Sopenharmony_ci rca_filename = opt_arg(); 465e1051a39Sopenharmony_ci break; 466e1051a39Sopenharmony_ci case OPT_NMIN: 467e1051a39Sopenharmony_ci nmin = opt_int_arg(); 468e1051a39Sopenharmony_ci if (ndays == -1) 469e1051a39Sopenharmony_ci ndays = 0; 470e1051a39Sopenharmony_ci break; 471e1051a39Sopenharmony_ci case OPT_REQUEST: 472e1051a39Sopenharmony_ci accept_count = opt_int_arg(); 473e1051a39Sopenharmony_ci break; 474e1051a39Sopenharmony_ci case OPT_NDAYS: 475e1051a39Sopenharmony_ci ndays = atoi(opt_arg()); 476e1051a39Sopenharmony_ci break; 477e1051a39Sopenharmony_ci case OPT_RSIGNER: 478e1051a39Sopenharmony_ci rsignfile = opt_arg(); 479e1051a39Sopenharmony_ci break; 480e1051a39Sopenharmony_ci case OPT_RKEY: 481e1051a39Sopenharmony_ci rkeyfile = opt_arg(); 482e1051a39Sopenharmony_ci break; 483e1051a39Sopenharmony_ci case OPT_PASSIN: 484e1051a39Sopenharmony_ci passinarg = opt_arg(); 485e1051a39Sopenharmony_ci break; 486e1051a39Sopenharmony_ci case OPT_ROTHER: 487e1051a39Sopenharmony_ci rcertfile = opt_arg(); 488e1051a39Sopenharmony_ci break; 489e1051a39Sopenharmony_ci case OPT_RMD: /* Response MessageDigest */ 490e1051a39Sopenharmony_ci respdigname = opt_arg(); 491e1051a39Sopenharmony_ci break; 492e1051a39Sopenharmony_ci case OPT_RSIGOPT: 493e1051a39Sopenharmony_ci if (rsign_sigopts == NULL) 494e1051a39Sopenharmony_ci rsign_sigopts = sk_OPENSSL_STRING_new_null(); 495e1051a39Sopenharmony_ci if (rsign_sigopts == NULL 496e1051a39Sopenharmony_ci || !sk_OPENSSL_STRING_push(rsign_sigopts, opt_arg())) 497e1051a39Sopenharmony_ci goto end; 498e1051a39Sopenharmony_ci break; 499e1051a39Sopenharmony_ci case OPT_HEADER: 500e1051a39Sopenharmony_ci header = opt_arg(); 501e1051a39Sopenharmony_ci value = strchr(header, '='); 502e1051a39Sopenharmony_ci if (value == NULL) { 503e1051a39Sopenharmony_ci BIO_printf(bio_err, "Missing = in header key=value\n"); 504e1051a39Sopenharmony_ci goto opthelp; 505e1051a39Sopenharmony_ci } 506e1051a39Sopenharmony_ci *value++ = '\0'; 507e1051a39Sopenharmony_ci if (!X509V3_add_value(header, value, &headers)) 508e1051a39Sopenharmony_ci goto end; 509e1051a39Sopenharmony_ci break; 510e1051a39Sopenharmony_ci case OPT_RCID: 511e1051a39Sopenharmony_ci if (!opt_md(opt_arg(), &resp_certid_md)) 512e1051a39Sopenharmony_ci goto opthelp; 513e1051a39Sopenharmony_ci break; 514e1051a39Sopenharmony_ci case OPT_MD: 515e1051a39Sopenharmony_ci if (trailing_md) { 516e1051a39Sopenharmony_ci BIO_printf(bio_err, 517e1051a39Sopenharmony_ci "%s: Digest must be before -cert or -serial\n", 518e1051a39Sopenharmony_ci prog); 519e1051a39Sopenharmony_ci goto opthelp; 520e1051a39Sopenharmony_ci } 521e1051a39Sopenharmony_ci if (!opt_md(opt_unknown(), &cert_id_md)) 522e1051a39Sopenharmony_ci goto opthelp; 523e1051a39Sopenharmony_ci trailing_md = 1; 524e1051a39Sopenharmony_ci break; 525e1051a39Sopenharmony_ci case OPT_MULTI: 526e1051a39Sopenharmony_ci#ifdef HTTP_DAEMON 527e1051a39Sopenharmony_ci multi = atoi(opt_arg()); 528e1051a39Sopenharmony_ci#endif 529e1051a39Sopenharmony_ci break; 530e1051a39Sopenharmony_ci case OPT_PROV_CASES: 531e1051a39Sopenharmony_ci if (!opt_provider(o)) 532e1051a39Sopenharmony_ci goto end; 533e1051a39Sopenharmony_ci break; 534e1051a39Sopenharmony_ci } 535e1051a39Sopenharmony_ci } 536e1051a39Sopenharmony_ci 537e1051a39Sopenharmony_ci /* No extra arguments. */ 538e1051a39Sopenharmony_ci argc = opt_num_rest(); 539e1051a39Sopenharmony_ci if (argc != 0) 540e1051a39Sopenharmony_ci goto opthelp; 541e1051a39Sopenharmony_ci 542e1051a39Sopenharmony_ci if (trailing_md) { 543e1051a39Sopenharmony_ci BIO_printf(bio_err, "%s: Digest must be before -cert or -serial\n", 544e1051a39Sopenharmony_ci prog); 545e1051a39Sopenharmony_ci goto opthelp; 546e1051a39Sopenharmony_ci } 547e1051a39Sopenharmony_ci 548e1051a39Sopenharmony_ci if (respdigname != NULL) { 549e1051a39Sopenharmony_ci if (!opt_md(respdigname, &rsign_md)) 550e1051a39Sopenharmony_ci goto end; 551e1051a39Sopenharmony_ci } 552e1051a39Sopenharmony_ci 553e1051a39Sopenharmony_ci /* Have we anything to do? */ 554e1051a39Sopenharmony_ci if (req == NULL && reqin == NULL 555e1051a39Sopenharmony_ci && respin == NULL && !(port != NULL && ridx_filename != NULL)) 556e1051a39Sopenharmony_ci goto opthelp; 557e1051a39Sopenharmony_ci 558e1051a39Sopenharmony_ci out = bio_open_default(outfile, 'w', FORMAT_TEXT); 559e1051a39Sopenharmony_ci if (out == NULL) 560e1051a39Sopenharmony_ci goto end; 561e1051a39Sopenharmony_ci 562e1051a39Sopenharmony_ci if (req == NULL && (add_nonce != 2)) 563e1051a39Sopenharmony_ci add_nonce = 0; 564e1051a39Sopenharmony_ci 565e1051a39Sopenharmony_ci if (req == NULL && reqin != NULL) { 566e1051a39Sopenharmony_ci derbio = bio_open_default(reqin, 'r', FORMAT_ASN1); 567e1051a39Sopenharmony_ci if (derbio == NULL) 568e1051a39Sopenharmony_ci goto end; 569e1051a39Sopenharmony_ci req = d2i_OCSP_REQUEST_bio(derbio, NULL); 570e1051a39Sopenharmony_ci BIO_free(derbio); 571e1051a39Sopenharmony_ci if (req == NULL) { 572e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error reading OCSP request\n"); 573e1051a39Sopenharmony_ci goto end; 574e1051a39Sopenharmony_ci } 575e1051a39Sopenharmony_ci } 576e1051a39Sopenharmony_ci 577e1051a39Sopenharmony_ci if (req == NULL && port != NULL) { 578e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SOCK 579e1051a39Sopenharmony_ci acbio = http_server_init_bio(prog, port); 580e1051a39Sopenharmony_ci if (acbio == NULL) 581e1051a39Sopenharmony_ci goto end; 582e1051a39Sopenharmony_ci#else 583e1051a39Sopenharmony_ci BIO_printf(bio_err, "Cannot act as server - sockets not supported\n"); 584e1051a39Sopenharmony_ci goto end; 585e1051a39Sopenharmony_ci#endif 586e1051a39Sopenharmony_ci } 587e1051a39Sopenharmony_ci 588e1051a39Sopenharmony_ci if (rsignfile != NULL) { 589e1051a39Sopenharmony_ci if (rkeyfile == NULL) 590e1051a39Sopenharmony_ci rkeyfile = rsignfile; 591e1051a39Sopenharmony_ci rsigner = load_cert(rsignfile, FORMAT_UNDEF, "responder certificate"); 592e1051a39Sopenharmony_ci if (rsigner == NULL) { 593e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error loading responder certificate\n"); 594e1051a39Sopenharmony_ci goto end; 595e1051a39Sopenharmony_ci } 596e1051a39Sopenharmony_ci if (!load_certs(rca_filename, 0, &rca_cert, NULL, "CA certificates")) 597e1051a39Sopenharmony_ci goto end; 598e1051a39Sopenharmony_ci if (rcertfile != NULL) { 599e1051a39Sopenharmony_ci if (!load_certs(rcertfile, 0, &rother, NULL, 600e1051a39Sopenharmony_ci "responder other certificates")) 601e1051a39Sopenharmony_ci goto end; 602e1051a39Sopenharmony_ci } 603e1051a39Sopenharmony_ci if (!app_passwd(passinarg, NULL, &passin, NULL)) { 604e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error getting password\n"); 605e1051a39Sopenharmony_ci goto end; 606e1051a39Sopenharmony_ci } 607e1051a39Sopenharmony_ci rkey = load_key(rkeyfile, FORMAT_UNDEF, 0, passin, NULL, 608e1051a39Sopenharmony_ci "responder private key"); 609e1051a39Sopenharmony_ci if (rkey == NULL) 610e1051a39Sopenharmony_ci goto end; 611e1051a39Sopenharmony_ci } 612e1051a39Sopenharmony_ci 613e1051a39Sopenharmony_ci if (ridx_filename != NULL 614e1051a39Sopenharmony_ci && (rkey == NULL || rsigner == NULL || rca_cert == NULL)) { 615e1051a39Sopenharmony_ci BIO_printf(bio_err, 616e1051a39Sopenharmony_ci "Responder mode requires certificate, key, and CA.\n"); 617e1051a39Sopenharmony_ci goto end; 618e1051a39Sopenharmony_ci } 619e1051a39Sopenharmony_ci 620e1051a39Sopenharmony_ci if (ridx_filename != NULL) { 621e1051a39Sopenharmony_ci rdb = load_index(ridx_filename, NULL); 622e1051a39Sopenharmony_ci if (rdb == NULL || index_index(rdb) <= 0) { 623e1051a39Sopenharmony_ci BIO_printf(bio_err, 624e1051a39Sopenharmony_ci "Problem with index file: %s (could not load/parse file)\n", 625e1051a39Sopenharmony_ci ridx_filename); 626e1051a39Sopenharmony_ci ret = 1; 627e1051a39Sopenharmony_ci goto end; 628e1051a39Sopenharmony_ci } 629e1051a39Sopenharmony_ci } 630e1051a39Sopenharmony_ci 631e1051a39Sopenharmony_ci#ifdef HTTP_DAEMON 632e1051a39Sopenharmony_ci if (multi && acbio != NULL) 633e1051a39Sopenharmony_ci spawn_loop(prog); 634e1051a39Sopenharmony_ci if (acbio != NULL && req_timeout > 0) 635e1051a39Sopenharmony_ci signal(SIGALRM, socket_timeout); 636e1051a39Sopenharmony_ci#endif 637e1051a39Sopenharmony_ci 638e1051a39Sopenharmony_ci if (acbio != NULL) 639e1051a39Sopenharmony_ci log_message(prog, LOG_INFO, "waiting for OCSP client connections..."); 640e1051a39Sopenharmony_ci 641e1051a39Sopenharmony_ciredo_accept: 642e1051a39Sopenharmony_ci 643e1051a39Sopenharmony_ci if (acbio != NULL) { 644e1051a39Sopenharmony_ci#ifdef HTTP_DAEMON 645e1051a39Sopenharmony_ci if (index_changed(rdb)) { 646e1051a39Sopenharmony_ci CA_DB *newrdb = load_index(ridx_filename, NULL); 647e1051a39Sopenharmony_ci 648e1051a39Sopenharmony_ci if (newrdb != NULL && index_index(newrdb) > 0) { 649e1051a39Sopenharmony_ci free_index(rdb); 650e1051a39Sopenharmony_ci rdb = newrdb; 651e1051a39Sopenharmony_ci } else { 652e1051a39Sopenharmony_ci free_index(newrdb); 653e1051a39Sopenharmony_ci log_message(prog, LOG_ERR, "error reloading updated index: %s", 654e1051a39Sopenharmony_ci ridx_filename); 655e1051a39Sopenharmony_ci } 656e1051a39Sopenharmony_ci } 657e1051a39Sopenharmony_ci#endif 658e1051a39Sopenharmony_ci 659e1051a39Sopenharmony_ci req = NULL; 660e1051a39Sopenharmony_ci res = do_responder(&req, &cbio, acbio, port, req_timeout); 661e1051a39Sopenharmony_ci if (res == 0) 662e1051a39Sopenharmony_ci goto redo_accept; 663e1051a39Sopenharmony_ci 664e1051a39Sopenharmony_ci if (req == NULL) { 665e1051a39Sopenharmony_ci if (res == 1) { 666e1051a39Sopenharmony_ci resp = 667e1051a39Sopenharmony_ci OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, 668e1051a39Sopenharmony_ci NULL); 669e1051a39Sopenharmony_ci send_ocsp_response(cbio, resp); 670e1051a39Sopenharmony_ci } 671e1051a39Sopenharmony_ci goto done_resp; 672e1051a39Sopenharmony_ci } 673e1051a39Sopenharmony_ci } 674e1051a39Sopenharmony_ci 675e1051a39Sopenharmony_ci if (req == NULL 676e1051a39Sopenharmony_ci && (signfile != NULL || reqout != NULL 677e1051a39Sopenharmony_ci || host != NULL || add_nonce || ridx_filename != NULL)) { 678e1051a39Sopenharmony_ci BIO_printf(bio_err, "Need an OCSP request for this operation!\n"); 679e1051a39Sopenharmony_ci goto end; 680e1051a39Sopenharmony_ci } 681e1051a39Sopenharmony_ci 682e1051a39Sopenharmony_ci if (req != NULL && add_nonce) { 683e1051a39Sopenharmony_ci if (!OCSP_request_add1_nonce(req, NULL, -1)) 684e1051a39Sopenharmony_ci goto end; 685e1051a39Sopenharmony_ci } 686e1051a39Sopenharmony_ci 687e1051a39Sopenharmony_ci if (signfile != NULL) { 688e1051a39Sopenharmony_ci if (keyfile == NULL) 689e1051a39Sopenharmony_ci keyfile = signfile; 690e1051a39Sopenharmony_ci signer = load_cert(signfile, FORMAT_UNDEF, "signer certificate"); 691e1051a39Sopenharmony_ci if (signer == NULL) { 692e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error loading signer certificate\n"); 693e1051a39Sopenharmony_ci goto end; 694e1051a39Sopenharmony_ci } 695e1051a39Sopenharmony_ci if (sign_certfile != NULL) { 696e1051a39Sopenharmony_ci if (!load_certs(sign_certfile, 0, &sign_other, NULL, 697e1051a39Sopenharmony_ci "signer certificates")) 698e1051a39Sopenharmony_ci goto end; 699e1051a39Sopenharmony_ci } 700e1051a39Sopenharmony_ci key = load_key(keyfile, FORMAT_UNDEF, 0, NULL, NULL, 701e1051a39Sopenharmony_ci "signer private key"); 702e1051a39Sopenharmony_ci if (key == NULL) 703e1051a39Sopenharmony_ci goto end; 704e1051a39Sopenharmony_ci 705e1051a39Sopenharmony_ci if (!OCSP_request_sign(req, signer, key, NULL, 706e1051a39Sopenharmony_ci sign_other, sign_flags)) { 707e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error signing OCSP request\n"); 708e1051a39Sopenharmony_ci goto end; 709e1051a39Sopenharmony_ci } 710e1051a39Sopenharmony_ci } 711e1051a39Sopenharmony_ci 712e1051a39Sopenharmony_ci if (req_text && req != NULL) 713e1051a39Sopenharmony_ci OCSP_REQUEST_print(out, req, 0); 714e1051a39Sopenharmony_ci 715e1051a39Sopenharmony_ci if (reqout != NULL) { 716e1051a39Sopenharmony_ci derbio = bio_open_default(reqout, 'w', FORMAT_ASN1); 717e1051a39Sopenharmony_ci if (derbio == NULL) 718e1051a39Sopenharmony_ci goto end; 719e1051a39Sopenharmony_ci i2d_OCSP_REQUEST_bio(derbio, req); 720e1051a39Sopenharmony_ci BIO_free(derbio); 721e1051a39Sopenharmony_ci } 722e1051a39Sopenharmony_ci 723e1051a39Sopenharmony_ci if (rdb != NULL) { 724e1051a39Sopenharmony_ci make_ocsp_response(bio_err, &resp, req, rdb, rca_cert, rsigner, rkey, 725e1051a39Sopenharmony_ci rsign_md, rsign_sigopts, rother, rflags, nmin, ndays, 726e1051a39Sopenharmony_ci badsig, resp_certid_md); 727e1051a39Sopenharmony_ci if (resp == NULL) 728e1051a39Sopenharmony_ci goto end; 729e1051a39Sopenharmony_ci if (cbio != NULL) 730e1051a39Sopenharmony_ci send_ocsp_response(cbio, resp); 731e1051a39Sopenharmony_ci } else if (host != NULL) { 732e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SOCK 733e1051a39Sopenharmony_ci resp = process_responder(req, host, port, path, opt_proxy, opt_no_proxy, 734e1051a39Sopenharmony_ci use_ssl, headers, req_timeout); 735e1051a39Sopenharmony_ci if (resp == NULL) 736e1051a39Sopenharmony_ci goto end; 737e1051a39Sopenharmony_ci#else 738e1051a39Sopenharmony_ci BIO_printf(bio_err, 739e1051a39Sopenharmony_ci "Error creating connect BIO - sockets not supported\n"); 740e1051a39Sopenharmony_ci goto end; 741e1051a39Sopenharmony_ci#endif 742e1051a39Sopenharmony_ci } else if (respin != NULL) { 743e1051a39Sopenharmony_ci derbio = bio_open_default(respin, 'r', FORMAT_ASN1); 744e1051a39Sopenharmony_ci if (derbio == NULL) 745e1051a39Sopenharmony_ci goto end; 746e1051a39Sopenharmony_ci resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); 747e1051a39Sopenharmony_ci BIO_free(derbio); 748e1051a39Sopenharmony_ci if (resp == NULL) { 749e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error reading OCSP response\n"); 750e1051a39Sopenharmony_ci goto end; 751e1051a39Sopenharmony_ci } 752e1051a39Sopenharmony_ci } else { 753e1051a39Sopenharmony_ci ret = 0; 754e1051a39Sopenharmony_ci goto end; 755e1051a39Sopenharmony_ci } 756e1051a39Sopenharmony_ci 757e1051a39Sopenharmony_ci done_resp: 758e1051a39Sopenharmony_ci 759e1051a39Sopenharmony_ci if (respout != NULL) { 760e1051a39Sopenharmony_ci derbio = bio_open_default(respout, 'w', FORMAT_ASN1); 761e1051a39Sopenharmony_ci if (derbio == NULL) 762e1051a39Sopenharmony_ci goto end; 763e1051a39Sopenharmony_ci i2d_OCSP_RESPONSE_bio(derbio, resp); 764e1051a39Sopenharmony_ci BIO_free(derbio); 765e1051a39Sopenharmony_ci } 766e1051a39Sopenharmony_ci 767e1051a39Sopenharmony_ci i = OCSP_response_status(resp); 768e1051a39Sopenharmony_ci if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) { 769e1051a39Sopenharmony_ci BIO_printf(out, "Responder Error: %s (%d)\n", 770e1051a39Sopenharmony_ci OCSP_response_status_str(i), i); 771e1051a39Sopenharmony_ci if (!ignore_err) 772e1051a39Sopenharmony_ci goto end; 773e1051a39Sopenharmony_ci } 774e1051a39Sopenharmony_ci 775e1051a39Sopenharmony_ci if (resp_text) 776e1051a39Sopenharmony_ci OCSP_RESPONSE_print(out, resp, 0); 777e1051a39Sopenharmony_ci 778e1051a39Sopenharmony_ci /* If running as responder don't verify our own response */ 779e1051a39Sopenharmony_ci if (cbio != NULL) { 780e1051a39Sopenharmony_ci /* If not unlimited, see if we took all we should. */ 781e1051a39Sopenharmony_ci if (accept_count != -1 && --accept_count <= 0) { 782e1051a39Sopenharmony_ci ret = 0; 783e1051a39Sopenharmony_ci goto end; 784e1051a39Sopenharmony_ci } 785e1051a39Sopenharmony_ci BIO_free_all(cbio); 786e1051a39Sopenharmony_ci cbio = NULL; 787e1051a39Sopenharmony_ci OCSP_REQUEST_free(req); 788e1051a39Sopenharmony_ci req = NULL; 789e1051a39Sopenharmony_ci OCSP_RESPONSE_free(resp); 790e1051a39Sopenharmony_ci resp = NULL; 791e1051a39Sopenharmony_ci goto redo_accept; 792e1051a39Sopenharmony_ci } 793e1051a39Sopenharmony_ci if (ridx_filename != NULL) { 794e1051a39Sopenharmony_ci ret = 0; 795e1051a39Sopenharmony_ci goto end; 796e1051a39Sopenharmony_ci } 797e1051a39Sopenharmony_ci 798e1051a39Sopenharmony_ci if (store == NULL) { 799e1051a39Sopenharmony_ci store = setup_verify(CAfile, noCAfile, CApath, noCApath, 800e1051a39Sopenharmony_ci CAstore, noCAstore); 801e1051a39Sopenharmony_ci if (!store) 802e1051a39Sopenharmony_ci goto end; 803e1051a39Sopenharmony_ci } 804e1051a39Sopenharmony_ci if (vpmtouched) 805e1051a39Sopenharmony_ci X509_STORE_set1_param(store, vpm); 806e1051a39Sopenharmony_ci if (verify_certfile != NULL) { 807e1051a39Sopenharmony_ci if (!load_certs(verify_certfile, 0, &verify_other, NULL, 808e1051a39Sopenharmony_ci "validator certificates")) 809e1051a39Sopenharmony_ci goto end; 810e1051a39Sopenharmony_ci } 811e1051a39Sopenharmony_ci 812e1051a39Sopenharmony_ci bs = OCSP_response_get1_basic(resp); 813e1051a39Sopenharmony_ci if (bs == NULL) { 814e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error parsing response\n"); 815e1051a39Sopenharmony_ci goto end; 816e1051a39Sopenharmony_ci } 817e1051a39Sopenharmony_ci 818e1051a39Sopenharmony_ci ret = 0; 819e1051a39Sopenharmony_ci 820e1051a39Sopenharmony_ci if (!noverify) { 821e1051a39Sopenharmony_ci if (req != NULL && ((i = OCSP_check_nonce(req, bs)) <= 0)) { 822e1051a39Sopenharmony_ci if (i == -1) 823e1051a39Sopenharmony_ci BIO_printf(bio_err, "WARNING: no nonce in response\n"); 824e1051a39Sopenharmony_ci else { 825e1051a39Sopenharmony_ci BIO_printf(bio_err, "Nonce Verify error\n"); 826e1051a39Sopenharmony_ci ret = 1; 827e1051a39Sopenharmony_ci goto end; 828e1051a39Sopenharmony_ci } 829e1051a39Sopenharmony_ci } 830e1051a39Sopenharmony_ci 831e1051a39Sopenharmony_ci i = OCSP_basic_verify(bs, verify_other, store, verify_flags); 832e1051a39Sopenharmony_ci if (i <= 0 && issuers) { 833e1051a39Sopenharmony_ci i = OCSP_basic_verify(bs, issuers, store, OCSP_TRUSTOTHER); 834e1051a39Sopenharmony_ci if (i > 0) 835e1051a39Sopenharmony_ci ERR_clear_error(); 836e1051a39Sopenharmony_ci } 837e1051a39Sopenharmony_ci if (i <= 0) { 838e1051a39Sopenharmony_ci BIO_printf(bio_err, "Response Verify Failure\n"); 839e1051a39Sopenharmony_ci ERR_print_errors(bio_err); 840e1051a39Sopenharmony_ci ret = 1; 841e1051a39Sopenharmony_ci } else { 842e1051a39Sopenharmony_ci BIO_printf(bio_err, "Response verify OK\n"); 843e1051a39Sopenharmony_ci } 844e1051a39Sopenharmony_ci } 845e1051a39Sopenharmony_ci 846e1051a39Sopenharmony_ci if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage)) 847e1051a39Sopenharmony_ci ret = 1; 848e1051a39Sopenharmony_ci 849e1051a39Sopenharmony_ci end: 850e1051a39Sopenharmony_ci ERR_print_errors(bio_err); 851e1051a39Sopenharmony_ci X509_free(signer); 852e1051a39Sopenharmony_ci X509_STORE_free(store); 853e1051a39Sopenharmony_ci X509_VERIFY_PARAM_free(vpm); 854e1051a39Sopenharmony_ci sk_OPENSSL_STRING_free(rsign_sigopts); 855e1051a39Sopenharmony_ci EVP_PKEY_free(key); 856e1051a39Sopenharmony_ci EVP_PKEY_free(rkey); 857e1051a39Sopenharmony_ci EVP_MD_free(cert_id_md); 858e1051a39Sopenharmony_ci EVP_MD_free(rsign_md); 859e1051a39Sopenharmony_ci EVP_MD_free(resp_certid_md); 860e1051a39Sopenharmony_ci X509_free(cert); 861e1051a39Sopenharmony_ci sk_X509_pop_free(issuers, X509_free); 862e1051a39Sopenharmony_ci X509_free(rsigner); 863e1051a39Sopenharmony_ci sk_X509_pop_free(rca_cert, X509_free); 864e1051a39Sopenharmony_ci free_index(rdb); 865e1051a39Sopenharmony_ci BIO_free_all(cbio); 866e1051a39Sopenharmony_ci BIO_free_all(acbio); 867e1051a39Sopenharmony_ci BIO_free_all(out); 868e1051a39Sopenharmony_ci OCSP_REQUEST_free(req); 869e1051a39Sopenharmony_ci OCSP_RESPONSE_free(resp); 870e1051a39Sopenharmony_ci OCSP_BASICRESP_free(bs); 871e1051a39Sopenharmony_ci sk_OPENSSL_STRING_free(reqnames); 872e1051a39Sopenharmony_ci sk_OCSP_CERTID_free(ids); 873e1051a39Sopenharmony_ci sk_X509_pop_free(sign_other, X509_free); 874e1051a39Sopenharmony_ci sk_X509_pop_free(verify_other, X509_free); 875e1051a39Sopenharmony_ci sk_CONF_VALUE_pop_free(headers, X509V3_conf_free); 876e1051a39Sopenharmony_ci OPENSSL_free(thost); 877e1051a39Sopenharmony_ci OPENSSL_free(tport); 878e1051a39Sopenharmony_ci OPENSSL_free(tpath); 879e1051a39Sopenharmony_ci 880e1051a39Sopenharmony_ci return ret; 881e1051a39Sopenharmony_ci} 882e1051a39Sopenharmony_ci 883e1051a39Sopenharmony_ci#ifdef HTTP_DAEMON 884e1051a39Sopenharmony_ci 885e1051a39Sopenharmony_cistatic int index_changed(CA_DB *rdb) 886e1051a39Sopenharmony_ci{ 887e1051a39Sopenharmony_ci struct stat sb; 888e1051a39Sopenharmony_ci 889e1051a39Sopenharmony_ci if (rdb != NULL && stat(rdb->dbfname, &sb) != -1) { 890e1051a39Sopenharmony_ci if (rdb->dbst.st_mtime != sb.st_mtime 891e1051a39Sopenharmony_ci || rdb->dbst.st_ctime != sb.st_ctime 892e1051a39Sopenharmony_ci || rdb->dbst.st_ino != sb.st_ino 893e1051a39Sopenharmony_ci || rdb->dbst.st_dev != sb.st_dev) { 894e1051a39Sopenharmony_ci syslog(LOG_INFO, "index file changed, reloading"); 895e1051a39Sopenharmony_ci return 1; 896e1051a39Sopenharmony_ci } 897e1051a39Sopenharmony_ci } 898e1051a39Sopenharmony_ci return 0; 899e1051a39Sopenharmony_ci} 900e1051a39Sopenharmony_ci 901e1051a39Sopenharmony_ci#endif 902e1051a39Sopenharmony_ci 903e1051a39Sopenharmony_cistatic int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, 904e1051a39Sopenharmony_ci const EVP_MD *cert_id_md, X509 *issuer, 905e1051a39Sopenharmony_ci STACK_OF(OCSP_CERTID) *ids) 906e1051a39Sopenharmony_ci{ 907e1051a39Sopenharmony_ci OCSP_CERTID *id; 908e1051a39Sopenharmony_ci 909e1051a39Sopenharmony_ci if (issuer == NULL) { 910e1051a39Sopenharmony_ci BIO_printf(bio_err, "No issuer certificate specified\n"); 911e1051a39Sopenharmony_ci return 0; 912e1051a39Sopenharmony_ci } 913e1051a39Sopenharmony_ci if (*req == NULL) 914e1051a39Sopenharmony_ci *req = OCSP_REQUEST_new(); 915e1051a39Sopenharmony_ci if (*req == NULL) 916e1051a39Sopenharmony_ci goto err; 917e1051a39Sopenharmony_ci id = OCSP_cert_to_id(cert_id_md, cert, issuer); 918e1051a39Sopenharmony_ci if (id == NULL || !sk_OCSP_CERTID_push(ids, id)) 919e1051a39Sopenharmony_ci goto err; 920e1051a39Sopenharmony_ci if (!OCSP_request_add0_id(*req, id)) 921e1051a39Sopenharmony_ci goto err; 922e1051a39Sopenharmony_ci return 1; 923e1051a39Sopenharmony_ci 924e1051a39Sopenharmony_ci err: 925e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error Creating OCSP request\n"); 926e1051a39Sopenharmony_ci return 0; 927e1051a39Sopenharmony_ci} 928e1051a39Sopenharmony_ci 929e1051a39Sopenharmony_cistatic int add_ocsp_serial(OCSP_REQUEST **req, char *serial, 930e1051a39Sopenharmony_ci const EVP_MD *cert_id_md, X509 *issuer, 931e1051a39Sopenharmony_ci STACK_OF(OCSP_CERTID) *ids) 932e1051a39Sopenharmony_ci{ 933e1051a39Sopenharmony_ci OCSP_CERTID *id; 934e1051a39Sopenharmony_ci const X509_NAME *iname; 935e1051a39Sopenharmony_ci ASN1_BIT_STRING *ikey; 936e1051a39Sopenharmony_ci ASN1_INTEGER *sno; 937e1051a39Sopenharmony_ci 938e1051a39Sopenharmony_ci if (issuer == NULL) { 939e1051a39Sopenharmony_ci BIO_printf(bio_err, "No issuer certificate specified\n"); 940e1051a39Sopenharmony_ci return 0; 941e1051a39Sopenharmony_ci } 942e1051a39Sopenharmony_ci if (*req == NULL) 943e1051a39Sopenharmony_ci *req = OCSP_REQUEST_new(); 944e1051a39Sopenharmony_ci if (*req == NULL) 945e1051a39Sopenharmony_ci goto err; 946e1051a39Sopenharmony_ci iname = X509_get_subject_name(issuer); 947e1051a39Sopenharmony_ci ikey = X509_get0_pubkey_bitstr(issuer); 948e1051a39Sopenharmony_ci sno = s2i_ASN1_INTEGER(NULL, serial); 949e1051a39Sopenharmony_ci if (sno == NULL) { 950e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error converting serial number %s\n", serial); 951e1051a39Sopenharmony_ci return 0; 952e1051a39Sopenharmony_ci } 953e1051a39Sopenharmony_ci id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno); 954e1051a39Sopenharmony_ci ASN1_INTEGER_free(sno); 955e1051a39Sopenharmony_ci if (id == NULL || !sk_OCSP_CERTID_push(ids, id)) 956e1051a39Sopenharmony_ci goto err; 957e1051a39Sopenharmony_ci if (!OCSP_request_add0_id(*req, id)) 958e1051a39Sopenharmony_ci goto err; 959e1051a39Sopenharmony_ci return 1; 960e1051a39Sopenharmony_ci 961e1051a39Sopenharmony_ci err: 962e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error Creating OCSP request\n"); 963e1051a39Sopenharmony_ci return 0; 964e1051a39Sopenharmony_ci} 965e1051a39Sopenharmony_ci 966e1051a39Sopenharmony_cistatic int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, 967e1051a39Sopenharmony_ci STACK_OF(OPENSSL_STRING) *names, 968e1051a39Sopenharmony_ci STACK_OF(OCSP_CERTID) *ids, long nsec, 969e1051a39Sopenharmony_ci long maxage) 970e1051a39Sopenharmony_ci{ 971e1051a39Sopenharmony_ci OCSP_CERTID *id; 972e1051a39Sopenharmony_ci const char *name; 973e1051a39Sopenharmony_ci int i, status, reason; 974e1051a39Sopenharmony_ci ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; 975e1051a39Sopenharmony_ci int ret = 1; 976e1051a39Sopenharmony_ci 977e1051a39Sopenharmony_ci if (req == NULL || !sk_OPENSSL_STRING_num(names)) 978e1051a39Sopenharmony_ci return 1; 979e1051a39Sopenharmony_ci 980e1051a39Sopenharmony_ci if (bs == NULL || !sk_OCSP_CERTID_num(ids)) 981e1051a39Sopenharmony_ci return 0; 982e1051a39Sopenharmony_ci 983e1051a39Sopenharmony_ci for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) { 984e1051a39Sopenharmony_ci id = sk_OCSP_CERTID_value(ids, i); 985e1051a39Sopenharmony_ci name = sk_OPENSSL_STRING_value(names, i); 986e1051a39Sopenharmony_ci BIO_printf(out, "%s: ", name); 987e1051a39Sopenharmony_ci 988e1051a39Sopenharmony_ci if (!OCSP_resp_find_status(bs, id, &status, &reason, 989e1051a39Sopenharmony_ci &rev, &thisupd, &nextupd)) { 990e1051a39Sopenharmony_ci BIO_puts(out, "ERROR: No Status found.\n"); 991e1051a39Sopenharmony_ci ret = 0; 992e1051a39Sopenharmony_ci continue; 993e1051a39Sopenharmony_ci } 994e1051a39Sopenharmony_ci 995e1051a39Sopenharmony_ci /* 996e1051a39Sopenharmony_ci * Check validity: if invalid write to output BIO so we know which 997e1051a39Sopenharmony_ci * response this refers to. 998e1051a39Sopenharmony_ci */ 999e1051a39Sopenharmony_ci if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage)) { 1000e1051a39Sopenharmony_ci BIO_puts(out, "WARNING: Status times invalid.\n"); 1001e1051a39Sopenharmony_ci ERR_print_errors(out); 1002e1051a39Sopenharmony_ci } 1003e1051a39Sopenharmony_ci BIO_printf(out, "%s\n", OCSP_cert_status_str(status)); 1004e1051a39Sopenharmony_ci 1005e1051a39Sopenharmony_ci BIO_puts(out, "\tThis Update: "); 1006e1051a39Sopenharmony_ci ASN1_GENERALIZEDTIME_print(out, thisupd); 1007e1051a39Sopenharmony_ci BIO_puts(out, "\n"); 1008e1051a39Sopenharmony_ci 1009e1051a39Sopenharmony_ci if (nextupd) { 1010e1051a39Sopenharmony_ci BIO_puts(out, "\tNext Update: "); 1011e1051a39Sopenharmony_ci ASN1_GENERALIZEDTIME_print(out, nextupd); 1012e1051a39Sopenharmony_ci BIO_puts(out, "\n"); 1013e1051a39Sopenharmony_ci } 1014e1051a39Sopenharmony_ci 1015e1051a39Sopenharmony_ci if (status != V_OCSP_CERTSTATUS_REVOKED) 1016e1051a39Sopenharmony_ci continue; 1017e1051a39Sopenharmony_ci 1018e1051a39Sopenharmony_ci if (reason != -1) 1019e1051a39Sopenharmony_ci BIO_printf(out, "\tReason: %s\n", OCSP_crl_reason_str(reason)); 1020e1051a39Sopenharmony_ci 1021e1051a39Sopenharmony_ci BIO_puts(out, "\tRevocation Time: "); 1022e1051a39Sopenharmony_ci ASN1_GENERALIZEDTIME_print(out, rev); 1023e1051a39Sopenharmony_ci BIO_puts(out, "\n"); 1024e1051a39Sopenharmony_ci } 1025e1051a39Sopenharmony_ci return ret; 1026e1051a39Sopenharmony_ci} 1027e1051a39Sopenharmony_ci 1028e1051a39Sopenharmony_cistatic void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req, 1029e1051a39Sopenharmony_ci CA_DB *db, STACK_OF(X509) *ca, X509 *rcert, 1030e1051a39Sopenharmony_ci EVP_PKEY *rkey, const EVP_MD *rmd, 1031e1051a39Sopenharmony_ci STACK_OF(OPENSSL_STRING) *sigopts, 1032e1051a39Sopenharmony_ci STACK_OF(X509) *rother, unsigned long flags, 1033e1051a39Sopenharmony_ci int nmin, int ndays, int badsig, 1034e1051a39Sopenharmony_ci const EVP_MD *resp_md) 1035e1051a39Sopenharmony_ci{ 1036e1051a39Sopenharmony_ci ASN1_TIME *thisupd = NULL, *nextupd = NULL; 1037e1051a39Sopenharmony_ci OCSP_CERTID *cid; 1038e1051a39Sopenharmony_ci OCSP_BASICRESP *bs = NULL; 1039e1051a39Sopenharmony_ci int i, id_count; 1040e1051a39Sopenharmony_ci EVP_MD_CTX *mctx = NULL; 1041e1051a39Sopenharmony_ci EVP_PKEY_CTX *pkctx = NULL; 1042e1051a39Sopenharmony_ci 1043e1051a39Sopenharmony_ci id_count = OCSP_request_onereq_count(req); 1044e1051a39Sopenharmony_ci 1045e1051a39Sopenharmony_ci if (id_count <= 0) { 1046e1051a39Sopenharmony_ci *resp = 1047e1051a39Sopenharmony_ci OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); 1048e1051a39Sopenharmony_ci goto end; 1049e1051a39Sopenharmony_ci } 1050e1051a39Sopenharmony_ci 1051e1051a39Sopenharmony_ci bs = OCSP_BASICRESP_new(); 1052e1051a39Sopenharmony_ci thisupd = X509_gmtime_adj(NULL, 0); 1053e1051a39Sopenharmony_ci if (ndays != -1) 1054e1051a39Sopenharmony_ci nextupd = X509_time_adj_ex(NULL, ndays, nmin * 60, NULL); 1055e1051a39Sopenharmony_ci 1056e1051a39Sopenharmony_ci /* Examine each certificate id in the request */ 1057e1051a39Sopenharmony_ci for (i = 0; i < id_count; i++) { 1058e1051a39Sopenharmony_ci OCSP_ONEREQ *one; 1059e1051a39Sopenharmony_ci ASN1_INTEGER *serial; 1060e1051a39Sopenharmony_ci char **inf; 1061e1051a39Sopenharmony_ci int jj; 1062e1051a39Sopenharmony_ci int found = 0; 1063e1051a39Sopenharmony_ci ASN1_OBJECT *cert_id_md_oid; 1064e1051a39Sopenharmony_ci const EVP_MD *cert_id_md; 1065e1051a39Sopenharmony_ci OCSP_CERTID *cid_resp_md = NULL; 1066e1051a39Sopenharmony_ci 1067e1051a39Sopenharmony_ci one = OCSP_request_onereq_get0(req, i); 1068e1051a39Sopenharmony_ci cid = OCSP_onereq_get0_id(one); 1069e1051a39Sopenharmony_ci 1070e1051a39Sopenharmony_ci OCSP_id_get0_info(NULL, &cert_id_md_oid, NULL, NULL, cid); 1071e1051a39Sopenharmony_ci 1072e1051a39Sopenharmony_ci cert_id_md = EVP_get_digestbyobj(cert_id_md_oid); 1073e1051a39Sopenharmony_ci if (cert_id_md == NULL) { 1074e1051a39Sopenharmony_ci *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, 1075e1051a39Sopenharmony_ci NULL); 1076e1051a39Sopenharmony_ci goto end; 1077e1051a39Sopenharmony_ci } 1078e1051a39Sopenharmony_ci for (jj = 0; jj < sk_X509_num(ca) && !found; jj++) { 1079e1051a39Sopenharmony_ci X509 *ca_cert = sk_X509_value(ca, jj); 1080e1051a39Sopenharmony_ci OCSP_CERTID *ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca_cert); 1081e1051a39Sopenharmony_ci 1082e1051a39Sopenharmony_ci if (OCSP_id_issuer_cmp(ca_id, cid) == 0) { 1083e1051a39Sopenharmony_ci found = 1; 1084e1051a39Sopenharmony_ci if (resp_md != NULL) 1085e1051a39Sopenharmony_ci cid_resp_md = OCSP_cert_to_id(resp_md, NULL, ca_cert); 1086e1051a39Sopenharmony_ci } 1087e1051a39Sopenharmony_ci OCSP_CERTID_free(ca_id); 1088e1051a39Sopenharmony_ci } 1089e1051a39Sopenharmony_ci OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid); 1090e1051a39Sopenharmony_ci inf = lookup_serial(db, serial); 1091e1051a39Sopenharmony_ci 1092e1051a39Sopenharmony_ci /* at this point, we can have cid be an alias of cid_resp_md */ 1093e1051a39Sopenharmony_ci cid = (cid_resp_md != NULL) ? cid_resp_md : cid; 1094e1051a39Sopenharmony_ci 1095e1051a39Sopenharmony_ci if (!found) { 1096e1051a39Sopenharmony_ci OCSP_basic_add1_status(bs, cid, 1097e1051a39Sopenharmony_ci V_OCSP_CERTSTATUS_UNKNOWN, 1098e1051a39Sopenharmony_ci 0, NULL, thisupd, nextupd); 1099e1051a39Sopenharmony_ci continue; 1100e1051a39Sopenharmony_ci } 1101e1051a39Sopenharmony_ci if (inf == NULL) { 1102e1051a39Sopenharmony_ci OCSP_basic_add1_status(bs, cid, 1103e1051a39Sopenharmony_ci V_OCSP_CERTSTATUS_UNKNOWN, 1104e1051a39Sopenharmony_ci 0, NULL, thisupd, nextupd); 1105e1051a39Sopenharmony_ci } else if (inf[DB_type][0] == DB_TYPE_VAL) { 1106e1051a39Sopenharmony_ci OCSP_basic_add1_status(bs, cid, 1107e1051a39Sopenharmony_ci V_OCSP_CERTSTATUS_GOOD, 1108e1051a39Sopenharmony_ci 0, NULL, thisupd, nextupd); 1109e1051a39Sopenharmony_ci } else if (inf[DB_type][0] == DB_TYPE_REV) { 1110e1051a39Sopenharmony_ci ASN1_OBJECT *inst = NULL; 1111e1051a39Sopenharmony_ci ASN1_TIME *revtm = NULL; 1112e1051a39Sopenharmony_ci ASN1_GENERALIZEDTIME *invtm = NULL; 1113e1051a39Sopenharmony_ci OCSP_SINGLERESP *single; 1114e1051a39Sopenharmony_ci int reason = -1; 1115e1051a39Sopenharmony_ci 1116e1051a39Sopenharmony_ci unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]); 1117e1051a39Sopenharmony_ci single = OCSP_basic_add1_status(bs, cid, 1118e1051a39Sopenharmony_ci V_OCSP_CERTSTATUS_REVOKED, 1119e1051a39Sopenharmony_ci reason, revtm, thisupd, nextupd); 1120e1051a39Sopenharmony_ci if (single == NULL) { 1121e1051a39Sopenharmony_ci *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, 1122e1051a39Sopenharmony_ci NULL); 1123e1051a39Sopenharmony_ci goto end; 1124e1051a39Sopenharmony_ci } 1125e1051a39Sopenharmony_ci if (invtm != NULL) 1126e1051a39Sopenharmony_ci OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, 1127e1051a39Sopenharmony_ci invtm, 0, 0); 1128e1051a39Sopenharmony_ci else if (inst != NULL) 1129e1051a39Sopenharmony_ci OCSP_SINGLERESP_add1_ext_i2d(single, 1130e1051a39Sopenharmony_ci NID_hold_instruction_code, inst, 1131e1051a39Sopenharmony_ci 0, 0); 1132e1051a39Sopenharmony_ci ASN1_OBJECT_free(inst); 1133e1051a39Sopenharmony_ci ASN1_TIME_free(revtm); 1134e1051a39Sopenharmony_ci ASN1_GENERALIZEDTIME_free(invtm); 1135e1051a39Sopenharmony_ci } 1136e1051a39Sopenharmony_ci OCSP_CERTID_free(cid_resp_md); 1137e1051a39Sopenharmony_ci } 1138e1051a39Sopenharmony_ci 1139e1051a39Sopenharmony_ci OCSP_copy_nonce(bs, req); 1140e1051a39Sopenharmony_ci 1141e1051a39Sopenharmony_ci mctx = EVP_MD_CTX_new(); 1142e1051a39Sopenharmony_ci if ( mctx == NULL || !EVP_DigestSignInit(mctx, &pkctx, rmd, NULL, rkey)) { 1143e1051a39Sopenharmony_ci *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, NULL); 1144e1051a39Sopenharmony_ci goto end; 1145e1051a39Sopenharmony_ci } 1146e1051a39Sopenharmony_ci for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { 1147e1051a39Sopenharmony_ci char *sigopt = sk_OPENSSL_STRING_value(sigopts, i); 1148e1051a39Sopenharmony_ci 1149e1051a39Sopenharmony_ci if (pkey_ctrl_string(pkctx, sigopt) <= 0) { 1150e1051a39Sopenharmony_ci BIO_printf(err, "parameter error \"%s\"\n", sigopt); 1151e1051a39Sopenharmony_ci ERR_print_errors(bio_err); 1152e1051a39Sopenharmony_ci *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, 1153e1051a39Sopenharmony_ci NULL); 1154e1051a39Sopenharmony_ci goto end; 1155e1051a39Sopenharmony_ci } 1156e1051a39Sopenharmony_ci } 1157e1051a39Sopenharmony_ci if (!OCSP_basic_sign_ctx(bs, rcert, mctx, rother, flags)) { 1158e1051a39Sopenharmony_ci *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, bs); 1159e1051a39Sopenharmony_ci goto end; 1160e1051a39Sopenharmony_ci } 1161e1051a39Sopenharmony_ci 1162e1051a39Sopenharmony_ci if (badsig) { 1163e1051a39Sopenharmony_ci const ASN1_OCTET_STRING *sig = OCSP_resp_get0_signature(bs); 1164e1051a39Sopenharmony_ci corrupt_signature(sig); 1165e1051a39Sopenharmony_ci } 1166e1051a39Sopenharmony_ci 1167e1051a39Sopenharmony_ci *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs); 1168e1051a39Sopenharmony_ci 1169e1051a39Sopenharmony_ci end: 1170e1051a39Sopenharmony_ci EVP_MD_CTX_free(mctx); 1171e1051a39Sopenharmony_ci ASN1_TIME_free(thisupd); 1172e1051a39Sopenharmony_ci ASN1_TIME_free(nextupd); 1173e1051a39Sopenharmony_ci OCSP_BASICRESP_free(bs); 1174e1051a39Sopenharmony_ci} 1175e1051a39Sopenharmony_ci 1176e1051a39Sopenharmony_cistatic char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser) 1177e1051a39Sopenharmony_ci{ 1178e1051a39Sopenharmony_ci int i; 1179e1051a39Sopenharmony_ci BIGNUM *bn = NULL; 1180e1051a39Sopenharmony_ci char *itmp, *row[DB_NUMBER], **rrow; 1181e1051a39Sopenharmony_ci for (i = 0; i < DB_NUMBER; i++) 1182e1051a39Sopenharmony_ci row[i] = NULL; 1183e1051a39Sopenharmony_ci bn = ASN1_INTEGER_to_BN(ser, NULL); 1184e1051a39Sopenharmony_ci OPENSSL_assert(bn); /* FIXME: should report an error at this 1185e1051a39Sopenharmony_ci * point and abort */ 1186e1051a39Sopenharmony_ci if (BN_is_zero(bn)) { 1187e1051a39Sopenharmony_ci itmp = OPENSSL_strdup("00"); 1188e1051a39Sopenharmony_ci OPENSSL_assert(itmp); 1189e1051a39Sopenharmony_ci } else { 1190e1051a39Sopenharmony_ci itmp = BN_bn2hex(bn); 1191e1051a39Sopenharmony_ci } 1192e1051a39Sopenharmony_ci row[DB_serial] = itmp; 1193e1051a39Sopenharmony_ci BN_free(bn); 1194e1051a39Sopenharmony_ci rrow = TXT_DB_get_by_index(db->db, DB_serial, row); 1195e1051a39Sopenharmony_ci OPENSSL_free(itmp); 1196e1051a39Sopenharmony_ci return rrow; 1197e1051a39Sopenharmony_ci} 1198e1051a39Sopenharmony_ci 1199e1051a39Sopenharmony_cistatic int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, 1200e1051a39Sopenharmony_ci const char *port, int timeout) 1201e1051a39Sopenharmony_ci{ 1202e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SOCK 1203e1051a39Sopenharmony_ci return http_server_get_asn1_req(ASN1_ITEM_rptr(OCSP_REQUEST), 1204e1051a39Sopenharmony_ci (ASN1_VALUE **)preq, NULL, pcbio, acbio, 1205e1051a39Sopenharmony_ci NULL /* found_keep_alive */, 1206e1051a39Sopenharmony_ci prog, port, 1 /* accept_get */, timeout); 1207e1051a39Sopenharmony_ci#else 1208e1051a39Sopenharmony_ci BIO_printf(bio_err, 1209e1051a39Sopenharmony_ci "Error getting OCSP request - sockets not supported\n"); 1210e1051a39Sopenharmony_ci *preq = NULL; 1211e1051a39Sopenharmony_ci return 0; 1212e1051a39Sopenharmony_ci#endif 1213e1051a39Sopenharmony_ci} 1214e1051a39Sopenharmony_ci 1215e1051a39Sopenharmony_cistatic int send_ocsp_response(BIO *cbio, const OCSP_RESPONSE *resp) 1216e1051a39Sopenharmony_ci{ 1217e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SOCK 1218e1051a39Sopenharmony_ci return http_server_send_asn1_resp(cbio, 1219e1051a39Sopenharmony_ci 0 /* no keep-alive */, 1220e1051a39Sopenharmony_ci "application/ocsp-response", 1221e1051a39Sopenharmony_ci ASN1_ITEM_rptr(OCSP_RESPONSE), 1222e1051a39Sopenharmony_ci (const ASN1_VALUE *)resp); 1223e1051a39Sopenharmony_ci#else 1224e1051a39Sopenharmony_ci BIO_printf(bio_err, 1225e1051a39Sopenharmony_ci "Error sending OCSP response - sockets not supported\n"); 1226e1051a39Sopenharmony_ci return 0; 1227e1051a39Sopenharmony_ci#endif 1228e1051a39Sopenharmony_ci} 1229e1051a39Sopenharmony_ci 1230e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SOCK 1231e1051a39Sopenharmony_ciOCSP_RESPONSE *process_responder(OCSP_REQUEST *req, const char *host, 1232e1051a39Sopenharmony_ci const char *port, const char *path, 1233e1051a39Sopenharmony_ci const char *proxy, const char *no_proxy, 1234e1051a39Sopenharmony_ci int use_ssl, STACK_OF(CONF_VALUE) *headers, 1235e1051a39Sopenharmony_ci int req_timeout) 1236e1051a39Sopenharmony_ci{ 1237e1051a39Sopenharmony_ci SSL_CTX *ctx = NULL; 1238e1051a39Sopenharmony_ci OCSP_RESPONSE *resp = NULL; 1239e1051a39Sopenharmony_ci 1240e1051a39Sopenharmony_ci if (use_ssl == 1) { 1241e1051a39Sopenharmony_ci ctx = SSL_CTX_new(TLS_client_method()); 1242e1051a39Sopenharmony_ci if (ctx == NULL) { 1243e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error creating SSL context.\n"); 1244e1051a39Sopenharmony_ci goto end; 1245e1051a39Sopenharmony_ci } 1246e1051a39Sopenharmony_ci } 1247e1051a39Sopenharmony_ci 1248e1051a39Sopenharmony_ci resp = (OCSP_RESPONSE *) 1249e1051a39Sopenharmony_ci app_http_post_asn1(host, port, path, proxy, no_proxy, 1250e1051a39Sopenharmony_ci ctx, headers, "application/ocsp-request", 1251e1051a39Sopenharmony_ci (ASN1_VALUE *)req, ASN1_ITEM_rptr(OCSP_REQUEST), 1252e1051a39Sopenharmony_ci "application/ocsp-response", 1253e1051a39Sopenharmony_ci req_timeout, ASN1_ITEM_rptr(OCSP_RESPONSE)); 1254e1051a39Sopenharmony_ci 1255e1051a39Sopenharmony_ci if (resp == NULL) 1256e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error querying OCSP responder\n"); 1257e1051a39Sopenharmony_ci 1258e1051a39Sopenharmony_ci end: 1259e1051a39Sopenharmony_ci SSL_CTX_free(ctx); 1260e1051a39Sopenharmony_ci return resp; 1261e1051a39Sopenharmony_ci} 1262e1051a39Sopenharmony_ci#endif 1263