From d542790b0767535bce903d9f6ad314357484d67f Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Thu, 2 Feb 2017 16:06:50 +0000 Subject: [PATCH] Update the kex modes tests to check various HRR scenarios Make sure we get an HRR in the right circumstances based on kex mode. Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/2341) --- test/recipes/70-test_tls13kexmodes.t | 90 +++++++++++++++++++++++++++- test/testlib/checkhandshake.pm | 29 ++++++++- 2 files changed, 113 insertions(+), 6 deletions(-) diff --git a/test/recipes/70-test_tls13kexmodes.t b/test/recipes/70-test_tls13kexmodes.t index 93835194b0..07020c686e 100755 --- a/test/recipes/70-test_tls13kexmodes.t +++ b/test/recipes/70-test_tls13kexmodes.t @@ -35,6 +35,10 @@ $ENV{CTLOG_FILE} = srctop_file("test", "ct", "log_list.conf"); @handmessages = ( [TLSProxy::Message::MT_CLIENT_HELLO, checkhandshake::ALL_HANDSHAKES], + [TLSProxy::Message::MT_HELLO_RETRY_REQUEST, + checkhandshake::HRR_HANDSHAKE | checkhandshake::HRR_RESUME_HANDSHAKE], + [TLSProxy::Message::MT_CLIENT_HELLO, + checkhandshake::HRR_HANDSHAKE | checkhandshake::HRR_RESUME_HANDSHAKE], [TLSProxy::Message::MT_SERVER_HELLO, checkhandshake::ALL_HANDSHAKES], [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, @@ -42,9 +46,9 @@ $ENV{CTLOG_FILE} = srctop_file("test", "ct", "log_list.conf"); [TLSProxy::Message::MT_CERTIFICATE_REQUEST, checkhandshake::CLIENT_AUTH_HANDSHAKE], [TLSProxy::Message::MT_CERTIFICATE, - checkhandshake::ALL_HANDSHAKES & ~checkhandshake::RESUME_HANDSHAKE], + checkhandshake::ALL_HANDSHAKES & ~(checkhandshake::RESUME_HANDSHAKE | checkhandshake::HRR_RESUME_HANDSHAKE)], [TLSProxy::Message::MT_CERTIFICATE_VERIFY, - checkhandshake::ALL_HANDSHAKES & ~checkhandshake::RESUME_HANDSHAKE], + checkhandshake::ALL_HANDSHAKES & ~(checkhandshake::RESUME_HANDSHAKE | checkhandshake::HRR_RESUME_HANDSHAKE)], [TLSProxy::Message::MT_FINISHED, checkhandshake::ALL_HANDSHAKES], [TLSProxy::Message::MT_CERTIFICATE, @@ -86,6 +90,30 @@ $ENV{CTLOG_FILE} = srctop_file("test", "ct", "log_list.conf"); [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK, checkhandshake::PSK_CLI_EXTENSION], + [TLSProxy::Message::MT_HELLO_RETRY_REQUEST, TLSProxy::Message::EXT_KEY_SHARE, + checkhandshake::KEY_SHARE_HRR_EXTENSION], + + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME, + checkhandshake::SERVER_NAME_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST, + checkhandshake::STATUS_REQUEST_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN, + checkhandshake::ALPN_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT, + checkhandshake::SCT_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES, + checkhandshake::PSK_KEX_MODES_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK, + checkhandshake::PSK_CLI_EXTENSION], + [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE, checkhandshake::KEY_SHARE_SRV_EXTENSION], [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_PSK, @@ -117,7 +145,7 @@ my $proxy = TLSProxy::Proxy->new( $proxy->clientflags("-sess_out ".$session); $proxy->sessionfile($session); $proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 7; +plan tests => 11; ok(TLSProxy::Message->success(), "Initial connection"); #Test 2: Attempt a resume with no kex modes extension. Should not resume @@ -192,6 +220,62 @@ checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, | checkhandshake::PSK_SRV_EXTENSION, "Resume with non-dhe kex mode"); +#Test 8: Attempt a resume with both non-dhe and dhe kex mode, but unacceptable +# initial key_share. Should resume with a key_share following an HRR +$proxy->clear(); +$proxy->clientflags("-sess_in ".$session); +$proxy->serverflags("-curves P-256"); +$testtype = BOTH_KEX_MODES; +$proxy->start(); +checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::PSK_KEX_MODES_EXTENSION + | checkhandshake::KEY_SHARE_SRV_EXTENSION + | checkhandshake::KEY_SHARE_HRR_EXTENSION + | checkhandshake::PSK_CLI_EXTENSION + | checkhandshake::PSK_SRV_EXTENSION, + "Resume with both kex modes and HRR"); + +#Test 9: Attempt a resume with dhe kex mode only and an unnacceptable initial +# key_share. Should resume with a key_share following an HRR +$proxy->clear(); +$proxy->clientflags("-sess_in ".$session); +$proxy->serverflags("-curves P-256"); +$testtype = DHE_KEX_MODE_ONLY; +$proxy->start(); +checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::PSK_KEX_MODES_EXTENSION + | checkhandshake::KEY_SHARE_SRV_EXTENSION + | checkhandshake::KEY_SHARE_HRR_EXTENSION + | checkhandshake::PSK_CLI_EXTENSION + | checkhandshake::PSK_SRV_EXTENSION, + "Resume with dhe kex mode and HRR"); + +#Test 10: Attempt a resume with both non-dhe and dhe kex mode, unacceptable +# initial key_share and no overlapping groups. Should resume without a +# key_share +$proxy->clear(); +$proxy->clientflags("-curves P-384 -sess_in ".$session); +$proxy->serverflags("-curves P-256"); +$testtype = BOTH_KEX_MODES; +$proxy->start(); +checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::PSK_KEX_MODES_EXTENSION + | checkhandshake::PSK_CLI_EXTENSION + | checkhandshake::PSK_SRV_EXTENSION, + "Resume with both kex modes, no overlapping groups"); + +#Test 11: Attempt a resume with dhe kex mode only, unacceptable +# initial key_share and no overlapping groups. Should fail +$proxy->clear(); +$proxy->clientflags("-curves P-384 -sess_in ".$session); +$proxy->serverflags("-curves P-256"); +$testtype = DHE_KEX_MODE_ONLY; +$proxy->start(); +ok(TLSProxy::Message->fail(), "Resume with dhe kex mode, no overlapping groups"); + unlink $session; sub modify_kex_modes_filter diff --git a/test/testlib/checkhandshake.pm b/test/testlib/checkhandshake.pm index a023f5ec45..43efe81327 100644 --- a/test/testlib/checkhandshake.pm +++ b/test/testlib/checkhandshake.pm @@ -24,8 +24,10 @@ use constant { RENEG_HANDSHAKE => 16, NPN_HANDSHAKE => 32, EC_HANDSHAKE => 64, + HRR_HANDSHAKE => 128, + HRR_RESUME_HANDSHAKE => 256, - ALL_HANDSHAKES => 127 + ALL_HANDSHAKES => 511 }; use constant { @@ -49,7 +51,8 @@ use constant { PSK_CLI_EXTENSION => 0x00008000, PSK_SRV_EXTENSION => 0x00010000, KEY_SHARE_SRV_EXTENSION => 0x00020000, - PSK_KEX_MODES_EXTENSION => 0x00040000 + PSK_KEX_MODES_EXTENSION => 0x00040000, + KEY_SHARE_HRR_EXTENSION => 0x00080000 }; our @handmessages = (); @@ -68,6 +71,7 @@ sub checkhandshake($$$$) #First count the number of tests my $nextmess = 0; my $message = undef; + my $chnum = 0; for ($numtests = 0; $handmessages[$loop][1] != 0; $loop++) { next if (($handmessages[$loop][1] & $handtype) == 0); if (scalar @{$proxy->message_list} > $nextmess) { @@ -79,7 +83,10 @@ sub checkhandshake($$$$) $numtests++; next if (!defined $message); + $chnum = 1 if $message->mt() != TLSProxy::Message::MT_CLIENT_HELLO + && TLSProxy::Proxy::is_tls13(); next if ($message->mt() != TLSProxy::Message::MT_CLIENT_HELLO + && $message->mt() != TLSProxy::Message::MT_HELLO_RETRY_REQUEST && $message->mt() != TLSProxy::Message::MT_SERVER_HELLO && $message->mt() != TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS @@ -88,9 +95,14 @@ sub checkhandshake($$$$) next if $message->mt() == TLSProxy::Message::MT_CERTIFICATE && !TLSProxy::Proxy::is_tls13(); + my $extchnum = 0; for (my $extloop = 0; $extensions[$extloop][2] != 0; $extloop++) { + $extchnum = 1 if $extensions[$extloop][0] != TLSProxy::Message::MT_CLIENT_HELLO + && TLSProxy::Proxy::is_tls13(); + next if $extensions[$extloop][0] == TLSProxy::Message::MT_CLIENT_HELLO + && $extchnum != $chnum; next if ($message->mt() != $extensions[$extloop][0]); $numtests++; } @@ -101,6 +113,7 @@ sub checkhandshake($$$$) $nextmess = 0; $message = undef; + $chnum = 0; for ($loop = 0; $handmessages[$loop][1] != 0; $loop++) { next if (($handmessages[$loop][1] & $handtype) == 0); if (scalar @{$proxy->message_list} > $nextmess) { @@ -118,8 +131,11 @@ sub checkhandshake($$$$) "Message type check. Got ".$message->mt .", expected ".$handmessages[$loop][0]); } + $chnum = 1 if $message->mt() != TLSProxy::Message::MT_CLIENT_HELLO + && TLSProxy::Proxy::is_tls13(); next if ($message->mt() != TLSProxy::Message::MT_CLIENT_HELLO + && $message->mt() != TLSProxy::Message::MT_HELLO_RETRY_REQUEST && $message->mt() != TLSProxy::Message::MT_SERVER_HELLO && $message->mt() != TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS @@ -136,9 +152,16 @@ sub checkhandshake($$$$) } #Now check that we saw the extensions we expected my $msgexts = $message->extension_data(); - + my $extchnum = 0; for (my $extloop = 0, $extcount = 0; $extensions[$extloop][2] != 0; $extloop++) { + #In TLSv1.3 we can have two ClientHellos if there has been a + #HelloRetryRequest, and they may have different extensions. Skip + #if these are extensions for a different ClientHello + $extchnum = 1 if $extensions[$extloop][0] != TLSProxy::Message::MT_CLIENT_HELLO + && TLSProxy::Proxy::is_tls13(); + next if $extensions[$extloop][0] == TLSProxy::Message::MT_CLIENT_HELLO + && $extchnum != $chnum; next if ($message->mt() != $extensions[$extloop][0]); ok (($extensions[$extloop][2] & $exttype) == 0 || defined ($msgexts->{$extensions[$extloop][1]}), -- 2.34.1