From f261e651fffcdcd8c74128c7c6622170d4593553 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Mon, 13 Aug 2018 20:46:21 +0200 Subject: protocols: bumped TLS1.3 version number to RFC8446 value This adds support of the final RFC numbers. Resolves #542 Signed-off-by: Nikos Mavrogiannopoulos --- NEWS | 2 ++ devel/openssl | 2 +- lib/algorithms/protocols.c | 22 ---------------------- tests/tls13/prf.c | 8 ++++---- tests/tls13/supported_versions.c | 4 ---- 5 files changed, 7 insertions(+), 31 deletions(-) diff --git a/NEWS b/NEWS index 57d2703903..96fac0299d 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ See the end for copying conditions. * Version 3.6.4 (unreleased) +** libgnutls: Added the final (RFC8446) version numbering of the TLS1.3 protocol. + ** libgnutls: Corrected regression since 3.6.3 in the callbacks set with gnutls_certificate_set_retrieve_function() which could not handle the case where no certificates were returned, or the callbacks were set to NULL (see #528). diff --git a/devel/openssl b/devel/openssl index 09fb65d5e4..2805ee1e09 160000 --- a/devel/openssl +++ b/devel/openssl @@ -1 +1 @@ -Subproject commit 09fb65d5e413b7b87bf26f01ec441b44a03d4ee2 +Subproject commit 2805ee1e095a78f596dc7adf778441e2edb9f15c diff --git a/lib/algorithms/protocols.c b/lib/algorithms/protocols.c index e1093a9ced..12907190df 100644 --- a/lib/algorithms/protocols.c +++ b/lib/algorithms/protocols.c @@ -93,7 +93,6 @@ static const version_entry_st sup_versions[] = { .tls_sig_sem = SIG_SEM_PRE_TLS12, .false_start = 1 }, -#ifdef TLS13_FINAL_VERSION {.name = "TLS1.3", .id = GNUTLS_TLS1_3, .age = 5, @@ -113,27 +112,6 @@ static const version_entry_st sup_versions[] = { .false_start = 0, /* doesn't make sense */ .tls_sig_sem = SIG_SEM_TLS13 }, -#else - {.name = "TLS1.3", - .id = GNUTLS_TLS1_3, - .age = 5, - .major = 0x7f, - .minor = 28, - .transport = GNUTLS_STREAM, - .supported = 1, - .explicit_iv = 0, - .extensions = 1, - .selectable_sighash = 1, - .selectable_prf = 1, - .tls13_sem = 1, - .obsolete = 0, - .only_extension = 1, - .post_handshake_auth = 1, - .key_shares = 1, - .false_start = 0, /* doesn't make sense */ - .tls_sig_sem = SIG_SEM_TLS13 - }, -#endif {.name = "DTLS0.9", /* Cisco AnyConnect (based on about OpenSSL 0.9.8e) */ .id = GNUTLS_DTLS0_9, .age = 200, diff --git a/tests/tls13/prf.c b/tests/tls13/prf.c index dc34973e8f..eb2d0e6096 100644 --- a/tests/tls13/prf.c +++ b/tests/tls13/prf.c @@ -126,10 +126,10 @@ static void dump(const char *name, const uint8_t *data, unsigned data_size) } \ } -#define KEY_EXP_VALUE "\x42\xba\x1d\x14\x6d\x09\x4f\x64\x7a\x65\xc0\x39\xf8\xd6\x98\xa7\x71\xcd\xb5\xd1\x8d\xf7\x70\xca\x22\x2d\xad\x3f\xac\x47\xe9\x13\xfa\xd0" -#define HELLO_VALUE "\x0a\xc9\xa4\x5b\xf8\x19\x07\x1c\x56\x61\x7f\xcf\x71\x8b\xff\x0d\xc3\x74\xd7\xf3\x12\xd8\xde\xa8\x33\xcb\x3d\xf3\xc2\x78\x51" -#define CONTEXT_VALUE "\x7c\x89\xaf\x6f\x98\xbd\xa4\xc4\xad\x10\x54\xc2\x6d\x87\xb3\x94\x02\x62\x2f\x1f\x64\x82\x10\x30\xb6\x49\x08\x2f\x0d\x82\xc1" -#define NULL_CONTEXT_VALUE "\xa6\xf4\x67\x86\x16\x06\xd0\x53\xcf\x19\xc7\x26\xa4\x94\xc4\x78\xea\xeb\x51\x8e\x04\x0b\x53\xaf\x9f\xde\x0b\xe8\xc3\x08\x04" +#define KEY_EXP_VALUE "\xfb\xcb\x96\x87\x8c\x64\x8b\x60\xef\xdc\x76\xb0\x7c\x3b\xd1\x50\x1e\xb1\x3f\x39\xb2\x20\x74\x2c\xb2\x76\x12\x9f\xfc\xad\xb9\xce\x1d\x9a" +#define HELLO_VALUE "\x61\x32\x14\x81\x9b\xa0\x43\xcd\x39\xbf\x63\x18\x7c\xb7\xf3\x02\x65\xab\x2c\xa4\xaf\xbc\x1c\x7a\x1d\xa4\xc5\x28\x8f\x45\x68" +#define CONTEXT_VALUE "\xa7\x3c\xa7\x59\x94\x33\xb4\x97\x90\x92\x8c\xe2\x39\xda\x56\x42\x4a\xeb\xeb\xab\x73\xc4\x20\xf0\x34\x4f\xda\xf8\x17\xf5\xbd" +#define NULL_CONTEXT_VALUE "\x66\xa1\x0a\xcb\xfa\x28\x85\x79\xa3\x30\xeb\xc5\xd5\x50\x62\xdd\xb4\x9c\xa7\x0b\x0b\xe0\x28\x03\x18\xfb\x32\x3d\x37\xf2\xe5" static void check_prfs(gnutls_session_t session) { unsigned char key_material[512]; diff --git a/tests/tls13/supported_versions.c b/tests/tls13/supported_versions.c index 49ba87212a..dbcc33d903 100644 --- a/tests/tls13/supported_versions.c +++ b/tests/tls13/supported_versions.c @@ -221,11 +221,7 @@ static int client_hello_callback(gnutls_session_t session, unsigned int htype, (int)msg->data[pos+2], (int)msg->data[pos+3], (int)msg->data[pos+4], (int)msg->data[pos+5]); -#ifdef TLS13_FINAL_VERSION if (msg->data[pos] != 0x03 || msg->data[pos+1] != 0x04) { -#else - if (msg->data[pos] != 0x7f || msg->data[pos+1] != 28) { -#endif fail("fail expected TLS 1.3, got %d.%d\n", (int)msg->data[pos], (int)msg->data[pos+1]); } pos+=2; -- cgit v1.2.1 From 40658915b205242b5870eb8397b7c7bc144ef5c9 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Mon, 13 Aug 2018 20:55:50 +0200 Subject: fuzz: updated traces for final TLS1.3 version Resolves #359 Signed-off-by: Nikos Mavrogiannopoulos --- .../4dafd0c57c8243a0faafc6da88e2d2be06bf3076 | Bin 0 -> 1815 bytes .../04765d237fc65da80b71ab4673725cb08930690e | Bin 0 -> 1542 bytes .../32ba496e9b29dbf1b18e4eb49fce1683f9bb233d | Bin 0 -> 698 bytes .../58abfe6c2b0b3ef8ff98223e782f65029b60e90e | Bin 0 -> 491 bytes .../5c58c38748fbe10ebc0218cc51f7288f747c54d3 | Bin 0 -> 669 bytes .../55458788a58053e365d9e42a07cdef29c45d9e63 | Bin 0 -> 427 bytes 6 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 fuzz/gnutls_client_fuzzer.in/4dafd0c57c8243a0faafc6da88e2d2be06bf3076 create mode 100644 fuzz/gnutls_psk_client_fuzzer.in/04765d237fc65da80b71ab4673725cb08930690e create mode 100644 fuzz/gnutls_psk_client_fuzzer.in/32ba496e9b29dbf1b18e4eb49fce1683f9bb233d create mode 100644 fuzz/gnutls_psk_server_fuzzer.in/58abfe6c2b0b3ef8ff98223e782f65029b60e90e create mode 100644 fuzz/gnutls_psk_server_fuzzer.in/5c58c38748fbe10ebc0218cc51f7288f747c54d3 create mode 100644 fuzz/gnutls_server_fuzzer.in/55458788a58053e365d9e42a07cdef29c45d9e63 diff --git a/fuzz/gnutls_client_fuzzer.in/4dafd0c57c8243a0faafc6da88e2d2be06bf3076 b/fuzz/gnutls_client_fuzzer.in/4dafd0c57c8243a0faafc6da88e2d2be06bf3076 new file mode 100644 index 0000000000..c9917159be Binary files /dev/null and b/fuzz/gnutls_client_fuzzer.in/4dafd0c57c8243a0faafc6da88e2d2be06bf3076 differ diff --git a/fuzz/gnutls_psk_client_fuzzer.in/04765d237fc65da80b71ab4673725cb08930690e b/fuzz/gnutls_psk_client_fuzzer.in/04765d237fc65da80b71ab4673725cb08930690e new file mode 100644 index 0000000000..690578ce4c Binary files /dev/null and b/fuzz/gnutls_psk_client_fuzzer.in/04765d237fc65da80b71ab4673725cb08930690e differ diff --git a/fuzz/gnutls_psk_client_fuzzer.in/32ba496e9b29dbf1b18e4eb49fce1683f9bb233d b/fuzz/gnutls_psk_client_fuzzer.in/32ba496e9b29dbf1b18e4eb49fce1683f9bb233d new file mode 100644 index 0000000000..fe8c6febd0 Binary files /dev/null and b/fuzz/gnutls_psk_client_fuzzer.in/32ba496e9b29dbf1b18e4eb49fce1683f9bb233d differ diff --git a/fuzz/gnutls_psk_server_fuzzer.in/58abfe6c2b0b3ef8ff98223e782f65029b60e90e b/fuzz/gnutls_psk_server_fuzzer.in/58abfe6c2b0b3ef8ff98223e782f65029b60e90e new file mode 100644 index 0000000000..48366abdf0 Binary files /dev/null and b/fuzz/gnutls_psk_server_fuzzer.in/58abfe6c2b0b3ef8ff98223e782f65029b60e90e differ diff --git a/fuzz/gnutls_psk_server_fuzzer.in/5c58c38748fbe10ebc0218cc51f7288f747c54d3 b/fuzz/gnutls_psk_server_fuzzer.in/5c58c38748fbe10ebc0218cc51f7288f747c54d3 new file mode 100644 index 0000000000..7113ffbaaa Binary files /dev/null and b/fuzz/gnutls_psk_server_fuzzer.in/5c58c38748fbe10ebc0218cc51f7288f747c54d3 differ diff --git a/fuzz/gnutls_server_fuzzer.in/55458788a58053e365d9e42a07cdef29c45d9e63 b/fuzz/gnutls_server_fuzzer.in/55458788a58053e365d9e42a07cdef29c45d9e63 new file mode 100644 index 0000000000..8ff3485ce9 Binary files /dev/null and b/fuzz/gnutls_server_fuzzer.in/55458788a58053e365d9e42a07cdef29c45d9e63 differ -- cgit v1.2.1 From f887495609e16ba250595a2e5e0afd2fb008a0c3 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Fri, 17 Aug 2018 10:50:15 +0200 Subject: tlsfuzzer: modify to use the final code points Relates #542 Signed-off-by: Nikos Mavrogiannopoulos --- tests/suite/tls-fuzzer/tls-fuzzer-nocert-tls13.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/suite/tls-fuzzer/tls-fuzzer-nocert-tls13.sh b/tests/suite/tls-fuzzer/tls-fuzzer-nocert-tls13.sh index 3a46cdb735..f5d94dd692 100755 --- a/tests/suite/tls-fuzzer/tls-fuzzer-nocert-tls13.sh +++ b/tests/suite/tls-fuzzer/tls-fuzzer-nocert-tls13.sh @@ -52,6 +52,8 @@ TLS_PY=./tlslite-ng/scripts/tls.py sed -e "s|@SERVER@|$SERV|g" -e "s/@PORT@/$PORT/g" -e "s/@PRIORITY@/$PRIORITY/g" ../gnutls-nocert-tls13.json >${TMPFILE} +sed -i 's/(127, 28)/(3, 4)/g' ./tlslite/constants.py + PYTHONPATH=. python tests/scripts_retention.py ${TMPFILE} ${SERV} retval=$? -- cgit v1.2.1 From 96863e08a4d0b3fbccaa68c7d5fd21fa269222ef Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Fri, 17 Aug 2018 12:57:25 +0200 Subject: handshake: simplified protocol version checking functions Signed-off-by: Nikos Mavrogiannopoulos --- lib/algorithms.h | 4 ++-- lib/algorithms/protocols.c | 16 +++++++++------- lib/ext/supported_versions.c | 12 +++--------- lib/handshake.c | 45 +++++++++++++++++++++----------------------- lib/handshake.h | 4 ++-- lib/sslv2_compat.c | 7 ++----- 6 files changed, 39 insertions(+), 49 deletions(-) diff --git a/lib/algorithms.h b/lib/algorithms.h index cff79348cb..46faa8d378 100644 --- a/lib/algorithms.h +++ b/lib/algorithms.h @@ -59,8 +59,8 @@ const version_entry_st *_gnutls_legacy_version_max(gnutls_session_t session); const version_entry_st *_gnutls_version_max(gnutls_session_t session); int _gnutls_version_priority(gnutls_session_t session, gnutls_protocol_t version); -int _gnutls_version_is_supported(gnutls_session_t session, - const gnutls_protocol_t version); +int _gnutls_nversion_is_supported(gnutls_session_t session, + unsigned char major, unsigned char minor); gnutls_protocol_t _gnutls_version_get(uint8_t major, uint8_t minor); unsigned _gnutls_version_is_too_high(gnutls_session_t session, uint8_t major, uint8_t minor); diff --git a/lib/algorithms/protocols.c b/lib/algorithms/protocols.c index 12907190df..f2277a9e28 100644 --- a/lib/algorithms/protocols.c +++ b/lib/algorithms/protocols.c @@ -463,26 +463,29 @@ gnutls_protocol_t _gnutls_version_get(uint8_t major, uint8_t minor) /* Version Functions */ int -_gnutls_version_is_supported(gnutls_session_t session, - const gnutls_protocol_t version) +_gnutls_nversion_is_supported(gnutls_session_t session, + unsigned char major, unsigned char minor) { const version_entry_st *p; - int ret = 0; + int version = 0; for (p = sup_versions; p->name != NULL; p++) { - if(p->id == version) { + if(p->major == major && p->minor == minor) { #ifndef ENABLE_SSL3 if (p->obsolete != 0) return 0; #endif if (p->tls13_sem && (session->internals.flags & INT_FLAG_NO_TLS13)) return 0; - ret = p->supported && p->transport == session->internals.transport; + if (!p->supported || p->transport != session->internals.transport) + return 0; + + version = p->id; break; } } - if (ret == 0) + if (version == 0) return 0; if (_gnutls_version_priority(session, version) < 0) @@ -490,4 +493,3 @@ _gnutls_version_is_supported(gnutls_session_t session, else return 1; } - diff --git a/lib/ext/supported_versions.c b/lib/ext/supported_versions.c index b637ec6637..3a11b39bd4 100644 --- a/lib/ext/supported_versions.c +++ b/lib/ext/supported_versions.c @@ -59,7 +59,6 @@ supported_versions_recv_params(gnutls_session_t session, const version_entry_st *vers; ssize_t data_size = _data_size; uint8_t major, minor; - gnutls_protocol_t proto; ssize_t bytes; int ret; @@ -90,15 +89,11 @@ supported_versions_recv_params(gnutls_session_t session, data += 2; bytes -= 2; - proto = _gnutls_version_get(major, minor); - _gnutls_handshake_log("EXT[%p]: Found version: %d.%d\n", session, (int)major, (int)minor); - if (_gnutls_version_is_supported(session, proto)) { - ret = _gnutls_set_current_version(session, proto); - if (ret < 0) - return gnutls_assert_val(ret); + if (_gnutls_nversion_is_supported(session, major, minor)) { + session->security_parameters.pversion = nversion_to_entry(major, minor); _gnutls_handshake_log("EXT[%p]: Negotiated version: %d.%d\n", session, (int)major, (int)minor); @@ -131,7 +126,6 @@ supported_versions_recv_params(gnutls_session_t session, return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET); set_adv_version(session, major, minor); - proto = _gnutls_version_get(major, minor); _gnutls_handshake_log("EXT[%p]: Negotiated version: %d.%d\n", session, (int)major, (int)minor); @@ -139,7 +133,7 @@ supported_versions_recv_params(gnutls_session_t session, if (!vers->tls13_sem) return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); - ret = _gnutls_negotiate_version(session, proto, major, minor); + ret = _gnutls_negotiate_version(session, major, minor); if (ret < 0) { gnutls_assert(); return ret; diff --git a/lib/handshake.c b/lib/handshake.c index 914f8ecacc..ccf8299165 100644 --- a/lib/handshake.c +++ b/lib/handshake.c @@ -431,21 +431,21 @@ _gnutls_finished(gnutls_session_t session, int type, void *ret, */ int _gnutls_negotiate_version(gnutls_session_t session, - gnutls_protocol_t adv_version, uint8_t major, uint8_t minor) + uint8_t major, uint8_t minor) { const version_entry_st *vers; + const version_entry_st *aversion = nversion_to_entry(major, minor); /* 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 (aversion == NULL || + _gnutls_nversion_is_supported(session, major, minor) == 0) { - if (adv_version == GNUTLS_TLS1_2) { + if (aversion && aversion->id == 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; + session->security_parameters.pversion = aversion; + return 0; } } @@ -467,12 +467,11 @@ _gnutls_negotiate_version(gnutls_session_t session, session->security_parameters.pversion = vers; - return vers->id; + return 0; } else { - if (_gnutls_set_current_version(session, adv_version) < 0) - return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET); + session->security_parameters.pversion = aversion; - return adv_version; + return 0; } } @@ -483,7 +482,7 @@ _gnutls_negotiate_version(gnutls_session_t session, */ int _gnutls_user_hello_func(gnutls_session_t session, - gnutls_protocol_t adv_version, uint8_t major, uint8_t minor) + uint8_t major, uint8_t minor) { int ret, sret = 0; const version_entry_st *vers; @@ -506,7 +505,7 @@ _gnutls_user_hello_func(gnutls_session_t session, * earlier, as TLS1.3 uses a different set of ciphersuites, and * thus we cannot fallback. */ - ret = _gnutls_negotiate_version(session, adv_version, major, minor); + ret = _gnutls_negotiate_version(session, major, minor); if (ret < 0) { gnutls_assert(); return ret; @@ -551,7 +550,6 @@ read_client_hello(gnutls_session_t session, uint8_t * data, int pos = 0, ret; uint16_t suite_size, comp_size; int ext_size; - gnutls_protocol_t adv_version; int neg_version, sret = 0; int len = datalen; uint8_t major, minor; @@ -562,17 +560,16 @@ read_client_hello(gnutls_session_t session, uint8_t * data, _gnutls_handshake_log("HSK[%p]: Client's version: %d.%d\n", session, data[pos], data[pos + 1]); - adv_version = _gnutls_version_get(data[pos], data[pos + 1]); - major = data[pos]; minor = data[pos+1]; + set_adv_version(session, major, minor); - neg_version = _gnutls_negotiate_version(session, adv_version, major, minor); - if (neg_version < 0) { - gnutls_assert(); - return neg_version; - } + ret = _gnutls_negotiate_version(session, major, minor); + if (ret < 0) + return gnutls_assert_val(ret); + + neg_version = get_num_version(session); pos += 2; @@ -677,7 +674,7 @@ read_client_hello(gnutls_session_t session, uint8_t * data, session->internals.resumed = RESUME_TRUE; - return _gnutls_user_hello_func(session, adv_version, major, minor); + return _gnutls_user_hello_func(session, major, minor); } else { ret = _gnutls_generate_session_id(session->security_parameters. session_id, @@ -711,7 +708,7 @@ read_client_hello(gnutls_session_t session, uint8_t * data, } /* we cache this error code */ - sret = _gnutls_user_hello_func(session, adv_version, major, minor); + sret = _gnutls_user_hello_func(session, major, minor); if (sret < 0 && sret != GNUTLS_E_INT_RET_0) { gnutls_assert(); return sret; @@ -1824,7 +1821,7 @@ read_server_hello(gnutls_session_t session, return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET); } - if (_gnutls_version_is_supported(session, vers->id) == 0) + if (_gnutls_nversion_is_supported(session, vers->major, vers->minor) == 0) return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET); /* set server random - done after final version is selected */ diff --git a/lib/handshake.h b/lib/handshake.h index e32de894f2..0d617213c5 100644 --- a/lib/handshake.h +++ b/lib/handshake.h @@ -94,9 +94,9 @@ int _gnutls_server_select_suite(gnutls_session_t session, uint8_t * data, unsigned int datalen, unsigned int scsv_only); int _gnutls_negotiate_version(gnutls_session_t session, - gnutls_protocol_t adv_version, uint8_t major, uint8_t minor); + uint8_t major, uint8_t minor); int _gnutls_user_hello_func(gnutls_session_t session, - gnutls_protocol_t adv_version, uint8_t major, uint8_t minor); + uint8_t major, uint8_t minor); void _gnutls_handshake_hash_buffers_clear(gnutls_session_t session); diff --git a/lib/sslv2_compat.c b/lib/sslv2_compat.c index d466cc30f1..de762a5674 100644 --- a/lib/sslv2_compat.c +++ b/lib/sslv2_compat.c @@ -93,7 +93,6 @@ _gnutls_read_client_hello_v2(gnutls_session_t session, uint8_t * data, int pos = 0; int ret = 0, sret = 0; uint16_t sizeOfSuites; - gnutls_protocol_t adv_version; uint8_t rnd[GNUTLS_RANDOM_SIZE], major, minor; int len = datalen; int neg_version; @@ -110,9 +109,7 @@ _gnutls_read_client_hello_v2(gnutls_session_t session, uint8_t * data, minor = data[pos + 1]; set_adv_version(session, major, minor); - adv_version = _gnutls_version_get(major, minor); - - ret = _gnutls_negotiate_version(session, adv_version, major, minor); + ret = _gnutls_negotiate_version(session, major, minor); if (ret < 0) { gnutls_assert(); return ret; @@ -148,7 +145,7 @@ _gnutls_read_client_hello_v2(gnutls_session_t session, uint8_t * data, /* call the user hello callback */ - ret = _gnutls_user_hello_func(session, adv_version, major, minor); + ret = _gnutls_user_hello_func(session, major, minor); if (ret < 0) { if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) { sret = GNUTLS_E_INT_RET_0; -- cgit v1.2.1 From 087cc4b95e5edd7a448dedd506eb8e7ffad95962 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Fri, 17 Aug 2018 14:02:34 +0200 Subject: handshake: do not negotiate TLS1.3 using the legacy version field Previously we could end-up with a TLS1.3 connection if the TLS1.3 ID was seen on the wire. We now explicitly fallback to TLS1.2 when we see a protocol with TLS1.3 semantics in an SSL2.0 or in the legacy version of the client hello. Signed-off-by: Nikos Mavrogiannopoulos --- lib/ext/supported_versions.c | 2 +- lib/handshake.c | 18 ++++++++++++++---- lib/handshake.h | 3 ++- lib/sslv2_compat.c | 10 ++++++++-- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/lib/ext/supported_versions.c b/lib/ext/supported_versions.c index 3a11b39bd4..b7fe31f75b 100644 --- a/lib/ext/supported_versions.c +++ b/lib/ext/supported_versions.c @@ -133,7 +133,7 @@ supported_versions_recv_params(gnutls_session_t session, if (!vers->tls13_sem) return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); - ret = _gnutls_negotiate_version(session, major, minor); + ret = _gnutls_negotiate_version(session, major, minor, 1); if (ret < 0) { gnutls_assert(); return ret; diff --git a/lib/handshake.c b/lib/handshake.c index ccf8299165..08481cca07 100644 --- a/lib/handshake.c +++ b/lib/handshake.c @@ -431,7 +431,7 @@ _gnutls_finished(gnutls_session_t session, int type, void *ret, */ int _gnutls_negotiate_version(gnutls_session_t session, - uint8_t major, uint8_t minor) + uint8_t major, uint8_t minor, unsigned allow_tls13) { const version_entry_st *vers; const version_entry_st *aversion = nversion_to_entry(major, minor); @@ -471,6 +471,12 @@ _gnutls_negotiate_version(gnutls_session_t session, } else { session->security_parameters.pversion = aversion; + /* we do not allow TLS1.3 negotiation using this mechanism */ + if (aversion->tls13_sem && !allow_tls13) { + vers = _gnutls_legacy_version_max(session); + session->security_parameters.pversion = vers; + } + return 0; } } @@ -505,7 +511,7 @@ _gnutls_user_hello_func(gnutls_session_t session, * earlier, as TLS1.3 uses a different set of ciphersuites, and * thus we cannot fallback. */ - ret = _gnutls_negotiate_version(session, major, minor); + ret = _gnutls_negotiate_version(session, major, minor, 0); if (ret < 0) { gnutls_assert(); return ret; @@ -565,11 +571,15 @@ read_client_hello(gnutls_session_t session, uint8_t * data, set_adv_version(session, major, minor); - ret = _gnutls_negotiate_version(session, major, minor); + ret = _gnutls_negotiate_version(session, major, minor, 0); if (ret < 0) return gnutls_assert_val(ret); - neg_version = get_num_version(session); + vers = get_version(session); + if (vers == NULL) + return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET); + + neg_version = vers->id; pos += 2; diff --git a/lib/handshake.h b/lib/handshake.h index 0d617213c5..184a349a91 100644 --- a/lib/handshake.h +++ b/lib/handshake.h @@ -94,7 +94,8 @@ int _gnutls_server_select_suite(gnutls_session_t session, uint8_t * data, unsigned int datalen, unsigned int scsv_only); int _gnutls_negotiate_version(gnutls_session_t session, - uint8_t major, uint8_t minor); + uint8_t major, uint8_t minor, + unsigned allow_tls13); int _gnutls_user_hello_func(gnutls_session_t session, uint8_t major, uint8_t minor); diff --git a/lib/sslv2_compat.c b/lib/sslv2_compat.c index de762a5674..9d8fd91bf4 100644 --- a/lib/sslv2_compat.c +++ b/lib/sslv2_compat.c @@ -96,6 +96,7 @@ _gnutls_read_client_hello_v2(gnutls_session_t session, uint8_t * data, uint8_t rnd[GNUTLS_RANDOM_SIZE], major, minor; int len = datalen; int neg_version; + const version_entry_st *vers; uint16_t challenge; uint8_t session_id[GNUTLS_MAX_SESSION_ID_SIZE]; @@ -109,12 +110,17 @@ _gnutls_read_client_hello_v2(gnutls_session_t session, uint8_t * data, minor = data[pos + 1]; set_adv_version(session, major, minor); - ret = _gnutls_negotiate_version(session, major, minor); + ret = _gnutls_negotiate_version(session, major, minor, 0); if (ret < 0) { gnutls_assert(); return ret; } - neg_version = ret; + + vers = get_version(session); + if (vers == NULL) + return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET); + + neg_version = vers->id; pos += 2; -- cgit v1.2.1