diff --git a/src/tls/tlsv1_client.c b/src/tls/tlsv1_client.c index a147a54a3..486da16fd 100644 --- a/src/tls/tlsv1_client.c +++ b/src/tls/tlsv1_client.c @@ -38,9 +38,33 @@ void tlsv1_client_free_dh(struct tlsv1_client *conn) } -int tls_derive_pre_master_secret(u8 *pre_master_secret) +u16 tls_client_highest_ver(struct tlsv1_client *conn) { - WPA_PUT_BE16(pre_master_secret, TLS_VERSION); + u16 tls_version = TLS_VERSION; + + /* Pick the highest locally enabled TLS version */ +#ifdef CONFIG_TLSV12 + if ((conn->flags & TLS_CONN_DISABLE_TLSv1_2) && + tls_version == TLS_VERSION_1_2) + tls_version = TLS_VERSION_1_1; +#endif /* CONFIG_TLSV12 */ +#ifdef CONFIG_TLSV11 + if ((conn->flags & TLS_CONN_DISABLE_TLSv1_1) && + tls_version == TLS_VERSION_1_1) + tls_version = TLS_VERSION_1; +#endif /* CONFIG_TLSV11 */ + if ((conn->flags & TLS_CONN_DISABLE_TLSv1_0) && + tls_version == TLS_VERSION_1) + return 0; + + return tls_version; +} + + +int tls_derive_pre_master_secret(struct tlsv1_client *conn, + u8 *pre_master_secret) +{ + WPA_PUT_BE16(pre_master_secret, tls_client_highest_ver(conn)); if (os_get_random(pre_master_secret + 2, TLS_PRE_MASTER_SECRET_LEN - 2)) return -1; @@ -844,6 +868,7 @@ int tlsv1_client_set_cred(struct tlsv1_client *conn, void tlsv1_client_set_flags(struct tlsv1_client *conn, unsigned int flags) { conn->flags = flags; + conn->rl.tls_version = tls_client_highest_ver(conn); } diff --git a/src/tls/tlsv1_client_i.h b/src/tls/tlsv1_client_i.h index 12ec8df6c..ccb2e1580 100644 --- a/src/tls/tlsv1_client_i.h +++ b/src/tls/tlsv1_client_i.h @@ -78,7 +78,9 @@ struct tlsv1_client { void tls_alert(struct tlsv1_client *conn, u8 level, u8 description); void tlsv1_client_free_dh(struct tlsv1_client *conn); -int tls_derive_pre_master_secret(u8 *pre_master_secret); +u16 tls_client_highest_ver(struct tlsv1_client *conn); +int tls_derive_pre_master_secret(struct tlsv1_client *conn, + u8 *pre_master_secret); int tls_derive_keys(struct tlsv1_client *conn, const u8 *pre_master_secret, size_t pre_master_secret_len); u8 * tls_send_client_hello(struct tlsv1_client *conn, size_t *out_len); diff --git a/src/tls/tlsv1_client_write.c b/src/tls/tlsv1_client_write.c index 4a1147b69..9b12618aa 100644 --- a/src/tls/tlsv1_client_write.c +++ b/src/tls/tlsv1_client_write.c @@ -48,21 +48,9 @@ u8 * tls_send_client_hello(struct tlsv1_client *conn, size_t *out_len) struct os_time now; size_t len, i; u8 *ext_start; - u16 tls_version = TLS_VERSION; + u16 tls_version = tls_client_highest_ver(conn); - /* Pick the highest locally enabled TLS version */ -#ifdef CONFIG_TLSV12 - if ((conn->flags & TLS_CONN_DISABLE_TLSv1_2) && - tls_version == TLS_VERSION_1_2) - tls_version = TLS_VERSION_1_1; -#endif /* CONFIG_TLSV12 */ -#ifdef CONFIG_TLSV11 - if ((conn->flags & TLS_CONN_DISABLE_TLSv1_1) && - tls_version == TLS_VERSION_1_1) - tls_version = TLS_VERSION_1; -#endif /* CONFIG_TLSV11 */ - if ((conn->flags & TLS_CONN_DISABLE_TLSv1_0) && - tls_version == TLS_VERSION_1) { + if (!tls_version) { wpa_printf(MSG_INFO, "TLSv1: No TLS version allowed"); return NULL; } @@ -474,7 +462,7 @@ static int tlsv1_key_x_rsa(struct tlsv1_client *conn, u8 **pos, u8 *end) size_t clen; int res; - if (tls_derive_pre_master_secret(pre_master_secret) < 0 || + if (tls_derive_pre_master_secret(conn, pre_master_secret) < 0 || tls_derive_keys(conn, pre_master_secret, TLS_PRE_MASTER_SECRET_LEN)) { wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");