diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-09-06 15:17:40 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-09-06 15:17:40 +0200 |
commit | 26eabf3e9fc4e338009132359a13f470e67abf3b (patch) | |
tree | 82969ed4478c95745f61d25a1bc56c4ddfe80906 | |
parent | b3f589609d0c48274b6212a51f2bc73cc528f815 (diff) | |
download | gnutls-26eabf3e9fc4e338009132359a13f470e67abf3b.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@redhat.com>
-rw-r--r-- | lib/handshake.c | 23 | ||||
-rw-r--r-- | lib/handshake.h | 2 | ||||
-rw-r--r-- | lib/sslv2_compat.c | 2 |
3 files changed, 21 insertions, 6 deletions
diff --git a/lib/handshake.c b/lib/handshake.c index 638fcbdf03..bed26eee9b 100644 --- a/lib/handshake.c +++ b/lib/handshake.c @@ -583,6 +583,10 @@ read_client_hello(gnutls_session_t session, uint8_t * data, session->internals.resumption_requested = 1; if (ret == 0) { /* resumed using default TLS resumption! */ + 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); @@ -642,6 +646,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); @@ -651,7 +659,7 @@ read_client_hello(gnutls_session_t session, uint8_t * data, /* select an appropriate cipher suite (as well as certificate) */ - 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; @@ -902,10 +910,13 @@ server_find_pk_algos_in_ciphersuites(const uint8_t * /* This selects the best supported ciphersuite from the given ones. Then * it adds the suite to the session and performs some checks. + * + * When @scsv_only is non-zero only the available SCSVs are parsed + * and acted upon. */ 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; @@ -917,7 +928,9 @@ _gnutls_server_select_suite(gnutls_session_t session, uint8_t * data, */ for (i = 0; i < datalen; i += 2) { -#ifdef ENABLE_SSL3 /* No need to support certain SCSV's without SSL 3.0 */ + /* we support the TLS renegotiation SCSV, even if we are + * not under SSL 3.0, because openssl sends this SCSV + * on resumption unconditionally. */ /* TLS_RENEGO_PROTECTION_REQUEST = { 0x00, 0xff } */ if (session->internals.priorities.sr != SR_DISABLED && data[i] == GNUTLS_RENEGO_PROTECTION_REQUEST_MAJOR && @@ -931,7 +944,6 @@ _gnutls_server_select_suite(gnutls_session_t session, uint8_t * data, return retval; } } -#endif /* TLS_FALLBACK_SCSV */ if (data[i] == GNUTLS_FALLBACK_SCSV_MAJOR && @@ -946,6 +958,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/handshake.h b/lib/handshake.h index 3e24c2aeb2..7de7a5ac45 100644 --- a/lib/handshake.h +++ b/lib/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, uint8_t major, uint8_t minor); diff --git a/lib/sslv2_compat.c b/lib/sslv2_compat.c index f85fb8c163..ba1849ced0 100644 --- a/lib/sslv2_compat.c +++ b/lib/sslv2_compat.c @@ -75,7 +75,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; |