Merge pull request #6787 from yuhaoth/pr/workaround-gnutls_anti_replay_fail

TLS 1.3: EarlyData: Workaround anti replay fail from GnuTLS
This commit is contained in:
Ronald Cron 2023-01-11 09:05:36 +01:00 committed by GitHub
commit 83c5ad4873
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 14 deletions

View file

@ -0,0 +1,7 @@
Bugfix
* In TLS 1.3, when using a ticket for session resumption, tweak its age
calculation on the client side. It prevents a server with more accurate
ticket timestamps (typically timestamps in milliseconds) compared to the
Mbed TLS ticket timestamps (in seconds) to compute a ticket age smaller
than the age computed and transmitted by the client and thus potentially
reject the ticket. Fix #6623.

View file

@ -946,6 +946,21 @@ int mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext(
uint32_t obfuscated_ticket_age =
(uint32_t)( now - session->ticket_received );
/*
* The ticket timestamp is in seconds but the ticket age is in
* milliseconds. If the ticket was received at the end of a second and
* re-used here just at the beginning of the next second, the computed
* age `now - session->ticket_received` is equal to 1s thus 1000 ms
* while the actual age could be just a few milliseconds or tens of
* milliseconds. If the server has more accurate ticket timestamps
* (typically timestamps in milliseconds), as part of the processing of
* the ClientHello, it may compute a ticket lifetime smaller than the
* one computed here and potentially reject the ticket. To avoid that,
* remove one second to the ticket age if possible.
*/
if( obfuscated_ticket_age > 0 )
obfuscated_ticket_age -= 1;
obfuscated_ticket_age *= 1000;
obfuscated_ticket_age += session->ticket_age_add;

View file

@ -424,7 +424,7 @@ int main( void )
" reconnect=%%d number of reconnections using session resumption\n" \
" default: 0 (disabled)\n" \
" reco_server_name=%%s default: NULL\n" \
" reco_delay=%%d default: 0 seconds\n" \
" reco_delay=%%d default: 0 millionseconds\n" \
" reco_mode=%%d 0: copy session, 1: serialize session\n" \
" default: 1\n" \
" reconnect_hard=%%d default: 0 (disabled)\n" \
@ -3184,7 +3184,7 @@ reconnect:
#if defined(MBEDTLS_TIMING_C)
if( opt.reco_delay > 0 )
mbedtls_net_usleep( 1000000 * opt.reco_delay );
mbedtls_net_usleep( 1000 * opt.reco_delay );
#endif
mbedtls_printf( " . Reconnecting with saved session..." );

View file

@ -264,9 +264,6 @@ run_test "TLS 1.3: G->m: PSK: configured ephemeral only, good." \
0 \
-s "key exchange mode: ephemeral$"
# skip the basic check now cause it will randomly trigger the anti-replay protection in gnutls_server
# Add it back once we fix the issue
skip_next_test
requires_gnutls_tls1_3
requires_config_enabled MBEDTLS_DEBUG_C
requires_config_enabled MBEDTLS_SSL_CLI_C
@ -277,7 +274,7 @@ requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
run_test "TLS 1.3 m->G: EarlyData: basic check, good" \
"$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK --earlydata --disable-client-cert" \
"$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1 reco_delay=2" \
"$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1 reco_delay=900" \
1 \
-c "Reconnecting with saved session" \
-c "NewSessionTicket: early_data(42) extension received." \
@ -298,7 +295,7 @@ requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
run_test "TLS 1.3 m->G: EarlyData: no early_data in NewSessionTicket, good" \
"$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK --disable-client-cert" \
"$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1 reco_delay=2" \
"$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1" \
0 \
-c "Reconnecting with saved session" \
-C "NewSessionTicket: early_data(42) extension received." \

View file

@ -3643,7 +3643,7 @@ run_test "Session resume using tickets: cache disabled" \
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Session resume using tickets: timeout" \
"$P_SRV debug_level=3 tickets=1 cache_max=0 ticket_timeout=1" \
"$P_CLI debug_level=3 tickets=1 reconnect=1 reco_delay=2" \
"$P_CLI debug_level=3 tickets=1 reconnect=1 reco_delay=2000" \
0 \
-c "client hello, adding session ticket extension" \
-s "found session ticket extension" \
@ -3953,7 +3953,7 @@ run_test "Session resume using tickets, DTLS: cache disabled" \
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "Session resume using tickets, DTLS: timeout" \
"$P_SRV debug_level=3 dtls=1 tickets=1 cache_max=0 ticket_timeout=1" \
"$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 skip_close_notify=1 reco_delay=2" \
"$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 skip_close_notify=1 reco_delay=2000" \
0 \
-c "client hello, adding session ticket extension" \
-s "found session ticket extension" \
@ -4077,7 +4077,7 @@ requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_config_enabled MBEDTLS_SSL_CACHE_C
run_test "Session resume using cache: timeout < delay" \
"$P_SRV debug_level=3 tickets=0 cache_timeout=1" \
"$P_CLI debug_level=3 tickets=0 reconnect=1 reco_delay=2" \
"$P_CLI debug_level=3 tickets=0 reconnect=1 reco_delay=2000" \
0 \
-S "session successfully restored from cache" \
-S "session successfully restored from ticket" \
@ -4088,7 +4088,7 @@ requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_config_enabled MBEDTLS_SSL_CACHE_C
run_test "Session resume using cache: no timeout" \
"$P_SRV debug_level=3 tickets=0 cache_timeout=0" \
"$P_CLI debug_level=3 tickets=0 reconnect=1 reco_delay=2" \
"$P_CLI debug_level=3 tickets=0 reconnect=1 reco_delay=2000" \
0 \
-s "session successfully restored from cache" \
-S "session successfully restored from ticket" \
@ -4224,7 +4224,7 @@ requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_config_enabled MBEDTLS_SSL_CACHE_C
run_test "Session resume using cache, DTLS: timeout < delay" \
"$P_SRV dtls=1 debug_level=3 tickets=0 cache_timeout=1" \
"$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_delay=2" \
"$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_delay=2000" \
0 \
-S "session successfully restored from cache" \
-S "session successfully restored from ticket" \
@ -4235,7 +4235,7 @@ requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_config_enabled MBEDTLS_SSL_CACHE_C
run_test "Session resume using cache, DTLS: no timeout" \
"$P_SRV dtls=1 debug_level=3 tickets=0 cache_timeout=0" \
"$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_delay=2" \
"$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_delay=2000" \
0 \
-s "session successfully restored from cache" \
-S "session successfully restored from ticket" \
@ -9891,7 +9891,7 @@ run_test "DTLS fragmenting: proxy MTU, resumed handshake" \
key_file=data_files/server8.key \
hs_timeout=10000-60000 \
force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
mtu=1450 reconnect=1 skip_close_notify=1 reco_delay=1" \
mtu=1450 reconnect=1 skip_close_notify=1 reco_delay=1000" \
0 \
-S "autoreduction" \
-s "found fragmented DTLS handshake message" \