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