1e1051a39Sopenharmony_ci# -*- mode: perl; -*-
2e1051a39Sopenharmony_ci# Copyright 2016-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_ci
10e1051a39Sopenharmony_ci## Test version negotiation
11e1051a39Sopenharmony_ci
12e1051a39Sopenharmony_cipackage ssltests;
13e1051a39Sopenharmony_ci
14e1051a39Sopenharmony_ciuse strict;
15e1051a39Sopenharmony_ciuse warnings;
16e1051a39Sopenharmony_ci
17e1051a39Sopenharmony_ciuse List::Util qw/max min/;
18e1051a39Sopenharmony_ci
19e1051a39Sopenharmony_ciuse OpenSSL::Test;
20e1051a39Sopenharmony_ciuse OpenSSL::Test::Utils qw/anydisabled alldisabled disabled/;
21e1051a39Sopenharmony_cisetup("no_test_here");
22e1051a39Sopenharmony_ci
23e1051a39Sopenharmony_cimy @tls_protocols = ("SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3");
24e1051a39Sopenharmony_cimy @tls_protocols_fips = ("TLSv1.2", "TLSv1.3");
25e1051a39Sopenharmony_ci# undef stands for "no limit".
26e1051a39Sopenharmony_cimy @min_tls_protocols = (undef, "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3");
27e1051a39Sopenharmony_cimy @min_tls_protocols_fips = (undef, "TLSv1.2", "TLSv1.3");
28e1051a39Sopenharmony_cimy @max_tls_protocols = ("SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3", undef);
29e1051a39Sopenharmony_cimy @max_tls_protocols_fips = ("TLSv1.2", "TLSv1.3", undef);
30e1051a39Sopenharmony_ci
31e1051a39Sopenharmony_cimy @is_tls_disabled = anydisabled("ssl3", "tls1", "tls1_1", "tls1_2", "tls1_3");
32e1051a39Sopenharmony_cimy @is_tls_disabled_fips = anydisabled("tls1_2", "tls1_3");
33e1051a39Sopenharmony_ci
34e1051a39Sopenharmony_cimy $min_tls_enabled; my $max_tls_enabled;
35e1051a39Sopenharmony_cimy $min_tls_enabled_fips; my $max_tls_enabled_fips;
36e1051a39Sopenharmony_ci
37e1051a39Sopenharmony_ci# Protocol configuration works in cascades, i.e.,
38e1051a39Sopenharmony_ci# $no_tls1_1 disables TLSv1.1 and below.
39e1051a39Sopenharmony_ci#
40e1051a39Sopenharmony_ci# $min_enabled and $max_enabled will be correct if there is at least one
41e1051a39Sopenharmony_ci# protocol enabled.
42e1051a39Sopenharmony_ci
43e1051a39Sopenharmony_cisub min_prot_enabled {
44e1051a39Sopenharmony_ci    my $protref = shift;
45e1051a39Sopenharmony_ci    my $disabledref = shift;
46e1051a39Sopenharmony_ci    my @protocols = @{$protref};
47e1051a39Sopenharmony_ci    my @is_disabled = @{$disabledref};
48e1051a39Sopenharmony_ci    my $min_enabled;
49e1051a39Sopenharmony_ci
50e1051a39Sopenharmony_ci    foreach my $i (0..$#protocols) {
51e1051a39Sopenharmony_ci        if (!$is_disabled[$i]) {
52e1051a39Sopenharmony_ci            $min_enabled = $i;
53e1051a39Sopenharmony_ci            last;
54e1051a39Sopenharmony_ci        }
55e1051a39Sopenharmony_ci    }
56e1051a39Sopenharmony_ci    return $min_enabled;
57e1051a39Sopenharmony_ci}
58e1051a39Sopenharmony_ci
59e1051a39Sopenharmony_cisub max_prot_enabled {
60e1051a39Sopenharmony_ci    my $protref = shift;
61e1051a39Sopenharmony_ci    my $disabledref = shift;
62e1051a39Sopenharmony_ci    my @protocols = @{$protref};
63e1051a39Sopenharmony_ci    my @is_disabled = @{$disabledref};
64e1051a39Sopenharmony_ci    my $max_enabled;
65e1051a39Sopenharmony_ci
66e1051a39Sopenharmony_ci    foreach my $i (0..$#protocols) {
67e1051a39Sopenharmony_ci        if (!$is_disabled[$i]
68e1051a39Sopenharmony_ci                && ($protocols[$i] ne "TLSv1.3"
69e1051a39Sopenharmony_ci                    || !disabled("ec")
70e1051a39Sopenharmony_ci                    || !disabled("dh"))) {
71e1051a39Sopenharmony_ci            $max_enabled = $i;
72e1051a39Sopenharmony_ci        }
73e1051a39Sopenharmony_ci    }
74e1051a39Sopenharmony_ci    return $max_enabled;
75e1051a39Sopenharmony_ci}
76e1051a39Sopenharmony_ci
77e1051a39Sopenharmony_ci$min_tls_enabled = min_prot_enabled(\@tls_protocols, \@is_tls_disabled);
78e1051a39Sopenharmony_ci$max_tls_enabled = max_prot_enabled(\@tls_protocols, \@is_tls_disabled);
79e1051a39Sopenharmony_ci$min_tls_enabled_fips = min_prot_enabled(\@tls_protocols_fips, \@is_tls_disabled_fips);
80e1051a39Sopenharmony_ci$max_tls_enabled_fips = max_prot_enabled(\@tls_protocols_fips, \@is_tls_disabled_fips);
81e1051a39Sopenharmony_ci
82e1051a39Sopenharmony_ci
83e1051a39Sopenharmony_cimy @dtls_protocols = ("DTLSv1", "DTLSv1.2");
84e1051a39Sopenharmony_cimy @dtls_protocols_fips = ("DTLSv1.2");
85e1051a39Sopenharmony_ci# undef stands for "no limit".
86e1051a39Sopenharmony_cimy @min_dtls_protocols = (undef, "DTLSv1", "DTLSv1.2");
87e1051a39Sopenharmony_cimy @min_dtls_protocols_fips = (undef, "DTLSv1.2");
88e1051a39Sopenharmony_cimy @max_dtls_protocols = ("DTLSv1", "DTLSv1.2", undef);
89e1051a39Sopenharmony_cimy @max_dtls_protocols_fips = ("DTLSv1.2", undef);
90e1051a39Sopenharmony_ci
91e1051a39Sopenharmony_cimy @is_dtls_disabled = anydisabled("dtls1", "dtls1_2");
92e1051a39Sopenharmony_cimy @is_dtls_disabled_fips = anydisabled("dtls1_2");
93e1051a39Sopenharmony_ci
94e1051a39Sopenharmony_cimy $min_dtls_enabled; my $max_dtls_enabled;
95e1051a39Sopenharmony_cimy $min_dtls_enabled_fips; my $max_dtls_enabled_fips;
96e1051a39Sopenharmony_ci
97e1051a39Sopenharmony_ci# $min_enabled and $max_enabled will be correct if there is at least one
98e1051a39Sopenharmony_ci# protocol enabled.
99e1051a39Sopenharmony_ci$min_dtls_enabled = min_prot_enabled(\@dtls_protocols, \@is_dtls_disabled);
100e1051a39Sopenharmony_ci$max_dtls_enabled = max_prot_enabled(\@dtls_protocols, \@is_dtls_disabled);
101e1051a39Sopenharmony_ci$min_dtls_enabled_fips = min_prot_enabled(\@dtls_protocols_fips, \@is_dtls_disabled_fips);
102e1051a39Sopenharmony_ci$max_dtls_enabled_fips = max_prot_enabled(\@dtls_protocols_fips, \@is_dtls_disabled_fips);
103e1051a39Sopenharmony_ci
104e1051a39Sopenharmony_cisub no_tests {
105e1051a39Sopenharmony_ci    my ($dtls, $fips) = @_;
106e1051a39Sopenharmony_ci    if ($dtls && $fips) {
107e1051a39Sopenharmony_ci        return disabled("dtls1_2");
108e1051a39Sopenharmony_ci    }
109e1051a39Sopenharmony_ci    return $dtls ? alldisabled("dtls1", "dtls1_2") :
110e1051a39Sopenharmony_ci      alldisabled("ssl3", "tls1", "tls1_1", "tls1_2", "tls1_3");
111e1051a39Sopenharmony_ci}
112e1051a39Sopenharmony_ci
113e1051a39Sopenharmony_cisub generate_version_tests {
114e1051a39Sopenharmony_ci    my $method = shift;
115e1051a39Sopenharmony_ci    my $fips = shift;
116e1051a39Sopenharmony_ci
117e1051a39Sopenharmony_ci    my $dtls = $method eq "DTLS";
118e1051a39Sopenharmony_ci    # Don't write the redundant "Method = TLS" into the configuration.
119e1051a39Sopenharmony_ci    undef $method if !$dtls;
120e1051a39Sopenharmony_ci
121e1051a39Sopenharmony_ci    my @protocols;
122e1051a39Sopenharmony_ci    my @min_protocols;
123e1051a39Sopenharmony_ci    my @max_protocols;
124e1051a39Sopenharmony_ci    my $min_enabled;
125e1051a39Sopenharmony_ci    my $max_enabled;
126e1051a39Sopenharmony_ci    if ($fips) {
127e1051a39Sopenharmony_ci        @protocols = $dtls ? @dtls_protocols_fips : @tls_protocols_fips;
128e1051a39Sopenharmony_ci        @min_protocols = $dtls ? @min_dtls_protocols_fips : @min_tls_protocols_fips;
129e1051a39Sopenharmony_ci        @max_protocols = $dtls ? @max_dtls_protocols_fips : @max_tls_protocols_fips;
130e1051a39Sopenharmony_ci        $min_enabled  = $dtls ? $min_dtls_enabled_fips : $min_tls_enabled_fips;
131e1051a39Sopenharmony_ci        $max_enabled  = $dtls ? $max_dtls_enabled_fips : $max_tls_enabled_fips;
132e1051a39Sopenharmony_ci    } else {
133e1051a39Sopenharmony_ci        @protocols = $dtls ? @dtls_protocols : @tls_protocols;
134e1051a39Sopenharmony_ci        @min_protocols = $dtls ? @min_dtls_protocols : @min_tls_protocols;
135e1051a39Sopenharmony_ci        @max_protocols = $dtls ? @max_dtls_protocols : @max_tls_protocols;
136e1051a39Sopenharmony_ci        $min_enabled  = $dtls ? $min_dtls_enabled : $min_tls_enabled;
137e1051a39Sopenharmony_ci        $max_enabled  = $dtls ? $max_dtls_enabled : $max_tls_enabled;
138e1051a39Sopenharmony_ci    }
139e1051a39Sopenharmony_ci
140e1051a39Sopenharmony_ci    if (no_tests($dtls, $fips)) {
141e1051a39Sopenharmony_ci        return;
142e1051a39Sopenharmony_ci    }
143e1051a39Sopenharmony_ci
144e1051a39Sopenharmony_ci    my @tests = ();
145e1051a39Sopenharmony_ci
146e1051a39Sopenharmony_ci    for (my $sctp = 0; $sctp < ($dtls && !disabled("sctp") ? 2 : 1); $sctp++) {
147e1051a39Sopenharmony_ci        foreach my $c_min (0..$#min_protocols) {
148e1051a39Sopenharmony_ci            my $c_max_min = $c_min == 0 ? 0 : $c_min - 1;
149e1051a39Sopenharmony_ci            foreach my $c_max ($c_max_min..$#max_protocols) {
150e1051a39Sopenharmony_ci                foreach my $s_min (0..$#min_protocols) {
151e1051a39Sopenharmony_ci                    my $s_max_min = $s_min == 0 ? 0 : $s_min - 1;
152e1051a39Sopenharmony_ci                    foreach my $s_max ($s_max_min..$#max_protocols) {
153e1051a39Sopenharmony_ci                        my ($result, $protocol) =
154e1051a39Sopenharmony_ci                            expected_result($c_min, $c_max, $s_min, $s_max,
155e1051a39Sopenharmony_ci                                            $min_enabled, $max_enabled,
156e1051a39Sopenharmony_ci                                            \@protocols);
157e1051a39Sopenharmony_ci                        push @tests, {
158e1051a39Sopenharmony_ci                            "name" => "version-negotiation",
159e1051a39Sopenharmony_ci                            "client" => {
160e1051a39Sopenharmony_ci                                "CipherString" => "DEFAULT:\@SECLEVEL=0",
161e1051a39Sopenharmony_ci                                "MinProtocol" => $min_protocols[$c_min],
162e1051a39Sopenharmony_ci                                "MaxProtocol" => $max_protocols[$c_max],
163e1051a39Sopenharmony_ci                            },
164e1051a39Sopenharmony_ci                            "server" => {
165e1051a39Sopenharmony_ci                                "CipherString" => "DEFAULT:\@SECLEVEL=0",
166e1051a39Sopenharmony_ci                                "MinProtocol" => $min_protocols[$s_min],
167e1051a39Sopenharmony_ci                                "MaxProtocol" => $max_protocols[$s_max],
168e1051a39Sopenharmony_ci                            },
169e1051a39Sopenharmony_ci                            "test" => {
170e1051a39Sopenharmony_ci                                "ExpectedResult" => $result,
171e1051a39Sopenharmony_ci                                "ExpectedProtocol" => $protocol,
172e1051a39Sopenharmony_ci                                "Method" => $method,
173e1051a39Sopenharmony_ci                            }
174e1051a39Sopenharmony_ci                        };
175e1051a39Sopenharmony_ci                        $tests[-1]{"test"}{"UseSCTP"} = "Yes" if $sctp;
176e1051a39Sopenharmony_ci                    }
177e1051a39Sopenharmony_ci                }
178e1051a39Sopenharmony_ci            }
179e1051a39Sopenharmony_ci        }
180e1051a39Sopenharmony_ci    }
181e1051a39Sopenharmony_ci    return @tests
182e1051a39Sopenharmony_ci        if disabled("tls1_3")
183e1051a39Sopenharmony_ci           || disabled("tls1_2")
184e1051a39Sopenharmony_ci           || (disabled("ec") && disabled("dh"))
185e1051a39Sopenharmony_ci           || $dtls;
186e1051a39Sopenharmony_ci
187e1051a39Sopenharmony_ci    #Add some version/ciphersuite sanity check tests
188e1051a39Sopenharmony_ci    push @tests, {
189e1051a39Sopenharmony_ci        "name" => "ciphersuite-sanity-check-client",
190e1051a39Sopenharmony_ci        "client" => {
191e1051a39Sopenharmony_ci            #Offering only <=TLSv1.2 ciphersuites with TLSv1.3 should fail
192e1051a39Sopenharmony_ci            "CipherString" => "AES128-SHA",
193e1051a39Sopenharmony_ci            "Ciphersuites" => "",
194e1051a39Sopenharmony_ci        },
195e1051a39Sopenharmony_ci        "server" => {
196e1051a39Sopenharmony_ci            "MaxProtocol" => "TLSv1.2"
197e1051a39Sopenharmony_ci        },
198e1051a39Sopenharmony_ci        "test" => {
199e1051a39Sopenharmony_ci            "ExpectedResult" => "ClientFail",
200e1051a39Sopenharmony_ci        }
201e1051a39Sopenharmony_ci    };
202e1051a39Sopenharmony_ci    push @tests, {
203e1051a39Sopenharmony_ci        "name" => "ciphersuite-sanity-check-server",
204e1051a39Sopenharmony_ci        "client" => {
205e1051a39Sopenharmony_ci            "CipherString" => "AES128-SHA",
206e1051a39Sopenharmony_ci            "MaxProtocol" => "TLSv1.2"
207e1051a39Sopenharmony_ci        },
208e1051a39Sopenharmony_ci        "server" => {
209e1051a39Sopenharmony_ci            #Allowing only <=TLSv1.2 ciphersuites with TLSv1.3 should fail
210e1051a39Sopenharmony_ci            "CipherString" => "AES128-SHA",
211e1051a39Sopenharmony_ci            "Ciphersuites" => "",
212e1051a39Sopenharmony_ci        },
213e1051a39Sopenharmony_ci        "test" => {
214e1051a39Sopenharmony_ci            "ExpectedResult" => "ServerFail",
215e1051a39Sopenharmony_ci        }
216e1051a39Sopenharmony_ci    };
217e1051a39Sopenharmony_ci
218e1051a39Sopenharmony_ci    return @tests;
219e1051a39Sopenharmony_ci}
220e1051a39Sopenharmony_ci
221e1051a39Sopenharmony_cisub generate_resumption_tests {
222e1051a39Sopenharmony_ci    my $method = shift;
223e1051a39Sopenharmony_ci    my $fips = shift;
224e1051a39Sopenharmony_ci
225e1051a39Sopenharmony_ci    my $dtls = $method eq "DTLS";
226e1051a39Sopenharmony_ci    # Don't write the redundant "Method = TLS" into the configuration.
227e1051a39Sopenharmony_ci    undef $method if !$dtls;
228e1051a39Sopenharmony_ci
229e1051a39Sopenharmony_ci    my @protocols;
230e1051a39Sopenharmony_ci    my $min_enabled;
231e1051a39Sopenharmony_ci    my $max_enabled;
232e1051a39Sopenharmony_ci
233e1051a39Sopenharmony_ci    if ($fips) {
234e1051a39Sopenharmony_ci        @protocols = $dtls ? @dtls_protocols_fips : @tls_protocols_fips;
235e1051a39Sopenharmony_ci        $min_enabled  = $dtls ? $min_dtls_enabled_fips : $min_tls_enabled_fips;
236e1051a39Sopenharmony_ci        $max_enabled = $dtls ? $max_dtls_enabled_fips : $max_tls_enabled_fips;
237e1051a39Sopenharmony_ci    } else {
238e1051a39Sopenharmony_ci        @protocols = $dtls ? @dtls_protocols : @tls_protocols;
239e1051a39Sopenharmony_ci        $min_enabled  = $dtls ? $min_dtls_enabled : $min_tls_enabled;
240e1051a39Sopenharmony_ci        $max_enabled = $dtls ? $max_dtls_enabled : $max_tls_enabled;
241e1051a39Sopenharmony_ci    }
242e1051a39Sopenharmony_ci
243e1051a39Sopenharmony_ci    if (no_tests($dtls)) {
244e1051a39Sopenharmony_ci        return;
245e1051a39Sopenharmony_ci    }
246e1051a39Sopenharmony_ci
247e1051a39Sopenharmony_ci    my @server_tests = ();
248e1051a39Sopenharmony_ci    my @client_tests = ();
249e1051a39Sopenharmony_ci
250e1051a39Sopenharmony_ci    # Obtain the first session against a fixed-version server/client.
251e1051a39Sopenharmony_ci    foreach my $original_protocol($min_enabled..$max_enabled) {
252e1051a39Sopenharmony_ci        # Upgrade or downgrade the server/client max version support and test
253e1051a39Sopenharmony_ci        # that it upgrades, downgrades or resumes the session as well.
254e1051a39Sopenharmony_ci        foreach my $resume_protocol($min_enabled..$max_enabled) {
255e1051a39Sopenharmony_ci            my $resumption_expected;
256e1051a39Sopenharmony_ci            # We should only resume on exact version match.
257e1051a39Sopenharmony_ci            if ($original_protocol eq $resume_protocol) {
258e1051a39Sopenharmony_ci                $resumption_expected = "Yes";
259e1051a39Sopenharmony_ci            } else {
260e1051a39Sopenharmony_ci                $resumption_expected = "No";
261e1051a39Sopenharmony_ci            }
262e1051a39Sopenharmony_ci
263e1051a39Sopenharmony_ci            for (my $sctp = 0; $sctp < ($dtls && !disabled("sctp") ? 2 : 1);
264e1051a39Sopenharmony_ci                 $sctp++) {
265e1051a39Sopenharmony_ci                foreach my $ticket ("SessionTicket", "-SessionTicket") {
266e1051a39Sopenharmony_ci                    # Client is flexible, server upgrades/downgrades.
267e1051a39Sopenharmony_ci                    push @server_tests, {
268e1051a39Sopenharmony_ci                        "name" => "resumption",
269e1051a39Sopenharmony_ci                        "client" => {
270e1051a39Sopenharmony_ci                            "CipherString" => "DEFAULT:\@SECLEVEL=0",
271e1051a39Sopenharmony_ci                        },
272e1051a39Sopenharmony_ci                        "server" => {
273e1051a39Sopenharmony_ci                            "CipherString" => "DEFAULT:\@SECLEVEL=0",
274e1051a39Sopenharmony_ci                            "MinProtocol" => $protocols[$original_protocol],
275e1051a39Sopenharmony_ci                            "MaxProtocol" => $protocols[$original_protocol],
276e1051a39Sopenharmony_ci                            "Options" => $ticket,
277e1051a39Sopenharmony_ci                        },
278e1051a39Sopenharmony_ci                        "resume_server" => {
279e1051a39Sopenharmony_ci                            "CipherString" => "DEFAULT:\@SECLEVEL=0",
280e1051a39Sopenharmony_ci                            "MaxProtocol" => $protocols[$resume_protocol],
281e1051a39Sopenharmony_ci                            "Options" => $ticket,
282e1051a39Sopenharmony_ci                        },
283e1051a39Sopenharmony_ci                        "test" => {
284e1051a39Sopenharmony_ci                            "ExpectedProtocol" => $protocols[$resume_protocol],
285e1051a39Sopenharmony_ci                            "Method" => $method,
286e1051a39Sopenharmony_ci                            "HandshakeMode" => "Resume",
287e1051a39Sopenharmony_ci                            "ResumptionExpected" => $resumption_expected,
288e1051a39Sopenharmony_ci                        }
289e1051a39Sopenharmony_ci                    };
290e1051a39Sopenharmony_ci                    $server_tests[-1]{"test"}{"UseSCTP"} = "Yes" if $sctp;
291e1051a39Sopenharmony_ci                    # Server is flexible, client upgrades/downgrades.
292e1051a39Sopenharmony_ci                    push @client_tests, {
293e1051a39Sopenharmony_ci                        "name" => "resumption",
294e1051a39Sopenharmony_ci                        "client" => {
295e1051a39Sopenharmony_ci                            "CipherString" => "DEFAULT:\@SECLEVEL=0",
296e1051a39Sopenharmony_ci                            "MinProtocol" => $protocols[$original_protocol],
297e1051a39Sopenharmony_ci                            "MaxProtocol" => $protocols[$original_protocol],
298e1051a39Sopenharmony_ci                        },
299e1051a39Sopenharmony_ci                        "server" => {
300e1051a39Sopenharmony_ci                            "CipherString" => "DEFAULT:\@SECLEVEL=0",
301e1051a39Sopenharmony_ci                            "Options" => $ticket,
302e1051a39Sopenharmony_ci                        },
303e1051a39Sopenharmony_ci                        "resume_client" => {
304e1051a39Sopenharmony_ci                            "CipherString" => "DEFAULT:\@SECLEVEL=0",
305e1051a39Sopenharmony_ci                            "MaxProtocol" => $protocols[$resume_protocol],
306e1051a39Sopenharmony_ci                        },
307e1051a39Sopenharmony_ci                        "test" => {
308e1051a39Sopenharmony_ci                            "ExpectedProtocol" => $protocols[$resume_protocol],
309e1051a39Sopenharmony_ci                            "Method" => $method,
310e1051a39Sopenharmony_ci                            "HandshakeMode" => "Resume",
311e1051a39Sopenharmony_ci                            "ResumptionExpected" => $resumption_expected,
312e1051a39Sopenharmony_ci                        }
313e1051a39Sopenharmony_ci                    };
314e1051a39Sopenharmony_ci                    $client_tests[-1]{"test"}{"UseSCTP"} = "Yes" if $sctp;
315e1051a39Sopenharmony_ci                }
316e1051a39Sopenharmony_ci            }
317e1051a39Sopenharmony_ci        }
318e1051a39Sopenharmony_ci    }
319e1051a39Sopenharmony_ci
320e1051a39Sopenharmony_ci    if (!disabled("tls1_3") && (!disabled("ec") || !disabled("dh")) && !$dtls) {
321e1051a39Sopenharmony_ci        push @client_tests, {
322e1051a39Sopenharmony_ci            "name" => "resumption-with-hrr",
323e1051a39Sopenharmony_ci            "client" => {
324e1051a39Sopenharmony_ci            },
325e1051a39Sopenharmony_ci            "server" => {
326e1051a39Sopenharmony_ci                "Curves" => disabled("ec") ? "ffdhe3072" : "P-256"
327e1051a39Sopenharmony_ci            },
328e1051a39Sopenharmony_ci            "resume_client" => {
329e1051a39Sopenharmony_ci            },
330e1051a39Sopenharmony_ci            "test" => {
331e1051a39Sopenharmony_ci                "ExpectedProtocol" => "TLSv1.3",
332e1051a39Sopenharmony_ci                "Method" => "TLS",
333e1051a39Sopenharmony_ci                "HandshakeMode" => "Resume",
334e1051a39Sopenharmony_ci                "ResumptionExpected" => "Yes",
335e1051a39Sopenharmony_ci            }
336e1051a39Sopenharmony_ci        };
337e1051a39Sopenharmony_ci    }
338e1051a39Sopenharmony_ci
339e1051a39Sopenharmony_ci    return (@server_tests, @client_tests);
340e1051a39Sopenharmony_ci}
341e1051a39Sopenharmony_ci
342e1051a39Sopenharmony_cisub expected_result {
343e1051a39Sopenharmony_ci    my ($c_min, $c_max, $s_min, $s_max, $min_enabled, $max_enabled,
344e1051a39Sopenharmony_ci        $protocols) = @_;
345e1051a39Sopenharmony_ci    my @prots = @$protocols;
346e1051a39Sopenharmony_ci
347e1051a39Sopenharmony_ci    my $orig_c_max = $c_max;
348e1051a39Sopenharmony_ci    # Adjust for "undef" (no limit).
349e1051a39Sopenharmony_ci    $c_min = $c_min == 0 ? 0 : $c_min - 1;
350e1051a39Sopenharmony_ci    $c_max = $c_max == scalar @$protocols ? $c_max - 1 : $c_max;
351e1051a39Sopenharmony_ci    $s_min = $s_min == 0 ? 0 : $s_min - 1;
352e1051a39Sopenharmony_ci    $s_max = $s_max == scalar @$protocols ? $s_max - 1 : $s_max;
353e1051a39Sopenharmony_ci
354e1051a39Sopenharmony_ci    # We now have at least one protocol enabled, so $min_enabled and
355e1051a39Sopenharmony_ci    # $max_enabled are well-defined.
356e1051a39Sopenharmony_ci    $c_min = max $c_min, $min_enabled;
357e1051a39Sopenharmony_ci    $s_min = max $s_min, $min_enabled;
358e1051a39Sopenharmony_ci    $c_max = min $c_max, $max_enabled;
359e1051a39Sopenharmony_ci    $s_max = min $s_max, $max_enabled;
360e1051a39Sopenharmony_ci
361e1051a39Sopenharmony_ci    if ($c_min > $c_max
362e1051a39Sopenharmony_ci            || ($orig_c_max != scalar @$protocols
363e1051a39Sopenharmony_ci                && $prots[$orig_c_max] eq "TLSv1.3"
364e1051a39Sopenharmony_ci                && $c_max != $orig_c_max
365e1051a39Sopenharmony_ci                && !disabled("tls1_3"))) {
366e1051a39Sopenharmony_ci        # Client should fail to even send a hello.
367e1051a39Sopenharmony_ci        return ("ClientFail", undef);
368e1051a39Sopenharmony_ci    } elsif ($s_min > $s_max) {
369e1051a39Sopenharmony_ci        # Server has no protocols, should always fail.
370e1051a39Sopenharmony_ci        return ("ServerFail", undef);
371e1051a39Sopenharmony_ci    } elsif ($s_min > $c_max) {
372e1051a39Sopenharmony_ci        # Server doesn't support the client range.
373e1051a39Sopenharmony_ci        return ("ServerFail", undef);
374e1051a39Sopenharmony_ci    } elsif ($c_min > $s_max) {
375e1051a39Sopenharmony_ci        if ($prots[$c_max] eq "TLSv1.3") {
376e1051a39Sopenharmony_ci            # Client will have sent supported_versions, so server will know
377e1051a39Sopenharmony_ci            # that there are no overlapping versions.
378e1051a39Sopenharmony_ci            return ("ServerFail", undef);
379e1051a39Sopenharmony_ci        } else {
380e1051a39Sopenharmony_ci            # Server will try with a version that is lower than the lowest
381e1051a39Sopenharmony_ci            # supported client version.
382e1051a39Sopenharmony_ci            return ("ClientFail", undef);
383e1051a39Sopenharmony_ci        }
384e1051a39Sopenharmony_ci    } else {
385e1051a39Sopenharmony_ci        # Server and client ranges overlap.
386e1051a39Sopenharmony_ci        my $max_common = $s_max < $c_max ? $s_max : $c_max;
387e1051a39Sopenharmony_ci        return ("Success", $protocols->[$max_common]);
388e1051a39Sopenharmony_ci    }
389e1051a39Sopenharmony_ci}
390e1051a39Sopenharmony_ci
391e1051a39Sopenharmony_ci1;
392