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