Merge pull request #3061 from mpg/skip-close-notify-2.7

[backport 2.7] Fix possible close_notify/ClientHello confusion
This commit is contained in:
Manuel Pégourié-Gonnard 2020-03-03 12:12:13 +01:00 committed by GitHub
commit 3f402bca58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 73 additions and 48 deletions

View File

@ -108,6 +108,7 @@ int main( void )
#define DFL_FALLBACK -1
#define DFL_EXTENDED_MS -1
#define DFL_ETM -1
#define DFL_SKIP_CLOSE_NOTIFY 0
#define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: "
#define GET_REQUEST_END "\r\n\r\n"
@ -256,6 +257,7 @@ int main( void )
" options: 1 (non-blocking), 2 (added delays)\n" \
" read_timeout=%%d default: 0 ms (no timeout)\n" \
" max_resend=%%d default: 0 (no resend on timeout)\n" \
" skip_close_notify=%%d default: 0 (send close_notify)\n" \
"\n" \
USAGE_DTLS \
"\n" \
@ -344,6 +346,7 @@ struct options
int fallback; /* is this a fallback connection? */
int extended_ms; /* negotiate extended master secret? */
int etm; /* negotiate encrypt then mac? */
int skip_close_notify; /* skip sending the close_notify alert */
} opt;
static void my_debug( void *ctx, int level,
@ -562,6 +565,7 @@ int main( int argc, char *argv[] )
opt.fallback = DFL_FALLBACK;
opt.extended_ms = DFL_EXTENDED_MS;
opt.etm = DFL_ETM;
opt.skip_close_notify = DFL_SKIP_CLOSE_NOTIFY;
for( i = 1; i < argc; i++ )
{
@ -864,6 +868,12 @@ int main( int argc, char *argv[] )
if( opt.dhmlen < 0 )
goto usage;
}
else if( strcmp( p, "skip_close_notify" ) == 0 )
{
opt.skip_close_notify = atoi( q );
if( opt.skip_close_notify < 0 || opt.skip_close_notify > 1 )
goto usage;
}
else
goto usage;
}
@ -1733,10 +1743,25 @@ close_notify:
mbedtls_printf( " . Closing the connection..." );
fflush( stdout );
/*
* Most of the time sending a close_notify before closing is the right
* thing to do. However, when the server already knows how many messages
* are expected and closes the connection by itself, this alert becomes
* redundant. Sometimes with DTLS this redundancy becomes a problem by
* leading to a race condition where the server might close the connection
* before seeing the alert, and since UDP is connection-less when the
* alert arrives it will be seen as a new connection, which will fail as
* the alert is clearly not a valid ClientHello. This may cause spurious
* failures in tests that use DTLS and resumption with ssl_server2 in
* ssl-opt.sh, avoided by enabling skip_close_notify client-side.
*/
if( opt.skip_close_notify == 0 )
{
/* No error checking, the connection might be closed already */
do ret = mbedtls_ssl_close_notify( &ssl );
while( ret == MBEDTLS_ERR_SSL_WANT_WRITE );
ret = 0;
}
mbedtls_printf( " done\n" );

View File

