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 Schubertuse constant { 16*e0c4386eSCy Schubert REVERSE_ORDER_VERSIONS => 1, 17*e0c4386eSCy Schubert UNRECOGNISED_VERSIONS => 2, 18*e0c4386eSCy Schubert NO_EXTENSION => 3, 19*e0c4386eSCy Schubert EMPTY_EXTENSION => 4, 20*e0c4386eSCy Schubert TLS1_1_AND_1_0_ONLY => 5, 21*e0c4386eSCy Schubert WITH_TLS1_4 => 6, 22*e0c4386eSCy Schubert BAD_LEGACY_VERSION => 7 23*e0c4386eSCy Schubert}; 24*e0c4386eSCy Schubert 25*e0c4386eSCy Schubertmy $testtype; 26*e0c4386eSCy Schubert 27*e0c4386eSCy Schubertmy $test_name = "test_sslversions"; 28*e0c4386eSCy Schubertsetup($test_name); 29*e0c4386eSCy Schubert 30*e0c4386eSCy Schubertplan skip_all => "TLSProxy isn't usable on $^O" 31*e0c4386eSCy Schubert if $^O =~ /^(VMS)$/; 32*e0c4386eSCy Schubert 33*e0c4386eSCy Schubertplan skip_all => "$test_name needs the dynamic engine feature enabled" 34*e0c4386eSCy Schubert if disabled("engine") || disabled("dynamic-engine"); 35*e0c4386eSCy Schubert 36*e0c4386eSCy Schubertplan skip_all => "$test_name needs the sock feature enabled" 37*e0c4386eSCy Schubert if disabled("sock"); 38*e0c4386eSCy Schubert 39*e0c4386eSCy Schubertplan skip_all => "$test_name needs TLS1.3, TLS1.2 and TLS1.1 enabled" 40*e0c4386eSCy Schubert if disabled("tls1_3") 41*e0c4386eSCy Schubert || (disabled("ec") && disabled("dh")) 42*e0c4386eSCy Schubert || disabled("tls1_2") 43*e0c4386eSCy Schubert || disabled("tls1_1"); 44*e0c4386eSCy Schubert 45*e0c4386eSCy Schubert$ENV{OPENSSL_ia32cap} = '~0x200000200000000'; 46*e0c4386eSCy Schubert 47*e0c4386eSCy Schubertmy $proxy = TLSProxy::Proxy->new( 48*e0c4386eSCy Schubert undef, 49*e0c4386eSCy Schubert cmdstr(app(["openssl"]), display => 1), 50*e0c4386eSCy Schubert srctop_file("apps", "server.pem"), 51*e0c4386eSCy Schubert (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}) 52*e0c4386eSCy Schubert); 53*e0c4386eSCy Schubert 54*e0c4386eSCy Schubert#We're just testing various negative and unusual scenarios here. ssltest with 55*e0c4386eSCy Schubert#02-protocol-version.cnf should check all the various combinations of normal 56*e0c4386eSCy Schubert#version neg 57*e0c4386eSCy Schubert 58*e0c4386eSCy Schubert#Test 1: An empty supported_versions extension should not succeed 59*e0c4386eSCy Schubert$testtype = EMPTY_EXTENSION; 60*e0c4386eSCy Schubert$proxy->filter(\&modify_supported_versions_filter); 61*e0c4386eSCy Schubert$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; 62*e0c4386eSCy Schubertplan tests => 8; 63*e0c4386eSCy Schubertok(TLSProxy::Message->fail(), "Empty supported versions"); 64*e0c4386eSCy Schubert 65*e0c4386eSCy Schubert#Test 2: supported_versions extension with no recognised versions should not 66*e0c4386eSCy Schubert#succeed 67*e0c4386eSCy Schubert$proxy->clear(); 68*e0c4386eSCy Schubert$testtype = UNRECOGNISED_VERSIONS; 69*e0c4386eSCy Schubert$proxy->start(); 70*e0c4386eSCy Schubertok(TLSProxy::Message->fail(), "No recognised versions"); 71*e0c4386eSCy Schubert 72*e0c4386eSCy Schubert#Test 3: No supported versions extensions should succeed and select TLSv1.2 73*e0c4386eSCy Schubert$proxy->clear(); 74*e0c4386eSCy Schubert$testtype = NO_EXTENSION; 75*e0c4386eSCy Schubert$proxy->start(); 76*e0c4386eSCy Schubertmy $record = pop @{$proxy->record_list}; 77*e0c4386eSCy Schubertok(TLSProxy::Message->success() 78*e0c4386eSCy Schubert && $record->version() == TLSProxy::Record::VERS_TLS_1_2, 79*e0c4386eSCy Schubert "No supported versions extension"); 80*e0c4386eSCy Schubert 81*e0c4386eSCy Schubert#Test 4: No supported versions extensions should fail if only TLS1.3 available 82*e0c4386eSCy Schubert$proxy->clear(); 83*e0c4386eSCy Schubert$proxy->serverflags("-tls1_3"); 84*e0c4386eSCy Schubert$proxy->start(); 85*e0c4386eSCy Schubertok(TLSProxy::Message->fail(), "No supported versions extension (only TLS1.3)"); 86*e0c4386eSCy Schubert 87*e0c4386eSCy Schubert#Test 5: supported versions extension with best version last should succeed 88*e0c4386eSCy Schubert#and select TLSv1.3 89*e0c4386eSCy Schubert$proxy->clear(); 90*e0c4386eSCy Schubert$testtype = REVERSE_ORDER_VERSIONS; 91*e0c4386eSCy Schubert$proxy->start(); 92*e0c4386eSCy Schubert$record = pop @{$proxy->record_list}; 93*e0c4386eSCy Schubertok(TLSProxy::Message->success() 94*e0c4386eSCy Schubert && $record->version() == TLSProxy::Record::VERS_TLS_1_2 95*e0c4386eSCy Schubert && TLSProxy::Proxy->is_tls13(), 96*e0c4386eSCy Schubert "Reverse order versions"); 97*e0c4386eSCy Schubert 98*e0c4386eSCy Schubert#Test 6: no TLSv1.3 or TLSv1.2 version in supported versions extension, but 99*e0c4386eSCy Schubert#TLSv1.1 and TLSv1.0 are present. Should just use TLSv1.1 and succeed 100*e0c4386eSCy Schubert$proxy->clear(); 101*e0c4386eSCy Schubert$proxy->clientflags("-cipher DEFAULT:\@SECLEVEL=0"); 102*e0c4386eSCy Schubert$proxy->ciphers("AES128-SHA:\@SECLEVEL=0"); 103*e0c4386eSCy Schubert$testtype = TLS1_1_AND_1_0_ONLY; 104*e0c4386eSCy Schubert$proxy->start(); 105*e0c4386eSCy Schubert$record = pop @{$proxy->record_list}; 106*e0c4386eSCy Schubertok(TLSProxy::Message->success() 107*e0c4386eSCy Schubert && $record->version() == TLSProxy::Record::VERS_TLS_1_1, 108*e0c4386eSCy Schubert "TLS1.1 and TLS1.0 in supported versions extension only"); 109*e0c4386eSCy Schubert 110*e0c4386eSCy Schubert#Test 7: TLS1.4 and TLS1.3 in supported versions. Should succeed and use TLS1.3 111*e0c4386eSCy Schubert$proxy->clear(); 112*e0c4386eSCy Schubert$testtype = WITH_TLS1_4; 113*e0c4386eSCy Schubert$proxy->start(); 114*e0c4386eSCy Schubert$record = pop @{$proxy->record_list}; 115*e0c4386eSCy Schubertok(TLSProxy::Message->success() 116*e0c4386eSCy Schubert && $record->version() == TLSProxy::Record::VERS_TLS_1_2 117*e0c4386eSCy Schubert && TLSProxy::Proxy->is_tls13(), 118*e0c4386eSCy Schubert "TLS1.4 in supported versions extension"); 119*e0c4386eSCy Schubert 120*e0c4386eSCy Schubert#Test 8: Set the legacy version to SSLv3 with supported versions. Should fail 121*e0c4386eSCy Schubert$proxy->clear(); 122*e0c4386eSCy Schubert$testtype = BAD_LEGACY_VERSION; 123*e0c4386eSCy Schubert$proxy->start(); 124*e0c4386eSCy Schubertok(TLSProxy::Message->fail(), "Legacy version is SSLv3 with supported versions"); 125*e0c4386eSCy Schubert 126*e0c4386eSCy Schubertsub modify_supported_versions_filter 127*e0c4386eSCy Schubert{ 128*e0c4386eSCy Schubert my $proxy = shift; 129*e0c4386eSCy Schubert 130*e0c4386eSCy Schubert if ($proxy->flight == 1) { 131*e0c4386eSCy Schubert # Change the ServerRandom so that the downgrade sentinel doesn't cause 132*e0c4386eSCy Schubert # the connection to fail 133*e0c4386eSCy Schubert my $message = ${$proxy->message_list}[1]; 134*e0c4386eSCy Schubert return if (!defined $message); 135*e0c4386eSCy Schubert 136*e0c4386eSCy Schubert $message->random("\0"x32); 137*e0c4386eSCy Schubert $message->repack(); 138*e0c4386eSCy Schubert return; 139*e0c4386eSCy Schubert } 140*e0c4386eSCy Schubert 141*e0c4386eSCy Schubert # We're only interested in the initial ClientHello 142*e0c4386eSCy Schubert if ($proxy->flight != 0) { 143*e0c4386eSCy Schubert return; 144*e0c4386eSCy Schubert } 145*e0c4386eSCy Schubert 146*e0c4386eSCy Schubert foreach my $message (@{$proxy->message_list}) { 147*e0c4386eSCy Schubert if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) { 148*e0c4386eSCy Schubert my $ext; 149*e0c4386eSCy Schubert if ($testtype == REVERSE_ORDER_VERSIONS) { 150*e0c4386eSCy Schubert $ext = pack "C5", 151*e0c4386eSCy Schubert 0x04, # Length 152*e0c4386eSCy Schubert 0x03, 0x03, #TLSv1.2 153*e0c4386eSCy Schubert 0x03, 0x04; #TLSv1.3 154*e0c4386eSCy Schubert } elsif ($testtype == UNRECOGNISED_VERSIONS) { 155*e0c4386eSCy Schubert $ext = pack "C5", 156*e0c4386eSCy Schubert 0x04, # Length 157*e0c4386eSCy Schubert 0x04, 0x04, #Some unrecognised version 158*e0c4386eSCy Schubert 0x04, 0x03; #Another unrecognised version 159*e0c4386eSCy Schubert } elsif ($testtype == TLS1_1_AND_1_0_ONLY) { 160*e0c4386eSCy Schubert $ext = pack "C5", 161*e0c4386eSCy Schubert 0x04, # Length 162*e0c4386eSCy Schubert 0x03, 0x02, #TLSv1.1 163*e0c4386eSCy Schubert 0x03, 0x01; #TLSv1.0 164*e0c4386eSCy Schubert } elsif ($testtype == WITH_TLS1_4) { 165*e0c4386eSCy Schubert $ext = pack "C5", 166*e0c4386eSCy Schubert 0x04, # Length 167*e0c4386eSCy Schubert 0x03, 0x05, #TLSv1.4 168*e0c4386eSCy Schubert 0x03, 0x04; #TLSv1.3 169*e0c4386eSCy Schubert } 170*e0c4386eSCy Schubert if ($testtype == REVERSE_ORDER_VERSIONS 171*e0c4386eSCy Schubert || $testtype == UNRECOGNISED_VERSIONS 172*e0c4386eSCy Schubert || $testtype == TLS1_1_AND_1_0_ONLY 173*e0c4386eSCy Schubert || $testtype == WITH_TLS1_4) { 174*e0c4386eSCy Schubert $message->set_extension( 175*e0c4386eSCy Schubert TLSProxy::Message::EXT_SUPPORTED_VERSIONS, $ext); 176*e0c4386eSCy Schubert } elsif ($testtype == EMPTY_EXTENSION) { 177*e0c4386eSCy Schubert $message->set_extension( 178*e0c4386eSCy Schubert TLSProxy::Message::EXT_SUPPORTED_VERSIONS, ""); 179*e0c4386eSCy Schubert } elsif ($testtype == NO_EXTENSION) { 180*e0c4386eSCy Schubert $message->delete_extension( 181*e0c4386eSCy Schubert TLSProxy::Message::EXT_SUPPORTED_VERSIONS); 182*e0c4386eSCy Schubert } else { 183*e0c4386eSCy Schubert # BAD_LEGACY_VERSION 184*e0c4386eSCy Schubert $message->client_version(TLSProxy::Record::VERS_SSL_3_0); 185*e0c4386eSCy Schubert } 186*e0c4386eSCy Schubert 187*e0c4386eSCy Schubert $message->repack(); 188*e0c4386eSCy Schubert } 189*e0c4386eSCy Schubert } 190*e0c4386eSCy Schubert} 191