mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-12-22 19:15:36 +00:00
Merge pull request #3142 from mpg/fix-reconnect-2.16
[Backport 2.16] Improve testing of DTLS client hard reconnect
This commit is contained in:
commit
5e65619669
|
@ -4005,17 +4005,23 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
|
|||
|
||||
if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
|
||||
{
|
||||
int send_ret;
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) );
|
||||
MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
|
||||
ssl->out_buf, len );
|
||||
/* Don't check write errors as we can't do anything here.
|
||||
* If the error is permanent we'll catch it later,
|
||||
* if it's not, then hopefully it'll work next time. */
|
||||
(void) ssl->f_send( ssl->p_bio, ssl->out_buf, len );
|
||||
send_ret = ssl->f_send( ssl->p_bio, ssl->out_buf, len );
|
||||
MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", send_ret );
|
||||
(void) send_ret;
|
||||
|
||||
return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
|
||||
}
|
||||
|
||||
if( ret == 0 )
|
||||
{
|
||||
/* Got a valid cookie, partially reset context */
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) );
|
||||
if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret );
|
||||
|
|
|
@ -130,6 +130,7 @@ int main( void )
|
|||
" bad_ad=0/1 default: 0 (don't add bad ApplicationData)\n" \
|
||||
" protect_hvr=0/1 default: 0 (don't protect HelloVerifyRequest)\n" \
|
||||
" protect_len=%%d default: (don't protect packets of this size)\n" \
|
||||
" inject_clihlo=0/1 default: 0 (don't inject fake ClientHello)\n" \
|
||||
"\n" \
|
||||
" seed=%%d default: (use current time)\n" \
|
||||
USAGE_PACK \
|
||||
|
@ -162,6 +163,7 @@ static struct options
|
|||
int bad_ad; /* inject corrupted ApplicationData record */
|
||||
int protect_hvr; /* never drop or delay HelloVerifyRequest */
|
||||
int protect_len; /* never drop/delay packet of the given size*/
|
||||
int inject_clihlo; /* inject fake ClientHello after handshake */
|
||||
unsigned pack; /* merge packets into single datagram for
|
||||
* at most \c merge milliseconds if > 0 */
|
||||
unsigned int seed; /* seed for "random" events */
|
||||
|
@ -304,6 +306,12 @@ static void get_options( int argc, char *argv[] )
|
|||
if( opt.protect_len < 0 )
|
||||
exit_usage( p, q );
|
||||
}
|
||||
else if( strcmp( p, "inject_clihlo" ) == 0 )
|
||||
{
|
||||
opt.inject_clihlo = atoi( q );
|
||||
if( opt.inject_clihlo < 0 || opt.inject_clihlo > 1 )
|
||||
exit_usage( p, q );
|
||||
}
|
||||
else if( strcmp( p, "seed" ) == 0 )
|
||||
{
|
||||
opt.seed = atoi( q );
|
||||
|
@ -503,11 +511,41 @@ void print_packet( const packet *p, const char *why )
|
|||
fflush( stdout );
|
||||
}
|
||||
|
||||
/*
|
||||
* In order to test the server's behaviour when receiving a ClientHello after
|
||||
* the connection is established (this could be a hard reset from the client,
|
||||
* but the server must not drop the existing connection before establishing
|
||||
* client reachability, see RFC 6347 Section 4.2.8), we memorize the first
|
||||
* ClientHello we see (which can't have a cookie), then replay it after the
|
||||
* first ApplicationData record - then we're done.
|
||||
*
|
||||
* This is controlled by the inject_clihlo option.
|
||||
*
|
||||
* We want an explicit state and a place to store the packet.
|
||||
*/
|
||||
typedef enum {
|
||||
ICH_INIT, /* haven't seen the first ClientHello yet */
|
||||
ICH_CACHED, /* cached the initial ClientHello */
|
||||
ICH_INJECTED, /* ClientHello already injected, done */
|
||||
} inject_clihlo_state_t;
|
||||
|
||||
static inject_clihlo_state_t inject_clihlo_state;
|
||||
static packet initial_clihlo;
|
||||
|
||||
int send_packet( const packet *p, const char *why )
|
||||
{
|
||||
int ret;
|
||||
mbedtls_net_context *dst = p->dst;
|
||||
|
||||
/* save initial ClientHello? */
|
||||
if( opt.inject_clihlo != 0 &&
|
||||
inject_clihlo_state == ICH_INIT &&
|
||||
strcmp( p->type, "ClientHello" ) == 0 )
|
||||
{
|
||||
memcpy( &initial_clihlo, p, sizeof( packet ) );
|
||||
inject_clihlo_state = ICH_CACHED;
|
||||
}
|
||||
|
||||
/* insert corrupted ApplicationData record? */
|
||||
if( opt.bad_ad &&
|
||||
strcmp( p->type, "ApplicationData" ) == 0 )
|
||||
|
@ -553,6 +591,23 @@ int send_packet( const packet *p, const char *why )
|
|||
}
|
||||
}
|
||||
|
||||
/* Inject ClientHello after first ApplicationData */
|
||||
if( opt.inject_clihlo != 0 &&
|
||||
inject_clihlo_state == ICH_CACHED &&
|
||||
strcmp( p->type, "ApplicationData" ) == 0 )
|
||||
{
|
||||
print_packet( &initial_clihlo, "injected" );
|
||||
|
||||
if( ( ret = dispatch_data( dst, initial_clihlo.buf,
|
||||
initial_clihlo.len ) ) <= 0 )
|
||||
{
|
||||
mbedtls_printf( " ! dispatch returned %d\n", ret );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
inject_clihlo_state = ICH_INJECTED;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
|
|
@ -5759,8 +5759,8 @@ run_test "DTLS cookie: enabled, nbio" \
|
|||
|
||||
not_with_valgrind # spurious resend
|
||||
run_test "DTLS client reconnect from same port: reference" \
|
||||
"$P_SRV dtls=1 exchanges=2 read_timeout=1000" \
|
||||
"$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=500-1000" \
|
||||
"$P_SRV dtls=1 exchanges=2 read_timeout=20000 hs_timeout=10000-20000" \
|
||||
"$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=10000-20000" \
|
||||
0 \
|
||||
-C "resend" \
|
||||
-S "The operation timed out" \
|
||||
|
@ -5768,8 +5768,8 @@ run_test "DTLS client reconnect from same port: reference" \
|
|||
|
||||
not_with_valgrind # spurious resend
|
||||
run_test "DTLS client reconnect from same port: reconnect" \
|
||||
"$P_SRV dtls=1 exchanges=2 read_timeout=1000" \
|
||||
"$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=500-1000 reconnect_hard=1" \
|
||||
"$P_SRV dtls=1 exchanges=2 read_timeout=20000 hs_timeout=10000-20000" \
|
||||
"$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=10000-20000 reconnect_hard=1" \
|
||||
0 \
|
||||
-C "resend" \
|
||||
-S "The operation timed out" \
|
||||
|
@ -5798,6 +5798,14 @@ run_test "DTLS client reconnect from same port: no cookies" \
|
|||
-s "The operation timed out" \
|
||||
-S "Client initiated reconnection from same port"
|
||||
|
||||
run_test "DTLS client reconnect from same port: attacker-injected" \
|
||||
-p "$P_PXY inject_clihlo=1" \
|
||||
"$P_SRV dtls=1 exchanges=2 debug_level=1" \
|
||||
"$P_CLI dtls=1 exchanges=2" \
|
||||
0 \
|
||||
-s "possible client reconnect from the same port" \
|
||||
-S "Client initiated reconnection from same port"
|
||||
|
||||
# Tests for various cases of client authentication with DTLS
|
||||
# (focused on handshake flows and message parsing)
|
||||
|
||||
|
@ -6867,8 +6875,8 @@ run_test "DTLS fragmenting: 3d, openssl client, DTLS 1.0" \
|
|||
not_with_valgrind # spurious resend due to timeout
|
||||
run_test "DTLS proxy: reference" \
|
||||
-p "$P_PXY" \
|
||||
"$P_SRV dtls=1 debug_level=2" \
|
||||
"$P_CLI dtls=1 debug_level=2" \
|
||||
"$P_SRV dtls=1 debug_level=2 hs_timeout=10000-20000" \
|
||||
"$P_CLI dtls=1 debug_level=2 hs_timeout=10000-20000" \
|
||||
0 \
|
||||
-C "replayed record" \
|
||||
-S "replayed record" \
|
||||
|
@ -6883,8 +6891,8 @@ run_test "DTLS proxy: reference" \
|
|||
not_with_valgrind # spurious resend due to timeout
|
||||
run_test "DTLS proxy: duplicate every packet" \
|
||||
-p "$P_PXY duplicate=1" \
|
||||
"$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
|
||||
"$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
|
||||
"$P_SRV dtls=1 dgram_packing=0 debug_level=2 hs_timeout=10000-20000" \
|
||||
"$P_CLI dtls=1 dgram_packing=0 debug_level=2 hs_timeout=10000-20000" \
|
||||
0 \
|
||||
-c "replayed record" \
|
||||
-s "replayed record" \
|
||||
|
|
Loading…
Reference in a new issue