diff options
author | Ander Juaristi <a@juaristi.eus> | 2017-09-23 16:21:43 +0200 |
---|---|---|
committer | Ander Juaristi <a@juaristi.eus> | 2017-09-24 23:51:24 +0200 |
commit | ec36c7c67ab5f4ca7c08d293070686f3f8a666ff (patch) | |
tree | 7c55bbbb3a7b94ab4c57112ea4540d56bb4b65c3 | |
parent | 2c6e3cc3ac5f810c9f2e86665764fe044fe7112f (diff) | |
download | gnutls-tmp-ajuaristi-draft-ietf-tls-tls13-21.tar.gz |
TLS 1.3 - New revived high-level record range APItmp-ajuaristi-draft-ietf-tls-tls13-21
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 2 | ||||
-rw-r--r-- | lib/libgnutls.map | 1 | ||||
-rw-r--r-- | lib/range.c | 52 | ||||
-rw-r--r-- | lib/record.c | 26 |
4 files changed, 73 insertions, 8 deletions
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index d14dd9e3cd..7247b4ded3 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -1205,6 +1205,8 @@ ssize_t gnutls_record_send(gnutls_session_t session, const void *data, ssize_t gnutls_record_send_range(gnutls_session_t session, const void *data, size_t data_size, const gnutls_range_st * range); +ssize_t gnutls_tls13_record_send_padding(gnutls_session_t session, + size_t min_pad); ssize_t gnutls_record_recv(gnutls_session_t session, void *data, size_t data_size); diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 43a6b13212..853f62b722 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -814,6 +814,7 @@ GNUTLS_3_4 gnutls_record_can_use_length_hiding; gnutls_range_split; gnutls_record_send_range; + gnutls_tls13_record_send_padding; gnutls_db_check_entry_time; gnutls_handshake_set_random; gnutls_record_cork; diff --git a/lib/range.c b/lib/range.c index 0b5655974f..4bdb65ba2c 100644 --- a/lib/range.c +++ b/lib/range.c @@ -26,6 +26,9 @@ #include "constate.h" #include "record.h" +/* TODO set this to the right value */ +#define TMP_IS_TLS_1_3(session) (1) + static void _gnutls_set_range(gnutls_range_st * dst, const size_t low, const size_t high) @@ -123,6 +126,8 @@ int gnutls_record_can_use_length_hiding(gnutls_session_t session) return 1; case CIPHER_STREAM: case CIPHER_AEAD: + if (TMP_IS_TLS_1_3(session)) + return 1; default: return 0; } @@ -304,3 +309,50 @@ gnutls_record_send_range(gnutls_session_t session, const void *data, return sent; } + +ssize_t +gnutls_tls13_record_send_padding(gnutls_session_t session, size_t min_pad) +{ + int ret; + size_t pad; + ssize_t max_frag; + record_parameters_st *record_params; + + ret = _gnutls_epoch_get(session, EPOCH_WRITE_CURRENT, + &record_params); + if (ret < 0) + return gnutls_assert_val(ret); + + max_frag = max_user_send_size(session, record_params); + ret = _gnutls_range_max_lh_pad(session, min_pad, max_frag); + if (ret < 0) + return gnutls_assert_val(ret); + pad = MIN(ret, min_pad); + + _gnutls_record_log( + "RANGE (TLS 1.3): Sending empty message with %u bytes of padding\n", + (unsigned int) pad); + + ret = _gnutls_send_tlen_int(session, GNUTLS_APPLICATION_DATA, + -1, EPOCH_WRITE_CURRENT, + NULL, 0, + pad, + MBUFFER_FLUSH); + while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) { + ret = _gnutls_send_tlen_int(session, GNUTLS_APPLICATION_DATA, + -1, EPOCH_WRITE_CURRENT, + NULL, 0, 0, + MBUFFER_FLUSH); + } + + if (ret < 0) + return gnutls_assert_val(ret); + if (ret > 0) { + _gnutls_record_log( + "RANGE (TLS 1.3): ERROR: ret = %u, but should be zero\n", + ret); + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + } + + return pad; +} diff --git a/lib/record.c b/lib/record.c index 7e455a4979..a8deb483f3 100644 --- a/lib/record.c +++ b/lib/record.c @@ -548,7 +548,8 @@ _gnutls_send_tlen_int(gnutls_session_t session, content_type_t type, * ok, and means to resume. */ if (session->internals.record_send_buffer.byte_length == 0 && - (tls_inner_plaintext.data_size == 0 && _data == NULL)) { + (tls_inner_plaintext.data_size == 0 && _data == NULL) && + !TMP_IS_TLS_1_3(session, type)) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } @@ -1459,6 +1460,10 @@ _gnutls_recv_in_buffers(gnutls_session_t session, content_type_t type, data = _mbuffer_get_udata_ptr(decrypted); len = _mbuffer_get_udata_size(decrypted); + if (len == 0) { + ret = GNUTLS_E_UNEXPECTED_PACKET_LENGTH; + goto sanity_check_error; + } if ((unsigned char) data[len - 1] != type) { _gnutls_audit_log(session, @@ -1469,6 +1474,11 @@ _gnutls_recv_in_buffers(gnutls_session_t session, content_type_t type, } _mbuffer_set_udata_size(decrypted, len - 1); + if ((len - 1) == 0) { + _gnutls_record_log( + "REC[%d]: TLS 1.3 - Got an empty message with padding only\n", + session); + } } /* Increase sequence number. We do both for TLS and DTLS, since in @@ -1482,13 +1492,13 @@ _gnutls_recv_in_buffers(gnutls_session_t session, content_type_t type, goto sanity_check_error; } -/* (originally for) TLS 1.0 CBC protection. - * Actually this code is called if we just received - * an empty packet. An empty TLS packet is usually - * sent to protect some vulnerabilities in the CBC mode. - * In that case we go to the beginning and start reading - * the next packet. - */ + /* (originally for) TLS 1.0 CBC protection. + * Actually this code is called if we just received + * an empty packet. An empty TLS packet is usually + * sent to protect some vulnerabilities in the CBC mode. + * In that case we go to the beginning and start reading + * the next packet. + */ if (_mbuffer_get_udata_size(decrypted) == 0) { _mbuffer_xfree(&decrypted); empty_fragments++; |