summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <dueno@redhat.com>2019-05-22 11:16:03 +0200
committerDaiki Ueno <dueno@redhat.com>2019-05-22 12:04:58 +0200
commitd810e4f80bf271dfe600e5f2e7298dbc9ffe12b7 (patch)
tree5d5313b0652d4b8746a3e4ce24c19227ce637e49
parent27ec82e781b3960693cd4550440ab7c1664553b8 (diff)
downloadgnutls-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--NEWS3
-rw-r--r--lib/ext/max_record.c5
-rw-r--r--lib/ext/record_size_limit.c4
-rw-r--r--lib/gnutls_int.h5
-rw-r--r--lib/priority.c5
-rw-r--r--lib/priority_options.gperf1
6 files changed, 21 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index 038cdc9167..36369bb0ae 100644
--- a/NEWS
+++ b/NEWS
@@ -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