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