1#! /usr/bin/env perl 2# Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. 3# 4# Licensed under the Apache License 2.0 (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; 13 14my $test_name = "test_sslvertol"; 15setup($test_name); 16 17plan skip_all => "TLSProxy isn't usable on $^O" 18 if $^O =~ /^(VMS)$/; 19 20plan skip_all => "$test_name needs the dynamic engine feature enabled" 21 if disabled("engine") || disabled("dynamic-engine"); 22 23plan skip_all => "$test_name needs the sock feature enabled" 24 if disabled("sock"); 25 26plan skip_all => "$test_name needs TLS enabled" 27 if alldisabled(available_protocols("tls")); 28 29my $proxy = TLSProxy::Proxy->new( 30 \&vers_tolerance_filter, 31 cmdstr(app(["openssl"]), display => 1), 32 srctop_file("apps", "server.pem"), 33 (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}) 34); 35 36my @available_tls_versions = (); 37foreach (available_protocols("tls")) { 38 unless (disabled($_)) { 39 note("Checking enabled protocol $_"); 40 m|^([a-z]+)(\d)(_\d)?|; 41 my $versionname; 42 if (defined $3) { 43 $versionname = 'TLSProxy::Record::VERS_'.uc($1).'_'.$2.$3; 44 note("'$1', '$2', '$3' => $versionname"); 45 } else { 46 $versionname = 'TLSProxy::Record::VERS_'.uc($1).'_'.$2.'_0'; 47 note("'$1', '$2' => $versionname"); 48 } 49 push @available_tls_versions, eval $versionname; 50 } 51} 52note("TLS versions we can expect: ", join(", ", @available_tls_versions)); 53 54#This file does tests without the supported_versions extension. 55#See 70-test_sslversions.t for tests with supported versions. 56 57#Test 1: Asking for TLS1.4 should pass and negotiate the maximum 58#available TLS version according to configuration below TLS1.3 59my $client_version = TLSProxy::Record::VERS_TLS_1_4; 60my $previous_version = tls_version_below(TLSProxy::Record::VERS_TLS_1_3); 61$proxy->clientflags("-no_tls1_3"); 62$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; 63plan tests => 3; 64SKIP: { 65 skip "There are too few protocols enabled for test 1", 1 66 unless defined $previous_version; 67 68 my $record = pop @{$proxy->record_list}; 69 ok((note("Record version received: ".$record->version()), 70 TLSProxy::Message->success()) 71 && $record->version() == $previous_version, 72 "Version tolerance test, below TLS 1.4 and not TLS 1.3"); 73} 74 75#Test 2: Asking for TLS1.3 with that disabled should succeed and negotiate 76#the highest configured TLS version below that. 77$client_version = TLSProxy::Record::VERS_TLS_1_3; 78$previous_version = tls_version_below($client_version); 79SKIP: { 80 skip "There are too few protocols enabled for test 2", 1 81 unless defined $previous_version; 82 83 $proxy->clear(); 84 $proxy->clientflags("-no_tls1_3"); 85 $proxy->start(); 86 my $record = pop @{$proxy->record_list}; 87 ok((note("Record version received: ".$record->version()), 88 TLSProxy::Message->success()) 89 && $record->version() == $previous_version, 90 "Version tolerance test, max version but not TLS 1.3"); 91} 92 93#Test 3: Testing something below SSLv3 should fail. We must disable TLS 1.3 94#to avoid having the 'supported_versions' extension kick in and override our 95#desires. 96$client_version = TLSProxy::Record::VERS_SSL_3_0 - 1; 97$proxy->clear(); 98$proxy->clientflags("-no_tls1_3"); 99$proxy->start(); 100my $record = pop @{$proxy->record_list}; 101ok((note("Record version received: ". 102 (defined $record ? $record->version() : "none")), 103 TLSProxy::Message->fail()), 104 "Version tolerance test, SSL < 3.0"); 105 106sub vers_tolerance_filter 107{ 108 my $proxy = shift; 109 110 # We're only interested in the initial ClientHello 111 if ($proxy->flight != 0) { 112 return; 113 } 114 115 foreach my $message (@{$proxy->message_list}) { 116 if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) { 117 #Set the client version 118 #Anything above the max supported version should succeed 119 #Anything below SSLv3 should fail 120 $message->client_version($client_version); 121 $message->repack(); 122 } 123 } 124} 125 126sub tls_version_below { 127 if (@_) { 128 my $term = shift; 129 my $res = undef; 130 131 foreach (@available_tls_versions) { 132 $res = $_ if $_ < $term; 133 } 134 return $res; 135 } 136 return $available_tls_versions[-1]; 137} 138