Home | History | Annotate | Line # | Download | only in ssl
      1 /*
      2  * Copyright 2012-2025 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 #include "internal/e_os.h"
     11 
     12 #include <stdio.h>
     13 #include "ssl_local.h"
     14 #include <openssl/conf.h>
     15 #include <openssl/objects.h>
     16 #include <openssl/decoder.h>
     17 #include <openssl/core_dispatch.h>
     18 #include "internal/nelem.h"
     19 #include "internal/ssl_unwrap.h"
     20 
     21 /*
     22  * structure holding name tables. This is used for permitted elements in lists
     23  * such as TLSv1.
     24  */
     25 
     26 typedef struct {
     27     const char *name;
     28     int namelen;
     29     unsigned int name_flags;
     30     uint64_t option_value;
     31 } ssl_flag_tbl;
     32 
     33 /* Switch table: use for single command line switches like no_tls2 */
     34 typedef struct {
     35     uint64_t option_value;
     36     unsigned int name_flags;
     37 } ssl_switch_tbl;
     38 
     39 /* Sense of name is inverted e.g. "TLSv1" will clear SSL_OP_NO_TLSv1 */
     40 #define SSL_TFLAG_INV 0x1
     41 /* Mask for type of flag referred to */
     42 #define SSL_TFLAG_TYPE_MASK 0xf00
     43 /* Flag is for options */
     44 #define SSL_TFLAG_OPTION 0x000
     45 /* Flag is for cert_flags */
     46 #define SSL_TFLAG_CERT 0x100
     47 /* Flag is for verify mode */
     48 #define SSL_TFLAG_VFY 0x200
     49 /* Option can only be used for clients */
     50 #define SSL_TFLAG_CLIENT SSL_CONF_FLAG_CLIENT
     51 /* Option can only be used for servers */
     52 #define SSL_TFLAG_SERVER SSL_CONF_FLAG_SERVER
     53 #define SSL_TFLAG_BOTH (SSL_TFLAG_CLIENT | SSL_TFLAG_SERVER)
     54 
     55 #define SSL_FLAG_TBL(str, flag) \
     56     { str, (int)(sizeof(str) - 1), SSL_TFLAG_BOTH, flag }
     57 #define SSL_FLAG_TBL_SRV(str, flag) \
     58     { str, (int)(sizeof(str) - 1), SSL_TFLAG_SERVER, flag }
     59 #define SSL_FLAG_TBL_CLI(str, flag) \
     60     { str, (int)(sizeof(str) - 1), SSL_TFLAG_CLIENT, flag }
     61 #define SSL_FLAG_TBL_INV(str, flag) \
     62     { str, (int)(sizeof(str) - 1), SSL_TFLAG_INV | SSL_TFLAG_BOTH, flag }
     63 #define SSL_FLAG_TBL_SRV_INV(str, flag) \
     64     { str, (int)(sizeof(str) - 1), SSL_TFLAG_INV | SSL_TFLAG_SERVER, flag }
     65 #define SSL_FLAG_TBL_CERT(str, flag) \
     66     { str, (int)(sizeof(str) - 1), SSL_TFLAG_CERT | SSL_TFLAG_BOTH, flag }
     67 
     68 #define SSL_FLAG_VFY_CLI(str, flag) \
     69     { str, (int)(sizeof(str) - 1), SSL_TFLAG_VFY | SSL_TFLAG_CLIENT, flag }
     70 #define SSL_FLAG_VFY_SRV(str, flag) \
     71     { str, (int)(sizeof(str) - 1), SSL_TFLAG_VFY | SSL_TFLAG_SERVER, flag }
     72 
     73 /*
     74  * Opaque structure containing SSL configuration context.
     75  */
     76 
     77 struct ssl_conf_ctx_st {
     78     /*
     79      * Various flags indicating (among other things) which options we will
     80      * recognise.
     81      */
     82     unsigned int flags;
     83     /* Prefix and length of commands */
     84     char *prefix;
     85     size_t prefixlen;
     86     /* SSL_CTX or SSL structure to perform operations on */
     87     SSL_CTX *ctx;
     88     SSL *ssl;
     89     /* Pointer to SSL or SSL_CTX options field or NULL if none */
     90     uint64_t *poptions;
     91     /* Certificate filenames for each type */
     92     char **cert_filename;
     93     /* Number of elements in the cert_filename array */
     94     size_t num_cert_filename;
     95     /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */
     96     uint32_t *pcert_flags;
     97     /* Pointer to SSL or SSL_CTX verify_mode or NULL if none */
     98     uint32_t *pvfy_flags;
     99     /* Pointer to SSL or SSL_CTX min_version field or NULL if none */
    100     int *min_version;
    101     /* Pointer to SSL or SSL_CTX max_version field or NULL if none */
    102     int *max_version;
    103     /* Current flag table being worked on */
    104     const ssl_flag_tbl *tbl;
    105     /* Size of table */
    106     size_t ntbl;
    107     /* Client CA names */
    108     STACK_OF(X509_NAME) *canames;
    109 };
    110 
    111 static void ssl_set_option(SSL_CONF_CTX *cctx, unsigned int name_flags,
    112     uint64_t option_value, int onoff)
    113 {
    114     uint32_t *pflags;
    115 
    116     if (cctx->poptions == NULL)
    117         return;
    118     if (name_flags & SSL_TFLAG_INV)
    119         onoff ^= 1;
    120     switch (name_flags & SSL_TFLAG_TYPE_MASK) {
    121 
    122     case SSL_TFLAG_CERT:
    123         pflags = cctx->pcert_flags;
    124         break;
    125 
    126     case SSL_TFLAG_VFY:
    127         pflags = cctx->pvfy_flags;
    128         break;
    129 
    130     case SSL_TFLAG_OPTION:
    131         if (onoff)
    132             *cctx->poptions |= option_value;
    133         else
    134             *cctx->poptions &= ~option_value;
    135         return;
    136 
    137     default:
    138         return;
    139     }
    140     if (onoff)
    141         *pflags |= option_value;
    142     else
    143         *pflags &= ~option_value;
    144 }
    145 
    146 static int ssl_match_option(SSL_CONF_CTX *cctx, const ssl_flag_tbl *tbl,
    147     const char *name, int namelen, int onoff)
    148 {
    149     /* If name not relevant for context skip */
    150     if (!(cctx->flags & tbl->name_flags & SSL_TFLAG_BOTH))
    151         return 0;
    152     if (namelen == -1) {
    153         if (strcmp(tbl->name, name))
    154             return 0;
    155     } else if (tbl->namelen != namelen
    156         || OPENSSL_strncasecmp(tbl->name, name, namelen))
    157         return 0;
    158     ssl_set_option(cctx, tbl->name_flags, tbl->option_value, onoff);
    159     return 1;
    160 }
    161 
    162 static int ssl_set_option_list(const char *elem, int len, void *usr)
    163 {
    164     SSL_CONF_CTX *cctx = usr;
    165     size_t i;
    166     const ssl_flag_tbl *tbl;
    167     int onoff = 1;
    168     /*
    169      * len == -1 indicates not being called in list context, just for single
    170      * command line switches, so don't allow +, -.
    171      */
    172     if (elem == NULL)
    173         return 0;
    174     if (len != -1) {
    175         if (*elem == '+') {
    176             elem++;
    177             len--;
    178             onoff = 1;
    179         } else if (*elem == '-') {
    180             elem++;
    181             len--;
    182             onoff = 0;
    183         }
    184     }
    185     for (i = 0, tbl = cctx->tbl; i < cctx->ntbl; i++, tbl++) {
    186         if (ssl_match_option(cctx, tbl, elem, len, onoff))
    187             return 1;
    188     }
    189     return 0;
    190 }
    191 
    192 /* Set supported signature algorithms */
    193 static int cmd_SignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
    194 {
    195     int rv;
    196     if (cctx->ssl)
    197         rv = SSL_set1_sigalgs_list(cctx->ssl, value);
    198     /* NB: ctx == NULL performs syntax checking only */
    199     else
    200         rv = SSL_CTX_set1_sigalgs_list(cctx->ctx, value);
    201     return rv > 0;
    202 }
    203 
    204 /* Set supported client signature algorithms */
    205 static int cmd_ClientSignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
    206 {
    207     int rv;
    208     if (cctx->ssl)
    209         rv = SSL_set1_client_sigalgs_list(cctx->ssl, value);
    210     /* NB: ctx == NULL performs syntax checking only */
    211     else
    212         rv = SSL_CTX_set1_client_sigalgs_list(cctx->ctx, value);
    213     return rv > 0;
    214 }
    215 
    216 static int cmd_Groups(SSL_CONF_CTX *cctx, const char *value)
    217 {
    218     int rv;
    219     if (cctx->ssl)
    220         rv = SSL_set1_groups_list(cctx->ssl, value);
    221     /* NB: ctx == NULL performs syntax checking only */
    222     else
    223         rv = SSL_CTX_set1_groups_list(cctx->ctx, value);
    224     return rv > 0;
    225 }
    226 
    227 /* This is the old name for cmd_Groups - retained for backwards compatibility */
    228 static int cmd_Curves(SSL_CONF_CTX *cctx, const char *value)
    229 {
    230     return cmd_Groups(cctx, value);
    231 }
    232 
    233 /* ECDH temporary parameters */
    234 static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value)
    235 {
    236     int rv = 1;
    237 
    238     /* Ignore values supported by 1.0.2 for the automatic selection */
    239     if ((cctx->flags & SSL_CONF_FLAG_FILE)
    240         && (OPENSSL_strcasecmp(value, "+automatic") == 0
    241             || OPENSSL_strcasecmp(value, "automatic") == 0))
    242         return 1;
    243     if ((cctx->flags & SSL_CONF_FLAG_CMDLINE) && strcmp(value, "auto") == 0)
    244         return 1;
    245 
    246     /* ECDHParameters accepts a single group name */
    247     if (strchr(value, ':') != NULL)
    248         return 0;
    249 
    250     if (cctx->ctx)
    251         rv = SSL_CTX_set1_groups_list(cctx->ctx, value);
    252     else if (cctx->ssl)
    253         rv = SSL_set1_groups_list(cctx->ssl, value);
    254 
    255     return rv > 0;
    256 }
    257 
    258 static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value)
    259 {
    260     int rv = 1;
    261 
    262     if (cctx->ctx)
    263         rv = SSL_CTX_set_cipher_list(cctx->ctx, value);
    264     if (cctx->ssl)
    265         rv = SSL_set_cipher_list(cctx->ssl, value);
    266     return rv > 0;
    267 }
    268 
    269 static int cmd_Ciphersuites(SSL_CONF_CTX *cctx, const char *value)
    270 {
    271     int rv = 1;
    272 
    273     if (cctx->ctx)
    274         rv = SSL_CTX_set_ciphersuites(cctx->ctx, value);
    275     if (cctx->ssl)
    276         rv = SSL_set_ciphersuites(cctx->ssl, value);
    277     return rv > 0;
    278 }
    279 
    280 static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value)
    281 {
    282     static const ssl_flag_tbl ssl_protocol_list[] = {
    283         SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK),
    284         SSL_FLAG_TBL_INV("SSLv2", SSL_OP_NO_SSLv2),
    285         SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3),
    286         SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1),
    287         SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1),
    288         SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2),
    289         SSL_FLAG_TBL_INV("TLSv1.3", SSL_OP_NO_TLSv1_3),
    290         SSL_FLAG_TBL_INV("DTLSv1", SSL_OP_NO_DTLSv1),
    291         SSL_FLAG_TBL_INV("DTLSv1.2", SSL_OP_NO_DTLSv1_2)
    292     };
    293     cctx->tbl = ssl_protocol_list;
    294     cctx->ntbl = OSSL_NELEM(ssl_protocol_list);
    295     return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
    296 }
    297 
    298 /*
    299  * protocol_from_string - converts a protocol version string to a number
    300  *
    301  * Returns -1 on failure or the version on success
    302  */
    303 static int protocol_from_string(const char *value)
    304 {
    305     struct protocol_versions {
    306         const char *name;
    307         int version;
    308     };
    309     /*
    310      * Note: To avoid breaking previously valid configurations, we must retain
    311      * legacy entries in this table even if the underlying protocol is no
    312      * longer supported.  This also means that the constants SSL3_VERSION, ...
    313      * need to be retained indefinitely.  This table can only grow, never
    314      * shrink.
    315      */
    316     static const struct protocol_versions versions[] = {
    317         { "None", 0 },
    318         { "SSLv3", SSL3_VERSION },
    319         { "TLSv1", TLS1_VERSION },
    320         { "TLSv1.1", TLS1_1_VERSION },
    321         { "TLSv1.2", TLS1_2_VERSION },
    322         { "TLSv1.3", TLS1_3_VERSION },
    323         { "DTLSv1", DTLS1_VERSION },
    324         { "DTLSv1.2", DTLS1_2_VERSION }
    325     };
    326     size_t i;
    327     size_t n = OSSL_NELEM(versions);
    328 
    329     for (i = 0; i < n; i++)
    330         if (strcmp(versions[i].name, value) == 0)
    331             return versions[i].version;
    332     return -1;
    333 }
    334 
    335 static int min_max_proto(SSL_CONF_CTX *cctx, const char *value, int *bound)
    336 {
    337     int method_version;
    338     int new_version;
    339 
    340     if (cctx->ctx != NULL)
    341         method_version = cctx->ctx->method->version;
    342     else if (cctx->ssl != NULL)
    343         method_version = cctx->ssl->defltmeth->version;
    344     else
    345         return 0;
    346     if ((new_version = protocol_from_string(value)) < 0)
    347         return 0;
    348     return ssl_set_version_bound(method_version, new_version, bound);
    349 }
    350 
    351 /*
    352  * cmd_MinProtocol - Set min protocol version
    353  * @cctx: config structure to save settings in
    354  * @value: The min protocol version in string form
    355  *
    356  * Returns 1 on success and 0 on failure.
    357  */
    358 static int cmd_MinProtocol(SSL_CONF_CTX *cctx, const char *value)
    359 {
    360     return min_max_proto(cctx, value, cctx->min_version);
    361 }
    362 
    363 /*
    364  * cmd_MaxProtocol - Set max protocol version
    365  * @cctx: config structure to save settings in
    366  * @value: The max protocol version in string form
    367  *
    368  * Returns 1 on success and 0 on failure.
    369  */
    370 static int cmd_MaxProtocol(SSL_CONF_CTX *cctx, const char *value)
    371 {
    372     return min_max_proto(cctx, value, cctx->max_version);
    373 }
    374 
    375 static int cmd_Options(SSL_CONF_CTX *cctx, const char *value)
    376 {
    377     static const ssl_flag_tbl ssl_option_list[] = {
    378         SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET),
    379         SSL_FLAG_TBL_INV("EmptyFragments",
    380             SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS),
    381         SSL_FLAG_TBL("Bugs", SSL_OP_ALL),
    382         SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION),
    383         SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE),
    384         SSL_FLAG_TBL_SRV("NoResumptionOnRenegotiation",
    385             SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION),
    386         SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE),
    387         SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE),
    388         SSL_FLAG_TBL("UnsafeLegacyRenegotiation",
    389             SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION),
    390         SSL_FLAG_TBL("UnsafeLegacyServerConnect",
    391             SSL_OP_LEGACY_SERVER_CONNECT),
    392         SSL_FLAG_TBL("ClientRenegotiation",
    393             SSL_OP_ALLOW_CLIENT_RENEGOTIATION),
    394         SSL_FLAG_TBL_INV("EncryptThenMac", SSL_OP_NO_ENCRYPT_THEN_MAC),
    395         SSL_FLAG_TBL("NoRenegotiation", SSL_OP_NO_RENEGOTIATION),
    396         SSL_FLAG_TBL("AllowNoDHEKEX", SSL_OP_ALLOW_NO_DHE_KEX),
    397         SSL_FLAG_TBL("PreferNoDHEKEX", SSL_OP_PREFER_NO_DHE_KEX),
    398         SSL_FLAG_TBL("PrioritizeChaCha", SSL_OP_PRIORITIZE_CHACHA),
    399         SSL_FLAG_TBL("MiddleboxCompat", SSL_OP_ENABLE_MIDDLEBOX_COMPAT),
    400         SSL_FLAG_TBL_INV("AntiReplay", SSL_OP_NO_ANTI_REPLAY),
    401         SSL_FLAG_TBL_INV("ExtendedMasterSecret", SSL_OP_NO_EXTENDED_MASTER_SECRET),
    402         SSL_FLAG_TBL_INV("CANames", SSL_OP_DISABLE_TLSEXT_CA_NAMES),
    403         SSL_FLAG_TBL("KTLS", SSL_OP_ENABLE_KTLS),
    404         SSL_FLAG_TBL_CERT("StrictCertCheck", SSL_CERT_FLAG_TLS_STRICT),
    405         SSL_FLAG_TBL_INV("TxCertificateCompression", SSL_OP_NO_TX_CERTIFICATE_COMPRESSION),
    406         SSL_FLAG_TBL_INV("RxCertificateCompression", SSL_OP_NO_RX_CERTIFICATE_COMPRESSION),
    407         SSL_FLAG_TBL("KTLSTxZerocopySendfile", SSL_OP_ENABLE_KTLS_TX_ZEROCOPY_SENDFILE),
    408         SSL_FLAG_TBL("IgnoreUnexpectedEOF", SSL_OP_IGNORE_UNEXPECTED_EOF),
    409     };
    410     if (value == NULL)
    411         return -3;
    412     cctx->tbl = ssl_option_list;
    413     cctx->ntbl = OSSL_NELEM(ssl_option_list);
    414     return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
    415 }
    416 
    417 static int cmd_VerifyMode(SSL_CONF_CTX *cctx, const char *value)
    418 {
    419     static const ssl_flag_tbl ssl_vfy_list[] = {
    420         SSL_FLAG_VFY_CLI("Peer", SSL_VERIFY_PEER),
    421         SSL_FLAG_VFY_SRV("Request", SSL_VERIFY_PEER),
    422         SSL_FLAG_VFY_SRV("Require",
    423             SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT),
    424         SSL_FLAG_VFY_SRV("Once", SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE),
    425         SSL_FLAG_VFY_SRV("RequestPostHandshake",
    426             SSL_VERIFY_PEER | SSL_VERIFY_POST_HANDSHAKE),
    427         SSL_FLAG_VFY_SRV("RequirePostHandshake",
    428             SSL_VERIFY_PEER | SSL_VERIFY_POST_HANDSHAKE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT),
    429     };
    430     if (value == NULL)
    431         return -3;
    432     cctx->tbl = ssl_vfy_list;
    433     cctx->ntbl = OSSL_NELEM(ssl_vfy_list);
    434     return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
    435 }
    436 
    437 static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value)
    438 {
    439     int rv = 1;
    440     CERT *c = NULL;
    441     if (cctx->ctx != NULL) {
    442         rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value);
    443         c = cctx->ctx->cert;
    444     }
    445     if (cctx->ssl != NULL) {
    446         SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(cctx->ssl);
    447 
    448         if (sc != NULL) {
    449             rv = SSL_use_certificate_chain_file(cctx->ssl, value);
    450             c = sc->cert;
    451         } else {
    452             rv = 0;
    453         }
    454     }
    455     if (rv > 0 && c != NULL && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
    456         size_t fileidx = c->key - c->pkeys;
    457 
    458         if (fileidx >= cctx->num_cert_filename) {
    459             rv = 0;
    460         } else {
    461             char **pfilename = &cctx->cert_filename[c->key - c->pkeys];
    462 
    463             OPENSSL_free(*pfilename);
    464             *pfilename = OPENSSL_strdup(value);
    465             if (*pfilename == NULL)
    466                 rv = 0;
    467         }
    468     }
    469 
    470     return rv > 0;
    471 }
    472 
    473 static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value)
    474 {
    475     int rv = 1;
    476     if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
    477         return -2;
    478     if (cctx->ctx)
    479         rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM);
    480     if (cctx->ssl)
    481         rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM);
    482     return rv > 0;
    483 }
    484 
    485 static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value)
    486 {
    487     int rv = 1;
    488     if (cctx->ctx)
    489         rv = SSL_CTX_use_serverinfo_file(cctx->ctx, value);
    490     return rv > 0;
    491 }
    492 
    493 static int do_store(SSL_CONF_CTX *cctx,
    494     const char *CAfile, const char *CApath, const char *CAstore,
    495     int verify_store)
    496 {
    497     CERT *cert;
    498     X509_STORE **st;
    499     SSL_CTX *ctx;
    500     OSSL_LIB_CTX *libctx = NULL;
    501     const char *propq = NULL;
    502 
    503     if (cctx->ctx != NULL) {
    504         cert = cctx->ctx->cert;
    505         ctx = cctx->ctx;
    506     } else if (cctx->ssl != NULL) {
    507         SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(cctx->ssl);
    508 
    509         if (sc == NULL)
    510             return 0;
    511 
    512         cert = sc->cert;
    513         ctx = cctx->ssl->ctx;
    514     } else {
    515         return 1;
    516     }
    517     if (ctx != NULL) {
    518         libctx = ctx->libctx;
    519         propq = ctx->propq;
    520     }
    521     st = verify_store ? &cert->verify_store : &cert->chain_store;
    522     if (*st == NULL) {
    523         *st = X509_STORE_new();
    524         if (*st == NULL)
    525             return 0;
    526     }
    527 
    528     if (CAfile != NULL && !X509_STORE_load_file_ex(*st, CAfile, libctx, propq))
    529         return 0;
    530     if (CApath != NULL && !X509_STORE_load_path(*st, CApath))
    531         return 0;
    532     if (CAstore != NULL && !X509_STORE_load_store_ex(*st, CAstore, libctx, propq))
    533         return 0;
    534     return 1;
    535 }
    536 
    537 static int cmd_ChainCAPath(SSL_CONF_CTX *cctx, const char *value)
    538 {
    539     return do_store(cctx, NULL, value, NULL, 0);
    540 }
    541 
    542 static int cmd_ChainCAFile(SSL_CONF_CTX *cctx, const char *value)
    543 {
    544     return do_store(cctx, value, NULL, NULL, 0);
    545 }
    546 
    547 static int cmd_ChainCAStore(SSL_CONF_CTX *cctx, const char *value)
    548 {
    549     return do_store(cctx, NULL, NULL, value, 0);
    550 }
    551 
    552 static int cmd_VerifyCAPath(SSL_CONF_CTX *cctx, const char *value)
    553 {
    554     return do_store(cctx, NULL, value, NULL, 1);
    555 }
    556 
    557 static int cmd_VerifyCAFile(SSL_CONF_CTX *cctx, const char *value)
    558 {
    559     return do_store(cctx, value, NULL, NULL, 1);
    560 }
    561 
    562 static int cmd_VerifyCAStore(SSL_CONF_CTX *cctx, const char *value)
    563 {
    564     return do_store(cctx, NULL, NULL, value, 1);
    565 }
    566 
    567 static int cmd_RequestCAFile(SSL_CONF_CTX *cctx, const char *value)
    568 {
    569     if (cctx->canames == NULL)
    570         cctx->canames = sk_X509_NAME_new_null();
    571     if (cctx->canames == NULL)
    572         return 0;
    573     return SSL_add_file_cert_subjects_to_stack(cctx->canames, value);
    574 }
    575 
    576 static int cmd_ClientCAFile(SSL_CONF_CTX *cctx, const char *value)
    577 {
    578     return cmd_RequestCAFile(cctx, value);
    579 }
    580 
    581 static int cmd_RequestCAPath(SSL_CONF_CTX *cctx, const char *value)
    582 {
    583     if (cctx->canames == NULL)
    584         cctx->canames = sk_X509_NAME_new_null();
    585     if (cctx->canames == NULL)
    586         return 0;
    587     return SSL_add_dir_cert_subjects_to_stack(cctx->canames, value);
    588 }
    589 
    590 static int cmd_ClientCAPath(SSL_CONF_CTX *cctx, const char *value)
    591 {
    592     return cmd_RequestCAPath(cctx, value);
    593 }
    594 
    595 static int cmd_RequestCAStore(SSL_CONF_CTX *cctx, const char *value)
    596 {
    597     if (cctx->canames == NULL)
    598         cctx->canames = sk_X509_NAME_new_null();
    599     if (cctx->canames == NULL)
    600         return 0;
    601     return SSL_add_store_cert_subjects_to_stack(cctx->canames, value);
    602 }
    603 
    604 static int cmd_ClientCAStore(SSL_CONF_CTX *cctx, const char *value)
    605 {
    606     return cmd_RequestCAStore(cctx, value);
    607 }
    608 
    609 static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value)
    610 {
    611     int rv = 0;
    612     EVP_PKEY *dhpkey = NULL;
    613     BIO *in = NULL;
    614     SSL_CTX *sslctx = (cctx->ssl != NULL) ? cctx->ssl->ctx : cctx->ctx;
    615     OSSL_DECODER_CTX *decoderctx = NULL;
    616 
    617     if (cctx->ctx != NULL || cctx->ssl != NULL) {
    618         in = BIO_new(BIO_s_file());
    619         if (in == NULL)
    620             goto end;
    621         if (BIO_read_filename(in, value) <= 0)
    622             goto end;
    623 
    624         decoderctx
    625             = OSSL_DECODER_CTX_new_for_pkey(&dhpkey, "PEM", NULL, "DH",
    626                 OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
    627                 sslctx->libctx, sslctx->propq);
    628         if (decoderctx == NULL)
    629             goto end;
    630         ERR_set_mark();
    631         while (!OSSL_DECODER_from_bio(decoderctx, in)
    632             && dhpkey == NULL
    633             && !BIO_eof(in))
    634             ;
    635         OSSL_DECODER_CTX_free(decoderctx);
    636 
    637         if (dhpkey == NULL) {
    638             ERR_clear_last_mark();
    639             goto end;
    640         }
    641         ERR_pop_to_mark();
    642     } else {
    643         return 1;
    644     }
    645 
    646     if (cctx->ctx != NULL) {
    647         if ((rv = SSL_CTX_set0_tmp_dh_pkey(cctx->ctx, dhpkey)) > 0)
    648             dhpkey = NULL;
    649     }
    650     if (cctx->ssl != NULL) {
    651         if ((rv = SSL_set0_tmp_dh_pkey(cctx->ssl, dhpkey)) > 0)
    652             dhpkey = NULL;
    653     }
    654 end:
    655     EVP_PKEY_free(dhpkey);
    656     BIO_free(in);
    657     return rv > 0;
    658 }
    659 
    660 /*
    661  * |value| input is "<number[,number]>"
    662  * where the first number is the padding block size for
    663  * application data, and the optional second is the
    664  * padding block size for handshake messages
    665  */
    666 static int cmd_RecordPadding(SSL_CONF_CTX *cctx, const char *value)
    667 {
    668     int rv = 0;
    669     unsigned long block_padding = 0, hs_padding = 0;
    670     char *commap = NULL, *copy = NULL;
    671     char *endptr = NULL;
    672 
    673     copy = OPENSSL_strdup(value);
    674     if (copy == NULL)
    675         goto out;
    676     commap = strstr(copy, ",");
    677     if (commap != NULL) {
    678         *commap = '\0';
    679         if (*(commap + 1) == '\0')
    680             goto out;
    681         if (!OPENSSL_strtoul(commap + 1, &endptr, 0, &hs_padding))
    682             goto out;
    683     }
    684     if (!OPENSSL_strtoul(copy, &endptr, 0, &block_padding))
    685         goto out;
    686     if (commap == NULL)
    687         hs_padding = block_padding;
    688 
    689     /*
    690      * All we care about are non-negative values,
    691      * the setters check the range
    692      */
    693     if (cctx->ctx) {
    694         /*
    695          * QUIC always pads TLS data at the packet level, and as such, attempting
    696          * to set block padding at the record level fails in calls to SSL_CTX_set_block_padding_ex.
    697          * However, when configuring record padding via config file, we have no idea if we are
    698          * going to create TCP or QUIC based SSL's, so silently ignore this configuration option
    699          * for QUIC.
    700          */
    701         if (SSL_CTX_is_quic(cctx->ctx))
    702             rv = 1;
    703         else
    704             rv = SSL_CTX_set_block_padding_ex(cctx->ctx, (size_t)block_padding,
    705                 (size_t)hs_padding);
    706     }
    707     if (cctx->ssl) {
    708         /*
    709          * As above, ignore this config option for QUIC
    710          */
    711         if (SSL_is_quic(cctx->ssl))
    712             rv = 1;
    713         else
    714             rv = SSL_set_block_padding_ex(cctx->ssl, (size_t)block_padding,
    715                 (size_t)hs_padding);
    716     }
    717 out:
    718     OPENSSL_free(copy);
    719     return rv;
    720 }
    721 
    722 static int cmd_NumTickets(SSL_CONF_CTX *cctx, const char *value)
    723 {
    724     int rv = 0;
    725     int num_tickets = atoi(value);
    726 
    727     if (num_tickets >= 0) {
    728         if (cctx->ctx)
    729             rv = SSL_CTX_set_num_tickets(cctx->ctx, num_tickets);
    730         if (cctx->ssl)
    731             rv = SSL_set_num_tickets(cctx->ssl, num_tickets);
    732     }
    733     return rv;
    734 }
    735 
    736 typedef struct {
    737     int (*cmd)(SSL_CONF_CTX *cctx, const char *value);
    738     const char *str_file;
    739     const char *str_cmdline;
    740     unsigned short flags;
    741     unsigned short value_type;
    742 } ssl_conf_cmd_tbl;
    743 
    744 /* Table of supported parameters */
    745 
    746 #define SSL_CONF_CMD(name, cmdopt, flags, type) \
    747     { cmd_##name, #name, cmdopt, flags, type }
    748 
    749 #define SSL_CONF_CMD_STRING(name, cmdopt, flags) \
    750     SSL_CONF_CMD(name, cmdopt, flags, SSL_CONF_TYPE_STRING)
    751 
    752 #define SSL_CONF_CMD_SWITCH(name, flags) \
    753     { 0, NULL, name, flags, SSL_CONF_TYPE_NONE }
    754 
    755 /* See apps/include/opt.h if you change this table. */
    756 /* The SSL_CONF_CMD_SWITCH should be the same order as ssl_cmd_switches */
    757 static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
    758     SSL_CONF_CMD_SWITCH("no_ssl3", 0),
    759     SSL_CONF_CMD_SWITCH("no_tls1", 0),
    760     SSL_CONF_CMD_SWITCH("no_tls1_1", 0),
    761     SSL_CONF_CMD_SWITCH("no_tls1_2", 0),
    762     SSL_CONF_CMD_SWITCH("no_tls1_3", 0),
    763     SSL_CONF_CMD_SWITCH("bugs", 0),
    764     SSL_CONF_CMD_SWITCH("no_comp", 0),
    765     SSL_CONF_CMD_SWITCH("comp", 0),
    766     SSL_CONF_CMD_SWITCH("no_tx_cert_comp", 0),
    767     SSL_CONF_CMD_SWITCH("tx_cert_comp", 0),
    768     SSL_CONF_CMD_SWITCH("no_rx_cert_comp", 0),
    769     SSL_CONF_CMD_SWITCH("rx_cert_comp", 0),
    770     SSL_CONF_CMD_SWITCH("ecdh_single", SSL_CONF_FLAG_SERVER),
    771     SSL_CONF_CMD_SWITCH("no_ticket", 0),
    772     SSL_CONF_CMD_SWITCH("serverpref", SSL_CONF_FLAG_SERVER),
    773     SSL_CONF_CMD_SWITCH("legacy_renegotiation", 0),
    774     SSL_CONF_CMD_SWITCH("client_renegotiation", SSL_CONF_FLAG_SERVER),
    775     SSL_CONF_CMD_SWITCH("legacy_server_connect", SSL_CONF_FLAG_CLIENT),
    776     SSL_CONF_CMD_SWITCH("no_renegotiation", 0),
    777     SSL_CONF_CMD_SWITCH("no_resumption_on_reneg", SSL_CONF_FLAG_SERVER),
    778     SSL_CONF_CMD_SWITCH("no_legacy_server_connect", SSL_CONF_FLAG_CLIENT),
    779     SSL_CONF_CMD_SWITCH("allow_no_dhe_kex", 0),
    780     SSL_CONF_CMD_SWITCH("prefer_no_dhe_kex", 0),
    781     SSL_CONF_CMD_SWITCH("prioritize_chacha", SSL_CONF_FLAG_SERVER),
    782     SSL_CONF_CMD_SWITCH("strict", 0),
    783     SSL_CONF_CMD_SWITCH("no_middlebox", 0),
    784     SSL_CONF_CMD_SWITCH("anti_replay", SSL_CONF_FLAG_SERVER),
    785     SSL_CONF_CMD_SWITCH("no_anti_replay", SSL_CONF_FLAG_SERVER),
    786     SSL_CONF_CMD_SWITCH("no_etm", 0),
    787     SSL_CONF_CMD_SWITCH("no_ems", 0),
    788     SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs", 0),
    789     SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs", 0),
    790     SSL_CONF_CMD_STRING(Curves, "curves", 0),
    791     SSL_CONF_CMD_STRING(Groups, "groups", 0),
    792     SSL_CONF_CMD_STRING(ECDHParameters, "named_curve", SSL_CONF_FLAG_SERVER),
    793     SSL_CONF_CMD_STRING(CipherString, "cipher", 0),
    794     SSL_CONF_CMD_STRING(Ciphersuites, "ciphersuites", 0),
    795     SSL_CONF_CMD_STRING(Protocol, NULL, 0),
    796     SSL_CONF_CMD_STRING(MinProtocol, "min_protocol", 0),
    797     SSL_CONF_CMD_STRING(MaxProtocol, "max_protocol", 0),
    798     SSL_CONF_CMD_STRING(Options, NULL, 0),
    799     SSL_CONF_CMD_STRING(VerifyMode, NULL, 0),
    800     SSL_CONF_CMD(Certificate, "cert", SSL_CONF_FLAG_CERTIFICATE,
    801         SSL_CONF_TYPE_FILE),
    802     SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_FLAG_CERTIFICATE,
    803         SSL_CONF_TYPE_FILE),
    804     SSL_CONF_CMD(ServerInfoFile, NULL,
    805         SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
    806         SSL_CONF_TYPE_FILE),
    807     SSL_CONF_CMD(ChainCAPath, "chainCApath", SSL_CONF_FLAG_CERTIFICATE,
    808         SSL_CONF_TYPE_DIR),
    809     SSL_CONF_CMD(ChainCAFile, "chainCAfile", SSL_CONF_FLAG_CERTIFICATE,
    810         SSL_CONF_TYPE_FILE),
    811     SSL_CONF_CMD(ChainCAStore, "chainCAstore", SSL_CONF_FLAG_CERTIFICATE,
    812         SSL_CONF_TYPE_STORE),
    813     SSL_CONF_CMD(VerifyCAPath, "verifyCApath", SSL_CONF_FLAG_CERTIFICATE,
    814         SSL_CONF_TYPE_DIR),
    815     SSL_CONF_CMD(VerifyCAFile, "verifyCAfile", SSL_CONF_FLAG_CERTIFICATE,
    816         SSL_CONF_TYPE_FILE),
    817     SSL_CONF_CMD(VerifyCAStore, "verifyCAstore", SSL_CONF_FLAG_CERTIFICATE,
    818         SSL_CONF_TYPE_STORE),
    819     SSL_CONF_CMD(RequestCAFile, "requestCAFile", SSL_CONF_FLAG_CERTIFICATE,
    820         SSL_CONF_TYPE_FILE),
    821     SSL_CONF_CMD(ClientCAFile, NULL,
    822         SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
    823         SSL_CONF_TYPE_FILE),
    824     SSL_CONF_CMD(RequestCAPath, NULL, SSL_CONF_FLAG_CERTIFICATE,
    825         SSL_CONF_TYPE_DIR),
    826     SSL_CONF_CMD(ClientCAPath, NULL,
    827         SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
    828         SSL_CONF_TYPE_DIR),
    829     SSL_CONF_CMD(RequestCAStore, "requestCAStore", SSL_CONF_FLAG_CERTIFICATE,
    830         SSL_CONF_TYPE_STORE),
    831     SSL_CONF_CMD(ClientCAStore, NULL,
    832         SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
    833         SSL_CONF_TYPE_STORE),
    834     SSL_CONF_CMD(DHParameters, "dhparam",
    835         SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
    836         SSL_CONF_TYPE_FILE),
    837     SSL_CONF_CMD_STRING(RecordPadding, "record_padding", 0),
    838     SSL_CONF_CMD_STRING(NumTickets, "num_tickets", SSL_CONF_FLAG_SERVER),
    839 };
    840 
    841 /* Supported switches: must match order of switches in ssl_conf_cmds */
    842 static const ssl_switch_tbl ssl_cmd_switches[] = {
    843     { SSL_OP_NO_SSLv3, 0 }, /* no_ssl3 */
    844     { SSL_OP_NO_TLSv1, 0 }, /* no_tls1 */
    845     { SSL_OP_NO_TLSv1_1, 0 }, /* no_tls1_1 */
    846     { SSL_OP_NO_TLSv1_2, 0 }, /* no_tls1_2 */
    847     { SSL_OP_NO_TLSv1_3, 0 }, /* no_tls1_3 */
    848     { SSL_OP_ALL, 0 }, /* bugs */
    849     { SSL_OP_NO_COMPRESSION, 0 }, /* no_comp */
    850     { SSL_OP_NO_COMPRESSION, SSL_TFLAG_INV }, /* comp */
    851     { SSL_OP_NO_TX_CERTIFICATE_COMPRESSION, 0 }, /* no_tx_cert_comp */
    852     { SSL_OP_NO_TX_CERTIFICATE_COMPRESSION, SSL_TFLAG_INV }, /* tx_cert_comp */
    853     { SSL_OP_NO_RX_CERTIFICATE_COMPRESSION, 0 }, /* no_rx_cert_comp */
    854     { SSL_OP_NO_RX_CERTIFICATE_COMPRESSION, SSL_TFLAG_INV }, /* rx_cert_comp */
    855     { SSL_OP_SINGLE_ECDH_USE, 0 }, /* ecdh_single */
    856     { SSL_OP_NO_TICKET, 0 }, /* no_ticket */
    857     { SSL_OP_CIPHER_SERVER_PREFERENCE, 0 }, /* serverpref */
    858     /* legacy_renegotiation */
    859     { SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, 0 },
    860     /* Allow client renegotiation */
    861     { SSL_OP_ALLOW_CLIENT_RENEGOTIATION, 0 },
    862     /* legacy_server_connect */
    863     { SSL_OP_LEGACY_SERVER_CONNECT, 0 },
    864     /* no_renegotiation */
    865     { SSL_OP_NO_RENEGOTIATION, 0 },
    866     /* no_resumption_on_reneg */
    867     { SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION, 0 },
    868     /* no_legacy_server_connect */
    869     { SSL_OP_LEGACY_SERVER_CONNECT, SSL_TFLAG_INV },
    870     /* allow_no_dhe_kex */
    871     { SSL_OP_ALLOW_NO_DHE_KEX, 0 },
    872     /* prefer_no_dhe_kex */
    873     { SSL_OP_PREFER_NO_DHE_KEX, 0 },
    874     /* chacha reprioritization */
    875     { SSL_OP_PRIORITIZE_CHACHA, 0 },
    876     { SSL_CERT_FLAG_TLS_STRICT, SSL_TFLAG_CERT }, /* strict */
    877     /* no_middlebox */
    878     { SSL_OP_ENABLE_MIDDLEBOX_COMPAT, SSL_TFLAG_INV },
    879     /* anti_replay */
    880     { SSL_OP_NO_ANTI_REPLAY, SSL_TFLAG_INV },
    881     /* no_anti_replay */
    882     { SSL_OP_NO_ANTI_REPLAY, 0 },
    883     /* no Encrypt-then-Mac */
    884     { SSL_OP_NO_ENCRYPT_THEN_MAC, 0 },
    885     /* no Extended master secret */
    886     { SSL_OP_NO_EXTENDED_MASTER_SECRET, 0 },
    887 };
    888 
    889 static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd)
    890 {
    891     if (pcmd == NULL || *pcmd == NULL)
    892         return 0;
    893     /* If a prefix is set, check and skip */
    894     if (cctx->prefix) {
    895         if (strlen(*pcmd) <= cctx->prefixlen)
    896             return 0;
    897         if (cctx->flags & SSL_CONF_FLAG_CMDLINE && strncmp(*pcmd, cctx->prefix, cctx->prefixlen))
    898             return 0;
    899         if (cctx->flags & SSL_CONF_FLAG_FILE && OPENSSL_strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen))
    900             return 0;
    901         *pcmd += cctx->prefixlen;
    902     } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
    903         if (**pcmd != '-' || !(*pcmd)[1])
    904             return 0;
    905         *pcmd += 1;
    906     }
    907     return 1;
    908 }
    909 
    910 /* Determine if a command is allowed according to cctx flags */
    911 static int ssl_conf_cmd_allowed(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl *t)
    912 {
    913     unsigned int tfl = t->flags;
    914     unsigned int cfl = cctx->flags;
    915     if ((tfl & SSL_CONF_FLAG_SERVER) && !(cfl & SSL_CONF_FLAG_SERVER))
    916         return 0;
    917     if ((tfl & SSL_CONF_FLAG_CLIENT) && !(cfl & SSL_CONF_FLAG_CLIENT))
    918         return 0;
    919     if ((tfl & SSL_CONF_FLAG_CERTIFICATE)
    920         && !(cfl & SSL_CONF_FLAG_CERTIFICATE))
    921         return 0;
    922     return 1;
    923 }
    924 
    925 static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx,
    926     const char *cmd)
    927 {
    928     const ssl_conf_cmd_tbl *t;
    929     size_t i;
    930     if (cmd == NULL)
    931         return NULL;
    932 
    933     /* Look for matching parameter name in table */
    934     for (i = 0, t = ssl_conf_cmds; i < OSSL_NELEM(ssl_conf_cmds); i++, t++) {
    935         if (ssl_conf_cmd_allowed(cctx, t)) {
    936             if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
    937                 if (t->str_cmdline && strcmp(t->str_cmdline, cmd) == 0)
    938                     return t;
    939             }
    940             if (cctx->flags & SSL_CONF_FLAG_FILE) {
    941                 if (t->str_file && OPENSSL_strcasecmp(t->str_file, cmd) == 0)
    942                     return t;
    943             }
    944         }
    945     }
    946     return NULL;
    947 }
    948 
    949 static int ctrl_switch_option(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl *cmd)
    950 {
    951     /* Find index of command in table */
    952     size_t idx = cmd - ssl_conf_cmds;
    953     const ssl_switch_tbl *scmd;
    954 
    955     /* Sanity check index */
    956     if (idx >= OSSL_NELEM(ssl_cmd_switches)) {
    957         ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
    958         return 0;
    959     }
    960     /* Obtain switches entry with same index */
    961     scmd = ssl_cmd_switches + idx;
    962     ssl_set_option(cctx, scmd->name_flags, scmd->option_value, 1);
    963     return 1;
    964 }
    965 
    966 int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value)
    967 {
    968     const ssl_conf_cmd_tbl *runcmd;
    969     if (cmd == NULL) {
    970         ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_NULL_CMD_NAME);
    971         return 0;
    972     }
    973 
    974     if (!ssl_conf_cmd_skip_prefix(cctx, &cmd))
    975         goto unknown_cmd;
    976 
    977     runcmd = ssl_conf_cmd_lookup(cctx, cmd);
    978 
    979     if (runcmd) {
    980         int rv = -3;
    981 
    982         if (runcmd->value_type == SSL_CONF_TYPE_NONE) {
    983             return ctrl_switch_option(cctx, runcmd);
    984         }
    985         if (value == NULL)
    986             goto bad_value;
    987         rv = runcmd->cmd(cctx, value);
    988         if (rv > 0)
    989             return 2;
    990         if (rv != -2)
    991             rv = 0;
    992 
    993     bad_value:
    994         if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS)
    995             ERR_raise_data(ERR_LIB_SSL, SSL_R_BAD_VALUE,
    996                 "cmd=%s, value=%s", cmd,
    997                 value != NULL ? value : "<EMPTY>");
    998         return rv;
    999     }
   1000 
   1001 unknown_cmd:
   1002     if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS)
   1003         ERR_raise_data(ERR_LIB_SSL, SSL_R_UNKNOWN_CMD_NAME, "cmd=%s", cmd);
   1004 
   1005     return -2;
   1006 }
   1007 
   1008 int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv)
   1009 {
   1010     int rv;
   1011     const char *arg = NULL, *argn;
   1012 
   1013     if (pargc != NULL && *pargc == 0)
   1014         return 0;
   1015     if (pargc == NULL || *pargc > 0)
   1016         arg = **pargv;
   1017     if (arg == NULL)
   1018         return 0;
   1019     if (pargc == NULL || *pargc > 1)
   1020         argn = (*pargv)[1];
   1021     else
   1022         argn = NULL;
   1023     cctx->flags &= ~SSL_CONF_FLAG_FILE;
   1024     cctx->flags |= SSL_CONF_FLAG_CMDLINE;
   1025     rv = SSL_CONF_cmd(cctx, arg, argn);
   1026     if (rv > 0) {
   1027         /* Success: update pargc, pargv */
   1028         (*pargv) += rv;
   1029         if (pargc)
   1030             (*pargc) -= rv;
   1031         return rv;
   1032     }
   1033     /* Unknown switch: indicate no arguments processed */
   1034     if (rv == -2)
   1035         return 0;
   1036     /* Some error occurred processing command, return fatal error */
   1037     if (rv == 0)
   1038         return -1;
   1039     return rv;
   1040 }
   1041 
   1042 int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd)
   1043 {
   1044     if (ssl_conf_cmd_skip_prefix(cctx, &cmd)) {
   1045         const ssl_conf_cmd_tbl *runcmd;
   1046         runcmd = ssl_conf_cmd_lookup(cctx, cmd);
   1047         if (runcmd)
   1048             return runcmd->value_type;
   1049     }
   1050     return SSL_CONF_TYPE_UNKNOWN;
   1051 }
   1052 
   1053 SSL_CONF_CTX *SSL_CONF_CTX_new(void)
   1054 {
   1055     SSL_CONF_CTX *ret = OPENSSL_zalloc(sizeof(*ret));
   1056 
   1057     return ret;
   1058 }
   1059 
   1060 int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx)
   1061 {
   1062     /* See if any certificates are missing private keys */
   1063     size_t i;
   1064     CERT *c = NULL;
   1065 
   1066     if (cctx->ctx != NULL) {
   1067         c = cctx->ctx->cert;
   1068     } else if (cctx->ssl != NULL) {
   1069         SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(cctx->ssl);
   1070 
   1071         if (sc != NULL)
   1072             c = sc->cert;
   1073     }
   1074     if (c != NULL && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
   1075         for (i = 0; i < cctx->num_cert_filename; i++) {
   1076             const char *p = cctx->cert_filename[i];
   1077 
   1078             /*
   1079              * If missing private key try to load one from certificate file
   1080              */
   1081             if (p != NULL && c->pkeys[i].privatekey == NULL) {
   1082                 if (!cmd_PrivateKey(cctx, p))
   1083                     return 0;
   1084             }
   1085         }
   1086     }
   1087     if (cctx->canames) {
   1088         if (cctx->ssl)
   1089             SSL_set0_CA_list(cctx->ssl, cctx->canames);
   1090         else if (cctx->ctx)
   1091             SSL_CTX_set0_CA_list(cctx->ctx, cctx->canames);
   1092         else
   1093             sk_X509_NAME_pop_free(cctx->canames, X509_NAME_free);
   1094         cctx->canames = NULL;
   1095     }
   1096     return 1;
   1097 }
   1098 
   1099 static void free_cert_filename(SSL_CONF_CTX *cctx)
   1100 {
   1101     size_t i;
   1102 
   1103     for (i = 0; i < cctx->num_cert_filename; i++)
   1104         OPENSSL_free(cctx->cert_filename[i]);
   1105     OPENSSL_free(cctx->cert_filename);
   1106     cctx->cert_filename = NULL;
   1107     cctx->num_cert_filename = 0;
   1108 }
   1109 
   1110 void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx)
   1111 {
   1112     if (cctx) {
   1113         free_cert_filename(cctx);
   1114         OPENSSL_free(cctx->prefix);
   1115         sk_X509_NAME_pop_free(cctx->canames, X509_NAME_free);
   1116         OPENSSL_free(cctx);
   1117     }
   1118 }
   1119 
   1120 unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags)
   1121 {
   1122     cctx->flags |= flags;
   1123     return cctx->flags;
   1124 }
   1125 
   1126 unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags)
   1127 {
   1128     cctx->flags &= ~flags;
   1129     return cctx->flags;
   1130 }
   1131 
   1132 int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre)
   1133 {
   1134     char *tmp = NULL;
   1135     if (pre) {
   1136         tmp = OPENSSL_strdup(pre);
   1137         if (tmp == NULL)
   1138             return 0;
   1139     }
   1140     OPENSSL_free(cctx->prefix);
   1141     cctx->prefix = tmp;
   1142     if (tmp)
   1143         cctx->prefixlen = strlen(tmp);
   1144     else
   1145         cctx->prefixlen = 0;
   1146     return 1;
   1147 }
   1148 
   1149 void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl)
   1150 {
   1151     cctx->ssl = ssl;
   1152     cctx->ctx = NULL;
   1153     free_cert_filename(cctx);
   1154     if (ssl != NULL) {
   1155         SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);
   1156 
   1157         if (sc == NULL)
   1158             return;
   1159         cctx->poptions = &sc->options;
   1160         cctx->min_version = &sc->min_proto_version;
   1161         cctx->max_version = &sc->max_proto_version;
   1162         cctx->pcert_flags = &sc->cert->cert_flags;
   1163         cctx->pvfy_flags = &sc->verify_mode;
   1164         cctx->cert_filename = OPENSSL_zalloc(sc->ssl_pkey_num
   1165             * sizeof(*cctx->cert_filename));
   1166         if (cctx->cert_filename != NULL)
   1167             cctx->num_cert_filename = sc->ssl_pkey_num;
   1168     } else {
   1169         cctx->poptions = NULL;
   1170         cctx->min_version = NULL;
   1171         cctx->max_version = NULL;
   1172         cctx->pcert_flags = NULL;
   1173         cctx->pvfy_flags = NULL;
   1174     }
   1175 }
   1176 
   1177 void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx)
   1178 {
   1179     cctx->ctx = ctx;
   1180     cctx->ssl = NULL;
   1181     free_cert_filename(cctx);
   1182     if (ctx) {
   1183         cctx->poptions = &ctx->options;
   1184         cctx->min_version = &ctx->min_proto_version;
   1185         cctx->max_version = &ctx->max_proto_version;
   1186         cctx->pcert_flags = &ctx->cert->cert_flags;
   1187         cctx->pvfy_flags = &ctx->verify_mode;
   1188         cctx->cert_filename = OPENSSL_zalloc((SSL_PKEY_NUM + ctx->sigalg_list_len)
   1189             * sizeof(*cctx->cert_filename));
   1190         if (cctx->cert_filename != NULL)
   1191             cctx->num_cert_filename = SSL_PKEY_NUM + ctx->sigalg_list_len;
   1192     } else {
   1193         cctx->poptions = NULL;
   1194         cctx->min_version = NULL;
   1195         cctx->max_version = NULL;
   1196         cctx->pcert_flags = NULL;
   1197         cctx->pvfy_flags = NULL;
   1198     }
   1199 }
   1200