OpenSSL: Allow systemwide policies to be overridden

Some distributions (e.g., Debian) have started introducting systemwide
OpenSSL policies to disable older protocol versions and ciphers
throughout all programs using OpenSSL. This can result in significant
number of interoperability issues with deployed EAP implementations.

Allow explicit wpa_supplicant (EAP peer) and hostapd (EAP server)
parameters to be used to request systemwide policies to be overridden if
older versions are needed to be able to interoperate with devices that
cannot be updated to support the newer protocol versions or keys. The
default behavior is not changed here, i.e., the systemwide policies will
be followed if no explicit override configuration is used. The overrides
should be used only if really needed since they can result in reduced
security.

In wpa_supplicant, tls_disable_tlsv1_?=0 value in the phase1 network
profile parameter can be used to explicitly enable TLS versions that are
disabled in the systemwide configuration. For example,
phase1="tls_disable_tlsv1_0=0 tls_disable_tlsv1_1=0" would request TLS
v1.0 and TLS v1.1 to be enabled even if the systemwide policy enforces
TLS v1.2 as the minimum version. Similarly, openssl_ciphers parameter
can be used to override systemwide policy, e.g., with
openssl_ciphers="DEFAULT@SECLEVEL=1" to drop from security level 2 to 1
in Debian to allow shorter keys to be used.

In hostapd, tls_flags parameter can be used to configure similar
options. E.g., tls_flags=[ENABLE-TLSv1.0][ENABLE-TLSv1.1]

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2019-01-05 17:02:33 +02:00
parent e3afbd796c
commit cc9c4feccc
6 changed files with 93 additions and 3 deletions

View file

@ -2265,10 +2265,16 @@ static unsigned int parse_tls_flags(const char *val)
flags |= TLS_CONN_DISABLE_TIME_CHECKS; flags |= TLS_CONN_DISABLE_TIME_CHECKS;
if (os_strstr(val, "[DISABLE-TLSv1.0]")) if (os_strstr(val, "[DISABLE-TLSv1.0]"))
flags |= TLS_CONN_DISABLE_TLSv1_0; flags |= TLS_CONN_DISABLE_TLSv1_0;
if (os_strstr(val, "[ENABLE-TLSv1.0]"))
flags |= TLS_CONN_ENABLE_TLSv1_0;
if (os_strstr(val, "[DISABLE-TLSv1.1]")) if (os_strstr(val, "[DISABLE-TLSv1.1]"))
flags |= TLS_CONN_DISABLE_TLSv1_1; flags |= TLS_CONN_DISABLE_TLSv1_1;
if (os_strstr(val, "[ENABLE-TLSv1.1]"))
flags |= TLS_CONN_ENABLE_TLSv1_1;
if (os_strstr(val, "[DISABLE-TLSv1.2]")) if (os_strstr(val, "[DISABLE-TLSv1.2]"))
flags |= TLS_CONN_DISABLE_TLSv1_2; flags |= TLS_CONN_DISABLE_TLSv1_2;
if (os_strstr(val, "[ENABLE-TLSv1.2]"))
flags |= TLS_CONN_ENABLE_TLSv1_2;
if (os_strstr(val, "[DISABLE-TLSv1.3]")) if (os_strstr(val, "[DISABLE-TLSv1.3]"))
flags |= TLS_CONN_DISABLE_TLSv1_3; flags |= TLS_CONN_DISABLE_TLSv1_3;
if (os_strstr(val, "[ENABLE-TLSv1.3]")) if (os_strstr(val, "[ENABLE-TLSv1.3]"))

View file

@ -917,6 +917,27 @@ eap_server=0
# (default: 0 = session caching and resumption disabled) # (default: 0 = session caching and resumption disabled)
#tls_session_lifetime=3600 #tls_session_lifetime=3600
# TLS flags
# [ALLOW-SIGN-RSA-MD5] = allow MD5-based certificate signatures (depending on
# the TLS library, these may be disabled by default to enforce stronger
# security)
# [DISABLE-TIME-CHECKS] = ignore certificate validity time (this requests
# the TLS library to accept certificates even if they are not currently
# valid, i.e., have expired or have not yet become valid; this should be
# used only for testing purposes)
# [DISABLE-TLSv1.0] = disable use of TLSv1.0
# [ENABLE-TLSv1.0] = explicitly enable use of TLSv1.0 (this allows
# systemwide TLS policies to be overridden)
# [DISABLE-TLSv1.1] = disable use of TLSv1.1
# [ENABLE-TLSv1.1] = explicitly enable use of TLSv1.1 (this allows
# systemwide TLS policies to be overridden)
# [DISABLE-TLSv1.2] = disable use of TLSv1.2
# [ENABLE-TLSv1.2] = explicitly enable use of TLSv1.2 (this allows
# systemwide TLS policies to be overridden)
# [DISABLE-TLSv1.3] = disable use of TLSv1.3
# [ENABLE-TLSv1.3] = enable TLSv1.3 (experimental - disabled by default)
#tls_flags=[flag1][flag2]...
# Cached OCSP stapling response (DER encoded) # Cached OCSP stapling response (DER encoded)
# If set, this file is sent as a certificate status response by the EAP server # If set, this file is sent as a certificate status response by the EAP server
# if the EAP peer requests certificate status in the ClientHello message. # if the EAP peer requests certificate status in the ClientHello message.

