diff options
author | Matt Caswell <matt@openssl.org> | 2016-08-02 17:24:54 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2016-08-15 23:14:30 +0100 |
commit | a2a0c86bb0d602253d02ded2a848ed69e8cc425a (patch) | |
tree | 55052ad87615adcd3848bd0ff2abfc9c87d227dd /test/recipes | |
parent | a01c86a25198921c5b8adb45c9379088ace4e42e (diff) | |
download | openssl-a2a0c86bb0d602253d02ded2a848ed69e8cc425a.tar.gz |
Add some SSLv2 ClientHello tests
Test that we handle a TLS ClientHello in an SSLv2 record correctly.
Reviewed-by: Tim Hudson <tjh@openssl.org>
Diffstat (limited to 'test/recipes')
-rw-r--r-- | test/recipes/70-test_sslrecords.t | 198 |
1 files changed, 197 insertions, 1 deletions
diff --git a/test/recipes/70-test_sslrecords.t b/test/recipes/70-test_sslrecords.t index 0ae018a07d..8af236fa32 100644 --- a/test/recipes/70-test_sslrecords.t +++ b/test/recipes/70-test_sslrecords.t @@ -38,7 +38,7 @@ my $proxy = TLSProxy::Proxy->new( my $content_type = TLSProxy::Record::RT_APPLICATION_DATA; my $inject_recs_num = 1; $proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 4; +plan tests => 9; ok(TLSProxy::Message->fail(), "Out of context empty records test"); #Test 2: Injecting in context empty records should succeed @@ -62,6 +62,52 @@ $proxy->filter(\&add_frag_alert_filter); $proxy->start(); ok(!TLSProxy::Message->end(), "Fragmented alert records test"); +#Run some SSLv2 ClientHello tests + +use constant { + TLSV1_2_IN_SSLV2 => 0, + SSLV2_IN_SSLV2 => 1, + FRAGMENTED_IN_TLSV1_2 => 2, + FRAGMENTED_IN_SSLV2 => 3, + ALERT_BEFORE_SSLV2 => 4 +}; +#Test 5: Inject an SSLv2 style record format for a TLSv1.2 ClientHello +#my $sslv2testtype = TLSV1_2_IN_SSLV2; +my $sslv2testtype = TLSV1_2_IN_SSLV2; +$proxy->clear(); +$proxy->filter(\&add_sslv2_filter); +$proxy->start(); +ok(TLSProxy::Message->success(), "TLSv1.2 in SSLv2 ClientHello test"); + +#Test 6: Inject an SSLv2 style record format for an SSLv2 ClientHello. We don't +# support this so it should fail. We actually treat it as an unknown +# protocol so we don't even send an alert in this case. +$sslv2testtype = SSLV2_IN_SSLV2; +$proxy->clear(); +$proxy->start(); +ok(!TLSProxy::Message->end(), "SSLv2 in SSLv2 ClientHello test"); + +#Test 7: Sanity check ClientHello fragmentation. This isn't really an SSLv2 test +# at all, but it gives us confidence that Test 8 fails for the right +# reasons +$sslv2testtype = FRAGMENTED_IN_TLSV1_2; +$proxy->clear(); +$proxy->start(); +ok(TLSProxy::Message->success(), "Fragmented ClientHello in TLSv1.2 test"); + +#Test 8: Fragment a TLSv1.2 ClientHello across a TLS1.2 record; an SSLv2 +# record; and another TLS1.2 record. This isn't allowed so should fail +$sslv2testtype = FRAGMENTED_IN_SSLV2; +$proxy->clear(); +$proxy->start(); +ok(TLSProxy::Message->fail(), "Fragmented ClientHello in TLSv1.2/SSLv2 test"); + +#Test 9: Send a TLS warning alert before an SSLv2 ClientHello. This should +# fail because an SSLv2 ClientHello must be the first record. +$sslv2testtype = ALERT_BEFORE_SSLV2; +$proxy->clear(); +$proxy->start(); +ok(TLSProxy::Message->fail(), "Alert before SSLv2 ClientHello test"); sub add_empty_recs_filter { my $proxy = shift; @@ -79,6 +125,7 @@ sub add_empty_recs_filter 0, 0, 0, + 0, "", "" ); @@ -117,6 +164,7 @@ sub add_frag_alert_filter TLSProxy::Record::RT_ALERT, TLSProxy::Record::VERS_TLS_1_2, 1, + 0, 1, 1, $byte, @@ -131,6 +179,7 @@ sub add_frag_alert_filter TLSProxy::Record::RT_ALERT, TLSProxy::Record::VERS_TLS_1_2, 1, + 0, 1, 1, $byte, @@ -138,3 +187,150 @@ sub add_frag_alert_filter ); push @{$proxy->record_list}, $record; } + +sub add_sslv2_filter +{ + my $proxy = shift; + my $clienthello; + my $record; + + # We're only interested in the initial ClientHello + if ($proxy->flight != 0) { + return; + } + + # Ditch the real ClientHello - we're going to replace it with our own + shift @{$proxy->record_list}; + + if ($sslv2testtype == ALERT_BEFORE_SSLV2) { + my $alert = pack('CC', TLSProxy::Message::AL_LEVEL_FATAL, + TLSProxy::Message::AL_DESC_NO_RENEGOTIATION); + my $alertlen = length $alert; + $record = TLSProxy::Record->new( + 0, + TLSProxy::Record::RT_ALERT, + TLSProxy::Record::VERS_TLS_1_2, + $alertlen, + 0, + $alertlen, + $alertlen, + $alert, + $alert + ); + + push @{$proxy->record_list}, $record; + } + + if ($sslv2testtype == ALERT_BEFORE_SSLV2 + || $sslv2testtype == TLSV1_2_IN_SSLV2 + || $sslv2testtype == SSLV2_IN_SSLV2) { + # This is an SSLv2 format ClientHello + $clienthello = + pack "C44", + 0x01, # ClientHello + 0x03, 0x03, #TLSv1.2 + 0x00, 0x03, # Ciphersuites len + 0x00, 0x00, # Session id len + 0x00, 0x20, # Challenge len + 0x00, 0x00, 0x2f, #AES128-SHA + 0x01, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90, + 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56, + 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6; # Challenge + + if ($sslv2testtype == SSLV2_IN_SSLV2) { + # Set the version to "real" SSLv2 + vec($clienthello, 1, 8) = 0x00; + vec($clienthello, 2, 8) = 0x02; + } + + my $chlen = length $clienthello; + + $record = TLSProxy::Record->new( + 0, + TLSProxy::Record::RT_HANDSHAKE, + TLSProxy::Record::VERS_TLS_1_2, + $chlen, + 1, #SSLv2 + $chlen, + $chlen, + $clienthello, + $clienthello + ); + + push @{$proxy->record_list}, $record; + } else { + # For this test we're using a real TLS ClientHello + $clienthello = + pack "C49", + 0x01, # ClientHello + 0x00, 0x00, 0x2D, # Message length + 0x03, 0x03, # TLSv1.2 + 0x01, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90, + 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56, + 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, # Random + 0x00, # Session id len + 0x00, 0x04, # Ciphersuites len + 0x00, 0x2f, # AES128-SHA + 0x00, 0xff, # Empty reneg info SCSV + 0x01, # Compression methods len + 0x00, # Null compression + 0x00, 0x00; # Extensions len + + # Split this into 3: A TLS record; a SSLv2 record and a TLS record. + # We deliberately split the second record prior to the Challenge/Random + # and set the first byte of the random to 1. This makes the second SSLv2 + # record look like an SSLv2 ClientHello + my $frag1 = substr $clienthello, 0, 6; + my $frag2 = substr $clienthello, 6, 32; + my $frag3 = substr $clienthello, 38; + + my $fraglen = length $frag1; + $record = TLSProxy::Record->new( + 0, + TLSProxy::Record::RT_HANDSHAKE, + TLSProxy::Record::VERS_TLS_1_2, + $fraglen, + 0, + $fraglen, + $fraglen, + $frag1, + $frag1 + ); + push @{$proxy->record_list}, $record; + + $fraglen = length $frag2; + my $recvers; + if ($sslv2testtype == FRAGMENTED_IN_SSLV2) { + $recvers = 1; + } else { + $recvers = 0; + } + $record = TLSProxy::Record->new( + 0, + TLSProxy::Record::RT_HANDSHAKE, + TLSProxy::Record::VERS_TLS_1_2, + $fraglen, + $recvers, + $fraglen, + $fraglen, + $frag2, + $frag2 + ); + push @{$proxy->record_list}, $record; + + $fraglen = length $frag3; + $record = TLSProxy::Record->new( + 0, + TLSProxy::Record::RT_HANDSHAKE, + TLSProxy::Record::VERS_TLS_1_2, + $fraglen, + 0, + $fraglen, + $fraglen, + $frag3, + $frag3 + ); + push @{$proxy->record_list}, $record; + } + +} |