diff options
author | Daiki Ueno <dueno@redhat.com> | 2019-05-22 11:16:03 +0200 |
---|---|---|
committer | Daiki Ueno <dueno@redhat.com> | 2019-05-22 12:04:58 +0200 |
commit | d810e4f80bf271dfe600e5f2e7298dbc9ffe12b7 (patch) | |
tree | 5d5313b0652d4b8746a3e4ce24c19227ce637e49 | |
parent | 27ec82e781b3960693cd4550440ab7c1664553b8 (diff) | |
download | gnutls-d810e4f80bf271dfe600e5f2e7298dbc9ffe12b7.tar.gz |
priority: add new option to allow small records (>= 64)
There is a mismatch in the lower limit of record sizes in RFC
8449 (64) and our default (512). If the server advertises a smaller
limit than our default, the client has no way to keep communicating
with the server.
This patch adds a new priority string option %ALLOW_SMALL_RECORDS to
set the limit to 64.
Signed-off-by: Daiki Ueno <dueno@redhat.com>
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | lib/ext/max_record.c | 5 | ||||
-rw-r--r-- | lib/ext/record_size_limit.c | 4 | ||||
-rw-r--r-- | lib/gnutls_int.h | 5 | ||||
-rw-r--r-- | lib/priority.c | 5 | ||||
-rw-r--r-- | lib/priority_options.gperf | 1 |
6 files changed, 21 insertions, 2 deletions
@@ -20,6 +20,9 @@ See the end for copying conditions. ** libgnutls: Apply STD3 ASCII rules in gnutls_idna_map() to prevent hostname/domain crafting via IDNA conversion +** libgnutls: The priority string option %ALLOW_SMALL_RECORDS was added to allow + clients to communicate with the server advertising smaller limits than 512 + ** API and ABI modifications: gnutls_prf_early: Added gnutls_record_set_max_recv_size: Added diff --git a/lib/ext/max_record.c b/lib/ext/max_record.c index 0fb97b9789..dbb98cf620 100644 --- a/lib/ext/max_record.c +++ b/lib/ext/max_record.c @@ -302,7 +302,10 @@ ssize_t gnutls_record_set_max_size(gnutls_session_t session, size_t size) **/ ssize_t gnutls_record_set_max_recv_size(gnutls_session_t session, size_t size) { - if (size < MIN_RECORD_SIZE || size > DEFAULT_MAX_RECORD_SIZE) + if (size < + (session->internals.allow_small_records ? + MIN_RECORD_SIZE_SMALL : MIN_RECORD_SIZE) || + size > DEFAULT_MAX_RECORD_SIZE) return GNUTLS_E_INVALID_REQUEST; if (session->internals.handshake_in_progress) diff --git a/lib/ext/record_size_limit.c b/lib/ext/record_size_limit.c index 8b491da72c..e9fe6a1d8d 100644 --- a/lib/ext/record_size_limit.c +++ b/lib/ext/record_size_limit.c @@ -66,7 +66,9 @@ _gnutls_record_size_limit_recv_params(gnutls_session_t session, session->internals.hsk_flags |= HSK_RECORD_SIZE_LIMIT_RECEIVED; /* we do not want to accept sizes outside of our supported range */ - if (new_size < MIN_RECORD_SIZE) { + if (new_size < + (session->internals.allow_small_records ? + MIN_RECORD_SIZE_SMALL : MIN_RECORD_SIZE)) { /* for server, reject it by omitting the extension in the reply */ if (session->security_parameters.entity == GNUTLS_SERVER) { _gnutls_handshake_log("EXT[%p]: client requested too small record_size_limit %u; ignoring\n", diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 50251a356a..ad290b0be3 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -194,6 +194,7 @@ typedef enum record_send_state_t { #define MAX_RECORD_HEADER_SIZE DTLS_RECORD_HEADER_SIZE #define MIN_RECORD_SIZE 512 +#define MIN_RECORD_SIZE_SMALL 64 /* The following macro is used to calculate the overhead when sending. * when receiving we use a different way as there are implementations that @@ -969,6 +970,7 @@ struct gnutls_priority_st { /* these should be accessed from * session->internals.VAR names */ bool _allow_large_records; + bool _allow_small_records; bool _no_etm; bool _no_ext_master_secret; bool _allow_key_usage_violation; @@ -986,6 +988,7 @@ struct gnutls_priority_st { #define ENABLE_COMPAT(x) \ (x)->allow_large_records = 1; \ + (x)->allow_small_records = 1; \ (x)->no_etm = 1; \ (x)->no_ext_master_secret = 1; \ (x)->allow_key_usage_violation = 1; \ @@ -994,6 +997,7 @@ struct gnutls_priority_st { #define ENABLE_PRIO_COMPAT(x) \ (x)->_allow_large_records = 1; \ + (x)->_allow_small_records = 1; \ (x)->_no_etm = 1; \ (x)->_no_ext_master_secret = 1; \ (x)->_allow_key_usage_violation = 1; \ @@ -1118,6 +1122,7 @@ typedef struct { /* variables directly set when setting the priorities above, or * when overriding them */ bool allow_large_records; + bool allow_small_records; bool no_etm; bool no_ext_master_secret; bool allow_key_usage_violation; diff --git a/lib/priority.c b/lib/priority.c index 1ed5d84927..746eae05a4 100644 --- a/lib/priority.c +++ b/lib/priority.c @@ -627,6 +627,7 @@ gnutls_priority_set(gnutls_session_t session, gnutls_priority_t priority) #undef COPY_TO_INTERNALS #define COPY_TO_INTERNALS(xx) session->internals.xx = priority->_##xx COPY_TO_INTERNALS(allow_large_records); + COPY_TO_INTERNALS(allow_small_records); COPY_TO_INTERNALS(no_etm); COPY_TO_INTERNALS(no_ext_master_secret); COPY_TO_INTERNALS(allow_key_usage_violation); @@ -816,6 +817,10 @@ static void enable_server_key_usage_violations(gnutls_priority_t c) { c->allow_server_key_usage_violation = 1; } +static void enable_allow_small_records(gnutls_priority_t c) +{ + c->_allow_small_records = 1; +} static void enable_dumbfw(gnutls_priority_t c) { c->_dumbfw = 1; diff --git a/lib/priority_options.gperf b/lib/priority_options.gperf index c0524e5a09..a81001dda1 100644 --- a/lib/priority_options.gperf +++ b/lib/priority_options.gperf @@ -38,3 +38,4 @@ PROFILE_SUITEB128, enable_profile_suiteb128 PROFILE_SUITEB192, enable_profile_suiteb192 NEW_PADDING, dummy_func DEBUG_ALLOW_KEY_USAGE_VIOLATIONS, enable_server_key_usage_violations +ALLOW_SMALL_RECORDS, enable_allow_small_records |