Add negative test for hard reconnect cookie check
The server must check client reachability (we chose to do that by checking a cookie) before destroying the existing association (RFC 6347 section 4.2.8). Let's make sure we do, by having a proxy-in-the-middle inject a ClientHello - the server should notice, but not destroy the connection. Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
This commit is contained in:
parent
824655c837
commit
baad2de6d8
2 changed files with 62 additions and 0 deletions
|
@ -133,6 +133,7 @@ int main( void )
|
|||
" modifying CID in first instance of the packet.\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 \
|
||||
|
@ -166,6 +167,7 @@ static struct options
|
|||
unsigned bad_cid; /* inject corrupted CID 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 */
|
||||
|
@ -314,6 +316,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 );
|
||||
|
@ -523,11 +531,40 @@ 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.
|
||||
*/
|
||||
static 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;
|
||||
|
||||
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 CID record? */
|
||||
if( opt.bad_cid != 0 &&
|
||||
strcmp( p->type, "CID" ) == 0 &&
|
||||
|
@ -592,6 +629,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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -7318,6 +7318,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)
|
||||
|
||||
|
|
Loading…
Reference in a new issue