17bded2dbSJung-uk Kim /*
2b077aed3SPierre Pronchery * Copyright 2012-2022 The OpenSSL Project Authors. All Rights Reserved.
37bded2dbSJung-uk Kim *
4b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (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>
14b077aed3SPierre Pronchery #include <openssl/decoder.h>
15b077aed3SPierre Pronchery #include <openssl/core_dispatch.h>
16e71b7053SJung-uk Kim #include "internal/nelem.h"
177bded2dbSJung-uk Kim
187bded2dbSJung-uk Kim /*
19e71b7053SJung-uk Kim * structure holding name tables. This is used for permitted elements in lists
20e71b7053SJung-uk Kim * such as TLSv1.
217bded2dbSJung-uk Kim */
227bded2dbSJung-uk Kim
237bded2dbSJung-uk Kim typedef struct {
247bded2dbSJung-uk Kim const char *name;
257bded2dbSJung-uk Kim int namelen;
267bded2dbSJung-uk Kim unsigned int name_flags;
27b077aed3SPierre Pronchery uint64_t option_value;
287bded2dbSJung-uk Kim } ssl_flag_tbl;
297bded2dbSJung-uk Kim
30e71b7053SJung-uk Kim /* Switch table: use for single command line switches like no_tls2 */
31e71b7053SJung-uk Kim typedef struct {
32b077aed3SPierre Pronchery uint64_t option_value;
33e71b7053SJung-uk Kim unsigned int name_flags;
34e71b7053SJung-uk Kim } ssl_switch_tbl;
35e71b7053SJung-uk Kim
367bded2dbSJung-uk Kim /* Sense of name is inverted e.g. "TLSv1" will clear SSL_OP_NO_TLSv1 */
377bded2dbSJung-uk Kim #define SSL_TFLAG_INV 0x1
38e71b7053SJung-uk Kim /* Mask for type of flag referred to */
39e71b7053SJung-uk Kim #define SSL_TFLAG_TYPE_MASK 0xf00
40e71b7053SJung-uk Kim /* Flag is for options */
41e71b7053SJung-uk Kim #define SSL_TFLAG_OPTION 0x000
42e71b7053SJung-uk Kim /* Flag is for cert_flags */
43e71b7053SJung-uk Kim #define SSL_TFLAG_CERT 0x100
44e71b7053SJung-uk Kim /* Flag is for verify mode */
45e71b7053SJung-uk Kim #define SSL_TFLAG_VFY 0x200
467bded2dbSJung-uk Kim /* Option can only be used for clients */
477bded2dbSJung-uk Kim #define SSL_TFLAG_CLIENT SSL_CONF_FLAG_CLIENT
487bded2dbSJung-uk Kim /* Option can only be used for servers */
497bded2dbSJung-uk Kim #define SSL_TFLAG_SERVER SSL_CONF_FLAG_SERVER
507bded2dbSJung-uk Kim #define SSL_TFLAG_BOTH (SSL_TFLAG_CLIENT|SSL_TFLAG_SERVER)
517bded2dbSJung-uk Kim
527bded2dbSJung-uk Kim #define SSL_FLAG_TBL(str, flag) \
537bded2dbSJung-uk Kim {str, (int)(sizeof(str) - 1), SSL_TFLAG_BOTH, flag}
547bded2dbSJung-uk Kim #define SSL_FLAG_TBL_SRV(str, flag) \
557bded2dbSJung-uk Kim {str, (int)(sizeof(str) - 1), SSL_TFLAG_SERVER, flag}
567bded2dbSJung-uk Kim #define SSL_FLAG_TBL_CLI(str, flag) \
577bded2dbSJung-uk Kim {str, (int)(sizeof(str) - 1), SSL_TFLAG_CLIENT, flag}
587bded2dbSJung-uk Kim #define SSL_FLAG_TBL_INV(str, flag) \
597bded2dbSJung-uk Kim {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_BOTH, flag}
607bded2dbSJung-uk Kim #define SSL_FLAG_TBL_SRV_INV(str, flag) \
617bded2dbSJung-uk Kim {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_SERVER, flag}
627bded2dbSJung-uk Kim #define SSL_FLAG_TBL_CERT(str, flag) \
637bded2dbSJung-uk Kim {str, (int)(sizeof(str) - 1), SSL_TFLAG_CERT|SSL_TFLAG_BOTH, flag}
647bded2dbSJung-uk Kim
65e71b7053SJung-uk Kim #define SSL_FLAG_VFY_CLI(str, flag) \
66e71b7053SJung-uk Kim {str, (int)(sizeof(str) - 1), SSL_TFLAG_VFY | SSL_TFLAG_CLIENT, flag}
67e71b7053SJung-uk Kim #define SSL_FLAG_VFY_SRV(str, flag) \
68e71b7053SJung-uk Kim {str, (int)(sizeof(str) - 1), SSL_TFLAG_VFY | SSL_TFLAG_SERVER, flag}
69e71b7053SJung-uk Kim
707bded2dbSJung-uk Kim /*
717bded2dbSJung-uk Kim * Opaque structure containing SSL configuration context.
727bded2dbSJung-uk Kim */
737bded2dbSJung-uk Kim
747bded2dbSJung-uk Kim struct ssl_conf_ctx_st {
757bded2dbSJung-uk Kim /*
767bded2dbSJung-uk Kim * Various flags indicating (among other things) which options we will
777bded2dbSJung-uk Kim * recognise.
787bded2dbSJung-uk Kim */
797bded2dbSJung-uk Kim unsigned int flags;
807bded2dbSJung-uk Kim /* Prefix and length of commands */
817bded2dbSJung-uk Kim char *prefix;
827bded2dbSJung-uk Kim size_t prefixlen;
837bded2dbSJung-uk Kim /* SSL_CTX or SSL structure to perform operations on */
847bded2dbSJung-uk Kim SSL_CTX *ctx;
857bded2dbSJung-uk Kim SSL *ssl;
867bded2dbSJung-uk Kim /* Pointer to SSL or SSL_CTX options field or NULL if none */
87b077aed3SPierre Pronchery uint64_t *poptions;
88e71b7053SJung-uk Kim /* Certificate filenames for each type */
89e71b7053SJung-uk Kim char *cert_filename[SSL_PKEY_NUM];
907bded2dbSJung-uk Kim /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */
91e71b7053SJung-uk Kim uint32_t *pcert_flags;
92e71b7053SJung-uk Kim /* Pointer to SSL or SSL_CTX verify_mode or NULL if none */
93e71b7053SJung-uk Kim uint32_t *pvfy_flags;
94e71b7053SJung-uk Kim /* Pointer to SSL or SSL_CTX min_version field or NULL if none */
95e71b7053SJung-uk Kim int *min_version;
96e71b7053SJung-uk Kim /* Pointer to SSL or SSL_CTX max_version field or NULL if none */
97e71b7053SJung-uk Kim int *max_version;
987bded2dbSJung-uk Kim /* Current flag table being worked on */
997bded2dbSJung-uk Kim const ssl_flag_tbl *tbl;
1007bded2dbSJung-uk Kim /* Size of table */
1017bded2dbSJung-uk Kim size_t ntbl;
102e71b7053SJung-uk Kim /* Client CA names */
103e71b7053SJung-uk Kim STACK_OF(X509_NAME) *canames;
1047bded2dbSJung-uk Kim };
1057bded2dbSJung-uk Kim
ssl_set_option(SSL_CONF_CTX * cctx,unsigned int name_flags,uint64_t option_value,int onoff)106e71b7053SJung-uk Kim static void ssl_set_option(SSL_CONF_CTX *cctx, unsigned int name_flags,
107b077aed3SPierre Pronchery uint64_t option_value, int onoff)
108e71b7053SJung-uk Kim {
109e71b7053SJung-uk Kim uint32_t *pflags;
110b077aed3SPierre Pronchery
111e71b7053SJung-uk Kim if (cctx->poptions == NULL)
112e71b7053SJung-uk Kim return;
113e71b7053SJung-uk Kim if (name_flags & SSL_TFLAG_INV)
114e71b7053SJung-uk Kim onoff ^= 1;
115e71b7053SJung-uk Kim switch (name_flags & SSL_TFLAG_TYPE_MASK) {
116e71b7053SJung-uk Kim
117e71b7053SJung-uk Kim case SSL_TFLAG_CERT:
118e71b7053SJung-uk Kim pflags = cctx->pcert_flags;
119e71b7053SJung-uk Kim break;
120e71b7053SJung-uk Kim
121e71b7053SJung-uk Kim case SSL_TFLAG_VFY:
122e71b7053SJung-uk Kim pflags = cctx->pvfy_flags;
123e71b7053SJung-uk Kim break;
124e71b7053SJung-uk Kim
125e71b7053SJung-uk Kim case SSL_TFLAG_OPTION:
126b077aed3SPierre Pronchery if (onoff)
127b077aed3SPierre Pronchery *cctx->poptions |= option_value;
128b077aed3SPierre Pronchery else
129b077aed3SPierre Pronchery *cctx->poptions &= ~option_value;
130b077aed3SPierre Pronchery return;
131e71b7053SJung-uk Kim
132e71b7053SJung-uk Kim default:
133e71b7053SJung-uk Kim return;
134e71b7053SJung-uk Kim
135e71b7053SJung-uk Kim }
136e71b7053SJung-uk Kim if (onoff)
137e71b7053SJung-uk Kim *pflags |= option_value;
138e71b7053SJung-uk Kim else
139e71b7053SJung-uk Kim *pflags &= ~option_value;
140e71b7053SJung-uk Kim }
141e71b7053SJung-uk Kim
ssl_match_option(SSL_CONF_CTX * cctx,const ssl_flag_tbl * tbl,const char * name,int namelen,int onoff)1427bded2dbSJung-uk Kim static int ssl_match_option(SSL_CONF_CTX *cctx, const ssl_flag_tbl *tbl,
1437bded2dbSJung-uk Kim const char *name, int namelen, int onoff)
1447bded2dbSJung-uk Kim {
1457bded2dbSJung-uk Kim /* If name not relevant for context skip */
1467bded2dbSJung-uk Kim if (!(cctx->flags & tbl->name_flags & SSL_TFLAG_BOTH))
1477bded2dbSJung-uk Kim return 0;
1487bded2dbSJung-uk Kim if (namelen == -1) {
1497bded2dbSJung-uk Kim if (strcmp(tbl->name, name))
1507bded2dbSJung-uk Kim return 0;
151b077aed3SPierre Pronchery } else if (tbl->namelen != namelen
152b077aed3SPierre Pronchery || OPENSSL_strncasecmp(tbl->name, name, namelen))
1537bded2dbSJung-uk Kim return 0;
154e71b7053SJung-uk Kim ssl_set_option(cctx, tbl->name_flags, tbl->option_value, onoff);
1557bded2dbSJung-uk Kim return 1;
1567bded2dbSJung-uk Kim }
1577bded2dbSJung-uk Kim
ssl_set_option_list(const char * elem,int len,void * usr)1587bded2dbSJung-uk Kim static int ssl_set_option_list(const char *elem, int len, void *usr)
1597bded2dbSJung-uk Kim {
1607bded2dbSJung-uk Kim SSL_CONF_CTX *cctx = usr;
1617bded2dbSJung-uk Kim size_t i;
1627bded2dbSJung-uk Kim const ssl_flag_tbl *tbl;
1637bded2dbSJung-uk Kim int onoff = 1;
1647bded2dbSJung-uk Kim /*
1657bded2dbSJung-uk Kim * len == -1 indicates not being called in list context, just for single
1667bded2dbSJung-uk Kim * command line switches, so don't allow +, -.
1677bded2dbSJung-uk Kim */
1687bded2dbSJung-uk Kim if (elem == NULL)
1697bded2dbSJung-uk Kim return 0;
1707bded2dbSJung-uk Kim if (len != -1) {
1717bded2dbSJung-uk Kim if (*elem == '+') {
1727bded2dbSJung-uk Kim elem++;
1737bded2dbSJung-uk Kim len--;
1747bded2dbSJung-uk Kim onoff = 1;
1757bded2dbSJung-uk Kim } else if (*elem == '-') {
1767bded2dbSJung-uk Kim elem++;
1777bded2dbSJung-uk Kim len--;
1787bded2dbSJung-uk Kim onoff = 0;
1797bded2dbSJung-uk Kim }
1807bded2dbSJung-uk Kim }
1817bded2dbSJung-uk Kim for (i = 0, tbl = cctx->tbl; i < cctx->ntbl; i++, tbl++) {
1827bded2dbSJung-uk Kim if (ssl_match_option(cctx, tbl, elem, len, onoff))
1837bded2dbSJung-uk Kim return 1;
1847bded2dbSJung-uk Kim }
1857bded2dbSJung-uk Kim return 0;
1867bded2dbSJung-uk Kim }
1877bded2dbSJung-uk Kim
1887bded2dbSJung-uk Kim /* Set supported signature algorithms */
cmd_SignatureAlgorithms(SSL_CONF_CTX * cctx,const char * value)1897bded2dbSJung-uk Kim static int cmd_SignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
1907bded2dbSJung-uk Kim {
1917bded2dbSJung-uk Kim int rv;
1927bded2dbSJung-uk Kim if (cctx->ssl)
1937bded2dbSJung-uk Kim rv = SSL_set1_sigalgs_list(cctx->ssl, value);
1947bded2dbSJung-uk Kim /* NB: ctx == NULL performs syntax checking only */
1957bded2dbSJung-uk Kim else
1967bded2dbSJung-uk Kim rv = SSL_CTX_set1_sigalgs_list(cctx->ctx, value);
1977bded2dbSJung-uk Kim return rv > 0;
1987bded2dbSJung-uk Kim }
1997bded2dbSJung-uk Kim
2007bded2dbSJung-uk Kim /* Set supported client signature algorithms */
cmd_ClientSignatureAlgorithms(SSL_CONF_CTX * cctx,const char * value)201e71b7053SJung-uk Kim static int cmd_ClientSignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
2027bded2dbSJung-uk Kim {
2037bded2dbSJung-uk Kim int rv;
2047bded2dbSJung-uk Kim if (cctx->ssl)
2057bded2dbSJung-uk Kim rv = SSL_set1_client_sigalgs_list(cctx->ssl, value);
2067bded2dbSJung-uk Kim /* NB: ctx == NULL performs syntax checking only */
2077bded2dbSJung-uk Kim else
2087bded2dbSJung-uk Kim rv = SSL_CTX_set1_client_sigalgs_list(cctx->ctx, value);
2097bded2dbSJung-uk Kim return rv > 0;
2107bded2dbSJung-uk Kim }
2117bded2dbSJung-uk Kim
cmd_Groups(SSL_CONF_CTX * cctx,const char * value)212e71b7053SJung-uk Kim static int cmd_Groups(SSL_CONF_CTX *cctx, const char *value)
2137bded2dbSJung-uk Kim {
2147bded2dbSJung-uk Kim int rv;
2157bded2dbSJung-uk Kim if (cctx->ssl)
216e71b7053SJung-uk Kim rv = SSL_set1_groups_list(cctx->ssl, value);
2177bded2dbSJung-uk Kim /* NB: ctx == NULL performs syntax checking only */
2187bded2dbSJung-uk Kim else
219e71b7053SJung-uk Kim rv = SSL_CTX_set1_groups_list(cctx->ctx, value);
2207bded2dbSJung-uk Kim return rv > 0;
2217bded2dbSJung-uk Kim }
2227bded2dbSJung-uk Kim
223e71b7053SJung-uk Kim /* This is the old name for cmd_Groups - retained for backwards compatibility */
cmd_Curves(SSL_CONF_CTX * cctx,const char * value)224e71b7053SJung-uk Kim static int cmd_Curves(SSL_CONF_CTX *cctx, const char *value)
225e71b7053SJung-uk Kim {
226e71b7053SJung-uk Kim return cmd_Groups(cctx, value);
227e71b7053SJung-uk Kim }
228e71b7053SJung-uk Kim
2297bded2dbSJung-uk Kim /* ECDH temporary parameters */
cmd_ECDHParameters(SSL_CONF_CTX * cctx,const char * value)2307bded2dbSJung-uk Kim static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value)
2317bded2dbSJung-uk Kim {
232e71b7053SJung-uk Kim int rv = 1;
233e71b7053SJung-uk Kim
234e71b7053SJung-uk Kim /* Ignore values supported by 1.0.2 for the automatic selection */
235e71b7053SJung-uk Kim if ((cctx->flags & SSL_CONF_FLAG_FILE)
236b077aed3SPierre Pronchery && (OPENSSL_strcasecmp(value, "+automatic") == 0
237b077aed3SPierre Pronchery || OPENSSL_strcasecmp(value, "automatic") == 0))
238e71b7053SJung-uk Kim return 1;
239e71b7053SJung-uk Kim if ((cctx->flags & SSL_CONF_FLAG_CMDLINE) &&
240e71b7053SJung-uk Kim strcmp(value, "auto") == 0)
241e71b7053SJung-uk Kim return 1;
242e71b7053SJung-uk Kim
243b077aed3SPierre Pronchery /* ECDHParameters accepts a single group name */
244b077aed3SPierre Pronchery if (strstr(value, ":") != NULL)
2457bded2dbSJung-uk Kim return 0;
246b077aed3SPierre Pronchery
2477bded2dbSJung-uk Kim if (cctx->ctx)
248b077aed3SPierre Pronchery rv = SSL_CTX_set1_groups_list(cctx->ctx, value);
2497bded2dbSJung-uk Kim else if (cctx->ssl)
250b077aed3SPierre Pronchery rv = SSL_set1_groups_list(cctx->ssl, value);
2517bded2dbSJung-uk Kim
2527bded2dbSJung-uk Kim return rv > 0;
2537bded2dbSJung-uk Kim }
254b077aed3SPierre Pronchery
cmd_CipherString(SSL_CONF_CTX * cctx,const char * value)2557bded2dbSJung-uk Kim static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value)
2567bded2dbSJung-uk Kim {
2577bded2dbSJung-uk Kim int rv = 1;
258e71b7053SJung-uk Kim
2597bded2dbSJung-uk Kim if (cctx->ctx)
2607bded2dbSJung-uk Kim rv = SSL_CTX_set_cipher_list(cctx->ctx, value);
2617bded2dbSJung-uk Kim if (cctx->ssl)
2627bded2dbSJung-uk Kim rv = SSL_set_cipher_list(cctx->ssl, value);
2637bded2dbSJung-uk Kim return rv > 0;
2647bded2dbSJung-uk Kim }
2657bded2dbSJung-uk Kim
cmd_Ciphersuites(SSL_CONF_CTX * cctx,const char * value)266e71b7053SJung-uk Kim static int cmd_Ciphersuites(SSL_CONF_CTX *cctx, const char *value)
267e71b7053SJung-uk Kim {
268e71b7053SJung-uk Kim int rv = 1;
269e71b7053SJung-uk Kim
270e71b7053SJung-uk Kim if (cctx->ctx)
271e71b7053SJung-uk Kim rv = SSL_CTX_set_ciphersuites(cctx->ctx, value);
272e71b7053SJung-uk Kim if (cctx->ssl)
273e71b7053SJung-uk Kim rv = SSL_set_ciphersuites(cctx->ssl, value);
274e71b7053SJung-uk Kim return rv > 0;
275e71b7053SJung-uk Kim }
276e71b7053SJung-uk Kim
cmd_Protocol(SSL_CONF_CTX * cctx,const char * value)2777bded2dbSJung-uk Kim static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value)
2787bded2dbSJung-uk Kim {
2797bded2dbSJung-uk Kim static const ssl_flag_tbl ssl_protocol_list[] = {
2807bded2dbSJung-uk Kim SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK),
2817bded2dbSJung-uk Kim SSL_FLAG_TBL_INV("SSLv2", SSL_OP_NO_SSLv2),
2827bded2dbSJung-uk Kim SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3),
2837bded2dbSJung-uk Kim SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1),
2847bded2dbSJung-uk Kim SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1),
285e71b7053SJung-uk Kim SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2),
286e71b7053SJung-uk Kim SSL_FLAG_TBL_INV("TLSv1.3", SSL_OP_NO_TLSv1_3),
287e71b7053SJung-uk Kim SSL_FLAG_TBL_INV("DTLSv1", SSL_OP_NO_DTLSv1),
288e71b7053SJung-uk Kim SSL_FLAG_TBL_INV("DTLSv1.2", SSL_OP_NO_DTLSv1_2)
2897bded2dbSJung-uk Kim };
2907bded2dbSJung-uk Kim cctx->tbl = ssl_protocol_list;
291e71b7053SJung-uk Kim cctx->ntbl = OSSL_NELEM(ssl_protocol_list);
292e71b7053SJung-uk Kim return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
293e71b7053SJung-uk Kim }
2944c6a0400SJung-uk Kim
295e71b7053SJung-uk Kim /*
296e71b7053SJung-uk Kim * protocol_from_string - converts a protocol version string to a number
297e71b7053SJung-uk Kim *
298e71b7053SJung-uk Kim * Returns -1 on failure or the version on success
299e71b7053SJung-uk Kim */
protocol_from_string(const char * value)300e71b7053SJung-uk Kim static int protocol_from_string(const char *value)
301e71b7053SJung-uk Kim {
302e71b7053SJung-uk Kim struct protocol_versions {
303e71b7053SJung-uk Kim const char *name;
304e71b7053SJung-uk Kim int version;
305e71b7053SJung-uk Kim };
30658f35182SJung-uk Kim /*
30758f35182SJung-uk Kim * Note: To avoid breaking previously valid configurations, we must retain
30858f35182SJung-uk Kim * legacy entries in this table even if the underlying protocol is no
30958f35182SJung-uk Kim * longer supported. This also means that the constants SSL3_VERSION, ...
31058f35182SJung-uk Kim * need to be retained indefinitely. This table can only grow, never
31158f35182SJung-uk Kim * shrink.
31258f35182SJung-uk Kim */
313e71b7053SJung-uk Kim static const struct protocol_versions versions[] = {
314e71b7053SJung-uk Kim {"None", 0},
315e71b7053SJung-uk Kim {"SSLv3", SSL3_VERSION},
316e71b7053SJung-uk Kim {"TLSv1", TLS1_VERSION},
317e71b7053SJung-uk Kim {"TLSv1.1", TLS1_1_VERSION},
318e71b7053SJung-uk Kim {"TLSv1.2", TLS1_2_VERSION},
319e71b7053SJung-uk Kim {"TLSv1.3", TLS1_3_VERSION},
320e71b7053SJung-uk Kim {"DTLSv1", DTLS1_VERSION},
321e71b7053SJung-uk Kim {"DTLSv1.2", DTLS1_2_VERSION}
322e71b7053SJung-uk Kim };
323e71b7053SJung-uk Kim size_t i;
324e71b7053SJung-uk Kim size_t n = OSSL_NELEM(versions);
325e71b7053SJung-uk Kim
326e71b7053SJung-uk Kim for (i = 0; i < n; i++)
327e71b7053SJung-uk Kim if (strcmp(versions[i].name, value) == 0)
328e71b7053SJung-uk Kim return versions[i].version;
329e71b7053SJung-uk Kim return -1;
330e71b7053SJung-uk Kim }
331e71b7053SJung-uk Kim
min_max_proto(SSL_CONF_CTX * cctx,const char * value,int * bound)332e71b7053SJung-uk Kim static int min_max_proto(SSL_CONF_CTX *cctx, const char *value, int *bound)
333e71b7053SJung-uk Kim {
334e71b7053SJung-uk Kim int method_version;
335e71b7053SJung-uk Kim int new_version;
336e71b7053SJung-uk Kim
337e71b7053SJung-uk Kim if (cctx->ctx != NULL)
338e71b7053SJung-uk Kim method_version = cctx->ctx->method->version;
339e71b7053SJung-uk Kim else if (cctx->ssl != NULL)
340e71b7053SJung-uk Kim method_version = cctx->ssl->ctx->method->version;
341e71b7053SJung-uk Kim else
342e71b7053SJung-uk Kim return 0;
343e71b7053SJung-uk Kim if ((new_version = protocol_from_string(value)) < 0)
344e71b7053SJung-uk Kim return 0;
345e71b7053SJung-uk Kim return ssl_set_version_bound(method_version, new_version, bound);
346e71b7053SJung-uk Kim }
347e71b7053SJung-uk Kim
348e71b7053SJung-uk Kim /*
349e71b7053SJung-uk Kim * cmd_MinProtocol - Set min protocol version
350e71b7053SJung-uk Kim * @cctx: config structure to save settings in
351e71b7053SJung-uk Kim * @value: The min protocol version in string form
352e71b7053SJung-uk Kim *
353e71b7053SJung-uk Kim * Returns 1 on success and 0 on failure.
354e71b7053SJung-uk Kim */
cmd_MinProtocol(SSL_CONF_CTX * cctx,const char * value)355e71b7053SJung-uk Kim static int cmd_MinProtocol(SSL_CONF_CTX *cctx, const char *value)
356e71b7053SJung-uk Kim {
357e71b7053SJung-uk Kim return min_max_proto(cctx, value, cctx->min_version);
358e71b7053SJung-uk Kim }
359e71b7053SJung-uk Kim
360e71b7053SJung-uk Kim /*
361e71b7053SJung-uk Kim * cmd_MaxProtocol - Set max protocol version
362e71b7053SJung-uk Kim * @cctx: config structure to save settings in
363e71b7053SJung-uk Kim * @value: The max protocol version in string form
364e71b7053SJung-uk Kim *
365e71b7053SJung-uk Kim * Returns 1 on success and 0 on failure.
366e71b7053SJung-uk Kim */
cmd_MaxProtocol(SSL_CONF_CTX * cctx,const char * value)367e71b7053SJung-uk Kim static int cmd_MaxProtocol(SSL_CONF_CTX *cctx, const char *value)
368e71b7053SJung-uk Kim {
369e71b7053SJung-uk Kim return min_max_proto(cctx, value, cctx->max_version);
3707bded2dbSJung-uk Kim }
3717bded2dbSJung-uk Kim
cmd_Options(SSL_CONF_CTX * cctx,const char * value)3727bded2dbSJung-uk Kim static int cmd_Options(SSL_CONF_CTX *cctx, const char *value)
3737bded2dbSJung-uk Kim {
3747bded2dbSJung-uk Kim static const ssl_flag_tbl ssl_option_list[] = {
3757bded2dbSJung-uk Kim SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET),
3767bded2dbSJung-uk Kim SSL_FLAG_TBL_INV("EmptyFragments",
3777bded2dbSJung-uk Kim SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS),
3787bded2dbSJung-uk Kim SSL_FLAG_TBL("Bugs", SSL_OP_ALL),
3797bded2dbSJung-uk Kim SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION),
3807bded2dbSJung-uk Kim SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE),
3817bded2dbSJung-uk Kim SSL_FLAG_TBL_SRV("NoResumptionOnRenegotiation",
3827bded2dbSJung-uk Kim SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION),
3837bded2dbSJung-uk Kim SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE),
3847bded2dbSJung-uk Kim SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE),
3857bded2dbSJung-uk Kim SSL_FLAG_TBL("UnsafeLegacyRenegotiation",
3867bded2dbSJung-uk Kim SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION),
387b077aed3SPierre Pronchery SSL_FLAG_TBL("UnsafeLegacyServerConnect",
388b077aed3SPierre Pronchery SSL_OP_LEGACY_SERVER_CONNECT),
389b077aed3SPierre Pronchery SSL_FLAG_TBL("ClientRenegotiation",
390b077aed3SPierre Pronchery SSL_OP_ALLOW_CLIENT_RENEGOTIATION),
391e71b7053SJung-uk Kim SSL_FLAG_TBL_INV("EncryptThenMac", SSL_OP_NO_ENCRYPT_THEN_MAC),
392e71b7053SJung-uk Kim SSL_FLAG_TBL("NoRenegotiation", SSL_OP_NO_RENEGOTIATION),
393e71b7053SJung-uk Kim SSL_FLAG_TBL("AllowNoDHEKEX", SSL_OP_ALLOW_NO_DHE_KEX),
394e71b7053SJung-uk Kim SSL_FLAG_TBL("PrioritizeChaCha", SSL_OP_PRIORITIZE_CHACHA),
395e71b7053SJung-uk Kim SSL_FLAG_TBL("MiddleboxCompat", SSL_OP_ENABLE_MIDDLEBOX_COMPAT),
39662ca9fc1SJohn Baldwin SSL_FLAG_TBL_INV("AntiReplay", SSL_OP_NO_ANTI_REPLAY),
397b077aed3SPierre Pronchery SSL_FLAG_TBL_INV("ExtendedMasterSecret", SSL_OP_NO_EXTENDED_MASTER_SECRET),
398b077aed3SPierre Pronchery SSL_FLAG_TBL_INV("CANames", SSL_OP_DISABLE_TLSEXT_CA_NAMES),
39962ca9fc1SJohn Baldwin SSL_FLAG_TBL("KTLS", SSL_OP_ENABLE_KTLS)
4007bded2dbSJung-uk Kim };
4017bded2dbSJung-uk Kim if (value == NULL)
4027bded2dbSJung-uk Kim return -3;
4037bded2dbSJung-uk Kim cctx->tbl = ssl_option_list;
404e71b7053SJung-uk Kim cctx->ntbl = OSSL_NELEM(ssl_option_list);
405e71b7053SJung-uk Kim return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
406e71b7053SJung-uk Kim }
407e71b7053SJung-uk Kim
cmd_VerifyMode(SSL_CONF_CTX * cctx,const char * value)408e71b7053SJung-uk Kim static int cmd_VerifyMode(SSL_CONF_CTX *cctx, const char *value)
409e71b7053SJung-uk Kim {
410e71b7053SJung-uk Kim static const ssl_flag_tbl ssl_vfy_list[] = {
411e71b7053SJung-uk Kim SSL_FLAG_VFY_CLI("Peer", SSL_VERIFY_PEER),
412e71b7053SJung-uk Kim SSL_FLAG_VFY_SRV("Request", SSL_VERIFY_PEER),
413e71b7053SJung-uk Kim SSL_FLAG_VFY_SRV("Require",
414e71b7053SJung-uk Kim SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT),
415e71b7053SJung-uk Kim SSL_FLAG_VFY_SRV("Once", SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE),
416e71b7053SJung-uk Kim SSL_FLAG_VFY_SRV("RequestPostHandshake",
417e71b7053SJung-uk Kim SSL_VERIFY_PEER | SSL_VERIFY_POST_HANDSHAKE),
418e71b7053SJung-uk Kim SSL_FLAG_VFY_SRV("RequirePostHandshake",
419e71b7053SJung-uk Kim SSL_VERIFY_PEER | SSL_VERIFY_POST_HANDSHAKE |
420e71b7053SJung-uk Kim SSL_VERIFY_FAIL_IF_NO_PEER_CERT),
421e71b7053SJung-uk Kim };
422e71b7053SJung-uk Kim if (value == NULL)
423e71b7053SJung-uk Kim return -3;
424e71b7053SJung-uk Kim cctx->tbl = ssl_vfy_list;
425e71b7053SJung-uk Kim cctx->ntbl = OSSL_NELEM(ssl_vfy_list);
4267bded2dbSJung-uk Kim return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
4277bded2dbSJung-uk Kim }
4287bded2dbSJung-uk Kim
cmd_Certificate(SSL_CONF_CTX * cctx,const char * value)4297bded2dbSJung-uk Kim static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value)
4307bded2dbSJung-uk Kim {
4317bded2dbSJung-uk Kim int rv = 1;
432e71b7053SJung-uk Kim CERT *c = NULL;
433e71b7053SJung-uk Kim if (cctx->ctx) {
4347bded2dbSJung-uk Kim rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value);
435e71b7053SJung-uk Kim c = cctx->ctx->cert;
436e71b7053SJung-uk Kim }
437e71b7053SJung-uk Kim if (cctx->ssl) {
438e71b7053SJung-uk Kim rv = SSL_use_certificate_chain_file(cctx->ssl, value);
439e71b7053SJung-uk Kim c = cctx->ssl->cert;
440e71b7053SJung-uk Kim }
441e71b7053SJung-uk Kim if (rv > 0 && c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
442e71b7053SJung-uk Kim char **pfilename = &cctx->cert_filename[c->key - c->pkeys];
443e71b7053SJung-uk Kim OPENSSL_free(*pfilename);
444e71b7053SJung-uk Kim *pfilename = OPENSSL_strdup(value);
445b077aed3SPierre Pronchery if (*pfilename == NULL)
446e71b7053SJung-uk Kim rv = 0;
447e71b7053SJung-uk Kim }
448e71b7053SJung-uk Kim
4497bded2dbSJung-uk Kim return rv > 0;
4507bded2dbSJung-uk Kim }
4517bded2dbSJung-uk Kim
cmd_PrivateKey(SSL_CONF_CTX * cctx,const char * value)4527bded2dbSJung-uk Kim static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value)
4537bded2dbSJung-uk Kim {
4547bded2dbSJung-uk Kim int rv = 1;
4557bded2dbSJung-uk Kim if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
4567bded2dbSJung-uk Kim return -2;
4577bded2dbSJung-uk Kim if (cctx->ctx)
4587bded2dbSJung-uk Kim rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM);
4597bded2dbSJung-uk Kim if (cctx->ssl)
4607bded2dbSJung-uk Kim rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM);
4617bded2dbSJung-uk Kim return rv > 0;
4627bded2dbSJung-uk Kim }
4637bded2dbSJung-uk Kim
cmd_ServerInfoFile(SSL_CONF_CTX * cctx,const char * value)4647bded2dbSJung-uk Kim static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value)
4657bded2dbSJung-uk Kim {
4667bded2dbSJung-uk Kim int rv = 1;
4677bded2dbSJung-uk Kim if (cctx->ctx)
4687bded2dbSJung-uk Kim rv = SSL_CTX_use_serverinfo_file(cctx->ctx, value);
4697bded2dbSJung-uk Kim return rv > 0;
4707bded2dbSJung-uk Kim }
4717bded2dbSJung-uk Kim
do_store(SSL_CONF_CTX * cctx,const char * CAfile,const char * CApath,const char * CAstore,int verify_store)472e71b7053SJung-uk Kim static int do_store(SSL_CONF_CTX *cctx,
473b077aed3SPierre Pronchery const char *CAfile, const char *CApath, const char *CAstore,
474b077aed3SPierre Pronchery int verify_store)
475e71b7053SJung-uk Kim {
476e71b7053SJung-uk Kim CERT *cert;
477e71b7053SJung-uk Kim X509_STORE **st;
478b077aed3SPierre Pronchery SSL_CTX *ctx;
479b077aed3SPierre Pronchery OSSL_LIB_CTX *libctx = NULL;
480b077aed3SPierre Pronchery const char *propq = NULL;
481b077aed3SPierre Pronchery
482b077aed3SPierre Pronchery if (cctx->ctx != NULL) {
483e71b7053SJung-uk Kim cert = cctx->ctx->cert;
484b077aed3SPierre Pronchery ctx = cctx->ctx;
485b077aed3SPierre Pronchery } else if (cctx->ssl != NULL) {
486e71b7053SJung-uk Kim cert = cctx->ssl->cert;
487b077aed3SPierre Pronchery ctx = cctx->ssl->ctx;
488b077aed3SPierre Pronchery } else {
489e71b7053SJung-uk Kim return 1;
490b077aed3SPierre Pronchery }
491b077aed3SPierre Pronchery if (ctx != NULL) {
492b077aed3SPierre Pronchery libctx = ctx->libctx;
493b077aed3SPierre Pronchery propq = ctx->propq;
494b077aed3SPierre Pronchery }
495e71b7053SJung-uk Kim st = verify_store ? &cert->verify_store : &cert->chain_store;
496e71b7053SJung-uk Kim if (*st == NULL) {
497e71b7053SJung-uk Kim *st = X509_STORE_new();
498e71b7053SJung-uk Kim if (*st == NULL)
499e71b7053SJung-uk Kim return 0;
500e71b7053SJung-uk Kim }
501b077aed3SPierre Pronchery
502b077aed3SPierre Pronchery if (CAfile != NULL && !X509_STORE_load_file_ex(*st, CAfile, libctx, propq))
503b077aed3SPierre Pronchery return 0;
504b077aed3SPierre Pronchery if (CApath != NULL && !X509_STORE_load_path(*st, CApath))
505b077aed3SPierre Pronchery return 0;
506b077aed3SPierre Pronchery if (CAstore != NULL && !X509_STORE_load_store_ex(*st, CAstore, libctx,
507b077aed3SPierre Pronchery propq))
508b077aed3SPierre Pronchery return 0;
509b077aed3SPierre Pronchery return 1;
510e71b7053SJung-uk Kim }
511e71b7053SJung-uk Kim
cmd_ChainCAPath(SSL_CONF_CTX * cctx,const char * value)512e71b7053SJung-uk Kim static int cmd_ChainCAPath(SSL_CONF_CTX *cctx, const char *value)
513e71b7053SJung-uk Kim {
514b077aed3SPierre Pronchery return do_store(cctx, NULL, value, NULL, 0);
515e71b7053SJung-uk Kim }
516e71b7053SJung-uk Kim
cmd_ChainCAFile(SSL_CONF_CTX * cctx,const char * value)517e71b7053SJung-uk Kim static int cmd_ChainCAFile(SSL_CONF_CTX *cctx, const char *value)
518e71b7053SJung-uk Kim {
519b077aed3SPierre Pronchery return do_store(cctx, value, NULL, NULL, 0);
520b077aed3SPierre Pronchery }
521b077aed3SPierre Pronchery
cmd_ChainCAStore(SSL_CONF_CTX * cctx,const char * value)522b077aed3SPierre Pronchery static int cmd_ChainCAStore(SSL_CONF_CTX *cctx, const char *value)
523b077aed3SPierre Pronchery {
524b077aed3SPierre Pronchery return do_store(cctx, NULL, NULL, value, 0);
525e71b7053SJung-uk Kim }
526e71b7053SJung-uk Kim
cmd_VerifyCAPath(SSL_CONF_CTX * cctx,const char * value)527e71b7053SJung-uk Kim static int cmd_VerifyCAPath(SSL_CONF_CTX *cctx, const char *value)
528e71b7053SJung-uk Kim {
529b077aed3SPierre Pronchery return do_store(cctx, NULL, value, NULL, 1);
530e71b7053SJung-uk Kim }
531e71b7053SJung-uk Kim
cmd_VerifyCAFile(SSL_CONF_CTX * cctx,const char * value)532e71b7053SJung-uk Kim static int cmd_VerifyCAFile(SSL_CONF_CTX *cctx, const char *value)
533e71b7053SJung-uk Kim {
534b077aed3SPierre Pronchery return do_store(cctx, value, NULL, NULL, 1);
535b077aed3SPierre Pronchery }
536b077aed3SPierre Pronchery
cmd_VerifyCAStore(SSL_CONF_CTX * cctx,const char * value)537b077aed3SPierre Pronchery static int cmd_VerifyCAStore(SSL_CONF_CTX *cctx, const char *value)
538b077aed3SPierre Pronchery {
539b077aed3SPierre Pronchery return do_store(cctx, NULL, NULL, value, 1);
540e71b7053SJung-uk Kim }
541e71b7053SJung-uk Kim
cmd_RequestCAFile(SSL_CONF_CTX * cctx,const char * value)542e71b7053SJung-uk Kim static int cmd_RequestCAFile(SSL_CONF_CTX *cctx, const char *value)
543e71b7053SJung-uk Kim {
544e71b7053SJung-uk Kim if (cctx->canames == NULL)
545e71b7053SJung-uk Kim cctx->canames = sk_X509_NAME_new_null();
546e71b7053SJung-uk Kim if (cctx->canames == NULL)
547e71b7053SJung-uk Kim return 0;
548e71b7053SJung-uk Kim return SSL_add_file_cert_subjects_to_stack(cctx->canames, value);
549e71b7053SJung-uk Kim }
550e71b7053SJung-uk Kim
cmd_ClientCAFile(SSL_CONF_CTX * cctx,const char * value)551e71b7053SJung-uk Kim static int cmd_ClientCAFile(SSL_CONF_CTX *cctx, const char *value)
552e71b7053SJung-uk Kim {
553e71b7053SJung-uk Kim return cmd_RequestCAFile(cctx, value);
554e71b7053SJung-uk Kim }
555e71b7053SJung-uk Kim
cmd_RequestCAPath(SSL_CONF_CTX * cctx,const char * value)556e71b7053SJung-uk Kim static int cmd_RequestCAPath(SSL_CONF_CTX *cctx, const char *value)
557e71b7053SJung-uk Kim {
558e71b7053SJung-uk Kim if (cctx->canames == NULL)
559e71b7053SJung-uk Kim cctx->canames = sk_X509_NAME_new_null();
560e71b7053SJung-uk Kim if (cctx->canames == NULL)
561e71b7053SJung-uk Kim return 0;
562e71b7053SJung-uk Kim return SSL_add_dir_cert_subjects_to_stack(cctx->canames, value);
563e71b7053SJung-uk Kim }
564e71b7053SJung-uk Kim
cmd_ClientCAPath(SSL_CONF_CTX * cctx,const char * value)565e71b7053SJung-uk Kim static int cmd_ClientCAPath(SSL_CONF_CTX *cctx, const char *value)
566e71b7053SJung-uk Kim {
567e71b7053SJung-uk Kim return cmd_RequestCAPath(cctx, value);
568e71b7053SJung-uk Kim }
569e71b7053SJung-uk Kim
cmd_RequestCAStore(SSL_CONF_CTX * cctx,const char * value)570b077aed3SPierre Pronchery static int cmd_RequestCAStore(SSL_CONF_CTX *cctx, const char *value)
571b077aed3SPierre Pronchery {
572b077aed3SPierre Pronchery if (cctx->canames == NULL)
573b077aed3SPierre Pronchery cctx->canames = sk_X509_NAME_new_null();
574b077aed3SPierre Pronchery if (cctx->canames == NULL)
575b077aed3SPierre Pronchery return 0;
576b077aed3SPierre Pronchery return SSL_add_store_cert_subjects_to_stack(cctx->canames, value);
577b077aed3SPierre Pronchery }
578b077aed3SPierre Pronchery
cmd_ClientCAStore(SSL_CONF_CTX * cctx,const char * value)579b077aed3SPierre Pronchery static int cmd_ClientCAStore(SSL_CONF_CTX *cctx, const char *value)
580b077aed3SPierre Pronchery {
581b077aed3SPierre Pronchery return cmd_RequestCAStore(cctx, value);
582b077aed3SPierre Pronchery }
583b077aed3SPierre Pronchery
cmd_DHParameters(SSL_CONF_CTX * cctx,const char * value)5847bded2dbSJung-uk Kim static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value)
5857bded2dbSJung-uk Kim {
5867bded2dbSJung-uk Kim int rv = 0;
587b077aed3SPierre Pronchery EVP_PKEY *dhpkey = NULL;
5887bded2dbSJung-uk Kim BIO *in = NULL;
589b077aed3SPierre Pronchery SSL_CTX *sslctx = (cctx->ssl != NULL) ? cctx->ssl->ctx : cctx->ctx;
590b077aed3SPierre Pronchery OSSL_DECODER_CTX *decoderctx = NULL;
591b077aed3SPierre Pronchery
592b077aed3SPierre Pronchery if (cctx->ctx != NULL || cctx->ssl != NULL) {
593e71b7053SJung-uk Kim in = BIO_new(BIO_s_file());
594e71b7053SJung-uk Kim if (in == NULL)
5957bded2dbSJung-uk Kim goto end;
5967bded2dbSJung-uk Kim if (BIO_read_filename(in, value) <= 0)
5977bded2dbSJung-uk Kim goto end;
598b077aed3SPierre Pronchery
599b077aed3SPierre Pronchery decoderctx
600b077aed3SPierre Pronchery = OSSL_DECODER_CTX_new_for_pkey(&dhpkey, "PEM", NULL, "DH",
601b077aed3SPierre Pronchery OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
602b077aed3SPierre Pronchery sslctx->libctx, sslctx->propq);
603b077aed3SPierre Pronchery if (decoderctx == NULL)
6047bded2dbSJung-uk Kim goto end;
605b077aed3SPierre Pronchery ERR_set_mark();
606b077aed3SPierre Pronchery while (!OSSL_DECODER_from_bio(decoderctx, in)
607b077aed3SPierre Pronchery && dhpkey == NULL
608b077aed3SPierre Pronchery && !BIO_eof(in));
609b077aed3SPierre Pronchery OSSL_DECODER_CTX_free(decoderctx);
610b077aed3SPierre Pronchery
611b077aed3SPierre Pronchery if (dhpkey == NULL) {
612b077aed3SPierre Pronchery ERR_clear_last_mark();
613b077aed3SPierre Pronchery goto end;
614b077aed3SPierre Pronchery }
615b077aed3SPierre Pronchery ERR_pop_to_mark();
616b077aed3SPierre Pronchery } else {
6177bded2dbSJung-uk Kim return 1;
618b077aed3SPierre Pronchery }
619b077aed3SPierre Pronchery
620b077aed3SPierre Pronchery if (cctx->ctx != NULL) {
621b077aed3SPierre Pronchery if ((rv = SSL_CTX_set0_tmp_dh_pkey(cctx->ctx, dhpkey)) > 0)
622b077aed3SPierre Pronchery dhpkey = NULL;
623b077aed3SPierre Pronchery }
624b077aed3SPierre Pronchery if (cctx->ssl != NULL) {
625b077aed3SPierre Pronchery if ((rv = SSL_set0_tmp_dh_pkey(cctx->ssl, dhpkey)) > 0)
626b077aed3SPierre Pronchery dhpkey = NULL;
627b077aed3SPierre Pronchery }
6287bded2dbSJung-uk Kim end:
629b077aed3SPierre Pronchery EVP_PKEY_free(dhpkey);
6307bded2dbSJung-uk Kim BIO_free(in);
6317bded2dbSJung-uk Kim return rv > 0;
6327bded2dbSJung-uk Kim }
633e71b7053SJung-uk Kim
cmd_RecordPadding(SSL_CONF_CTX * cctx,const char * value)634e71b7053SJung-uk Kim static int cmd_RecordPadding(SSL_CONF_CTX *cctx, const char *value)
635e71b7053SJung-uk Kim {
636e71b7053SJung-uk Kim int rv = 0;
637e71b7053SJung-uk Kim int block_size = atoi(value);
638e71b7053SJung-uk Kim
639e71b7053SJung-uk Kim /*
640e71b7053SJung-uk Kim * All we care about is a non-negative value,
641e71b7053SJung-uk Kim * the setters check the range
642e71b7053SJung-uk Kim */
643e71b7053SJung-uk Kim if (block_size >= 0) {
644e71b7053SJung-uk Kim if (cctx->ctx)
645e71b7053SJung-uk Kim rv = SSL_CTX_set_block_padding(cctx->ctx, block_size);
646e71b7053SJung-uk Kim if (cctx->ssl)
647e71b7053SJung-uk Kim rv = SSL_set_block_padding(cctx->ssl, block_size);
648e71b7053SJung-uk Kim }
649e71b7053SJung-uk Kim return rv;
650e71b7053SJung-uk Kim }
651e71b7053SJung-uk Kim
652e71b7053SJung-uk Kim
cmd_NumTickets(SSL_CONF_CTX * cctx,const char * value)653e71b7053SJung-uk Kim static int cmd_NumTickets(SSL_CONF_CTX *cctx, const char *value)
654e71b7053SJung-uk Kim {
655e71b7053SJung-uk Kim int rv = 0;
656e71b7053SJung-uk Kim int num_tickets = atoi(value);
657e71b7053SJung-uk Kim
658e71b7053SJung-uk Kim if (num_tickets >= 0) {
659e71b7053SJung-uk Kim if (cctx->ctx)
660e71b7053SJung-uk Kim rv = SSL_CTX_set_num_tickets(cctx->ctx, num_tickets);
661e71b7053SJung-uk Kim if (cctx->ssl)
662e71b7053SJung-uk Kim rv = SSL_set_num_tickets(cctx->ssl, num_tickets);
663e71b7053SJung-uk Kim }
664e71b7053SJung-uk Kim return rv;
665e71b7053SJung-uk Kim }
666e71b7053SJung-uk Kim
6677bded2dbSJung-uk Kim typedef struct {
6687bded2dbSJung-uk Kim int (*cmd) (SSL_CONF_CTX *cctx, const char *value);
6697bded2dbSJung-uk Kim const char *str_file;
6707bded2dbSJung-uk Kim const char *str_cmdline;
671e71b7053SJung-uk Kim unsigned short flags;
672e71b7053SJung-uk Kim unsigned short value_type;
6737bded2dbSJung-uk Kim } ssl_conf_cmd_tbl;
6747bded2dbSJung-uk Kim
6757bded2dbSJung-uk Kim /* Table of supported parameters */
6767bded2dbSJung-uk Kim
677e71b7053SJung-uk Kim #define SSL_CONF_CMD(name, cmdopt, flags, type) \
678e71b7053SJung-uk Kim {cmd_##name, #name, cmdopt, flags, type}
6797bded2dbSJung-uk Kim
680e71b7053SJung-uk Kim #define SSL_CONF_CMD_STRING(name, cmdopt, flags) \
681e71b7053SJung-uk Kim SSL_CONF_CMD(name, cmdopt, flags, SSL_CONF_TYPE_STRING)
6827bded2dbSJung-uk Kim
683e71b7053SJung-uk Kim #define SSL_CONF_CMD_SWITCH(name, flags) \
684e71b7053SJung-uk Kim {0, NULL, name, flags, SSL_CONF_TYPE_NONE}
685e71b7053SJung-uk Kim
686b077aed3SPierre Pronchery /* See apps/include/opt.h if you change this table. */
687b077aed3SPierre Pronchery /* The SSL_CONF_CMD_SWITCH should be the same order as ssl_cmd_switches */
6887bded2dbSJung-uk Kim static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
689e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("no_ssl3", 0),
690e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("no_tls1", 0),
691e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("no_tls1_1", 0),
692e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("no_tls1_2", 0),
693e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("no_tls1_3", 0),
694e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("bugs", 0),
695e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("no_comp", 0),
696e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("comp", 0),
697e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("ecdh_single", SSL_CONF_FLAG_SERVER),
698e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("no_ticket", 0),
699e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("serverpref", SSL_CONF_FLAG_SERVER),
700e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("legacy_renegotiation", 0),
701b077aed3SPierre Pronchery SSL_CONF_CMD_SWITCH("client_renegotiation", SSL_CONF_FLAG_SERVER),
702b077aed3SPierre Pronchery SSL_CONF_CMD_SWITCH("legacy_server_connect", SSL_CONF_FLAG_CLIENT),
703e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("no_renegotiation", 0),
704e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("no_resumption_on_reneg", SSL_CONF_FLAG_SERVER),
705b077aed3SPierre Pronchery SSL_CONF_CMD_SWITCH("no_legacy_server_connect", SSL_CONF_FLAG_CLIENT),
706e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("allow_no_dhe_kex", 0),
707e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("prioritize_chacha", SSL_CONF_FLAG_SERVER),
708e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("strict", 0),
709e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("no_middlebox", 0),
710e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("anti_replay", SSL_CONF_FLAG_SERVER),
711e71b7053SJung-uk Kim SSL_CONF_CMD_SWITCH("no_anti_replay", SSL_CONF_FLAG_SERVER),
712b077aed3SPierre Pronchery SSL_CONF_CMD_SWITCH("no_etm", 0),
713e71b7053SJung-uk Kim SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs", 0),
714e71b7053SJung-uk Kim SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs", 0),
715e71b7053SJung-uk Kim SSL_CONF_CMD_STRING(Curves, "curves", 0),
716e71b7053SJung-uk Kim SSL_CONF_CMD_STRING(Groups, "groups", 0),
717e71b7053SJung-uk Kim SSL_CONF_CMD_STRING(ECDHParameters, "named_curve", SSL_CONF_FLAG_SERVER),
718e71b7053SJung-uk Kim SSL_CONF_CMD_STRING(CipherString, "cipher", 0),
719e71b7053SJung-uk Kim SSL_CONF_CMD_STRING(Ciphersuites, "ciphersuites", 0),
720e71b7053SJung-uk Kim SSL_CONF_CMD_STRING(Protocol, NULL, 0),
721e71b7053SJung-uk Kim SSL_CONF_CMD_STRING(MinProtocol, "min_protocol", 0),
722e71b7053SJung-uk Kim SSL_CONF_CMD_STRING(MaxProtocol, "max_protocol", 0),
723e71b7053SJung-uk Kim SSL_CONF_CMD_STRING(Options, NULL, 0),
724e71b7053SJung-uk Kim SSL_CONF_CMD_STRING(VerifyMode, NULL, 0),
725e71b7053SJung-uk Kim SSL_CONF_CMD(Certificate, "cert", SSL_CONF_FLAG_CERTIFICATE,
726e71b7053SJung-uk Kim SSL_CONF_TYPE_FILE),
727e71b7053SJung-uk Kim SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_FLAG_CERTIFICATE,
728e71b7053SJung-uk Kim SSL_CONF_TYPE_FILE),
729e71b7053SJung-uk Kim SSL_CONF_CMD(ServerInfoFile, NULL,
730e71b7053SJung-uk Kim SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
731e71b7053SJung-uk Kim SSL_CONF_TYPE_FILE),
732e71b7053SJung-uk Kim SSL_CONF_CMD(ChainCAPath, "chainCApath", SSL_CONF_FLAG_CERTIFICATE,
733e71b7053SJung-uk Kim SSL_CONF_TYPE_DIR),
734e71b7053SJung-uk Kim SSL_CONF_CMD(ChainCAFile, "chainCAfile", SSL_CONF_FLAG_CERTIFICATE,
735e71b7053SJung-uk Kim SSL_CONF_TYPE_FILE),
736b077aed3SPierre Pronchery SSL_CONF_CMD(ChainCAStore, "chainCAstore", SSL_CONF_FLAG_CERTIFICATE,
737b077aed3SPierre Pronchery SSL_CONF_TYPE_STORE),
738e71b7053SJung-uk Kim SSL_CONF_CMD(VerifyCAPath, "verifyCApath", SSL_CONF_FLAG_CERTIFICATE,
739e71b7053SJung-uk Kim SSL_CONF_TYPE_DIR),
740e71b7053SJung-uk Kim SSL_CONF_CMD(VerifyCAFile, "verifyCAfile", SSL_CONF_FLAG_CERTIFICATE,
741e71b7053SJung-uk Kim SSL_CONF_TYPE_FILE),
742b077aed3SPierre Pronchery SSL_CONF_CMD(VerifyCAStore, "verifyCAstore", SSL_CONF_FLAG_CERTIFICATE,
743b077aed3SPierre Pronchery SSL_CONF_TYPE_STORE),
744e71b7053SJung-uk Kim SSL_CONF_CMD(RequestCAFile, "requestCAFile", SSL_CONF_FLAG_CERTIFICATE,
745e71b7053SJung-uk Kim SSL_CONF_TYPE_FILE),
746e71b7053SJung-uk Kim SSL_CONF_CMD(ClientCAFile, NULL,
747e71b7053SJung-uk Kim SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
748e71b7053SJung-uk Kim SSL_CONF_TYPE_FILE),
749e71b7053SJung-uk Kim SSL_CONF_CMD(RequestCAPath, NULL, SSL_CONF_FLAG_CERTIFICATE,
750e71b7053SJung-uk Kim SSL_CONF_TYPE_DIR),
751e71b7053SJung-uk Kim SSL_CONF_CMD(ClientCAPath, NULL,
752e71b7053SJung-uk Kim SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
753e71b7053SJung-uk Kim SSL_CONF_TYPE_DIR),
754b077aed3SPierre Pronchery SSL_CONF_CMD(RequestCAStore, "requestCAStore", SSL_CONF_FLAG_CERTIFICATE,
755b077aed3SPierre Pronchery SSL_CONF_TYPE_STORE),
756b077aed3SPierre Pronchery SSL_CONF_CMD(ClientCAStore, NULL,
757b077aed3SPierre Pronchery SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
758b077aed3SPierre Pronchery SSL_CONF_TYPE_STORE),
759e71b7053SJung-uk Kim SSL_CONF_CMD(DHParameters, "dhparam",
760e71b7053SJung-uk Kim SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
761e71b7053SJung-uk Kim SSL_CONF_TYPE_FILE),
762e71b7053SJung-uk Kim SSL_CONF_CMD_STRING(RecordPadding, "record_padding", 0),
763e71b7053SJung-uk Kim SSL_CONF_CMD_STRING(NumTickets, "num_tickets", SSL_CONF_FLAG_SERVER),
764e71b7053SJung-uk Kim };
765e71b7053SJung-uk Kim
766e71b7053SJung-uk Kim /* Supported switches: must match order of switches in ssl_conf_cmds */
767e71b7053SJung-uk Kim static const ssl_switch_tbl ssl_cmd_switches[] = {
768e71b7053SJung-uk Kim {SSL_OP_NO_SSLv3, 0}, /* no_ssl3 */
769e71b7053SJung-uk Kim {SSL_OP_NO_TLSv1, 0}, /* no_tls1 */
770e71b7053SJung-uk Kim {SSL_OP_NO_TLSv1_1, 0}, /* no_tls1_1 */
771e71b7053SJung-uk Kim {SSL_OP_NO_TLSv1_2, 0}, /* no_tls1_2 */
772e71b7053SJung-uk Kim {SSL_OP_NO_TLSv1_3, 0}, /* no_tls1_3 */
773e71b7053SJung-uk Kim {SSL_OP_ALL, 0}, /* bugs */
774e71b7053SJung-uk Kim {SSL_OP_NO_COMPRESSION, 0}, /* no_comp */
775e71b7053SJung-uk Kim {SSL_OP_NO_COMPRESSION, SSL_TFLAG_INV}, /* comp */
776e71b7053SJung-uk Kim {SSL_OP_SINGLE_ECDH_USE, 0}, /* ecdh_single */
777e71b7053SJung-uk Kim {SSL_OP_NO_TICKET, 0}, /* no_ticket */
778e71b7053SJung-uk Kim {SSL_OP_CIPHER_SERVER_PREFERENCE, 0}, /* serverpref */
779e71b7053SJung-uk Kim /* legacy_renegotiation */
780e71b7053SJung-uk Kim {SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, 0},
781b077aed3SPierre Pronchery /* Allow client renegotiation */
782b077aed3SPierre Pronchery {SSL_OP_ALLOW_CLIENT_RENEGOTIATION, 0},
783e71b7053SJung-uk Kim /* legacy_server_connect */
784e71b7053SJung-uk Kim {SSL_OP_LEGACY_SERVER_CONNECT, 0},
785e71b7053SJung-uk Kim /* no_renegotiation */
786e71b7053SJung-uk Kim {SSL_OP_NO_RENEGOTIATION, 0},
787e71b7053SJung-uk Kim /* no_resumption_on_reneg */
788e71b7053SJung-uk Kim {SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION, 0},
789e71b7053SJung-uk Kim /* no_legacy_server_connect */
790e71b7053SJung-uk Kim {SSL_OP_LEGACY_SERVER_CONNECT, SSL_TFLAG_INV},
791e71b7053SJung-uk Kim /* allow_no_dhe_kex */
792e71b7053SJung-uk Kim {SSL_OP_ALLOW_NO_DHE_KEX, 0},
793e71b7053SJung-uk Kim /* chacha reprioritization */
794e71b7053SJung-uk Kim {SSL_OP_PRIORITIZE_CHACHA, 0},
795e71b7053SJung-uk Kim {SSL_CERT_FLAG_TLS_STRICT, SSL_TFLAG_CERT}, /* strict */
796e71b7053SJung-uk Kim /* no_middlebox */
797e71b7053SJung-uk Kim {SSL_OP_ENABLE_MIDDLEBOX_COMPAT, SSL_TFLAG_INV},
798e71b7053SJung-uk Kim /* anti_replay */
799e71b7053SJung-uk Kim {SSL_OP_NO_ANTI_REPLAY, SSL_TFLAG_INV},
800e71b7053SJung-uk Kim /* no_anti_replay */
801e71b7053SJung-uk Kim {SSL_OP_NO_ANTI_REPLAY, 0},
802b077aed3SPierre Pronchery /* no Encrypt-then-Mac */
803b077aed3SPierre Pronchery {SSL_OP_NO_ENCRYPT_THEN_MAC, 0},
8047bded2dbSJung-uk Kim };
8057bded2dbSJung-uk Kim
ssl_conf_cmd_skip_prefix(SSL_CONF_CTX * cctx,const char ** pcmd)8067bded2dbSJung-uk Kim static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd)
8077bded2dbSJung-uk Kim {
808b077aed3SPierre Pronchery if (pcmd == NULL || *pcmd == NULL)
8097bded2dbSJung-uk Kim return 0;
8107bded2dbSJung-uk Kim /* If a prefix is set, check and skip */
8117bded2dbSJung-uk Kim if (cctx->prefix) {
8127bded2dbSJung-uk Kim if (strlen(*pcmd) <= cctx->prefixlen)
8137bded2dbSJung-uk Kim return 0;
8147bded2dbSJung-uk Kim if (cctx->flags & SSL_CONF_FLAG_CMDLINE &&
8157bded2dbSJung-uk Kim strncmp(*pcmd, cctx->prefix, cctx->prefixlen))
8167bded2dbSJung-uk Kim return 0;
8177bded2dbSJung-uk Kim if (cctx->flags & SSL_CONF_FLAG_FILE &&
818b077aed3SPierre Pronchery OPENSSL_strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen))
8197bded2dbSJung-uk Kim return 0;
8207bded2dbSJung-uk Kim *pcmd += cctx->prefixlen;
8217bded2dbSJung-uk Kim } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
8227bded2dbSJung-uk Kim if (**pcmd != '-' || !(*pcmd)[1])
8237bded2dbSJung-uk Kim return 0;
8247bded2dbSJung-uk Kim *pcmd += 1;
8257bded2dbSJung-uk Kim }
8267bded2dbSJung-uk Kim return 1;
8277bded2dbSJung-uk Kim }
8287bded2dbSJung-uk Kim
829e71b7053SJung-uk Kim /* Determine if a command is allowed according to cctx flags */
ssl_conf_cmd_allowed(SSL_CONF_CTX * cctx,const ssl_conf_cmd_tbl * t)830e71b7053SJung-uk Kim static int ssl_conf_cmd_allowed(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl * t)
831e71b7053SJung-uk Kim {
832e71b7053SJung-uk Kim unsigned int tfl = t->flags;
833e71b7053SJung-uk Kim unsigned int cfl = cctx->flags;
834e71b7053SJung-uk Kim if ((tfl & SSL_CONF_FLAG_SERVER) && !(cfl & SSL_CONF_FLAG_SERVER))
835e71b7053SJung-uk Kim return 0;
836e71b7053SJung-uk Kim if ((tfl & SSL_CONF_FLAG_CLIENT) && !(cfl & SSL_CONF_FLAG_CLIENT))
837e71b7053SJung-uk Kim return 0;
838e71b7053SJung-uk Kim if ((tfl & SSL_CONF_FLAG_CERTIFICATE)
839e71b7053SJung-uk Kim && !(cfl & SSL_CONF_FLAG_CERTIFICATE))
840e71b7053SJung-uk Kim return 0;
841e71b7053SJung-uk Kim return 1;
842e71b7053SJung-uk Kim }
843e71b7053SJung-uk Kim
ssl_conf_cmd_lookup(SSL_CONF_CTX * cctx,const char * cmd)8447bded2dbSJung-uk Kim static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx,
8457bded2dbSJung-uk Kim const char *cmd)
8467bded2dbSJung-uk Kim {
8477bded2dbSJung-uk Kim const ssl_conf_cmd_tbl *t;
8487bded2dbSJung-uk Kim size_t i;
8497bded2dbSJung-uk Kim if (cmd == NULL)
8507bded2dbSJung-uk Kim return NULL;
8517bded2dbSJung-uk Kim
8527bded2dbSJung-uk Kim /* Look for matching parameter name in table */
853e71b7053SJung-uk Kim for (i = 0, t = ssl_conf_cmds; i < OSSL_NELEM(ssl_conf_cmds); i++, t++) {
854e71b7053SJung-uk Kim if (ssl_conf_cmd_allowed(cctx, t)) {
8557bded2dbSJung-uk Kim if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
856e71b7053SJung-uk Kim if (t->str_cmdline && strcmp(t->str_cmdline, cmd) == 0)
8577bded2dbSJung-uk Kim return t;
8587bded2dbSJung-uk Kim }
8597bded2dbSJung-uk Kim if (cctx->flags & SSL_CONF_FLAG_FILE) {
860b077aed3SPierre Pronchery if (t->str_file && OPENSSL_strcasecmp(t->str_file, cmd) == 0)
8617bded2dbSJung-uk Kim return t;
8627bded2dbSJung-uk Kim }
8637bded2dbSJung-uk Kim }
864e71b7053SJung-uk Kim }
8657bded2dbSJung-uk Kim return NULL;
8667bded2dbSJung-uk Kim }
8677bded2dbSJung-uk Kim
ctrl_switch_option(SSL_CONF_CTX * cctx,const ssl_conf_cmd_tbl * cmd)868e71b7053SJung-uk Kim static int ctrl_switch_option(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl * cmd)
869e71b7053SJung-uk Kim {
870e71b7053SJung-uk Kim /* Find index of command in table */
871e71b7053SJung-uk Kim size_t idx = cmd - ssl_conf_cmds;
872e71b7053SJung-uk Kim const ssl_switch_tbl *scmd;
873*e0c4386eSCy Schubert
874e71b7053SJung-uk Kim /* Sanity check index */
875*e0c4386eSCy Schubert if (idx >= OSSL_NELEM(ssl_cmd_switches)) {
876*e0c4386eSCy Schubert ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
877e71b7053SJung-uk Kim return 0;
878*e0c4386eSCy Schubert }
879e71b7053SJung-uk Kim /* Obtain switches entry with same index */
880e71b7053SJung-uk Kim scmd = ssl_cmd_switches + idx;
881e71b7053SJung-uk Kim ssl_set_option(cctx, scmd->name_flags, scmd->option_value, 1);
882e71b7053SJung-uk Kim return 1;
883e71b7053SJung-uk Kim }
884e71b7053SJung-uk Kim
SSL_CONF_cmd(SSL_CONF_CTX * cctx,const char * cmd,const char * value)8857bded2dbSJung-uk Kim int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value)
8867bded2dbSJung-uk Kim {
8877bded2dbSJung-uk Kim const ssl_conf_cmd_tbl *runcmd;
8887bded2dbSJung-uk Kim if (cmd == NULL) {
889b077aed3SPierre Pronchery ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_NULL_CMD_NAME);
8907bded2dbSJung-uk Kim return 0;
8917bded2dbSJung-uk Kim }
8927bded2dbSJung-uk Kim
8937bded2dbSJung-uk Kim if (!ssl_conf_cmd_skip_prefix(cctx, &cmd))
894*e0c4386eSCy Schubert goto unknown_cmd;
8957bded2dbSJung-uk Kim
8967bded2dbSJung-uk Kim runcmd = ssl_conf_cmd_lookup(cctx, cmd);
8977bded2dbSJung-uk Kim
8987bded2dbSJung-uk Kim if (runcmd) {
899*e0c4386eSCy Schubert int rv = -3;
900*e0c4386eSCy Schubert
901e71b7053SJung-uk Kim if (runcmd->value_type == SSL_CONF_TYPE_NONE) {
902e71b7053SJung-uk Kim return ctrl_switch_option(cctx, runcmd);
903e71b7053SJung-uk Kim }
9047bded2dbSJung-uk Kim if (value == NULL)
905*e0c4386eSCy Schubert goto bad_value;
9067bded2dbSJung-uk Kim rv = runcmd->cmd(cctx, value);
9077bded2dbSJung-uk Kim if (rv > 0)
9087bded2dbSJung-uk Kim return 2;
909*e0c4386eSCy Schubert if (rv != -2)
910*e0c4386eSCy Schubert rv = 0;
911*e0c4386eSCy Schubert
912*e0c4386eSCy Schubert bad_value:
913b077aed3SPierre Pronchery if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS)
914b077aed3SPierre Pronchery ERR_raise_data(ERR_LIB_SSL, SSL_R_BAD_VALUE,
915*e0c4386eSCy Schubert "cmd=%s, value=%s", cmd,
916*e0c4386eSCy Schubert value != NULL ? value : "<EMPTY>");
917*e0c4386eSCy Schubert return rv;
9187bded2dbSJung-uk Kim }
9197bded2dbSJung-uk Kim
920*e0c4386eSCy Schubert unknown_cmd:
921b077aed3SPierre Pronchery if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS)
922b077aed3SPierre Pronchery ERR_raise_data(ERR_LIB_SSL, SSL_R_UNKNOWN_CMD_NAME, "cmd=%s", cmd);
9237bded2dbSJung-uk Kim
9247bded2dbSJung-uk Kim return -2;
9257bded2dbSJung-uk Kim }
9267bded2dbSJung-uk Kim
SSL_CONF_cmd_argv(SSL_CONF_CTX * cctx,int * pargc,char *** pargv)9277bded2dbSJung-uk Kim int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv)
9287bded2dbSJung-uk Kim {
9297bded2dbSJung-uk Kim int rv;
9307bded2dbSJung-uk Kim const char *arg = NULL, *argn;
931b077aed3SPierre Pronchery
932b077aed3SPierre Pronchery if (pargc != NULL && *pargc == 0)
9337bded2dbSJung-uk Kim return 0;
934b077aed3SPierre Pronchery if (pargc == NULL || *pargc > 0)
9357bded2dbSJung-uk Kim arg = **pargv;
9367bded2dbSJung-uk Kim if (arg == NULL)
9377bded2dbSJung-uk Kim return 0;
938b077aed3SPierre Pronchery if (pargc == NULL || *pargc > 1)
9397bded2dbSJung-uk Kim argn = (*pargv)[1];
9407bded2dbSJung-uk Kim else
9417bded2dbSJung-uk Kim argn = NULL;
9427bded2dbSJung-uk Kim cctx->flags &= ~SSL_CONF_FLAG_FILE;
9437bded2dbSJung-uk Kim cctx->flags |= SSL_CONF_FLAG_CMDLINE;
9447bded2dbSJung-uk Kim rv = SSL_CONF_cmd(cctx, arg, argn);
9457bded2dbSJung-uk Kim if (rv > 0) {
9467bded2dbSJung-uk Kim /* Success: update pargc, pargv */
9477bded2dbSJung-uk Kim (*pargv) += rv;
9487bded2dbSJung-uk Kim if (pargc)
9497bded2dbSJung-uk Kim (*pargc) -= rv;
9507bded2dbSJung-uk Kim return rv;
9517bded2dbSJung-uk Kim }
9527bded2dbSJung-uk Kim /* Unknown switch: indicate no arguments processed */
9537bded2dbSJung-uk Kim if (rv == -2)
9547bded2dbSJung-uk Kim return 0;
9557bded2dbSJung-uk Kim /* Some error occurred processing command, return fatal error */
9567bded2dbSJung-uk Kim if (rv == 0)
9577bded2dbSJung-uk Kim return -1;
9587bded2dbSJung-uk Kim return rv;
9597bded2dbSJung-uk Kim }
9607bded2dbSJung-uk Kim
SSL_CONF_cmd_value_type(SSL_CONF_CTX * cctx,const char * cmd)9617bded2dbSJung-uk Kim int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd)
9627bded2dbSJung-uk Kim {
9637bded2dbSJung-uk Kim if (ssl_conf_cmd_skip_prefix(cctx, &cmd)) {
9647bded2dbSJung-uk Kim const ssl_conf_cmd_tbl *runcmd;
9657bded2dbSJung-uk Kim runcmd = ssl_conf_cmd_lookup(cctx, cmd);
9667bded2dbSJung-uk Kim if (runcmd)
9677bded2dbSJung-uk Kim return runcmd->value_type;
9687bded2dbSJung-uk Kim }
9697bded2dbSJung-uk Kim return SSL_CONF_TYPE_UNKNOWN;
9707bded2dbSJung-uk Kim }
9717bded2dbSJung-uk Kim
SSL_CONF_CTX_new(void)9727bded2dbSJung-uk Kim SSL_CONF_CTX *SSL_CONF_CTX_new(void)
9737bded2dbSJung-uk Kim {
974e71b7053SJung-uk Kim SSL_CONF_CTX *ret = OPENSSL_zalloc(sizeof(*ret));
975e71b7053SJung-uk Kim
9767bded2dbSJung-uk Kim return ret;
9777bded2dbSJung-uk Kim }
9787bded2dbSJung-uk Kim
SSL_CONF_CTX_finish(SSL_CONF_CTX * cctx)9797bded2dbSJung-uk Kim int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx)
9807bded2dbSJung-uk Kim {
981e71b7053SJung-uk Kim /* See if any certificates are missing private keys */
982e71b7053SJung-uk Kim size_t i;
983e71b7053SJung-uk Kim CERT *c = NULL;
984e71b7053SJung-uk Kim if (cctx->ctx)
985e71b7053SJung-uk Kim c = cctx->ctx->cert;
986e71b7053SJung-uk Kim else if (cctx->ssl)
987e71b7053SJung-uk Kim c = cctx->ssl->cert;
988e71b7053SJung-uk Kim if (c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
989e71b7053SJung-uk Kim for (i = 0; i < SSL_PKEY_NUM; i++) {
990e71b7053SJung-uk Kim const char *p = cctx->cert_filename[i];
991e71b7053SJung-uk Kim /*
992e71b7053SJung-uk Kim * If missing private key try to load one from certificate file
993e71b7053SJung-uk Kim */
994e71b7053SJung-uk Kim if (p && !c->pkeys[i].privatekey) {
995e71b7053SJung-uk Kim if (!cmd_PrivateKey(cctx, p))
996e71b7053SJung-uk Kim return 0;
997e71b7053SJung-uk Kim }
998e71b7053SJung-uk Kim }
999e71b7053SJung-uk Kim }
1000e71b7053SJung-uk Kim if (cctx->canames) {
1001e71b7053SJung-uk Kim if (cctx->ssl)
1002e71b7053SJung-uk Kim SSL_set0_CA_list(cctx->ssl, cctx->canames);
1003e71b7053SJung-uk Kim else if (cctx->ctx)
1004e71b7053SJung-uk Kim SSL_CTX_set0_CA_list(cctx->ctx, cctx->canames);
1005e71b7053SJung-uk Kim else
1006e71b7053SJung-uk Kim sk_X509_NAME_pop_free(cctx->canames, X509_NAME_free);
1007e71b7053SJung-uk Kim cctx->canames = NULL;
1008e71b7053SJung-uk Kim }
10097bded2dbSJung-uk Kim return 1;
10107bded2dbSJung-uk Kim }
10117bded2dbSJung-uk Kim
SSL_CONF_CTX_free(SSL_CONF_CTX * cctx)10127bded2dbSJung-uk Kim void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx)
10137bded2dbSJung-uk Kim {
10147bded2dbSJung-uk Kim if (cctx) {
1015e71b7053SJung-uk Kim size_t i;
1016e71b7053SJung-uk Kim for (i = 0; i < SSL_PKEY_NUM; i++)
1017e71b7053SJung-uk Kim OPENSSL_free(cctx->cert_filename[i]);
10187bded2dbSJung-uk Kim OPENSSL_free(cctx->prefix);
1019e71b7053SJung-uk Kim sk_X509_NAME_pop_free(cctx->canames, X509_NAME_free);
10207bded2dbSJung-uk Kim OPENSSL_free(cctx);
10217bded2dbSJung-uk Kim }
10227bded2dbSJung-uk Kim }
10237bded2dbSJung-uk Kim
SSL_CONF_CTX_set_flags(SSL_CONF_CTX * cctx,unsigned int flags)10247bded2dbSJung-uk Kim unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags)
10257bded2dbSJung-uk Kim {
10267bded2dbSJung-uk Kim cctx->flags |= flags;
10277bded2dbSJung-uk Kim return cctx->flags;
10287bded2dbSJung-uk Kim }
10297bded2dbSJung-uk Kim
SSL_CONF_CTX_clear_flags(SSL_CONF_CTX * cctx,unsigned int flags)10307bded2dbSJung-uk Kim unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags)
10317bded2dbSJung-uk Kim {
10327bded2dbSJung-uk Kim cctx->flags &= ~flags;
10337bded2dbSJung-uk Kim return cctx->flags;
10347bded2dbSJung-uk Kim }
10357bded2dbSJung-uk Kim
SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX * cctx,const char * pre)10367bded2dbSJung-uk Kim int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre)
10377bded2dbSJung-uk Kim {
10387bded2dbSJung-uk Kim char *tmp = NULL;
10397bded2dbSJung-uk Kim if (pre) {
1040e71b7053SJung-uk Kim tmp = OPENSSL_strdup(pre);
10417bded2dbSJung-uk Kim if (tmp == NULL)
10427bded2dbSJung-uk Kim return 0;
10437bded2dbSJung-uk Kim }
10447bded2dbSJung-uk Kim OPENSSL_free(cctx->prefix);
10457bded2dbSJung-uk Kim cctx->prefix = tmp;
10467bded2dbSJung-uk Kim if (tmp)
10477bded2dbSJung-uk Kim cctx->prefixlen = strlen(tmp);
10487bded2dbSJung-uk Kim else
10497bded2dbSJung-uk Kim cctx->prefixlen = 0;
10507bded2dbSJung-uk Kim return 1;
10517bded2dbSJung-uk Kim }
10527bded2dbSJung-uk Kim
SSL_CONF_CTX_set_ssl(SSL_CONF_CTX * cctx,SSL * ssl)10537bded2dbSJung-uk Kim void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl)
10547bded2dbSJung-uk Kim {
10557bded2dbSJung-uk Kim cctx->ssl = ssl;
10567bded2dbSJung-uk Kim cctx->ctx = NULL;
10577bded2dbSJung-uk Kim if (ssl) {
10587bded2dbSJung-uk Kim cctx->poptions = &ssl->options;
1059e71b7053SJung-uk Kim cctx->min_version = &ssl->min_proto_version;
1060e71b7053SJung-uk Kim cctx->max_version = &ssl->max_proto_version;
10617bded2dbSJung-uk Kim cctx->pcert_flags = &ssl->cert->cert_flags;
1062e71b7053SJung-uk Kim cctx->pvfy_flags = &ssl->verify_mode;
10637bded2dbSJung-uk Kim } else {
10647bded2dbSJung-uk Kim cctx->poptions = NULL;
1065e71b7053SJung-uk Kim cctx->min_version = NULL;
1066e71b7053SJung-uk Kim cctx->max_version = NULL;
10677bded2dbSJung-uk Kim cctx->pcert_flags = NULL;
1068e71b7053SJung-uk Kim cctx->pvfy_flags = NULL;
10697bded2dbSJung-uk Kim }
10707bded2dbSJung-uk Kim }
10717bded2dbSJung-uk Kim
SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX * cctx,SSL_CTX * ctx)10727bded2dbSJung-uk Kim void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx)
10737bded2dbSJung-uk Kim {
10747bded2dbSJung-uk Kim cctx->ctx = ctx;
10757bded2dbSJung-uk Kim cctx->ssl = NULL;
10767bded2dbSJung-uk Kim if (ctx) {
10777bded2dbSJung-uk Kim cctx->poptions = &ctx->options;
1078e71b7053SJung-uk Kim cctx->min_version = &ctx->min_proto_version;
1079e71b7053SJung-uk Kim cctx->max_version = &ctx->max_proto_version;
10807bded2dbSJung-uk Kim cctx->pcert_flags = &ctx->cert->cert_flags;
1081e71b7053SJung-uk Kim cctx->pvfy_flags = &ctx->verify_mode;
10827bded2dbSJung-uk Kim } else {
10837bded2dbSJung-uk Kim cctx->poptions = NULL;
1084e71b7053SJung-uk Kim cctx->min_version = NULL;
1085e71b7053SJung-uk Kim cctx->max_version = NULL;
10867bded2dbSJung-uk Kim cctx->pcert_flags = NULL;
1087e71b7053SJung-uk Kim cctx->pvfy_flags = NULL;
10887bded2dbSJung-uk Kim }
10897bded2dbSJung-uk Kim }
1090