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