summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2017-09-28 07:47:40 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-10-10 18:10:33 +0200
commitc3f6a3f82855fa5e55e21aca8c85d4a612ba89d7 (patch)
tree88ceb82ee035547811d59b145924aa51d7f885f9
parent6f0ea556b121cb849e44a59553655ee6975a42b7 (diff)
downloadgnutls-c3f6a3f82855fa5e55e21aca8c85d4a612ba89d7.tar.gz
handshake: only attempt to detect downgrade attacks if TLS1.3 is supported
Otherwise, connections under TLS 1.2 may fail, even if client never enabled TLS 1.3 support. Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
-rw-r--r--lib/handshake.c101
-rw-r--r--lib/handshake.h2
-rw-r--r--lib/sslv2_compat.c2
3 files changed, 57 insertions, 48 deletions
diff --git a/lib/handshake.c b/lib/handshake.c
index 7f249f845f..3e9da188d1 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -193,60 +193,69 @@ int _gnutls_set_client_random(gnutls_session_t session, uint8_t * rnd)
return 0;
}
+static
int _gnutls_set_server_random(gnutls_session_t session, int version, uint8_t * rnd)
{
+ memcpy(session->security_parameters.server_random, rnd,
+ GNUTLS_RANDOM_SIZE);
+
+ /* check whether the server random value is set according to
+ * to TLS 1.3. p4.1.3 requirements */
+ if (!IS_DTLS(session) && version <= GNUTLS_TLS1_2 &&
+ _gnutls_version_is_supported(session, GNUTLS_TLS1_3)) {
+ if (version == GNUTLS_TLS1_2 &&
+ memcmp(&session->security_parameters.server_random[GNUTLS_RANDOM_SIZE-8-1],
+ "\x44\x4F\x57\x4E\x47\x52\x44\x01", 8) == 0) {
+ _gnutls_audit_log(session,
+ "Detected downgrade to TLS 1.2 from TLS 1.3\n");
+ return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
+ } else if (version <= GNUTLS_TLS1_1 &&
+ memcmp(&session->security_parameters.server_random[GNUTLS_RANDOM_SIZE-8-1],
+ "\x44\x4F\x57\x4E\x47\x52\x44\x00", 8) == 0) {
+ _gnutls_audit_log(session,
+ "Detected downgrade to TLS 1.1 or earlier from TLS 1.3\n");
+ return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
+ }
+ }
+
+ return 0;
+}
+
+int _gnutls_gen_server_random(gnutls_session_t session, int version)
+{
int ret;
- if (rnd != NULL) { /* client */
- memcpy(session->security_parameters.server_random, rnd,
+ if (session->internals.sc_random_set != 0) {
+ memcpy(session->security_parameters.server_random,
+ session->internals.
+ resumed_security_parameters.server_random,
GNUTLS_RANDOM_SIZE);
+ return 0;
+ }
- /* check whether the server random value is set according to
- * to TLS 1.3. p4.1.3 requirements */
- if (version <= GNUTLS_TLS1_2 && _gnutls_version_is_supported(session, GNUTLS_TLS1_3)) {
- if (version == GNUTLS_TLS1_2 &&
- memcmp(&session->security_parameters.server_random[GNUTLS_RANDOM_SIZE-8-1],
- "\x44\x4F\x57\x4E\x47\x52\x44\x01", 8) == 0) {
- _gnutls_audit_log(session,
- "Detected downgrade to TLS 1.2 from TLS 1.3\n");
- return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
- } else if (version <= GNUTLS_TLS1_1 &&
- memcmp(&session->security_parameters.server_random[GNUTLS_RANDOM_SIZE-8-1],
- "\x44\x4F\x57\x4E\x47\x52\x44\x00", 8) == 0) {
- _gnutls_audit_log(session,
- "Detected downgrade to TLS 1.1 or earlier from TLS 1.3\n");
- return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
- }
- }
-
- } else { /* server */
- if (session->internals.sc_random_set != 0) {
- memcpy(session->security_parameters.server_random,
- session->internals.
- resumed_security_parameters.server_random,
- GNUTLS_RANDOM_SIZE);
+ if (!IS_DTLS(session) && _gnutls_version_is_supported(session, GNUTLS_TLS1_3) &&
+ version <= GNUTLS_TLS1_2) {
+ if (version == GNUTLS_TLS1_2) {
+ memcpy(&session->security_parameters.server_random[GNUTLS_RANDOM_SIZE-8-1],
+ "\x44\x4F\x57\x4E\x47\x52\x44\x01", 8);
+ ret =
+ gnutls_rnd(GNUTLS_RND_NONCE, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE-8);
} else {
- if (version == GNUTLS_TLS1_2) {
- memcpy(&session->security_parameters.server_random[GNUTLS_RANDOM_SIZE-8-1],
- "\x44\x4F\x57\x4E\x47\x52\x44\x01", 8);
- ret =
- gnutls_rnd(GNUTLS_RND_NONCE, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE-8);
- } else if (version <= GNUTLS_TLS1_1) {
- memcpy(&session->security_parameters.server_random[GNUTLS_RANDOM_SIZE-8-1],
- "\x44\x4F\x57\x4E\x47\x52\x44\x00", 8);
- ret =
- gnutls_rnd(GNUTLS_RND_NONCE, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE-8);
- } else {
- ret =
- gnutls_rnd(GNUTLS_RND_NONCE, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE);
- }
-
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
+ memcpy(&session->security_parameters.server_random[GNUTLS_RANDOM_SIZE-8-1],
+ "\x44\x4F\x57\x4E\x47\x52\x44\x00", 8);
+ ret =
+ gnutls_rnd(GNUTLS_RND_NONCE, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE-8);
}
+ } else {
+ ret =
+ gnutls_rnd(GNUTLS_RND_NONCE, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE);
+ }
+
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
}
+
return 0;
}
@@ -487,7 +496,7 @@ read_client_hello(gnutls_session_t session, uint8_t * data,
pos += GNUTLS_RANDOM_SIZE;
- ret = _gnutls_set_server_random(session, neg_version, NULL);
+ ret = _gnutls_gen_server_random(session, neg_version);
if (ret < 0)
return gnutls_assert_val(ret);
diff --git a/lib/handshake.h b/lib/handshake.h
index 0e63ee39b4..b491ba1e51 100644
--- a/lib/handshake.h
+++ b/lib/handshake.h
@@ -61,7 +61,7 @@ int _gnutls_recv_handshake(gnutls_session_t session,
gnutls_handshake_description_t type,
unsigned int optional, gnutls_buffer_st * buf);
int _gnutls_generate_session_id(uint8_t * session_id, uint8_t * len);
-int _gnutls_set_server_random(gnutls_session_t session, int version, uint8_t * rnd);
+int _gnutls_gen_server_random(gnutls_session_t session, int version);
int _gnutls_set_client_random(gnutls_session_t session, uint8_t * rnd);
int _gnutls_find_pk_algos_in_ciphersuites(uint8_t * data, int datalen);
diff --git a/lib/sslv2_compat.c b/lib/sslv2_compat.c
index f8eff3b151..43890f3c94 100644
--- a/lib/sslv2_compat.c
+++ b/lib/sslv2_compat.c
@@ -213,7 +213,7 @@ _gnutls_read_client_hello_v2(gnutls_session_t session, uint8_t * data,
return gnutls_assert_val(ret);
/* generate server random value */
- ret = _gnutls_set_server_random(session, neg_version, NULL);
+ ret = _gnutls_gen_server_random(session, neg_version);
if (ret < 0)
return gnutls_assert_val(ret);