diff options
Diffstat (limited to 'lib/record.c')
-rw-r--r-- | lib/record.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/lib/record.c b/lib/record.c index 577a15aef8..a8ba45032d 100644 --- a/lib/record.c +++ b/lib/record.c @@ -1,6 +1,7 @@ /* - * Copyright (C) 2000-2016 Free Software Foundation, Inc. - * Copyright (C) 2012-2016 Nikos Mavrogiannopoulos + * Copyright (C) 2000-2018 Free Software Foundation, Inc. + * Copyright (C) 2012-2018 Nikos Mavrogiannopoulos + * Copyright (C) 2018 Red Hat, Inc. * * Author: Nikos Mavrogiannopoulos * @@ -372,7 +373,7 @@ copy_record_version(gnutls_session_t session, if (lver->tls13_sem) { version[0] = 0x03; - version[1] = 0x01; + version[1] = 0x03; } else { version[0] = lver->major; version[1] = lver->minor; @@ -687,8 +688,8 @@ record_check_version(gnutls_session_t session, int diff = 0; if (vers->tls13_sem) { - /* TLS 1.3 requires version to be 0x0301 */ - if (version[0] != 0x03 || version[1] != 0x01) + /* TLS 1.3 requires version to be 0x0303 */ + if (version[0] != 0x03 || version[1] != 0x03) diff = 1; } else { if (vers->major != version[0] || vers->minor != version[1]) @@ -1195,14 +1196,15 @@ _gnutls_recv_in_buffers(gnutls_session_t session, content_type_t type, mbuffer_st *bufel = NULL, *decrypted = NULL; gnutls_datum_t t; int ret; - unsigned int empty_fragments = 0; + unsigned int n_retries = 0; record_parameters_st *record_params; record_state_st *record_state; struct tls_record_st record; + const version_entry_st *vers = get_version(session); - begin: + begin: - if (empty_fragments > DEFAULT_MAX_EMPTY_RECORDS) { + if (n_retries > DEFAULT_MAX_EMPTY_RECORDS) { gnutls_assert(); return GNUTLS_E_TOO_MANY_EMPTY_PACKETS; } @@ -1263,6 +1265,18 @@ _gnutls_recv_in_buffers(gnutls_session_t session, content_type_t type, if (bufel == NULL) return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + if (vers && vers->tls13_sem && record.type == GNUTLS_CHANGE_CIPHER_SPEC && + record.length == 1 && session->internals.handshake_in_progress) { + _gnutls_read_log("discarding change cipher spec in TLS1.3\n"); + /* we use the same mechanism to retry as when + * receiving multiple empty TLS packets */ + bufel = + _mbuffer_head_pop_first(&session->internals. + record_recv_buffer); + _mbuffer_xfree(&bufel); + n_retries++; + goto begin; + } /* We allocate the maximum possible to allow few compressed bytes to expand to a * full record. Moreover we add space for any pad and the MAC (in case @@ -1362,7 +1376,7 @@ _gnutls_recv_in_buffers(gnutls_session_t session, content_type_t type, */ if (_mbuffer_get_udata_size(decrypted) == 0) { _mbuffer_xfree(&decrypted); - empty_fragments++; + n_retries++; goto begin; } @@ -1387,7 +1401,7 @@ _gnutls_recv_in_buffers(gnutls_session_t session, content_type_t type, return ret; - discard: + discard: session->internals.dtls.packets_dropped++; /* discard the whole received fragment. */ @@ -1397,7 +1411,7 @@ _gnutls_recv_in_buffers(gnutls_session_t session, content_type_t type, _mbuffer_xfree(&bufel); return gnutls_assert_val(GNUTLS_E_AGAIN); - sanity_check_error: + sanity_check_error: if (IS_DTLS(session)) { session->internals.dtls.packets_dropped++; ret = gnutls_assert_val(GNUTLS_E_AGAIN); @@ -1407,11 +1421,11 @@ _gnutls_recv_in_buffers(gnutls_session_t session, content_type_t type, session_unresumable(session); session_invalidate(session); - cleanup: + cleanup: _mbuffer_xfree(&decrypted); return ret; - recv_error: + recv_error: if (ret < 0 && (gnutls_error_is_fatal(ret) == 0 || ret == GNUTLS_E_TIMEDOUT)) |