c920af59991f67f22bfd4012c995f21e4c55ce3e
[openssl.git] / ssl / ssl_conf.c
1 /*
2  * ! \file ssl/ssl_conf.c \brief SSL configuration functions
3  */
4 /* ====================================================================
5  * Copyright (c) 2012 The OpenSSL Project.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. All advertising materials mentioning features or use of this
20  *    software must display the following acknowledgment:
21  *    "This product includes software developed by the OpenSSL Project
22  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
23  *
24  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25  *    endorse or promote products derived from this software without
26  *    prior written permission. For written permission, please contact
27  *    openssl-core@openssl.org.
28  *
29  * 5. Products derived from this software may not be called "OpenSSL"
30  *    nor may "OpenSSL" appear in their names without prior written
31  *    permission of the OpenSSL Project.
32  *
33  * 6. Redistributions of any form whatsoever must retain the following
34  *    acknowledgment:
35  *    "This product includes software developed by the OpenSSL Project
36  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
42  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49  * OF THE POSSIBILITY OF SUCH DAMAGE.
50  * ====================================================================
51  *
52  * This product includes cryptographic software written by Eric Young
53  * (eay@cryptsoft.com).  This product includes software written by Tim
54  * Hudson (tjh@cryptsoft.com).
55  *
56  */
57
58 #ifdef REF_CHECK
59 # include <assert.h>
60 #endif
61 #include <stdio.h>
62 #include "ssl_locl.h"
63 #include <openssl/conf.h>
64 #include <openssl/objects.h>
65 #ifndef OPENSSL_NO_DH
66 # include <openssl/dh.h>
67 #endif
68
69 /*
70  * structure holding name tables. This is used for pemitted elements in lists
71  * such as TLSv1.
72  */
73
74 typedef struct {
75     const char *name;
76     int namelen;
77     unsigned int name_flags;
78     unsigned long option_value;
79 } ssl_flag_tbl;
80
81 /* Switch table: use for single command line switches like no_tls2 */
82 typedef struct {
83     unsigned long option_value;
84     unsigned int name_flags;
85 } ssl_switch_tbl;
86
87 /* Sense of name is inverted e.g. "TLSv1" will clear SSL_OP_NO_TLSv1 */
88 #define SSL_TFLAG_INV   0x1
89 /* Flags refers to cert_flags not options */
90 #define SSL_TFLAG_CERT  0x2
91 /* Option can only be used for clients */
92 #define SSL_TFLAG_CLIENT SSL_CONF_FLAG_CLIENT
93 /* Option can only be used for servers */
94 #define SSL_TFLAG_SERVER SSL_CONF_FLAG_SERVER
95 #define SSL_TFLAG_BOTH (SSL_TFLAG_CLIENT|SSL_TFLAG_SERVER)
96
97 #define SSL_FLAG_TBL(str, flag) \
98         {str, (int)(sizeof(str) - 1), SSL_TFLAG_BOTH, flag}
99 #define SSL_FLAG_TBL_SRV(str, flag) \
100         {str, (int)(sizeof(str) - 1), SSL_TFLAG_SERVER, flag}
101 #define SSL_FLAG_TBL_CLI(str, flag) \
102         {str, (int)(sizeof(str) - 1), SSL_TFLAG_CLIENT, flag}
103 #define SSL_FLAG_TBL_INV(str, flag) \
104         {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_BOTH, flag}
105 #define SSL_FLAG_TBL_SRV_INV(str, flag) \
106         {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_SERVER, flag}
107 #define SSL_FLAG_TBL_CERT(str, flag) \
108         {str, (int)(sizeof(str) - 1), SSL_TFLAG_CERT|SSL_TFLAG_BOTH, flag}
109
110 /*
111  * Opaque structure containing SSL configuration context.
112  */
113
114 struct ssl_conf_ctx_st {
115     /*
116      * Various flags indicating (among other things) which options we will
117      * recognise.
118      */
119     unsigned int flags;
120     /* Prefix and length of commands */
121     char *prefix;
122     size_t prefixlen;
123     /* SSL_CTX or SSL structure to perform operations on */
124     SSL_CTX *ctx;
125     SSL *ssl;
126     /* Pointer to SSL or SSL_CTX options field or NULL if none */
127     unsigned long *poptions;
128     /* Certificate filenames for each type */
129     char *cert_filename[SSL_PKEY_NUM];
130     /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */
131     unsigned int *pcert_flags;
132     /* Current flag table being worked on */
133     const ssl_flag_tbl *tbl;
134     /* Size of table */
135     size_t ntbl;
136 };
137
138 static void ssl_set_option(SSL_CONF_CTX *cctx, unsigned int name_flags,
139                            unsigned long option_value, int onoff)
140 {
141     if (cctx->poptions == NULL)
142         return;
143     if (name_flags & SSL_TFLAG_INV)
144         onoff ^= 1;
145     if (name_flags & SSL_TFLAG_CERT) {
146         if (onoff)
147             *cctx->pcert_flags |= option_value;
148         else
149             *cctx->pcert_flags &= ~option_value;
150     } else {
151         if (onoff)
152             *cctx->poptions |= option_value;
153         else
154             *cctx->poptions &= ~option_value;
155     }
156 }
157
158 static int ssl_match_option(SSL_CONF_CTX *cctx, const ssl_flag_tbl *tbl,
159                             const char *name, int namelen, int onoff)
160 {
161     /* If name not relevant for context skip */
162     if (!(cctx->flags & tbl->name_flags & SSL_TFLAG_BOTH))
163         return 0;
164     if (namelen == -1) {
165         if (strcmp(tbl->name, name))
166             return 0;
167     } else if (tbl->namelen != namelen
168                || strncasecmp(tbl->name, name, namelen))
169         return 0;
170     ssl_set_option(cctx, tbl->name_flags, tbl->option_value, onoff);
171     return 1;
172 }
173
174 static int ssl_set_option_list(const char *elem, int len, void *usr)
175 {
176     SSL_CONF_CTX *cctx = usr;
177     size_t i;
178     const ssl_flag_tbl *tbl;
179     int onoff = 1;
180     /*
181      * len == -1 indicates not being called in list context, just for single
182      * command line switches, so don't allow +, -.
183      */
184     if (elem == NULL)
185         return 0;
186     if (len != -1) {
187         if (*elem == '+') {
188             elem++;
189             len--;
190             onoff = 1;
191         } else if (*elem == '-') {
192             elem++;
193             len--;
194             onoff = 0;
195         }
196     }
197     for (i = 0, tbl = cctx->tbl; i < cctx->ntbl; i++, tbl++) {
198         if (ssl_match_option(cctx, tbl, elem, len, onoff))
199             return 1;
200     }
201     return 0;
202 }
203
204 /* Set supported signature algorithms */
205 static int cmd_SignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
206 {
207     int rv;
208     if (cctx->ssl)
209         rv = SSL_set1_sigalgs_list(cctx->ssl, value);
210     /* NB: ctx == NULL performs syntax checking only */
211     else
212         rv = SSL_CTX_set1_sigalgs_list(cctx->ctx, value);
213     return rv > 0;
214 }
215
216 /* Set supported client signature algorithms */
217 static int cmd_ClientSignatureAlgorithms(SSL_CONF_CTX *cctx,
218                                          const char *value)
219 {
220     int rv;
221     if (cctx->ssl)
222         rv = SSL_set1_client_sigalgs_list(cctx->ssl, value);
223     /* NB: ctx == NULL performs syntax checking only */
224     else
225         rv = SSL_CTX_set1_client_sigalgs_list(cctx->ctx, value);
226     return rv > 0;
227 }
228
229 static int cmd_Curves(SSL_CONF_CTX *cctx, const char *value)
230 {
231     int rv;
232     if (cctx->ssl)
233         rv = SSL_set1_curves_list(cctx->ssl, value);
234     /* NB: ctx == NULL performs syntax checking only */
235     else
236         rv = SSL_CTX_set1_curves_list(cctx->ctx, value);
237     return rv > 0;
238 }
239
240 #ifndef OPENSSL_NO_EC
241 /* ECDH temporary parameters */
242 static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value)
243 {
244     int onoff = -1, rv = 1;
245     if (cctx->flags & SSL_CONF_FLAG_FILE) {
246         if (*value == '+') {
247             onoff = 1;
248             value++;
249         }
250         if (*value == '-') {
251             onoff = 0;
252             value++;
253         }
254         if (!strcasecmp(value, "automatic")) {
255             if (onoff == -1)
256                 onoff = 1;
257         } else if (onoff != -1)
258             return 0;
259     } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
260         if (!strcmp(value, "auto"))
261             onoff = 1;
262     }
263
264     if (onoff != -1) {
265         if (cctx->ctx)
266             rv = SSL_CTX_set_ecdh_auto(cctx->ctx, onoff);
267         else if (cctx->ssl)
268             rv = SSL_set_ecdh_auto(cctx->ssl, onoff);
269     } else {
270         EC_KEY *ecdh;
271         int nid;
272         nid = EC_curve_nist2nid(value);
273         if (nid == NID_undef)
274             nid = OBJ_sn2nid(value);
275         if (nid == 0)
276             return 0;
277         ecdh = EC_KEY_new_by_curve_name(nid);
278         if (!ecdh)
279             return 0;
280         if (cctx->ctx)
281             rv = SSL_CTX_set_tmp_ecdh(cctx->ctx, ecdh);
282         else if (cctx->ssl)
283             rv = SSL_set_tmp_ecdh(cctx->ssl, ecdh);
284         EC_KEY_free(ecdh);
285     }
286
287     return rv > 0;
288 }
289 #endif
290 static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value)
291 {
292     int rv = 1;
293     if (cctx->ctx)
294         rv = SSL_CTX_set_cipher_list(cctx->ctx, value);
295     if (cctx->ssl)
296         rv = SSL_set_cipher_list(cctx->ssl, value);
297     return rv > 0;
298 }
299
300 static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value)
301 {
302     static const ssl_flag_tbl ssl_protocol_list[] = {
303         SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK),
304         SSL_FLAG_TBL_INV("SSLv2", SSL_OP_NO_SSLv2),
305         SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3),
306         SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1),
307         SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1),
308         SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2)
309     };
310     cctx->tbl = ssl_protocol_list;
311     cctx->ntbl = OSSL_NELEM(ssl_protocol_list);
312     return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
313 }
314
315 static int cmd_Options(SSL_CONF_CTX *cctx, const char *value)
316 {
317     static const ssl_flag_tbl ssl_option_list[] = {
318         SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET),
319         SSL_FLAG_TBL_INV("EmptyFragments",
320                          SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS),
321         SSL_FLAG_TBL("Bugs", SSL_OP_ALL),
322         SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION),
323         SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE),
324         SSL_FLAG_TBL_SRV("NoResumptionOnRenegotiation",
325                          SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION),
326         SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE),
327         SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE),
328         SSL_FLAG_TBL("UnsafeLegacyRenegotiation",
329                      SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION),
330     };
331     if (value == NULL)
332         return -3;
333     cctx->tbl = ssl_option_list;
334     cctx->ntbl = OSSL_NELEM(ssl_option_list);
335     return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
336 }
337
338 static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value)
339 {
340     int rv = 1;
341     CERT *c = NULL;
342     if (cctx->ctx) {
343         rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value);
344         c = cctx->ctx->cert;
345     }
346     if (cctx->ssl) {
347         rv = SSL_use_certificate_file(cctx->ssl, value, SSL_FILETYPE_PEM);
348         c = cctx->ssl->cert;
349     }
350     if (rv > 0 && c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
351         char **pfilename = &cctx->cert_filename[c->key - c->pkeys];
352         OPENSSL_free(*pfilename);
353         *pfilename = BUF_strdup(value);
354         if (!*pfilename)
355             rv = 0;
356     }
357
358     return rv > 0;
359 }
360
361 static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value)
362 {
363     int rv = 1;
364     if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
365         return -2;
366     if (cctx->ctx)
367         rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM);
368     if (cctx->ssl)
369         rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM);
370     return rv > 0;
371 }
372
373 static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value)
374 {
375     int rv = 1;
376     if (cctx->ctx)
377         rv = SSL_CTX_use_serverinfo_file(cctx->ctx, value);
378     return rv > 0;
379 }
380
381 #ifndef OPENSSL_NO_DH
382 static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value)
383 {
384     int rv = 0;
385     DH *dh = NULL;
386     BIO *in = NULL;
387     if (cctx->ctx || cctx->ssl) {
388         in = BIO_new(BIO_s_file_internal());
389         if (!in)
390             goto end;
391         if (BIO_read_filename(in, value) <= 0)
392             goto end;
393         dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
394         if (!dh)
395             goto end;
396     } else
397         return 1;
398     if (cctx->ctx)
399         rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh);
400     if (cctx->ssl)
401         rv = SSL_set_tmp_dh(cctx->ssl, dh);
402  end:
403     DH_free(dh);
404     BIO_free(in);
405     return rv > 0;
406 }
407 #endif
408 typedef struct {
409     int (*cmd) (SSL_CONF_CTX *cctx, const char *value);
410     const char *str_file;
411     const char *str_cmdline;
412     unsigned short flags;
413     unsigned short value_type;
414 } ssl_conf_cmd_tbl;
415
416 /* Table of supported parameters */
417
418 #define SSL_CONF_CMD(name, cmdopt, flags, type) \
419         {cmd_##name, #name, cmdopt, flags, type}
420
421 #define SSL_CONF_CMD_STRING(name, cmdopt, flags) \
422         SSL_CONF_CMD(name, cmdopt, flags, SSL_CONF_TYPE_STRING)
423
424 #define SSL_CONF_CMD_SWITCH(name, flags) \
425         {0, NULL, name, flags, SSL_CONF_TYPE_NONE}
426
427 /* See apps/apps.h if you change this table. */
428 static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
429     SSL_CONF_CMD_SWITCH("no_ssl3", 0),
430     SSL_CONF_CMD_SWITCH("no_tls1", 0),
431     SSL_CONF_CMD_SWITCH("no_tls1_1", 0),
432     SSL_CONF_CMD_SWITCH("no_tls1_2", 0),
433     SSL_CONF_CMD_SWITCH("bugs", 0),
434     SSL_CONF_CMD_SWITCH("no_comp", 0),
435     SSL_CONF_CMD_SWITCH("ecdh_single", SSL_CONF_FLAG_SERVER),
436 #ifndef OPENSSL_NO_TLSEXT
437     SSL_CONF_CMD_SWITCH("no_ticket", 0),
438 #endif
439     SSL_CONF_CMD_SWITCH("serverpref", SSL_CONF_FLAG_SERVER),
440     SSL_CONF_CMD_SWITCH("legacy_renegotiation", 0),
441     SSL_CONF_CMD_SWITCH("legacy_server_connect", SSL_CONF_FLAG_SERVER),
442     SSL_CONF_CMD_SWITCH("no_resumption_on_reneg", SSL_CONF_FLAG_SERVER),
443     SSL_CONF_CMD_SWITCH("no_legacy_server_connect", SSL_CONF_FLAG_SERVER),
444     SSL_CONF_CMD_SWITCH("strict", 0),
445 #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
446     SSL_CONF_CMD_SWITCH("debug_broken_protocol", 0),
447 #endif
448     SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs", 0),
449     SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs", 0),
450     SSL_CONF_CMD_STRING(Curves, "curves", 0),
451 #ifndef OPENSSL_NO_EC
452     SSL_CONF_CMD_STRING(ECDHParameters, "named_curve", SSL_CONF_FLAG_SERVER),
453 #endif
454     SSL_CONF_CMD_STRING(CipherString, "cipher", 0),
455     SSL_CONF_CMD_STRING(Protocol, NULL, 0),
456     SSL_CONF_CMD_STRING(Options, NULL, 0),
457     SSL_CONF_CMD(Certificate, "cert", SSL_CONF_FLAG_CERTIFICATE,
458                  SSL_CONF_TYPE_FILE),
459     SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_FLAG_CERTIFICATE,
460                  SSL_CONF_TYPE_FILE),
461     SSL_CONF_CMD(ServerInfoFile, NULL,
462                  SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
463                  SSL_CONF_TYPE_FILE),
464 #ifndef OPENSSL_NO_DH
465     SSL_CONF_CMD(DHParameters, "dhparam",
466                  SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
467                  SSL_CONF_TYPE_FILE)
468 #endif
469 };
470
471 /* Supported switches: must match order of switches in ssl_conf_cmds */
472 static const ssl_switch_tbl ssl_cmd_switches[] = {
473     {SSL_OP_NO_SSLv3, 0},       /* no_ssl3 */
474     {SSL_OP_NO_TLSv1, 0},       /* no_tls1 */
475     {SSL_OP_NO_TLSv1_1, 0},     /* no_tls1_1 */
476     {SSL_OP_NO_TLSv1_2, 0},     /* no_tls1_2 */
477     {SSL_OP_ALL, 0},            /* bugs */
478     {SSL_OP_NO_COMPRESSION, 0}, /* no_comp */
479     {SSL_OP_SINGLE_ECDH_USE, 0}, /* ecdh_single */
480 #ifndef OPENSSL_NO_TLSEXT
481     {SSL_OP_NO_TICKET, 0},      /* no_ticket */
482 #endif
483     {SSL_OP_CIPHER_SERVER_PREFERENCE, 0}, /* serverpref */
484     /* legacy_renegotiation */
485     {SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, 0},
486     /* legacy_server_connect */
487     {SSL_OP_LEGACY_SERVER_CONNECT, 0},
488     /* no_resumption_on_reneg */
489     {SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION, 0},
490     /* no_legacy_server_connect */
491     {SSL_OP_LEGACY_SERVER_CONNECT, SSL_TFLAG_INV},
492     {SSL_CERT_FLAG_TLS_STRICT, SSL_TFLAG_CERT}, /* strict */
493 #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
494     {SSL_CERT_FLAG_BROKEN_PROTOCOL, SSL_TFLAG_CERT} /* debug_broken_protocol */
495 #endif
496 };
497
498 static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd)
499 {
500     if (!pcmd || !*pcmd)
501         return 0;
502     /* If a prefix is set, check and skip */
503     if (cctx->prefix) {
504         if (strlen(*pcmd) <= cctx->prefixlen)
505             return 0;
506         if (cctx->flags & SSL_CONF_FLAG_CMDLINE &&
507             strncmp(*pcmd, cctx->prefix, cctx->prefixlen))
508             return 0;
509         if (cctx->flags & SSL_CONF_FLAG_FILE &&
510             strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen))
511             return 0;
512         *pcmd += cctx->prefixlen;
513     } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
514         if (**pcmd != '-' || !(*pcmd)[1])
515             return 0;
516         *pcmd += 1;
517     }
518     return 1;
519 }
520
521 /* Determine if a command is allowed according to cctx flags */
522 static int ssl_conf_cmd_allowed(SSL_CONF_CTX *cctx,
523                                 const ssl_conf_cmd_tbl * t)
524 {
525     unsigned int tfl = t->flags;
526     unsigned int cfl = cctx->flags;
527     if ((tfl & SSL_CONF_FLAG_SERVER) && !(cfl & SSL_CONF_FLAG_SERVER))
528         return 0;
529     if ((tfl & SSL_CONF_FLAG_CLIENT) && !(cfl & SSL_CONF_FLAG_CLIENT))
530         return 0;
531     if ((tfl & SSL_CONF_FLAG_CERTIFICATE)
532         && !(cfl & SSL_CONF_FLAG_CERTIFICATE))
533         return 0;
534     return 1;
535 }
536
537 static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx,
538                                                    const char *cmd)
539 {
540     const ssl_conf_cmd_tbl *t;
541     size_t i;
542     if (cmd == NULL)
543         return NULL;
544
545     /* Look for matching parameter name in table */
546     for (i = 0, t = ssl_conf_cmds; i < OSSL_NELEM(ssl_conf_cmds); i++, t++) {
547         if (ssl_conf_cmd_allowed(cctx, t)) {
548             if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
549                 if (t->str_cmdline && !strcmp(t->str_cmdline, cmd))
550                     return t;
551             }
552             if (cctx->flags & SSL_CONF_FLAG_FILE) {
553                 if (t->str_file && !strcasecmp(t->str_file, cmd))
554                     return t;
555             }
556         }
557     }
558     return NULL;
559 }
560
561 static int ctrl_switch_option(SSL_CONF_CTX *cctx,
562                               const ssl_conf_cmd_tbl * cmd)
563 {
564     /* Find index of command in table */
565     size_t idx = cmd - ssl_conf_cmds;
566     const ssl_switch_tbl *scmd;
567     /* Sanity check index */
568     if (idx >= OSSL_NELEM(ssl_cmd_switches))
569         return 0;
570     /* Obtain switches entry with same index */
571     scmd = ssl_cmd_switches + idx;
572     ssl_set_option(cctx, scmd->name_flags, scmd->option_value, 1);
573     return 1;
574 }
575
576 int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value)
577 {
578     const ssl_conf_cmd_tbl *runcmd;
579     if (cmd == NULL) {
580         SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_INVALID_NULL_CMD_NAME);
581         return 0;
582     }
583
584     if (!ssl_conf_cmd_skip_prefix(cctx, &cmd))
585         return -2;
586
587     runcmd = ssl_conf_cmd_lookup(cctx, cmd);
588
589     if (runcmd) {
590         int rv;
591         if (runcmd->value_type == SSL_CONF_TYPE_NONE) {
592             return ctrl_switch_option(cctx, runcmd);
593         }
594         if (value == NULL)
595             return -3;
596         rv = runcmd->cmd(cctx, value);
597         if (rv > 0)
598             return 2;
599         if (rv == -2)
600             return -2;
601         if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) {
602             SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_BAD_VALUE);
603             ERR_add_error_data(4, "cmd=", cmd, ", value=", value);
604         }
605         return 0;
606     }
607
608     if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) {
609         SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_UNKNOWN_CMD_NAME);
610         ERR_add_error_data(2, "cmd=", cmd);
611     }
612
613     return -2;
614 }
615
616 int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv)
617 {
618     int rv;
619     const char *arg = NULL, *argn;
620     if (pargc && *pargc == 0)
621         return 0;
622     if (!pargc || *pargc > 0)
623         arg = **pargv;
624     if (arg == NULL)
625         return 0;
626     if (!pargc || *pargc > 1)
627         argn = (*pargv)[1];
628     else
629         argn = NULL;
630     cctx->flags &= ~SSL_CONF_FLAG_FILE;
631     cctx->flags |= SSL_CONF_FLAG_CMDLINE;
632     rv = SSL_CONF_cmd(cctx, arg, argn);
633     if (rv > 0) {
634         /* Success: update pargc, pargv */
635         (*pargv) += rv;
636         if (pargc)
637             (*pargc) -= rv;
638         return rv;
639     }
640     /* Unknown switch: indicate no arguments processed */
641     if (rv == -2)
642         return 0;
643     /* Some error occurred processing command, return fatal error */
644     if (rv == 0)
645         return -1;
646     return rv;
647 }
648
649 int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd)
650 {
651     if (ssl_conf_cmd_skip_prefix(cctx, &cmd)) {
652         const ssl_conf_cmd_tbl *runcmd;
653         runcmd = ssl_conf_cmd_lookup(cctx, cmd);
654         if (runcmd)
655             return runcmd->value_type;
656     }
657     return SSL_CONF_TYPE_UNKNOWN;
658 }
659
660 SSL_CONF_CTX *SSL_CONF_CTX_new(void)
661 {
662     SSL_CONF_CTX *ret = OPENSSL_malloc(sizeof(*ret));
663     size_t i;
664
665     if (ret) {
666         ret->flags = 0;
667         ret->prefix = NULL;
668         ret->prefixlen = 0;
669         ret->ssl = NULL;
670         ret->ctx = NULL;
671         ret->poptions = NULL;
672         ret->pcert_flags = NULL;
673         ret->tbl = NULL;
674         ret->ntbl = 0;
675         for (i = 0; i < SSL_PKEY_NUM; i++)
676             ret->cert_filename[i] = NULL;
677     }
678     return ret;
679 }
680
681 int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx)
682 {
683     /* See if any certificates are missing private keys */
684     size_t i;
685     CERT *c = NULL;
686     if (cctx->ctx)
687         c = cctx->ctx->cert;
688     else if (cctx->ssl)
689         c = cctx->ssl->cert;
690     if (c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
691         for (i = 0; i < SSL_PKEY_NUM; i++) {
692             const char *p = cctx->cert_filename[i];
693             /*
694              * If missing private key try to load one from certificate file
695              */
696             if (p && !c->pkeys[i].privatekey) {
697                 if (!cmd_PrivateKey(cctx, p))
698                     return 0;
699             }
700         }
701     }
702     return 1;
703 }
704
705 void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx)
706 {
707     if (cctx) {
708         size_t i;
709         for (i = 0; i < SSL_PKEY_NUM; i++)
710             OPENSSL_free(cctx->cert_filename[i]);
711         OPENSSL_free(cctx->prefix);
712         OPENSSL_free(cctx);
713     }
714 }
715
716 unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags)
717 {
718     cctx->flags |= flags;
719     return cctx->flags;
720 }
721
722 unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags)
723 {
724     cctx->flags &= ~flags;
725     return cctx->flags;
726 }
727
728 int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre)
729 {
730     char *tmp = NULL;
731     if (pre) {
732         tmp = BUF_strdup(pre);
733         if (tmp == NULL)
734             return 0;
735     }
736     OPENSSL_free(cctx->prefix);
737     cctx->prefix = tmp;
738     if (tmp)
739         cctx->prefixlen = strlen(tmp);
740     else
741         cctx->prefixlen = 0;
742     return 1;
743 }
744
745 void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl)
746 {
747     cctx->ssl = ssl;
748     cctx->ctx = NULL;
749     if (ssl) {
750         cctx->poptions = &ssl->options;
751         cctx->pcert_flags = &ssl->cert->cert_flags;
752     } else {
753         cctx->poptions = NULL;
754         cctx->pcert_flags = NULL;
755     }
756 }
757
758 void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx)
759 {
760     cctx->ctx = ctx;
761     cctx->ssl = NULL;
762     if (ctx) {
763         cctx->poptions = &ctx->options;
764         cctx->pcert_flags = &ctx->cert->cert_flags;
765     } else {
766         cctx->poptions = NULL;
767         cctx->pcert_flags = NULL;
768     }
769 }