]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Use SSL_CTX_set_max_proto_version/SSL_CTX_set_min_proto_version where available
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 7 Sep 2017 05:07:02 +0000 (12:07 +0700)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 7 Sep 2017 05:10:06 +0000 (12:10 +0700)
Debian OpenSSL may disable TLS < 1.2 by default.

See here for details:

https://lists.debian.org/debian-devel-announce/2017/08/msg00004.html

Kurt Roeckx (author of the patch) stated that the original patch was modified so that
the version could still be changed with SSL_CTX_set_max_proto_version and SSL_CTX_set_min_proto_version.

But we still needed to add support for those functions.

raddb/mods-available/eap
src/include/tls-h
src/main/tls/conf.c
src/main/tls/ctx.c
src/modules/rlm_eap/types/rlm_eap_fast/rlm_eap_fast.c

index 53cf4aad939145b5258331ff5be068c6343043f9..d7200515148ed9e230d24d43bad28dfc5268e77e 100644 (file)
@@ -340,9 +340,23 @@ eap {
                #  not calculate the EAP keys correctly.  The fix is to upgrade
                #  OpenSSL, or disable TLS 1.2 here.
                #
-               #  For EAP-FAST, this MUST be set to "yes".
+               #  For EAP-FAST, this MUST be set to 1.1
                #
-               disable_tlsv1_2 = no
+               #  SSLv2 and SSLv3 are permanently disabled due to security
+               #  issues.
+               #
+#              tls_max_version = 1.1
+
+               #
+               #  Prevents versions < tls_min_version from being negotiated.
+               #  In general the higher the tls_min_version the more secure
+               #  the protocol, but the narrower the range of supported TLS
+               #  clients.
+               #
+               #  SSLv2 and SSLv3 are permanently disabled due to security
+               #  issues.
+               #
+#              tls_min_version = 1.0
 
                #
                #  Elliptical cryptography configuration
index 34f01b5d696d9861c3e1e1dde70e6f8fac2e6f96..75b2f9ba62a018b358f259eb05b5a0a5f0379217 100644 (file)
@@ -232,9 +232,9 @@ struct fr_tls_conf_t {
                                                        //!< If false, the complete chain must be provided in
                                                        //!< certificate file.
        bool            disable_single_dh_use;
-       bool            disable_tlsv1;                  //!< Prevent TLSv1 being negotiated.
-       bool            disable_tlsv1_1;                //!< Prevent TLSv1.1 being negotiated.
-       bool            disable_tlsv1_2;                //!< Prevent TLSv1.2 being negotiated.
+
+       float           tls_max_version;                //!< Maximum TLS version allowed.
+       float           tls_min_version;                //!< Minimum TLS version allowed.
 
        uint32_t        fragment_size;                  //!< Maximum record fragment, or record size.
        bool            check_crl;                      //!< Check certificate revocation lists.
index 58dff83f6f59af8aff4ac88fe97c30a915c716e1..9b4ca2bd6b25ab1ac4f45d5f6245f2274c0a8382 100644 (file)
@@ -119,17 +119,21 @@ CONF_PARSER tls_server_config[] = {
 #endif
 
 #ifdef SSL_OP_NO_TLSv1
-       { FR_CONF_OFFSET("disable_tlsv1", FR_TYPE_BOOL, fr_tls_conf_t, disable_tlsv1) },
+       { FR_CONF_DEPRECATED("disable_tlsv1", FR_TYPE_BOOL, fr_tls_conf_t, disable_tlsv1) },
 #endif
 
 #ifdef SSL_OP_NO_TLSv1_1
-       { FR_CONF_OFFSET("disable_tlsv1_1", FR_TYPE_BOOL, fr_tls_conf_t, disable_tlsv1_1) },
+       { FR_CONF_DEPRECATED("disable_tlsv1_1", FR_TYPE_BOOL, fr_tls_conf_t, disable_tlsv1_1) },
 #endif
 
 #ifdef SSL_OP_NO_TLSv1_2
-       { FR_CONF_OFFSET("disable_tlsv1_2", FR_TYPE_BOOL, fr_tls_conf_t, disable_tlsv1_2) },
+       { FR_CONF_DEPRECATED("disable_tlsv1_2", FR_TYPE_BOOL, fr_tls_conf_t, disable_tlsv1_2) },
 #endif
 
+       { FR_CONF_OFFSET("tls_max_version", FR_TYPE_FLOAT32, fr_tls_conf_t, tls_max_version) },
+
+       { FR_CONF_OFFSET("tls_min_version", FR_TYPE_FLOAT32, fr_tls_conf_t, tls_min_version), .dflt = "1.0" },
+
        { FR_CONF_POINTER("cache", FR_TYPE_SUBSECTION, NULL), .subcs = (void const *) cache_config },
 
        { FR_CONF_POINTER("verify", FR_TYPE_SUBSECTION, NULL), .subcs = (void const *) verify_config },
@@ -165,16 +169,20 @@ CONF_PARSER tls_client_config[] = {
 #endif
 
 #ifdef SSL_OP_NO_TLSv1
-       { FR_CONF_OFFSET("disable_tlsv1", FR_TYPE_BOOL, fr_tls_conf_t, disable_tlsv1) },
+       { FR_CONF_DEPRECATED("disable_tlsv1", FR_TYPE_BOOL, fr_tls_conf_t, disable_tlsv1) },
 #endif
 
 #ifdef SSL_OP_NO_TLSv1_1
-       { FR_CONF_OFFSET("disable_tlsv1_1", FR_TYPE_BOOL, fr_tls_conf_t, disable_tlsv1_1) },
+       { FR_CONF_DEPRECATED("disable_tlsv1_1", FR_TYPE_BOOL, fr_tls_conf_t, disable_tlsv1_1) },
 #endif
 
 #ifdef SSL_OP_NO_TLSv1_2
-       { FR_CONF_OFFSET("disable_tlsv1_2", FR_TYPE_BOOL, fr_tls_conf_t, disable_tlsv1_2) },
+       { FR_CONF_DEPRECATED("disable_tlsv1_2", FR_TYPE_BOOL, fr_tls_conf_t, disable_tlsv1_2) },
 #endif
+       { FR_CONF_OFFSET("tls_max_version", FR_TYPE_FLOAT32, fr_tls_conf_t, tls_max_version) },
+
+       { FR_CONF_OFFSET("tls_min_version", FR_TYPE_FLOAT32, fr_tls_conf_t, tls_min_version), .dflt = "1.0" },
+
        CONF_PARSER_TERMINATOR
 };
 
@@ -411,7 +419,7 @@ fr_tls_conf_t *tls_conf_parse_server(CONF_SECTION *cs)
         *      OpenSSL 1.0.1f and 1.0.1g get the MS-MPPE keys wrong.
         */
 #if (OPENSSL_VERSION_NUMBER >= 0x10010060L) && (OPENSSL_VERSION_NUMBER < 0x10010060L)
-       conf->disable_tlsv1_2 = true;
+       conf->max_tls_version = 1.1;
        WARN("OpenSSL version in range 1.0.1f-1.0.1g. "
             "TLSv1.2 disabled to workaround broken keying material export");
 #endif
index c49ab4049896a10791c7dc86404f3dc9119d20ed..7f67676cb6db7e79b48c4334f2a82f2cc3aa4e5d 100644 (file)
@@ -121,7 +121,6 @@ SSL_CTX *tls_ctx_alloc(fr_tls_conf_t const *conf, bool client)
        X509_STORE      *cert_vpstore;
        int             verify_mode = SSL_VERIFY_NONE;
        int             ctx_options = 0;
-       int             ctx_tls_versions = 0;
        int             type;
        void            *app_data_index;
 
@@ -287,36 +286,116 @@ load_ca:
 post_ca:
 #endif
 
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
        /*
-        *      We never want SSLv2 or SSLv3.
+        *      SSL_CTX_set_(min|max)_proto_version was included in OpenSSL 1.1.0
+        *
+        *      This version already defines macros for TLS1_2_VERSION and
+        *      below, so we don't need to check for them explicitly.
+        *
+        *      TLS1_3_VERSION is available in OpenSSL 1.1.1.
+        *
+        *      TLS1_4_VERSION in speculative.
         */
-       ctx_options |= SSL_OP_NO_SSLv2;
-       ctx_options |= SSL_OP_NO_SSLv3;
+       if (conf->tls_max_version > 0.0) {
+               int max_version = 0;
 
-       /*
-        *      As of 3.0.5, we always allow TLSv1.1 and TLSv1.2.
-        *      Though they can be *globally* disabled if necessary.x
-        */
-#ifdef SSL_OP_NO_TLSv1
-       if (conf->disable_tlsv1) ctx_options |= SSL_OP_NO_TLSv1;
+               if (conf->tls_min_version > conf->tls_max_version) {
+                       ERROR("tls_min_version (%f) must be <= tls_max_version (%f)",
+                             conf->tls_min_version, conf->tls_max_version);
+                       return NULL;
+               }
 
-       ctx_tls_versions |= SSL_OP_NO_TLSv1;
-#endif
-#ifdef SSL_OP_NO_TLSv1_1
-       if (conf->disable_tlsv1_1) ctx_options |= SSL_OP_NO_TLSv1_1;
+               if (conf->tls_max_version < 1.0) {
+                       ERROR("tls_max_version must be >= 1.0 as SSLv2 and SSLv3 are permanently disabled");
+                       return NULL;
+               }
 
-       ctx_tls_versions |= SSL_OP_NO_TLSv1_1;
-#endif
-#ifdef SSL_OP_NO_TLSv1_2
-       if (conf->disable_tlsv1_2) ctx_options |= SSL_OP_NO_TLSv1_2;
+#  ifdef TLS1_4_VERSION
+               else if (conf->tls_max_version >= 1.4) max_version = TLS1_4_VERSION;
+#  endif
+#  ifdef TLS1_3_VERSION
+               else if (conf->tls_max_version >= 1.3) max_version = TLS1_3_VERSION;
+#  endif
+               else if (conf->tls_max_version >= 1.2) max_version = TLS1_2_VERSION;
+               else if (conf->tls_max_version >= 1.1) max_version = TLS1_1_VERSION;
+               else max_version = TLS1_VERSION;
 
-       ctx_tls_versions |= SSL_OP_NO_TLSv1_2;
-#endif
+               if (!SSL_CTX_set_max_proto_version(ctx, max_version)) {
+                       tls_log_error(NULL, "Failed setting TLS maximum version");
+                       return NULL;
+               }
+       }
 
-       if ((ctx_options & ctx_tls_versions) == ctx_tls_versions) {
-               ERROR("You have disabled all available TLS versions.  EAP will not work");
-               return NULL;
+       {
+               int min_version = TLS1_VERSION;
+
+               if (conf->tls_min_version < 1.0) {
+                       ERROR("tls_min_version must be >= 1.0 as SSLv2 and SSLv3 are permanently disabled");
+                       return NULL;
+               }
+#  ifdef TLS1_4_VERSION
+               else if (conf->tls_min_version >= 1.4) min_version = TLS1_4_VERSION;
+#  endif
+#  ifdef TLS1_3_VERSION
+               else if (conf->tls_min_version >= 1.3) min_version = TLS1_3_VERSION;
+#  endif
+               else if (conf->tls_min_version >= 1.2) min_version = TLS1_2_VERSION;
+               else if (conf->tls_min_version >= 1.1) min_version = TLS1_1_VERSION;
+               else min_version = TLS1_VERSION;
+
+               if (!SSL_CTX_set_min_proto_version(ctx, min_version)) {
+                       tls_log_error(NULL, "Failed setting TLS minimum version");
+                       return NULL;
+               }
+       }
+#else
+       {
+               int ctx_tls_versions = 0;
+
+               /*
+                *      We never want SSLv2 or SSLv3.
+                */
+               ctx_options |= SSL_OP_NO_SSLv2;
+               ctx_options |= SSL_OP_NO_SSLv3;
+
+               if (conf->tls_min_version < 1.0) {
+                       ERROR("SSLv2 and SSLv3 are permanently disabled due to critical security issues");
+                       return NULL;
+               }
+
+               /*
+                *      As of 3.0.5, we always allow TLSv1.1 and TLSv1.2.
+                *      Though they can be *globally* disabled if necessary.x
+                */
+#  ifdef SSL_OP_NO_TLSv1
+               if (conf->tls_min_version > 1.0) ctx_options |= SSL_OP_NO_TLSv1;
+               if ((conf->tls_max_version != 0.0) && (conf->tls_max_version < 1.0)) {
+                       ctx_options |= SSL_OP_NO_TLSv1;
+               }
+               ctx_tls_versions |= SSL_OP_NO_TLSv1;
+#  endif
+#  ifdef SSL_OP_NO_TLSv1_1
+               if (conf->tls_min_version > 1.1) ctx_options |= SSL_OP_NO_TLSv1_1;
+               if ((conf->tls_max_version != 0.0) && (conf->tls_max_version < 1.1)) {
+                       ctx_options |= SSL_OP_NO_TLSv1_1;
+               }
+               ctx_tls_versions |= SSL_OP_NO_TLSv1_1;
+#  endif
+#  ifdef SSL_OP_NO_TLSv1_2
+               if (conf->tls_min_version > 1.2) ctx_options |= SSL_OP_NO_TLSv1_2;
+               if ((conf->tls_max_version != 0.0) && (conf->tls_max_version < 1.2)) {
+                       ctx_options |= SSL_OP_NO_TLSv1_2;
+               }
+               ctx_tls_versions |= SSL_OP_NO_TLSv1_2;
+#  endif
+
+               if ((ctx_options & ctx_tls_versions) == ctx_tls_versions) {
+                       ERROR("You have disabled all available TLS versions.  EAP will not work");
+                       return NULL;
+               }
        }
+#endif
 
 #ifdef SSL_OP_NO_TICKET
        ctx_options |= SSL_OP_NO_TICKET;
index 588e20356417a99b485ea5e59f5233142700ea0a..51730d95c1ac16564a72c9ae34cc7d9caa8b2f3e 100644 (file)
@@ -107,8 +107,8 @@ static int mod_instantiate(void *instance, CONF_SECTION *cs)
        }
 
        // FIXME TLSv1.2 uses a different PRF and SSL_export_keying_material("key expansion") is forbidden
-       if (!inst->tls_conf->disable_tlsv1_2) {
-               cf_log_err_by_name(cs, "disable_tlsv1_2", "require disable_tlsv1_2=yes");
+       if ((inst->tls_conf->tls_max_version > 1.1) || (inst->tls_conf->tls_max_version == 0.0)) {
+               cf_log_err_by_name(cs, "tls_max_version", "require tls_max_version <= 1.1");
                return -1;
        }