summaryrefslogtreecommitdiff
path: root/lib/record.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/record.c')
-rw-r--r--lib/record.c40
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))