2 # Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved.
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
10 use OpenSSL
::Test qw
/:DEFAULT cmdstr srctop_file bldtop_dir/;
11 use OpenSSL
::Test
::Utils
;
13 use TLSProxy
::Message
;
15 my $test_name = "test_tls13hrr";
18 plan skip_all
=> "TLSProxy isn't usable on $^O"
21 plan skip_all
=> "$test_name needs the dynamic engine feature enabled"
22 if disabled
("engine") || disabled
("dynamic-engine");
24 plan skip_all
=> "$test_name needs the sock feature enabled"
27 plan skip_all
=> "$test_name needs TLS1.3 enabled"
28 if disabled
("tls1_3") || (disabled
("ec") && disabled
("dh"));
30 my $proxy = TLSProxy
::Proxy
->new(
32 cmdstr
(app
(["openssl"]), display
=> 1),
33 srctop_file
("apps", "server.pem"),
34 (!$ENV{HARNESS_ACTIVE
} || $ENV{HARNESS_VERBOSE
})
38 CHANGE_HRR_CIPHERSUITE
=> 0,
39 CHANGE_CH1_CIPHERSUITE
=> 1,
44 #Test 1: A client should fail if the server changes the ciphersuite between the
46 $proxy->filter(\
&hrr_filter
);
48 $proxy->serverflags("-curves ffdhe3072");
50 $proxy->serverflags("-curves P-256");
52 my $testtype = CHANGE_HRR_CIPHERSUITE
;
53 $proxy->start() or plan skip_all
=> "Unable to start up Proxy for tests";
55 ok
(TLSProxy
::Message
->fail(), "Server ciphersuite changes");
57 #Test 2: It is an error if the client changes the offered ciphersuites so that
58 # we end up selecting a different ciphersuite between HRR and the SH
61 $proxy->serverflags("-curves ffdhe3072");
63 $proxy->serverflags("-curves P-384");
65 $proxy->ciphersuitess("TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384");
66 $testtype = CHANGE_CH1_CIPHERSUITE
;
68 ok
(TLSProxy
::Message
->fail(), "Client ciphersuite changes");
70 #Test 3: A client should fail with unexpected_message alert if the server
71 # sends more than 1 HRR
75 $proxy->serverflags("-curves ffdhe3072");
77 $proxy->serverflags("-curves P-384");
79 $testtype = DUPLICATE_HRR
;
81 ok
($fatal_alert, "Server duplicated HRR");
83 #Test 4: If the client sends a group that is in the supported_groups list but
84 # otherwise not valid (e.g. not suitable for TLSv1.3) we should reject it
85 # and not consider it when sending the HRR. We send brainpoolP512r1 in
86 # the ClientHello, which is acceptable to the server but is not valid in
87 # TLSv1.3. We expect the server to select P-521 in the HRR and the
88 # handshake to complete successfully
90 skip
"EC/TLSv1.2 is disabled in this build", 1
91 if disabled
("ec") || disabled
("tls1_2");
94 $proxy->clientflags("-groups P-256:brainpoolP512r1:P-521");
95 $proxy->serverflags("-groups brainpoolP512r1:P-521");
96 $testtype = INVALID_GROUP
;
98 ok
(TLSProxy
::Message
->success(), "Invalid group with HRR");
105 if ($testtype == CHANGE_HRR_CIPHERSUITE
) {
106 # We're only interested in the HRR
107 if ($proxy->flight != 1) {
111 my $hrr = ${$proxy->message_list}[1];
113 # We will normally only ever select CIPHER_TLS13_AES_128_GCM_SHA256
114 # because that's what Proxy tells s_server to do. Setting as below means
115 # the ciphersuite will change will we get the ServerHello
116 $hrr->ciphersuite(TLSProxy
::Message
::CIPHER_TLS13_AES_256_GCM_SHA384
);
121 if ($testtype == DUPLICATE_HRR
) {
122 # We're only interested in the HRR
123 # and the unexpected_message alert from client
124 if ($proxy->flight == 4) {
126 if @
{$proxy->record_list}[-1]->is_fatal_alert(0) == TLSProxy
::Message
::AL_DESC_UNEXPECTED_MESSAGE
;
129 if ($proxy->flight != 3) {
133 # Find ServerHello record (HRR actually) and insert after that
135 for ($i = 0; ${$proxy->record_list}[$i]->flight() < 1; $i++) {
138 my $hrr_record = ${$proxy->record_list}[$i];
139 my $dup_hrr = TLSProxy
::Record
->new(3,
140 $hrr_record->content_type(),
141 $hrr_record->version(),
143 $hrr_record->sslv2(),
144 $hrr_record->len_real(),
145 $hrr_record->decrypt_len(),
147 $hrr_record->decrypt_data());
150 splice @
{$proxy->record_list}, $i, 0, $dup_hrr;
154 if ($proxy->flight != 0) {
158 my $ch1 = ${$proxy->message_list}[0];
160 if ($testtype == CHANGE_CH1_CIPHERSUITE
) {
161 # The server will always pick TLS_AES_256_GCM_SHA384
162 my @ciphersuites = (TLSProxy
::Message
::CIPHER_TLS13_AES_128_GCM_SHA256
);
163 $ch1->ciphersuite_len(2 * scalar @ciphersuites);
164 $ch1->ciphersuites(\
@ciphersuites);
165 } elsif ($testtype == INVALID_GROUP
) {
168 0x00, 0x05, #List Length
169 0x00, 0x1c, #brainpoolP512r1 (not compatible with TLSv1.3)
170 0x00, 0x01, 0xff; #key_exchange data
172 TLSProxy
::Message
::EXT_KEY_SHARE
, $ext);