mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-26 08:15:44 +01:00
Make handshake fragmentation follow max_frag_len
Note: no interop tests in ssl-opt.sh for now, as some of them make us run into bugs in (the CI's default versions of) OpenSSL and GnuTLS, so interop tests will be added later once the situation is clarified. <- TODO
This commit is contained in:
parent
28f4beab1c
commit
2cb17e201b
@ -2845,12 +2845,23 @@ int mbedtls_ssl_resend( mbedtls_ssl_context *ssl )
|
|||||||
*/
|
*/
|
||||||
int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
|
int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
|
||||||
{
|
{
|
||||||
|
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
|
||||||
|
const size_t max_record_content_len = mbedtls_ssl_get_max_frag_len( ssl );
|
||||||
|
#else
|
||||||
|
const size_t max_record_content_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
|
||||||
|
#endif
|
||||||
|
/* DTLS handshake headers are 12 bytes */
|
||||||
|
const size_t max_hs_fragment_len = max_record_content_len - 12;
|
||||||
|
|
||||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) );
|
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) );
|
||||||
|
|
||||||
if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING )
|
if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING )
|
||||||
{
|
{
|
||||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise fligh transmission" ) );
|
MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise fligh transmission" ) );
|
||||||
|
|
||||||
|
MBEDTLS_SSL_DEBUG_MSG( 2, ( "max handshake fragment length: %u",
|
||||||
|
max_hs_fragment_len ) );
|
||||||
|
|
||||||
ssl->handshake->cur_msg = ssl->handshake->flight;
|
ssl->handshake->cur_msg = ssl->handshake->flight;
|
||||||
ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
|
ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
|
||||||
ssl_swap_epochs( ssl );
|
ssl_swap_epochs( ssl );
|
||||||
@ -2858,13 +2869,6 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
|
|||||||
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
|
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX: this should not be hardcoded.
|
|
||||||
* Currently UDP limit - HS header - Record header
|
|
||||||
* (Should account for encryption overhead (renegotiation, finished)?)
|
|
||||||
*/
|
|
||||||
#define HS_LIMIT ( 512 - 12 - 13 )
|
|
||||||
|
|
||||||
while( ssl->handshake->cur_msg != NULL )
|
while( ssl->handshake->cur_msg != NULL )
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -2894,7 +2898,8 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
|
|||||||
const size_t hs_len = cur->len - 12;
|
const size_t hs_len = cur->len - 12;
|
||||||
const size_t frag_off = p - ( cur->p + 12 );
|
const size_t frag_off = p - ( cur->p + 12 );
|
||||||
const size_t rem_len = hs_len - frag_off;
|
const size_t rem_len = hs_len - frag_off;
|
||||||
const size_t frag_len = rem_len > HS_LIMIT ? HS_LIMIT : rem_len;
|
const size_t frag_len = rem_len > max_hs_fragment_len
|
||||||
|
? max_hs_fragment_len : rem_len;
|
||||||
|
|
||||||
/* Messages are stored with handshake headers as if not fragmented,
|
/* Messages are stored with handshake headers as if not fragmented,
|
||||||
* copy beginning of headers then fill fragmentation fields.
|
* copy beginning of headers then fill fragmentation fields.
|
||||||
@ -7029,15 +7034,20 @@ size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
|
|||||||
*/
|
*/
|
||||||
max_len = ssl_mfl_code_to_length( ssl->conf->mfl_code );
|
max_len = ssl_mfl_code_to_length( ssl->conf->mfl_code );
|
||||||
|
|
||||||
/*
|
/* Check if a smaller max length was negotiated */
|
||||||
* Check if a smaller max length was negotiated
|
|
||||||
*/
|
|
||||||
if( ssl->session_out != NULL &&
|
if( ssl->session_out != NULL &&
|
||||||
ssl_mfl_code_to_length( ssl->session_out->mfl_code ) < max_len )
|
ssl_mfl_code_to_length( ssl->session_out->mfl_code ) < max_len )
|
||||||
{
|
{
|
||||||
max_len = ssl_mfl_code_to_length( ssl->session_out->mfl_code );
|
max_len = ssl_mfl_code_to_length( ssl->session_out->mfl_code );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* During a handshake, use the value being negotiated */
|
||||||
|
if( ssl->session_negotiate != NULL &&
|
||||||
|
ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code ) < max_len )
|
||||||
|
{
|
||||||
|
max_len = ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code );
|
||||||
|
}
|
||||||
|
|
||||||
return max_len;
|
return max_len;
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
|
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
|
||||||
|
102
tests/ssl-opt.sh
102
tests/ssl-opt.sh
@ -4877,6 +4877,108 @@ run_test "DTLS reassembly: fragmentation, nbio (openssl server)" \
|
|||||||
-c "found fragmented DTLS handshake message" \
|
-c "found fragmented DTLS handshake message" \
|
||||||
-C "error"
|
-C "error"
|
||||||
|
|
||||||
|
# Tests for sending fragmented handshake messages with DTLS
|
||||||
|
#
|
||||||
|
# Use client auth when we need the client to send large messages,
|
||||||
|
# and use large cert chains on both sides too (the long chains we have all use
|
||||||
|
# both RSA and ECDSA, but ideally we should have long chains with either).
|
||||||
|
# Sizes reached (UDP payload):
|
||||||
|
# - 2037B for server certificate
|
||||||
|
# - 1542B for client certificate
|
||||||
|
# - 1013B for newsessionticket
|
||||||
|
# - all others below 512B
|
||||||
|
# All those tests assume MAX_CONTENT_LEN is at least 2048
|
||||||
|
|
||||||
|
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
|
||||||
|
requires_config_enabled MBEDTLS_RSA_C
|
||||||
|
requires_config_enabled MBEDTLS_ECDSA_C
|
||||||
|
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
|
||||||
|
run_test "DTLS fragmenting: none (for reference)" \
|
||||||
|
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
|
||||||
|
crt_file=data_files/server7_int-ca.crt \
|
||||||
|
key_file=data_files/server7.key \
|
||||||
|
max_frag_len=2048" \
|
||||||
|
"$P_CLI dtls=1 debug_level=2 \
|
||||||
|
crt_file=data_files/server8_int-ca2.crt \
|
||||||
|
key_file=data_files/server8.key \
|
||||||
|
max_frag_len=2048" \
|
||||||
|
0 \
|
||||||
|
-S "found fragmented DTLS handshake message" \
|
||||||
|
-C "found fragmented DTLS handshake message" \
|
||||||
|
-C "error"
|
||||||
|
|
||||||
|
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
|
||||||
|
requires_config_enabled MBEDTLS_RSA_C
|
||||||
|
requires_config_enabled MBEDTLS_ECDSA_C
|
||||||
|
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
|
||||||
|
run_test "DTLS fragmenting: server only" \
|
||||||
|
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
|
||||||
|
crt_file=data_files/server7_int-ca.crt \
|
||||||
|
key_file=data_files/server7.key \
|
||||||
|
max_frag_len=1024" \
|
||||||
|
"$P_CLI dtls=1 debug_level=2 \
|
||||||
|
crt_file=data_files/server8_int-ca2.crt \
|
||||||
|
key_file=data_files/server8.key \
|
||||||
|
max_frag_len=2048" \
|
||||||
|
0 \
|
||||||
|
-S "found fragmented DTLS handshake message" \
|
||||||
|
-c "found fragmented DTLS handshake message" \
|
||||||
|
-C "error"
|
||||||
|
|
||||||
|
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
|
||||||
|
requires_config_enabled MBEDTLS_RSA_C
|
||||||
|
requires_config_enabled MBEDTLS_ECDSA_C
|
||||||
|
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
|
||||||
|
run_test "DTLS fragmenting: server only (more)" \
|
||||||
|
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
|
||||||
|
crt_file=data_files/server7_int-ca.crt \
|
||||||
|
key_file=data_files/server7.key \
|
||||||
|
max_frag_len=512" \
|
||||||
|
"$P_CLI dtls=1 debug_level=2 \
|
||||||
|
crt_file=data_files/server8_int-ca2.crt \
|
||||||
|
key_file=data_files/server8.key \
|
||||||
|
max_frag_len=2048" \
|
||||||
|
0 \
|
||||||
|
-S "found fragmented DTLS handshake message" \
|
||||||
|
-c "found fragmented DTLS handshake message" \
|
||||||
|
-C "error"
|
||||||
|
|
||||||
|
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
|
||||||
|
requires_config_enabled MBEDTLS_RSA_C
|
||||||
|
requires_config_enabled MBEDTLS_ECDSA_C
|
||||||
|
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
|
||||||
|
run_test "DTLS fragmenting: client-initiated, server only" \
|
||||||
|
"$P_SRV dtls=1 debug_level=2 auth_mode=none \
|
||||||
|
crt_file=data_files/server7_int-ca.crt \
|
||||||
|
key_file=data_files/server7.key \
|
||||||
|
max_frag_len=2048" \
|
||||||
|
"$P_CLI dtls=1 debug_level=2 \
|
||||||
|
crt_file=data_files/server8_int-ca2.crt \
|
||||||
|
key_file=data_files/server8.key \
|
||||||
|
max_frag_len=512" \
|
||||||
|
0 \
|
||||||
|
-S "found fragmented DTLS handshake message" \
|
||||||
|
-c "found fragmented DTLS handshake message" \
|
||||||
|
-C "error"
|
||||||
|
|
||||||
|
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
|
||||||
|
requires_config_enabled MBEDTLS_RSA_C
|
||||||
|
requires_config_enabled MBEDTLS_ECDSA_C
|
||||||
|
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
|
||||||
|
run_test "DTLS fragmenting: client-initiated, both" \
|
||||||
|
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
|
||||||
|
crt_file=data_files/server7_int-ca.crt \
|
||||||
|
key_file=data_files/server7.key \
|
||||||
|
max_frag_len=2048" \
|
||||||
|
"$P_CLI dtls=1 debug_level=2 \
|
||||||
|
crt_file=data_files/server8_int-ca2.crt \
|
||||||
|
key_file=data_files/server8.key \
|
||||||
|
max_frag_len=512" \
|
||||||
|
0 \
|
||||||
|
-s "found fragmented DTLS handshake message" \
|
||||||
|
-c "found fragmented DTLS handshake message" \
|
||||||
|
-C "error"
|
||||||
|
|
||||||
# Tests for specific things with "unreliable" UDP connection
|
# Tests for specific things with "unreliable" UDP connection
|
||||||
|
|
||||||
not_with_valgrind # spurious resend due to timeout
|
not_with_valgrind # spurious resend due to timeout
|
||||||
|
Loading…
Reference in New Issue
Block a user