1*e0c4386eSCy Schubert#! /usr/bin/env perl 2*e0c4386eSCy Schubert# Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. 3*e0c4386eSCy Schubert# 4*e0c4386eSCy Schubert# Licensed under the Apache License 2.0 (the "License"). You may not use 5*e0c4386eSCy Schubert# this file except in compliance with the License. You can obtain a copy 6*e0c4386eSCy Schubert# in the file LICENSE in the source distribution or at 7*e0c4386eSCy Schubert# https://www.openssl.org/source/license.html 8*e0c4386eSCy Schubert 9*e0c4386eSCy Schubertuse strict; 10*e0c4386eSCy Schubertuse OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/; 11*e0c4386eSCy Schubertuse OpenSSL::Test::Utils; 12*e0c4386eSCy Schubertuse TLSProxy::Proxy; 13*e0c4386eSCy Schubertuse File::Temp qw(tempfile); 14*e0c4386eSCy Schubert 15*e0c4386eSCy Schubertmy $test_name = "test_tlsextms"; 16*e0c4386eSCy Schubertsetup($test_name); 17*e0c4386eSCy Schubert 18*e0c4386eSCy Schubertplan skip_all => "TLSProxy isn't usable on $^O" 19*e0c4386eSCy Schubert if $^O =~ /^(VMS)$/; 20*e0c4386eSCy Schubert 21*e0c4386eSCy Schubertplan skip_all => "$test_name needs the dynamic engine feature enabled" 22*e0c4386eSCy Schubert if disabled("engine") || disabled("dynamic-engine"); 23*e0c4386eSCy Schubert 24*e0c4386eSCy Schubertplan skip_all => "$test_name needs the sock feature enabled" 25*e0c4386eSCy Schubert if disabled("sock"); 26*e0c4386eSCy Schubert 27*e0c4386eSCy Schubertplan skip_all => "$test_name needs TLSv1.0, TLSv1.1 or TLSv1.2 enabled" 28*e0c4386eSCy Schubert if disabled("tls1") && disabled("tls1_1") && disabled("tls1_2"); 29*e0c4386eSCy Schubert 30*e0c4386eSCy Schubert$ENV{OPENSSL_ia32cap} = '~0x200000200000000'; 31*e0c4386eSCy Schubert 32*e0c4386eSCy Schubertsub checkmessages($$$$$); 33*e0c4386eSCy Schubertsub setrmextms($$); 34*e0c4386eSCy Schubertsub clearall(); 35*e0c4386eSCy Schubert 36*e0c4386eSCy Schubertmy $crmextms = 0; 37*e0c4386eSCy Schubertmy $srmextms = 0; 38*e0c4386eSCy Schubertmy $cextms = 0; 39*e0c4386eSCy Schubertmy $sextms = 0; 40*e0c4386eSCy Schubertmy $fullhand = 0; 41*e0c4386eSCy Schubert 42*e0c4386eSCy Schubertmy $proxy = TLSProxy::Proxy->new( 43*e0c4386eSCy Schubert \&extms_filter, 44*e0c4386eSCy Schubert cmdstr(app(["openssl"]), display => 1), 45*e0c4386eSCy Schubert srctop_file("apps", "server.pem"), 46*e0c4386eSCy Schubert (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}) 47*e0c4386eSCy Schubert); 48*e0c4386eSCy Schubert 49*e0c4386eSCy Schubert#Note that EXTMS is only relevant for <TLS1.3 50*e0c4386eSCy Schubert 51*e0c4386eSCy Schubert#Test 1: By default server and client should send extended master secret 52*e0c4386eSCy Schubert# extension. 53*e0c4386eSCy Schubert#Expected result: ClientHello extension seen; ServerHello extension seen 54*e0c4386eSCy Schubert# Full handshake 55*e0c4386eSCy Schubert 56*e0c4386eSCy Schubertsetrmextms(0, 0); 57*e0c4386eSCy Schubert$proxy->clientflags("-no_tls1_3"); 58*e0c4386eSCy Schubert$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; 59*e0c4386eSCy Schubertplan tests => 10; 60*e0c4386eSCy Schubertcheckmessages(1, "Default extended master secret test", 1, 1, 1); 61*e0c4386eSCy Schubert 62*e0c4386eSCy Schubert#Test 2: If client omits extended master secret extension, server should too. 63*e0c4386eSCy Schubert#Expected result: ClientHello extension not seen; ServerHello extension not seen 64*e0c4386eSCy Schubert# Full handshake 65*e0c4386eSCy Schubert 66*e0c4386eSCy Schubertclearall(); 67*e0c4386eSCy Schubertsetrmextms(1, 0); 68*e0c4386eSCy Schubert$proxy->clientflags("-no_tls1_3"); 69*e0c4386eSCy Schubert$proxy->start(); 70*e0c4386eSCy Schubertcheckmessages(2, "No client extension extended master secret test", 0, 0, 1); 71*e0c4386eSCy Schubert 72*e0c4386eSCy Schubert# Test 3: same as 1 but with session tickets disabled. 73*e0c4386eSCy Schubert# Expected result: same as test 1. 74*e0c4386eSCy Schubert 75*e0c4386eSCy Schubertclearall(); 76*e0c4386eSCy Schubert$proxy->clientflags("-no_ticket -no_tls1_3"); 77*e0c4386eSCy Schubertsetrmextms(0, 0); 78*e0c4386eSCy Schubert$proxy->start(); 79*e0c4386eSCy Schubertcheckmessages(3, "No ticket extended master secret test", 1, 1, 1); 80*e0c4386eSCy Schubert 81*e0c4386eSCy Schubert# Test 4: same as 2 but with session tickets disabled. 82*e0c4386eSCy Schubert# Expected result: same as test 2. 83*e0c4386eSCy Schubert 84*e0c4386eSCy Schubertclearall(); 85*e0c4386eSCy Schubert$proxy->clientflags("-no_ticket -no_tls1_3"); 86*e0c4386eSCy Schubertsetrmextms(1, 0); 87*e0c4386eSCy Schubert$proxy->start(); 88*e0c4386eSCy Schubertcheckmessages(4, "No ticket, no client extension extended master secret test", 0, 0, 1); 89*e0c4386eSCy Schubert 90*e0c4386eSCy Schubert#Test 5: Session resumption extended master secret test 91*e0c4386eSCy Schubert# 92*e0c4386eSCy Schubert#Expected result: ClientHello extension seen; ServerHello extension seen 93*e0c4386eSCy Schubert# Abbreviated handshake 94*e0c4386eSCy Schubert 95*e0c4386eSCy Schubertclearall(); 96*e0c4386eSCy Schubertsetrmextms(0, 0); 97*e0c4386eSCy Schubert(undef, my $session) = tempfile(); 98*e0c4386eSCy Schubert$proxy->serverconnects(2); 99*e0c4386eSCy Schubert$proxy->clientflags("-no_tls1_3 -sess_out ".$session); 100*e0c4386eSCy Schubert$proxy->start(); 101*e0c4386eSCy Schubert$proxy->clearClient(); 102*e0c4386eSCy Schubert$proxy->clientflags("-no_tls1_3 -sess_in ".$session); 103*e0c4386eSCy Schubert$proxy->clientstart(); 104*e0c4386eSCy Schubertcheckmessages(5, "Session resumption extended master secret test", 1, 1, 0); 105*e0c4386eSCy Schubertunlink $session; 106*e0c4386eSCy Schubert 107*e0c4386eSCy Schubert#Test 6: Session resumption extended master secret test original session 108*e0c4386eSCy Schubert# omits extension. Server must not resume session. 109*e0c4386eSCy Schubert#Expected result: ClientHello extension seen; ServerHello extension seen 110*e0c4386eSCy Schubert# Full handshake 111*e0c4386eSCy Schubert 112*e0c4386eSCy Schubertclearall(); 113*e0c4386eSCy Schubertsetrmextms(1, 0); 114*e0c4386eSCy Schubert(undef, $session) = tempfile(); 115*e0c4386eSCy Schubert$proxy->serverconnects(2); 116*e0c4386eSCy Schubert$proxy->clientflags("-no_tls1_3 -sess_out ".$session); 117*e0c4386eSCy Schubert$proxy->start(); 118*e0c4386eSCy Schubert$proxy->clearClient(); 119*e0c4386eSCy Schubert$proxy->clientflags("-no_tls1_3 -sess_in ".$session); 120*e0c4386eSCy Schubertsetrmextms(0, 0); 121*e0c4386eSCy Schubert$proxy->clientstart(); 122*e0c4386eSCy Schubertcheckmessages(6, "Session resumption extended master secret test", 1, 1, 1); 123*e0c4386eSCy Schubertunlink $session; 124*e0c4386eSCy Schubert 125*e0c4386eSCy Schubert#Test 7: Session resumption extended master secret test resumed session 126*e0c4386eSCy Schubert# omits client extension. Server must abort connection. 127*e0c4386eSCy Schubert#Expected result: aborted connection. 128*e0c4386eSCy Schubert 129*e0c4386eSCy Schubertclearall(); 130*e0c4386eSCy Schubertsetrmextms(0, 0); 131*e0c4386eSCy Schubert(undef, $session) = tempfile(); 132*e0c4386eSCy Schubert$proxy->serverconnects(2); 133*e0c4386eSCy Schubert$proxy->clientflags("-no_tls1_3 -sess_out ".$session); 134*e0c4386eSCy Schubert$proxy->start(); 135*e0c4386eSCy Schubert$proxy->clearClient(); 136*e0c4386eSCy Schubert$proxy->clientflags("-no_tls1_3 -sess_in ".$session); 137*e0c4386eSCy Schubertsetrmextms(1, 0); 138*e0c4386eSCy Schubert$proxy->clientstart(); 139*e0c4386eSCy Schubertok(TLSProxy::Message->fail(), "Client inconsistent session resumption"); 140*e0c4386eSCy Schubertunlink $session; 141*e0c4386eSCy Schubert 142*e0c4386eSCy Schubert#Test 8: Session resumption extended master secret test resumed session 143*e0c4386eSCy Schubert# omits server extension. Client must abort connection. 144*e0c4386eSCy Schubert#Expected result: aborted connection. 145*e0c4386eSCy Schubert 146*e0c4386eSCy Schubertclearall(); 147*e0c4386eSCy Schubertsetrmextms(0, 0); 148*e0c4386eSCy Schubert(undef, $session) = tempfile(); 149*e0c4386eSCy Schubert$proxy->serverconnects(2); 150*e0c4386eSCy Schubert$proxy->clientflags("-no_tls1_3 -sess_out ".$session); 151*e0c4386eSCy Schubert$proxy->start(); 152*e0c4386eSCy Schubert$proxy->clearClient(); 153*e0c4386eSCy Schubert$proxy->clientflags("-no_tls1_3 -sess_in ".$session); 154*e0c4386eSCy Schubertsetrmextms(0, 1); 155*e0c4386eSCy Schubert$proxy->clientstart(); 156*e0c4386eSCy Schubertok(TLSProxy::Message->fail(), "Server inconsistent session resumption 1"); 157*e0c4386eSCy Schubertunlink $session; 158*e0c4386eSCy Schubert 159*e0c4386eSCy Schubert#Test 9: Session resumption extended master secret test initial session 160*e0c4386eSCy Schubert# omits server extension. Client must abort connection. 161*e0c4386eSCy Schubert#Expected result: aborted connection. 162*e0c4386eSCy Schubert 163*e0c4386eSCy Schubertclearall(); 164*e0c4386eSCy Schubertsetrmextms(0, 1); 165*e0c4386eSCy Schubert(undef, $session) = tempfile(); 166*e0c4386eSCy Schubert$proxy->serverconnects(2); 167*e0c4386eSCy Schubert$proxy->clientflags("-no_tls1_3 -sess_out ".$session); 168*e0c4386eSCy Schubert$proxy->start(); 169*e0c4386eSCy Schubert$proxy->clearClient(); 170*e0c4386eSCy Schubert$proxy->clientflags("-no_tls1_3 -sess_in ".$session); 171*e0c4386eSCy Schubertsetrmextms(0, 0); 172*e0c4386eSCy Schubert$proxy->clientstart(); 173*e0c4386eSCy Schubertok(TLSProxy::Message->fail(), "Server inconsistent session resumption 2"); 174*e0c4386eSCy Schubertunlink $session; 175*e0c4386eSCy Schubert 176*e0c4386eSCy SchubertSKIP: { 177*e0c4386eSCy Schubert skip "TLS 1.3 disabled", 1 178*e0c4386eSCy Schubert if disabled("tls1_3") || (disabled("ec") && disabled("dh")); 179*e0c4386eSCy Schubert 180*e0c4386eSCy Schubert #Test 10: In TLS1.3 we should not negotiate extended master secret 181*e0c4386eSCy Schubert #Expected result: ClientHello extension seen; ServerHello extension not seen 182*e0c4386eSCy Schubert # TLS1.3 handshake (will appear as abbreviated handshake 183*e0c4386eSCy Schubert # because of no CKE message) 184*e0c4386eSCy Schubert clearall(); 185*e0c4386eSCy Schubert setrmextms(0, 0); 186*e0c4386eSCy Schubert $proxy->start(); 187*e0c4386eSCy Schubert checkmessages(10, "TLS1.3 extended master secret test", 1, 0, 0); 188*e0c4386eSCy Schubert} 189*e0c4386eSCy Schubert 190*e0c4386eSCy Schubert 191*e0c4386eSCy Schubertsub extms_filter 192*e0c4386eSCy Schubert{ 193*e0c4386eSCy Schubert my $proxy = shift; 194*e0c4386eSCy Schubert 195*e0c4386eSCy Schubert foreach my $message (@{$proxy->message_list}) { 196*e0c4386eSCy Schubert if ($crmextms && $message->mt == TLSProxy::Message::MT_CLIENT_HELLO) { 197*e0c4386eSCy Schubert $message->delete_extension(TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET); 198*e0c4386eSCy Schubert $message->repack(); 199*e0c4386eSCy Schubert } 200*e0c4386eSCy Schubert if ($srmextms && $message->mt == TLSProxy::Message::MT_SERVER_HELLO) { 201*e0c4386eSCy Schubert $message->delete_extension(TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET); 202*e0c4386eSCy Schubert $message->repack(); 203*e0c4386eSCy Schubert } 204*e0c4386eSCy Schubert } 205*e0c4386eSCy Schubert} 206*e0c4386eSCy Schubert 207*e0c4386eSCy Schubertsub checkmessages($$$$$) 208*e0c4386eSCy Schubert{ 209*e0c4386eSCy Schubert my ($testno, $testname, $testcextms, $testsextms, $testhand) = @_; 210*e0c4386eSCy Schubert 211*e0c4386eSCy Schubert subtest $testname => sub { 212*e0c4386eSCy Schubert 213*e0c4386eSCy Schubert foreach my $message (@{$proxy->message_list}) { 214*e0c4386eSCy Schubert if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO 215*e0c4386eSCy Schubert || $message->mt == TLSProxy::Message::MT_SERVER_HELLO) { 216*e0c4386eSCy Schubert #Get the extensions data 217*e0c4386eSCy Schubert my %extensions = %{$message->extension_data}; 218*e0c4386eSCy Schubert if (defined 219*e0c4386eSCy Schubert $extensions{TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET}) { 220*e0c4386eSCy Schubert if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) { 221*e0c4386eSCy Schubert $cextms = 1; 222*e0c4386eSCy Schubert } else { 223*e0c4386eSCy Schubert $sextms = 1; 224*e0c4386eSCy Schubert } 225*e0c4386eSCy Schubert } 226*e0c4386eSCy Schubert } elsif ($message->mt == TLSProxy::Message::MT_CLIENT_KEY_EXCHANGE) { 227*e0c4386eSCy Schubert #Must be doing a full handshake 228*e0c4386eSCy Schubert $fullhand = 1; 229*e0c4386eSCy Schubert } 230*e0c4386eSCy Schubert } 231*e0c4386eSCy Schubert 232*e0c4386eSCy Schubert plan tests => 4; 233*e0c4386eSCy Schubert 234*e0c4386eSCy Schubert ok(TLSProxy::Message->success, "Handshake"); 235*e0c4386eSCy Schubert 236*e0c4386eSCy Schubert ok($testcextms == $cextms, 237*e0c4386eSCy Schubert "ClientHello extension extended master secret check"); 238*e0c4386eSCy Schubert ok($testsextms == $sextms, 239*e0c4386eSCy Schubert "ServerHello extension extended master secret check"); 240*e0c4386eSCy Schubert ok($testhand == $fullhand, 241*e0c4386eSCy Schubert "Extended master secret full handshake check"); 242*e0c4386eSCy Schubert 243*e0c4386eSCy Schubert } 244*e0c4386eSCy Schubert} 245*e0c4386eSCy Schubert 246*e0c4386eSCy Schubertsub setrmextms($$) 247*e0c4386eSCy Schubert{ 248*e0c4386eSCy Schubert ($crmextms, $srmextms) = @_; 249*e0c4386eSCy Schubert} 250*e0c4386eSCy Schubert 251*e0c4386eSCy Schubertsub clearall() 252*e0c4386eSCy Schubert{ 253*e0c4386eSCy Schubert $cextms = 0; 254*e0c4386eSCy Schubert $sextms = 0; 255*e0c4386eSCy Schubert $fullhand = 0; 256*e0c4386eSCy Schubert $proxy->clear(); 257*e0c4386eSCy Schubert} 258