xref: /freebsd/crypto/openssl/ssl/ssl_conf.c (revision 58f351825a371d1a3dd693d6f64a1245ea851a51)
17bded2dbSJung-uk Kim /*
2*58f35182SJung-uk Kim  * Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved.
37bded2dbSJung-uk Kim  *
4e71b7053SJung-uk Kim  * Licensed under the OpenSSL license (the "License").  You may not use
5e71b7053SJung-uk Kim  * this file except in compliance with the License.  You can obtain a copy
6e71b7053SJung-uk Kim  * in the file LICENSE in the source distribution or at
7e71b7053SJung-uk Kim  * https://www.openssl.org/source/license.html
87bded2dbSJung-uk Kim  */
97bded2dbSJung-uk Kim 
107bded2dbSJung-uk Kim #include <stdio.h>
1117f01e99SJung-uk Kim #include "ssl_local.h"
127bded2dbSJung-uk Kim #include <openssl/conf.h>
137bded2dbSJung-uk Kim #include <openssl/objects.h>
147bded2dbSJung-uk Kim #include <openssl/dh.h>
15e71b7053SJung-uk Kim #include "internal/nelem.h"
167bded2dbSJung-uk Kim 
177bded2dbSJung-uk Kim /*
18e71b7053SJung-uk Kim  * structure holding name tables. This is used for permitted elements in lists
19e71b7053SJung-uk Kim  * such as TLSv1.
207bded2dbSJung-uk Kim  */
217bded2dbSJung-uk Kim 
227bded2dbSJung-uk Kim typedef struct {
237bded2dbSJung-uk Kim     const char *name;
247bded2dbSJung-uk Kim     int namelen;
257bded2dbSJung-uk Kim     unsigned int name_flags;
267bded2dbSJung-uk Kim     unsigned long option_value;
277bded2dbSJung-uk Kim } ssl_flag_tbl;
287bded2dbSJung-uk Kim 
29e71b7053SJung-uk Kim /* Switch table: use for single command line switches like no_tls2 */
30e71b7053SJung-uk Kim typedef struct {
31e71b7053SJung-uk Kim     unsigned long option_value;
32e71b7053SJung-uk Kim     unsigned int name_flags;
33e71b7053SJung-uk Kim } ssl_switch_tbl;
34e71b7053SJung-uk Kim 
357bded2dbSJung-uk Kim /* Sense of name is inverted e.g. "TLSv1" will clear SSL_OP_NO_TLSv1 */
367bded2dbSJung-uk Kim #define SSL_TFLAG_INV   0x1
37e71b7053SJung-uk Kim /* Mask for type of flag referred to */
38e71b7053SJung-uk Kim #define SSL_TFLAG_TYPE_MASK 0xf00
39e71b7053SJung-uk Kim /* Flag is for options */
40e71b7053SJung-uk Kim #define SSL_TFLAG_OPTION    0x000
41e71b7053SJung-uk Kim /* Flag is for cert_flags */
42e71b7053SJung-uk Kim #define SSL_TFLAG_CERT      0x100
43e71b7053SJung-uk Kim /* Flag is for verify mode */
44e71b7053SJung-uk Kim #define SSL_TFLAG_VFY       0x200
457bded2dbSJung-uk Kim /* Option can only be used for clients */
467bded2dbSJung-uk Kim #define SSL_TFLAG_CLIENT SSL_CONF_FLAG_CLIENT
477bded2dbSJung-uk Kim /* Option can only be used for servers */
487bded2dbSJung-uk Kim #define SSL_TFLAG_SERVER SSL_CONF_FLAG_SERVER
497bded2dbSJung-uk Kim #define SSL_TFLAG_BOTH (SSL_TFLAG_CLIENT|SSL_TFLAG_SERVER)
507bded2dbSJung-uk Kim 
517bded2dbSJung-uk Kim #define SSL_FLAG_TBL(str, flag) \
527bded2dbSJung-uk Kim         {str, (int)(sizeof(str) - 1), SSL_TFLAG_BOTH, flag}
537bded2dbSJung-uk Kim #define SSL_FLAG_TBL_SRV(str, flag) \
547bded2dbSJung-uk Kim         {str, (int)(sizeof(str) - 1), SSL_TFLAG_SERVER, flag}
557bded2dbSJung-uk Kim #define SSL_FLAG_TBL_CLI(str, flag) \
567bded2dbSJung-uk Kim         {str, (int)(sizeof(str) - 1), SSL_TFLAG_CLIENT, flag}
577bded2dbSJung-uk Kim #define SSL_FLAG_TBL_INV(str, flag) \
587bded2dbSJung-uk Kim         {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_BOTH, flag}
597bded2dbSJung-uk Kim #define SSL_FLAG_TBL_SRV_INV(str, flag) \
607bded2dbSJung-uk Kim         {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_SERVER, flag}
617bded2dbSJung-uk Kim #define SSL_FLAG_TBL_CERT(str, flag) \
627bded2dbSJung-uk Kim         {str, (int)(sizeof(str) - 1), SSL_TFLAG_CERT|SSL_TFLAG_BOTH, flag}
637bded2dbSJung-uk Kim 
64e71b7053SJung-uk Kim #define SSL_FLAG_VFY_CLI(str, flag) \
65e71b7053SJung-uk Kim         {str, (int)(sizeof(str) - 1), SSL_TFLAG_VFY | SSL_TFLAG_CLIENT, flag}
66e71b7053SJung-uk Kim #define SSL_FLAG_VFY_SRV(str, flag) \
67e71b7053SJung-uk Kim         {str, (int)(sizeof(str) - 1), SSL_TFLAG_VFY | SSL_TFLAG_SERVER, flag}
68e71b7053SJung-uk Kim 
697bded2dbSJung-uk Kim /*
707bded2dbSJung-uk Kim  * Opaque structure containing SSL configuration context.
717bded2dbSJung-uk Kim  */
727bded2dbSJung-uk Kim 
737bded2dbSJung-uk Kim struct ssl_conf_ctx_st {
747bded2dbSJung-uk Kim     /*
757bded2dbSJung-uk Kim      * Various flags indicating (among other things) which options we will
767bded2dbSJung-uk Kim      * recognise.
777bded2dbSJung-uk Kim      */
787bded2dbSJung-uk Kim     unsigned int flags;
797bded2dbSJung-uk Kim     /* Prefix and length of commands */
807bded2dbSJung-uk Kim     char *prefix;
817bded2dbSJung-uk Kim     size_t prefixlen;
827bded2dbSJung-uk Kim     /* SSL_CTX or SSL structure to perform operations on */
837bded2dbSJung-uk Kim     SSL_CTX *ctx;
847bded2dbSJung-uk Kim     SSL *ssl;
857bded2dbSJung-uk Kim     /* Pointer to SSL or SSL_CTX options field or NULL if none */
86e71b7053SJung-uk Kim     uint32_t *poptions;
87e71b7053SJung-uk Kim     /* Certificate filenames for each type */
88e71b7053SJung-uk Kim     char *cert_filename[SSL_PKEY_NUM];
897bded2dbSJung-uk Kim     /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */
90e71b7053SJung-uk Kim     uint32_t *pcert_flags;
91e71b7053SJung-uk Kim     /* Pointer to SSL or SSL_CTX verify_mode or NULL if none */
92e71b7053SJung-uk Kim     uint32_t *pvfy_flags;
93e71b7053SJung-uk Kim     /* Pointer to SSL or SSL_CTX min_version field or NULL if none */
94e71b7053SJung-uk Kim     int *min_version;
95e71b7053SJung-uk Kim     /* Pointer to SSL or SSL_CTX max_version field or NULL if none */
96e71b7053SJung-uk Kim     int *max_version;
977bded2dbSJung-uk Kim     /* Current flag table being worked on */
987bded2dbSJung-uk Kim     const ssl_flag_tbl *tbl;
997bded2dbSJung-uk Kim     /* Size of table */
1007bded2dbSJung-uk Kim     size_t ntbl;
101e71b7053SJung-uk Kim     /* Client CA names */
102e71b7053SJung-uk Kim     STACK_OF(X509_NAME) *canames;
1037bded2dbSJung-uk Kim };
1047bded2dbSJung-uk Kim 
105e71b7053SJung-uk Kim static void ssl_set_option(SSL_CONF_CTX *cctx, unsigned int name_flags,
106e71b7053SJung-uk Kim                            unsigned long option_value, int onoff)
107e71b7053SJung-uk Kim {
108e71b7053SJung-uk Kim     uint32_t *pflags;
109e71b7053SJung-uk Kim     if (cctx->poptions == NULL)
110e71b7053SJung-uk Kim         return;
111e71b7053SJung-uk Kim     if (name_flags & SSL_TFLAG_INV)
112e71b7053SJung-uk Kim         onoff ^= 1;
113e71b7053SJung-uk Kim     switch (name_flags & SSL_TFLAG_TYPE_MASK) {
114e71b7053SJung-uk Kim 
115e71b7053SJung-uk Kim     case SSL_TFLAG_CERT:
116e71b7053SJung-uk Kim         pflags = cctx->pcert_flags;
117e71b7053SJung-uk Kim         break;
118e71b7053SJung-uk Kim 
119e71b7053SJung-uk Kim     case SSL_TFLAG_VFY:
120e71b7053SJung-uk Kim         pflags = cctx->pvfy_flags;
121e71b7053SJung-uk Kim         break;
122e71b7053SJung-uk Kim 
123e71b7053SJung-uk Kim     case SSL_TFLAG_OPTION:
124e71b7053SJung-uk Kim         pflags = cctx->poptions;
125e71b7053SJung-uk Kim         break;
126e71b7053SJung-uk Kim 
127e71b7053SJung-uk Kim     default:
128e71b7053SJung-uk Kim         return;
129e71b7053SJung-uk Kim 
130e71b7053SJung-uk Kim     }
131e71b7053SJung-uk Kim     if (onoff)
132e71b7053SJung-uk Kim         *pflags |= option_value;
133e71b7053SJung-uk Kim     else
134e71b7053SJung-uk Kim         *pflags &= ~option_value;
135e71b7053SJung-uk Kim }
136e71b7053SJung-uk Kim 
1377bded2dbSJung-uk Kim static int ssl_match_option(SSL_CONF_CTX *cctx, const ssl_flag_tbl *tbl,
1387bded2dbSJung-uk Kim                             const char *name, int namelen, int onoff)
1397bded2dbSJung-uk Kim {
1407bded2dbSJung-uk Kim     /* If name not relevant for context skip */
1417bded2dbSJung-uk Kim     if (!(cctx->flags & tbl->name_flags & SSL_TFLAG_BOTH))
1427bded2dbSJung-uk Kim         return 0;
1437bded2dbSJung-uk Kim     if (namelen == -1) {
1447bded2dbSJung-uk Kim         if (strcmp(tbl->name, name))
1457bded2dbSJung-uk Kim             return 0;
146e71b7053SJung-uk Kim     } else if (tbl->namelen != namelen || strncasecmp(tbl->name, name, namelen))
1477bded2dbSJung-uk Kim         return 0;
148e71b7053SJung-uk Kim     ssl_set_option(cctx, tbl->name_flags, tbl->option_value, onoff);
1497bded2dbSJung-uk Kim     return 1;
1507bded2dbSJung-uk Kim }
1517bded2dbSJung-uk Kim 
1527bded2dbSJung-uk Kim static int ssl_set_option_list(const char *elem, int len, void *usr)
1537bded2dbSJung-uk Kim {
1547bded2dbSJung-uk Kim     SSL_CONF_CTX *cctx = usr;
1557bded2dbSJung-uk Kim     size_t i;
1567bded2dbSJung-uk Kim     const ssl_flag_tbl *tbl;
1577bded2dbSJung-uk Kim     int onoff = 1;
1587bded2dbSJung-uk Kim     /*
1597bded2dbSJung-uk Kim      * len == -1 indicates not being called in list context, just for single
1607bded2dbSJung-uk Kim      * command line switches, so don't allow +, -.
1617bded2dbSJung-uk Kim      */
1627bded2dbSJung-uk Kim     if (elem == NULL)
1637bded2dbSJung-uk Kim         return 0;
1647bded2dbSJung-uk Kim     if (len != -1) {
1657bded2dbSJung-uk Kim         if (*elem == '+') {
1667bded2dbSJung-uk Kim             elem++;
1677bded2dbSJung-uk Kim             len--;
1687bded2dbSJung-uk Kim             onoff = 1;
1697bded2dbSJung-uk Kim         } else if (*elem == '-') {
1707bded2dbSJung-uk Kim             elem++;
1717bded2dbSJung-uk Kim             len--;
1727bded2dbSJung-uk Kim             onoff = 0;
1737bded2dbSJung-uk Kim         }
1747bded2dbSJung-uk Kim     }
1757bded2dbSJung-uk Kim     for (i = 0, tbl = cctx->tbl; i < cctx->ntbl; i++, tbl++) {
1767bded2dbSJung-uk Kim         if (ssl_match_option(cctx, tbl, elem, len, onoff))
1777bded2dbSJung-uk Kim             return 1;
1787bded2dbSJung-uk Kim     }
1797bded2dbSJung-uk Kim     return 0;
1807bded2dbSJung-uk Kim }
1817bded2dbSJung-uk Kim 
1827bded2dbSJung-uk Kim /* Set supported signature algorithms */
1837bded2dbSJung-uk Kim static int cmd_SignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
1847bded2dbSJung-uk Kim {
1857bded2dbSJung-uk Kim     int rv;
1867bded2dbSJung-uk Kim     if (cctx->ssl)
1877bded2dbSJung-uk Kim         rv = SSL_set1_sigalgs_list(cctx->ssl, value);
1887bded2dbSJung-uk Kim     /* NB: ctx == NULL performs syntax checking only */
1897bded2dbSJung-uk Kim     else
1907bded2dbSJung-uk Kim         rv = SSL_CTX_set1_sigalgs_list(cctx->ctx, value);
1917bded2dbSJung-uk Kim     return rv > 0;
1927bded2dbSJung-uk Kim }
1937bded2dbSJung-uk Kim 
1947bded2dbSJung-uk Kim /* Set supported client signature algorithms */
195e71b7053SJung-uk Kim static int cmd_ClientSignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
1967bded2dbSJung-uk Kim {
1977bded2dbSJung-uk Kim     int rv;
1987bded2dbSJung-uk Kim     if (cctx->ssl)
1997bded2dbSJung-uk Kim         rv = SSL_set1_client_sigalgs_list(cctx->ssl, value);
2007bded2dbSJung-uk Kim     /* NB: ctx == NULL performs syntax checking only */
2017bded2dbSJung-uk Kim     else
2027bded2dbSJung-uk Kim         rv = SSL_CTX_set1_client_sigalgs_list(cctx->ctx, value);
2037bded2dbSJung-uk Kim     return rv > 0;
2047bded2dbSJung-uk Kim }
2057bded2dbSJung-uk Kim 
206e71b7053SJung-uk Kim static int cmd_Groups(SSL_CONF_CTX *cctx, const char *value)
2077bded2dbSJung-uk Kim {
2087bded2dbSJung-uk Kim     int rv;
2097bded2dbSJung-uk Kim     if (cctx->ssl)
210e71b7053SJung-uk Kim         rv = SSL_set1_groups_list(cctx->ssl, value);
2117bded2dbSJung-uk Kim     /* NB: ctx == NULL performs syntax checking only */
2127bded2dbSJung-uk Kim     else
213e71b7053SJung-uk Kim         rv = SSL_CTX_set1_groups_list(cctx->ctx, value);
2147bded2dbSJung-uk Kim     return rv > 0;
2157bded2dbSJung-uk Kim }
2167bded2dbSJung-uk Kim 
217e71b7053SJung-uk Kim /* This is the old name for cmd_Groups - retained for backwards compatibility */
218e71b7053SJung-uk Kim static int cmd_Curves(SSL_CONF_CTX *cctx, const char *value)
219e71b7053SJung-uk Kim {
220e71b7053SJung-uk Kim     return cmd_Groups(cctx, value);
221e71b7053SJung-uk Kim }
222e71b7053SJung-uk Kim 
223e71b7053SJung-uk Kim #ifndef OPENSSL_NO_EC
2247bded2dbSJung-uk Kim /* ECDH temporary parameters */
2257bded2dbSJung-uk Kim static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value)
2267bded2dbSJung-uk Kim {
227e71b7053SJung-uk Kim     int rv = 1;
2287bded2dbSJung-uk Kim     EC_KEY *ecdh;
2297bded2dbSJung-uk Kim     int nid;
230e71b7053SJung-uk Kim 
231e71b7053SJung-uk Kim     /* Ignore values supported by 1.0.2 for the automatic selection */
232e71b7053SJung-uk Kim     if ((cctx->flags & SSL_CONF_FLAG_FILE)
233e71b7053SJung-uk Kim             && (strcasecmp(value, "+automatic") == 0
234e71b7053SJung-uk Kim                 || strcasecmp(value, "automatic") == 0))
235e71b7053SJung-uk Kim         return 1;
236e71b7053SJung-uk Kim     if ((cctx->flags & SSL_CONF_FLAG_CMDLINE) &&
237e71b7053SJung-uk Kim         strcmp(value, "auto") == 0)
238e71b7053SJung-uk Kim         return 1;
239e71b7053SJung-uk Kim 
2407bded2dbSJung-uk Kim     nid = EC_curve_nist2nid(value);
2417bded2dbSJung-uk Kim     if (nid == NID_undef)
2427bded2dbSJung-uk Kim         nid = OBJ_sn2nid(value);
2437bded2dbSJung-uk Kim     if (nid == 0)
2447bded2dbSJung-uk Kim         return 0;
2457bded2dbSJung-uk Kim     ecdh = EC_KEY_new_by_curve_name(nid);
2467bded2dbSJung-uk Kim     if (!ecdh)
2477bded2dbSJung-uk Kim         return 0;
2487bded2dbSJung-uk Kim     if (cctx->ctx)
2497bded2dbSJung-uk Kim         rv = SSL_CTX_set_tmp_ecdh(cctx->ctx, ecdh);
2507bded2dbSJung-uk Kim     else if (cctx->ssl)
2517bded2dbSJung-uk Kim         rv = SSL_set_tmp_ecdh(cctx->ssl, ecdh);
2527bded2dbSJung-uk Kim     EC_KEY_free(ecdh);
2537bded2dbSJung-uk Kim 
2547bded2dbSJung-uk Kim     return rv > 0;
2557bded2dbSJung-uk Kim }
2567bded2dbSJung-uk Kim #endif
2577bded2dbSJung-uk Kim static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value)
2587bded2dbSJung-uk Kim {
2597bded2dbSJung-uk Kim     int rv = 1;
260e71b7053SJung-uk Kim 
2617bded2dbSJung-uk Kim     if (cctx->ctx)
2627bded2dbSJung-uk Kim         rv = SSL_CTX_set_cipher_list(cctx->ctx, value);
2637bded2dbSJung-uk Kim     if (cctx->ssl)
2647bded2dbSJung-uk Kim         rv = SSL_set_cipher_list(cctx->ssl, value);
2657bded2dbSJung-uk Kim     return rv > 0;
2667bded2dbSJung-uk Kim }
2677bded2dbSJung-uk Kim 
268e71b7053SJung-uk Kim static int cmd_Ciphersuites(SSL_CONF_CTX *cctx, const char *value)
269e71b7053SJung-uk Kim {
270e71b7053SJung-uk Kim     int rv = 1;
271e71b7053SJung-uk Kim 
272e71b7053SJung-uk Kim     if (cctx->ctx)
273e71b7053SJung-uk Kim         rv = SSL_CTX_set_ciphersuites(cctx->ctx, value);
274e71b7053SJung-uk Kim     if (cctx->ssl)
275e71b7053SJung-uk Kim         rv = SSL_set_ciphersuites(cctx->ssl, value);
276e71b7053SJung-uk Kim     return rv > 0;
277e71b7053SJung-uk Kim }
278e71b7053SJung-uk Kim 
2797bded2dbSJung-uk Kim static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value)
2807bded2dbSJung-uk Kim {
2817bded2dbSJung-uk Kim     static const ssl_flag_tbl ssl_protocol_list[] = {
2827bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK),
2837bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("SSLv2", SSL_OP_NO_SSLv2),
2847bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3),
2857bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1),
2867bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1),
287e71b7053SJung-uk Kim         SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2),
288e71b7053SJung-uk Kim         SSL_FLAG_TBL_INV("TLSv1.3", SSL_OP_NO_TLSv1_3),
289e71b7053SJung-uk Kim         SSL_FLAG_TBL_INV("DTLSv1", SSL_OP_NO_DTLSv1),
290e71b7053SJung-uk Kim         SSL_FLAG_TBL_INV("DTLSv1.2", SSL_OP_NO_DTLSv1_2)
2917bded2dbSJung-uk Kim     };
2927bded2dbSJung-uk Kim     cctx->tbl = ssl_protocol_list;
293e71b7053SJung-uk Kim     cctx->ntbl = OSSL_NELEM(ssl_protocol_list);
294e71b7053SJung-uk Kim     return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
295e71b7053SJung-uk Kim }
2964c6a0400SJung-uk Kim 
297e71b7053SJung-uk Kim /*
298e71b7053SJung-uk Kim  * protocol_from_string - converts a protocol version string to a number
299e71b7053SJung-uk Kim  *
300e71b7053SJung-uk Kim  * Returns -1 on failure or the version on success
301e71b7053SJung-uk Kim  */
302e71b7053SJung-uk Kim static int protocol_from_string(const char *value)
303e71b7053SJung-uk Kim {
304e71b7053SJung-uk Kim     struct protocol_versions {
305e71b7053SJung-uk Kim         const char *name;
306e71b7053SJung-uk Kim         int version;
307e71b7053SJung-uk Kim     };
308*58f35182SJung-uk Kim     /*
309*58f35182SJung-uk Kim      * Note: To avoid breaking previously valid configurations, we must retain
310*58f35182SJung-uk Kim      * legacy entries in this table even if the underlying protocol is no
311*58f35182SJung-uk Kim      * longer supported.  This also means that the constants SSL3_VERSION, ...
312*58f35182SJung-uk Kim      * need to be retained indefinitely.  This table can only grow, never
313*58f35182SJung-uk Kim      * shrink.
314*58f35182SJung-uk Kim      */
315e71b7053SJung-uk Kim     static const struct protocol_versions versions[] = {
316e71b7053SJung-uk Kim         {"None", 0},
317e71b7053SJung-uk Kim         {"SSLv3", SSL3_VERSION},
318e71b7053SJung-uk Kim         {"TLSv1", TLS1_VERSION},
319e71b7053SJung-uk Kim         {"TLSv1.1", TLS1_1_VERSION},
320e71b7053SJung-uk Kim         {"TLSv1.2", TLS1_2_VERSION},
321e71b7053SJung-uk Kim         {"TLSv1.3", TLS1_3_VERSION},
322e71b7053SJung-uk Kim         {"DTLSv1", DTLS1_VERSION},
323e71b7053SJung-uk Kim         {"DTLSv1.2", DTLS1_2_VERSION}
324e71b7053SJung-uk Kim     };
325e71b7053SJung-uk Kim     size_t i;
326e71b7053SJung-uk Kim     size_t n = OSSL_NELEM(versions);
327e71b7053SJung-uk Kim 
328e71b7053SJung-uk Kim     for (i = 0; i < n; i++)
329e71b7053SJung-uk Kim         if (strcmp(versions[i].name, value) == 0)
330e71b7053SJung-uk Kim             return versions[i].version;
331e71b7053SJung-uk Kim     return -1;
332e71b7053SJung-uk Kim }
333e71b7053SJung-uk Kim 
334e71b7053SJung-uk Kim static int min_max_proto(SSL_CONF_CTX *cctx, const char *value, int *bound)
335e71b7053SJung-uk Kim {
336e71b7053SJung-uk Kim     int method_version;
337e71b7053SJung-uk Kim     int new_version;
338e71b7053SJung-uk Kim 
339e71b7053SJung-uk Kim     if (cctx->ctx != NULL)
340e71b7053SJung-uk Kim         method_version = cctx->ctx->method->version;
341e71b7053SJung-uk Kim     else if (cctx->ssl != NULL)
342e71b7053SJung-uk Kim         method_version = cctx->ssl->ctx->method->version;
343e71b7053SJung-uk Kim     else
344e71b7053SJung-uk Kim         return 0;
345e71b7053SJung-uk Kim     if ((new_version = protocol_from_string(value)) < 0)
346e71b7053SJung-uk Kim         return 0;
347e71b7053SJung-uk Kim     return ssl_set_version_bound(method_version, new_version, bound);
348e71b7053SJung-uk Kim }
349e71b7053SJung-uk Kim 
350e71b7053SJung-uk Kim /*
351e71b7053SJung-uk Kim  * cmd_MinProtocol - Set min protocol version
352e71b7053SJung-uk Kim  * @cctx: config structure to save settings in
353e71b7053SJung-uk Kim  * @value: The min protocol version in string form
354e71b7053SJung-uk Kim  *
355e71b7053SJung-uk Kim  * Returns 1 on success and 0 on failure.
356e71b7053SJung-uk Kim  */
357e71b7053SJung-uk Kim static int cmd_MinProtocol(SSL_CONF_CTX *cctx, const char *value)
358e71b7053SJung-uk Kim {
359e71b7053SJung-uk Kim     return min_max_proto(cctx, value, cctx->min_version);
360e71b7053SJung-uk Kim }
361e71b7053SJung-uk Kim 
362e71b7053SJung-uk Kim /*
363e71b7053SJung-uk Kim  * cmd_MaxProtocol - Set max protocol version
364e71b7053SJung-uk Kim  * @cctx: config structure to save settings in
365e71b7053SJung-uk Kim  * @value: The max protocol version in string form
366e71b7053SJung-uk Kim  *
367e71b7053SJung-uk Kim  * Returns 1 on success and 0 on failure.
368e71b7053SJung-uk Kim  */
369e71b7053SJung-uk Kim static int cmd_MaxProtocol(SSL_CONF_CTX *cctx, const char *value)
370e71b7053SJung-uk Kim {
371e71b7053SJung-uk Kim     return min_max_proto(cctx, value, cctx->max_version);
3727bded2dbSJung-uk Kim }
3737bded2dbSJung-uk Kim 
3747bded2dbSJung-uk Kim static int cmd_Options(SSL_CONF_CTX *cctx, const char *value)
3757bded2dbSJung-uk Kim {
3767bded2dbSJung-uk Kim     static const ssl_flag_tbl ssl_option_list[] = {
3777bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET),
3787bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("EmptyFragments",
3797bded2dbSJung-uk Kim                          SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS),
3807bded2dbSJung-uk Kim         SSL_FLAG_TBL("Bugs", SSL_OP_ALL),
3817bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION),
3827bded2dbSJung-uk Kim         SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE),
3837bded2dbSJung-uk Kim         SSL_FLAG_TBL_SRV("NoResumptionOnRenegotiation",
3847bded2dbSJung-uk Kim                          SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION),
3857bded2dbSJung-uk Kim         SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE),
3867bded2dbSJung-uk Kim         SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE),
3877bded2dbSJung-uk Kim         SSL_FLAG_TBL("UnsafeLegacyRenegotiation",
3887bded2dbSJung-uk Kim                      SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION),
389e71b7053SJung-uk Kim         SSL_FLAG_TBL_INV("EncryptThenMac", SSL_OP_NO_ENCRYPT_THEN_MAC),
390e71b7053SJung-uk Kim         SSL_FLAG_TBL("NoRenegotiation", SSL_OP_NO_RENEGOTIATION),
391e71b7053SJung-uk Kim         SSL_FLAG_TBL("AllowNoDHEKEX", SSL_OP_ALLOW_NO_DHE_KEX),
392e71b7053SJung-uk Kim         SSL_FLAG_TBL("PrioritizeChaCha", SSL_OP_PRIORITIZE_CHACHA),
393e71b7053SJung-uk Kim         SSL_FLAG_TBL("MiddleboxCompat", SSL_OP_ENABLE_MIDDLEBOX_COMPAT),
394e71b7053SJung-uk Kim         SSL_FLAG_TBL_INV("AntiReplay", SSL_OP_NO_ANTI_REPLAY)
3957bded2dbSJung-uk Kim     };
3967bded2dbSJung-uk Kim     if (value == NULL)
3977bded2dbSJung-uk Kim         return -3;
3987bded2dbSJung-uk Kim     cctx->tbl = ssl_option_list;
399e71b7053SJung-uk Kim     cctx->ntbl = OSSL_NELEM(ssl_option_list);
400e71b7053SJung-uk Kim     return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
401e71b7053SJung-uk Kim }
402e71b7053SJung-uk Kim 
403e71b7053SJung-uk Kim static int cmd_VerifyMode(SSL_CONF_CTX *cctx, const char *value)
404e71b7053SJung-uk Kim {
405e71b7053SJung-uk Kim     static const ssl_flag_tbl ssl_vfy_list[] = {
406e71b7053SJung-uk Kim         SSL_FLAG_VFY_CLI("Peer", SSL_VERIFY_PEER),
407e71b7053SJung-uk Kim         SSL_FLAG_VFY_SRV("Request", SSL_VERIFY_PEER),
408e71b7053SJung-uk Kim         SSL_FLAG_VFY_SRV("Require",
409e71b7053SJung-uk Kim                          SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT),
410e71b7053SJung-uk Kim         SSL_FLAG_VFY_SRV("Once", SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE),
411e71b7053SJung-uk Kim         SSL_FLAG_VFY_SRV("RequestPostHandshake",
412e71b7053SJung-uk Kim                          SSL_VERIFY_PEER | SSL_VERIFY_POST_HANDSHAKE),
413e71b7053SJung-uk Kim         SSL_FLAG_VFY_SRV("RequirePostHandshake",
414e71b7053SJung-uk Kim                          SSL_VERIFY_PEER | SSL_VERIFY_POST_HANDSHAKE |
415e71b7053SJung-uk Kim                          SSL_VERIFY_FAIL_IF_NO_PEER_CERT),
416e71b7053SJung-uk Kim     };
417e71b7053SJung-uk Kim     if (value == NULL)
418e71b7053SJung-uk Kim         return -3;
419e71b7053SJung-uk Kim     cctx->tbl = ssl_vfy_list;
420e71b7053SJung-uk Kim     cctx->ntbl = OSSL_NELEM(ssl_vfy_list);
4217bded2dbSJung-uk Kim     return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
4227bded2dbSJung-uk Kim }
4237bded2dbSJung-uk Kim 
4247bded2dbSJung-uk Kim static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value)
4257bded2dbSJung-uk Kim {
4267bded2dbSJung-uk Kim     int rv = 1;
427e71b7053SJung-uk Kim     CERT *c = NULL;
428e71b7053SJung-uk Kim     if (cctx->ctx) {
4297bded2dbSJung-uk Kim         rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value);
430e71b7053SJung-uk Kim         c = cctx->ctx->cert;
431e71b7053SJung-uk Kim     }
432e71b7053SJung-uk Kim     if (cctx->ssl) {
433e71b7053SJung-uk Kim         rv = SSL_use_certificate_chain_file(cctx->ssl, value);
434e71b7053SJung-uk Kim         c = cctx->ssl->cert;
435e71b7053SJung-uk Kim     }
436e71b7053SJung-uk Kim     if (rv > 0 && c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
437e71b7053SJung-uk Kim         char **pfilename = &cctx->cert_filename[c->key - c->pkeys];
438e71b7053SJung-uk Kim         OPENSSL_free(*pfilename);
439e71b7053SJung-uk Kim         *pfilename = OPENSSL_strdup(value);
440e71b7053SJung-uk Kim         if (!*pfilename)
441e71b7053SJung-uk Kim             rv = 0;
442e71b7053SJung-uk Kim     }
443e71b7053SJung-uk Kim 
4447bded2dbSJung-uk Kim     return rv > 0;
4457bded2dbSJung-uk Kim }
4467bded2dbSJung-uk Kim 
4477bded2dbSJung-uk Kim static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value)
4487bded2dbSJung-uk Kim {
4497bded2dbSJung-uk Kim     int rv = 1;
4507bded2dbSJung-uk Kim     if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
4517bded2dbSJung-uk Kim         return -2;
4527bded2dbSJung-uk Kim     if (cctx->ctx)
4537bded2dbSJung-uk Kim         rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM);
4547bded2dbSJung-uk Kim     if (cctx->ssl)
4557bded2dbSJung-uk Kim         rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM);
4567bded2dbSJung-uk Kim     return rv > 0;
4577bded2dbSJung-uk Kim }
4587bded2dbSJung-uk Kim 
4597bded2dbSJung-uk Kim static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value)
4607bded2dbSJung-uk Kim {
4617bded2dbSJung-uk Kim     int rv = 1;
4627bded2dbSJung-uk Kim     if (cctx->ctx)
4637bded2dbSJung-uk Kim         rv = SSL_CTX_use_serverinfo_file(cctx->ctx, value);
4647bded2dbSJung-uk Kim     return rv > 0;
4657bded2dbSJung-uk Kim }
4667bded2dbSJung-uk Kim 
467e71b7053SJung-uk Kim static int do_store(SSL_CONF_CTX *cctx,
468e71b7053SJung-uk Kim                     const char *CAfile, const char *CApath, int verify_store)
469e71b7053SJung-uk Kim {
470e71b7053SJung-uk Kim     CERT *cert;
471e71b7053SJung-uk Kim     X509_STORE **st;
472e71b7053SJung-uk Kim     if (cctx->ctx)
473e71b7053SJung-uk Kim         cert = cctx->ctx->cert;
474e71b7053SJung-uk Kim     else if (cctx->ssl)
475e71b7053SJung-uk Kim         cert = cctx->ssl->cert;
476e71b7053SJung-uk Kim     else
477e71b7053SJung-uk Kim         return 1;
478e71b7053SJung-uk Kim     st = verify_store ? &cert->verify_store : &cert->chain_store;
479e71b7053SJung-uk Kim     if (*st == NULL) {
480e71b7053SJung-uk Kim         *st = X509_STORE_new();
481e71b7053SJung-uk Kim         if (*st == NULL)
482e71b7053SJung-uk Kim             return 0;
483e71b7053SJung-uk Kim     }
484e71b7053SJung-uk Kim     return X509_STORE_load_locations(*st, CAfile, CApath) > 0;
485e71b7053SJung-uk Kim }
486e71b7053SJung-uk Kim 
487e71b7053SJung-uk Kim static int cmd_ChainCAPath(SSL_CONF_CTX *cctx, const char *value)
488e71b7053SJung-uk Kim {
489e71b7053SJung-uk Kim     return do_store(cctx, NULL, value, 0);
490e71b7053SJung-uk Kim }
491e71b7053SJung-uk Kim 
492e71b7053SJung-uk Kim static int cmd_ChainCAFile(SSL_CONF_CTX *cctx, const char *value)
493e71b7053SJung-uk Kim {
494e71b7053SJung-uk Kim     return do_store(cctx, value, NULL, 0);
495e71b7053SJung-uk Kim }
496e71b7053SJung-uk Kim 
497e71b7053SJung-uk Kim static int cmd_VerifyCAPath(SSL_CONF_CTX *cctx, const char *value)
498e71b7053SJung-uk Kim {
499e71b7053SJung-uk Kim     return do_store(cctx, NULL, value, 1);
500e71b7053SJung-uk Kim }
501e71b7053SJung-uk Kim 
502e71b7053SJung-uk Kim static int cmd_VerifyCAFile(SSL_CONF_CTX *cctx, const char *value)
503e71b7053SJung-uk Kim {
504e71b7053SJung-uk Kim     return do_store(cctx, value, NULL, 1);
505e71b7053SJung-uk Kim }
506e71b7053SJung-uk Kim 
507e71b7053SJung-uk Kim static int cmd_RequestCAFile(SSL_CONF_CTX *cctx, const char *value)
508e71b7053SJung-uk Kim {
509e71b7053SJung-uk Kim     if (cctx->canames == NULL)
510e71b7053SJung-uk Kim         cctx->canames = sk_X509_NAME_new_null();
511e71b7053SJung-uk Kim     if (cctx->canames == NULL)
512e71b7053SJung-uk Kim         return 0;
513e71b7053SJung-uk Kim     return SSL_add_file_cert_subjects_to_stack(cctx->canames, value);
514e71b7053SJung-uk Kim }
515e71b7053SJung-uk Kim 
516e71b7053SJung-uk Kim static int cmd_ClientCAFile(SSL_CONF_CTX *cctx, const char *value)
517e71b7053SJung-uk Kim {
518e71b7053SJung-uk Kim     return cmd_RequestCAFile(cctx, value);
519e71b7053SJung-uk Kim }
520e71b7053SJung-uk Kim 
521e71b7053SJung-uk Kim static int cmd_RequestCAPath(SSL_CONF_CTX *cctx, const char *value)
522e71b7053SJung-uk Kim {
523e71b7053SJung-uk Kim     if (cctx->canames == NULL)
524e71b7053SJung-uk Kim         cctx->canames = sk_X509_NAME_new_null();
525e71b7053SJung-uk Kim     if (cctx->canames == NULL)
526e71b7053SJung-uk Kim         return 0;
527e71b7053SJung-uk Kim     return SSL_add_dir_cert_subjects_to_stack(cctx->canames, value);
528e71b7053SJung-uk Kim }
529e71b7053SJung-uk Kim 
530e71b7053SJung-uk Kim static int cmd_ClientCAPath(SSL_CONF_CTX *cctx, const char *value)
531e71b7053SJung-uk Kim {
532e71b7053SJung-uk Kim     return cmd_RequestCAPath(cctx, value);
533e71b7053SJung-uk Kim }
534e71b7053SJung-uk Kim 
5357bded2dbSJung-uk Kim #ifndef OPENSSL_NO_DH
5367bded2dbSJung-uk Kim static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value)
5377bded2dbSJung-uk Kim {
5387bded2dbSJung-uk Kim     int rv = 0;
5397bded2dbSJung-uk Kim     DH *dh = NULL;
5407bded2dbSJung-uk Kim     BIO *in = NULL;
5417bded2dbSJung-uk Kim     if (cctx->ctx || cctx->ssl) {
542e71b7053SJung-uk Kim         in = BIO_new(BIO_s_file());
543e71b7053SJung-uk Kim         if (in == NULL)
5447bded2dbSJung-uk Kim             goto end;
5457bded2dbSJung-uk Kim         if (BIO_read_filename(in, value) <= 0)
5467bded2dbSJung-uk Kim             goto end;
5477bded2dbSJung-uk Kim         dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
548e71b7053SJung-uk Kim         if (dh == NULL)
5497bded2dbSJung-uk Kim             goto end;
5507bded2dbSJung-uk Kim     } else
5517bded2dbSJung-uk Kim         return 1;
5527bded2dbSJung-uk Kim     if (cctx->ctx)
5537bded2dbSJung-uk Kim         rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh);
5547bded2dbSJung-uk Kim     if (cctx->ssl)
5557bded2dbSJung-uk Kim         rv = SSL_set_tmp_dh(cctx->ssl, dh);
5567bded2dbSJung-uk Kim  end:
5577bded2dbSJung-uk Kim     DH_free(dh);
5587bded2dbSJung-uk Kim     BIO_free(in);
5597bded2dbSJung-uk Kim     return rv > 0;
5607bded2dbSJung-uk Kim }
5617bded2dbSJung-uk Kim #endif
562e71b7053SJung-uk Kim 
563e71b7053SJung-uk Kim static int cmd_RecordPadding(SSL_CONF_CTX *cctx, const char *value)
564e71b7053SJung-uk Kim {
565e71b7053SJung-uk Kim     int rv = 0;
566e71b7053SJung-uk Kim     int block_size = atoi(value);
567e71b7053SJung-uk Kim 
568e71b7053SJung-uk Kim     /*
569e71b7053SJung-uk Kim      * All we care about is a non-negative value,
570e71b7053SJung-uk Kim      * the setters check the range
571e71b7053SJung-uk Kim      */
572e71b7053SJung-uk Kim     if (block_size >= 0) {
573e71b7053SJung-uk Kim         if (cctx->ctx)
574e71b7053SJung-uk Kim             rv = SSL_CTX_set_block_padding(cctx->ctx, block_size);
575e71b7053SJung-uk Kim         if (cctx->ssl)
576e71b7053SJung-uk Kim             rv = SSL_set_block_padding(cctx->ssl, block_size);
577e71b7053SJung-uk Kim     }
578e71b7053SJung-uk Kim     return rv;
579e71b7053SJung-uk Kim }
580e71b7053SJung-uk Kim 
581e71b7053SJung-uk Kim 
582e71b7053SJung-uk Kim static int cmd_NumTickets(SSL_CONF_CTX *cctx, const char *value)
583e71b7053SJung-uk Kim {
584e71b7053SJung-uk Kim     int rv = 0;
585e71b7053SJung-uk Kim     int num_tickets = atoi(value);
586e71b7053SJung-uk Kim 
587e71b7053SJung-uk Kim     if (num_tickets >= 0) {
588e71b7053SJung-uk Kim         if (cctx->ctx)
589e71b7053SJung-uk Kim             rv = SSL_CTX_set_num_tickets(cctx->ctx, num_tickets);
590e71b7053SJung-uk Kim         if (cctx->ssl)
591e71b7053SJung-uk Kim             rv = SSL_set_num_tickets(cctx->ssl, num_tickets);
592e71b7053SJung-uk Kim     }
593e71b7053SJung-uk Kim     return rv;
594e71b7053SJung-uk Kim }
595e71b7053SJung-uk Kim 
5967bded2dbSJung-uk Kim typedef struct {
5977bded2dbSJung-uk Kim     int (*cmd) (SSL_CONF_CTX *cctx, const char *value);
5987bded2dbSJung-uk Kim     const char *str_file;
5997bded2dbSJung-uk Kim     const char *str_cmdline;
600e71b7053SJung-uk Kim     unsigned short flags;
601e71b7053SJung-uk Kim     unsigned short value_type;
6027bded2dbSJung-uk Kim } ssl_conf_cmd_tbl;
6037bded2dbSJung-uk Kim 
6047bded2dbSJung-uk Kim /* Table of supported parameters */
6057bded2dbSJung-uk Kim 
606e71b7053SJung-uk Kim #define SSL_CONF_CMD(name, cmdopt, flags, type) \
607e71b7053SJung-uk Kim         {cmd_##name, #name, cmdopt, flags, type}
6087bded2dbSJung-uk Kim 
609e71b7053SJung-uk Kim #define SSL_CONF_CMD_STRING(name, cmdopt, flags) \
610e71b7053SJung-uk Kim         SSL_CONF_CMD(name, cmdopt, flags, SSL_CONF_TYPE_STRING)
6117bded2dbSJung-uk Kim 
612e71b7053SJung-uk Kim #define SSL_CONF_CMD_SWITCH(name, flags) \
613e71b7053SJung-uk Kim         {0, NULL, name, flags, SSL_CONF_TYPE_NONE}
614e71b7053SJung-uk Kim 
615e71b7053SJung-uk Kim /* See apps/apps.h if you change this table. */
6167bded2dbSJung-uk Kim static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
617e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("no_ssl3", 0),
618e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("no_tls1", 0),
619e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("no_tls1_1", 0),
620e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("no_tls1_2", 0),
621e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("no_tls1_3", 0),
622e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("bugs", 0),
623e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("no_comp", 0),
624e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("comp", 0),
625e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("ecdh_single", SSL_CONF_FLAG_SERVER),
626e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("no_ticket", 0),
627e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("serverpref", SSL_CONF_FLAG_SERVER),
628e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("legacy_renegotiation", 0),
629e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("legacy_server_connect", SSL_CONF_FLAG_SERVER),
630e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("no_renegotiation", 0),
631e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("no_resumption_on_reneg", SSL_CONF_FLAG_SERVER),
632e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("no_legacy_server_connect", SSL_CONF_FLAG_SERVER),
633e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("allow_no_dhe_kex", 0),
634e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("prioritize_chacha", SSL_CONF_FLAG_SERVER),
635e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("strict", 0),
636e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("no_middlebox", 0),
637e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("anti_replay", SSL_CONF_FLAG_SERVER),
638e71b7053SJung-uk Kim     SSL_CONF_CMD_SWITCH("no_anti_replay", SSL_CONF_FLAG_SERVER),
639e71b7053SJung-uk Kim     SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs", 0),
640e71b7053SJung-uk Kim     SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs", 0),
641e71b7053SJung-uk Kim     SSL_CONF_CMD_STRING(Curves, "curves", 0),
642e71b7053SJung-uk Kim     SSL_CONF_CMD_STRING(Groups, "groups", 0),
643e71b7053SJung-uk Kim #ifndef OPENSSL_NO_EC
644e71b7053SJung-uk Kim     SSL_CONF_CMD_STRING(ECDHParameters, "named_curve", SSL_CONF_FLAG_SERVER),
6457bded2dbSJung-uk Kim #endif
646e71b7053SJung-uk Kim     SSL_CONF_CMD_STRING(CipherString, "cipher", 0),
647e71b7053SJung-uk Kim     SSL_CONF_CMD_STRING(Ciphersuites, "ciphersuites", 0),
648e71b7053SJung-uk Kim     SSL_CONF_CMD_STRING(Protocol, NULL, 0),
649e71b7053SJung-uk Kim     SSL_CONF_CMD_STRING(MinProtocol, "min_protocol", 0),
650e71b7053SJung-uk Kim     SSL_CONF_CMD_STRING(MaxProtocol, "max_protocol", 0),
651e71b7053SJung-uk Kim     SSL_CONF_CMD_STRING(Options, NULL, 0),
652e71b7053SJung-uk Kim     SSL_CONF_CMD_STRING(VerifyMode, NULL, 0),
653e71b7053SJung-uk Kim     SSL_CONF_CMD(Certificate, "cert", SSL_CONF_FLAG_CERTIFICATE,
654e71b7053SJung-uk Kim                  SSL_CONF_TYPE_FILE),
655e71b7053SJung-uk Kim     SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_FLAG_CERTIFICATE,
656e71b7053SJung-uk Kim                  SSL_CONF_TYPE_FILE),
657e71b7053SJung-uk Kim     SSL_CONF_CMD(ServerInfoFile, NULL,
658e71b7053SJung-uk Kim                  SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
659e71b7053SJung-uk Kim                  SSL_CONF_TYPE_FILE),
660e71b7053SJung-uk Kim     SSL_CONF_CMD(ChainCAPath, "chainCApath", SSL_CONF_FLAG_CERTIFICATE,
661e71b7053SJung-uk Kim                  SSL_CONF_TYPE_DIR),
662e71b7053SJung-uk Kim     SSL_CONF_CMD(ChainCAFile, "chainCAfile", SSL_CONF_FLAG_CERTIFICATE,
663e71b7053SJung-uk Kim                  SSL_CONF_TYPE_FILE),
664e71b7053SJung-uk Kim     SSL_CONF_CMD(VerifyCAPath, "verifyCApath", SSL_CONF_FLAG_CERTIFICATE,
665e71b7053SJung-uk Kim                  SSL_CONF_TYPE_DIR),
666e71b7053SJung-uk Kim     SSL_CONF_CMD(VerifyCAFile, "verifyCAfile", SSL_CONF_FLAG_CERTIFICATE,
667e71b7053SJung-uk Kim                  SSL_CONF_TYPE_FILE),
668e71b7053SJung-uk Kim     SSL_CONF_CMD(RequestCAFile, "requestCAFile", SSL_CONF_FLAG_CERTIFICATE,
669e71b7053SJung-uk Kim                  SSL_CONF_TYPE_FILE),
670e71b7053SJung-uk Kim     SSL_CONF_CMD(ClientCAFile, NULL,
671e71b7053SJung-uk Kim                  SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
672e71b7053SJung-uk Kim                  SSL_CONF_TYPE_FILE),
673e71b7053SJung-uk Kim     SSL_CONF_CMD(RequestCAPath, NULL, SSL_CONF_FLAG_CERTIFICATE,
674e71b7053SJung-uk Kim                  SSL_CONF_TYPE_DIR),
675e71b7053SJung-uk Kim     SSL_CONF_CMD(ClientCAPath, NULL,
676e71b7053SJung-uk Kim                  SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
677e71b7053SJung-uk Kim                  SSL_CONF_TYPE_DIR),
6787bded2dbSJung-uk Kim #ifndef OPENSSL_NO_DH
679e71b7053SJung-uk Kim     SSL_CONF_CMD(DHParameters, "dhparam",
680e71b7053SJung-uk Kim                  SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
681e71b7053SJung-uk Kim                  SSL_CONF_TYPE_FILE),
6827bded2dbSJung-uk Kim #endif
683e71b7053SJung-uk Kim     SSL_CONF_CMD_STRING(RecordPadding, "record_padding", 0),
684e71b7053SJung-uk Kim     SSL_CONF_CMD_STRING(NumTickets, "num_tickets", SSL_CONF_FLAG_SERVER),
685e71b7053SJung-uk Kim };
686e71b7053SJung-uk Kim 
687e71b7053SJung-uk Kim /* Supported switches: must match order of switches in ssl_conf_cmds */
688e71b7053SJung-uk Kim static const ssl_switch_tbl ssl_cmd_switches[] = {
689e71b7053SJung-uk Kim     {SSL_OP_NO_SSLv3, 0},       /* no_ssl3 */
690e71b7053SJung-uk Kim     {SSL_OP_NO_TLSv1, 0},       /* no_tls1 */
691e71b7053SJung-uk Kim     {SSL_OP_NO_TLSv1_1, 0},     /* no_tls1_1 */
692e71b7053SJung-uk Kim     {SSL_OP_NO_TLSv1_2, 0},     /* no_tls1_2 */
693e71b7053SJung-uk Kim     {SSL_OP_NO_TLSv1_3, 0},     /* no_tls1_3 */
694e71b7053SJung-uk Kim     {SSL_OP_ALL, 0},            /* bugs */
695e71b7053SJung-uk Kim     {SSL_OP_NO_COMPRESSION, 0}, /* no_comp */
696e71b7053SJung-uk Kim     {SSL_OP_NO_COMPRESSION, SSL_TFLAG_INV}, /* comp */
697e71b7053SJung-uk Kim     {SSL_OP_SINGLE_ECDH_USE, 0}, /* ecdh_single */
698e71b7053SJung-uk Kim     {SSL_OP_NO_TICKET, 0},      /* no_ticket */
699e71b7053SJung-uk Kim     {SSL_OP_CIPHER_SERVER_PREFERENCE, 0}, /* serverpref */
700e71b7053SJung-uk Kim     /* legacy_renegotiation */
701e71b7053SJung-uk Kim     {SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, 0},
702e71b7053SJung-uk Kim     /* legacy_server_connect */
703e71b7053SJung-uk Kim     {SSL_OP_LEGACY_SERVER_CONNECT, 0},
704e71b7053SJung-uk Kim     /* no_renegotiation */
705e71b7053SJung-uk Kim     {SSL_OP_NO_RENEGOTIATION, 0},
706e71b7053SJung-uk Kim     /* no_resumption_on_reneg */
707e71b7053SJung-uk Kim     {SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION, 0},
708e71b7053SJung-uk Kim     /* no_legacy_server_connect */
709e71b7053SJung-uk Kim     {SSL_OP_LEGACY_SERVER_CONNECT, SSL_TFLAG_INV},
710e71b7053SJung-uk Kim     /* allow_no_dhe_kex */
711e71b7053SJung-uk Kim     {SSL_OP_ALLOW_NO_DHE_KEX, 0},
712e71b7053SJung-uk Kim     /* chacha reprioritization */
713e71b7053SJung-uk Kim     {SSL_OP_PRIORITIZE_CHACHA, 0},
714e71b7053SJung-uk Kim     {SSL_CERT_FLAG_TLS_STRICT, SSL_TFLAG_CERT}, /* strict */
715e71b7053SJung-uk Kim     /* no_middlebox */
716e71b7053SJung-uk Kim     {SSL_OP_ENABLE_MIDDLEBOX_COMPAT, SSL_TFLAG_INV},
717e71b7053SJung-uk Kim     /* anti_replay */
718e71b7053SJung-uk Kim     {SSL_OP_NO_ANTI_REPLAY, SSL_TFLAG_INV},
719e71b7053SJung-uk Kim     /* no_anti_replay */
720e71b7053SJung-uk Kim     {SSL_OP_NO_ANTI_REPLAY, 0},
7217bded2dbSJung-uk Kim };
7227bded2dbSJung-uk Kim 
7237bded2dbSJung-uk Kim static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd)
7247bded2dbSJung-uk Kim {
7257bded2dbSJung-uk Kim     if (!pcmd || !*pcmd)
7267bded2dbSJung-uk Kim         return 0;
7277bded2dbSJung-uk Kim     /* If a prefix is set, check and skip */
7287bded2dbSJung-uk Kim     if (cctx->prefix) {
7297bded2dbSJung-uk Kim         if (strlen(*pcmd) <= cctx->prefixlen)
7307bded2dbSJung-uk Kim             return 0;
7317bded2dbSJung-uk Kim         if (cctx->flags & SSL_CONF_FLAG_CMDLINE &&
7327bded2dbSJung-uk Kim             strncmp(*pcmd, cctx->prefix, cctx->prefixlen))
7337bded2dbSJung-uk Kim             return 0;
7347bded2dbSJung-uk Kim         if (cctx->flags & SSL_CONF_FLAG_FILE &&
7357bded2dbSJung-uk Kim             strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen))
7367bded2dbSJung-uk Kim             return 0;
7377bded2dbSJung-uk Kim         *pcmd += cctx->prefixlen;
7387bded2dbSJung-uk Kim     } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
7397bded2dbSJung-uk Kim         if (**pcmd != '-' || !(*pcmd)[1])
7407bded2dbSJung-uk Kim             return 0;
7417bded2dbSJung-uk Kim         *pcmd += 1;
7427bded2dbSJung-uk Kim     }
7437bded2dbSJung-uk Kim     return 1;
7447bded2dbSJung-uk Kim }
7457bded2dbSJung-uk Kim 
746e71b7053SJung-uk Kim /* Determine if a command is allowed according to cctx flags */
747e71b7053SJung-uk Kim static int ssl_conf_cmd_allowed(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl * t)
748e71b7053SJung-uk Kim {
749e71b7053SJung-uk Kim     unsigned int tfl = t->flags;
750e71b7053SJung-uk Kim     unsigned int cfl = cctx->flags;
751e71b7053SJung-uk Kim     if ((tfl & SSL_CONF_FLAG_SERVER) && !(cfl & SSL_CONF_FLAG_SERVER))
752e71b7053SJung-uk Kim         return 0;
753e71b7053SJung-uk Kim     if ((tfl & SSL_CONF_FLAG_CLIENT) && !(cfl & SSL_CONF_FLAG_CLIENT))
754e71b7053SJung-uk Kim         return 0;
755e71b7053SJung-uk Kim     if ((tfl & SSL_CONF_FLAG_CERTIFICATE)
756e71b7053SJung-uk Kim         && !(cfl & SSL_CONF_FLAG_CERTIFICATE))
757e71b7053SJung-uk Kim         return 0;
758e71b7053SJung-uk Kim     return 1;
759e71b7053SJung-uk Kim }
760e71b7053SJung-uk Kim 
7617bded2dbSJung-uk Kim static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx,
7627bded2dbSJung-uk Kim                                                    const char *cmd)
7637bded2dbSJung-uk Kim {
7647bded2dbSJung-uk Kim     const ssl_conf_cmd_tbl *t;
7657bded2dbSJung-uk Kim     size_t i;
7667bded2dbSJung-uk Kim     if (cmd == NULL)
7677bded2dbSJung-uk Kim         return NULL;
7687bded2dbSJung-uk Kim 
7697bded2dbSJung-uk Kim     /* Look for matching parameter name in table */
770e71b7053SJung-uk Kim     for (i = 0, t = ssl_conf_cmds; i < OSSL_NELEM(ssl_conf_cmds); i++, t++) {
771e71b7053SJung-uk Kim         if (ssl_conf_cmd_allowed(cctx, t)) {
7727bded2dbSJung-uk Kim             if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
773e71b7053SJung-uk Kim                 if (t->str_cmdline && strcmp(t->str_cmdline, cmd) == 0)
7747bded2dbSJung-uk Kim                     return t;
7757bded2dbSJung-uk Kim             }
7767bded2dbSJung-uk Kim             if (cctx->flags & SSL_CONF_FLAG_FILE) {
777e71b7053SJung-uk Kim                 if (t->str_file && strcasecmp(t->str_file, cmd) == 0)
7787bded2dbSJung-uk Kim                     return t;
7797bded2dbSJung-uk Kim             }
7807bded2dbSJung-uk Kim         }
781e71b7053SJung-uk Kim     }
7827bded2dbSJung-uk Kim     return NULL;
7837bded2dbSJung-uk Kim }
7847bded2dbSJung-uk Kim 
785e71b7053SJung-uk Kim static int ctrl_switch_option(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl * cmd)
786e71b7053SJung-uk Kim {
787e71b7053SJung-uk Kim     /* Find index of command in table */
788e71b7053SJung-uk Kim     size_t idx = cmd - ssl_conf_cmds;
789e71b7053SJung-uk Kim     const ssl_switch_tbl *scmd;
790e71b7053SJung-uk Kim     /* Sanity check index */
791e71b7053SJung-uk Kim     if (idx >= OSSL_NELEM(ssl_cmd_switches))
792e71b7053SJung-uk Kim         return 0;
793e71b7053SJung-uk Kim     /* Obtain switches entry with same index */
794e71b7053SJung-uk Kim     scmd = ssl_cmd_switches + idx;
795e71b7053SJung-uk Kim     ssl_set_option(cctx, scmd->name_flags, scmd->option_value, 1);
796e71b7053SJung-uk Kim     return 1;
797e71b7053SJung-uk Kim }
798e71b7053SJung-uk Kim 
7997bded2dbSJung-uk Kim int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value)
8007bded2dbSJung-uk Kim {
8017bded2dbSJung-uk Kim     const ssl_conf_cmd_tbl *runcmd;
8027bded2dbSJung-uk Kim     if (cmd == NULL) {
8037bded2dbSJung-uk Kim         SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_INVALID_NULL_CMD_NAME);
8047bded2dbSJung-uk Kim         return 0;
8057bded2dbSJung-uk Kim     }
8067bded2dbSJung-uk Kim 
8077bded2dbSJung-uk Kim     if (!ssl_conf_cmd_skip_prefix(cctx, &cmd))
8087bded2dbSJung-uk Kim         return -2;
8097bded2dbSJung-uk Kim 
8107bded2dbSJung-uk Kim     runcmd = ssl_conf_cmd_lookup(cctx, cmd);
8117bded2dbSJung-uk Kim 
8127bded2dbSJung-uk Kim     if (runcmd) {
8137bded2dbSJung-uk Kim         int rv;
814e71b7053SJung-uk Kim         if (runcmd->value_type == SSL_CONF_TYPE_NONE) {
815e71b7053SJung-uk Kim             return ctrl_switch_option(cctx, runcmd);
816e71b7053SJung-uk Kim         }
8177bded2dbSJung-uk Kim         if (value == NULL)
8187bded2dbSJung-uk Kim             return -3;
8197bded2dbSJung-uk Kim         rv = runcmd->cmd(cctx, value);
8207bded2dbSJung-uk Kim         if (rv > 0)
8217bded2dbSJung-uk Kim             return 2;
8227bded2dbSJung-uk Kim         if (rv == -2)
8237bded2dbSJung-uk Kim             return -2;
8247bded2dbSJung-uk Kim         if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) {
8257bded2dbSJung-uk Kim             SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_BAD_VALUE);
8267bded2dbSJung-uk Kim             ERR_add_error_data(4, "cmd=", cmd, ", value=", value);
8277bded2dbSJung-uk Kim         }
8287bded2dbSJung-uk Kim         return 0;
8297bded2dbSJung-uk Kim     }
8307bded2dbSJung-uk Kim 
8317bded2dbSJung-uk Kim     if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) {
8327bded2dbSJung-uk Kim         SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_UNKNOWN_CMD_NAME);
8337bded2dbSJung-uk Kim         ERR_add_error_data(2, "cmd=", cmd);
8347bded2dbSJung-uk Kim     }
8357bded2dbSJung-uk Kim 
8367bded2dbSJung-uk Kim     return -2;
8377bded2dbSJung-uk Kim }
8387bded2dbSJung-uk Kim 
8397bded2dbSJung-uk Kim int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv)
8407bded2dbSJung-uk Kim {
8417bded2dbSJung-uk Kim     int rv;
8427bded2dbSJung-uk Kim     const char *arg = NULL, *argn;
8437bded2dbSJung-uk Kim     if (pargc && *pargc == 0)
8447bded2dbSJung-uk Kim         return 0;
8457bded2dbSJung-uk Kim     if (!pargc || *pargc > 0)
8467bded2dbSJung-uk Kim         arg = **pargv;
8477bded2dbSJung-uk Kim     if (arg == NULL)
8487bded2dbSJung-uk Kim         return 0;
8497bded2dbSJung-uk Kim     if (!pargc || *pargc > 1)
8507bded2dbSJung-uk Kim         argn = (*pargv)[1];
8517bded2dbSJung-uk Kim     else
8527bded2dbSJung-uk Kim         argn = NULL;
8537bded2dbSJung-uk Kim     cctx->flags &= ~SSL_CONF_FLAG_FILE;
8547bded2dbSJung-uk Kim     cctx->flags |= SSL_CONF_FLAG_CMDLINE;
8557bded2dbSJung-uk Kim     rv = SSL_CONF_cmd(cctx, arg, argn);
8567bded2dbSJung-uk Kim     if (rv > 0) {
8577bded2dbSJung-uk Kim         /* Success: update pargc, pargv */
8587bded2dbSJung-uk Kim         (*pargv) += rv;
8597bded2dbSJung-uk Kim         if (pargc)
8607bded2dbSJung-uk Kim             (*pargc) -= rv;
8617bded2dbSJung-uk Kim         return rv;
8627bded2dbSJung-uk Kim     }
8637bded2dbSJung-uk Kim     /* Unknown switch: indicate no arguments processed */
8647bded2dbSJung-uk Kim     if (rv == -2)
8657bded2dbSJung-uk Kim         return 0;
8667bded2dbSJung-uk Kim     /* Some error occurred processing command, return fatal error */
8677bded2dbSJung-uk Kim     if (rv == 0)
8687bded2dbSJung-uk Kim         return -1;
8697bded2dbSJung-uk Kim     return rv;
8707bded2dbSJung-uk Kim }
8717bded2dbSJung-uk Kim 
8727bded2dbSJung-uk Kim int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd)
8737bded2dbSJung-uk Kim {
8747bded2dbSJung-uk Kim     if (ssl_conf_cmd_skip_prefix(cctx, &cmd)) {
8757bded2dbSJung-uk Kim         const ssl_conf_cmd_tbl *runcmd;
8767bded2dbSJung-uk Kim         runcmd = ssl_conf_cmd_lookup(cctx, cmd);
8777bded2dbSJung-uk Kim         if (runcmd)
8787bded2dbSJung-uk Kim             return runcmd->value_type;
8797bded2dbSJung-uk Kim     }
8807bded2dbSJung-uk Kim     return SSL_CONF_TYPE_UNKNOWN;
8817bded2dbSJung-uk Kim }
8827bded2dbSJung-uk Kim 
8837bded2dbSJung-uk Kim SSL_CONF_CTX *SSL_CONF_CTX_new(void)
8847bded2dbSJung-uk Kim {
885e71b7053SJung-uk Kim     SSL_CONF_CTX *ret = OPENSSL_zalloc(sizeof(*ret));
886e71b7053SJung-uk Kim 
8877bded2dbSJung-uk Kim     return ret;
8887bded2dbSJung-uk Kim }
8897bded2dbSJung-uk Kim 
8907bded2dbSJung-uk Kim int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx)
8917bded2dbSJung-uk Kim {
892e71b7053SJung-uk Kim     /* See if any certificates are missing private keys */
893e71b7053SJung-uk Kim     size_t i;
894e71b7053SJung-uk Kim     CERT *c = NULL;
895e71b7053SJung-uk Kim     if (cctx->ctx)
896e71b7053SJung-uk Kim         c = cctx->ctx->cert;
897e71b7053SJung-uk Kim     else if (cctx->ssl)
898e71b7053SJung-uk Kim         c = cctx->ssl->cert;
899e71b7053SJung-uk Kim     if (c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
900e71b7053SJung-uk Kim         for (i = 0; i < SSL_PKEY_NUM; i++) {
901e71b7053SJung-uk Kim             const char *p = cctx->cert_filename[i];
902e71b7053SJung-uk Kim             /*
903e71b7053SJung-uk Kim              * If missing private key try to load one from certificate file
904e71b7053SJung-uk Kim              */
905e71b7053SJung-uk Kim             if (p && !c->pkeys[i].privatekey) {
906e71b7053SJung-uk Kim                 if (!cmd_PrivateKey(cctx, p))
907e71b7053SJung-uk Kim                     return 0;
908e71b7053SJung-uk Kim             }
909e71b7053SJung-uk Kim         }
910e71b7053SJung-uk Kim     }
911e71b7053SJung-uk Kim     if (cctx->canames) {
912e71b7053SJung-uk Kim         if (cctx->ssl)
913e71b7053SJung-uk Kim             SSL_set0_CA_list(cctx->ssl, cctx->canames);
914e71b7053SJung-uk Kim         else if (cctx->ctx)
915e71b7053SJung-uk Kim             SSL_CTX_set0_CA_list(cctx->ctx, cctx->canames);
916e71b7053SJung-uk Kim         else
917e71b7053SJung-uk Kim             sk_X509_NAME_pop_free(cctx->canames, X509_NAME_free);
918e71b7053SJung-uk Kim         cctx->canames = NULL;
919e71b7053SJung-uk Kim     }
9207bded2dbSJung-uk Kim     return 1;
9217bded2dbSJung-uk Kim }
9227bded2dbSJung-uk Kim 
9237bded2dbSJung-uk Kim void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx)
9247bded2dbSJung-uk Kim {
9257bded2dbSJung-uk Kim     if (cctx) {
926e71b7053SJung-uk Kim         size_t i;
927e71b7053SJung-uk Kim         for (i = 0; i < SSL_PKEY_NUM; i++)
928e71b7053SJung-uk Kim             OPENSSL_free(cctx->cert_filename[i]);
9297bded2dbSJung-uk Kim         OPENSSL_free(cctx->prefix);
930e71b7053SJung-uk Kim         sk_X509_NAME_pop_free(cctx->canames, X509_NAME_free);
9317bded2dbSJung-uk Kim         OPENSSL_free(cctx);
9327bded2dbSJung-uk Kim     }
9337bded2dbSJung-uk Kim }
9347bded2dbSJung-uk Kim 
9357bded2dbSJung-uk Kim unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags)
9367bded2dbSJung-uk Kim {
9377bded2dbSJung-uk Kim     cctx->flags |= flags;
9387bded2dbSJung-uk Kim     return cctx->flags;
9397bded2dbSJung-uk Kim }
9407bded2dbSJung-uk Kim 
9417bded2dbSJung-uk Kim unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags)
9427bded2dbSJung-uk Kim {
9437bded2dbSJung-uk Kim     cctx->flags &= ~flags;
9447bded2dbSJung-uk Kim     return cctx->flags;
9457bded2dbSJung-uk Kim }
9467bded2dbSJung-uk Kim 
9477bded2dbSJung-uk Kim int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre)
9487bded2dbSJung-uk Kim {
9497bded2dbSJung-uk Kim     char *tmp = NULL;
9507bded2dbSJung-uk Kim     if (pre) {
951e71b7053SJung-uk Kim         tmp = OPENSSL_strdup(pre);
9527bded2dbSJung-uk Kim         if (tmp == NULL)
9537bded2dbSJung-uk Kim             return 0;
9547bded2dbSJung-uk Kim     }
9557bded2dbSJung-uk Kim     OPENSSL_free(cctx->prefix);
9567bded2dbSJung-uk Kim     cctx->prefix = tmp;
9577bded2dbSJung-uk Kim     if (tmp)
9587bded2dbSJung-uk Kim         cctx->prefixlen = strlen(tmp);
9597bded2dbSJung-uk Kim     else
9607bded2dbSJung-uk Kim         cctx->prefixlen = 0;
9617bded2dbSJung-uk Kim     return 1;
9627bded2dbSJung-uk Kim }
9637bded2dbSJung-uk Kim 
9647bded2dbSJung-uk Kim void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl)
9657bded2dbSJung-uk Kim {
9667bded2dbSJung-uk Kim     cctx->ssl = ssl;
9677bded2dbSJung-uk Kim     cctx->ctx = NULL;
9687bded2dbSJung-uk Kim     if (ssl) {
9697bded2dbSJung-uk Kim         cctx->poptions = &ssl->options;
970e71b7053SJung-uk Kim         cctx->min_version = &ssl->min_proto_version;
971e71b7053SJung-uk Kim         cctx->max_version = &ssl->max_proto_version;
9727bded2dbSJung-uk Kim         cctx->pcert_flags = &ssl->cert->cert_flags;
973e71b7053SJung-uk Kim         cctx->pvfy_flags = &ssl->verify_mode;
9747bded2dbSJung-uk Kim     } else {
9757bded2dbSJung-uk Kim         cctx->poptions = NULL;
976e71b7053SJung-uk Kim         cctx->min_version = NULL;
977e71b7053SJung-uk Kim         cctx->max_version = NULL;
9787bded2dbSJung-uk Kim         cctx->pcert_flags = NULL;
979e71b7053SJung-uk Kim         cctx->pvfy_flags = NULL;
9807bded2dbSJung-uk Kim     }
9817bded2dbSJung-uk Kim }
9827bded2dbSJung-uk Kim 
9837bded2dbSJung-uk Kim void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx)
9847bded2dbSJung-uk Kim {
9857bded2dbSJung-uk Kim     cctx->ctx = ctx;
9867bded2dbSJung-uk Kim     cctx->ssl = NULL;
9877bded2dbSJung-uk Kim     if (ctx) {
9887bded2dbSJung-uk Kim         cctx->poptions = &ctx->options;
989e71b7053SJung-uk Kim         cctx->min_version = &ctx->min_proto_version;
990e71b7053SJung-uk Kim         cctx->max_version = &ctx->max_proto_version;
9917bded2dbSJung-uk Kim         cctx->pcert_flags = &ctx->cert->cert_flags;
992e71b7053SJung-uk Kim         cctx->pvfy_flags = &ctx->verify_mode;
9937bded2dbSJung-uk Kim     } else {
9947bded2dbSJung-uk Kim         cctx->poptions = NULL;
995e71b7053SJung-uk Kim         cctx->min_version = NULL;
996e71b7053SJung-uk Kim         cctx->max_version = NULL;
9977bded2dbSJung-uk Kim         cctx->pcert_flags = NULL;
998e71b7053SJung-uk Kim         cctx->pvfy_flags = NULL;
9997bded2dbSJung-uk Kim     }
10007bded2dbSJung-uk Kim }
1001