Created
August 26, 2022 14:39
-
-
Save erikcorry/cda15075a1a8fcb281d7e8dca4ea332e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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