View file

@ -103,6 +103,9 @@ struct tls_config {
#define TLS_CONN_SUITEB BIT(11) #define TLS_CONN_SUITEB BIT(11)
#define TLS_CONN_SUITEB_NO_ECDH BIT(12) #define TLS_CONN_SUITEB_NO_ECDH BIT(12)
#define TLS_CONN_DISABLE_TLSv1_3 BIT(13) #define TLS_CONN_DISABLE_TLSv1_3 BIT(13)
#define TLS_CONN_ENABLE_TLSv1_0 BIT(14)
#define TLS_CONN_ENABLE_TLSv1_1 BIT(15)
#define TLS_CONN_ENABLE_TLSv1_2 BIT(16)
/** /**
* struct tls_connection_params - Parameters for TLS connection * struct tls_connection_params - Parameters for TLS connection

View file

@ -2533,6 +2533,38 @@ static int tls_set_conn_flags(struct tls_connection *conn, unsigned int flags,
else else
SSL_clear_options(ssl, SSL_OP_NO_TLSv1_3); SSL_clear_options(ssl, SSL_OP_NO_TLSv1_3);
#endif /* SSL_OP_NO_TLSv1_3 */ #endif /* SSL_OP_NO_TLSv1_3 */
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
if (flags & (TLS_CONN_ENABLE_TLSv1_0 |
TLS_CONN_ENABLE_TLSv1_1 |
TLS_CONN_ENABLE_TLSv1_2)) {
int version = 0;
/* Explicit request to enable TLS versions even if needing to
* override systemwide policies. */
if (flags & TLS_CONN_ENABLE_TLSv1_0) {
version = TLS1_VERSION;
} else if (flags & TLS_CONN_ENABLE_TLSv1_1) {
if (!(flags & TLS_CONN_DISABLE_TLSv1_0))
version = TLS1_1_VERSION;
} else if (flags & TLS_CONN_ENABLE_TLSv1_2) {
if (!(flags & (TLS_CONN_DISABLE_TLSv1_0 |
TLS_CONN_DISABLE_TLSv1_1)))
version = TLS1_2_VERSION;
}
if (!version) {
wpa_printf(MSG_DEBUG,
"OpenSSL: Invalid TLS version configuration");
return -1;
}
if (SSL_set_min_proto_version(ssl, version) != 1) {
wpa_printf(MSG_DEBUG,
"OpenSSL: Failed to set minimum TLS version");
return -1;
}
}
#endif /* >= 1.1.0 */
#ifdef CONFIG_SUITEB #ifdef CONFIG_SUITEB
#ifdef OPENSSL_IS_BORINGSSL #ifdef OPENSSL_IS_BORINGSSL
/* Start with defaults from BoringSSL */ /* Start with defaults from BoringSSL */
@ -2635,7 +2667,22 @@ static int tls_set_conn_flags(struct tls_connection *conn, unsigned int flags,
return -1; return -1;
} }
} }
#else /* OPENSSL_IS_BORINGSSL */
if (!(flags & (TLS_CONN_SUITEB | TLS_CONN_SUITEB_NO_ECDH)) &&
openssl_ciphers && SSL_set_cipher_list(ssl, openssl_ciphers) != 1) {
wpa_printf(MSG_INFO,
"OpenSSL: Failed to set openssl_ciphers '%s'",
openssl_ciphers);
return -1;
}
#endif /* OPENSSL_IS_BORINGSSL */ #endif /* OPENSSL_IS_BORINGSSL */
#else /* CONFIG_SUITEB */
if (openssl_ciphers && SSL_set_cipher_list(ssl, openssl_ciphers) != 1) {
wpa_printf(MSG_INFO,
"OpenSSL: Failed to set openssl_ciphers '%s'",
openssl_ciphers);
return -1;
}
#endif /* CONFIG_SUITEB */ #endif /* CONFIG_SUITEB */
return 0; return 0;

View file