@ -1394,7 +1394,7 @@ run_test "Session resume using tickets: openssl client" \
run_test "Session resume using tickets, DTLS: basic" \
"$P_SRV debug_level=3 dtls=1 tickets=1" \
"$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1" \
"$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 skip_close_notify=1" \
0 \
-c "client hello, adding session ticket extension" \
-s "found session ticket extension" \
@ -1408,7 +1408,7 @@ run_test "Session resume using tickets, DTLS: basic" \
run_test "Session resume using tickets, DTLS: cache disabled" \
"$P_SRV debug_level=3 dtls=1 tickets=1 cache_max=0" \
"$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1" \
"$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 skip_close_notify=1" \
0 \
-c "client hello, adding session ticket extension" \
-s "found session ticket extension" \
@ -1422,7 +1422,7 @@ run_test "Session resume using tickets, DTLS: cache disabled" \
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 reco_delay=2" \
"$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 skip_close_notify=1 reco_delay=2" \
0 \
-c "client hello, adding session ticket extension" \
-s "found session ticket extension" \
@ -1554,7 +1554,7 @@ run_test "Session resume using cache: openssl server" \
run_test "Session resume using cache, DTLS: tickets enabled on client" \
"$P_SRV dtls=1 debug_level=3 tickets=0" \
"$P_CLI dtls=1 debug_level=3 tickets=1 reconnect=1" \
"$P_CLI dtls=1 debug_level=3 tickets=1 reconnect=1 skip_close_notify=1" \
0 \
-c "client hello, adding session ticket extension" \
-s "found session ticket extension" \
@ -1568,7 +1568,7 @@ run_test "Session resume using cache, DTLS: tickets enabled on client" \
run_test "Session resume using cache, DTLS: tickets enabled on server" \
"$P_SRV dtls=1 debug_level=3 tickets=1" \
"$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1" \
"$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1" \
0 \
-C "client hello, adding session ticket extension" \
-S "found session ticket extension" \
@ -1582,7 +1582,7 @@ run_test "Session resume using cache, DTLS: tickets enabled on server" \
run_test "Session resume using cache, DTLS: cache_max=0" \
"$P_SRV dtls=1 debug_level=3 tickets=0 cache_max=0" \
"$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1" \
"$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1" \
0 \
-S "session successfully restored from cache" \
-S "session successfully restored from ticket" \
@ -1591,7 +1591,7 @@ run_test "Session resume using cache, DTLS: cache_max=0" \
run_test "Session resume using cache, DTLS: cache_max=1" \
"$P_SRV dtls=1 debug_level=3 tickets=0 cache_max=1" \
"$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1" \
"$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1" \
0 \
-s "session successfully restored from cache" \
-S "session successfully restored from ticket" \
@ -1600,7 +1600,7 @@ run_test "Session resume using cache, DTLS: cache_max=1" \
run_test "Session resume using cache, DTLS: timeout > delay" \
"$P_SRV dtls=1 debug_level=3 tickets=0" \
"$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 reco_delay=0" \
"$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_delay=0" \
0 \
-s "session successfully restored from cache" \
-S "session successfully restored from ticket" \
@ -1609,7 +1609,7 @@ run_test "Session resume using cache, DTLS: timeout > delay" \
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 reco_delay=2" \
"$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_delay=2" \
0 \
-S "session successfully restored from cache" \
-S "session successfully restored from ticket" \
@ -1618,7 +1618,7 @@ run_test "Session resume using cache, DTLS: timeout < delay" \
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 reco_delay=2" \
"$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_delay=2" \
0 \
-s "session successfully restored from cache" \
-S "session successfully restored from ticket" \
@ -5239,9 +5239,9 @@ run_test "DTLS proxy: delay ChangeCipherSpec" \
client_needs_more_time 2
run_test "DTLS proxy: 3d (drop, delay, duplicate), \"short\" PSK handshake" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \
"$P_SRV dtls=1 hs_timeout=500-10000 tickets=0 auth_mode=none \
psk=abc123" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \
"$P_CLI dtls=1 hs_timeout=500-10000 tickets=0 psk=abc123 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \
-s "Extra-header:" \
@ -5250,8 +5250,8 @@ run_test "DTLS proxy: 3d (drop, delay, duplicate), \"short\" PSK handshake" \
client_needs_more_time 2
run_test "DTLS proxy: 3d, \"short\" RSA handshake" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 \
"$P_SRV dtls=1 hs_timeout=500-10000 tickets=0 auth_mode=none" \
"$P_CLI dtls=1 hs_timeout=500-10000 tickets=0 \
force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
0 \
-s "Extra-header:" \
@ -5260,8 +5260,8 @@ run_test "DTLS proxy: 3d, \"short\" RSA handshake" \
client_needs_more_time 2
run_test "DTLS proxy: 3d, \"short\" (no ticket, no cli_auth) FS handshake" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0" \
"$P_SRV dtls=1 hs_timeout=500-10000 tickets=0 auth_mode=none" \
"$P_CLI dtls=1 hs_timeout=500-10000 tickets=0" \
0 \
-s "Extra-header:" \
-c "HTTP/1.0 200 OK"
@ -5269,8 +5269,8 @@ run_test "DTLS proxy: 3d, \"short\" (no ticket, no cli_auth) FS handshake" \
client_needs_more_time 2
run_test "DTLS proxy: 3d, FS, client auth" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=required" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0" \
"$P_SRV dtls=1 hs_timeout=500-10000 tickets=0 auth_mode=required" \
"$P_CLI dtls=1 hs_timeout=500-10000 tickets=0" \
0 \
-s "Extra-header:" \
-c "HTTP/1.0 200 OK"
@ -5278,8 +5278,8 @@ run_test "DTLS proxy: 3d, FS, client auth" \
client_needs_more_time 2
run_test "DTLS proxy: 3d, FS, ticket" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=1 auth_mode=none" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=1" \
"$P_SRV dtls=1 hs_timeout=500-10000 tickets=1 auth_mode=none" \
"$P_CLI dtls=1 hs_timeout=500-10000 tickets=1" \
0 \
-s "Extra-header:" \
-c "HTTP/1.0 200 OK"
@ -5287,8 +5287,8 @@ run_test "DTLS proxy: 3d, FS, ticket" \
client_needs_more_time 2
run_test "DTLS proxy: 3d, max handshake (FS, ticket + client auth)" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=1 auth_mode=required" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=1" \
"$P_SRV dtls=1 hs_timeout=500-10000 tickets=1 auth_mode=required" \
"$P_CLI dtls=1 hs_timeout=500-10000 tickets=1" \
0 \
-s "Extra-header:" \
-c "HTTP/1.0 200 OK"
@ -5296,9 +5296,9 @@ run_test "DTLS proxy: 3d, max handshake (FS, ticket + client auth)" \
client_needs_more_time 2
run_test "DTLS proxy: 3d, max handshake, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 nbio=2 tickets=1 \
"$P_SRV dtls=1 hs_timeout=500-10000 nbio=2 tickets=1 \
auth_mode=required" \
"$P_CLI dtls=1 hs_timeout=250-10000 nbio=2 tickets=1" \
"$P_CLI dtls=1 hs_timeout=500-10000 nbio=2 tickets=1" \
0 \
-s "Extra-header:" \
-c "HTTP/1.0 200 OK"
@ -5306,10 +5306,10 @@ run_test "DTLS proxy: 3d, max handshake, nbio" \
client_needs_more_time 4
run_test "DTLS proxy: 3d, min handshake, resumption" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \
"$P_SRV dtls=1 hs_timeout=500-10000 tickets=0 auth_mode=none \
psk=abc123 debug_level=3" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \
debug_level=3 reconnect=1 read_timeout=1000 max_resend=10 \
"$P_CLI dtls=1 hs_timeout=500-10000 tickets=0 psk=abc123 \
debug_level=3 reconnect=1 skip_close_notify=1 read_timeout=1000 max_resend=10 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \
-s "a session has been resumed" \
@ -5320,10 +5320,10 @@ run_test "DTLS proxy: 3d, min handshake, resumption" \
client_needs_more_time 4
run_test "DTLS proxy: 3d, min handshake, resumption, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \
"$P_SRV dtls=1 hs_timeout=500-10000 tickets=0 auth_mode=none \
psk=abc123 debug_level=3 nbio=2" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \
debug_level=3 reconnect=1 read_timeout=1000 max_resend=10 \
"$P_CLI dtls=1 hs_timeout=500-10000 tickets=0 psk=abc123 \
debug_level=3 reconnect=1 skip_close_notify=1 read_timeout=1000 max_resend=10 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8 nbio=2" \
0 \
-s "a session has been resumed" \
@ -5335,9 +5335,9 @@ client_needs_more_time 4
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
run_test "DTLS proxy: 3d, min handshake, client-initiated renego" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \
"$P_SRV dtls=1 hs_timeout=500-10000 tickets=0 auth_mode=none \
psk=abc123 renegotiation=1 debug_level=2" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \
"$P_CLI dtls=1 hs_timeout=500-10000 tickets=0 psk=abc123 \
renegotiate=1 debug_level=2 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \
@ -5350,9 +5350,9 @@ client_needs_more_time 4
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
run_test "DTLS proxy: 3d, min handshake, client-initiated renego, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \
"$P_SRV dtls=1 hs_timeout=500-10000 tickets=0 auth_mode=none \
psk=abc123 renegotiation=1 debug_level=2" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \
"$P_CLI dtls=1 hs_timeout=500-10000 tickets=0 psk=abc123 \
renegotiate=1 debug_level=2 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \
@ -5365,10 +5365,10 @@ client_needs_more_time 4
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
run_test "DTLS proxy: 3d, min handshake, server-initiated renego" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \
"$P_SRV dtls=1 hs_timeout=500-10000 tickets=0 auth_mode=none \
psk=abc123 renegotiate=1 renegotiation=1 exchanges=4 \
debug_level=2" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \
"$P_CLI dtls=1 hs_timeout=500-10000 tickets=0 psk=abc123 \
renegotiation=1 exchanges=4 debug_level=2 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \
@ -5381,10 +5381,10 @@ client_needs_more_time 4
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
run_test "DTLS proxy: 3d, min handshake, server-initiated renego, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dtls=1 hs_timeout=250-10000 tickets=0 auth_mode=none \
"$P_SRV dtls=1 hs_timeout=500-10000 tickets=0 auth_mode=none \
psk=abc123 renegotiate=1 renegotiation=1 exchanges=4 \
debug_level=2 nbio=2" \
"$P_CLI dtls=1 hs_timeout=250-10000 tickets=0 psk=abc123 \
"$P_CLI dtls=1 hs_timeout=500-10000 tickets=0 psk=abc123 \
renegotiation=1 exchanges=4 debug_level=2 nbio=2 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
0 \
@ -5398,7 +5398,7 @@ not_with_valgrind # risk of non-mbedtls peer timing out
run_test "DTLS proxy: 3d, openssl server" \
-p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \
"$O_SRV -dtls1 -mtu 2048" \
"$P_CLI dtls=1 hs_timeout=250-60000 tickets=0" \
"$P_CLI dtls=1 hs_timeout=500-60000 tickets=0" \
0 \
-c "HTTP/1.0 200 OK"
@ -5407,7 +5407,7 @@ not_with_valgrind # risk of non-mbedtls peer timing out
run_test "DTLS proxy: 3d, openssl server, fragmentation" \
-p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \
"$O_SRV -dtls1 -mtu 768" \
"$P_CLI dtls=1 hs_timeout=250-60000 tickets=0" \
"$P_CLI dtls=1 hs_timeout=500-60000 tickets=0" \
0 \
-c "HTTP/1.0 200 OK"
@ -5416,7 +5416,7 @@ not_with_valgrind # risk of non-mbedtls peer timing out
run_test "DTLS proxy: 3d, openssl server, fragmentation, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \
"$O_SRV -dtls1 -mtu 768" \
"$P_CLI dtls=1 hs_timeout=250-60000 nbio=2 tickets=0" \
"$P_CLI dtls=1 hs_timeout=500-60000 nbio=2 tickets=0" \
0 \
-c "HTTP/1.0 200 OK"
@ -5426,7 +5426,7 @@ not_with_valgrind # risk of non-mbedtls peer timing out
run_test "DTLS proxy: 3d, gnutls server" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$G_SRV -u --mtu 2048 -a" \
"$P_CLI dtls=1 hs_timeout=250-60000" \
"$P_CLI dtls=1 hs_timeout=500-60000" \
0 \
-s "Extra-header:" \
-c "Extra-header:"
@ -5437,7 +5437,7 @@ not_with_valgrind # risk of non-mbedtls peer timing out
run_test "DTLS proxy: 3d, gnutls server, fragmentation" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$G_SRV -u --mtu 512" \
"$P_CLI dtls=1 hs_timeout=250-60000" \
"$P_CLI dtls=1 hs_timeout=500-60000" \
0 \
-s "Extra-header:" \
-c "Extra-header:"
@ -5448,7 +5448,7 @@ not_with_valgrind # risk of non-mbedtls peer timing out
run_test "DTLS proxy: 3d, gnutls server, fragmentation, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$G_SRV -u --mtu 512" \
"$P_CLI dtls=1 hs_timeout=250-60000 nbio=2" \
"$P_CLI dtls=1 hs_timeout=500-60000 nbio=2" \
0 \
-s "Extra-header:" \
-c "Extra-header:"