From: Nikos Mavrogiannopoulos Date: Tue, 18 Jul 2017 07:23:53 +0000 (+0200) Subject: handshake: always accept TLS 1.2 in client hello if we have later protocols enabled X-Git-Tag: gnutls_3_6_3~429 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=d48eebb53752dc3b7cbcdbc09f5ca3cab477e7a5;p=thirdparty%2Fgnutls.git handshake: always accept TLS 1.2 in client hello if we have later protocols enabled That is because after TLS 1.3 there is no negotiation of the version using the Client Hello field, but with an extension. Signed-off-by: Nikos Mavrogiannopoulos --- diff --git a/lib/handshake.c b/lib/handshake.c index 332349747a..36ecc11440 100644 --- a/lib/handshake.c +++ b/lib/handshake.c @@ -363,10 +363,21 @@ int _gnutls_negotiate_legacy_version(gnutls_session_t session, gnutls_protocol_t adv_version, uint8_t major, uint8_t minor) { - int ret; + const version_entry_st *vers; - /* if we do not support that version */ + /* if we do not support that version, unless that version is TLS 1.2; + * TLS 1.2 is handled separately because it is always advertized under TLS 1.3 or later */ if (adv_version == GNUTLS_VERSION_UNKNOWN || _gnutls_version_is_supported(session, adv_version) == 0) { + + if (adv_version == GNUTLS_TLS1_2) { + vers = _gnutls_version_max(session); + if (vers->id >= GNUTLS_TLS1_2) { + if (_gnutls_set_current_version(session, adv_version) < 0) + return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET); + return adv_version; + } + } + /* if we get an unknown/unsupported version, then fail if the version we * got is too low to be supported */ if (!_gnutls_version_is_too_high(session, major, minor)) @@ -375,21 +386,23 @@ _gnutls_negotiate_legacy_version(gnutls_session_t session, /* If he requested something we do not support * then we send him the highest we support. */ - ret = _gnutls_legacy_version_max(session); - if (ret == GNUTLS_VERSION_UNKNOWN) { + vers = _gnutls_legacy_version_max(session); + if (vers == NULL) { /* this check is not really needed. */ gnutls_assert(); return GNUTLS_E_UNKNOWN_CIPHER_SUITE; } - } else { - ret = adv_version; - } - if (_gnutls_set_current_version(session, ret) < 0) - return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET); + session->security_parameters.pversion = vers; - return ret; + return vers->id; + } else { + if (_gnutls_set_current_version(session, adv_version) < 0) + return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET); + + return adv_version; + } } /* This function returns: @@ -873,12 +886,14 @@ _gnutls_server_select_suite(gnutls_session_t session, uint8_t * data, /* TLS_FALLBACK_SCSV */ if (data[i] == GNUTLS_FALLBACK_SCSV_MAJOR && data[i + 1] == GNUTLS_FALLBACK_SCSV_MINOR) { - unsigned max = _gnutls_legacy_version_max(session); + const version_entry_st *vers = get_version(session); + const version_entry_st *max = _gnutls_version_max(session); + _gnutls_handshake_log ("HSK[%p]: Received fallback CS\n", session); - if (gnutls_protocol_get_version(session) != max) + if (vers != max) return gnutls_assert_val(GNUTLS_E_INAPPROPRIATE_FALLBACK); } else if (!scsv_only) { if (peer_clist.size < MAX_CIPHERSUITE_SIZE) { @@ -1646,9 +1661,7 @@ static int send_client_hello(gnutls_session_t session, int again) if (rehandshake) /* already negotiated version thus version_max == negotiated version */ hver = get_version(session); else /* new handshake. just get the max */ - hver = - version_to_entry(_gnutls_legacy_version_max - (session)); + hver = _gnutls_legacy_version_max(session); } else { /* we are resuming a session */ hver =