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