xref: /openssl/ssl/ssl_conf.c (revision 0abbd3e5)
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         goto out;
670     commap = strstr(copy, ",");
671     if (commap != NULL) {
672         *commap = '\0';
673         if (*(commap + 1) == '\0')
674             goto out;
675         if (!OPENSSL_strtoul(commap + 1, &endptr, 0, &hs_padding))
676             goto out;
677     }
678     if (!OPENSSL_strtoul(copy, &endptr, 0, &block_padding))
679         goto out;
680     if (commap == NULL)
681         hs_padding = block_padding;
682 
683     /*
684      * All we care about are non-negative values,
685      * the setters check the range
686      */
687     if (cctx->ctx)
688         rv = SSL_CTX_set_block_padding_ex(cctx->ctx, (size_t)block_padding,
689                                           (size_t)hs_padding);
690     if (cctx->ssl)
691         rv = SSL_set_block_padding_ex(cctx->ssl, (size_t)block_padding,
692                                       (size_t)hs_padding);
693 out:
694     OPENSSL_free(copy);
695     return rv;
696 }
697 
698 
cmd_NumTickets(SSL_CONF_CTX * cctx,const char * value)699 static int cmd_NumTickets(SSL_CONF_CTX *cctx, const char *value)
700 {
701     int rv = 0;
702     int num_tickets = atoi(value);
703 
704     if (num_tickets >= 0) {
705         if (cctx->ctx)
706             rv = SSL_CTX_set_num_tickets(cctx->ctx, num_tickets);
707         if (cctx->ssl)
708             rv = SSL_set_num_tickets(cctx->ssl, num_tickets);
709     }
710     return rv;
711 }
712 
713 typedef struct {
714     int (*cmd) (SSL_CONF_CTX *cctx, const char *value);
715     const char *str_file;
716     const char *str_cmdline;
717     unsigned short flags;
718     unsigned short value_type;
719 } ssl_conf_cmd_tbl;
720 
721 /* Table of supported parameters */
722 
723 #define SSL_CONF_CMD(name, cmdopt, flags, type) \
724         {cmd_##name, #name, cmdopt, flags, type}
725 
726 #define SSL_CONF_CMD_STRING(name, cmdopt, flags) \
727         SSL_CONF_CMD(name, cmdopt, flags, SSL_CONF_TYPE_STRING)
728 
729 #define SSL_CONF_CMD_SWITCH(name, flags) \
730         {0, NULL, name, flags, SSL_CONF_TYPE_NONE}
731 
732 /* See apps/include/opt.h if you change this table. */
733 /* The SSL_CONF_CMD_SWITCH should be the same order as ssl_cmd_switches */
734 static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
735     SSL_CONF_CMD_SWITCH("no_ssl3", 0),
736     SSL_CONF_CMD_SWITCH("no_tls1", 0),
737     SSL_CONF_CMD_SWITCH("no_tls1_1", 0),
738     SSL_CONF_CMD_SWITCH("no_tls1_2", 0),
739     SSL_CONF_CMD_SWITCH("no_tls1_3", 0),
740     SSL_CONF_CMD_SWITCH("bugs", 0),
741     SSL_CONF_CMD_SWITCH("no_comp", 0),
742     SSL_CONF_CMD_SWITCH("comp", 0),
743     SSL_CONF_CMD_SWITCH("no_tx_cert_comp", 0),
744     SSL_CONF_CMD_SWITCH("tx_cert_comp", 0),
745     SSL_CONF_CMD_SWITCH("no_rx_cert_comp", 0),
746     SSL_CONF_CMD_SWITCH("rx_cert_comp", 0),
747     SSL_CONF_CMD_SWITCH("ecdh_single", SSL_CONF_FLAG_SERVER),
748     SSL_CONF_CMD_SWITCH("no_ticket", 0),
749     SSL_CONF_CMD_SWITCH("serverpref", SSL_CONF_FLAG_SERVER),
750     SSL_CONF_CMD_SWITCH("legacy_renegotiation", 0),
751     SSL_CONF_CMD_SWITCH("client_renegotiation", SSL_CONF_FLAG_SERVER),
752     SSL_CONF_CMD_SWITCH("legacy_server_connect", SSL_CONF_FLAG_CLIENT),
753     SSL_CONF_CMD_SWITCH("no_renegotiation", 0),
754     SSL_CONF_CMD_SWITCH("no_resumption_on_reneg", SSL_CONF_FLAG_SERVER),
755     SSL_CONF_CMD_SWITCH("no_legacy_server_connect", SSL_CONF_FLAG_CLIENT),
756     SSL_CONF_CMD_SWITCH("allow_no_dhe_kex", 0),
757     SSL_CONF_CMD_SWITCH("prefer_no_dhe_kex", 0),
758     SSL_CONF_CMD_SWITCH("prioritize_chacha", SSL_CONF_FLAG_SERVER),
759     SSL_CONF_CMD_SWITCH("strict", 0),
760     SSL_CONF_CMD_SWITCH("no_middlebox", 0),
761     SSL_CONF_CMD_SWITCH("anti_replay", SSL_CONF_FLAG_SERVER),
762     SSL_CONF_CMD_SWITCH("no_anti_replay", SSL_CONF_FLAG_SERVER),
763     SSL_CONF_CMD_SWITCH("no_etm", 0),
764     SSL_CONF_CMD_SWITCH("no_ems", 0),
765     SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs", 0),
766     SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs", 0),
767     SSL_CONF_CMD_STRING(Curves, "curves", 0),
768     SSL_CONF_CMD_STRING(Groups, "groups", 0),
769     SSL_CONF_CMD_STRING(ECDHParameters, "named_curve", SSL_CONF_FLAG_SERVER),
770     SSL_CONF_CMD_STRING(CipherString, "cipher", 0),
771     SSL_CONF_CMD_STRING(Ciphersuites, "ciphersuites", 0),
772     SSL_CONF_CMD_STRING(Protocol, NULL, 0),
773     SSL_CONF_CMD_STRING(MinProtocol, "min_protocol", 0),
774     SSL_CONF_CMD_STRING(MaxProtocol, "max_protocol", 0),
775     SSL_CONF_CMD_STRING(Options, NULL, 0),
776     SSL_CONF_CMD_STRING(VerifyMode, NULL, 0),
777     SSL_CONF_CMD(Certificate, "cert", SSL_CONF_FLAG_CERTIFICATE,
778                  SSL_CONF_TYPE_FILE),
779     SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_FLAG_CERTIFICATE,
780                  SSL_CONF_TYPE_FILE),
781     SSL_CONF_CMD(ServerInfoFile, NULL,
782                  SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
783                  SSL_CONF_TYPE_FILE),
784     SSL_CONF_CMD(ChainCAPath, "chainCApath", SSL_CONF_FLAG_CERTIFICATE,
785                  SSL_CONF_TYPE_DIR),
786     SSL_CONF_CMD(ChainCAFile, "chainCAfile", SSL_CONF_FLAG_CERTIFICATE,
787                  SSL_CONF_TYPE_FILE),
788     SSL_CONF_CMD(ChainCAStore, "chainCAstore", SSL_CONF_FLAG_CERTIFICATE,
789                  SSL_CONF_TYPE_STORE),
790     SSL_CONF_CMD(VerifyCAPath, "verifyCApath", SSL_CONF_FLAG_CERTIFICATE,
791                  SSL_CONF_TYPE_DIR),
792     SSL_CONF_CMD(VerifyCAFile, "verifyCAfile", SSL_CONF_FLAG_CERTIFICATE,
793                  SSL_CONF_TYPE_FILE),
794     SSL_CONF_CMD(VerifyCAStore, "verifyCAstore", SSL_CONF_FLAG_CERTIFICATE,
795                  SSL_CONF_TYPE_STORE),
796     SSL_CONF_CMD(RequestCAFile, "requestCAFile", SSL_CONF_FLAG_CERTIFICATE,
797                  SSL_CONF_TYPE_FILE),
798     SSL_CONF_CMD(ClientCAFile, NULL,
799                  SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
800                  SSL_CONF_TYPE_FILE),
801     SSL_CONF_CMD(RequestCAPath, NULL, SSL_CONF_FLAG_CERTIFICATE,
802                  SSL_CONF_TYPE_DIR),
803     SSL_CONF_CMD(ClientCAPath, NULL,
804                  SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
805                  SSL_CONF_TYPE_DIR),
806     SSL_CONF_CMD(RequestCAStore, "requestCAStore", SSL_CONF_FLAG_CERTIFICATE,
807                  SSL_CONF_TYPE_STORE),
808     SSL_CONF_CMD(ClientCAStore, NULL,
809                  SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
810                  SSL_CONF_TYPE_STORE),
811     SSL_CONF_CMD(DHParameters, "dhparam",
812                  SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
813                  SSL_CONF_TYPE_FILE),
814     SSL_CONF_CMD_STRING(RecordPadding, "record_padding", 0),
815     SSL_CONF_CMD_STRING(NumTickets, "num_tickets", SSL_CONF_FLAG_SERVER),
816 };
817 
818 /* Supported switches: must match order of switches in ssl_conf_cmds */
819 static const ssl_switch_tbl ssl_cmd_switches[] = {
820     {SSL_OP_NO_SSLv3, 0},       /* no_ssl3 */
821     {SSL_OP_NO_TLSv1, 0},       /* no_tls1 */
822     {SSL_OP_NO_TLSv1_1, 0},     /* no_tls1_1 */
823     {SSL_OP_NO_TLSv1_2, 0},     /* no_tls1_2 */
824     {SSL_OP_NO_TLSv1_3, 0},     /* no_tls1_3 */
825     {SSL_OP_ALL, 0},            /* bugs */
826     {SSL_OP_NO_COMPRESSION, 0}, /* no_comp */
827     {SSL_OP_NO_COMPRESSION, SSL_TFLAG_INV}, /* comp */
828     {SSL_OP_NO_TX_CERTIFICATE_COMPRESSION, 0}, /* no_tx_cert_comp */
829     {SSL_OP_NO_TX_CERTIFICATE_COMPRESSION, SSL_TFLAG_INV}, /* tx_cert_comp */
830     {SSL_OP_NO_RX_CERTIFICATE_COMPRESSION, 0}, /* no_rx_cert_comp */
831     {SSL_OP_NO_RX_CERTIFICATE_COMPRESSION, SSL_TFLAG_INV}, /* rx_cert_comp */
832     {SSL_OP_SINGLE_ECDH_USE, 0}, /* ecdh_single */
833     {SSL_OP_NO_TICKET, 0},      /* no_ticket */
834     {SSL_OP_CIPHER_SERVER_PREFERENCE, 0}, /* serverpref */
835     /* legacy_renegotiation */
836     {SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, 0},
837     /* Allow client renegotiation */
838     {SSL_OP_ALLOW_CLIENT_RENEGOTIATION, 0},
839     /* legacy_server_connect */
840     {SSL_OP_LEGACY_SERVER_CONNECT, 0},
841     /* no_renegotiation */
842     {SSL_OP_NO_RENEGOTIATION, 0},
843     /* no_resumption_on_reneg */
844     {SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION, 0},
845     /* no_legacy_server_connect */
846     {SSL_OP_LEGACY_SERVER_CONNECT, SSL_TFLAG_INV},
847     /* allow_no_dhe_kex */
848     {SSL_OP_ALLOW_NO_DHE_KEX, 0},
849     /* prefer_no_dhe_kex */
850     {SSL_OP_PREFER_NO_DHE_KEX, 0},
851     /* chacha reprioritization */
852     {SSL_OP_PRIORITIZE_CHACHA, 0},
853     {SSL_CERT_FLAG_TLS_STRICT, SSL_TFLAG_CERT}, /* strict */
854     /* no_middlebox */
855     {SSL_OP_ENABLE_MIDDLEBOX_COMPAT, SSL_TFLAG_INV},
856     /* anti_replay */
857     {SSL_OP_NO_ANTI_REPLAY, SSL_TFLAG_INV},
858     /* no_anti_replay */
859     {SSL_OP_NO_ANTI_REPLAY, 0},
860     /* no Encrypt-then-Mac */
861     {SSL_OP_NO_ENCRYPT_THEN_MAC, 0},
862     /* no Extended master secret */
863     {SSL_OP_NO_EXTENDED_MASTER_SECRET, 0},
864 };
865 
ssl_conf_cmd_skip_prefix(SSL_CONF_CTX * cctx,const char ** pcmd)866 static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd)
867 {
868     if (pcmd == NULL || *pcmd == NULL)
869         return 0;
870     /* If a prefix is set, check and skip */
871     if (cctx->prefix) {
872         if (strlen(*pcmd) <= cctx->prefixlen)
873             return 0;
874         if (cctx->flags & SSL_CONF_FLAG_CMDLINE &&
875             strncmp(*pcmd, cctx->prefix, cctx->prefixlen))
876             return 0;
877         if (cctx->flags & SSL_CONF_FLAG_FILE &&
878             OPENSSL_strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen))
879             return 0;
880         *pcmd += cctx->prefixlen;
881     } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
882         if (**pcmd != '-' || !(*pcmd)[1])
883             return 0;
884         *pcmd += 1;
885     }
886     return 1;
887 }
888 
889 /* Determine if a command is allowed according to cctx flags */
ssl_conf_cmd_allowed(SSL_CONF_CTX * cctx,const ssl_conf_cmd_tbl * t)890 static int ssl_conf_cmd_allowed(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl *t)
891 {
892     unsigned int tfl = t->flags;
893     unsigned int cfl = cctx->flags;
894     if ((tfl & SSL_CONF_FLAG_SERVER) && !(cfl & SSL_CONF_FLAG_SERVER))
895         return 0;
896     if ((tfl & SSL_CONF_FLAG_CLIENT) && !(cfl & SSL_CONF_FLAG_CLIENT))
897         return 0;
898     if ((tfl & SSL_CONF_FLAG_CERTIFICATE)
899         && !(cfl & SSL_CONF_FLAG_CERTIFICATE))
900         return 0;
901     return 1;
902 }
903 
ssl_conf_cmd_lookup(SSL_CONF_CTX * cctx,const char * cmd)904 static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx,
905                                                    const char *cmd)
906 {
907     const ssl_conf_cmd_tbl *t;
908     size_t i;
909     if (cmd == NULL)
910         return NULL;
911 
912     /* Look for matching parameter name in table */
913     for (i = 0, t = ssl_conf_cmds; i < OSSL_NELEM(ssl_conf_cmds); i++, t++) {
914         if (ssl_conf_cmd_allowed(cctx, t)) {
915             if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
916                 if (t->str_cmdline && strcmp(t->str_cmdline, cmd) == 0)
917                     return t;
918             }
919             if (cctx->flags & SSL_CONF_FLAG_FILE) {
920                 if (t->str_file && OPENSSL_strcasecmp(t->str_file, cmd) == 0)
921                     return t;
922             }
923         }
924     }
925     return NULL;
926 }
927 
ctrl_switch_option(SSL_CONF_CTX * cctx,const ssl_conf_cmd_tbl * cmd)928 static int ctrl_switch_option(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl *cmd)
929 {
930     /* Find index of command in table */
931     size_t idx = cmd - ssl_conf_cmds;
932     const ssl_switch_tbl *scmd;
933 
934     /* Sanity check index */
935     if (idx >= OSSL_NELEM(ssl_cmd_switches)) {
936         ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
937         return 0;
938     }
939     /* Obtain switches entry with same index */
940     scmd = ssl_cmd_switches + idx;
941     ssl_set_option(cctx, scmd->name_flags, scmd->option_value, 1);
942     return 1;
943 }
944 
SSL_CONF_cmd(SSL_CONF_CTX * cctx,const char * cmd,const char * value)945 int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value)
946 {
947     const ssl_conf_cmd_tbl *runcmd;
948     if (cmd == NULL) {
949         ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_NULL_CMD_NAME);
950         return 0;
951     }
952 
953     if (!ssl_conf_cmd_skip_prefix(cctx, &cmd))
954         goto unknown_cmd;
955 
956     runcmd = ssl_conf_cmd_lookup(cctx, cmd);
957 
958     if (runcmd) {
959         int rv = -3;
960 
961         if (runcmd->value_type == SSL_CONF_TYPE_NONE) {
962             return ctrl_switch_option(cctx, runcmd);
963         }
964         if (value == NULL)
965             goto bad_value;
966         rv = runcmd->cmd(cctx, value);
967         if (rv > 0)
968             return 2;
969         if (rv != -2)
970             rv = 0;
971 
972  bad_value:
973         if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS)
974             ERR_raise_data(ERR_LIB_SSL, SSL_R_BAD_VALUE,
975                            "cmd=%s, value=%s", cmd,
976                            value != NULL ? value : "<EMPTY>");
977         return rv;
978     }
979 
980  unknown_cmd:
981     if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS)
982         ERR_raise_data(ERR_LIB_SSL, SSL_R_UNKNOWN_CMD_NAME, "cmd=%s", cmd);
983 
984     return -2;
985 }
986 
SSL_CONF_cmd_argv(SSL_CONF_CTX * cctx,int * pargc,char *** pargv)987 int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv)
988 {
989     int rv;
990     const char *arg = NULL, *argn;
991 
992     if (pargc != NULL && *pargc == 0)
993         return 0;
994     if (pargc == NULL || *pargc > 0)
995         arg = **pargv;
996     if (arg == NULL)
997         return 0;
998     if (pargc == NULL || *pargc > 1)
999         argn = (*pargv)[1];
1000     else
1001         argn = NULL;
1002     cctx->flags &= ~SSL_CONF_FLAG_FILE;
1003     cctx->flags |= SSL_CONF_FLAG_CMDLINE;
1004     rv = SSL_CONF_cmd(cctx, arg, argn);
1005     if (rv > 0) {
1006         /* Success: update pargc, pargv */
1007         (*pargv) += rv;
1008         if (pargc)
1009             (*pargc) -= rv;
1010         return rv;
1011     }
1012     /* Unknown switch: indicate no arguments processed */
1013     if (rv == -2)
1014         return 0;
1015     /* Some error occurred processing command, return fatal error */
1016     if (rv == 0)
1017         return -1;
1018     return rv;
1019 }
1020 
SSL_CONF_cmd_value_type(SSL_CONF_CTX * cctx,const char * cmd)1021 int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd)
1022 {
1023     if (ssl_conf_cmd_skip_prefix(cctx, &cmd)) {
1024         const ssl_conf_cmd_tbl *runcmd;
1025         runcmd = ssl_conf_cmd_lookup(cctx, cmd);
1026         if (runcmd)
1027             return runcmd->value_type;
1028     }
1029     return SSL_CONF_TYPE_UNKNOWN;
1030 }
1031 
SSL_CONF_CTX_new(void)1032 SSL_CONF_CTX *SSL_CONF_CTX_new(void)
1033 {
1034     SSL_CONF_CTX *ret = OPENSSL_zalloc(sizeof(*ret));
1035 
1036     return ret;
1037 }
1038 
SSL_CONF_CTX_finish(SSL_CONF_CTX * cctx)1039 int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx)
1040 {
1041     /* See if any certificates are missing private keys */
1042     size_t i;
1043     CERT *c = NULL;
1044 
1045     if (cctx->ctx != NULL) {
1046         c = cctx->ctx->cert;
1047     } else if (cctx->ssl != NULL) {
1048         SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(cctx->ssl);
1049 
1050         if (sc != NULL)
1051             c = sc->cert;
1052     }
1053     if (c != NULL && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
1054         for (i = 0; i < SSL_PKEY_NUM; i++) {
1055             const char *p = cctx->cert_filename[i];
1056             /*
1057              * If missing private key try to load one from certificate file
1058              */
1059             if (p && !c->pkeys[i].privatekey) {
1060                 if (!cmd_PrivateKey(cctx, p))
1061                     return 0;
1062             }
1063         }
1064     }
1065     if (cctx->canames) {
1066         if (cctx->ssl)
1067             SSL_set0_CA_list(cctx->ssl, cctx->canames);
1068         else if (cctx->ctx)
1069             SSL_CTX_set0_CA_list(cctx->ctx, cctx->canames);
1070         else
1071             sk_X509_NAME_pop_free(cctx->canames, X509_NAME_free);
1072         cctx->canames = NULL;
1073     }
1074     return 1;
1075 }
1076 
SSL_CONF_CTX_free(SSL_CONF_CTX * cctx)1077 void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx)
1078 {
1079     if (cctx) {
1080         size_t i;
1081         for (i = 0; i < SSL_PKEY_NUM; i++)
1082             OPENSSL_free(cctx->cert_filename[i]);
1083         OPENSSL_free(cctx->prefix);
1084         sk_X509_NAME_pop_free(cctx->canames, X509_NAME_free);
1085         OPENSSL_free(cctx);
1086     }
1087 }
1088 
SSL_CONF_CTX_set_flags(SSL_CONF_CTX * cctx,unsigned int flags)1089 unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags)
1090 {
1091     cctx->flags |= flags;
1092     return cctx->flags;
1093 }
1094 
SSL_CONF_CTX_clear_flags(SSL_CONF_CTX * cctx,unsigned int flags)1095 unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags)
1096 {
1097     cctx->flags &= ~flags;
1098     return cctx->flags;
1099 }
1100 
SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX * cctx,const char * pre)1101 int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre)
1102 {
1103     char *tmp = NULL;
1104     if (pre) {
1105         tmp = OPENSSL_strdup(pre);
1106         if (tmp == NULL)
1107             return 0;
1108     }
1109     OPENSSL_free(cctx->prefix);
1110     cctx->prefix = tmp;
1111     if (tmp)
1112         cctx->prefixlen = strlen(tmp);
1113     else
1114         cctx->prefixlen = 0;
1115     return 1;
1116 }
1117 
SSL_CONF_CTX_set_ssl(SSL_CONF_CTX * cctx,SSL * ssl)1118 void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl)
1119 {
1120     cctx->ssl = ssl;
1121     cctx->ctx = NULL;
1122     if (ssl != NULL) {
1123         SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);
1124 
1125         if (sc == NULL)
1126             return;
1127         cctx->poptions = &sc->options;
1128         cctx->min_version = &sc->min_proto_version;
1129         cctx->max_version = &sc->max_proto_version;
1130         cctx->pcert_flags = &sc->cert->cert_flags;
1131         cctx->pvfy_flags = &sc->verify_mode;
1132     } else {
1133         cctx->poptions = NULL;
1134         cctx->min_version = NULL;
1135         cctx->max_version = NULL;
1136         cctx->pcert_flags = NULL;
1137         cctx->pvfy_flags = NULL;
1138     }
1139 }
1140 
SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX * cctx,SSL_CTX * ctx)1141 void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx)
1142 {
1143     cctx->ctx = ctx;
1144     cctx->ssl = NULL;
1145     if (ctx) {
1146         cctx->poptions = &ctx->options;
1147         cctx->min_version = &ctx->min_proto_version;
1148         cctx->max_version = &ctx->max_proto_version;
1149         cctx->pcert_flags = &ctx->cert->cert_flags;
1150         cctx->pvfy_flags = &ctx->verify_mode;
1151     } else {
1152         cctx->poptions = NULL;
1153         cctx->min_version = NULL;
1154         cctx->max_version = NULL;
1155         cctx->pcert_flags = NULL;
1156         cctx->pvfy_flags = NULL;
1157     }
1158 }
1159