xref: /freebsd/crypto/openssl/ssl/ssl_conf.c (revision 4c6a0400b9d2b61156387f94d9adbc5f9baa5415)
17bded2dbSJung-uk Kim /*
27bded2dbSJung-uk Kim  * ! \file ssl/ssl_conf.c \brief SSL configuration functions
37bded2dbSJung-uk Kim  */
47bded2dbSJung-uk Kim /* ====================================================================
57bded2dbSJung-uk Kim  * Copyright (c) 2012 The OpenSSL Project.  All rights reserved.
67bded2dbSJung-uk Kim  *
77bded2dbSJung-uk Kim  * Redistribution and use in source and binary forms, with or without
87bded2dbSJung-uk Kim  * modification, are permitted provided that the following conditions
97bded2dbSJung-uk Kim  * are met:
107bded2dbSJung-uk Kim  *
117bded2dbSJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
127bded2dbSJung-uk Kim  *    notice, this list of conditions and the following disclaimer.
137bded2dbSJung-uk Kim  *
147bded2dbSJung-uk Kim  * 2. Redistributions in binary form must reproduce the above copyright
157bded2dbSJung-uk Kim  *    notice, this list of conditions and the following disclaimer in
167bded2dbSJung-uk Kim  *    the documentation and/or other materials provided with the
177bded2dbSJung-uk Kim  *    distribution.
187bded2dbSJung-uk Kim  *
197bded2dbSJung-uk Kim  * 3. All advertising materials mentioning features or use of this
207bded2dbSJung-uk Kim  *    software must display the following acknowledgment:
217bded2dbSJung-uk Kim  *    "This product includes software developed by the OpenSSL Project
227bded2dbSJung-uk Kim  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
237bded2dbSJung-uk Kim  *
247bded2dbSJung-uk Kim  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
257bded2dbSJung-uk Kim  *    endorse or promote products derived from this software without
267bded2dbSJung-uk Kim  *    prior written permission. For written permission, please contact
277bded2dbSJung-uk Kim  *    openssl-core@openssl.org.
287bded2dbSJung-uk Kim  *
297bded2dbSJung-uk Kim  * 5. Products derived from this software may not be called "OpenSSL"
307bded2dbSJung-uk Kim  *    nor may "OpenSSL" appear in their names without prior written
317bded2dbSJung-uk Kim  *    permission of the OpenSSL Project.
327bded2dbSJung-uk Kim  *
337bded2dbSJung-uk Kim  * 6. Redistributions of any form whatsoever must retain the following
347bded2dbSJung-uk Kim  *    acknowledgment:
357bded2dbSJung-uk Kim  *    "This product includes software developed by the OpenSSL Project
367bded2dbSJung-uk Kim  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
377bded2dbSJung-uk Kim  *
387bded2dbSJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
397bded2dbSJung-uk Kim  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
407bded2dbSJung-uk Kim  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
417bded2dbSJung-uk Kim  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
427bded2dbSJung-uk Kim  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
437bded2dbSJung-uk Kim  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
447bded2dbSJung-uk Kim  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
457bded2dbSJung-uk Kim  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
467bded2dbSJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
477bded2dbSJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
487bded2dbSJung-uk Kim  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
497bded2dbSJung-uk Kim  * OF THE POSSIBILITY OF SUCH DAMAGE.
507bded2dbSJung-uk Kim  * ====================================================================
517bded2dbSJung-uk Kim  *
527bded2dbSJung-uk Kim  * This product includes cryptographic software written by Eric Young
537bded2dbSJung-uk Kim  * (eay@cryptsoft.com).  This product includes software written by Tim
547bded2dbSJung-uk Kim  * Hudson (tjh@cryptsoft.com).
557bded2dbSJung-uk Kim  *
567bded2dbSJung-uk Kim  */
577bded2dbSJung-uk Kim 
587bded2dbSJung-uk Kim #ifdef REF_CHECK
597bded2dbSJung-uk Kim # include <assert.h>
607bded2dbSJung-uk Kim #endif
617bded2dbSJung-uk Kim #include <stdio.h>
627bded2dbSJung-uk Kim #include "ssl_locl.h"
637bded2dbSJung-uk Kim #include <openssl/conf.h>
647bded2dbSJung-uk Kim #include <openssl/objects.h>
657bded2dbSJung-uk Kim #ifndef OPENSSL_NO_DH
667bded2dbSJung-uk Kim # include <openssl/dh.h>
677bded2dbSJung-uk Kim #endif
687bded2dbSJung-uk Kim 
697bded2dbSJung-uk Kim /*
707bded2dbSJung-uk Kim  * structure holding name tables. This is used for pemitted elements in lists
717bded2dbSJung-uk Kim  * such as TLSv1 and single command line switches such as no_tls1
727bded2dbSJung-uk Kim  */
737bded2dbSJung-uk Kim 
747bded2dbSJung-uk Kim typedef struct {
757bded2dbSJung-uk Kim     const char *name;
767bded2dbSJung-uk Kim     int namelen;
777bded2dbSJung-uk Kim     unsigned int name_flags;
787bded2dbSJung-uk Kim     unsigned long option_value;
797bded2dbSJung-uk Kim } ssl_flag_tbl;
807bded2dbSJung-uk Kim 
817bded2dbSJung-uk Kim /* Sense of name is inverted e.g. "TLSv1" will clear SSL_OP_NO_TLSv1 */
827bded2dbSJung-uk Kim #define SSL_TFLAG_INV   0x1
837bded2dbSJung-uk Kim /* Flags refers to cert_flags not options */
847bded2dbSJung-uk Kim #define SSL_TFLAG_CERT  0x2
857bded2dbSJung-uk Kim /* Option can only be used for clients */
867bded2dbSJung-uk Kim #define SSL_TFLAG_CLIENT SSL_CONF_FLAG_CLIENT
877bded2dbSJung-uk Kim /* Option can only be used for servers */
887bded2dbSJung-uk Kim #define SSL_TFLAG_SERVER SSL_CONF_FLAG_SERVER
897bded2dbSJung-uk Kim #define SSL_TFLAG_BOTH (SSL_TFLAG_CLIENT|SSL_TFLAG_SERVER)
907bded2dbSJung-uk Kim 
917bded2dbSJung-uk Kim #define SSL_FLAG_TBL(str, flag) \
927bded2dbSJung-uk Kim         {str, (int)(sizeof(str) - 1), SSL_TFLAG_BOTH, flag}
937bded2dbSJung-uk Kim #define SSL_FLAG_TBL_SRV(str, flag) \
947bded2dbSJung-uk Kim         {str, (int)(sizeof(str) - 1), SSL_TFLAG_SERVER, flag}
957bded2dbSJung-uk Kim #define SSL_FLAG_TBL_CLI(str, flag) \
967bded2dbSJung-uk Kim         {str, (int)(sizeof(str) - 1), SSL_TFLAG_CLIENT, flag}
977bded2dbSJung-uk Kim #define SSL_FLAG_TBL_INV(str, flag) \
987bded2dbSJung-uk Kim         {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_BOTH, flag}
997bded2dbSJung-uk Kim #define SSL_FLAG_TBL_SRV_INV(str, flag) \
1007bded2dbSJung-uk Kim         {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_SERVER, flag}
1017bded2dbSJung-uk Kim #define SSL_FLAG_TBL_CERT(str, flag) \
1027bded2dbSJung-uk Kim         {str, (int)(sizeof(str) - 1), SSL_TFLAG_CERT|SSL_TFLAG_BOTH, flag}
1037bded2dbSJung-uk Kim 
1047bded2dbSJung-uk Kim /*
1057bded2dbSJung-uk Kim  * Opaque structure containing SSL configuration context.
1067bded2dbSJung-uk Kim  */
1077bded2dbSJung-uk Kim 
1087bded2dbSJung-uk Kim struct ssl_conf_ctx_st {
1097bded2dbSJung-uk Kim     /*
1107bded2dbSJung-uk Kim      * Various flags indicating (among other things) which options we will
1117bded2dbSJung-uk Kim      * recognise.
1127bded2dbSJung-uk Kim      */
1137bded2dbSJung-uk Kim     unsigned int flags;
1147bded2dbSJung-uk Kim     /* Prefix and length of commands */
1157bded2dbSJung-uk Kim     char *prefix;
1167bded2dbSJung-uk Kim     size_t prefixlen;
1177bded2dbSJung-uk Kim     /* SSL_CTX or SSL structure to perform operations on */
1187bded2dbSJung-uk Kim     SSL_CTX *ctx;
1197bded2dbSJung-uk Kim     SSL *ssl;
1207bded2dbSJung-uk Kim     /* Pointer to SSL or SSL_CTX options field or NULL if none */
1217bded2dbSJung-uk Kim     unsigned long *poptions;
1227bded2dbSJung-uk Kim     /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */
1237bded2dbSJung-uk Kim     unsigned int *pcert_flags;
1247bded2dbSJung-uk Kim     /* Current flag table being worked on */
1257bded2dbSJung-uk Kim     const ssl_flag_tbl *tbl;
1267bded2dbSJung-uk Kim     /* Size of table */
1277bded2dbSJung-uk Kim     size_t ntbl;
1287bded2dbSJung-uk Kim };
1297bded2dbSJung-uk Kim 
1307bded2dbSJung-uk Kim static int ssl_match_option(SSL_CONF_CTX *cctx, const ssl_flag_tbl *tbl,
1317bded2dbSJung-uk Kim                             const char *name, int namelen, int onoff)
1327bded2dbSJung-uk Kim {
1337bded2dbSJung-uk Kim     /* If name not relevant for context skip */
1347bded2dbSJung-uk Kim     if (!(cctx->flags & tbl->name_flags & SSL_TFLAG_BOTH))
1357bded2dbSJung-uk Kim         return 0;
1367bded2dbSJung-uk Kim     if (namelen == -1) {
1377bded2dbSJung-uk Kim         if (strcmp(tbl->name, name))
1387bded2dbSJung-uk Kim             return 0;
1397bded2dbSJung-uk Kim     } else if (tbl->namelen != namelen
1407bded2dbSJung-uk Kim                || strncasecmp(tbl->name, name, namelen))
1417bded2dbSJung-uk Kim         return 0;
1427bded2dbSJung-uk Kim     if (cctx->poptions) {
1437bded2dbSJung-uk Kim         if (tbl->name_flags & SSL_TFLAG_INV)
1447bded2dbSJung-uk Kim             onoff ^= 1;
1457bded2dbSJung-uk Kim         if (tbl->name_flags & SSL_TFLAG_CERT) {
1467bded2dbSJung-uk Kim             if (onoff)
1477bded2dbSJung-uk Kim                 *cctx->pcert_flags |= tbl->option_value;
1487bded2dbSJung-uk Kim             else
1497bded2dbSJung-uk Kim                 *cctx->pcert_flags &= ~tbl->option_value;
1507bded2dbSJung-uk Kim         } else {
1517bded2dbSJung-uk Kim             if (onoff)
1527bded2dbSJung-uk Kim                 *cctx->poptions |= tbl->option_value;
1537bded2dbSJung-uk Kim             else
1547bded2dbSJung-uk Kim                 *cctx->poptions &= ~tbl->option_value;
1557bded2dbSJung-uk Kim         }
1567bded2dbSJung-uk Kim     }
1577bded2dbSJung-uk Kim     return 1;
1587bded2dbSJung-uk Kim }
1597bded2dbSJung-uk Kim 
1607bded2dbSJung-uk Kim static int ssl_set_option_list(const char *elem, int len, void *usr)
1617bded2dbSJung-uk Kim {
1627bded2dbSJung-uk Kim     SSL_CONF_CTX *cctx = usr;
1637bded2dbSJung-uk Kim     size_t i;
1647bded2dbSJung-uk Kim     const ssl_flag_tbl *tbl;
1657bded2dbSJung-uk Kim     int onoff = 1;
1667bded2dbSJung-uk Kim     /*
1677bded2dbSJung-uk Kim      * len == -1 indicates not being called in list context, just for single
1687bded2dbSJung-uk Kim      * command line switches, so don't allow +, -.
1697bded2dbSJung-uk Kim      */
1707bded2dbSJung-uk Kim     if (elem == NULL)
1717bded2dbSJung-uk Kim         return 0;
1727bded2dbSJung-uk Kim     if (len != -1) {
1737bded2dbSJung-uk Kim         if (*elem == '+') {
1747bded2dbSJung-uk Kim             elem++;
1757bded2dbSJung-uk Kim             len--;
1767bded2dbSJung-uk Kim             onoff = 1;
1777bded2dbSJung-uk Kim         } else if (*elem == '-') {
1787bded2dbSJung-uk Kim             elem++;
1797bded2dbSJung-uk Kim             len--;
1807bded2dbSJung-uk Kim             onoff = 0;
1817bded2dbSJung-uk Kim         }
1827bded2dbSJung-uk Kim     }
1837bded2dbSJung-uk Kim     for (i = 0, tbl = cctx->tbl; i < cctx->ntbl; i++, tbl++) {
1847bded2dbSJung-uk Kim         if (ssl_match_option(cctx, tbl, elem, len, onoff))
1857bded2dbSJung-uk Kim             return 1;
1867bded2dbSJung-uk Kim     }
1877bded2dbSJung-uk Kim     return 0;
1887bded2dbSJung-uk Kim }
1897bded2dbSJung-uk Kim 
1907bded2dbSJung-uk Kim /* Single command line switches with no argument e.g. -no_ssl3 */
1917bded2dbSJung-uk Kim static int ctrl_str_option(SSL_CONF_CTX *cctx, const char *cmd)
1927bded2dbSJung-uk Kim {
1937bded2dbSJung-uk Kim     static const ssl_flag_tbl ssl_option_single[] = {
1947bded2dbSJung-uk Kim         SSL_FLAG_TBL("no_ssl2", SSL_OP_NO_SSLv2),
1957bded2dbSJung-uk Kim         SSL_FLAG_TBL("no_ssl3", SSL_OP_NO_SSLv3),
1967bded2dbSJung-uk Kim         SSL_FLAG_TBL("no_tls1", SSL_OP_NO_TLSv1),
1977bded2dbSJung-uk Kim         SSL_FLAG_TBL("no_tls1_1", SSL_OP_NO_TLSv1_1),
1987bded2dbSJung-uk Kim         SSL_FLAG_TBL("no_tls1_2", SSL_OP_NO_TLSv1_2),
1997bded2dbSJung-uk Kim         SSL_FLAG_TBL("bugs", SSL_OP_ALL),
2007bded2dbSJung-uk Kim         SSL_FLAG_TBL("no_comp", SSL_OP_NO_COMPRESSION),
2017bded2dbSJung-uk Kim         SSL_FLAG_TBL_SRV("ecdh_single", SSL_OP_SINGLE_ECDH_USE),
2027bded2dbSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT
2037bded2dbSJung-uk Kim         SSL_FLAG_TBL("no_ticket", SSL_OP_NO_TICKET),
2047bded2dbSJung-uk Kim #endif
2057bded2dbSJung-uk Kim         SSL_FLAG_TBL_SRV("serverpref", SSL_OP_CIPHER_SERVER_PREFERENCE),
2067bded2dbSJung-uk Kim         SSL_FLAG_TBL("legacy_renegotiation",
2077bded2dbSJung-uk Kim                      SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION),
2087bded2dbSJung-uk Kim         SSL_FLAG_TBL_SRV("legacy_server_connect",
2097bded2dbSJung-uk Kim                          SSL_OP_LEGACY_SERVER_CONNECT),
2107bded2dbSJung-uk Kim         SSL_FLAG_TBL_SRV("no_resumption_on_reneg",
2117bded2dbSJung-uk Kim                          SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION),
2127bded2dbSJung-uk Kim         SSL_FLAG_TBL_SRV_INV("no_legacy_server_connect",
2137bded2dbSJung-uk Kim                              SSL_OP_LEGACY_SERVER_CONNECT),
2147bded2dbSJung-uk Kim         SSL_FLAG_TBL_CERT("strict", SSL_CERT_FLAG_TLS_STRICT),
2157bded2dbSJung-uk Kim #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
2167bded2dbSJung-uk Kim         SSL_FLAG_TBL_CERT("debug_broken_protocol",
2177bded2dbSJung-uk Kim                           SSL_CERT_FLAG_BROKEN_PROTOCOL),
2187bded2dbSJung-uk Kim #endif
2197bded2dbSJung-uk Kim     };
2207bded2dbSJung-uk Kim     cctx->tbl = ssl_option_single;
2217bded2dbSJung-uk Kim     cctx->ntbl = sizeof(ssl_option_single) / sizeof(ssl_flag_tbl);
2227bded2dbSJung-uk Kim     return ssl_set_option_list(cmd, -1, cctx);
2237bded2dbSJung-uk Kim }
2247bded2dbSJung-uk Kim 
2257bded2dbSJung-uk Kim /* Set supported signature algorithms */
2267bded2dbSJung-uk Kim static int cmd_SignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
2277bded2dbSJung-uk Kim {
2287bded2dbSJung-uk Kim     int rv;
2297bded2dbSJung-uk Kim     if (cctx->ssl)
2307bded2dbSJung-uk Kim         rv = SSL_set1_sigalgs_list(cctx->ssl, value);
2317bded2dbSJung-uk Kim     /* NB: ctx == NULL performs syntax checking only */
2327bded2dbSJung-uk Kim     else
2337bded2dbSJung-uk Kim         rv = SSL_CTX_set1_sigalgs_list(cctx->ctx, value);
2347bded2dbSJung-uk Kim     return rv > 0;
2357bded2dbSJung-uk Kim }
2367bded2dbSJung-uk Kim 
2377bded2dbSJung-uk Kim /* Set supported client signature algorithms */
2387bded2dbSJung-uk Kim static int cmd_ClientSignatureAlgorithms(SSL_CONF_CTX *cctx,
2397bded2dbSJung-uk Kim                                          const char *value)
2407bded2dbSJung-uk Kim {
2417bded2dbSJung-uk Kim     int rv;
2427bded2dbSJung-uk Kim     if (cctx->ssl)
2437bded2dbSJung-uk Kim         rv = SSL_set1_client_sigalgs_list(cctx->ssl, value);
2447bded2dbSJung-uk Kim     /* NB: ctx == NULL performs syntax checking only */
2457bded2dbSJung-uk Kim     else
2467bded2dbSJung-uk Kim         rv = SSL_CTX_set1_client_sigalgs_list(cctx->ctx, value);
2477bded2dbSJung-uk Kim     return rv > 0;
2487bded2dbSJung-uk Kim }
2497bded2dbSJung-uk Kim 
2507bded2dbSJung-uk Kim static int cmd_Curves(SSL_CONF_CTX *cctx, const char *value)
2517bded2dbSJung-uk Kim {
2527bded2dbSJung-uk Kim     int rv;
2537bded2dbSJung-uk Kim     if (cctx->ssl)
2547bded2dbSJung-uk Kim         rv = SSL_set1_curves_list(cctx->ssl, value);
2557bded2dbSJung-uk Kim     /* NB: ctx == NULL performs syntax checking only */
2567bded2dbSJung-uk Kim     else
2577bded2dbSJung-uk Kim         rv = SSL_CTX_set1_curves_list(cctx->ctx, value);
2587bded2dbSJung-uk Kim     return rv > 0;
2597bded2dbSJung-uk Kim }
2607bded2dbSJung-uk Kim 
2617bded2dbSJung-uk Kim #ifndef OPENSSL_NO_ECDH
2627bded2dbSJung-uk Kim /* ECDH temporary parameters */
2637bded2dbSJung-uk Kim static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value)
2647bded2dbSJung-uk Kim {
2657bded2dbSJung-uk Kim     int onoff = -1, rv = 1;
2667bded2dbSJung-uk Kim     if (!(cctx->flags & SSL_CONF_FLAG_SERVER))
2677bded2dbSJung-uk Kim         return -2;
2687bded2dbSJung-uk Kim     if (cctx->flags & SSL_CONF_FLAG_FILE) {
2697bded2dbSJung-uk Kim         if (*value == '+') {
2707bded2dbSJung-uk Kim             onoff = 1;
2717bded2dbSJung-uk Kim             value++;
2727bded2dbSJung-uk Kim         }
2737bded2dbSJung-uk Kim         if (*value == '-') {
2747bded2dbSJung-uk Kim             onoff = 0;
2757bded2dbSJung-uk Kim             value++;
2767bded2dbSJung-uk Kim         }
2777bded2dbSJung-uk Kim         if (!strcasecmp(value, "automatic")) {
2787bded2dbSJung-uk Kim             if (onoff == -1)
2797bded2dbSJung-uk Kim                 onoff = 1;
2807bded2dbSJung-uk Kim         } else if (onoff != -1)
2817bded2dbSJung-uk Kim             return 0;
2827bded2dbSJung-uk Kim     } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
2837bded2dbSJung-uk Kim         if (!strcmp(value, "auto"))
2847bded2dbSJung-uk Kim             onoff = 1;
2857bded2dbSJung-uk Kim     }
2867bded2dbSJung-uk Kim 
2877bded2dbSJung-uk Kim     if (onoff != -1) {
2887bded2dbSJung-uk Kim         if (cctx->ctx)
2897bded2dbSJung-uk Kim             rv = SSL_CTX_set_ecdh_auto(cctx->ctx, onoff);
2907bded2dbSJung-uk Kim         else if (cctx->ssl)
2917bded2dbSJung-uk Kim             rv = SSL_set_ecdh_auto(cctx->ssl, onoff);
2927bded2dbSJung-uk Kim     } else {
2937bded2dbSJung-uk Kim         EC_KEY *ecdh;
2947bded2dbSJung-uk Kim         int nid;
2957bded2dbSJung-uk Kim         nid = EC_curve_nist2nid(value);
2967bded2dbSJung-uk Kim         if (nid == NID_undef)
2977bded2dbSJung-uk Kim             nid = OBJ_sn2nid(value);
2987bded2dbSJung-uk Kim         if (nid == 0)
2997bded2dbSJung-uk Kim             return 0;
3007bded2dbSJung-uk Kim         ecdh = EC_KEY_new_by_curve_name(nid);
3017bded2dbSJung-uk Kim         if (!ecdh)
3027bded2dbSJung-uk Kim             return 0;
3037bded2dbSJung-uk Kim         if (cctx->ctx)
3047bded2dbSJung-uk Kim             rv = SSL_CTX_set_tmp_ecdh(cctx->ctx, ecdh);
3057bded2dbSJung-uk Kim         else if (cctx->ssl)
3067bded2dbSJung-uk Kim             rv = SSL_set_tmp_ecdh(cctx->ssl, ecdh);
3077bded2dbSJung-uk Kim         EC_KEY_free(ecdh);
3087bded2dbSJung-uk Kim     }
3097bded2dbSJung-uk Kim 
3107bded2dbSJung-uk Kim     return rv > 0;
3117bded2dbSJung-uk Kim }
3127bded2dbSJung-uk Kim #endif
3137bded2dbSJung-uk Kim static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value)
3147bded2dbSJung-uk Kim {
3157bded2dbSJung-uk Kim     int rv = 1;
3167bded2dbSJung-uk Kim     if (cctx->ctx)
3177bded2dbSJung-uk Kim         rv = SSL_CTX_set_cipher_list(cctx->ctx, value);
3187bded2dbSJung-uk Kim     if (cctx->ssl)
3197bded2dbSJung-uk Kim         rv = SSL_set_cipher_list(cctx->ssl, value);
3207bded2dbSJung-uk Kim     return rv > 0;
3217bded2dbSJung-uk Kim }
3227bded2dbSJung-uk Kim 
3237bded2dbSJung-uk Kim static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value)
3247bded2dbSJung-uk Kim {
3257bded2dbSJung-uk Kim     static const ssl_flag_tbl ssl_protocol_list[] = {
3267bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK),
3277bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("SSLv2", SSL_OP_NO_SSLv2),
3287bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3),
3297bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1),
3307bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1),
3317bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2)
3327bded2dbSJung-uk Kim     };
333*4c6a0400SJung-uk Kim     int ret;
334*4c6a0400SJung-uk Kim     int sslv2off;
335*4c6a0400SJung-uk Kim 
3367bded2dbSJung-uk Kim     if (!(cctx->flags & SSL_CONF_FLAG_FILE))
3377bded2dbSJung-uk Kim         return -2;
3387bded2dbSJung-uk Kim     cctx->tbl = ssl_protocol_list;
3397bded2dbSJung-uk Kim     cctx->ntbl = sizeof(ssl_protocol_list) / sizeof(ssl_flag_tbl);
340*4c6a0400SJung-uk Kim 
341*4c6a0400SJung-uk Kim     sslv2off = *cctx->poptions & SSL_OP_NO_SSLv2;
342*4c6a0400SJung-uk Kim     ret = CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
343*4c6a0400SJung-uk Kim     /* Never turn on SSLv2 through configuration */
344*4c6a0400SJung-uk Kim     *cctx->poptions |= sslv2off;
345*4c6a0400SJung-uk Kim     return ret;
3467bded2dbSJung-uk Kim }
3477bded2dbSJung-uk Kim 
3487bded2dbSJung-uk Kim static int cmd_Options(SSL_CONF_CTX *cctx, const char *value)
3497bded2dbSJung-uk Kim {
3507bded2dbSJung-uk Kim     static const ssl_flag_tbl ssl_option_list[] = {
3517bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET),
3527bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("EmptyFragments",
3537bded2dbSJung-uk Kim                          SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS),
3547bded2dbSJung-uk Kim         SSL_FLAG_TBL("Bugs", SSL_OP_ALL),
3557bded2dbSJung-uk Kim         SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION),
3567bded2dbSJung-uk Kim         SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE),
3577bded2dbSJung-uk Kim         SSL_FLAG_TBL_SRV("NoResumptionOnRenegotiation",
3587bded2dbSJung-uk Kim                          SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION),
3597bded2dbSJung-uk Kim         SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE),
3607bded2dbSJung-uk Kim         SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE),
3617bded2dbSJung-uk Kim         SSL_FLAG_TBL("UnsafeLegacyRenegotiation",
3627bded2dbSJung-uk Kim                      SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION),
3637bded2dbSJung-uk Kim     };
3647bded2dbSJung-uk Kim     if (!(cctx->flags & SSL_CONF_FLAG_FILE))
3657bded2dbSJung-uk Kim         return -2;
3667bded2dbSJung-uk Kim     if (value == NULL)
3677bded2dbSJung-uk Kim         return -3;
3687bded2dbSJung-uk Kim     cctx->tbl = ssl_option_list;
3697bded2dbSJung-uk Kim     cctx->ntbl = sizeof(ssl_option_list) / sizeof(ssl_flag_tbl);
3707bded2dbSJung-uk Kim     return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
3717bded2dbSJung-uk Kim }
3727bded2dbSJung-uk Kim 
3737bded2dbSJung-uk Kim static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value)
3747bded2dbSJung-uk Kim {
3757bded2dbSJung-uk Kim     int rv = 1;
3767bded2dbSJung-uk Kim     if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
3777bded2dbSJung-uk Kim         return -2;
3787bded2dbSJung-uk Kim     if (cctx->ctx)
3797bded2dbSJung-uk Kim         rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value);
3807bded2dbSJung-uk Kim     if (cctx->ssl)
3817bded2dbSJung-uk Kim         rv = SSL_use_certificate_file(cctx->ssl, value, SSL_FILETYPE_PEM);
3827bded2dbSJung-uk Kim     return rv > 0;
3837bded2dbSJung-uk Kim }
3847bded2dbSJung-uk Kim 
3857bded2dbSJung-uk Kim static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value)
3867bded2dbSJung-uk Kim {
3877bded2dbSJung-uk Kim     int rv = 1;
3887bded2dbSJung-uk Kim     if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
3897bded2dbSJung-uk Kim         return -2;
3907bded2dbSJung-uk Kim     if (cctx->ctx)
3917bded2dbSJung-uk Kim         rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM);
3927bded2dbSJung-uk Kim     if (cctx->ssl)
3937bded2dbSJung-uk Kim         rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM);
3947bded2dbSJung-uk Kim     return rv > 0;
3957bded2dbSJung-uk Kim }
3967bded2dbSJung-uk Kim 
3977bded2dbSJung-uk Kim static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value)
3987bded2dbSJung-uk Kim {
3997bded2dbSJung-uk Kim     int rv = 1;
4007bded2dbSJung-uk Kim     if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
4017bded2dbSJung-uk Kim         return -2;
4027bded2dbSJung-uk Kim     if (!(cctx->flags & SSL_CONF_FLAG_SERVER))
4037bded2dbSJung-uk Kim         return -2;
4047bded2dbSJung-uk Kim     if (cctx->ctx)
4057bded2dbSJung-uk Kim         rv = SSL_CTX_use_serverinfo_file(cctx->ctx, value);
4067bded2dbSJung-uk Kim     return rv > 0;
4077bded2dbSJung-uk Kim }
4087bded2dbSJung-uk Kim 
4097bded2dbSJung-uk Kim #ifndef OPENSSL_NO_DH
4107bded2dbSJung-uk Kim static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value)
4117bded2dbSJung-uk Kim {
4127bded2dbSJung-uk Kim     int rv = 0;
4137bded2dbSJung-uk Kim     DH *dh = NULL;
4147bded2dbSJung-uk Kim     BIO *in = NULL;
4157bded2dbSJung-uk Kim     if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
4167bded2dbSJung-uk Kim         return -2;
4177bded2dbSJung-uk Kim     if (cctx->ctx || cctx->ssl) {
4187bded2dbSJung-uk Kim         in = BIO_new(BIO_s_file_internal());
4197bded2dbSJung-uk Kim         if (!in)
4207bded2dbSJung-uk Kim             goto end;
4217bded2dbSJung-uk Kim         if (BIO_read_filename(in, value) <= 0)
4227bded2dbSJung-uk Kim             goto end;
4237bded2dbSJung-uk Kim         dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
4247bded2dbSJung-uk Kim         if (!dh)
4257bded2dbSJung-uk Kim             goto end;
4267bded2dbSJung-uk Kim     } else
4277bded2dbSJung-uk Kim         return 1;
4287bded2dbSJung-uk Kim     if (cctx->ctx)
4297bded2dbSJung-uk Kim         rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh);
4307bded2dbSJung-uk Kim     if (cctx->ssl)
4317bded2dbSJung-uk Kim         rv = SSL_set_tmp_dh(cctx->ssl, dh);
4327bded2dbSJung-uk Kim  end:
4337bded2dbSJung-uk Kim     if (dh)
4347bded2dbSJung-uk Kim         DH_free(dh);
4357bded2dbSJung-uk Kim     if (in)
4367bded2dbSJung-uk Kim         BIO_free(in);
4377bded2dbSJung-uk Kim     return rv > 0;
4387bded2dbSJung-uk Kim }
4397bded2dbSJung-uk Kim #endif
4407bded2dbSJung-uk Kim typedef struct {
4417bded2dbSJung-uk Kim     int (*cmd) (SSL_CONF_CTX *cctx, const char *value);
4427bded2dbSJung-uk Kim     const char *str_file;
4437bded2dbSJung-uk Kim     const char *str_cmdline;
4447bded2dbSJung-uk Kim     unsigned int value_type;
4457bded2dbSJung-uk Kim } ssl_conf_cmd_tbl;
4467bded2dbSJung-uk Kim 
4477bded2dbSJung-uk Kim /* Table of supported parameters */
4487bded2dbSJung-uk Kim 
4497bded2dbSJung-uk Kim #define SSL_CONF_CMD(name, cmdopt, type) \
4507bded2dbSJung-uk Kim         {cmd_##name, #name, cmdopt, type}
4517bded2dbSJung-uk Kim 
4527bded2dbSJung-uk Kim #define SSL_CONF_CMD_STRING(name, cmdopt) \
4537bded2dbSJung-uk Kim         SSL_CONF_CMD(name, cmdopt, SSL_CONF_TYPE_STRING)
4547bded2dbSJung-uk Kim 
4557bded2dbSJung-uk Kim static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
4567bded2dbSJung-uk Kim     SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs"),
4577bded2dbSJung-uk Kim     SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs"),
4587bded2dbSJung-uk Kim     SSL_CONF_CMD_STRING(Curves, "curves"),
4597bded2dbSJung-uk Kim #ifndef OPENSSL_NO_ECDH
4607bded2dbSJung-uk Kim     SSL_CONF_CMD_STRING(ECDHParameters, "named_curve"),
4617bded2dbSJung-uk Kim #endif
4627bded2dbSJung-uk Kim     SSL_CONF_CMD_STRING(CipherString, "cipher"),
4637bded2dbSJung-uk Kim     SSL_CONF_CMD_STRING(Protocol, NULL),
4647bded2dbSJung-uk Kim     SSL_CONF_CMD_STRING(Options, NULL),
4657bded2dbSJung-uk Kim     SSL_CONF_CMD(Certificate, "cert", SSL_CONF_TYPE_FILE),
4667bded2dbSJung-uk Kim     SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_TYPE_FILE),
4677bded2dbSJung-uk Kim     SSL_CONF_CMD(ServerInfoFile, NULL, SSL_CONF_TYPE_FILE),
4687bded2dbSJung-uk Kim #ifndef OPENSSL_NO_DH
4697bded2dbSJung-uk Kim     SSL_CONF_CMD(DHParameters, "dhparam", SSL_CONF_TYPE_FILE)
4707bded2dbSJung-uk Kim #endif
4717bded2dbSJung-uk Kim };
4727bded2dbSJung-uk Kim 
4737bded2dbSJung-uk Kim static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd)
4747bded2dbSJung-uk Kim {
4757bded2dbSJung-uk Kim     if (!pcmd || !*pcmd)
4767bded2dbSJung-uk Kim         return 0;
4777bded2dbSJung-uk Kim     /* If a prefix is set, check and skip */
4787bded2dbSJung-uk Kim     if (cctx->prefix) {
4797bded2dbSJung-uk Kim         if (strlen(*pcmd) <= cctx->prefixlen)
4807bded2dbSJung-uk Kim             return 0;
4817bded2dbSJung-uk Kim         if (cctx->flags & SSL_CONF_FLAG_CMDLINE &&
4827bded2dbSJung-uk Kim             strncmp(*pcmd, cctx->prefix, cctx->prefixlen))
4837bded2dbSJung-uk Kim             return 0;
4847bded2dbSJung-uk Kim         if (cctx->flags & SSL_CONF_FLAG_FILE &&
4857bded2dbSJung-uk Kim             strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen))
4867bded2dbSJung-uk Kim             return 0;
4877bded2dbSJung-uk Kim         *pcmd += cctx->prefixlen;
4887bded2dbSJung-uk Kim     } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
4897bded2dbSJung-uk Kim         if (**pcmd != '-' || !(*pcmd)[1])
4907bded2dbSJung-uk Kim             return 0;
4917bded2dbSJung-uk Kim         *pcmd += 1;
4927bded2dbSJung-uk Kim     }
4937bded2dbSJung-uk Kim     return 1;
4947bded2dbSJung-uk Kim }
4957bded2dbSJung-uk Kim 
4967bded2dbSJung-uk Kim static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx,
4977bded2dbSJung-uk Kim                                                    const char *cmd)
4987bded2dbSJung-uk Kim {
4997bded2dbSJung-uk Kim     const ssl_conf_cmd_tbl *t;
5007bded2dbSJung-uk Kim     size_t i;
5017bded2dbSJung-uk Kim     if (cmd == NULL)
5027bded2dbSJung-uk Kim         return NULL;
5037bded2dbSJung-uk Kim 
5047bded2dbSJung-uk Kim     /* Look for matching parameter name in table */
5057bded2dbSJung-uk Kim     for (i = 0, t = ssl_conf_cmds;
5067bded2dbSJung-uk Kim          i < sizeof(ssl_conf_cmds) / sizeof(ssl_conf_cmd_tbl); i++, t++) {
5077bded2dbSJung-uk Kim         if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
5087bded2dbSJung-uk Kim             if (t->str_cmdline && !strcmp(t->str_cmdline, cmd))
5097bded2dbSJung-uk Kim                 return t;
5107bded2dbSJung-uk Kim         }
5117bded2dbSJung-uk Kim         if (cctx->flags & SSL_CONF_FLAG_FILE) {
5127bded2dbSJung-uk Kim             if (t->str_file && !strcasecmp(t->str_file, cmd))
5137bded2dbSJung-uk Kim                 return t;
5147bded2dbSJung-uk Kim         }
5157bded2dbSJung-uk Kim     }
5167bded2dbSJung-uk Kim     return NULL;
5177bded2dbSJung-uk Kim }
5187bded2dbSJung-uk Kim 
5197bded2dbSJung-uk Kim int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value)
5207bded2dbSJung-uk Kim {
5217bded2dbSJung-uk Kim     const ssl_conf_cmd_tbl *runcmd;
5227bded2dbSJung-uk Kim     if (cmd == NULL) {
5237bded2dbSJung-uk Kim         SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_INVALID_NULL_CMD_NAME);
5247bded2dbSJung-uk Kim         return 0;
5257bded2dbSJung-uk Kim     }
5267bded2dbSJung-uk Kim 
5277bded2dbSJung-uk Kim     if (!ssl_conf_cmd_skip_prefix(cctx, &cmd))
5287bded2dbSJung-uk Kim         return -2;
5297bded2dbSJung-uk Kim 
5307bded2dbSJung-uk Kim     runcmd = ssl_conf_cmd_lookup(cctx, cmd);
5317bded2dbSJung-uk Kim 
5327bded2dbSJung-uk Kim     if (runcmd) {
5337bded2dbSJung-uk Kim         int rv;
5347bded2dbSJung-uk Kim         if (value == NULL)
5357bded2dbSJung-uk Kim             return -3;
5367bded2dbSJung-uk Kim         rv = runcmd->cmd(cctx, value);
5377bded2dbSJung-uk Kim         if (rv > 0)
5387bded2dbSJung-uk Kim             return 2;
5397bded2dbSJung-uk Kim         if (rv == -2)
5407bded2dbSJung-uk Kim             return -2;
5417bded2dbSJung-uk Kim         if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) {
5427bded2dbSJung-uk Kim             SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_BAD_VALUE);
5437bded2dbSJung-uk Kim             ERR_add_error_data(4, "cmd=", cmd, ", value=", value);
5447bded2dbSJung-uk Kim         }
5457bded2dbSJung-uk Kim         return 0;
5467bded2dbSJung-uk Kim     }
5477bded2dbSJung-uk Kim 
5487bded2dbSJung-uk Kim     if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
5497bded2dbSJung-uk Kim         if (ctrl_str_option(cctx, cmd))
5507bded2dbSJung-uk Kim             return 1;
5517bded2dbSJung-uk Kim     }
5527bded2dbSJung-uk Kim 
5537bded2dbSJung-uk Kim     if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) {
5547bded2dbSJung-uk Kim         SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_UNKNOWN_CMD_NAME);
5557bded2dbSJung-uk Kim         ERR_add_error_data(2, "cmd=", cmd);
5567bded2dbSJung-uk Kim     }
5577bded2dbSJung-uk Kim 
5587bded2dbSJung-uk Kim     return -2;
5597bded2dbSJung-uk Kim }
5607bded2dbSJung-uk Kim 
5617bded2dbSJung-uk Kim int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv)
5627bded2dbSJung-uk Kim {
5637bded2dbSJung-uk Kim     int rv;
5647bded2dbSJung-uk Kim     const char *arg = NULL, *argn;
5657bded2dbSJung-uk Kim     if (pargc && *pargc == 0)
5667bded2dbSJung-uk Kim         return 0;
5677bded2dbSJung-uk Kim     if (!pargc || *pargc > 0)
5687bded2dbSJung-uk Kim         arg = **pargv;
5697bded2dbSJung-uk Kim     if (arg == NULL)
5707bded2dbSJung-uk Kim         return 0;
5717bded2dbSJung-uk Kim     if (!pargc || *pargc > 1)
5727bded2dbSJung-uk Kim         argn = (*pargv)[1];
5737bded2dbSJung-uk Kim     else
5747bded2dbSJung-uk Kim         argn = NULL;
5757bded2dbSJung-uk Kim     cctx->flags &= ~SSL_CONF_FLAG_FILE;
5767bded2dbSJung-uk Kim     cctx->flags |= SSL_CONF_FLAG_CMDLINE;
5777bded2dbSJung-uk Kim     rv = SSL_CONF_cmd(cctx, arg, argn);
5787bded2dbSJung-uk Kim     if (rv > 0) {
5797bded2dbSJung-uk Kim         /* Success: update pargc, pargv */
5807bded2dbSJung-uk Kim         (*pargv) += rv;
5817bded2dbSJung-uk Kim         if (pargc)
5827bded2dbSJung-uk Kim             (*pargc) -= rv;
5837bded2dbSJung-uk Kim         return rv;
5847bded2dbSJung-uk Kim     }
5857bded2dbSJung-uk Kim     /* Unknown switch: indicate no arguments processed */
5867bded2dbSJung-uk Kim     if (rv == -2)
5877bded2dbSJung-uk Kim         return 0;
5887bded2dbSJung-uk Kim     /* Some error occurred processing command, return fatal error */
5897bded2dbSJung-uk Kim     if (rv == 0)
5907bded2dbSJung-uk Kim         return -1;
5917bded2dbSJung-uk Kim     return rv;
5927bded2dbSJung-uk Kim }
5937bded2dbSJung-uk Kim 
5947bded2dbSJung-uk Kim int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd)
5957bded2dbSJung-uk Kim {
5967bded2dbSJung-uk Kim     if (ssl_conf_cmd_skip_prefix(cctx, &cmd)) {
5977bded2dbSJung-uk Kim         const ssl_conf_cmd_tbl *runcmd;
5987bded2dbSJung-uk Kim         runcmd = ssl_conf_cmd_lookup(cctx, cmd);
5997bded2dbSJung-uk Kim         if (runcmd)
6007bded2dbSJung-uk Kim             return runcmd->value_type;
6017bded2dbSJung-uk Kim     }
6027bded2dbSJung-uk Kim     return SSL_CONF_TYPE_UNKNOWN;
6037bded2dbSJung-uk Kim }
6047bded2dbSJung-uk Kim 
6057bded2dbSJung-uk Kim SSL_CONF_CTX *SSL_CONF_CTX_new(void)
6067bded2dbSJung-uk Kim {
6077bded2dbSJung-uk Kim     SSL_CONF_CTX *ret;
6087bded2dbSJung-uk Kim     ret = OPENSSL_malloc(sizeof(SSL_CONF_CTX));
6097bded2dbSJung-uk Kim     if (ret) {
6107bded2dbSJung-uk Kim         ret->flags = 0;
6117bded2dbSJung-uk Kim         ret->prefix = NULL;
6127bded2dbSJung-uk Kim         ret->prefixlen = 0;
6137bded2dbSJung-uk Kim         ret->ssl = NULL;
6147bded2dbSJung-uk Kim         ret->ctx = NULL;
6157bded2dbSJung-uk Kim         ret->poptions = NULL;
6167bded2dbSJung-uk Kim         ret->pcert_flags = NULL;
6177bded2dbSJung-uk Kim         ret->tbl = NULL;
6187bded2dbSJung-uk Kim         ret->ntbl = 0;
6197bded2dbSJung-uk Kim     }
6207bded2dbSJung-uk Kim     return ret;
6217bded2dbSJung-uk Kim }
6227bded2dbSJung-uk Kim 
6237bded2dbSJung-uk Kim int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx)
6247bded2dbSJung-uk Kim {
6257bded2dbSJung-uk Kim     return 1;
6267bded2dbSJung-uk Kim }
6277bded2dbSJung-uk Kim 
6287bded2dbSJung-uk Kim void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx)
6297bded2dbSJung-uk Kim {
6307bded2dbSJung-uk Kim     if (cctx) {
6317bded2dbSJung-uk Kim         if (cctx->prefix)
6327bded2dbSJung-uk Kim             OPENSSL_free(cctx->prefix);
6337bded2dbSJung-uk Kim         OPENSSL_free(cctx);
6347bded2dbSJung-uk Kim     }
6357bded2dbSJung-uk Kim }
6367bded2dbSJung-uk Kim 
6377bded2dbSJung-uk Kim unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags)
6387bded2dbSJung-uk Kim {
6397bded2dbSJung-uk Kim     cctx->flags |= flags;
6407bded2dbSJung-uk Kim     return cctx->flags;
6417bded2dbSJung-uk Kim }
6427bded2dbSJung-uk Kim 
6437bded2dbSJung-uk Kim unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags)
6447bded2dbSJung-uk Kim {
6457bded2dbSJung-uk Kim     cctx->flags &= ~flags;
6467bded2dbSJung-uk Kim     return cctx->flags;
6477bded2dbSJung-uk Kim }
6487bded2dbSJung-uk Kim 
6497bded2dbSJung-uk Kim int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre)
6507bded2dbSJung-uk Kim {
6517bded2dbSJung-uk Kim     char *tmp = NULL;
6527bded2dbSJung-uk Kim     if (pre) {
6537bded2dbSJung-uk Kim         tmp = BUF_strdup(pre);
6547bded2dbSJung-uk Kim         if (tmp == NULL)
6557bded2dbSJung-uk Kim             return 0;
6567bded2dbSJung-uk Kim     }
6577bded2dbSJung-uk Kim     if (cctx->prefix)
6587bded2dbSJung-uk Kim         OPENSSL_free(cctx->prefix);
6597bded2dbSJung-uk Kim     cctx->prefix = tmp;
6607bded2dbSJung-uk Kim     if (tmp)
6617bded2dbSJung-uk Kim         cctx->prefixlen = strlen(tmp);
6627bded2dbSJung-uk Kim     else
6637bded2dbSJung-uk Kim         cctx->prefixlen = 0;
6647bded2dbSJung-uk Kim     return 1;
6657bded2dbSJung-uk Kim }
6667bded2dbSJung-uk Kim 
6677bded2dbSJung-uk Kim void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl)
6687bded2dbSJung-uk Kim {
6697bded2dbSJung-uk Kim     cctx->ssl = ssl;
6707bded2dbSJung-uk Kim     cctx->ctx = NULL;
6717bded2dbSJung-uk Kim     if (ssl) {
6727bded2dbSJung-uk Kim         cctx->poptions = &ssl->options;
6737bded2dbSJung-uk Kim         cctx->pcert_flags = &ssl->cert->cert_flags;
6747bded2dbSJung-uk Kim     } else {
6757bded2dbSJung-uk Kim         cctx->poptions = NULL;
6767bded2dbSJung-uk Kim         cctx->pcert_flags = NULL;
6777bded2dbSJung-uk Kim     }
6787bded2dbSJung-uk Kim }
6797bded2dbSJung-uk Kim 
6807bded2dbSJung-uk Kim void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx)
6817bded2dbSJung-uk Kim {
6827bded2dbSJung-uk Kim     cctx->ctx = ctx;
6837bded2dbSJung-uk Kim     cctx->ssl = NULL;
6847bded2dbSJung-uk Kim     if (ctx) {
6857bded2dbSJung-uk Kim         cctx->poptions = &ctx->options;
6867bded2dbSJung-uk Kim         cctx->pcert_flags = &ctx->cert->cert_flags;
6877bded2dbSJung-uk Kim     } else {
6887bded2dbSJung-uk Kim         cctx->poptions = NULL;
6897bded2dbSJung-uk Kim         cctx->pcert_flags = NULL;
6907bded2dbSJung-uk Kim     }
6917bded2dbSJung-uk Kim }
692