@ -70,16 +70,22 @@ static void eap_tls_params_flags(struct tls_connection_params *params,
params->flags &= ~TLS_CONN_DISABLE_SESSION_TICKET; params->flags &= ~TLS_CONN_DISABLE_SESSION_TICKET;
if (os_strstr(txt, "tls_disable_tlsv1_0=1")) if (os_strstr(txt, "tls_disable_tlsv1_0=1"))
params->flags |= TLS_CONN_DISABLE_TLSv1_0; params->flags |= TLS_CONN_DISABLE_TLSv1_0;
if (os_strstr(txt, "tls_disable_tlsv1_0=0")) if (os_strstr(txt, "tls_disable_tlsv1_0=0")) {
params->flags &= ~TLS_CONN_DISABLE_TLSv1_0; params->flags &= ~TLS_CONN_DISABLE_TLSv1_0;
params->flags |= TLS_CONN_ENABLE_TLSv1_0;
}
if (os_strstr(txt, "tls_disable_tlsv1_1=1")) if (os_strstr(txt, "tls_disable_tlsv1_1=1"))
params->flags |= TLS_CONN_DISABLE_TLSv1_1; params->flags |= TLS_CONN_DISABLE_TLSv1_1;
if (os_strstr(txt, "tls_disable_tlsv1_1=0")) if (os_strstr(txt, "tls_disable_tlsv1_1=0")) {
params->flags &= ~TLS_CONN_DISABLE_TLSv1_1; params->flags &= ~TLS_CONN_DISABLE_TLSv1_1;
params->flags |= TLS_CONN_ENABLE_TLSv1_1;
}
if (os_strstr(txt, "tls_disable_tlsv1_2=1")) if (os_strstr(txt, "tls_disable_tlsv1_2=1"))
params->flags |= TLS_CONN_DISABLE_TLSv1_2; params->flags |= TLS_CONN_DISABLE_TLSv1_2;
if (os_strstr(txt, "tls_disable_tlsv1_2=0")) if (os_strstr(txt, "tls_disable_tlsv1_2=0")) {
params->flags &= ~TLS_CONN_DISABLE_TLSv1_2; params->flags &= ~TLS_CONN_DISABLE_TLSv1_2;
params->flags |= TLS_CONN_ENABLE_TLSv1_2;
}
if (os_strstr(txt, "tls_disable_tlsv1_3=1")) if (os_strstr(txt, "tls_disable_tlsv1_3=1"))
params->flags |= TLS_CONN_DISABLE_TLSv1_3; params->flags |= TLS_CONN_DISABLE_TLSv1_3;
if (os_strstr(txt, "tls_disable_tlsv1_3=0")) if (os_strstr(txt, "tls_disable_tlsv1_3=0"))

View file

@ -1240,12 +1240,19 @@ fast_reauth=1
# For EAP-FAST, this must be set to 0 (or left unconfigured for the # For EAP-FAST, this must be set to 0 (or left unconfigured for the
# default value to be used automatically). # default value to be used automatically).
# tls_disable_tlsv1_0=1 - disable use of TLSv1.0 # tls_disable_tlsv1_0=1 - disable use of TLSv1.0
# tls_disable_tlsv1_0=0 - explicitly enable use of TLSv1.0 (this allows
# systemwide TLS policies to be overridden)
# tls_disable_tlsv1_1=1 - disable use of TLSv1.1 (a workaround for AAA servers # tls_disable_tlsv1_1=1 - disable use of TLSv1.1 (a workaround for AAA servers
# that have issues interoperating with updated TLS version) # that have issues interoperating with updated TLS version)
# tls_disable_tlsv1_1=0 - explicitly enable use of TLSv1.1 (this allows
# systemwide TLS policies to be overridden)
# tls_disable_tlsv1_2=1 - disable use of TLSv1.2 (a workaround for AAA servers # tls_disable_tlsv1_2=1 - disable use of TLSv1.2 (a workaround for AAA servers
# that have issues interoperating with updated TLS version) # that have issues interoperating with updated TLS version)
# tls_disable_tlsv1_2=0 - explicitly enable use of TLSv1.2 (this allows
# systemwide TLS policies to be overridden)
# tls_disable_tlsv1_3=1 - disable use of TLSv1.3 (a workaround for AAA servers # tls_disable_tlsv1_3=1 - disable use of TLSv1.3 (a workaround for AAA servers
# that have issues interoperating with updated TLS version) # that have issues interoperating with updated TLS version)
# tls_disable_tlsv1_3=0 - enable TLSv1.3 (experimental - disabled by default)
# tls_ext_cert_check=0 - No external server certificate validation (default) # tls_ext_cert_check=0 - No external server certificate validation (default)
# tls_ext_cert_check=1 - External server certificate validation enabled; this # tls_ext_cert_check=1 - External server certificate validation enabled; this
# requires an external program doing validation of server certificate # requires an external program doing validation of server certificate