summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2017-12-10 15:26:28 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2017-12-10 15:26:31 +0100
commitff41f1d0a860685f2df0b12dd65ad4f9f2da36c0 (patch)
tree647b5557439f0809b2d60eb97a9e28076f580843
parentd35a3bd2969bfe138b002c4d7865f3a13cef16c1 (diff)
downloadgnutls-ff41f1d0a860685f2df0b12dd65ad4f9f2da36c0.tar.gz
handshake: check SCSVs prior to resuming a session
This ensures that extensions which are also available as SCSVs are parsed prior to resuming a session. This resolves an issue with openssl sending SCSV instead of an extension for the safe renegotiation. Resolves #259 Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
-rw-r--r--lib/gnutls_handshake.c16
-rw-r--r--lib/gnutls_handshake.h2
-rw-r--r--lib/gnutls_v2_compat.c2
3 files changed, 16 insertions, 4 deletions
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index dd773428be..cef29c35da 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -553,8 +553,13 @@ read_client_hello(gnutls_session_t session, uint8_t * data,
pos += 2;
DECR_LEN(len, suite_size);
+ suite_ptr = &data[pos];
pos += suite_size;
+ ret = _gnutls_server_select_suite(session, suite_ptr, suite_size, 1);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
DECR_LEN(len, 1);
comp_size = data[pos++]; /* z is the number of compression methods */
DECR_LEN(len, comp_size);
@@ -653,6 +658,10 @@ read_client_hello(gnutls_session_t session, uint8_t * data,
max_record_send_size =
session->security_parameters.max_record_send_size;
+ ret = _gnutls_server_select_suite(session, suite_ptr, suite_size, 1);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
ret = resume_copy_required_values(session);
if (ret < 0)
return gnutls_assert_val(ret);
@@ -662,7 +671,7 @@ read_client_hello(gnutls_session_t session, uint8_t * data,
/* select an appropriate cipher suite
*/
- ret = _gnutls_server_select_suite(session, suite_ptr, suite_size);
+ ret = _gnutls_server_select_suite(session, suite_ptr, suite_size, 0);
if (ret < 0) {
gnutls_assert();
return ret;
@@ -900,7 +909,7 @@ server_find_pk_algos_in_ciphersuites(const uint8_t *
*/
int
_gnutls_server_select_suite(gnutls_session_t session, uint8_t * data,
- unsigned int datalen)
+ unsigned int datalen, unsigned scsv_only)
{
int ret;
unsigned int i, j, cipher_suites_size;
@@ -935,6 +944,9 @@ _gnutls_server_select_suite(gnutls_session_t session, uint8_t * data,
}
}
+ if (scsv_only)
+ return 0;
+
pk_algos_size = MAX_ALGOS;
ret =
server_find_pk_algos_in_ciphersuites(data, datalen, pk_algos,
diff --git a/lib/gnutls_handshake.h b/lib/gnutls_handshake.h
index 88a4169b6d..ddb589ee1b 100644
--- a/lib/gnutls_handshake.h
+++ b/lib/gnutls_handshake.h
@@ -38,7 +38,7 @@ int _gnutls_set_client_random(gnutls_session_t session, uint8_t * rnd);
int _gnutls_find_pk_algos_in_ciphersuites(uint8_t * data, int datalen);
int _gnutls_server_select_suite(gnutls_session_t session, uint8_t * data,
- unsigned int datalen);
+ unsigned int datalen, unsigned scsv_only);
int _gnutls_negotiate_version(gnutls_session_t session,
gnutls_protocol_t adv_version);
diff --git a/lib/gnutls_v2_compat.c b/lib/gnutls_v2_compat.c
index 42fd3c5491..267aeabf01 100644
--- a/lib/gnutls_v2_compat.c
+++ b/lib/gnutls_v2_compat.c
@@ -74,7 +74,7 @@ _gnutls_handshake_select_v2_suite(gnutls_session_t session,
}
}
- ret = _gnutls_server_select_suite(session, _data, _datalen);
+ ret = _gnutls_server_select_suite(session, _data, _datalen, 0);
gnutls_free(_data);
return ret;