summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-10-04 10:33:11 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-11-14 16:37:16 +0100
commit2f228975554a138e27fbc9a26e33c143d85c8047 (patch)
tree22044c311b49a0129006672736145445148ae2ab
parentd2fdfb991efaf4f43ad0d02f9b1f4dc24eb3f6e6 (diff)
downloadgnutls-2f228975554a138e27fbc9a26e33c143d85c8047.tar.gz
_gnutls_set_server_random: corrected TLS1.2 and TLS1.1 rollback detection
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--lib/handshake.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/lib/handshake.c b/lib/handshake.c
index 22b984050b..cdc9558c8e 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -235,24 +235,32 @@ int _gnutls_gen_client_random(gnutls_session_t session)
}
static
-int _gnutls_set_server_random(gnutls_session_t session, int version, uint8_t * rnd)
+int _gnutls_set_server_random(gnutls_session_t session, const version_entry_st *vers, uint8_t * rnd)
{
+ const version_entry_st *max;
+
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],
+ if (!IS_DTLS(session) && vers->id <= GNUTLS_TLS1_2) {
+
+ max = _gnutls_version_max(session);
+ if (max->id <= GNUTLS_TLS1_2)
+ return 0;
+
+ if (vers->id == GNUTLS_TLS1_2 &&
+ memcmp(&session->security_parameters.server_random[GNUTLS_RANDOM_SIZE-8],
"\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],
+ } else if (vers->id <= GNUTLS_TLS1_1 &&
+ memcmp(&session->security_parameters.server_random[GNUTLS_RANDOM_SIZE-8],
"\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);
@@ -265,6 +273,7 @@ int _gnutls_set_server_random(gnutls_session_t session, int version, uint8_t * r
int _gnutls_gen_server_random(gnutls_session_t session, int version)
{
int ret;
+ const version_entry_st *max;
if (session->internals.sc_random_set != 0) {
memcpy(session->security_parameters.server_random,
@@ -274,19 +283,20 @@ int _gnutls_gen_server_random(gnutls_session_t session, int version)
return 0;
}
- if (!IS_DTLS(session) && _gnutls_version_is_supported(session, GNUTLS_TLS1_3) &&
+ max = _gnutls_version_max(session);
+
+ if (!IS_DTLS(session) && max->id >= GNUTLS_TLS1_3 &&
version <= GNUTLS_TLS1_2) {
if (version == GNUTLS_TLS1_2) {
- memcpy(&session->security_parameters.server_random[GNUTLS_RANDOM_SIZE-8-1],
+ memcpy(&session->security_parameters.server_random[GNUTLS_RANDOM_SIZE-8],
"\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 {
- memcpy(&session->security_parameters.server_random[GNUTLS_RANDOM_SIZE-8-1],
+ memcpy(&session->security_parameters.server_random[GNUTLS_RANDOM_SIZE-8],
"\x44\x4F\x57\x4E\x47\x52\x44\x00", 8);
- ret =
- gnutls_rnd(GNUTLS_RND_NONCE, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE-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);
@@ -1629,7 +1639,7 @@ read_server_hello(gnutls_session_t session,
pos += 2;
DECR_LEN(len, GNUTLS_RANDOM_SIZE);
- ret = _gnutls_set_server_random(session, vers->id, &data[pos]);
+ ret = _gnutls_set_server_random(session, vers, &data[pos]);
if (ret < 0)
return gnutls_assert_val(ret);