summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnder Juaristi <a@juaristi.eus>2017-09-23 16:21:43 +0200
committerAnder Juaristi <a@juaristi.eus>2017-09-24 23:51:24 +0200
commitec36c7c67ab5f4ca7c08d293070686f3f8a666ff (patch)
tree7c55bbbb3a7b94ab4c57112ea4540d56bb4b65c3
parent2c6e3cc3ac5f810c9f2e86665764fe044fe7112f (diff)
downloadgnutls-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.in2
-rw-r--r--lib/libgnutls.map1
-rw-r--r--lib/range.c52
-rw-r--r--lib/record.c26
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++;