Home | History | Annotate | Line # | Download | only in apps
cmp.c revision 1.1.1.2
      1 /*
      2  * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved.
      3  * Copyright Nokia 2007-2019
      4  * Copyright Siemens AG 2015-2019
      5  *
      6  * Licensed under the Apache License 2.0 (the "License").  You may not use
      7  * this file except in compliance with the License.  You can obtain a copy
      8  * in the file LICENSE in the source distribution or at
      9  * https://www.openssl.org/source/license.html
     10  */
     11 
     12 /* This app is disabled when OPENSSL_NO_CMP is defined. */
     13 #include "internal/e_os.h"
     14 
     15 #include <string.h>
     16 #include <ctype.h>
     17 
     18 #include "apps.h"
     19 #include "http_server.h"
     20 #include "s_apps.h"
     21 #include "progs.h"
     22 
     23 #include "cmp_mock_srv.h"
     24 
     25 /* tweaks needed due to missing unistd.h on Windows */
     26 #if defined(_WIN32) && !defined(__BORLANDC__)
     27 #define access _access
     28 #endif
     29 #ifndef F_OK
     30 #define F_OK 0
     31 #endif
     32 
     33 #include <openssl/ui.h>
     34 #include <openssl/pkcs12.h>
     35 #include <openssl/ssl.h>
     36 
     37 /* explicit #includes not strictly needed since implied by the above: */
     38 #include <stdlib.h>
     39 #include <openssl/cmp.h>
     40 #include <openssl/cmp_util.h>
     41 #include <openssl/crmf.h>
     42 #include <openssl/crypto.h>
     43 #include <openssl/err.h>
     44 #include <openssl/store.h>
     45 #include <openssl/objects.h>
     46 #include <openssl/x509.h>
     47 
     48 static char *prog;
     49 static char *opt_config = NULL;
     50 #define CMP_SECTION "cmp"
     51 #define SECTION_NAME_MAX 40 /* max length of section name */
     52 #define DEFAULT_SECTION "default"
     53 static char *opt_section = CMP_SECTION;
     54 static int opt_verbosity = OSSL_CMP_LOG_INFO;
     55 
     56 static int read_config(void);
     57 
     58 static CONF *conf = NULL; /* OpenSSL config file context structure */
     59 static OSSL_CMP_CTX *cmp_ctx = NULL; /* the client-side CMP context */
     60 
     61 /* the type of cmp command we want to send */
     62 typedef enum {
     63     CMP_IR,
     64     CMP_KUR,
     65     CMP_CR,
     66     CMP_P10CR,
     67     CMP_RR,
     68     CMP_GENM
     69 } cmp_cmd_t;
     70 
     71 /* message transfer */
     72 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
     73 static char *opt_server = NULL;
     74 static char *opt_proxy = NULL;
     75 static char *opt_no_proxy = NULL;
     76 #endif
     77 static char *opt_recipient = NULL;
     78 static char *opt_path = NULL;
     79 static int opt_keep_alive = 1;
     80 static int opt_msg_timeout = -1;
     81 static int opt_total_timeout = -1;
     82 
     83 /* server authentication */
     84 static char *opt_trusted = NULL;
     85 static char *opt_untrusted = NULL;
     86 static char *opt_srvcert = NULL;
     87 static char *opt_expect_sender = NULL;
     88 static int opt_ignore_keyusage = 0;
     89 static int opt_unprotected_errors = 0;
     90 static int opt_no_cache_extracerts = 0;
     91 static char *opt_srvcertout = NULL;
     92 static char *opt_extracertsout = NULL;
     93 static char *opt_cacertsout = NULL;
     94 static char *opt_oldwithold = NULL;
     95 static char *opt_newwithnew = NULL;
     96 static char *opt_newwithold = NULL;
     97 static char *opt_oldwithnew = NULL;
     98 static char *opt_crlcert = NULL;
     99 static char *opt_oldcrl = NULL;
    100 static char *opt_crlout = NULL;
    101 static char *opt_template = NULL;
    102 static char *opt_keyspec = NULL;
    103 
    104 /* client authentication */
    105 static char *opt_ref = NULL;
    106 static char *opt_secret = NULL;
    107 static char *opt_cert = NULL;
    108 static char *opt_own_trusted = NULL;
    109 static char *opt_key = NULL;
    110 static char *opt_keypass = NULL;
    111 static char *opt_digest = NULL;
    112 static char *opt_mac = NULL;
    113 static char *opt_extracerts = NULL;
    114 static int opt_unprotected_requests = 0;
    115 
    116 /* generic message */
    117 static char *opt_cmd_s = NULL;
    118 static int opt_cmd = -1;
    119 static char *opt_geninfo = NULL;
    120 static char *opt_infotype_s = NULL;
    121 static int opt_infotype = NID_undef;
    122 static char *opt_profile = NULL;
    123 
    124 /* certificate enrollment */
    125 static char *opt_newkey = NULL;
    126 static char *opt_newkeypass = NULL;
    127 static int opt_centralkeygen = 0;
    128 static char *opt_newkeyout = NULL;
    129 static char *opt_subject = NULL;
    130 static int opt_days = 0;
    131 static char *opt_reqexts = NULL;
    132 static char *opt_sans = NULL;
    133 static int opt_san_nodefault = 0;
    134 static char *opt_policies = NULL;
    135 static char *opt_policy_oids = NULL;
    136 static int opt_policy_oids_critical = 0;
    137 static int opt_popo = OSSL_CRMF_POPO_NONE - 1;
    138 static char *opt_csr = NULL;
    139 static char *opt_out_trusted = NULL;
    140 static int opt_implicit_confirm = 0;
    141 static int opt_disable_confirm = 0;
    142 static char *opt_certout = NULL;
    143 static char *opt_chainout = NULL;
    144 
    145 /* certificate enrollment and revocation */
    146 static char *opt_oldcert = NULL;
    147 static char *opt_issuer = NULL;
    148 static char *opt_serial = NULL;
    149 static int opt_revreason = CRL_REASON_NONE;
    150 
    151 /* credentials format */
    152 static char *opt_certform_s = "PEM";
    153 static int opt_certform = FORMAT_PEM;
    154 /*
    155  * DER format is the preferred choice for saving a CRL because it allows for
    156  * more efficient storage, especially when dealing with large CRLs.
    157  */
    158 static char *opt_crlform_s = "DER";
    159 static int opt_crlform = FORMAT_ASN1;
    160 static char *opt_keyform_s = NULL;
    161 static int opt_keyform = FORMAT_UNDEF;
    162 static char *opt_otherpass = NULL;
    163 static char *opt_engine = NULL;
    164 
    165 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
    166 /* TLS connection */
    167 static int opt_tls_used = 0;
    168 static char *opt_tls_cert = NULL;
    169 static char *opt_tls_key = NULL;
    170 static char *opt_tls_keypass = NULL;
    171 static char *opt_tls_extra = NULL;
    172 static char *opt_tls_trusted = NULL;
    173 static char *opt_tls_host = NULL;
    174 #endif
    175 
    176 /* client-side debugging */
    177 static int opt_batch = 0;
    178 static int opt_repeat = 1;
    179 static char *opt_reqin = NULL;
    180 static int opt_reqin_new_tid = 0;
    181 static char *opt_reqout = NULL;
    182 static char *opt_reqout_only = NULL;
    183 static int reqout_only_done = 0;
    184 static char *opt_rspin = NULL;
    185 static int rspin_in_use = 0;
    186 static char *opt_rspout = NULL;
    187 static int opt_use_mock_srv = 0;
    188 
    189 /* mock server */
    190 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
    191 static char *opt_port = NULL;
    192 static int opt_max_msgs = 0;
    193 #endif
    194 static char *opt_srv_ref = NULL;
    195 static char *opt_srv_secret = NULL;
    196 static char *opt_srv_cert = NULL;
    197 static char *opt_srv_key = NULL;
    198 static char *opt_srv_keypass = NULL;
    199 
    200 static char *opt_srv_trusted = NULL;
    201 static char *opt_srv_untrusted = NULL;
    202 static char *opt_ref_cert = NULL;
    203 static char *opt_rsp_cert = NULL;
    204 static char *opt_rsp_key = NULL;
    205 static char *opt_rsp_keypass = NULL;
    206 static char *opt_rsp_crl = NULL;
    207 static char *opt_rsp_extracerts = NULL;
    208 static char *opt_rsp_capubs = NULL;
    209 static char *opt_rsp_newwithnew = NULL;
    210 static char *opt_rsp_newwithold = NULL;
    211 static char *opt_rsp_oldwithnew = NULL;
    212 
    213 static int opt_poll_count = 0;
    214 static int opt_check_after = 1;
    215 static int opt_grant_implicitconf = 0;
    216 
    217 static int opt_pkistatus = OSSL_CMP_PKISTATUS_accepted;
    218 static int opt_failure = INT_MIN;
    219 static int opt_failurebits = 0;
    220 static char *opt_statusstring = NULL;
    221 static int opt_send_error = 0;
    222 static int opt_send_unprotected = 0;
    223 static int opt_send_unprot_err = 0;
    224 static int opt_accept_unprotected = 0;
    225 static int opt_accept_unprot_err = 0;
    226 static int opt_accept_raverified = 0;
    227 
    228 static X509_VERIFY_PARAM *vpm = NULL;
    229 
    230 typedef enum OPTION_choice {
    231     OPT_COMMON,
    232     OPT_CONFIG,
    233     OPT_SECTION,
    234     OPT_VERBOSITY,
    235 
    236     OPT_CMD,
    237     OPT_INFOTYPE,
    238     OPT_PROFILE,
    239     OPT_GENINFO,
    240     OPT_TEMPLATE,
    241     OPT_KEYSPEC,
    242 
    243     OPT_NEWKEY,
    244     OPT_NEWKEYPASS,
    245     OPT_CENTRALKEYGEN,
    246     OPT_NEWKEYOUT,
    247     OPT_SUBJECT,
    248     OPT_DAYS,
    249     OPT_REQEXTS,
    250     OPT_SANS,
    251     OPT_SAN_NODEFAULT,
    252     OPT_POLICIES,
    253     OPT_POLICY_OIDS,
    254     OPT_POLICY_OIDS_CRITICAL,
    255     OPT_POPO,
    256     OPT_CSR,
    257     OPT_OUT_TRUSTED,
    258     OPT_IMPLICIT_CONFIRM,
    259     OPT_DISABLE_CONFIRM,
    260     OPT_CERTOUT,
    261     OPT_CHAINOUT,
    262 
    263     OPT_OLDCERT,
    264     OPT_ISSUER,
    265     OPT_SERIAL,
    266     OPT_REVREASON,
    267 
    268 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
    269     OPT_SERVER,
    270     OPT_PROXY,
    271     OPT_NO_PROXY,
    272 #endif
    273     OPT_RECIPIENT,
    274     OPT_PATH,
    275     OPT_KEEP_ALIVE,
    276     OPT_MSG_TIMEOUT,
    277     OPT_TOTAL_TIMEOUT,
    278 
    279     OPT_TRUSTED,
    280     OPT_UNTRUSTED,
    281     OPT_SRVCERT,
    282     OPT_EXPECT_SENDER,
    283     OPT_IGNORE_KEYUSAGE,
    284     OPT_UNPROTECTED_ERRORS,
    285     OPT_NO_CACHE_EXTRACERTS,
    286     OPT_SRVCERTOUT,
    287     OPT_EXTRACERTSOUT,
    288     OPT_CACERTSOUT,
    289     OPT_OLDWITHOLD,
    290     OPT_NEWWITHNEW,
    291     OPT_NEWWITHOLD,
    292     OPT_OLDWITHNEW,
    293     OPT_CRLCERT,
    294     OPT_OLDCRL,
    295     OPT_CRLOUT,
    296 
    297     OPT_REF,
    298     OPT_SECRET,
    299     OPT_CERT,
    300     OPT_OWN_TRUSTED,
    301     OPT_KEY,
    302     OPT_KEYPASS,
    303     OPT_DIGEST,
    304     OPT_MAC,
    305     OPT_EXTRACERTS,
    306     OPT_UNPROTECTED_REQUESTS,
    307 
    308     OPT_CERTFORM,
    309     OPT_CRLFORM,
    310     OPT_KEYFORM,
    311     OPT_OTHERPASS,
    312 #ifndef OPENSSL_NO_ENGINE
    313     OPT_ENGINE,
    314 #endif
    315     OPT_PROV_ENUM,
    316     OPT_R_ENUM,
    317 
    318 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
    319     OPT_TLS_USED,
    320     OPT_TLS_CERT,
    321     OPT_TLS_KEY,
    322     OPT_TLS_KEYPASS,
    323     OPT_TLS_EXTRA,
    324     OPT_TLS_TRUSTED,
    325     OPT_TLS_HOST,
    326 #endif
    327 
    328     OPT_BATCH,
    329     OPT_REPEAT,
    330     OPT_REQIN,
    331     OPT_REQIN_NEW_TID,
    332     OPT_REQOUT,
    333     OPT_REQOUT_ONLY,
    334     OPT_RSPIN,
    335     OPT_RSPOUT,
    336     OPT_USE_MOCK_SRV,
    337 
    338 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
    339     OPT_PORT,
    340     OPT_MAX_MSGS,
    341 #endif
    342     OPT_SRV_REF,
    343     OPT_SRV_SECRET,
    344     OPT_SRV_CERT,
    345     OPT_SRV_KEY,
    346     OPT_SRV_KEYPASS,
    347     OPT_SRV_TRUSTED,
    348     OPT_SRV_UNTRUSTED,
    349     OPT_REF_CERT,
    350     OPT_RSP_CERT,
    351     OPT_RSP_KEY,
    352     OPT_RSP_KEYPASS,
    353     OPT_RSP_CRL,
    354     OPT_RSP_EXTRACERTS,
    355     OPT_RSP_CAPUBS,
    356     OPT_RSP_NEWWITHNEW,
    357     OPT_RSP_NEWWITHOLD,
    358     OPT_RSP_OLDWITHNEW,
    359     OPT_POLL_COUNT,
    360     OPT_CHECK_AFTER,
    361     OPT_GRANT_IMPLICITCONF,
    362     OPT_PKISTATUS,
    363     OPT_FAILURE,
    364     OPT_FAILUREBITS,
    365     OPT_STATUSSTRING,
    366     OPT_SEND_ERROR,
    367     OPT_SEND_UNPROTECTED,
    368     OPT_SEND_UNPROT_ERR,
    369     OPT_ACCEPT_UNPROTECTED,
    370     OPT_ACCEPT_UNPROT_ERR,
    371     OPT_ACCEPT_RAVERIFIED,
    372 
    373     OPT_V_ENUM
    374 } OPTION_CHOICE;
    375 
    376 const OPTIONS cmp_options[] = {
    377     /* entries must be in the same order as enumerated above!! */
    378     { "help", OPT_HELP, '-', "Display this summary" },
    379     { "config", OPT_CONFIG, 's',
    380         "Configuration file to use. \"\" = none. Default from env variable OPENSSL_CONF" },
    381     { "section", OPT_SECTION, 's',
    382         "Section(s) in config file to get options from. \"\" = 'default'. Default 'cmp'" },
    383     { "verbosity", OPT_VERBOSITY, 'N',
    384         "Log level; 3=ERR, 4=WARN, 6=INFO, 7=DEBUG, 8=TRACE. Default 6 = INFO" },
    385 
    386     OPT_SECTION("Generic message"),
    387     { "cmd", OPT_CMD, 's', "CMP request to send: ir/cr/kur/p10cr/rr/genm" },
    388     { "infotype", OPT_INFOTYPE, 's',
    389         "InfoType name for requesting specific info in genm, with specific support" },
    390     { OPT_MORE_STR, 0, 0,
    391         "for 'caCerts' and 'rootCaCert'" },
    392     { "profile", OPT_PROFILE, 's',
    393         "Certificate profile name to place in generalInfo field of request PKIHeader" },
    394     { "geninfo", OPT_GENINFO, 's',
    395         "Comma-separated list of OID and value to place in generalInfo PKIHeader" },
    396     { OPT_MORE_STR, 0, 0,
    397         "of form <OID>:int:<n> or <OID>:str:<s>, e.g. \'1.2.3.4:int:56789, id-kp:str:name'" },
    398     { "template", OPT_TEMPLATE, 's',
    399         "File to save certTemplate received in genp of type certReqTemplate" },
    400     { "keyspec", OPT_KEYSPEC, 's',
    401         "Optional file to save Key specification received in genp of type certReqTemplate" },
    402 
    403     OPT_SECTION("Certificate enrollment"),
    404     { "newkey", OPT_NEWKEY, 's',
    405         "Private or public key for the requested cert. Default: CSR key or client key" },
    406     { "newkeypass", OPT_NEWKEYPASS, 's', "New private key pass phrase source" },
    407     { "centralkeygen", OPT_CENTRALKEYGEN, '-',
    408         "Request central (server-side) key generation. Default is local generation" },
    409     { "newkeyout", OPT_NEWKEYOUT, 's',
    410         "File to save centrally generated key, in PEM format" },
    411     { "subject", OPT_SUBJECT, 's',
    412         "Distinguished Name (DN) of subject to use in the requested cert template" },
    413     { OPT_MORE_STR, 0, 0,
    414         "For kur, default is subject of -csr arg or reference cert (see -oldcert)" },
    415     { OPT_MORE_STR, 0, 0,
    416         "this default is used for ir and cr only if no Subject Alt Names are set" },
    417     { "days", OPT_DAYS, 'N',
    418         "Requested validity time of the new certificate in number of days" },
    419     { "reqexts", OPT_REQEXTS, 's',
    420         "Name of config file section defining certificate request extensions." },
    421     { OPT_MORE_STR, 0, 0,
    422         "Augments or replaces any extensions contained CSR given with -csr" },
    423     { "sans", OPT_SANS, 's',
    424         "Subject Alt Names (IPADDR/DNS/URI) to add as (critical) cert req extension" },
    425     { "san_nodefault", OPT_SAN_NODEFAULT, '-',
    426         "Do not take default SANs from reference certificate (see -oldcert)" },
    427     { "policies", OPT_POLICIES, 's',
    428         "Name of config file section defining policies certificate request extension" },
    429     { "policy_oids", OPT_POLICY_OIDS, 's',
    430         "Policy OID(s) to add as policies certificate request extension" },
    431     { "policy_oids_critical", OPT_POLICY_OIDS_CRITICAL, '-',
    432         "Flag the policy OID(s) given with -policy_oids as critical" },
    433     { "popo", OPT_POPO, 'n',
    434         "Proof-of-Possession (POPO) method to use for ir/cr/kur where" },
    435     { OPT_MORE_STR, 0, 0,
    436         "-1 = NONE, 0 = RAVERIFIED, 1 = SIGNATURE (default), 2 = KEYENC" },
    437     { "csr", OPT_CSR, 's',
    438         "PKCS#10 CSR file in PEM or DER format to convert or to use in p10cr" },
    439     { "out_trusted", OPT_OUT_TRUSTED, 's',
    440         "Certificates to trust when verifying newly enrolled certificates" },
    441     { "implicit_confirm", OPT_IMPLICIT_CONFIRM, '-',
    442         "Request implicit confirmation of newly enrolled certificates" },
    443     { "disable_confirm", OPT_DISABLE_CONFIRM, '-',
    444         "Do not confirm newly enrolled certificate w/o requesting implicit" },
    445     { OPT_MORE_STR, 0, 0,
    446         "confirmation. WARNING: This leads to behavior violating RFC 9810" },
    447     { "certout", OPT_CERTOUT, 's',
    448         "File to save newly enrolled certificate" },
    449     { "chainout", OPT_CHAINOUT, 's',
    450         "File to save the chain of newly enrolled certificate" },
    451 
    452     OPT_SECTION("Certificate enrollment and revocation"),
    453 
    454     { "oldcert", OPT_OLDCERT, 's',
    455         "Certificate to be updated (defaulting to -cert) or to be revoked in rr;" },
    456     { OPT_MORE_STR, 0, 0,
    457         "also used as reference (defaulting to -cert) for subject DN and SANs." },
    458     { OPT_MORE_STR, 0, 0,
    459         "Issuer is used as recipient unless -recipient, -srvcert, or -issuer given" },
    460     { "issuer", OPT_ISSUER, 's',
    461         "DN of the issuer to place in the certificate template of ir/cr/kur/rr;" },
    462     { OPT_MORE_STR, 0, 0,
    463         "also used as recipient if neither -recipient nor -srvcert are given" },
    464     { "serial", OPT_SERIAL, 's',
    465         "Serial number of certificate to be revoked in revocation request (rr)" },
    466     { "revreason", OPT_REVREASON, 'n',
    467         "Reason code to include in revocation request (rr); possible values:" },
    468     { OPT_MORE_STR, 0, 0,
    469         "0..6, 8..10 (see RFC5280, 5.3.1) or -1. Default -1 = none included" },
    470 
    471     OPT_SECTION("Message transfer"),
    472 #if defined(OPENSSL_NO_SOCK) || defined(OPENSSL_NO_HTTP)
    473     { OPT_MORE_STR, 0, 0,
    474         "NOTE: -server, -proxy, and -no_proxy not supported due to no-sock/no-http build" },
    475 #else
    476     { "server", OPT_SERVER, 's',
    477         "[http[s]://]address[:port][/path] of CMP server. Default port 80 or 443." },
    478     { OPT_MORE_STR, 0, 0,
    479         "address may be a DNS name or an IP address; path can be overridden by -path" },
    480     { "proxy", OPT_PROXY, 's',
    481         "[http[s]://]address[:port][/path] of HTTP(S) proxy to use; path is ignored" },
    482     { "no_proxy", OPT_NO_PROXY, 's',
    483         "List of addresses of servers not to use HTTP(S) proxy for" },
    484     { OPT_MORE_STR, 0, 0,
    485         "Default from environment variable 'no_proxy', else 'NO_PROXY', else none" },
    486 #endif
    487     { "recipient", OPT_RECIPIENT, 's',
    488         "DN of CA. Default: subject of -srvcert, -issuer, issuer of -oldcert or -cert" },
    489     { "path", OPT_PATH, 's',
    490         "HTTP path (aka CMP alias) at the CMP server. Default from -server, else \"/\"" },
    491     { "keep_alive", OPT_KEEP_ALIVE, 'N',
    492         "Persistent HTTP connections. 0: no, 1 (the default): request, 2: require" },
    493     { "msg_timeout", OPT_MSG_TIMEOUT, 'N',
    494         "Number of seconds allowed per CMP message round trip, or 0 for infinite" },
    495     { "total_timeout", OPT_TOTAL_TIMEOUT, 'N',
    496         "Overall time an enrollment incl. polling may take. Default 0 = infinite" },
    497 
    498     OPT_SECTION("Server authentication"),
    499     { "trusted", OPT_TRUSTED, 's',
    500         "Certificates to use as trust anchors when verifying signed CMP responses" },
    501     { OPT_MORE_STR, 0, 0, "unless -srvcert is given" },
    502     { "untrusted", OPT_UNTRUSTED, 's',
    503         "Intermediate CA certs for chain construction for CMP/TLS/enrolled certs" },
    504     { "srvcert", OPT_SRVCERT, 's',
    505         "Server cert to pin and trust directly when verifying signed CMP responses" },
    506     { "expect_sender", OPT_EXPECT_SENDER, 's',
    507         "DN of expected sender of responses. Defaults to subject of -srvcert, if any" },
    508     { "ignore_keyusage", OPT_IGNORE_KEYUSAGE, '-',
    509         "Ignore CMP signer cert key usage, else 'digitalSignature' must be allowed" },
    510     { "unprotected_errors", OPT_UNPROTECTED_ERRORS, '-',
    511         "Accept missing or invalid protection of regular error messages and negative" },
    512     { OPT_MORE_STR, 0, 0,
    513         "certificate responses (ip/cp/kup), revocation responses (rp), and PKIConf" },
    514     { OPT_MORE_STR, 0, 0,
    515         "WARNING: This setting leads to behavior allowing violation of RFC 9810" },
    516     { "no_cache_extracerts", OPT_NO_CACHE_EXTRACERTS, '-',
    517         "Do not keep certificates received in the extraCerts CMP message field" },
    518     { "srvcertout", OPT_SRVCERTOUT, 's',
    519         "File to save the server cert used and validated for CMP response protection" },
    520     { "extracertsout", OPT_EXTRACERTSOUT, 's',
    521         "File to save extra certificates received in the extraCerts field" },
    522     { "cacertsout", OPT_CACERTSOUT, 's',
    523         "File to save CA certs received in caPubs field or genp with id-it-caCerts" },
    524     { "oldwithold", OPT_OLDWITHOLD, 's',
    525         "Root CA certificate to request update for in genm of type rootCaCert" },
    526     { "newwithnew", OPT_NEWWITHNEW, 's',
    527         "File to save NewWithNew cert received in genp of type rootCaKeyUpdate" },
    528     { "newwithold", OPT_NEWWITHOLD, 's',
    529         "File to save NewWithOld cert received in genp of type rootCaKeyUpdate" },
    530     { "oldwithnew", OPT_OLDWITHNEW, 's',
    531         "File to save OldWithNew cert received in genp of type rootCaKeyUpdate" },
    532     { "crlcert", OPT_CRLCERT, 's',
    533         "certificate to request a CRL for in genm of type crlStatusList" },
    534     { "oldcrl", OPT_OLDCRL, 's',
    535         "CRL to request update for in genm of type crlStatusList" },
    536     { "crlout", OPT_CRLOUT, 's',
    537         "File to save new CRL received in genp of type 'crls'" },
    538 
    539     OPT_SECTION("Client authentication"),
    540     { "ref", OPT_REF, 's',
    541         "Reference value to use as senderKID in case no -cert is given" },
    542     { "secret", OPT_SECRET, 's',
    543         "Prefer PBM (over signatures) for protecting msgs with given password source" },
    544     { "cert", OPT_CERT, 's',
    545         "Client's CMP signer certificate; its public key must match the -key argument" },
    546     { OPT_MORE_STR, 0, 0,
    547         "This also used as default reference for subject DN and SANs." },
    548     { OPT_MORE_STR, 0, 0,
    549         "Any further certs included are appended to the untrusted certs" },
    550     { "own_trusted", OPT_OWN_TRUSTED, 's',
    551         "Optional certs to verify chain building for own CMP signer cert" },
    552     { "key", OPT_KEY, 's', "CMP signer private key, not used when -secret given" },
    553     { "keypass", OPT_KEYPASS, 's',
    554         "Client private key (and cert and old cert) pass phrase source" },
    555     { "digest", OPT_DIGEST, 's',
    556         "Digest to use in message protection and POPO signatures. Default \"sha256\"" },
    557     { "mac", OPT_MAC, 's',
    558         "MAC algorithm to use in PBM-based message protection. Default \"hmac-sha1\"" },
    559     { "extracerts", OPT_EXTRACERTS, 's',
    560         "Certificates to append in extraCerts field of outgoing messages." },
    561     { OPT_MORE_STR, 0, 0,
    562         "This can be used as the default CMP signer cert chain to include" },
    563     { "unprotected_requests", OPT_UNPROTECTED_REQUESTS, '-',
    564         "Send request messages without CMP-level protection" },
    565 
    566     OPT_SECTION("Credentials format"),
    567     { "certform", OPT_CERTFORM, 's',
    568         "Format (PEM or DER) to use when saving a certificate to a file. Default PEM" },
    569     { "crlform", OPT_CRLFORM, 's',
    570         "Format (PEM or DER) to use when saving a CRL to a file. Default DER" },
    571     { "keyform", OPT_KEYFORM, 's',
    572         "Format of the key input (ENGINE, other values ignored)" },
    573     { "otherpass", OPT_OTHERPASS, 's',
    574         "Pass phrase source potentially needed for loading certificates of others" },
    575 #ifndef OPENSSL_NO_ENGINE
    576     { "engine", OPT_ENGINE, 's',
    577         "Use crypto engine with given identifier, possibly a hardware device." },
    578     { OPT_MORE_STR, 0, 0,
    579         "Engines may also be defined in OpenSSL config file engine section." },
    580 #endif
    581     OPT_PROV_OPTIONS,
    582     OPT_R_OPTIONS,
    583 
    584     OPT_SECTION("TLS connection"),
    585 #if defined(OPENSSL_NO_SOCK) || defined(OPENSSL_NO_HTTP)
    586     { OPT_MORE_STR, 0, 0,
    587         "NOTE: -tls_used and all other TLS options not supported due to no-sock/no-http build" },
    588 #else
    589     { "tls_used", OPT_TLS_USED, '-',
    590         "Enable using TLS (also when other TLS options are not set)" },
    591     { "tls_cert", OPT_TLS_CERT, 's',
    592         "Client's TLS certificate. May include chain to be provided to TLS server" },
    593     { "tls_key", OPT_TLS_KEY, 's',
    594         "Private key for the client's TLS certificate" },
    595     { "tls_keypass", OPT_TLS_KEYPASS, 's',
    596         "Pass phrase source for the client's private TLS key (and TLS cert)" },
    597     { "tls_extra", OPT_TLS_EXTRA, 's',
    598         "Extra certificates to provide to TLS server during TLS handshake" },
    599     { "tls_trusted", OPT_TLS_TRUSTED, 's',
    600         "Trusted certificates to use for verifying the TLS server certificate;" },
    601     { OPT_MORE_STR, 0, 0, "this implies hostname validation" },
    602     { "tls_host", OPT_TLS_HOST, 's',
    603         "Address to be checked (rather than -server) during TLS hostname validation" },
    604 #endif
    605 
    606     OPT_SECTION("Client-side debugging"),
    607     { "batch", OPT_BATCH, '-',
    608         "Do not interactively prompt for input when a password is required etc." },
    609     { "repeat", OPT_REPEAT, 'p',
    610         "Invoke the transaction the given positive number of times. Default 1" },
    611     { "reqin", OPT_REQIN, 's',
    612         "Take sequence of CMP requests to send to server from file(s)" },
    613     { "reqin_new_tid", OPT_REQIN_NEW_TID, '-',
    614         "Use fresh transactionID for CMP requests read from -reqin" },
    615     { "reqout", OPT_REQOUT, 's',
    616         "Save sequence of CMP requests created by the client to file(s)" },
    617     { "reqout_only", OPT_REQOUT_ONLY, 's',
    618         "Save first CMP request created by the client to file and exit" },
    619     { "rspin", OPT_RSPIN, 's',
    620         "Process sequence of CMP responses provided in file(s), skipping server" },
    621     { "rspout", OPT_RSPOUT, 's',
    622         "Save sequence of actually used CMP responses to file(s)" },
    623 
    624     { "use_mock_srv", OPT_USE_MOCK_SRV, '-',
    625         "Use internal mock server at API level, bypassing socket-based HTTP" },
    626 
    627     OPT_SECTION("Mock server"),
    628 #if defined(OPENSSL_NO_SOCK) || defined(OPENSSL_NO_HTTP)
    629     { OPT_MORE_STR, 0, 0,
    630         "NOTE: -port and -max_msgs not supported due to no-sock/no-http build" },
    631 #else
    632     { "port", OPT_PORT, 's',
    633         "Act as HTTP-based mock server listening on given port" },
    634     { "max_msgs", OPT_MAX_MSGS, 'N',
    635         "max number of messages handled by HTTP mock server. Default: 0 = unlimited" },
    636 #endif
    637 
    638     { "srv_ref", OPT_SRV_REF, 's',
    639         "Reference value to use as senderKID of server in case no -srv_cert is given" },
    640     { "srv_secret", OPT_SRV_SECRET, 's',
    641         "Password source for server authentication with a pre-shared key (secret)" },
    642     { "srv_cert", OPT_SRV_CERT, 's', "Certificate of the server" },
    643     { "srv_key", OPT_SRV_KEY, 's',
    644         "Private key used by the server for signing messages" },
    645     { "srv_keypass", OPT_SRV_KEYPASS, 's',
    646         "Server private key (and cert) pass phrase source" },
    647 
    648     { "srv_trusted", OPT_SRV_TRUSTED, 's',
    649         "Trusted certificates for client authentication" },
    650     { "srv_untrusted", OPT_SRV_UNTRUSTED, 's',
    651         "Intermediate certs that may be useful for verifying CMP protection" },
    652     { "ref_cert", OPT_RSP_CERT, 's',
    653         "Certificate to be expected for rr and any oldCertID in kur messages" },
    654     { "rsp_cert", OPT_RSP_CERT, 's',
    655         "Certificate to be returned as mock enrollment result" },
    656     { "rsp_key", OPT_RSP_KEY, 's',
    657         "Private key for the certificate to be returned as mock enrollment result" },
    658     { OPT_MORE_STR, 0, 0,
    659         "Key to be returned for central key pair generation" },
    660     { "rsp_keypass", OPT_RSP_KEYPASS, 's',
    661         "Response private key (and cert) pass phrase source" },
    662     { "rsp_crl", OPT_RSP_CRL, 's',
    663         "CRL to be returned in genp of type crls" },
    664     { "rsp_extracerts", OPT_RSP_EXTRACERTS, 's',
    665         "Extra certificates to be included in mock certification responses" },
    666     { "rsp_capubs", OPT_RSP_CAPUBS, 's',
    667         "CA certificates to be included in mock ip response" },
    668     { "rsp_newwithnew", OPT_RSP_NEWWITHNEW, 's',
    669         "New root CA certificate to include in genp of type rootCaKeyUpdate" },
    670     { "rsp_newwithold", OPT_RSP_NEWWITHOLD, 's',
    671         "NewWithOld transition cert to include in genp of type rootCaKeyUpdate" },
    672     { "rsp_oldwithnew", OPT_RSP_OLDWITHNEW, 's',
    673         "OldWithNew transition cert to include in genp of type rootCaKeyUpdate" },
    674     { "poll_count", OPT_POLL_COUNT, 'N',
    675         "Number of times the client must poll before receiving a certificate" },
    676     { "check_after", OPT_CHECK_AFTER, 'N',
    677         "The check_after value (time to wait) to include in poll response" },
    678     { "grant_implicitconf", OPT_GRANT_IMPLICITCONF, '-',
    679         "Grant implicit confirmation of newly enrolled certificate" },
    680 
    681     { "pkistatus", OPT_PKISTATUS, 'N',
    682         "PKIStatus to be included in server response. Possible values: 0..6" },
    683     { "failure", OPT_FAILURE, 'N',
    684         "A single failure info bit number to include in server response, 0..26" },
    685     { "failurebits", OPT_FAILUREBITS, 'N',
    686         "Number representing failure bits to include in server response, 0..2^27 - 1" },
    687     { "statusstring", OPT_STATUSSTRING, 's',
    688         "Status string to be included in server response" },
    689     { "send_error", OPT_SEND_ERROR, '-',
    690         "Force server to reply with error message" },
    691     { "send_unprotected", OPT_SEND_UNPROTECTED, '-',
    692         "Send response messages without CMP-level protection" },
    693     { "send_unprot_err", OPT_SEND_UNPROT_ERR, '-',
    694         "In case of negative responses, server shall send unprotected error messages," },
    695     { OPT_MORE_STR, 0, 0,
    696         "certificate responses (ip/cp/kup), and revocation responses (rp)." },
    697     { OPT_MORE_STR, 0, 0,
    698         "WARNING: This setting leads to behavior violating RFC 9810" },
    699     { "accept_unprotected", OPT_ACCEPT_UNPROTECTED, '-',
    700         "Accept missing or invalid protection of requests" },
    701     { "accept_unprot_err", OPT_ACCEPT_UNPROT_ERR, '-',
    702         "Accept unprotected error messages from client" },
    703     { "accept_raverified", OPT_ACCEPT_RAVERIFIED, '-',
    704         "Accept RAVERIFIED as proof-of-possession (POPO)" },
    705 
    706     OPT_V_OPTIONS,
    707     { NULL }
    708 };
    709 
    710 typedef union {
    711     char **txt;
    712     int *num;
    713     long *num_long;
    714 } varref;
    715 static varref cmp_vars[] = { /* must be in same order as enumerated above! */
    716     { &opt_config }, { &opt_section }, { (char **)&opt_verbosity },
    717 
    718     { &opt_cmd_s }, { &opt_infotype_s }, { &opt_profile }, { &opt_geninfo },
    719     { &opt_template }, { &opt_keyspec },
    720 
    721     { &opt_newkey }, { &opt_newkeypass }, { (char **)&opt_centralkeygen },
    722     { &opt_newkeyout }, { &opt_subject }, { (char **)&opt_days }, { &opt_reqexts },
    723     { &opt_sans }, { (char **)&opt_san_nodefault },
    724     { &opt_policies }, { &opt_policy_oids }, { (char **)&opt_policy_oids_critical },
    725     { (char **)&opt_popo }, { &opt_csr },
    726     { &opt_out_trusted },
    727     { (char **)&opt_implicit_confirm }, { (char **)&opt_disable_confirm },
    728     { &opt_certout }, { &opt_chainout },
    729 
    730     { &opt_oldcert }, { &opt_issuer }, { &opt_serial }, { (char **)&opt_revreason },
    731 
    732 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
    733     { &opt_server }, { &opt_proxy }, { &opt_no_proxy },
    734 #endif
    735     { &opt_recipient }, { &opt_path }, { (char **)&opt_keep_alive },
    736     { (char **)&opt_msg_timeout }, { (char **)&opt_total_timeout },
    737 
    738     { &opt_trusted }, { &opt_untrusted }, { &opt_srvcert },
    739     { &opt_expect_sender },
    740     { (char **)&opt_ignore_keyusage }, { (char **)&opt_unprotected_errors },
    741     { (char **)&opt_no_cache_extracerts },
    742     { &opt_srvcertout }, { &opt_extracertsout }, { &opt_cacertsout },
    743     { &opt_oldwithold }, { &opt_newwithnew }, { &opt_newwithold }, { &opt_oldwithnew },
    744     { &opt_crlcert }, { &opt_oldcrl }, { &opt_crlout },
    745 
    746     { &opt_ref }, { &opt_secret },
    747     { &opt_cert }, { &opt_own_trusted }, { &opt_key }, { &opt_keypass },
    748     { &opt_digest }, { &opt_mac }, { &opt_extracerts },
    749     { (char **)&opt_unprotected_requests },
    750 
    751     { &opt_certform_s }, { &opt_crlform_s }, { &opt_keyform_s },
    752     { &opt_otherpass },
    753 #ifndef OPENSSL_NO_ENGINE
    754     { &opt_engine },
    755 #endif
    756 
    757 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
    758     { (char **)&opt_tls_used }, { &opt_tls_cert }, { &opt_tls_key },
    759     { &opt_tls_keypass },
    760     { &opt_tls_extra }, { &opt_tls_trusted }, { &opt_tls_host },
    761 #endif
    762 
    763     { (char **)&opt_batch }, { (char **)&opt_repeat },
    764     { &opt_reqin }, { (char **)&opt_reqin_new_tid },
    765     { &opt_reqout }, { &opt_reqout_only }, { &opt_rspin }, { &opt_rspout },
    766 
    767     { (char **)&opt_use_mock_srv },
    768 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
    769     { &opt_port }, { (char **)&opt_max_msgs },
    770 #endif
    771     { &opt_srv_ref }, { &opt_srv_secret },
    772     { &opt_srv_cert }, { &opt_srv_key }, { &opt_srv_keypass },
    773     { &opt_srv_trusted }, { &opt_srv_untrusted },
    774     { &opt_ref_cert }, { &opt_rsp_cert }, { &opt_rsp_key }, { &opt_rsp_keypass },
    775     { &opt_rsp_crl }, { &opt_rsp_extracerts }, { &opt_rsp_capubs },
    776     { &opt_rsp_newwithnew }, { &opt_rsp_newwithold }, { &opt_rsp_oldwithnew },
    777 
    778     { (char **)&opt_poll_count }, { (char **)&opt_check_after },
    779     { (char **)&opt_grant_implicitconf },
    780     { (char **)&opt_pkistatus }, { (char **)&opt_failure },
    781     { (char **)&opt_failurebits }, { &opt_statusstring },
    782     { (char **)&opt_send_error }, { (char **)&opt_send_unprotected },
    783     { (char **)&opt_send_unprot_err }, { (char **)&opt_accept_unprotected },
    784     { (char **)&opt_accept_unprot_err }, { (char **)&opt_accept_raverified },
    785 
    786     { NULL }
    787 };
    788 
    789 #define FUNC (strcmp(OPENSSL_FUNC, "(unknown function)") == 0 \
    790         ? "CMP"                                               \
    791         : OPENSSL_FUNC)
    792 #define CMP_print(bio, level, prefix, msg, a1, a2, a3) \
    793     ((void)(level > opt_verbosity ? 0 : (BIO_printf(bio, "%s:%s:%d:CMP %s: " msg "\n", FUNC, OPENSSL_FILE, OPENSSL_LINE, prefix, a1, a2, a3))))
    794 #define CMP_DEBUG(m, a1, a2, a3) \
    795     CMP_print(bio_out, OSSL_CMP_LOG_DEBUG, "debug", m, a1, a2, a3)
    796 #define CMP_debug(msg) CMP_DEBUG(msg "%s%s%s", "", "", "")
    797 #define CMP_debug1(msg, a1) CMP_DEBUG(msg "%s%s", a1, "", "")
    798 #define CMP_debug2(msg, a1, a2) CMP_DEBUG(msg "%s", a1, a2, "")
    799 #define CMP_debug3(msg, a1, a2, a3) CMP_DEBUG(msg, a1, a2, a3)
    800 #define CMP_INFO(msg, a1, a2, a3) \
    801     CMP_print(bio_out, OSSL_CMP_LOG_INFO, "info", msg, a1, a2, a3)
    802 #define CMP_info(msg) CMP_INFO(msg "%s%s%s", "", "", "")
    803 #define CMP_info1(msg, a1) CMP_INFO(msg "%s%s", a1, "", "")
    804 #define CMP_info2(msg, a1, a2) CMP_INFO(msg "%s", a1, a2, "")
    805 #define CMP_info3(msg, a1, a2, a3) CMP_INFO(msg, a1, a2, a3)
    806 #define CMP_WARN(m, a1, a2, a3) \
    807     CMP_print(bio_out, OSSL_CMP_LOG_WARNING, "warning", m, a1, a2, a3)
    808 #define CMP_warn(msg) CMP_WARN(msg "%s%s%s", "", "", "")
    809 #define CMP_warn1(msg, a1) CMP_WARN(msg "%s%s", a1, "", "")
    810 #define CMP_warn2(msg, a1, a2) CMP_WARN(msg "%s", a1, a2, "")
    811 #define CMP_warn3(msg, a1, a2, a3) CMP_WARN(msg, a1, a2, a3)
    812 #define CMP_ERR(msg, a1, a2, a3) \
    813     CMP_print(bio_err, OSSL_CMP_LOG_ERR, "error", msg, a1, a2, a3)
    814 #define CMP_err(msg) CMP_ERR(msg "%s%s%s", "", "", "")
    815 #define CMP_err1(msg, a1) CMP_ERR(msg "%s%s", a1, "", "")
    816 #define CMP_err2(msg, a1, a2) CMP_ERR(msg "%s", a1, a2, "")
    817 #define CMP_err3(msg, a1, a2, a3) CMP_ERR(msg, a1, a2, a3)
    818 
    819 static int print_to_bio_out(const char *func, const char *file, int line,
    820     OSSL_CMP_severity level, const char *msg)
    821 {
    822     return OSSL_CMP_print_to_bio(bio_out, func, file, line, level, msg);
    823 }
    824 
    825 static int print_to_bio_err(const char *func, const char *file, int line,
    826     OSSL_CMP_severity level, const char *msg)
    827 {
    828     return OSSL_CMP_print_to_bio(bio_err, func, file, line, level, msg);
    829 }
    830 
    831 static int set_verbosity(int level)
    832 {
    833     if (level < OSSL_CMP_LOG_EMERG || level > OSSL_CMP_LOG_MAX) {
    834         CMP_err1("Logging verbosity level %d out of range (0 .. 8)", level);
    835         return 0;
    836     }
    837     opt_verbosity = level;
    838     return 1;
    839 }
    840 
    841 static EVP_PKEY *load_key_pwd(const char *uri, int format,
    842     const char *pass, ENGINE *eng, const char *desc)
    843 {
    844     char *pass_string = get_passwd(pass, desc);
    845     EVP_PKEY *pkey = load_key(uri, format, 0, pass_string, eng, desc);
    846 
    847     clear_free(pass_string);
    848     return pkey;
    849 }
    850 
    851 static X509 *load_cert_pwd(const char *uri, const char *pass, const char *desc)
    852 {
    853     X509 *cert;
    854     char *pass_string = get_passwd(pass, desc);
    855 
    856     cert = load_cert_pass(uri, FORMAT_UNDEF, 0, pass_string, desc);
    857     clear_free(pass_string);
    858     return cert;
    859 }
    860 
    861 /* set expected hostname/IP addr and clears the email addr in the given ts */
    862 static int truststore_set_host_etc(X509_STORE *ts, const char *host)
    863 {
    864     X509_VERIFY_PARAM *ts_vpm = X509_STORE_get0_param(ts);
    865 
    866     /* first clear any hostnames, IP, and email addresses */
    867     if (!X509_VERIFY_PARAM_set1_host(ts_vpm, NULL, 0)
    868         || !X509_VERIFY_PARAM_set1_ip(ts_vpm, NULL, 0)
    869         || !X509_VERIFY_PARAM_set1_email(ts_vpm, NULL, 0))
    870         return 0;
    871     X509_VERIFY_PARAM_set_hostflags(ts_vpm,
    872         X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT | X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
    873     return (host != NULL && X509_VERIFY_PARAM_set1_ip_asc(ts_vpm, host))
    874         || X509_VERIFY_PARAM_set1_host(ts_vpm, host, 0);
    875 }
    876 
    877 /* write OSSL_CMP_MSG DER-encoded to the specified file name item */
    878 static int write_PKIMESSAGE(const OSSL_CMP_MSG *msg, char **filenames)
    879 {
    880     char *file;
    881 
    882     if (msg == NULL || filenames == NULL) {
    883         CMP_err("NULL arg to write_PKIMESSAGE");
    884         return 0;
    885     }
    886     if (*filenames == NULL) {
    887         CMP_err("not enough file names provided for writing PKIMessage");
    888         return 0;
    889     }
    890 
    891     file = *filenames;
    892     *filenames = next_item(file);
    893     if (OSSL_CMP_MSG_write(file, msg) < 0) {
    894         CMP_err1("cannot write PKIMessage to file '%s'", file);
    895         return 0;
    896     }
    897     return 1;
    898 }
    899 
    900 /* read DER-encoded OSSL_CMP_MSG from the specified file name item */
    901 static OSSL_CMP_MSG *read_PKIMESSAGE(const char *desc, char **filenames)
    902 {
    903     char *file;
    904     OSSL_CMP_MSG *ret;
    905 
    906     if (filenames == NULL || desc == NULL) {
    907         CMP_err("NULL arg to read_PKIMESSAGE");
    908         return NULL;
    909     }
    910     if (*filenames == NULL) {
    911         CMP_err("not enough file names provided for reading PKIMessage");
    912         return NULL;
    913     }
    914 
    915     file = *filenames;
    916     *filenames = next_item(file);
    917 
    918     ret = OSSL_CMP_MSG_read(file, app_get0_libctx(), app_get0_propq());
    919     if (ret == NULL)
    920         CMP_err1("cannot read PKIMessage from file '%s'", file);
    921     else
    922         CMP_info2("%s %s", desc, file);
    923     return ret;
    924 }
    925 
    926 /*-
    927  * Sends the PKIMessage req and on success place the response in *res
    928  * basically like OSSL_CMP_MSG_http_perform(), but in addition allows
    929  * to dump the sequence of requests and responses to files and/or
    930  * to take the sequence of requests and responses from files.
    931  */
    932 static OSSL_CMP_MSG *read_write_req_resp(OSSL_CMP_CTX *ctx,
    933     const OSSL_CMP_MSG *req)
    934 {
    935     OSSL_CMP_MSG *req_new = NULL;
    936     OSSL_CMP_MSG *res = NULL;
    937     OSSL_CMP_PKIHEADER *hdr;
    938     const char *prev_opt_rspin = opt_rspin;
    939 
    940     if (opt_reqout_only != NULL) {
    941         if (OSSL_CMP_MSG_write(opt_reqout_only, req) < 0)
    942             CMP_err1("cannot write request PKIMessage to file '%s'",
    943                 opt_reqout_only);
    944         else
    945             reqout_only_done = 1;
    946         return NULL; /* stop at this point, not contacting any server */
    947     }
    948     if (opt_reqout != NULL && !write_PKIMESSAGE(req, &opt_reqout))
    949         goto err;
    950     if (opt_reqin != NULL && opt_rspin == NULL) {
    951         if ((req_new = read_PKIMESSAGE("actually sending", &opt_reqin)) == NULL)
    952             goto err;
    953         /*-
    954          * The transaction ID in req_new read from opt_reqin may not be fresh.
    955          * In this case the server may complain "Transaction id already in use."
    956          * The following workaround unfortunately requires re-protection.
    957          */
    958         if (opt_reqin_new_tid
    959             && !OSSL_CMP_MSG_update_transactionID(ctx, req_new))
    960             goto err;
    961 
    962         /*
    963          * Except for first request, need to satisfy recipNonce check by server.
    964          * Unfortunately requires re-protection if protection is required.
    965          */
    966         if (!OSSL_CMP_MSG_update_recipNonce(ctx, req_new))
    967             goto err;
    968     }
    969 
    970     if (opt_rspin != NULL) {
    971         res = read_PKIMESSAGE("actually using", &opt_rspin);
    972     } else {
    973         const OSSL_CMP_MSG *actual_req = req_new != NULL ? req_new : req;
    974 
    975         if (opt_use_mock_srv) {
    976             if (rspin_in_use)
    977                 CMP_warn("too few -rspin filename arguments; resorting to using mock server");
    978             res = OSSL_CMP_CTX_server_perform(ctx, actual_req);
    979         } else {
    980 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
    981             if (opt_server == NULL) {
    982                 CMP_err("missing -server or -use_mock_srv option, or too few -rspin filename arguments");
    983                 goto err;
    984             }
    985             if (rspin_in_use)
    986                 CMP_warn("too few -rspin filename arguments; resorting to contacting server");
    987             res = OSSL_CMP_MSG_http_perform(ctx, actual_req);
    988 #else
    989             CMP_err("-server not supported on no-sock/no-http build; missing -use_mock_srv option or too few -rspin filename arguments");
    990 #endif
    991         }
    992         rspin_in_use = 0;
    993     }
    994     if (res == NULL)
    995         goto err;
    996 
    997     if (req_new != NULL || prev_opt_rspin != NULL) {
    998         /* need to satisfy nonce and transactionID checks by client */
    999         ASN1_OCTET_STRING *nonce;
   1000         ASN1_OCTET_STRING *tid;
   1001 
   1002         hdr = OSSL_CMP_MSG_get0_header(res);
   1003         nonce = OSSL_CMP_HDR_get0_recipNonce(hdr);
   1004         tid = OSSL_CMP_HDR_get0_transactionID(hdr);
   1005         if (!OSSL_CMP_CTX_set1_senderNonce(ctx, nonce)
   1006             || !OSSL_CMP_CTX_set1_transactionID(ctx, tid)) {
   1007             OSSL_CMP_MSG_free(res);
   1008             res = NULL;
   1009             goto err;
   1010         }
   1011     }
   1012 
   1013     if (opt_rspout != NULL && !write_PKIMESSAGE(res, &opt_rspout)) {
   1014         OSSL_CMP_MSG_free(res);
   1015         res = NULL;
   1016     }
   1017 
   1018 err:
   1019     OSSL_CMP_MSG_free(req_new);
   1020     return res;
   1021 }
   1022 
   1023 static int set_name(const char *str,
   1024     int (*set_fn)(OSSL_CMP_CTX *ctx, const X509_NAME *name),
   1025     OSSL_CMP_CTX *ctx, const char *desc)
   1026 {
   1027     if (str != NULL) {
   1028         X509_NAME *n = parse_name(str, MBSTRING_UTF8, 1, desc);
   1029 
   1030         if (n == NULL)
   1031             return 0;
   1032         if (!(*set_fn)(ctx, n)) {
   1033             X509_NAME_free(n);
   1034             CMP_err("out of memory");
   1035             return 0;
   1036         }
   1037         X509_NAME_free(n);
   1038     }
   1039     return 1;
   1040 }
   1041 
   1042 static int set_gennames(OSSL_CMP_CTX *ctx, char *names, const char *desc)
   1043 {
   1044     char *next;
   1045 
   1046     for (; names != NULL; names = next) {
   1047         GENERAL_NAME *n;
   1048 
   1049         next = next_item(names);
   1050         if (strcmp(names, "critical") == 0) {
   1051             (void)OSSL_CMP_CTX_set_option(ctx,
   1052                 OSSL_CMP_OPT_SUBJECTALTNAME_CRITICAL,
   1053                 1);
   1054             continue;
   1055         }
   1056 
   1057         /* try IP address first, then email/URI/domain name */
   1058         (void)ERR_set_mark();
   1059         n = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_IPADD, names, 0);
   1060         if (n == NULL)
   1061             n = a2i_GENERAL_NAME(NULL, NULL, NULL,
   1062                 strchr(names, '@') != NULL ? GEN_EMAIL : strchr(names, ':') != NULL ? GEN_URI
   1063                                                                                     : GEN_DNS,
   1064                 names, 0);
   1065         (void)ERR_pop_to_mark();
   1066 
   1067         if (n == NULL) {
   1068             CMP_err2("bad syntax of %s '%s'", desc, names);
   1069             return 0;
   1070         }
   1071         if (!OSSL_CMP_CTX_push1_subjectAltName(ctx, n)) {
   1072             GENERAL_NAME_free(n);
   1073             CMP_err("out of memory");
   1074             return 0;
   1075         }
   1076         GENERAL_NAME_free(n);
   1077     }
   1078     return 1;
   1079 }
   1080 
   1081 static X509_STORE *load_trusted(char *input, int for_new_cert, const char *desc)
   1082 {
   1083     X509_STORE *ts = load_certstore(input, opt_otherpass, desc, vpm);
   1084 
   1085     if (ts == NULL)
   1086         return NULL;
   1087     X509_STORE_set_verify_cb(ts, X509_STORE_CTX_print_verify_cb);
   1088 
   1089     /* copy vpm to store */
   1090     if (X509_STORE_set1_param(ts, vpm /* may be NULL */)
   1091         && (for_new_cert || truststore_set_host_etc(ts, NULL)))
   1092         return ts;
   1093     BIO_printf(bio_err, "error setting verification parameters for %s\n", desc);
   1094     OSSL_CMP_CTX_print_errors(cmp_ctx);
   1095     X509_STORE_free(ts);
   1096     return NULL;
   1097 }
   1098 
   1099 typedef int (*add_X509_fn_t)(void *ctx, const X509 *cert);
   1100 static int setup_cert(void *ctx, const char *file, const char *pass,
   1101     const char *desc, add_X509_fn_t set1_fn)
   1102 {
   1103     X509 *cert;
   1104     int ok;
   1105 
   1106     if (file == NULL)
   1107         return 1;
   1108     if ((cert = load_cert_pwd(file, pass, desc)) == NULL)
   1109         return 0;
   1110     ok = (*set1_fn)(ctx, cert);
   1111     X509_free(cert);
   1112     return ok;
   1113 }
   1114 
   1115 typedef int (*add_X509_stack_fn_t)(void *ctx, const STACK_OF(X509) *certs);
   1116 static int setup_certs(char *files, const char *desc, void *ctx,
   1117     add_X509_stack_fn_t set1_fn)
   1118 {
   1119     STACK_OF(X509) *certs;
   1120     int ok;
   1121 
   1122     if (files == NULL)
   1123         return 1;
   1124     if ((certs = load_certs_multifile(files, opt_otherpass, desc, vpm)) == NULL)
   1125         return 0;
   1126     ok = (*set1_fn)(ctx, certs);
   1127     OSSL_STACK_OF_X509_free(certs);
   1128     return ok;
   1129 }
   1130 
   1131 static int setup_mock_crlout(void *ctx, const char *file, const char *desc)
   1132 {
   1133     X509_CRL *crl;
   1134     int ok;
   1135 
   1136     if (file == NULL)
   1137         return 1;
   1138     if ((crl = load_crl(file, FORMAT_UNDEF, 0, desc)) == NULL)
   1139         return 0;
   1140     ok = ossl_cmp_mock_srv_set1_crlOut(ctx, crl);
   1141     X509_CRL_free(crl);
   1142     return ok;
   1143 }
   1144 /*
   1145  * parse and transform some options, checking their syntax.
   1146  * Returns 1 on success, 0 on error
   1147  */
   1148 static int transform_opts(void)
   1149 {
   1150     if (opt_cmd_s != NULL) {
   1151         if (!strcmp(opt_cmd_s, "ir")) {
   1152             opt_cmd = CMP_IR;
   1153         } else if (!strcmp(opt_cmd_s, "kur")) {
   1154             opt_cmd = CMP_KUR;
   1155         } else if (!strcmp(opt_cmd_s, "cr")) {
   1156             opt_cmd = CMP_CR;
   1157         } else if (!strcmp(opt_cmd_s, "p10cr")) {
   1158             opt_cmd = CMP_P10CR;
   1159         } else if (!strcmp(opt_cmd_s, "rr")) {
   1160             opt_cmd = CMP_RR;
   1161         } else if (!strcmp(opt_cmd_s, "genm")) {
   1162             opt_cmd = CMP_GENM;
   1163         } else {
   1164             CMP_err1("unknown cmp command '%s'", opt_cmd_s);
   1165             return 0;
   1166         }
   1167     } else {
   1168         CMP_err("no cmp command to execute");
   1169         return 0;
   1170     }
   1171 
   1172 #ifndef OPENSSL_NO_ENGINE
   1173 #define FORMAT_OPTIONS (OPT_FMT_PEMDER | OPT_FMT_PKCS12 | OPT_FMT_ENGINE)
   1174 #else
   1175 #define FORMAT_OPTIONS (OPT_FMT_PEMDER | OPT_FMT_PKCS12)
   1176 #endif
   1177 
   1178     if (opt_keyform_s != NULL
   1179         && !opt_format(opt_keyform_s, FORMAT_OPTIONS, &opt_keyform)) {
   1180         CMP_err("unknown option given for key loading format");
   1181         return 0;
   1182     }
   1183 
   1184 #undef FORMAT_OPTIONS
   1185 
   1186     if (opt_certform_s != NULL
   1187         && !opt_format(opt_certform_s, OPT_FMT_PEMDER, &opt_certform)) {
   1188         CMP_err("unknown option given for certificate storing format");
   1189         return 0;
   1190     }
   1191     if (opt_crlform_s != NULL
   1192         && !opt_format(opt_crlform_s, OPT_FMT_PEMDER, &opt_crlform)) {
   1193         CMP_err("unknown option given for CRL storing format");
   1194         return 0;
   1195     }
   1196 
   1197     return 1;
   1198 }
   1199 
   1200 static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine)
   1201 {
   1202     OSSL_CMP_CTX *ctx; /* extra CMP (client) ctx partly used by server */
   1203     OSSL_CMP_SRV_CTX *srv_ctx = ossl_cmp_mock_srv_new(app_get0_libctx(),
   1204         app_get0_propq());
   1205 
   1206     if (srv_ctx == NULL)
   1207         return NULL;
   1208     ctx = OSSL_CMP_SRV_CTX_get0_cmp_ctx(srv_ctx);
   1209 
   1210     if (opt_srv_ref == NULL) {
   1211         if (opt_srv_cert == NULL) {
   1212             /* opt_srv_cert should determine the sender */
   1213             CMP_err("must give -srv_ref for mock server if no -srv_cert given");
   1214             goto err;
   1215         }
   1216     } else {
   1217         if (!OSSL_CMP_CTX_set1_referenceValue(ctx, (unsigned char *)opt_srv_ref,
   1218                 strlen(opt_srv_ref)))
   1219             goto err;
   1220     }
   1221 
   1222     if (opt_srv_secret != NULL) {
   1223         int res;
   1224         char *pass_str = get_passwd(opt_srv_secret, "PBMAC secret of mock server");
   1225 
   1226         if (pass_str != NULL) {
   1227             cleanse(opt_srv_secret);
   1228             res = OSSL_CMP_CTX_set1_secretValue(ctx, (unsigned char *)pass_str,
   1229                 strlen(pass_str));
   1230             clear_free(pass_str);
   1231             if (res == 0)
   1232                 goto err;
   1233         }
   1234     } else if (opt_srv_cert == NULL) {
   1235         CMP_err("server credentials (-srv_secret or -srv_cert) must be given if -use_mock_srv or -port is used");
   1236         goto err;
   1237     } else {
   1238         CMP_warn("server will not be able to handle PBM-protected requests since -srv_secret is not given");
   1239     }
   1240 
   1241     if (opt_srv_secret == NULL
   1242         && ((opt_srv_cert == NULL) != (opt_srv_key == NULL))) {
   1243         CMP_err("must give both -srv_cert and -srv_key options or neither");
   1244         goto err;
   1245     }
   1246     if (!setup_cert(ctx, opt_srv_cert, opt_srv_keypass,
   1247             "signer certificate of the mock server",
   1248             (add_X509_fn_t)OSSL_CMP_CTX_set1_cert))
   1249         goto err;
   1250     if (opt_srv_key != NULL) {
   1251         EVP_PKEY *pkey = load_key_pwd(opt_srv_key, opt_keyform,
   1252             opt_srv_keypass,
   1253             engine, "private key for mock server cert");
   1254 
   1255         if (pkey == NULL || !OSSL_CMP_CTX_set1_pkey(ctx, pkey)) {
   1256             EVP_PKEY_free(pkey);
   1257             goto err;
   1258         }
   1259         EVP_PKEY_free(pkey);
   1260     }
   1261     cleanse(opt_srv_keypass);
   1262 
   1263     if (opt_srv_trusted != NULL) {
   1264         X509_STORE *ts = load_trusted(opt_srv_trusted, 0, "certs trusted by mock server");
   1265 
   1266         if (ts == NULL || !OSSL_CMP_CTX_set0_trusted(ctx, ts)) {
   1267             X509_STORE_free(ts);
   1268             goto err;
   1269         }
   1270     } else {
   1271         CMP_warn("mock server will not be able to handle signature-protected requests since -srv_trusted is not given");
   1272     }
   1273     if (!setup_certs(opt_srv_untrusted,
   1274             "untrusted certificates for mock server", ctx,
   1275             (add_X509_stack_fn_t)OSSL_CMP_CTX_set1_untrusted))
   1276         goto err;
   1277 
   1278     if (!setup_cert(srv_ctx, opt_ref_cert, opt_otherpass,
   1279             "reference cert to be expected by the mock server",
   1280             (add_X509_fn_t)ossl_cmp_mock_srv_set1_refCert))
   1281         goto err;
   1282     if (opt_rsp_cert == NULL) {
   1283         CMP_warn("no -rsp_cert given for mock server");
   1284     } else {
   1285         if (!setup_cert(srv_ctx, opt_rsp_cert, opt_rsp_keypass,
   1286                 "cert the mock server returns on certificate requests",
   1287                 (add_X509_fn_t)ossl_cmp_mock_srv_set1_certOut))
   1288             goto err;
   1289     }
   1290     if (opt_rsp_key != NULL) {
   1291         EVP_PKEY *pkey = load_key_pwd(opt_rsp_key, opt_keyform,
   1292             opt_rsp_keypass, engine,
   1293             "private key for enrollment cert");
   1294 
   1295         if (pkey == NULL
   1296             || !ossl_cmp_mock_srv_set1_keyOut(srv_ctx, pkey)) {
   1297             EVP_PKEY_free(pkey);
   1298             goto err;
   1299         }
   1300         EVP_PKEY_free(pkey);
   1301     }
   1302     cleanse(opt_rsp_keypass);
   1303 
   1304     if (!setup_mock_crlout(srv_ctx, opt_rsp_crl,
   1305             "CRL to be returned by the mock server"))
   1306         goto err;
   1307     if (!setup_certs(opt_rsp_extracerts,
   1308             "CMP extra certificates for mock server", srv_ctx,
   1309             (add_X509_stack_fn_t)ossl_cmp_mock_srv_set1_chainOut))
   1310         goto err;
   1311     if (!setup_certs(opt_rsp_capubs, "caPubs for mock server", srv_ctx,
   1312             (add_X509_stack_fn_t)ossl_cmp_mock_srv_set1_caPubsOut))
   1313         goto err;
   1314     if (!setup_cert(srv_ctx, opt_rsp_newwithnew, opt_otherpass,
   1315             "NewWithNew cert the mock server returns in rootCaKeyUpdate",
   1316             (add_X509_fn_t)ossl_cmp_mock_srv_set1_newWithNew)
   1317         || !setup_cert(srv_ctx, opt_rsp_newwithold, opt_otherpass,
   1318             "NewWithOld cert the mock server returns in rootCaKeyUpdate",
   1319             (add_X509_fn_t)ossl_cmp_mock_srv_set1_newWithOld)
   1320         || !setup_cert(srv_ctx, opt_rsp_oldwithnew, opt_otherpass,
   1321             "OldWithNew cert the mock server returns in rootCaKeyUpdate",
   1322             (add_X509_fn_t)ossl_cmp_mock_srv_set1_oldWithNew))
   1323         goto err;
   1324     (void)ossl_cmp_mock_srv_set_pollCount(srv_ctx, opt_poll_count);
   1325     (void)ossl_cmp_mock_srv_set_checkAfterTime(srv_ctx, opt_check_after);
   1326     if (opt_grant_implicitconf)
   1327         (void)OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(srv_ctx, 1);
   1328 
   1329     if (opt_failure != INT_MIN) { /* option has been set explicitly */
   1330         if (opt_failure < 0 || OSSL_CMP_PKIFAILUREINFO_MAX < opt_failure) {
   1331             CMP_err1("-failure out of range, should be >= 0 and <= %d",
   1332                 OSSL_CMP_PKIFAILUREINFO_MAX);
   1333             goto err;
   1334         }
   1335         if (opt_failurebits != 0)
   1336             CMP_warn("-failurebits overrides -failure");
   1337         else
   1338             opt_failurebits = 1 << opt_failure;
   1339     }
   1340     if ((unsigned)opt_failurebits > OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN) {
   1341         CMP_err("-failurebits out of range");
   1342         goto err;
   1343     }
   1344     if (!ossl_cmp_mock_srv_set_statusInfo(srv_ctx, opt_pkistatus,
   1345             opt_failurebits, opt_statusstring))
   1346         goto err;
   1347 
   1348     if (opt_send_error)
   1349         (void)ossl_cmp_mock_srv_set_sendError(srv_ctx, 1);
   1350 
   1351     if (opt_send_unprotected)
   1352         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_SEND, 1);
   1353     if (opt_send_unprot_err)
   1354         (void)OSSL_CMP_SRV_CTX_set_send_unprotected_errors(srv_ctx, 1);
   1355     if (opt_accept_unprotected)
   1356         (void)OSSL_CMP_SRV_CTX_set_accept_unprotected(srv_ctx, 1);
   1357     if (opt_accept_unprot_err)
   1358         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS, 1);
   1359     if (opt_accept_raverified)
   1360         (void)OSSL_CMP_SRV_CTX_set_accept_raverified(srv_ctx, 1);
   1361 
   1362     return srv_ctx;
   1363 
   1364 err:
   1365     ossl_cmp_mock_srv_free(srv_ctx);
   1366     return NULL;
   1367 }
   1368 
   1369 /*
   1370  * set up verification aspects of OSSL_CMP_CTX w.r.t. opts from config file/CLI.
   1371  * Returns pointer on success, NULL on error
   1372  */
   1373 static int setup_verification_ctx(OSSL_CMP_CTX *ctx)
   1374 {
   1375     if (!setup_certs(opt_untrusted, "untrusted certificates", ctx,
   1376             (add_X509_stack_fn_t)OSSL_CMP_CTX_set1_untrusted))
   1377         return 0;
   1378 
   1379     if (opt_srvcert != NULL || opt_trusted != NULL) {
   1380         if (opt_srvcert != NULL) {
   1381             if (opt_trusted != NULL) {
   1382                 CMP_warn("-trusted option is ignored since -srvcert option is present");
   1383                 opt_trusted = NULL;
   1384             }
   1385             if (opt_recipient != NULL) {
   1386                 CMP_warn("-recipient option is ignored since -srvcert option is present");
   1387                 opt_recipient = NULL;
   1388             }
   1389             if (!setup_cert(ctx, opt_srvcert, opt_otherpass,
   1390                     "directly trusted CMP server certificate",
   1391                     (add_X509_fn_t)OSSL_CMP_CTX_set1_srvCert))
   1392                 return 0;
   1393         }
   1394         if (opt_trusted != NULL) {
   1395             X509_STORE *ts;
   1396 
   1397             /*
   1398              * the 0 arg below clears any expected host/ip/email address;
   1399              * opt_expect_sender is used instead
   1400              */
   1401             ts = load_trusted(opt_trusted, 0, "certs trusted by client");
   1402 
   1403             if (ts == NULL || !OSSL_CMP_CTX_set0_trusted(ctx, ts)) {
   1404                 X509_STORE_free(ts);
   1405                 return 0;
   1406             }
   1407         }
   1408     }
   1409 
   1410     if (opt_unprotected_errors)
   1411         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS, 1);
   1412 
   1413     if (opt_out_trusted != NULL) { /* for use in OSSL_CMP_certConf_cb() */
   1414         X509_VERIFY_PARAM *out_vpm = NULL;
   1415         X509_STORE *out_trusted = load_trusted(opt_out_trusted, 1,
   1416             "trusted certs for verifying newly enrolled cert");
   1417 
   1418         if (out_trusted == NULL)
   1419             return 0;
   1420         /* ignore any -attime here, new certs are current anyway */
   1421         out_vpm = X509_STORE_get0_param(out_trusted);
   1422         X509_VERIFY_PARAM_clear_flags(out_vpm, X509_V_FLAG_USE_CHECK_TIME);
   1423 
   1424         (void)OSSL_CMP_CTX_set_certConf_cb_arg(ctx, out_trusted);
   1425     }
   1426 
   1427     if (opt_disable_confirm)
   1428         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_DISABLE_CONFIRM, 1);
   1429 
   1430     if (opt_implicit_confirm)
   1431         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM, 1);
   1432 
   1433     return 1;
   1434 }
   1435 
   1436 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   1437 /*
   1438  * set up ssl_ctx for the OSSL_CMP_CTX based on options from config file/CLI.
   1439  * Returns pointer on success, NULL on error
   1440  */
   1441 static SSL_CTX *setup_ssl_ctx(OSSL_CMP_CTX *ctx, const char *host,
   1442     ENGINE *engine)
   1443 {
   1444     STACK_OF(X509) *untrusted = OSSL_CMP_CTX_get0_untrusted(ctx);
   1445     EVP_PKEY *pkey = NULL;
   1446     X509_STORE *trust_store = NULL;
   1447     SSL_CTX *ssl_ctx;
   1448     int i;
   1449 
   1450     ssl_ctx = SSL_CTX_new(TLS_client_method());
   1451     if (ssl_ctx == NULL)
   1452         return NULL;
   1453 
   1454     if (opt_tls_trusted != NULL) {
   1455         trust_store = load_trusted(opt_tls_trusted, 0, "trusted TLS certs");
   1456         if (trust_store == NULL)
   1457             goto err;
   1458         SSL_CTX_set_cert_store(ssl_ctx, trust_store);
   1459         SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
   1460     } else {
   1461         CMP_warn("-tls_used given without -tls_trusted; will not authenticate the TLS server");
   1462     }
   1463 
   1464     if (opt_tls_cert != NULL && opt_tls_key != NULL) {
   1465         X509 *cert;
   1466         STACK_OF(X509) *certs = NULL;
   1467         int ok;
   1468 
   1469         if (!load_cert_certs(opt_tls_cert, &cert, &certs, 0, opt_tls_keypass,
   1470                 "TLS client certificate (optionally with chain)",
   1471                 vpm))
   1472             /* need opt_tls_keypass if opt_tls_cert is encrypted PKCS#12 file */
   1473             goto err;
   1474 
   1475         ok = SSL_CTX_use_certificate(ssl_ctx, cert) > 0;
   1476         X509_free(cert);
   1477 
   1478         /*
   1479          * Any further certs and any untrusted certs are used for constructing
   1480          * the chain to be provided with the TLS client cert to the TLS server.
   1481          */
   1482         if (!ok || !SSL_CTX_set0_chain(ssl_ctx, certs)) {
   1483             CMP_err1("unable to use client TLS certificate file '%s'",
   1484                 opt_tls_cert);
   1485             OSSL_STACK_OF_X509_free(certs);
   1486             goto err;
   1487         }
   1488         for (i = 0; i < sk_X509_num(untrusted); i++) {
   1489             cert = sk_X509_value(untrusted, i);
   1490             if (!SSL_CTX_add1_chain_cert(ssl_ctx, cert)) {
   1491                 CMP_err("could not add untrusted cert to TLS client cert chain");
   1492                 goto err;
   1493             }
   1494         }
   1495 
   1496         {
   1497             X509_VERIFY_PARAM *tls_vpm = NULL;
   1498             unsigned long bak_flags = 0; /* compiler warns without init */
   1499 
   1500             if (trust_store != NULL) {
   1501                 tls_vpm = X509_STORE_get0_param(trust_store);
   1502                 bak_flags = X509_VERIFY_PARAM_get_flags(tls_vpm);
   1503                 /* disable any cert status/revocation checking etc. */
   1504                 X509_VERIFY_PARAM_clear_flags(tls_vpm,
   1505                     ~(X509_V_FLAG_USE_CHECK_TIME
   1506                         | X509_V_FLAG_NO_CHECK_TIME
   1507                         | X509_V_FLAG_PARTIAL_CHAIN
   1508                         | X509_V_FLAG_POLICY_CHECK));
   1509             }
   1510             CMP_debug("trying to build cert chain for own TLS cert");
   1511             if (SSL_CTX_build_cert_chain(ssl_ctx,
   1512                     SSL_BUILD_CHAIN_FLAG_UNTRUSTED | SSL_BUILD_CHAIN_FLAG_NO_ROOT)) {
   1513                 CMP_debug("success building cert chain for own TLS cert");
   1514             } else {
   1515                 OSSL_CMP_CTX_print_errors(ctx);
   1516                 CMP_warn("could not build cert chain for own TLS cert");
   1517             }
   1518             if (trust_store != NULL)
   1519                 X509_VERIFY_PARAM_set_flags(tls_vpm, bak_flags);
   1520         }
   1521 
   1522         /* If present we append to the list also the certs from opt_tls_extra */
   1523         if (opt_tls_extra != NULL) {
   1524             STACK_OF(X509) *tls_extra = load_certs_multifile(opt_tls_extra,
   1525                 opt_otherpass,
   1526                 "extra certificates for TLS",
   1527                 vpm);
   1528             int res = 1;
   1529 
   1530             if (tls_extra == NULL)
   1531                 goto err;
   1532             for (i = 0; i < sk_X509_num(tls_extra); i++) {
   1533                 cert = sk_X509_value(tls_extra, i);
   1534                 if (res != 0)
   1535                     res = SSL_CTX_add_extra_chain_cert(ssl_ctx, cert);
   1536                 if (res == 0)
   1537                     X509_free(cert);
   1538             }
   1539             sk_X509_free(tls_extra);
   1540             if (res == 0) {
   1541                 BIO_printf(bio_err, "error: unable to add TLS extra certs\n");
   1542                 goto err;
   1543             }
   1544         }
   1545 
   1546         pkey = load_key_pwd(opt_tls_key, opt_keyform, opt_tls_keypass,
   1547             engine, "TLS client private key");
   1548         cleanse(opt_tls_keypass);
   1549         if (pkey == NULL)
   1550             goto err;
   1551         /*
   1552          * verify the key matches the cert,
   1553          * not using SSL_CTX_check_private_key(ssl_ctx)
   1554          * because it gives poor and sometimes misleading diagnostics
   1555          */
   1556         if (!X509_check_private_key(SSL_CTX_get0_certificate(ssl_ctx),
   1557                 pkey)) {
   1558             CMP_err2("TLS private key '%s' does not match the TLS certificate '%s'\n",
   1559                 opt_tls_key, opt_tls_cert);
   1560             EVP_PKEY_free(pkey);
   1561             pkey = NULL; /* otherwise, for some reason double free! */
   1562             goto err;
   1563         }
   1564         if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) <= 0) {
   1565             CMP_err1("unable to use TLS client private key '%s'", opt_tls_key);
   1566             EVP_PKEY_free(pkey);
   1567             pkey = NULL; /* otherwise, for some reason double free! */
   1568             goto err;
   1569         }
   1570         EVP_PKEY_free(pkey); /* we do not need the handle any more */
   1571     } else {
   1572         CMP_warn("-tls_used given without -tls_key; cannot authenticate to the TLS server");
   1573     }
   1574     if (trust_store != NULL) {
   1575         /*
   1576          * Enable and parameterize server hostname/IP address check.
   1577          * If we did this before checking our own TLS cert
   1578          * the expected hostname would mislead the check.
   1579          */
   1580         if (!truststore_set_host_etc(trust_store,
   1581                 opt_tls_host != NULL ? opt_tls_host : host))
   1582             goto err;
   1583     }
   1584     return ssl_ctx;
   1585 err:
   1586     SSL_CTX_free(ssl_ctx);
   1587     return NULL;
   1588 }
   1589 #endif /* OPENSSL_NO_SOCK */
   1590 
   1591 /*
   1592  * set up protection aspects of OSSL_CMP_CTX based on options from config
   1593  * file/CLI while parsing options and checking their consistency.
   1594  * Returns 1 on success, 0 on error
   1595  */
   1596 static int setup_protection_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
   1597 {
   1598     if (!opt_unprotected_requests && opt_secret == NULL && opt_key == NULL) {
   1599         CMP_err("must give -key or -secret unless -unprotected_requests is used");
   1600         return 0;
   1601     }
   1602 
   1603     if (opt_ref == NULL && opt_cert == NULL && opt_subject == NULL) {
   1604         /* cert or subject should determine the sender */
   1605         CMP_err("must give -ref if no -cert and no -subject given");
   1606         return 0;
   1607     }
   1608     if (opt_secret == NULL && ((opt_cert == NULL) != (opt_key == NULL))) {
   1609         CMP_err("must give both -cert and -key options or neither");
   1610         return 0;
   1611     }
   1612     if (opt_secret != NULL) {
   1613         char *pass_string = get_passwd(opt_secret, "PBMAC");
   1614         int res;
   1615 
   1616         if (pass_string != NULL) {
   1617             cleanse(opt_secret);
   1618             res = OSSL_CMP_CTX_set1_secretValue(ctx,
   1619                 (unsigned char *)pass_string,
   1620                 strlen(pass_string));
   1621             clear_free(pass_string);
   1622             if (res == 0)
   1623                 return 0;
   1624         }
   1625         if (opt_cert != NULL || opt_key != NULL)
   1626             CMP_warn("-cert and -key not used for protection since -secret is given");
   1627     }
   1628     if (opt_ref != NULL
   1629         && !OSSL_CMP_CTX_set1_referenceValue(ctx, (unsigned char *)opt_ref,
   1630             strlen(opt_ref)))
   1631         return 0;
   1632 
   1633     if (opt_key != NULL) {
   1634         EVP_PKEY *pkey = load_key_pwd(opt_key, opt_keyform, opt_keypass, engine,
   1635             "private key for CMP client certificate");
   1636 
   1637         if (pkey == NULL || !OSSL_CMP_CTX_set1_pkey(ctx, pkey)) {
   1638             EVP_PKEY_free(pkey);
   1639             return 0;
   1640         }
   1641         EVP_PKEY_free(pkey);
   1642     }
   1643     if (opt_secret == NULL && opt_srvcert == NULL && opt_trusted == NULL)
   1644         CMP_warn("will not authenticate server due to missing -secret, -trusted, or -srvcert");
   1645 
   1646     if (opt_cert != NULL) {
   1647         X509 *cert;
   1648         STACK_OF(X509) *certs = NULL;
   1649         X509_STORE *own_trusted = NULL;
   1650         int ok;
   1651 
   1652         if (!load_cert_certs(opt_cert, &cert, &certs, 0, opt_keypass,
   1653                 "CMP client certificate (optionally with chain)",
   1654                 vpm))
   1655             /* opt_keypass is needed if opt_cert is an encrypted PKCS#12 file */
   1656             return 0;
   1657         ok = OSSL_CMP_CTX_set1_cert(ctx, cert);
   1658         X509_free(cert);
   1659         if (!ok) {
   1660             CMP_err("out of memory");
   1661         } else {
   1662             if (opt_own_trusted != NULL) {
   1663                 own_trusted = load_trusted(opt_own_trusted, 0,
   1664                     "trusted certs for verifying own CMP signer cert");
   1665                 ok = own_trusted != NULL;
   1666             }
   1667             ok = ok && OSSL_CMP_CTX_build_cert_chain(ctx, own_trusted, certs);
   1668         }
   1669         X509_STORE_free(own_trusted);
   1670         OSSL_STACK_OF_X509_free(certs);
   1671         if (!ok)
   1672             return 0;
   1673     } else if (opt_own_trusted != NULL) {
   1674         CMP_warn("-own_trusted option is ignored without -cert");
   1675     }
   1676 
   1677     if (!setup_certs(opt_extracerts, "extra certificates for CMP", ctx,
   1678             (add_X509_stack_fn_t)OSSL_CMP_CTX_set1_extraCertsOut))
   1679         return 0;
   1680     cleanse(opt_otherpass);
   1681 
   1682     if (opt_unprotected_requests)
   1683         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_SEND, 1);
   1684 
   1685     if (opt_digest != NULL) {
   1686         int digest = OBJ_ln2nid(opt_digest);
   1687 
   1688         if (digest == NID_undef) {
   1689             CMP_err1("digest algorithm name not recognized: '%s'", opt_digest);
   1690             return 0;
   1691         }
   1692         if (!OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_DIGEST_ALGNID, digest)
   1693             || !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_OWF_ALGNID, digest)) {
   1694             CMP_err1("digest algorithm name not supported: '%s'", opt_digest);
   1695             return 0;
   1696         }
   1697     }
   1698 
   1699     if (opt_mac != NULL) {
   1700         int mac = OBJ_ln2nid(opt_mac);
   1701 
   1702         if (mac == NID_undef) {
   1703             CMP_err1("MAC algorithm name not recognized: '%s'", opt_mac);
   1704             return 0;
   1705         }
   1706         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_MAC_ALGNID, mac);
   1707     }
   1708     return 1;
   1709 }
   1710 
   1711 static int set_fallback_pubkey(OSSL_CMP_CTX *ctx)
   1712 {
   1713     char *file = opt_reqin, *end = file, bak;
   1714     OSSL_CMP_MSG *req;
   1715     const X509_PUBKEY *pubkey;
   1716     EVP_PKEY *pkey;
   1717     EVP_PKEY *pkey1;
   1718     int res = 0;
   1719 
   1720     /* temporarily separate first file name in opt_reqin */
   1721     while (*end != ',' && !isspace(_UC(*end)) && *end != '\0')
   1722         end++;
   1723     bak = *end;
   1724     *end = '\0';
   1725     req = OSSL_CMP_MSG_read(file, app_get0_libctx(), app_get0_propq());
   1726     *end = bak;
   1727 
   1728     if (req == NULL) {
   1729         CMP_err1("failed to load ir/cr/kur file '%s' attempting to get fallback public key",
   1730             file);
   1731         return 0;
   1732     }
   1733     if ((pubkey = OSSL_CMP_MSG_get0_certreq_publickey(req)) == NULL
   1734         || (pkey = X509_PUBKEY_get0(pubkey)) == NULL) {
   1735         CMP_err1("failed to get fallback public key from ir/cr/kur file '%s'",
   1736             file);
   1737         goto err;
   1738     }
   1739     pkey1 = EVP_PKEY_dup(pkey);
   1740     if (pkey == NULL || !OSSL_CMP_CTX_set0_newPkey(ctx, 0 /* priv */, pkey1)) {
   1741         EVP_PKEY_free(pkey1);
   1742         CMP_err1("failed to get fallback public key obtained from ir/cr/kur file '%s'",
   1743             file);
   1744         goto err;
   1745     }
   1746     res = 1;
   1747 
   1748 err:
   1749     OSSL_CMP_MSG_free(req);
   1750     return res;
   1751 }
   1752 
   1753 /*
   1754  * Set up IR/CR/P10CR/KUR/CertConf/RR/GENM specific parts of the OSSL_CMP_CTX
   1755  * based on options from CLI and/or config file.
   1756  * Returns 1 on success, 0 on error
   1757  */
   1758 static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
   1759 {
   1760     X509_REQ *csr = NULL;
   1761     X509_EXTENSIONS *exts = NULL;
   1762     X509V3_CTX ext_ctx;
   1763 
   1764     if (opt_subject == NULL
   1765         && opt_csr == NULL && opt_oldcert == NULL && opt_cert == NULL
   1766         && opt_cmd != CMP_RR && opt_cmd != CMP_GENM)
   1767         CMP_warn("no -subject given; no -csr or -oldcert or -cert available for fallback");
   1768 
   1769     if (!set_name(opt_issuer, OSSL_CMP_CTX_set1_issuer, ctx, "issuer"))
   1770         return 0;
   1771     if (opt_cmd == CMP_IR || opt_cmd == CMP_CR || opt_cmd == CMP_KUR) {
   1772         if (opt_reqin == NULL && opt_newkey == NULL && !opt_centralkeygen
   1773             && opt_key == NULL && opt_csr == NULL && opt_oldcert == NULL) {
   1774             CMP_err("missing -newkey (or -key) to be certified and no -csr, -oldcert, -cert, or -reqin option given, which could provide fallback public key."
   1775                     " Neither central key generation is requested.");
   1776             return 0;
   1777         }
   1778         if (opt_popo == OSSL_CRMF_POPO_NONE && !opt_centralkeygen) {
   1779             CMP_info("POPO is disabled, which implies -centralkeygen");
   1780             opt_centralkeygen = 1;
   1781         }
   1782         if (opt_centralkeygen) {
   1783             if (opt_popo > OSSL_CRMF_POPO_NONE) {
   1784                 CMP_err1("-popo value %d is inconsistent with -centralkeygen", opt_popo);
   1785                 return 0;
   1786             }
   1787             if (opt_newkeyout == NULL) {
   1788                 CMP_err("-newkeyout not given, nowhere to save centrally generated key");
   1789                 return 0;
   1790             }
   1791             opt_popo = OSSL_CRMF_POPO_NONE;
   1792         }
   1793         if (opt_newkey == NULL
   1794             && opt_popo != OSSL_CRMF_POPO_NONE
   1795             && opt_popo != OSSL_CRMF_POPO_RAVERIFIED) {
   1796             if (opt_csr != NULL) {
   1797                 CMP_err1("no -newkey option given with private key for POPO, -csr option provides just public key%s",
   1798                     opt_key == NULL ? "" : ", and -key option superseded by -csr");
   1799                 if (opt_reqin != NULL)
   1800                     CMP_info("since -reqin is used, may use -popo -1 or -popo 0 to disable the needless generation of a POPO");
   1801                 return 0;
   1802             }
   1803             if (opt_key == NULL) {
   1804                 CMP_err("missing -newkey (or -key) option for key to be certified and for POPO");
   1805                 return 0;
   1806             }
   1807         }
   1808         if (opt_certout == NULL && opt_reqout_only == NULL) {
   1809             CMP_err("-certout not given, nowhere to save newly enrolled certificate");
   1810             return 0;
   1811         }
   1812         if (!set_name(opt_subject, OSSL_CMP_CTX_set1_subjectName, ctx, "subject"))
   1813             return 0;
   1814     } else {
   1815         const char *msg = "option is ignored for commands other than 'ir', 'cr', and 'kur'";
   1816 
   1817         if (opt_subject != NULL) {
   1818             if (opt_ref == NULL && opt_cert == NULL) {
   1819                 /* will use subject as sender unless oldcert subject is used */
   1820                 if (!set_name(opt_subject, OSSL_CMP_CTX_set1_subjectName, ctx, "subject"))
   1821                     return 0;
   1822             } else {
   1823                 CMP_warn1("-subject %s since sender is taken from -ref or -cert",
   1824                     msg);
   1825             }
   1826         }
   1827         if (opt_issuer != NULL && opt_cmd != CMP_RR)
   1828             CMP_warn1("-issuer %s and 'rr'", msg);
   1829         if (opt_reqexts != NULL)
   1830             CMP_warn1("-reqexts %s", msg);
   1831         if (opt_san_nodefault)
   1832             CMP_warn1("-san_nodefault %s", msg);
   1833         if (opt_sans != NULL)
   1834             CMP_warn1("-sans %s", msg);
   1835         if (opt_policies != NULL)
   1836             CMP_warn1("-policies %s", msg);
   1837         if (opt_policy_oids != NULL)
   1838             CMP_warn1("-policy_oids %s", msg);
   1839         if (opt_popo != OSSL_CRMF_POPO_NONE - 1)
   1840             CMP_warn1("-popo %s", msg);
   1841         if (opt_centralkeygen)
   1842             CMP_warn1("-popo -1 or -centralkeygen %s", msg);
   1843         if (opt_newkeyout != NULL)
   1844             CMP_warn1("-newkeyout %s", msg);
   1845         if (opt_cmd != CMP_P10CR) {
   1846             if (opt_implicit_confirm)
   1847                 CMP_warn1("-implicit_confirm %s, and 'p10cr'", msg);
   1848             if (opt_disable_confirm)
   1849                 CMP_warn1("-disable_confirm %s, and 'p10cr'", msg);
   1850             if (opt_certout != NULL)
   1851                 CMP_warn1("-certout %s, and 'p10cr'", msg);
   1852             if (opt_chainout != NULL)
   1853                 CMP_warn1("-chainout %s, and 'p10cr'", msg);
   1854         }
   1855     }
   1856     if (opt_cmd == CMP_KUR) {
   1857         char *ref_cert = opt_oldcert != NULL ? opt_oldcert : opt_cert;
   1858 
   1859         if (ref_cert == NULL && opt_csr == NULL) {
   1860             CMP_err("missing -oldcert for certificate to be updated and no -csr given");
   1861             return 0;
   1862         }
   1863         if (opt_subject != NULL)
   1864             CMP_warn2("given -subject '%s' overrides the subject of '%s' for KUR",
   1865                 opt_subject, ref_cert != NULL ? ref_cert : opt_csr);
   1866     }
   1867     if (opt_cmd == CMP_RR) {
   1868         if (opt_issuer == NULL && opt_serial == NULL) {
   1869             if (opt_oldcert == NULL && opt_csr == NULL) {
   1870                 CMP_err("missing -oldcert or -issuer and -serial for certificate to be revoked and no -csr given");
   1871                 return 0;
   1872             }
   1873             if (opt_oldcert != NULL && opt_csr != NULL)
   1874                 CMP_warn("ignoring -csr since certificate to be revoked is given");
   1875         } else {
   1876 #define OSSL_CMP_RR_MSG "since -issuer and -serial is given for command 'rr'"
   1877             if (opt_issuer == NULL || opt_serial == NULL) {
   1878                 CMP_err("Must give both -issuer and -serial options or neither");
   1879                 return 0;
   1880             }
   1881             if (opt_oldcert != NULL)
   1882                 CMP_warn("Ignoring -oldcert " OSSL_CMP_RR_MSG);
   1883             if (opt_csr != NULL)
   1884                 CMP_warn("Ignoring -csr " OSSL_CMP_RR_MSG);
   1885         }
   1886         if (opt_serial != NULL) {
   1887             ASN1_INTEGER *sno;
   1888 
   1889             if ((sno = s2i_ASN1_INTEGER(NULL, opt_serial)) == NULL) {
   1890                 CMP_err1("cannot read serial number: '%s'", opt_serial);
   1891                 return 0;
   1892             }
   1893             if (!OSSL_CMP_CTX_set1_serialNumber(ctx, sno)) {
   1894                 ASN1_INTEGER_free(sno);
   1895                 CMP_err("out of memory");
   1896                 return 0;
   1897             }
   1898             ASN1_INTEGER_free(sno);
   1899         }
   1900         if (opt_revreason > CRL_REASON_NONE)
   1901             (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_REVOCATION_REASON,
   1902                 opt_revreason);
   1903     } else {
   1904         if (opt_serial != NULL)
   1905             CMP_warn("Ignoring -serial for command other than 'rr'");
   1906     }
   1907     if (opt_cmd == CMP_P10CR && opt_csr == NULL) {
   1908         CMP_err("missing PKCS#10 CSR for p10cr");
   1909         return 0;
   1910     }
   1911 
   1912     if (opt_recipient == NULL && opt_srvcert == NULL && opt_issuer == NULL
   1913         && opt_oldcert == NULL && opt_cert == NULL)
   1914         CMP_warn("missing -recipient, -srvcert, -issuer, -oldcert or -cert; recipient for any requests not covered by -reqin will be set to \"NULL-DN\"");
   1915 
   1916     if (opt_cmd == CMP_P10CR || opt_cmd == CMP_RR || opt_cmd == CMP_GENM) {
   1917         const char *msg = "option is ignored for 'p10cr', 'rr', and 'genm' commands";
   1918 
   1919         if (opt_newkeypass != NULL)
   1920             CMP_warn1("-newkeypass %s", msg);
   1921         if (opt_newkey != NULL)
   1922             CMP_warn1("-newkey %s", msg);
   1923         if (opt_days != 0)
   1924             CMP_warn1("-days %s", msg);
   1925         if (opt_popo != OSSL_CRMF_POPO_NONE - 1)
   1926             CMP_warn1("-popo %s", msg);
   1927         if (opt_out_trusted != NULL)
   1928             CMP_warn1("-out_trusted %s", msg);
   1929     } else if (opt_newkey != NULL) {
   1930         const char *file = opt_newkey;
   1931         const int format = opt_keyform;
   1932         const char *pass = opt_newkeypass;
   1933         const char *desc = "new private key for cert to be enrolled";
   1934         EVP_PKEY *pkey;
   1935         int priv = 1;
   1936         BIO *bio_bak = bio_err;
   1937 
   1938         bio_err = NULL; /* suppress diagnostics on first try loading key */
   1939         pkey = load_key_pwd(file, format, pass, engine, desc);
   1940         bio_err = bio_bak;
   1941         if (pkey == NULL) {
   1942             ERR_clear_error();
   1943             desc = opt_csr == NULL
   1944                 ? "fallback public key for cert to be enrolled"
   1945                 : "public key for checking cert resulting from p10cr";
   1946             pkey = load_pubkey(file, format, 0, pass, engine, desc);
   1947             priv = 0;
   1948         }
   1949 
   1950         if (pkey == NULL || !OSSL_CMP_CTX_set0_newPkey(ctx, priv, pkey)) {
   1951             EVP_PKEY_free(pkey);
   1952             return 0;
   1953         }
   1954     } else if (opt_reqin != NULL
   1955         && opt_key == NULL && opt_csr == NULL && opt_oldcert == NULL
   1956         && !opt_centralkeygen) {
   1957         if (!set_fallback_pubkey(ctx))
   1958             return 0;
   1959     }
   1960 
   1961     if (opt_days > 0
   1962         && !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_VALIDITY_DAYS,
   1963             opt_days)) {
   1964         CMP_err("could not set requested cert validity period");
   1965         return 0;
   1966     }
   1967 
   1968     if (opt_policies != NULL && opt_policy_oids != NULL) {
   1969         CMP_err("cannot have policies both via -policies and via -policy_oids");
   1970         return 0;
   1971     }
   1972 
   1973     if (opt_csr != NULL) {
   1974         if (opt_cmd == CMP_GENM) {
   1975             CMP_warn("-csr option is ignored for 'genm' command");
   1976         } else {
   1977             csr = load_csr_autofmt(opt_csr, FORMAT_UNDEF, NULL, "PKCS#10 CSR");
   1978             if (csr == NULL)
   1979                 return 0;
   1980             if (!OSSL_CMP_CTX_set1_p10CSR(ctx, csr))
   1981                 goto oom;
   1982         }
   1983     }
   1984     if (opt_reqexts != NULL || opt_policies != NULL) {
   1985         if ((exts = sk_X509_EXTENSION_new_null()) == NULL)
   1986             goto oom;
   1987         X509V3_set_ctx(&ext_ctx, NULL, NULL, csr, NULL, X509V3_CTX_REPLACE);
   1988         X509V3_set_nconf(&ext_ctx, conf);
   1989         if (opt_reqexts != NULL
   1990             && !X509V3_EXT_add_nconf_sk(conf, &ext_ctx, opt_reqexts, &exts)) {
   1991             CMP_err1("cannot load certificate request extension section '%s'",
   1992                 opt_reqexts);
   1993             goto exts_err;
   1994         }
   1995         if (opt_policies != NULL
   1996             && !X509V3_EXT_add_nconf_sk(conf, &ext_ctx, opt_policies, &exts)) {
   1997             CMP_err1("cannot load policy cert request extension section '%s'",
   1998                 opt_policies);
   1999             goto exts_err;
   2000         }
   2001         OSSL_CMP_CTX_set0_reqExtensions(ctx, exts);
   2002     }
   2003     X509_REQ_free(csr);
   2004     /* After here, must not goto oom/exts_err */
   2005 
   2006     if (OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) && opt_sans != NULL) {
   2007         CMP_err("cannot have Subject Alternative Names both via -reqexts and via -sans");
   2008         return 0;
   2009     }
   2010     if (!set_gennames(ctx, opt_sans, "Subject Alternative Name"))
   2011         return 0;
   2012 
   2013     if (opt_san_nodefault) {
   2014         if (opt_sans != NULL)
   2015             CMP_warn("-opt_san_nodefault has no effect when -sans is used");
   2016         (void)OSSL_CMP_CTX_set_option(ctx,
   2017             OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT, 1);
   2018     }
   2019 
   2020     if (opt_policy_oids_critical) {
   2021         if (opt_policy_oids == NULL)
   2022             CMP_warn("-opt_policy_oids_critical has no effect unless -policy_oids is given");
   2023         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_POLICIES_CRITICAL, 1);
   2024     }
   2025 
   2026     while (opt_policy_oids != NULL) {
   2027         ASN1_OBJECT *policy;
   2028         POLICYINFO *pinfo;
   2029         char *next = next_item(opt_policy_oids);
   2030 
   2031         if ((policy = OBJ_txt2obj(opt_policy_oids, 1)) == 0) {
   2032             CMP_err1("Invalid -policy_oids arg '%s'", opt_policy_oids);
   2033             return 0;
   2034         }
   2035         if (OBJ_obj2nid(policy) == NID_undef)
   2036             CMP_warn1("Unknown -policy_oids arg: %.40s", opt_policy_oids);
   2037 
   2038         if ((pinfo = POLICYINFO_new()) == NULL) {
   2039             ASN1_OBJECT_free(policy);
   2040             return 0;
   2041         }
   2042         pinfo->policyid = policy;
   2043 
   2044         if (!OSSL_CMP_CTX_push0_policy(ctx, pinfo)) {
   2045             CMP_err1("cannot add policy with OID '%s'", opt_policy_oids);
   2046             POLICYINFO_free(pinfo);
   2047             return 0;
   2048         }
   2049         opt_policy_oids = next;
   2050     }
   2051     if (opt_popo >= OSSL_CRMF_POPO_NONE)
   2052         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_POPO_METHOD, opt_popo);
   2053 
   2054     if (opt_oldcert != NULL) {
   2055         if (opt_cmd == CMP_GENM) {
   2056             CMP_warn("-oldcert option is ignored for 'genm' command");
   2057         } else {
   2058             if (!setup_cert(ctx, opt_oldcert, opt_keypass,
   2059                     /* needed if opt_oldcert is encrypted PKCS12 file */
   2060                     opt_cmd == CMP_KUR ? "certificate to be updated" : opt_cmd == CMP_RR ? "certificate to be revoked"
   2061                                                                                          : "reference certificate (oldcert)",
   2062                     (add_X509_fn_t)OSSL_CMP_CTX_set1_oldCert))
   2063                 return 0;
   2064         }
   2065     }
   2066     cleanse(opt_keypass);
   2067 
   2068     return 1;
   2069 
   2070 oom:
   2071     CMP_err("out of memory");
   2072 exts_err:
   2073     sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
   2074     X509_REQ_free(csr);
   2075     return 0;
   2076 }
   2077 
   2078 static int add_certProfile(OSSL_CMP_CTX *ctx, const char *name)
   2079 {
   2080     OSSL_CMP_ITAV *itav = NULL;
   2081     STACK_OF(ASN1_UTF8STRING) *sk;
   2082     ASN1_UTF8STRING *utf8string;
   2083 
   2084     if (ctx == NULL || name == NULL)
   2085         return 0;
   2086 
   2087     if ((sk = sk_ASN1_UTF8STRING_new_reserve(NULL, 1)) == NULL)
   2088         return 0;
   2089     if ((utf8string = ASN1_UTF8STRING_new()) == NULL)
   2090         goto err;
   2091     if (!ASN1_STRING_set(utf8string, name, (int)strlen(name))) {
   2092         ASN1_STRING_free(utf8string);
   2093         goto err;
   2094     }
   2095     /* Due to sk_ASN1_UTF8STRING_new_reserve(NULL, 1), this surely succeeds: */
   2096     (void)sk_ASN1_UTF8STRING_push(sk, utf8string);
   2097     if ((itav = OSSL_CMP_ITAV_new0_certProfile(sk)) == NULL)
   2098         goto err;
   2099     if (OSSL_CMP_CTX_push0_geninfo_ITAV(ctx, itav))
   2100         return 1;
   2101     OSSL_CMP_ITAV_free(itav);
   2102     return 0;
   2103 
   2104 err:
   2105     sk_ASN1_UTF8STRING_pop_free(sk, ASN1_UTF8STRING_free);
   2106     return 0;
   2107 }
   2108 
   2109 static int handle_opt_geninfo(OSSL_CMP_CTX *ctx)
   2110 {
   2111     ASN1_OBJECT *obj = NULL;
   2112     ASN1_TYPE *type = NULL;
   2113     long value;
   2114     ASN1_INTEGER *aint = NULL;
   2115     ASN1_UTF8STRING *text = NULL;
   2116     OSSL_CMP_ITAV *itav;
   2117     char *ptr = opt_geninfo, *oid, *end;
   2118 
   2119     do {
   2120         while (isspace(_UC(*ptr)))
   2121             ptr++;
   2122         oid = ptr;
   2123         if ((ptr = strchr(oid, ':')) == NULL) {
   2124             CMP_err1("Missing ':' in -geninfo arg %.40s", oid);
   2125             return 0;
   2126         }
   2127         *ptr++ = '\0';
   2128         if ((obj = OBJ_txt2obj(oid, 0)) == NULL) {
   2129             CMP_err1("Invalid OID in -geninfo arg %.40s", oid);
   2130             return 0;
   2131         }
   2132         if (OBJ_obj2nid(obj) == NID_undef)
   2133             CMP_warn1("Unknown OID in -geninfo arg: %.40s", oid);
   2134         if ((type = ASN1_TYPE_new()) == NULL)
   2135             goto oom;
   2136 
   2137         if (CHECK_AND_SKIP_CASE_PREFIX(ptr, "int:")) {
   2138             value = strtol(ptr, &end, 10);
   2139             if (end == ptr) {
   2140                 CMP_err1("Cannot parse int in -geninfo arg %.40s", ptr);
   2141                 goto err;
   2142             }
   2143             ptr = end;
   2144             if (*ptr != '\0') {
   2145                 if (*ptr != ',') {
   2146                     CMP_err1("Missing ',' or end of -geninfo arg after int at %.40s",
   2147                         ptr);
   2148                     goto err;
   2149                 }
   2150                 ptr++;
   2151             }
   2152 
   2153             if ((aint = ASN1_INTEGER_new()) == NULL
   2154                 || !ASN1_INTEGER_set(aint, value))
   2155                 goto oom;
   2156             ASN1_TYPE_set(type, V_ASN1_INTEGER, aint);
   2157             aint = NULL;
   2158 
   2159         } else if (CHECK_AND_SKIP_CASE_PREFIX(ptr, "str:")) {
   2160             end = strchr(ptr, ',');
   2161             if (end == NULL)
   2162                 end = ptr + strlen(ptr);
   2163             else
   2164                 *end++ = '\0';
   2165             if ((text = ASN1_UTF8STRING_new()) == NULL
   2166                 || !ASN1_STRING_set(text, ptr, -1))
   2167                 goto oom;
   2168             ptr = end;
   2169             ASN1_TYPE_set(type, V_ASN1_UTF8STRING, text);
   2170             text = NULL;
   2171 
   2172         } else {
   2173             CMP_err1("Missing 'int:' or 'str:' in -geninfo arg %.40s", ptr);
   2174             goto err;
   2175         }
   2176 
   2177         if ((itav = OSSL_CMP_ITAV_create(obj, type)) == NULL) {
   2178             CMP_err("Unable to create 'OSSL_CMP_ITAV' structure");
   2179             goto err;
   2180         }
   2181         obj = NULL;
   2182         type = NULL;
   2183 
   2184         if (!OSSL_CMP_CTX_push0_geninfo_ITAV(ctx, itav)) {
   2185             CMP_err("Failed to add ITAV for geninfo of the PKI message header");
   2186             OSSL_CMP_ITAV_free(itav);
   2187             return 0;
   2188         }
   2189     } while (*ptr != '\0');
   2190     return 1;
   2191 
   2192 oom:
   2193     CMP_err("out of memory");
   2194 err:
   2195     ASN1_OBJECT_free(obj);
   2196     ASN1_TYPE_free(type);
   2197     ASN1_INTEGER_free(aint);
   2198     ASN1_UTF8STRING_free(text);
   2199     return 0;
   2200 }
   2201 
   2202 /*
   2203  * set up the client-side OSSL_CMP_CTX based on options from config file/CLI
   2204  * while parsing options and checking their consistency.
   2205  * Prints reason for error to bio_err.
   2206  * Returns 1 on success, 0 on error
   2207  */
   2208 static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
   2209 {
   2210     int ret = 0;
   2211     char *host = NULL, *port = NULL, *path = NULL, *used_path = opt_path;
   2212 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   2213     int portnum, use_ssl;
   2214     static char server_port[32] = { '\0' };
   2215     const char *proxy_host = NULL;
   2216 #endif
   2217     char server_buf[200] = "mock server";
   2218     char proxy_buf[200] = "";
   2219 
   2220     if (!opt_use_mock_srv)
   2221         strcpy(server_buf, "no server");
   2222     if (!opt_use_mock_srv && opt_rspin == NULL) { /* note: -port is not given */
   2223 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   2224         if (opt_server == NULL && opt_reqout_only == NULL) {
   2225             CMP_err("missing -server or -use_mock_srv or -rspin option");
   2226             goto err;
   2227         }
   2228 #else
   2229         CMP_err("missing -use_mock_srv or -rspin option; -server option is not supported due to no-sock build");
   2230         goto err;
   2231 #endif
   2232     }
   2233 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   2234     if (opt_server == NULL) {
   2235         if (opt_proxy != NULL)
   2236             CMP_warn("ignoring -proxy option since -server is not given");
   2237         if (opt_no_proxy != NULL)
   2238             CMP_warn("ignoring -no_proxy option since -server is not given");
   2239         goto set_path;
   2240     }
   2241     if (!OSSL_HTTP_parse_url(opt_server, &use_ssl, NULL /* user */,
   2242             &host, &port, &portnum,
   2243             &path, NULL /* q */, NULL /* frag */)) {
   2244         CMP_err1("cannot parse -server URL: %s", opt_server);
   2245         goto err;
   2246     }
   2247     if (use_ssl && !opt_tls_used) {
   2248         CMP_warn("assuming -tls_used since -server URL indicates HTTPS");
   2249         opt_tls_used = 1;
   2250     }
   2251     if (!OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_USE_TLS, opt_tls_used))
   2252         goto err;
   2253 
   2254     BIO_snprintf(server_port, sizeof(server_port), "%s", port);
   2255     if (opt_path == NULL)
   2256         used_path = path;
   2257     if (!OSSL_CMP_CTX_set1_server(ctx, host)
   2258         || !OSSL_CMP_CTX_set_serverPort(ctx, portnum))
   2259         goto oom;
   2260     if (opt_proxy != NULL && !OSSL_CMP_CTX_set1_proxy(ctx, opt_proxy))
   2261         goto oom;
   2262     if (opt_no_proxy != NULL && !OSSL_CMP_CTX_set1_no_proxy(ctx, opt_no_proxy))
   2263         goto oom;
   2264     (void)BIO_snprintf(server_buf, sizeof(server_buf), "http%s://%s:%s/%s",
   2265         opt_tls_used ? "s" : "", host, port,
   2266         *used_path == '/' ? used_path + 1 : used_path);
   2267 
   2268     proxy_host = OSSL_HTTP_adapt_proxy(opt_proxy, opt_no_proxy, host, use_ssl);
   2269     if (proxy_host != NULL)
   2270         (void)BIO_snprintf(proxy_buf, sizeof(proxy_buf), " via %s", proxy_host);
   2271 
   2272 set_path:
   2273 #endif
   2274 
   2275     if (!OSSL_CMP_CTX_set1_serverPath(ctx, used_path))
   2276         goto oom;
   2277     if (!transform_opts())
   2278         goto err;
   2279 
   2280     if (opt_infotype_s == NULL) {
   2281         if (opt_cmd == CMP_GENM)
   2282             CMP_warn("no -infotype option given for genm");
   2283     } else if (opt_cmd != CMP_GENM) {
   2284         CMP_warn("-infotype option is ignored for commands other than 'genm'");
   2285     } else {
   2286         char id_buf[100] = "id-it-";
   2287 
   2288         strncat(id_buf, opt_infotype_s, sizeof(id_buf) - strlen(id_buf) - 1);
   2289         if ((opt_infotype = OBJ_sn2nid(id_buf)) == NID_undef) {
   2290             CMP_err("unknown OID name in -infotype option");
   2291             goto err;
   2292         }
   2293     }
   2294     if (opt_cmd != CMP_GENM || opt_infotype != NID_id_it_rootCaCert) {
   2295         const char *msg = "option is ignored unless -cmd 'genm' and -infotype rootCaCert is given";
   2296 
   2297         if (opt_oldwithold != NULL)
   2298             CMP_warn1("-oldwithold %s", msg);
   2299         if (opt_newwithnew != NULL)
   2300             CMP_warn1("-newwithnew %s", msg);
   2301         if (opt_newwithold != NULL)
   2302             CMP_warn1("-newwithold %s", msg);
   2303         if (opt_oldwithnew != NULL)
   2304             CMP_warn1("-oldwithnew %s", msg);
   2305     }
   2306     if (opt_cmd != CMP_GENM || opt_infotype != NID_id_it_certReqTemplate) {
   2307         const char *msg = "option is ignored unless -cmd 'genm' and -infotype 'certReqTemplate' is given";
   2308 
   2309         if (opt_template != NULL)
   2310             CMP_warn1("-template %s", msg);
   2311         if (opt_keyspec != NULL)
   2312             CMP_warn1("-keyspec %s", msg);
   2313     } else {
   2314         if (opt_template == NULL)
   2315             CMP_err("missing -template option for genm with infotype certReqTemplate");
   2316     }
   2317 
   2318     if (!setup_verification_ctx(ctx))
   2319         goto err;
   2320 
   2321     if (opt_keep_alive != 1)
   2322         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_KEEP_ALIVE,
   2323             opt_keep_alive);
   2324     if (opt_total_timeout > 0 && opt_msg_timeout > 0
   2325         && opt_total_timeout < opt_msg_timeout) {
   2326         CMP_err2("-total_timeout argument = %d must not be < %d (-msg_timeout)",
   2327             opt_total_timeout, opt_msg_timeout);
   2328         goto err;
   2329     }
   2330     if (opt_msg_timeout >= 0) /* must do this before setup_ssl_ctx() */
   2331         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_MSG_TIMEOUT,
   2332             opt_msg_timeout);
   2333     if (opt_total_timeout >= 0)
   2334         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_TOTAL_TIMEOUT,
   2335             opt_total_timeout);
   2336 
   2337     if (opt_rspin != NULL) {
   2338         rspin_in_use = 1;
   2339         if (opt_reqin != NULL)
   2340             CMP_warn("-reqin is ignored since -rspin is present");
   2341     }
   2342     if (opt_reqin_new_tid && opt_reqin == NULL)
   2343         CMP_warn("-reqin_new_tid is ignored since -reqin is not present");
   2344     if (opt_reqin != NULL || opt_reqout != NULL
   2345         || opt_rspin != NULL || opt_rspout != NULL || opt_use_mock_srv)
   2346         (void)OSSL_CMP_CTX_set_transfer_cb(ctx, read_write_req_resp);
   2347 
   2348 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   2349     if (opt_tls_used) {
   2350         APP_HTTP_TLS_INFO *info;
   2351 
   2352         if (opt_tls_cert != NULL
   2353             || opt_tls_key != NULL || opt_tls_keypass != NULL) {
   2354             if (opt_tls_key == NULL) {
   2355                 CMP_err("missing -tls_key option");
   2356                 goto err;
   2357             } else if (opt_tls_cert == NULL) {
   2358                 CMP_err("missing -tls_cert option");
   2359                 goto err;
   2360             }
   2361         }
   2362 
   2363         if ((info = OPENSSL_zalloc(sizeof(*info))) == NULL)
   2364             goto err;
   2365         APP_HTTP_TLS_INFO_free(OSSL_CMP_CTX_get_http_cb_arg(ctx));
   2366         (void)OSSL_CMP_CTX_set_http_cb_arg(ctx, info);
   2367         info->ssl_ctx = setup_ssl_ctx(ctx, host, engine);
   2368         info->server = host;
   2369         host = NULL; /* prevent deallocation */
   2370         if ((info->port = OPENSSL_strdup(server_port)) == NULL)
   2371             goto err;
   2372         /* workaround for callback design flaw, see #17088: */
   2373         info->use_proxy = proxy_host != NULL;
   2374         info->timeout = OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_MSG_TIMEOUT);
   2375 
   2376         if (info->ssl_ctx == NULL)
   2377             goto err;
   2378         (void)OSSL_CMP_CTX_set_http_cb(ctx, app_http_tls_cb);
   2379     }
   2380 #endif
   2381 
   2382     if (!setup_protection_ctx(ctx, engine))
   2383         goto err;
   2384 
   2385     if (!setup_request_ctx(ctx, engine))
   2386         goto err;
   2387 
   2388     if (!set_name(opt_recipient, OSSL_CMP_CTX_set1_recipient, ctx, "recipient")
   2389         || !set_name(opt_expect_sender, OSSL_CMP_CTX_set1_expected_sender,
   2390             ctx, "expected sender"))
   2391         goto err;
   2392 
   2393     if (opt_geninfo != NULL && !handle_opt_geninfo(ctx))
   2394         goto err;
   2395     if (opt_profile != NULL && !add_certProfile(ctx, opt_profile))
   2396         goto err;
   2397 
   2398     /* not printing earlier, to minimize confusion in case setup fails before */
   2399     if (opt_reqout_only == NULL)
   2400         CMP_info3("will contact %s%s%s ", server_buf, proxy_buf,
   2401             opt_rspin == NULL ? "" : " only if -rspin argument gives too few filenames");
   2402 
   2403     ret = 1;
   2404 
   2405 err:
   2406     OPENSSL_free(host);
   2407     OPENSSL_free(port);
   2408     OPENSSL_free(path);
   2409     return ret;
   2410 oom:
   2411     CMP_err("out of memory");
   2412     goto err;
   2413 }
   2414 
   2415 /*
   2416  * write out the given certificate to the output specified by bio.
   2417  * Depending on options use either PEM or DER format.
   2418  * Returns 1 on success, 0 on error
   2419  */
   2420 static int write_cert(BIO *bio, X509 *cert)
   2421 {
   2422     if ((opt_certform == FORMAT_PEM && PEM_write_bio_X509(bio, cert))
   2423         || (opt_certform == FORMAT_ASN1 && i2d_X509_bio(bio, cert)))
   2424         return 1;
   2425     if (opt_certform != FORMAT_PEM && opt_certform != FORMAT_ASN1)
   2426         BIO_printf(bio_err,
   2427             "error: unsupported type '%s' for writing certificates\n",
   2428             opt_certform_s);
   2429     return 0;
   2430 }
   2431 
   2432 static int write_crl(BIO *bio, X509_CRL *crl)
   2433 {
   2434     if (opt_crlform != FORMAT_PEM && opt_crlform != FORMAT_ASN1) {
   2435         BIO_printf(bio_err, "error: unsupported type '%s' for writing CRLs\n",
   2436             opt_crlform_s);
   2437         return 0;
   2438     }
   2439 
   2440     return opt_crlform == FORMAT_PEM ? PEM_write_bio_X509_CRL(bio, crl)
   2441                                      : i2d_X509_CRL_bio(bio, crl);
   2442 }
   2443 
   2444 /*
   2445  * If file != NULL writes out a stack of certs to the given file.
   2446  * If certs is NULL, the file is emptied.
   2447  * Frees the certs if present.
   2448  * Depending on options use either PEM or DER format,
   2449  * where DER does not make much sense for writing more than one cert!
   2450  * Returns number of written certificates on success, -1 on error.
   2451  */
   2452 static int save_free_certs(STACK_OF(X509) *certs,
   2453     const char *file, const char *desc)
   2454 {
   2455     BIO *bio = NULL;
   2456     int i;
   2457     int n = sk_X509_num(certs /* may be NULL */);
   2458 
   2459     if (n < 0)
   2460         n = 0;
   2461     if (file == NULL)
   2462         goto end;
   2463     if (certs != NULL)
   2464         CMP_info3("received %d %s certificate(s), saving to file '%s'",
   2465             n, desc, file);
   2466     if (n > 1 && opt_certform != FORMAT_PEM)
   2467         CMP_warn("saving more than one certificate in non-PEM format");
   2468 
   2469     if ((bio = BIO_new(BIO_s_file())) == NULL
   2470         || !BIO_write_filename(bio, (char *)file)) {
   2471         CMP_err3("could not open file '%s' for %s %s certificate(s)",
   2472             file, certs == NULL ? "deleting" : "writing", desc);
   2473         n = -1;
   2474         goto end;
   2475     }
   2476 
   2477     for (i = 0; i < n; i++) {
   2478         if (!write_cert(bio, sk_X509_value(certs, i))) {
   2479             CMP_err2("cannot write %s certificate to file '%s'", desc, file);
   2480             n = -1;
   2481             goto end;
   2482         }
   2483     }
   2484 
   2485 end:
   2486     BIO_free(bio);
   2487     OSSL_STACK_OF_X509_free(certs);
   2488     return n;
   2489 }
   2490 
   2491 static int save_crl(X509_CRL *crl,
   2492     const char *file, const char *desc)
   2493 {
   2494     BIO *bio = NULL;
   2495     int res = 0;
   2496 
   2497     if (file == NULL)
   2498         return 1;
   2499     if (crl != NULL)
   2500         CMP_info2("received %s, saving to file '%s'", desc, file);
   2501 
   2502     if ((bio = BIO_new(BIO_s_file())) == NULL
   2503         || !BIO_write_filename(bio, (char *)file)) {
   2504         CMP_err2("could not open file '%s' for writing %s",
   2505             file, desc);
   2506         goto end;
   2507     }
   2508 
   2509     if (!write_crl(bio, crl)) {
   2510         CMP_err2("cannot write %s to file '%s'", desc, file);
   2511         goto end;
   2512     }
   2513     res = 1;
   2514 
   2515 end:
   2516     BIO_free(bio);
   2517     return res;
   2518 }
   2519 
   2520 static int delete_file(const char *file, const char *desc)
   2521 {
   2522     if (file == NULL)
   2523         return 1;
   2524 
   2525     if (unlink(file) != 0 && errno != ENOENT) {
   2526         CMP_err2("Failed to delete %s, which should be done to indicate there is no %s",
   2527             file, desc);
   2528         return 0;
   2529     }
   2530     return 1;
   2531 }
   2532 
   2533 static int save_cert_or_delete(X509 *cert, const char *file, const char *desc)
   2534 {
   2535     if (file == NULL)
   2536         return 1;
   2537     if (cert == NULL) {
   2538         char desc_cert[80];
   2539 
   2540         BIO_snprintf(desc_cert, sizeof(desc_cert), "%s certificate", desc);
   2541         return delete_file(file, desc_cert);
   2542     } else {
   2543         STACK_OF(X509) *certs = sk_X509_new_null();
   2544 
   2545         if (!X509_add_cert(certs, cert, X509_ADD_FLAG_UP_REF)) {
   2546             sk_X509_free(certs);
   2547             return 0;
   2548         }
   2549         return save_free_certs(certs, file, desc) >= 0;
   2550     }
   2551 }
   2552 
   2553 static int save_crl_or_delete(X509_CRL *crl, const char *file, const char *desc)
   2554 {
   2555     if (file == NULL)
   2556         return 1;
   2557     return (crl == NULL) ? delete_file(file, desc) : save_crl(crl, file, desc);
   2558 }
   2559 
   2560 static int save_template(const char *file, const OSSL_CRMF_CERTTEMPLATE *tmpl)
   2561 {
   2562     BIO *bio = BIO_new_file(file, "wb");
   2563 
   2564     if (bio == NULL) {
   2565         CMP_err1("error saving certTemplate from genp: cannot open file %s",
   2566             file);
   2567         return 0;
   2568     }
   2569     if (!ASN1_i2d_bio_of(OSSL_CRMF_CERTTEMPLATE, i2d_OSSL_CRMF_CERTTEMPLATE,
   2570             bio, tmpl)) {
   2571         CMP_err1("error saving certTemplate from genp: cannot write file %s",
   2572             file);
   2573         BIO_free(bio);
   2574         return 0;
   2575     } else {
   2576         CMP_info1("stored certTemplate from genp to file '%s'", file);
   2577     }
   2578     BIO_free(bio);
   2579     return 1;
   2580 }
   2581 
   2582 static int save_keyspec(const char *file, const OSSL_CMP_ATAVS *keyspec)
   2583 {
   2584     BIO *bio = BIO_new_file(file, "wb");
   2585 
   2586     if (bio == NULL) {
   2587         CMP_err1("error saving keySpec from genp: cannot open file %s", file);
   2588         return 0;
   2589     }
   2590 
   2591     if (!ASN1_i2d_bio_of(OSSL_CMP_ATAVS, i2d_OSSL_CMP_ATAVS, bio, keyspec)) {
   2592         CMP_err1("error saving keySpec from genp: cannot write file %s", file);
   2593         BIO_free(bio);
   2594         return 0;
   2595     } else {
   2596         CMP_info1("stored keySpec from genp to file '%s'", file);
   2597     }
   2598     BIO_free(bio);
   2599     return 1;
   2600 }
   2601 
   2602 static const char *nid_name(int nid)
   2603 {
   2604     const char *name = OBJ_nid2ln(nid);
   2605 
   2606     if (name == NULL)
   2607         name = OBJ_nid2sn(nid);
   2608     if (name == NULL)
   2609         name = "<unknown OID>";
   2610     return name;
   2611 }
   2612 
   2613 static int print_itavs(const STACK_OF(OSSL_CMP_ITAV) *itavs)
   2614 {
   2615     int i, ret = 1;
   2616     int n = sk_OSSL_CMP_ITAV_num(itavs);
   2617 
   2618     if (n <= 0) { /* also in case itavs == NULL */
   2619         CMP_info("genp does not contain any ITAV");
   2620         return ret;
   2621     }
   2622 
   2623     for (i = 1; i <= n; i++) {
   2624         OSSL_CMP_ITAV *itav = sk_OSSL_CMP_ITAV_value(itavs, i - 1);
   2625         ASN1_OBJECT *type = OSSL_CMP_ITAV_get0_type(itav);
   2626         char name[80];
   2627 
   2628         if (itav == NULL) {
   2629             CMP_err1("could not get ITAV #%d from genp", i);
   2630             ret = 0;
   2631             continue;
   2632         }
   2633         if (i2t_ASN1_OBJECT(name, sizeof(name), type) <= 0) {
   2634             CMP_err1("error parsing type of ITAV #%d from genp", i);
   2635             ret = 0;
   2636         } else {
   2637             CMP_info2("ITAV #%d from genp infoType=%s", i, name);
   2638         }
   2639     }
   2640     return ret;
   2641 }
   2642 
   2643 static char opt_item[SECTION_NAME_MAX + 1];
   2644 /* get previous name from a comma or space-separated list of names */
   2645 static const char *prev_item(const char *opt, const char *end)
   2646 {
   2647     const char *beg;
   2648     size_t len;
   2649 
   2650     if (end == opt)
   2651         return NULL;
   2652     beg = end;
   2653     while (beg > opt) {
   2654         --beg;
   2655         if (beg[0] == ',' || isspace(_UC(beg[0]))) {
   2656             ++beg;
   2657             break;
   2658         }
   2659     }
   2660     len = end - beg;
   2661     if (len > SECTION_NAME_MAX) {
   2662         CMP_warn3("using only first %d characters of section name starting with \"%.*s\"",
   2663             SECTION_NAME_MAX, SECTION_NAME_MAX, beg);
   2664         len = SECTION_NAME_MAX;
   2665     }
   2666     memcpy(opt_item, beg, len);
   2667     opt_item[len] = '\0';
   2668     while (beg > opt) {
   2669         --beg;
   2670         if (beg[0] != ',' && !isspace(_UC(beg[0]))) {
   2671             ++beg;
   2672             break;
   2673         }
   2674     }
   2675     return beg;
   2676 }
   2677 
   2678 /* get str value for name from a comma-separated hierarchy of config sections */
   2679 static char *conf_get_string(const CONF *src_conf, const char *groups,
   2680     const char *name)
   2681 {
   2682     char *res = NULL;
   2683     const char *end = groups + strlen(groups);
   2684 
   2685     while ((end = prev_item(groups, end)) != NULL) {
   2686         if ((res = app_conf_try_string(src_conf, opt_item, name)) != NULL)
   2687             return res;
   2688     }
   2689     return res;
   2690 }
   2691 
   2692 /* get long val for name from a comma-separated hierarchy of config sections */
   2693 static int conf_get_number_e(const CONF *conf_, const char *groups,
   2694     const char *name, long *result)
   2695 {
   2696     char *str = conf_get_string(conf_, groups, name);
   2697     char *tailptr;
   2698     long res;
   2699 
   2700     if (str == NULL || *str == '\0')
   2701         return 0;
   2702 
   2703     res = strtol(str, &tailptr, 10);
   2704     if (res == LONG_MIN || res == LONG_MAX || *tailptr != '\0')
   2705         return 0;
   2706 
   2707     *result = res;
   2708     return 1;
   2709 }
   2710 
   2711 /*
   2712  * use the command line option table to read values from the CMP section
   2713  * of openssl.cnf.  Defaults are taken from the config file, they can be
   2714  * overwritten on the command line.
   2715  */
   2716 static int read_config(void)
   2717 {
   2718     unsigned int i;
   2719     long num = 0;
   2720     char *txt = NULL;
   2721     const OPTIONS *opt;
   2722     int start_opt = OPT_VERBOSITY - OPT_HELP;
   2723     int start_idx = OPT_VERBOSITY - 2;
   2724     /*
   2725      * starting with offset OPT_VERBOSITY because OPT_CONFIG and OPT_SECTION
   2726      * would not make sense within the config file.
   2727      */
   2728     int n_options = OSSL_NELEM(cmp_options) - 1;
   2729 
   2730     for (opt = &cmp_options[start_opt], i = start_idx;
   2731         opt->name != NULL; i++, opt++)
   2732         if (!strcmp(opt->name, OPT_SECTION_STR)
   2733             || !strcmp(opt->name, OPT_MORE_STR))
   2734             n_options--;
   2735     OPENSSL_assert(OSSL_NELEM(cmp_vars) == n_options + OPT_PROV__FIRST + 1 - OPT_PROV__LAST + OPT_R__FIRST + 1 - OPT_R__LAST + OPT_V__FIRST + 1 - OPT_V__LAST);
   2736     for (opt = &cmp_options[start_opt], i = start_idx;
   2737         opt->name != NULL; i++, opt++) {
   2738         int provider_option = (OPT_PROV__FIRST <= opt->retval
   2739             && opt->retval < OPT_PROV__LAST);
   2740         int rand_state_option = (OPT_R__FIRST <= opt->retval
   2741             && opt->retval < OPT_R__LAST);
   2742         int verification_option = (OPT_V__FIRST <= opt->retval
   2743             && opt->retval < OPT_V__LAST);
   2744 
   2745         if (strcmp(opt->name, OPT_SECTION_STR) == 0
   2746             || strcmp(opt->name, OPT_MORE_STR) == 0) {
   2747             i--;
   2748             continue;
   2749         }
   2750         if (provider_option || rand_state_option || verification_option)
   2751             i--;
   2752         switch (opt->valtype) {
   2753         case '-':
   2754         case 'p':
   2755         case 'n':
   2756         case 'N':
   2757         case 'l':
   2758             if (!conf_get_number_e(conf, opt_section, opt->name, &num)) {
   2759                 ERR_clear_error();
   2760                 continue; /* option not provided */
   2761             }
   2762             if (opt->valtype == 'p' && num <= 0) {
   2763                 opt_printf_stderr("Non-positive number \"%ld\" for config option -%s\n",
   2764                     num, opt->name);
   2765                 return -1;
   2766             }
   2767             if (opt->valtype == 'N' && num < 0) {
   2768                 opt_printf_stderr("Negative number \"%ld\" for config option -%s\n",
   2769                     num, opt->name);
   2770                 return -1;
   2771             }
   2772             break;
   2773         case 's':
   2774         case '>':
   2775         case 'M':
   2776             txt = conf_get_string(conf, opt_section, opt->name);
   2777             if (txt == NULL) {
   2778                 ERR_clear_error();
   2779                 continue; /* option not provided */
   2780             }
   2781             break;
   2782         default:
   2783             CMP_err2("internal: unsupported type '%c' for option '%s'",
   2784                 opt->valtype, opt->name);
   2785             return 0;
   2786             break;
   2787         }
   2788         if (provider_option || verification_option) {
   2789             int conf_argc = 1;
   2790             char *conf_argv[3];
   2791             char arg1[82];
   2792 
   2793             BIO_snprintf(arg1, 81, "-%s", (char *)opt->name);
   2794             conf_argv[0] = prog;
   2795             conf_argv[1] = arg1;
   2796             if (opt->valtype == '-') {
   2797                 if (num != 0)
   2798                     conf_argc = 2;
   2799             } else {
   2800                 conf_argc = 3;
   2801                 conf_argv[2] = conf_get_string(conf, opt_section, opt->name);
   2802                 /* not NULL */
   2803             }
   2804             if (conf_argc > 1) {
   2805                 (void)opt_init(conf_argc, conf_argv, cmp_options);
   2806 
   2807                 if (provider_option
   2808                         ? !opt_provider(opt_next())
   2809                         : !opt_verify(opt_next(), vpm)) {
   2810                     CMP_err2("for option '%s' in config file section '%s'",
   2811                         opt->name, opt_section);
   2812                     return 0;
   2813                 }
   2814             }
   2815         } else {
   2816             switch (opt->valtype) {
   2817             case '-':
   2818             case 'p':
   2819             case 'n':
   2820             case 'N':
   2821                 if (num < INT_MIN || INT_MAX < num) {
   2822                     BIO_printf(bio_err,
   2823                         "integer value out of range for option '%s'\n",
   2824                         opt->name);
   2825                     return 0;
   2826                 }
   2827                 *cmp_vars[i].num = (int)num;
   2828                 break;
   2829             case 'l':
   2830                 *cmp_vars[i].num_long = num;
   2831                 break;
   2832             default:
   2833                 if (txt != NULL && txt[0] == '\0')
   2834                     txt = NULL; /* reset option on empty string input */
   2835                 *cmp_vars[i].txt = txt;
   2836                 break;
   2837             }
   2838         }
   2839     }
   2840 
   2841     return 1;
   2842 }
   2843 
   2844 static char *opt_str(void)
   2845 {
   2846     char *arg = opt_arg();
   2847 
   2848     if (arg[0] == '\0') {
   2849         CMP_warn1("%s option argument is empty string, resetting option",
   2850             opt_flag());
   2851         arg = NULL;
   2852     } else if (arg[0] == '-') {
   2853         CMP_warn1("%s option argument starts with hyphen", opt_flag());
   2854     }
   2855     return arg;
   2856 }
   2857 
   2858 /* returns 1 on success, 0 on error, -1 on -help (i.e., stop with success) */
   2859 static int get_opts(int argc, char **argv)
   2860 {
   2861     OPTION_CHOICE o;
   2862 
   2863     prog = opt_init(argc, argv, cmp_options);
   2864 
   2865     while ((o = opt_next()) != OPT_EOF) {
   2866         switch (o) {
   2867         case OPT_EOF:
   2868         case OPT_ERR:
   2869         opthelp:
   2870             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
   2871             return 0;
   2872         case OPT_HELP:
   2873             opt_help(cmp_options);
   2874             return -1;
   2875         case OPT_CONFIG: /* has already been handled */
   2876         case OPT_SECTION: /* has already been handled */
   2877             break;
   2878         case OPT_VERBOSITY:
   2879             if (!set_verbosity(opt_int_arg()))
   2880                 goto opthelp;
   2881             break;
   2882 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   2883         case OPT_SERVER:
   2884             opt_server = opt_str();
   2885             break;
   2886         case OPT_PROXY:
   2887             opt_proxy = opt_str();
   2888             break;
   2889         case OPT_NO_PROXY:
   2890             opt_no_proxy = opt_str();
   2891             break;
   2892 #endif
   2893         case OPT_RECIPIENT:
   2894             opt_recipient = opt_str();
   2895             break;
   2896         case OPT_PATH:
   2897             opt_path = opt_str();
   2898             break;
   2899         case OPT_KEEP_ALIVE:
   2900             opt_keep_alive = opt_int_arg();
   2901             if (opt_keep_alive > 2) {
   2902                 CMP_err("-keep_alive argument must be 0, 1, or 2");
   2903                 goto opthelp;
   2904             }
   2905             break;
   2906         case OPT_MSG_TIMEOUT:
   2907             opt_msg_timeout = opt_int_arg();
   2908             break;
   2909         case OPT_TOTAL_TIMEOUT:
   2910             opt_total_timeout = opt_int_arg();
   2911             break;
   2912 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   2913         case OPT_TLS_USED:
   2914             opt_tls_used = 1;
   2915             break;
   2916         case OPT_TLS_CERT:
   2917             opt_tls_cert = opt_str();
   2918             break;
   2919         case OPT_TLS_KEY:
   2920             opt_tls_key = opt_str();
   2921             break;
   2922         case OPT_TLS_KEYPASS:
   2923             opt_tls_keypass = opt_str();
   2924             break;
   2925         case OPT_TLS_EXTRA:
   2926             opt_tls_extra = opt_str();
   2927             break;
   2928         case OPT_TLS_TRUSTED:
   2929             opt_tls_trusted = opt_str();
   2930             break;
   2931         case OPT_TLS_HOST:
   2932             opt_tls_host = opt_str();
   2933             break;
   2934 #endif
   2935 
   2936         case OPT_REF:
   2937             opt_ref = opt_str();
   2938             break;
   2939         case OPT_SECRET:
   2940             opt_secret = opt_str();
   2941             break;
   2942         case OPT_CERT:
   2943             opt_cert = opt_str();
   2944             break;
   2945         case OPT_OWN_TRUSTED:
   2946             opt_own_trusted = opt_str();
   2947             break;
   2948         case OPT_KEY:
   2949             opt_key = opt_str();
   2950             break;
   2951         case OPT_KEYPASS:
   2952             opt_keypass = opt_str();
   2953             break;
   2954         case OPT_DIGEST:
   2955             opt_digest = opt_str();
   2956             break;
   2957         case OPT_MAC:
   2958             opt_mac = opt_str();
   2959             break;
   2960         case OPT_EXTRACERTS:
   2961             opt_extracerts = opt_str();
   2962             break;
   2963         case OPT_UNPROTECTED_REQUESTS:
   2964             opt_unprotected_requests = 1;
   2965             break;
   2966 
   2967         case OPT_TRUSTED:
   2968             opt_trusted = opt_str();
   2969             break;
   2970         case OPT_UNTRUSTED:
   2971             opt_untrusted = opt_str();
   2972             break;
   2973         case OPT_SRVCERT:
   2974             opt_srvcert = opt_str();
   2975             break;
   2976         case OPT_EXPECT_SENDER:
   2977             opt_expect_sender = opt_str();
   2978             break;
   2979         case OPT_IGNORE_KEYUSAGE:
   2980             opt_ignore_keyusage = 1;
   2981             break;
   2982         case OPT_UNPROTECTED_ERRORS:
   2983             opt_unprotected_errors = 1;
   2984             break;
   2985         case OPT_NO_CACHE_EXTRACERTS:
   2986             opt_no_cache_extracerts = 1;
   2987             break;
   2988         case OPT_SRVCERTOUT:
   2989             opt_srvcertout = opt_str();
   2990             break;
   2991         case OPT_EXTRACERTSOUT:
   2992             opt_extracertsout = opt_str();
   2993             break;
   2994         case OPT_CACERTSOUT:
   2995             opt_cacertsout = opt_str();
   2996             break;
   2997         case OPT_OLDWITHOLD:
   2998             opt_oldwithold = opt_str();
   2999             break;
   3000         case OPT_NEWWITHNEW:
   3001             opt_newwithnew = opt_str();
   3002             break;
   3003         case OPT_NEWWITHOLD:
   3004             opt_newwithold = opt_str();
   3005             break;
   3006         case OPT_OLDWITHNEW:
   3007             opt_oldwithnew = opt_str();
   3008             break;
   3009         case OPT_CRLCERT:
   3010             opt_crlcert = opt_str();
   3011             break;
   3012         case OPT_OLDCRL:
   3013             opt_oldcrl = opt_str();
   3014             break;
   3015         case OPT_CRLOUT:
   3016             opt_crlout = opt_str();
   3017             break;
   3018 
   3019         case OPT_V_CASES:
   3020             if (!opt_verify(o, vpm))
   3021                 goto opthelp;
   3022             break;
   3023         case OPT_CMD:
   3024             opt_cmd_s = opt_str();
   3025             break;
   3026         case OPT_INFOTYPE:
   3027             opt_infotype_s = opt_str();
   3028             break;
   3029         case OPT_PROFILE:
   3030             opt_profile = opt_str();
   3031             break;
   3032         case OPT_GENINFO:
   3033             opt_geninfo = opt_str();
   3034             break;
   3035         case OPT_TEMPLATE:
   3036             opt_template = opt_str();
   3037             break;
   3038         case OPT_KEYSPEC:
   3039             opt_keyspec = opt_str();
   3040             break;
   3041         case OPT_NEWKEY:
   3042             opt_newkey = opt_str();
   3043             break;
   3044         case OPT_NEWKEYPASS:
   3045             opt_newkeypass = opt_str();
   3046             break;
   3047         case OPT_CENTRALKEYGEN:
   3048             opt_centralkeygen = 1;
   3049             break;
   3050         case OPT_NEWKEYOUT:
   3051             opt_newkeyout = opt_str();
   3052             break;
   3053         case OPT_SUBJECT:
   3054             opt_subject = opt_str();
   3055             break;
   3056         case OPT_DAYS:
   3057             opt_days = opt_int_arg();
   3058             break;
   3059         case OPT_REQEXTS:
   3060             opt_reqexts = opt_str();
   3061             break;
   3062         case OPT_SANS:
   3063             opt_sans = opt_str();
   3064             break;
   3065         case OPT_SAN_NODEFAULT:
   3066             opt_san_nodefault = 1;
   3067             break;
   3068         case OPT_POLICIES:
   3069             opt_policies = opt_str();
   3070             break;
   3071         case OPT_POLICY_OIDS:
   3072             opt_policy_oids = opt_str();
   3073             break;
   3074         case OPT_POLICY_OIDS_CRITICAL:
   3075             opt_policy_oids_critical = 1;
   3076             break;
   3077         case OPT_POPO:
   3078             opt_popo = opt_int_arg();
   3079             if (opt_popo < OSSL_CRMF_POPO_NONE
   3080                 || opt_popo > OSSL_CRMF_POPO_KEYENC) {
   3081                 CMP_err("invalid popo spec. Valid values are -1 .. 2");
   3082                 goto opthelp;
   3083             }
   3084             break;
   3085         case OPT_CSR:
   3086             opt_csr = opt_str();
   3087             break;
   3088         case OPT_OUT_TRUSTED:
   3089             opt_out_trusted = opt_str();
   3090             break;
   3091         case OPT_IMPLICIT_CONFIRM:
   3092             opt_implicit_confirm = 1;
   3093             break;
   3094         case OPT_DISABLE_CONFIRM:
   3095             opt_disable_confirm = 1;
   3096             break;
   3097         case OPT_CERTOUT:
   3098             opt_certout = opt_str();
   3099             break;
   3100         case OPT_CHAINOUT:
   3101             opt_chainout = opt_str();
   3102             break;
   3103         case OPT_OLDCERT:
   3104             opt_oldcert = opt_str();
   3105             break;
   3106         case OPT_REVREASON:
   3107             opt_revreason = opt_int_arg();
   3108             if (opt_revreason < CRL_REASON_NONE
   3109                 || opt_revreason > CRL_REASON_AA_COMPROMISE
   3110                 || opt_revreason == 7) {
   3111                 CMP_err("invalid revreason. Valid values are -1 .. 6, 8 .. 10");
   3112                 goto opthelp;
   3113             }
   3114             break;
   3115         case OPT_ISSUER:
   3116             opt_issuer = opt_str();
   3117             break;
   3118         case OPT_SERIAL:
   3119             opt_serial = opt_str();
   3120             break;
   3121         case OPT_CERTFORM:
   3122             opt_certform_s = opt_str();
   3123             break;
   3124         case OPT_CRLFORM:
   3125             opt_crlform_s = opt_str();
   3126             break;
   3127         case OPT_KEYFORM:
   3128             opt_keyform_s = opt_str();
   3129             break;
   3130         case OPT_OTHERPASS:
   3131             opt_otherpass = opt_str();
   3132             break;
   3133 #ifndef OPENSSL_NO_ENGINE
   3134         case OPT_ENGINE:
   3135             opt_engine = opt_str();
   3136             break;
   3137 #endif
   3138         case OPT_PROV_CASES:
   3139             if (!opt_provider(o))
   3140                 goto opthelp;
   3141             break;
   3142         case OPT_R_CASES:
   3143             if (!opt_rand(o))
   3144                 goto opthelp;
   3145             break;
   3146 
   3147         case OPT_BATCH:
   3148             opt_batch = 1;
   3149             break;
   3150         case OPT_REPEAT:
   3151             opt_repeat = opt_int_arg();
   3152             break;
   3153         case OPT_REQIN:
   3154             opt_reqin = opt_str();
   3155             break;
   3156         case OPT_REQIN_NEW_TID:
   3157             opt_reqin_new_tid = 1;
   3158             break;
   3159         case OPT_REQOUT:
   3160             opt_reqout = opt_str();
   3161             break;
   3162         case OPT_REQOUT_ONLY:
   3163             opt_reqout_only = opt_str();
   3164             break;
   3165         case OPT_RSPIN:
   3166             opt_rspin = opt_str();
   3167             break;
   3168         case OPT_RSPOUT:
   3169             opt_rspout = opt_str();
   3170             break;
   3171         case OPT_USE_MOCK_SRV:
   3172             opt_use_mock_srv = 1;
   3173             break;
   3174 
   3175 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   3176         case OPT_PORT:
   3177             opt_port = opt_str();
   3178             break;
   3179         case OPT_MAX_MSGS:
   3180             opt_max_msgs = opt_int_arg();
   3181             break;
   3182 #endif
   3183         case OPT_SRV_REF:
   3184             opt_srv_ref = opt_str();
   3185             break;
   3186         case OPT_SRV_SECRET:
   3187             opt_srv_secret = opt_str();
   3188             break;
   3189         case OPT_SRV_CERT:
   3190             opt_srv_cert = opt_str();
   3191             break;
   3192         case OPT_SRV_KEY:
   3193             opt_srv_key = opt_str();
   3194             break;
   3195         case OPT_SRV_KEYPASS:
   3196             opt_srv_keypass = opt_str();
   3197             break;
   3198         case OPT_SRV_TRUSTED:
   3199             opt_srv_trusted = opt_str();
   3200             break;
   3201         case OPT_SRV_UNTRUSTED:
   3202             opt_srv_untrusted = opt_str();
   3203             break;
   3204         case OPT_REF_CERT:
   3205             opt_ref_cert = opt_str();
   3206             break;
   3207         case OPT_RSP_CERT:
   3208             opt_rsp_cert = opt_str();
   3209             break;
   3210         case OPT_RSP_KEY:
   3211             opt_rsp_key = opt_str();
   3212             break;
   3213         case OPT_RSP_KEYPASS:
   3214             opt_rsp_keypass = opt_str();
   3215             break;
   3216         case OPT_RSP_CRL:
   3217             opt_rsp_crl = opt_str();
   3218             break;
   3219         case OPT_RSP_EXTRACERTS:
   3220             opt_rsp_extracerts = opt_str();
   3221             break;
   3222         case OPT_RSP_CAPUBS:
   3223             opt_rsp_capubs = opt_str();
   3224             break;
   3225         case OPT_RSP_NEWWITHNEW:
   3226             opt_rsp_newwithnew = opt_str();
   3227             break;
   3228         case OPT_RSP_NEWWITHOLD:
   3229             opt_rsp_newwithold = opt_str();
   3230             break;
   3231         case OPT_RSP_OLDWITHNEW:
   3232             opt_rsp_oldwithnew = opt_str();
   3233             break;
   3234         case OPT_POLL_COUNT:
   3235             opt_poll_count = opt_int_arg();
   3236             break;
   3237         case OPT_CHECK_AFTER:
   3238             opt_check_after = opt_int_arg();
   3239             break;
   3240         case OPT_GRANT_IMPLICITCONF:
   3241             opt_grant_implicitconf = 1;
   3242             break;
   3243         case OPT_PKISTATUS:
   3244             opt_pkistatus = opt_int_arg();
   3245             break;
   3246         case OPT_FAILURE:
   3247             opt_failure = opt_int_arg();
   3248             break;
   3249         case OPT_FAILUREBITS:
   3250             opt_failurebits = opt_int_arg();
   3251             break;
   3252         case OPT_STATUSSTRING:
   3253             opt_statusstring = opt_str();
   3254             break;
   3255         case OPT_SEND_ERROR:
   3256             opt_send_error = 1;
   3257             break;
   3258         case OPT_SEND_UNPROTECTED:
   3259             opt_send_unprotected = 1;
   3260             break;
   3261         case OPT_SEND_UNPROT_ERR:
   3262             opt_send_unprot_err = 1;
   3263             break;
   3264         case OPT_ACCEPT_UNPROTECTED:
   3265             opt_accept_unprotected = 1;
   3266             break;
   3267         case OPT_ACCEPT_UNPROT_ERR:
   3268             opt_accept_unprot_err = 1;
   3269             break;
   3270         case OPT_ACCEPT_RAVERIFIED:
   3271             opt_accept_raverified = 1;
   3272             break;
   3273         }
   3274     }
   3275 
   3276     /* No extra args. */
   3277     if (!opt_check_rest_arg(NULL))
   3278         goto opthelp;
   3279     return 1;
   3280 }
   3281 
   3282 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   3283 static int cmp_server(OSSL_CMP_CTX *srv_cmp_ctx)
   3284 {
   3285     BIO *acbio;
   3286     BIO *cbio = NULL;
   3287     int keep_alive = 0;
   3288     int msgs = 0;
   3289     int retry = 1;
   3290     int ret = 1;
   3291 
   3292     if ((acbio = http_server_init(prog, opt_port, opt_verbosity)) == NULL)
   3293         return 0;
   3294     while (opt_max_msgs <= 0 || msgs < opt_max_msgs) {
   3295         char *path = NULL;
   3296         OSSL_CMP_MSG *req = NULL;
   3297         OSSL_CMP_MSG *resp = NULL;
   3298 
   3299         ret = http_server_get_asn1_req(ASN1_ITEM_rptr(OSSL_CMP_MSG),
   3300             (ASN1_VALUE **)&req, &path,
   3301             &cbio, acbio, &keep_alive,
   3302             prog, 0, 0);
   3303         if (ret == 0) { /* no request yet */
   3304             if (retry) {
   3305                 OSSL_sleep(1000);
   3306                 retry = 0;
   3307                 continue;
   3308             }
   3309             ret = 0;
   3310             goto next;
   3311         }
   3312         if (ret++ == -1) /* fatal error */
   3313             break;
   3314 
   3315         ret = 0;
   3316         msgs++;
   3317         if (req != NULL) {
   3318             if (strcmp(path, "") != 0 && strcmp(path, "pkix/") != 0) {
   3319                 (void)http_server_send_status(prog, cbio, 404, "Not Found");
   3320                 CMP_err1("expecting empty path or 'pkix/' but got '%s'",
   3321                     path);
   3322                 OPENSSL_free(path);
   3323                 OSSL_CMP_MSG_free(req);
   3324                 goto next;
   3325             }
   3326             OPENSSL_free(path);
   3327             resp = OSSL_CMP_CTX_server_perform(cmp_ctx /* of client */, req);
   3328             OSSL_CMP_MSG_free(req);
   3329             if (resp == NULL) {
   3330                 (void)http_server_send_status(prog, cbio,
   3331                     500, "Internal Server Error");
   3332                 break; /* treated as fatal error */
   3333             }
   3334             ret = http_server_send_asn1_resp(prog, cbio, keep_alive,
   3335                 "application/pkixcmp",
   3336                 ASN1_ITEM_rptr(OSSL_CMP_MSG),
   3337                 (const ASN1_VALUE *)resp);
   3338             OSSL_CMP_MSG_free(resp);
   3339             if (!ret)
   3340                 break; /* treated as fatal error */
   3341         }
   3342     next:
   3343         if (!ret) { /* on transmission error, cancel CMP transaction */
   3344             (void)OSSL_CMP_CTX_set1_transactionID(srv_cmp_ctx, NULL);
   3345             (void)OSSL_CMP_CTX_set1_senderNonce(srv_cmp_ctx, NULL);
   3346         }
   3347         if (!ret || !keep_alive
   3348             || OSSL_CMP_CTX_get_status(srv_cmp_ctx) != OSSL_CMP_PKISTATUS_trans
   3349             /* transaction closed by OSSL_CMP_CTX_server_perform() */) {
   3350             BIO_free_all(cbio);
   3351             cbio = NULL;
   3352         }
   3353     }
   3354 
   3355     BIO_free_all(cbio);
   3356     BIO_free_all(acbio);
   3357     return ret;
   3358 }
   3359 #endif
   3360 
   3361 static void print_keyspec(OSSL_CMP_ATAVS *keySpec)
   3362 {
   3363     const char *desc = "specifications contained in keySpec from genp";
   3364     BIO *mem;
   3365     int i;
   3366     const char *p;
   3367     long len;
   3368 
   3369     if (keySpec == NULL) {
   3370         CMP_info1("No %s", desc);
   3371         return;
   3372     }
   3373 
   3374     mem = BIO_new(BIO_s_mem());
   3375     if (mem == NULL) {
   3376         CMP_err1("Out of memory - cannot dump key %s", desc);
   3377         return;
   3378     }
   3379     BIO_printf(mem, "Key %s:\n", desc);
   3380 
   3381     for (i = 0; i < sk_OSSL_CMP_ATAV_num(keySpec); i++) {
   3382         OSSL_CMP_ATAV *atav = sk_OSSL_CMP_ATAV_value(keySpec, i);
   3383         ASN1_OBJECT *type = OSSL_CMP_ATAV_get0_type(atav /* may be NULL */);
   3384         int nid = OBJ_obj2nid(type);
   3385 
   3386         switch (nid) {
   3387         case NID_id_regCtrl_algId: {
   3388             X509_ALGOR *alg = OSSL_CMP_ATAV_get0_algId(atav);
   3389             const ASN1_OBJECT *oid;
   3390             int paramtype;
   3391             const void *param;
   3392 
   3393             X509_ALGOR_get0(&oid, &paramtype, &param, alg);
   3394             BIO_printf(mem, "Key algorithm: ");
   3395             i2a_ASN1_OBJECT(mem, oid);
   3396             if (paramtype == V_ASN1_UNDEF || alg->parameter == NULL) {
   3397                 BIO_printf(mem, "\n");
   3398             } else {
   3399                 BIO_printf(mem, " - ");
   3400                 ASN1_item_print(mem, (ASN1_VALUE *)alg,
   3401                     0, ASN1_ITEM_rptr(X509_ALGOR), NULL);
   3402             }
   3403         } break;
   3404         case NID_id_regCtrl_rsaKeyLen:
   3405             BIO_printf(mem, "Key algorithm: RSA %d\n",
   3406                 OSSL_CMP_ATAV_get_rsaKeyLen(atav));
   3407             break;
   3408         default:
   3409             BIO_printf(mem, "Invalid key spec: %s\n", nid_name(nid));
   3410             break;
   3411         }
   3412     }
   3413     BIO_printf(mem, "End of key %s", desc);
   3414 
   3415     len = BIO_get_mem_data(mem, &p);
   3416     if (len > INT_MAX)
   3417         CMP_err1("Info too large - cannot dump key %s", desc);
   3418     else
   3419         CMP_info2("%.*s", (int)len, p);
   3420     BIO_free(mem);
   3421     return;
   3422 }
   3423 
   3424 static void print_status(void)
   3425 {
   3426     /* print PKIStatusInfo */
   3427     int status = OSSL_CMP_CTX_get_status(cmp_ctx);
   3428     char *buf = app_malloc(OSSL_CMP_PKISI_BUFLEN, "PKIStatusInfo buf");
   3429     const char *string = OSSL_CMP_CTX_snprint_PKIStatus(cmp_ctx, buf, OSSL_CMP_PKISI_BUFLEN);
   3430     const char *from = "", *server = "";
   3431 
   3432 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   3433     if (opt_server != NULL) {
   3434         from = " from ";
   3435         server = opt_server;
   3436     }
   3437 #endif
   3438     CMP_print(bio_err,
   3439         status == OSSL_CMP_PKISTATUS_accepted
   3440             ? OSSL_CMP_LOG_INFO
   3441             : status == OSSL_CMP_PKISTATUS_rejection
   3442                 || status == OSSL_CMP_PKISTATUS_waiting
   3443             ? OSSL_CMP_LOG_ERR
   3444             : OSSL_CMP_LOG_WARNING,
   3445         status == OSSL_CMP_PKISTATUS_accepted ? "info" : status == OSSL_CMP_PKISTATUS_rejection ? "server error"
   3446             : status == OSSL_CMP_PKISTATUS_waiting                                              ? "internal error"
   3447                                                                                                 : "warning",
   3448         "received%s%s %s", from, server,
   3449         string != NULL ? string : "<unknown PKIStatus>");
   3450     OPENSSL_free(buf);
   3451 }
   3452 
   3453 static int do_genm(OSSL_CMP_CTX *ctx)
   3454 {
   3455     if (opt_infotype == NID_id_it_caCerts) {
   3456         STACK_OF(X509) *cacerts = NULL;
   3457 
   3458         if (opt_cacertsout == NULL) {
   3459             CMP_err("Missing -cacertsout option for -infotype caCerts");
   3460             return 0;
   3461         }
   3462 
   3463         if (!OSSL_CMP_get1_caCerts(ctx, &cacerts))
   3464             return 0;
   3465 
   3466         /* could check authorization of sender/origin at this point */
   3467         if (cacerts == NULL) {
   3468             CMP_warn("no CA certificates provided by server");
   3469         } else if (save_free_certs(cacerts, opt_cacertsout, "CA") < 0) {
   3470             CMP_err1("Failed to store CA certificates from genp in %s",
   3471                 opt_cacertsout);
   3472             return 0;
   3473         }
   3474         return 1;
   3475     } else if (opt_infotype == NID_id_it_rootCaCert) {
   3476         X509 *oldwithold = NULL;
   3477         X509 *newwithnew = NULL;
   3478         X509 *newwithold = NULL;
   3479         X509 *oldwithnew = NULL;
   3480         int res = 0;
   3481 
   3482         if (opt_newwithnew == NULL) {
   3483             CMP_err("Missing -newwithnew option for -infotype rootCaCert");
   3484             return 0;
   3485         }
   3486         if (opt_oldwithold == NULL) {
   3487             CMP_warn("No -oldwithold given, will use all certs given with -trusted as trust anchors for verifying the newWithNew cert");
   3488         } else {
   3489             oldwithold = load_cert_pwd(opt_oldwithold, opt_otherpass,
   3490                 "OldWithOld cert for genm with -infotype rootCaCert");
   3491             if (oldwithold == NULL)
   3492                 goto end_upd;
   3493         }
   3494         if (!OSSL_CMP_get1_rootCaKeyUpdate(ctx, oldwithold, &newwithnew,
   3495                 &newwithold, &oldwithnew))
   3496             goto end_upd;
   3497         /* At this point might check authorization of response sender/origin */
   3498 
   3499         if (newwithnew == NULL)
   3500             CMP_info("no root CA certificate update available");
   3501         else if (oldwithold == NULL && oldwithnew != NULL)
   3502             CMP_warn("oldWithNew certificate received in genp for verifying oldWithOld, but oldWithOld was not provided");
   3503 
   3504         if (save_cert_or_delete(newwithnew, opt_newwithnew,
   3505                 "NewWithNew cert from genp")
   3506             && save_cert_or_delete(newwithold, opt_newwithold,
   3507                 "NewWithOld cert from genp")
   3508             && save_cert_or_delete(oldwithnew, opt_oldwithnew,
   3509                 "OldWithNew cert from genp"))
   3510             res = 1;
   3511 
   3512         X509_free(newwithnew);
   3513         X509_free(newwithold);
   3514         X509_free(oldwithnew);
   3515     end_upd:
   3516         X509_free(oldwithold);
   3517         return res;
   3518     } else if (opt_infotype == NID_id_it_crlStatusList) {
   3519         X509_CRL *oldcrl = NULL, *crl = NULL;
   3520         X509 *crlcert = NULL;
   3521         int res = 0;
   3522         const char *desc = "CRL from genp of type 'crls'";
   3523 
   3524         if (opt_oldcrl == NULL && opt_crlcert == NULL) {
   3525             CMP_err("Missing -oldcrl and no -crlcert given for -infotype crlStatusList");
   3526             return 0;
   3527         }
   3528         if (opt_crlout == NULL) {
   3529             CMP_err("Missing -crlout for -infotype crlStatusList");
   3530             return 0;
   3531         }
   3532 
   3533         if (opt_crlcert != NULL) {
   3534             crlcert = load_cert_pwd(opt_crlcert, opt_otherpass,
   3535                 "Cert for genm with -infotype crlStatusList");
   3536             if (crlcert == NULL)
   3537                 goto end_crlupd;
   3538         }
   3539 
   3540         if (opt_oldcrl != NULL) {
   3541             oldcrl = load_crl(opt_oldcrl, FORMAT_UNDEF, 0,
   3542                 "CRL for genm with -infotype crlStatusList");
   3543             if (oldcrl == NULL)
   3544                 goto end_crlupd;
   3545         }
   3546 
   3547         if (opt_oldcrl != NULL && opt_crlcert != NULL) {
   3548             if (X509_NAME_cmp(X509_CRL_get_issuer(oldcrl),
   3549                     X509_get_issuer_name(crlcert))
   3550                 != 0)
   3551                 CMP_warn("-oldcrl and -crlcert have different issuer");
   3552         }
   3553 
   3554         if (!OSSL_CMP_get1_crlUpdate(ctx, crlcert, oldcrl, &crl))
   3555             goto end_crlupd;
   3556 
   3557         if (crl == NULL)
   3558             CMP_info("no CRL update available");
   3559         if (!save_crl_or_delete(crl, opt_crlout, desc))
   3560             goto end_crlupd;
   3561 
   3562         res = 1;
   3563 
   3564     end_crlupd:
   3565         X509_free(crlcert);
   3566         X509_CRL_free(oldcrl);
   3567         X509_CRL_free(crl);
   3568         return res;
   3569 
   3570     } else if (opt_infotype == NID_id_it_certReqTemplate) {
   3571         OSSL_CRMF_CERTTEMPLATE *certTemplate;
   3572         OSSL_CMP_ATAVS *keySpec;
   3573         int res = 0;
   3574 
   3575         if (!OSSL_CMP_get1_certReqTemplate(ctx, &certTemplate, &keySpec))
   3576             return 0;
   3577 
   3578         if (certTemplate == NULL) {
   3579             CMP_warn("no certificate request template available");
   3580             if (!delete_file(opt_template, "certTemplate from genp"))
   3581                 return 0;
   3582             if (opt_keyspec != NULL
   3583                 && !delete_file(opt_keyspec, "keySpec from genp"))
   3584                 return 0;
   3585             return 1;
   3586         }
   3587         if (!save_template(opt_template, certTemplate))
   3588             goto tmpl_end;
   3589 
   3590         print_keyspec(keySpec);
   3591         if (opt_keyspec != NULL) {
   3592             if (keySpec == NULL) {
   3593                 CMP_warn("no key specifications available");
   3594                 if (!delete_file(opt_keyspec, "keySpec from genp"))
   3595                     goto tmpl_end;
   3596             } else if (!save_keyspec(opt_keyspec, keySpec)) {
   3597                 goto tmpl_end;
   3598             }
   3599         }
   3600 
   3601         res = 1;
   3602     tmpl_end:
   3603         OSSL_CRMF_CERTTEMPLATE_free(certTemplate);
   3604         sk_OSSL_CMP_ATAV_pop_free(keySpec, OSSL_CMP_ATAV_free);
   3605         return res;
   3606     } else {
   3607         OSSL_CMP_ITAV *req;
   3608         STACK_OF(OSSL_CMP_ITAV) *itavs;
   3609 
   3610         if (opt_infotype != NID_undef) {
   3611             CMP_warn1("No specific support for -infotype %s available",
   3612                 opt_infotype_s);
   3613 
   3614             req = OSSL_CMP_ITAV_create(OBJ_nid2obj(opt_infotype), NULL);
   3615             if (req == NULL || !OSSL_CMP_CTX_push0_genm_ITAV(ctx, req)) {
   3616                 CMP_err1("Failed to create genm for -infotype %s",
   3617                     opt_infotype_s);
   3618                 return 0;
   3619             }
   3620         }
   3621 
   3622         if ((itavs = OSSL_CMP_exec_GENM_ses(ctx)) != NULL) {
   3623             int res = print_itavs(itavs);
   3624 
   3625             sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free);
   3626             return res;
   3627         }
   3628         if (OSSL_CMP_CTX_get_status(ctx) != OSSL_CMP_PKISTATUS_request)
   3629             CMP_err("Did not receive response on genm or genp is not valid");
   3630         return 0;
   3631     }
   3632 }
   3633 
   3634 static int handle_opts_upfront(int argc, char **argv)
   3635 {
   3636     int i;
   3637 
   3638     prog = opt_appname(argv[0]);
   3639     if (argc <= 1) {
   3640         opt_help(cmp_options);
   3641         return 0;
   3642     }
   3643 
   3644     /* handle -config, -section, and -verbosity to take effect for other opts */
   3645     for (i = 1; i < argc - 1; i++) {
   3646         if (*argv[i] == '-') {
   3647             if (!strcmp(argv[i] + 1, cmp_options[OPT_CONFIG - OPT_HELP].name))
   3648                 opt_config = argv[++i];
   3649             else if (!strcmp(argv[i] + 1,
   3650                          cmp_options[OPT_SECTION - OPT_HELP].name))
   3651                 opt_section = argv[++i];
   3652             else if (strcmp(argv[i] + 1,
   3653                          cmp_options[OPT_VERBOSITY - OPT_HELP].name)
   3654                     == 0
   3655                 && !set_verbosity(atoi(argv[++i])))
   3656                 return 0;
   3657         }
   3658     }
   3659     if (opt_section[0] == '\0') /* empty string */
   3660         opt_section = DEFAULT_SECTION;
   3661     return 1;
   3662 }
   3663 
   3664 int cmp_main(int argc, char **argv)
   3665 {
   3666     char *configfile = NULL;
   3667     int i;
   3668     X509 *newcert = NULL;
   3669     ENGINE *engine = NULL;
   3670     int ret = 0; /* default: failure */
   3671 
   3672     if (!handle_opts_upfront(argc, argv))
   3673         goto err;
   3674 
   3675     vpm = X509_VERIFY_PARAM_new();
   3676     if (vpm == NULL) {
   3677         CMP_err("out of memory");
   3678         goto err;
   3679     }
   3680 
   3681     /* read default values for options from config file */
   3682     configfile = opt_config != NULL ? opt_config : default_config_file;
   3683     if (configfile != NULL && configfile[0] != '\0' /* non-empty string */
   3684         && (configfile != default_config_file
   3685             || access(configfile, F_OK) != -1)) {
   3686         CMP_info2("using section(s) '%s' of OpenSSL configuration file '%s'",
   3687             opt_section, configfile);
   3688         conf = app_load_config(configfile);
   3689         if (conf == NULL) {
   3690             goto err;
   3691         } else {
   3692             if (strcmp(opt_section, CMP_SECTION) == 0) { /* default */
   3693                 if (!NCONF_get_section(conf, opt_section))
   3694                     CMP_info2("no [%s] section found in config file '%s';"
   3695                               " will thus use just [default] and unnamed section if present",
   3696                         opt_section, configfile);
   3697             } else {
   3698                 const char *end = opt_section + strlen(opt_section);
   3699 
   3700                 while ((end = prev_item(opt_section, end)) != NULL) {
   3701                     if (!NCONF_get_section(conf, opt_item)) {
   3702                         CMP_err2("no [%s] section found in config file '%s'",
   3703                             opt_item, configfile);
   3704                         goto err;
   3705                     }
   3706                 }
   3707             }
   3708             ret = read_config();
   3709             if (!set_verbosity(opt_verbosity)) /* just for checking range */
   3710                 ret = -1;
   3711             if (ret <= 0) {
   3712                 if (ret == -1)
   3713                     BIO_printf(bio_err, "Use -help for summary.\n");
   3714                 goto err;
   3715             }
   3716         }
   3717     }
   3718     (void)BIO_flush(bio_err); /* prevent interference with opt_help() */
   3719 
   3720     cmp_ctx = OSSL_CMP_CTX_new(app_get0_libctx(), app_get0_propq());
   3721     if (cmp_ctx == NULL)
   3722         goto err;
   3723 
   3724     ret = get_opts(argc, argv);
   3725     if (ret <= 0)
   3726         goto err;
   3727 
   3728     ret = 0;
   3729     if (!app_RAND_load())
   3730         goto err;
   3731 
   3732     if (opt_batch)
   3733         set_base_ui_method(UI_null());
   3734 
   3735     if (opt_engine != NULL) {
   3736         engine = setup_engine_methods(opt_engine,
   3737             0 /* not: ENGINE_METHOD_ALL */, 0);
   3738         if (engine == NULL) {
   3739             CMP_err1("cannot load engine %s", opt_engine);
   3740             goto err;
   3741         }
   3742     }
   3743 
   3744     OSSL_CMP_CTX_set_log_verbosity(cmp_ctx, opt_verbosity);
   3745     if (!OSSL_CMP_CTX_set_log_cb(cmp_ctx, print_to_bio_out)) {
   3746         CMP_err1("cannot set up error reporting and logging for %s", prog);
   3747         goto err;
   3748     }
   3749 
   3750 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   3751     if (opt_tls_cert == NULL && opt_tls_key == NULL && opt_tls_keypass == NULL
   3752         && opt_tls_extra == NULL && opt_tls_trusted == NULL
   3753         && opt_tls_host == NULL) {
   3754         if (opt_tls_used)
   3755             CMP_warn("-tls_used given without any other TLS options");
   3756     } else if (!opt_tls_used) {
   3757         CMP_warn("ignoring TLS options(s) since -tls_used is not given");
   3758     }
   3759     if (opt_port != NULL) {
   3760         if (opt_tls_used) {
   3761             CMP_err("-tls_used option not supported with -port option");
   3762             goto err;
   3763         }
   3764         if (opt_server != NULL || opt_use_mock_srv) {
   3765             CMP_err("The -port option excludes -server and -use_mock_srv");
   3766             goto err;
   3767         }
   3768         if (opt_reqin != NULL || opt_reqout != NULL) {
   3769             CMP_err("The -port option does not support -reqin and -reqout");
   3770             goto err;
   3771         }
   3772         if (opt_rspin != NULL || opt_rspout != NULL) {
   3773             CMP_err("The -port option does not support -rspin and -rspout");
   3774             goto err;
   3775         }
   3776     }
   3777 
   3778     if (opt_server != NULL && opt_use_mock_srv) {
   3779         CMP_err("cannot use both -server and -use_mock_srv options");
   3780         goto err;
   3781     }
   3782     if ((opt_server == NULL || opt_use_mock_srv) && opt_tls_used) {
   3783         CMP_warn("ignoring -tls_used option since -server is not given or -use_mock_srv is given");
   3784         opt_tls_used = 0;
   3785     }
   3786 
   3787 #endif
   3788 
   3789     if (opt_ignore_keyusage)
   3790         (void)OSSL_CMP_CTX_set_option(cmp_ctx, OSSL_CMP_OPT_IGNORE_KEYUSAGE, 1);
   3791     if (opt_no_cache_extracerts)
   3792         (void)OSSL_CMP_CTX_set_option(cmp_ctx, OSSL_CMP_OPT_NO_CACHE_EXTRACERTS,
   3793             1);
   3794 
   3795     if (opt_reqout_only == NULL && (opt_use_mock_srv
   3796 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   3797             || opt_port != NULL
   3798 #endif
   3799             )) {
   3800         OSSL_CMP_SRV_CTX *srv_ctx;
   3801         OSSL_CMP_CTX *srv_cmp_ctx;
   3802 
   3803         if ((srv_ctx = setup_srv_ctx(engine)) == NULL)
   3804             goto err;
   3805         OSSL_CMP_CTX_set_transfer_cb_arg(cmp_ctx /* of client */, srv_ctx);
   3806 
   3807         srv_cmp_ctx = OSSL_CMP_SRV_CTX_get0_cmp_ctx(srv_ctx);
   3808         if (!OSSL_CMP_CTX_set_log_cb(srv_cmp_ctx, print_to_bio_err)) {
   3809             CMP_err1("cannot set up error reporting and logging for %s", prog);
   3810             goto err;
   3811         }
   3812         OSSL_CMP_CTX_set_log_verbosity(srv_cmp_ctx, opt_verbosity);
   3813 
   3814 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   3815         if (opt_port != NULL) { /* act as very basic CMP HTTP server only */
   3816             ret = cmp_server(srv_cmp_ctx);
   3817             goto err;
   3818         }
   3819 #endif
   3820     }
   3821 
   3822     /* act as CMP client, possibly using internal mock server */
   3823 
   3824     if (opt_reqout_only != NULL) {
   3825         const char *msg = "option is ignored since -reqout_only option is given";
   3826 
   3827 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   3828         if (opt_port != NULL) {
   3829             CMP_err("the -reqout_only client option does not combine with -port implying server behavior");
   3830             goto err;
   3831         }
   3832         if (opt_server != NULL)
   3833             CMP_warn1("-server %s", msg);
   3834 #endif
   3835         if (opt_use_mock_srv)
   3836             CMP_warn1("-use_mock_srv %s", msg);
   3837         if (opt_reqout != NULL)
   3838             CMP_warn1("-reqout %s", msg);
   3839         if (opt_rspin != NULL)
   3840             CMP_warn1("-rspin %s", msg);
   3841         if (opt_rspout != NULL)
   3842             CMP_warn1("-rspout %s", msg);
   3843         opt_reqout = opt_reqout_only;
   3844     }
   3845     if (opt_rspin != NULL) {
   3846 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   3847         if (opt_server != NULL)
   3848             CMP_warn("-server option is not used if enough filenames given for -rspin");
   3849 #endif
   3850         if (opt_use_mock_srv)
   3851             CMP_warn("-use_mock_srv option is not used if enough filenames given for -rspin");
   3852     }
   3853 
   3854     if (!setup_client_ctx(cmp_ctx, engine)) {
   3855         CMP_err("cannot set up CMP context");
   3856         goto err;
   3857     }
   3858     for (i = 0; i < opt_repeat; i++) {
   3859         /* everything is ready, now connect and perform the command! */
   3860         switch (opt_cmd) {
   3861         case CMP_IR:
   3862             newcert = OSSL_CMP_exec_IR_ses(cmp_ctx);
   3863             if (newcert != NULL)
   3864                 ret = 1;
   3865             break;
   3866         case CMP_KUR:
   3867             newcert = OSSL_CMP_exec_KUR_ses(cmp_ctx);
   3868             if (newcert != NULL)
   3869                 ret = 1;
   3870             break;
   3871         case CMP_CR:
   3872             newcert = OSSL_CMP_exec_CR_ses(cmp_ctx);
   3873             if (newcert != NULL)
   3874                 ret = 1;
   3875             break;
   3876         case CMP_P10CR:
   3877             newcert = OSSL_CMP_exec_P10CR_ses(cmp_ctx);
   3878             if (newcert != NULL)
   3879                 ret = 1;
   3880             break;
   3881         case CMP_RR:
   3882             ret = OSSL_CMP_exec_RR_ses(cmp_ctx);
   3883             break;
   3884         case CMP_GENM:
   3885             ret = do_genm(cmp_ctx);
   3886         default:
   3887             break;
   3888         }
   3889         if (OSSL_CMP_CTX_get_status(cmp_ctx) < OSSL_CMP_PKISTATUS_accepted) {
   3890             /* we got no response, maybe even did not send request */
   3891             ret = 0;
   3892             if (reqout_only_done) {
   3893                 ERR_clear_error();
   3894                 ret = 1;
   3895             }
   3896             goto err;
   3897         }
   3898         print_status();
   3899         if (!save_cert_or_delete(OSSL_CMP_CTX_get0_validatedSrvCert(cmp_ctx),
   3900                 opt_srvcertout, "validated server"))
   3901             ret = 0;
   3902         if (!ret)
   3903             goto err;
   3904         ret = 0;
   3905         if (save_free_certs(OSSL_CMP_CTX_get1_extraCertsIn(cmp_ctx),
   3906                 opt_extracertsout, "extra")
   3907             < 0)
   3908             goto err;
   3909         if (newcert != NULL && (opt_cmd == CMP_IR || opt_cmd == CMP_CR || opt_cmd == CMP_KUR || opt_cmd == CMP_P10CR)) {
   3910             STACK_OF(X509) *newchain = OSSL_CMP_CTX_get1_newChain(cmp_ctx);
   3911 
   3912             if (newcert != NULL && newchain != NULL /* NULL is on error only */
   3913                 && opt_certout != NULL && opt_chainout != NULL
   3914                 && strcmp(opt_certout, opt_chainout) == 0) {
   3915                 if (!X509_add_cert(newchain, newcert, X509_ADD_FLAG_PREPEND | X509_ADD_FLAG_UP_REF)) {
   3916                     sk_X509_pop_free(newchain, X509_free);
   3917                     goto err;
   3918                 }
   3919                 if (!save_free_certs(newchain, opt_chainout, "newly enrolled cert and chain"))
   3920                     goto err;
   3921             } else {
   3922                 if (save_free_certs(newchain, opt_chainout, "chain") < 0
   3923                     || !save_cert_or_delete(newcert, opt_certout, "newly enrolled"))
   3924                     goto err;
   3925             }
   3926             if (save_free_certs(OSSL_CMP_CTX_get1_caPubs(cmp_ctx),
   3927                     opt_cacertsout, "CA")
   3928                 < 0)
   3929                 goto err;
   3930             if (opt_centralkeygen) {
   3931                 EVP_CIPHER *cipher = NULL;
   3932                 char *pass_string = NULL;
   3933                 BIO *out;
   3934                 int result = 1;
   3935                 EVP_PKEY *new_key = OSSL_CMP_CTX_get0_newPkey(cmp_ctx, 1 /* priv */);
   3936 
   3937                 if (new_key == NULL)
   3938                     goto err;
   3939                 if ((out = bio_open_owner(opt_newkeyout, FORMAT_PEM, 1)) == NULL)
   3940                     goto err;
   3941                 if (opt_newkeypass != NULL) {
   3942                     pass_string = get_passwd(opt_newkeypass,
   3943                         "Centrally generated private key password");
   3944                     cipher = EVP_CIPHER_fetch(app_get0_libctx(), SN_aes_256_cbc, app_get0_propq());
   3945                 }
   3946 
   3947                 CMP_info1("saving centrally generated key to file '%s'", opt_newkeyout);
   3948                 if (PEM_write_bio_PrivateKey(out, new_key, cipher, NULL, 0, NULL,
   3949                         (void *)pass_string)
   3950                     <= 0)
   3951                     result = 0;
   3952 
   3953                 BIO_free(out);
   3954                 clear_free(pass_string);
   3955                 EVP_CIPHER_free(cipher);
   3956                 if (!result)
   3957                     goto err;
   3958             }
   3959         }
   3960         if (!OSSL_CMP_CTX_reinit(cmp_ctx))
   3961             goto err;
   3962     }
   3963     ret = 1;
   3964 
   3965 err:
   3966     /* in case we ended up here on error without proper cleaning */
   3967     cleanse(opt_keypass);
   3968     cleanse(opt_newkeypass);
   3969     cleanse(opt_otherpass);
   3970 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   3971     cleanse(opt_tls_keypass);
   3972 #endif
   3973     cleanse(opt_secret);
   3974     cleanse(opt_srv_keypass);
   3975     cleanse(opt_srv_secret);
   3976 
   3977     if (ret != 1)
   3978         OSSL_CMP_CTX_print_errors(cmp_ctx);
   3979 
   3980     if (cmp_ctx != NULL) {
   3981 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   3982         APP_HTTP_TLS_INFO *info = OSSL_CMP_CTX_get_http_cb_arg(cmp_ctx);
   3983 
   3984         (void)OSSL_CMP_CTX_set_http_cb_arg(cmp_ctx, NULL);
   3985 #endif
   3986         ossl_cmp_mock_srv_free(OSSL_CMP_CTX_get_transfer_cb_arg(cmp_ctx));
   3987         X509_STORE_free(OSSL_CMP_CTX_get_certConf_cb_arg(cmp_ctx));
   3988         /* cannot free info already here, as it may be used indirectly by: */
   3989         OSSL_CMP_CTX_free(cmp_ctx);
   3990 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
   3991         if (info != NULL) {
   3992             OPENSSL_free((char *)info->server);
   3993             OPENSSL_free((char *)info->port);
   3994             APP_HTTP_TLS_INFO_free(info);
   3995         }
   3996 #endif
   3997     }
   3998     X509_VERIFY_PARAM_free(vpm);
   3999     release_engine(engine);
   4000 
   4001     NCONF_free(conf); /* must not do as long as opt_... variables are used */
   4002     OSSL_CMP_log_close();
   4003 
   4004     return ret == 0 ? EXIT_FAILURE : EXIT_SUCCESS; /* ret == -1 for -help */
   4005 }
   4006