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