Skip to content

Instantly share code, notes, and snippets.

@erikcorry
Created August 26, 2022 14:39
Show Gist options
  • Save erikcorry/cda15075a1a8fcb281d7e8dca4ea332e to your computer and use it in GitHub Desktop.
Save erikcorry/cda15075a1a8fcb281d7e8dca4ea332e to your computer and use it in GitHub Desktop.
diff --git a/include/mbedtls/compat-1.3.h b/include/mbedtls/compat-1.3.h
index 40177512c..efa1f78bb 100644
--- a/include/mbedtls/compat-1.3.h
+++ b/include/mbedtls/compat-1.3.h
@@ -2390,6 +2390,7 @@
#define ssl_set_sni mbedtls_ssl_conf_sni
#define ssl_set_transport mbedtls_ssl_conf_transport
#define ssl_set_truncated_hmac mbedtls_ssl_conf_truncated_hmac
+#define ssl_set_record_size_limit mbedtls_ssl_conf_record_size_limit
#define ssl_set_verify mbedtls_ssl_conf_verify
#define ssl_sig_from_pk mbedtls_ssl_sig_from_pk
#define ssl_states mbedtls_ssl_states
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 5064ec568..62bf82d6c 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -262,6 +262,9 @@
#define MBEDTLS_SSL_TRUNC_HMAC_ENABLED 1
#define MBEDTLS_SSL_TRUNCATED_HMAC_LEN 10 /* 80 bits, rfc 6066 section 7 */
+#define MBEDTLS_SSL_RECORD_SIZE_LIMIT_DISABLED 0
+#define MBEDTLS_SSL_RECORD_SIZE_LIMIT_ENABLED 1
+
#define MBEDTLS_SSL_SESSION_TICKETS_DISABLED 0
#define MBEDTLS_SSL_SESSION_TICKETS_ENABLED 1
@@ -466,6 +469,8 @@
#define MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC 22 /* 0x16 */
#define MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET 0x0017 /* 23 */
+#define MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT 28
+
#define MBEDTLS_TLS_EXT_SESSION_TICKET 35
/* The value of the CID extension is still TBD as of
@@ -1066,6 +1071,9 @@ struct mbedtls_ssl_config
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
uint8_t trunc_hmac /*bool*/; /*!< negotiate truncated hmac? */
#endif
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ unsigned int record_size_limit : 1; /*!< inform server of limit? */
+#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
uint8_t session_tickets /*bool*/; /*!< use session tickets? */
#endif
@@ -3533,6 +3541,18 @@ int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_c
void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate );
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+/**
+ * \brief Inform server of our incoming buffer size.
+ * (Default: MBEDTLS_SSL_RECORD_SIZE_LIMIT_ENABLED)
+ *
+ * \param conf SSL configuration
+ * \param truncate Enable or disable (MBEDTLS_SSL_RECORD_SIZE_LIMIT_ENABLED or
+ * MBEDTLS_SSL_RECORD_SIZE_LIMIT_DISABLED)
+ */
+void mbedtls_ssl_conf_record_size_limit( mbedtls_ssl_config *conf, int enable );
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
+
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
/**
* \brief Enable / Disable 1/n-1 record splitting
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 72351c975..0bdfcde75 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -595,6 +595,41 @@ static int ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+static int ssl_write_record_size_limit( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
+{
+ unsigned char *p = buf;
+
+ int limit = MBEDTLS_SSL_IN_CONTENT_LEN;
+
+ *olen = 0;
+
+ if( ssl->conf->record_size_limit == MBEDTLS_SSL_RECORD_SIZE_LIMIT_DISABLED )
+ return( 0 );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "client hello, adding record_size_limit extension, limit %d", limit) );
+
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
+
+ *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT >> 8 ) & 0xFF );
+ *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT ) & 0xFF );
+
+ *p++ = 0x00;
+ *p++ = 0x02;
+
+ *p++ = (unsigned char)( ( limit >> 8 ) & 0xFF );
+ *p++ = (unsigned char)( ( limit ) & 0xFF );
+
+ *olen = 6;
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
+
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
@@ -1374,6 +1409,16 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
ext_len += olen;
#endif
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ if( ( ret = ssl_write_record_size_limit( ssl, p + 2 + ext_len,
+ end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record_size_limit", ret );
+ return( ret );
+ }
+ ext_len += olen;
+#endif
+
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
if( ( ret = ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len,
end, &olen ) ) != 0 )
@@ -1623,6 +1668,40 @@ static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+static int ssl_parse_record_size_limit( mbedtls_ssl_context *ssl,
+ const unsigned char *buf,
+ size_t len )
+{
+ if( ssl->conf->record_size_limit == MBEDTLS_SSL_RECORD_SIZE_LIMIT_DISABLED ||
+ len != 2 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "non-matching record size limit extension" ) );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 4,
+ ( "server recognized our record size limit extension" ) );
+
+ ((void) buf);
+
+ /* We don't actually do anything with the server's answer. If the server
+ understood the extension it will include it in the answer. If the
+ server did not understand the extension we continue in the hope that it
+ will never the less not send us records that are too big. This will
+ always be the case for very small TLS downloads. For example many data
+ APIs don't produce enough data in all to exceed the limit on record
+ size. */
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
+
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
@@ -2455,6 +2534,19 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
break;
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ case MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT:
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "found record_size_limit extension" ) );
+
+ if( ( ret = ssl_parse_record_size_limit( ssl,
+ ext + 4, ext_size ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ break;
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
+
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) );
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index e47c53888..288114be5 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -1895,7 +1895,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
if( nb_want > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 7badec51a..97a2a423b 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4967,6 +4967,13 @@ void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate )
}
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+void mbedtls_ssl_conf_record_size_limit( mbedtls_ssl_config *conf, int enable )
+{
+ conf->record_size_limit = enable;
+}
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
+
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split )
{
@@ -7013,6 +7020,10 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
conf->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
#endif
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ conf->record_size_limit = MBEDTLS_SSL_RECORD_SIZE_LIMIT_ENABLED;
+#endif
+
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
conf->cbc_record_splitting = MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED;
#endif
diff --git a/library/version_features.c b/library/version_features.c
index 40c95201b..fbda7927b 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -570,6 +570,9 @@ static const char * const features[] = {
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
"MBEDTLS_SSL_TRUNCATED_HMAC",
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ "MBEDTLS_SSL_RECORD_SIZE_LIMIT",
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT)
"MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT",
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT */
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 4f076602a..4c24ab733 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -78,6 +78,7 @@ int main( void )
#define DFL_AUTH_MODE -1
#define DFL_MFL_CODE MBEDTLS_SSL_MAX_FRAG_LEN_NONE
#define DFL_TRUNC_HMAC -1
+#define DFL_RECORD_SIZE_LIMIT -1
#define DFL_RECSPLIT -1
#define DFL_DHMLEN -1
#define DFL_RECONNECT 0
@@ -245,6 +246,13 @@ int main( void )
#define USAGE_TRUNC_HMAC ""
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+#define USAGE_RECORD_SIZE_LIMIT \
+ " record_size_limit=%%d default: 1 (enabled)\n"
+#else
+#define USAGE_RECORD_SIZE_LIMIT ""
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
+
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
#define USAGE_MAX_FRAG_LEN \
" max_frag_len=%%d default: 16384 (tls default)\n" \
@@ -843,6 +851,7 @@ int main( int argc, char *argv[] )
opt.auth_mode = DFL_AUTH_MODE;
opt.mfl_code = DFL_MFL_CODE;
opt.trunc_hmac = DFL_TRUNC_HMAC;
+ opt.record_size_limit = DFL_RECORD_SIZE_LIMIT;
opt.recsplit = DFL_RECSPLIT;
opt.dhmlen = DFL_DHMLEN;
opt.reconnect = DFL_RECONNECT;
@@ -1218,6 +1227,15 @@ int main( int argc, char *argv[] )
default: goto usage;
}
}
+ else if( strcmp( p, "record_size_limit" ) == 0 )
+ {
+ switch( atoi( q ) )
+ {
+ case 0: opt.record_size_limit = MBEDTLS_SSL_RECORD_SIZE_LIMIT_DISABLED; break;
+ case 1: opt.record_size_limit = MBEDTLS_SSL_RECORD_SIZE_LIMIT_ENABLED; break;
+ default: goto usage;
+ }
+ }
else if( strcmp( p, "hs_timeout" ) == 0 )
{
if( ( p = strchr( q, '-' ) ) == NULL )
@@ -1822,6 +1840,11 @@ int main( int argc, char *argv[] )
mbedtls_ssl_conf_truncated_hmac( &conf, opt.trunc_hmac );
#endif
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ if( opt.record_size_limit != DFL_RECORD_SIZE_LIMIT )
+ mbedtls_ssl_conf_record_size_limit( &conf, opt.record_size_limit );
+#endif
+
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
if( opt.extended_ms != DFL_EXTENDED_MS )
mbedtls_ssl_conf_extended_master_secret( &conf, opt.extended_ms );
diff --git a/programs/test/query_config.c b/programs/test/query_config.c
index 331310165..74c5311b9 100644
--- a/programs/test/query_config.c
+++ b/programs/test/query_config.c
@@ -1584,6 +1584,14 @@ int query_config( const char *config )
}
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ if( strcmp( "MBEDTLS_SSL_RECORD_SIZE_LIMIT", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_RECORD_SIZE_LIMIT );
+ return( 0 );
+ }
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
+
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT)
if( strcmp( "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT", config ) == 0 )
{
diff --git a/scripts/data_files/rename-1.3-2.0.txt b/scripts/data_files/rename-1.3-2.0.txt
index e599ac597..54a88da73 100644
--- a/scripts/data_files/rename-1.3-2.0.txt
+++ b/scripts/data_files/rename-1.3-2.0.txt
@@ -1079,6 +1079,8 @@ SSL_TRANSPORT_STREAM MBEDTLS_SSL_TRANSPORT_STREAM
SSL_TRUNCATED_HMAC_LEN MBEDTLS_SSL_TRUNCATED_HMAC_LEN
SSL_TRUNC_HMAC_DISABLED MBEDTLS_SSL_TRUNC_HMAC_DISABLED
SSL_TRUNC_HMAC_ENABLED MBEDTLS_SSL_TRUNC_HMAC_ENABLED
+SSL_RECORD_SIZE_LIMIT_DISABLED MBEDTLS_SSL_RECORD_SIZE_LIMIT_DISABLED
+SSL_RECORD_SIZE_LIMIT_ENABLED MBEDTLS_SSL_RECORD_SIZE_LIMIT_ENABLED
SSL_VERIFY_DATA_MAX_LEN MBEDTLS_SSL_VERIFY_DATA_MAX_LEN
SSL_VERIFY_NONE MBEDTLS_SSL_VERIFY_NONE
SSL_VERIFY_OPTIONAL MBEDTLS_SSL_VERIFY_OPTIONAL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment