Fix grammar in certificates.txt
[openssl.git] / test / recipes / 70-test_tls13kexmodes.t
1 #! /usr/bin/env perl
2 # Copyright 2017-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
9 use strict;
10 use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file srctop_dir bldtop_dir/;
11 use OpenSSL::Test::Utils;
12 use File::Temp qw(tempfile);
13 use TLSProxy::Proxy;
14 use checkhandshake qw(checkhandshake @handmessages @extensions);
15
16 my $test_name = "test_tls13kexmodes";
17 setup($test_name);
18
19 plan skip_all => "TLSProxy isn't usable on $^O"
20     if $^O =~ /^(VMS)$/;
21
22 plan skip_all => "$test_name needs the dynamic engine feature enabled"
23     if disabled("engine") || disabled("dynamic-engine");
24
25 plan skip_all => "$test_name needs the sock feature enabled"
26     if disabled("sock");
27
28 plan skip_all => "$test_name needs TLSv1.3 enabled"
29     if disabled("tls1_3") || (disabled("ec") && disabled("dh"));
30
31 plan skip_all => "$test_name needs EC enabled"
32     if disabled("ec");
33
34 $ENV{OPENSSL_ia32cap} = '~0x200000200000000';
35
36
37 @handmessages = (
38     [TLSProxy::Message::MT_CLIENT_HELLO,
39         checkhandshake::ALL_HANDSHAKES],
40     [TLSProxy::Message::MT_SERVER_HELLO,
41         checkhandshake::HRR_HANDSHAKE | checkhandshake::HRR_RESUME_HANDSHAKE],
42     [TLSProxy::Message::MT_CLIENT_HELLO,
43         checkhandshake::HRR_HANDSHAKE | checkhandshake::HRR_RESUME_HANDSHAKE],
44     [TLSProxy::Message::MT_SERVER_HELLO,
45         checkhandshake::ALL_HANDSHAKES],
46     [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS,
47         checkhandshake::ALL_HANDSHAKES],
48     [TLSProxy::Message::MT_CERTIFICATE_REQUEST,
49         checkhandshake::CLIENT_AUTH_HANDSHAKE],
50     [TLSProxy::Message::MT_CERTIFICATE,
51         checkhandshake::ALL_HANDSHAKES & ~(checkhandshake::RESUME_HANDSHAKE | checkhandshake::HRR_RESUME_HANDSHAKE)],
52     [TLSProxy::Message::MT_CERTIFICATE_VERIFY,
53         checkhandshake::ALL_HANDSHAKES & ~(checkhandshake::RESUME_HANDSHAKE | checkhandshake::HRR_RESUME_HANDSHAKE)],
54     [TLSProxy::Message::MT_FINISHED,
55         checkhandshake::ALL_HANDSHAKES],
56     [TLSProxy::Message::MT_CERTIFICATE,
57         checkhandshake::CLIENT_AUTH_HANDSHAKE],
58     [TLSProxy::Message::MT_CERTIFICATE_VERIFY,
59         checkhandshake::CLIENT_AUTH_HANDSHAKE],
60     [TLSProxy::Message::MT_FINISHED,
61         checkhandshake::ALL_HANDSHAKES],
62     [0, 0]
63 );
64
65 @extensions = (
66     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME,
67         TLSProxy::Message::CLIENT,
68         checkhandshake::SERVER_NAME_CLI_EXTENSION],
69     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST,
70         TLSProxy::Message::CLIENT,
71         checkhandshake::STATUS_REQUEST_CLI_EXTENSION],
72     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS,
73         TLSProxy::Message::CLIENT,
74         checkhandshake::DEFAULT_EXTENSIONS],
75     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS,
76         TLSProxy::Message::CLIENT,
77         checkhandshake::DEFAULT_EXTENSIONS],
78     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS,
79         TLSProxy::Message::CLIENT,
80         checkhandshake::DEFAULT_EXTENSIONS],
81     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN,
82         TLSProxy::Message::CLIENT,
83         checkhandshake::ALPN_CLI_EXTENSION],
84     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT,
85         TLSProxy::Message::CLIENT,
86         checkhandshake::SCT_CLI_EXTENSION],
87     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC,
88         TLSProxy::Message::CLIENT,
89         checkhandshake::DEFAULT_EXTENSIONS],
90     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET,
91         TLSProxy::Message::CLIENT,
92         checkhandshake::DEFAULT_EXTENSIONS],
93     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET,
94         TLSProxy::Message::CLIENT,
95         checkhandshake::DEFAULT_EXTENSIONS],
96     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
97         TLSProxy::Message::CLIENT,
98         checkhandshake::DEFAULT_EXTENSIONS],
99     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
100         TLSProxy::Message::CLIENT,
101         checkhandshake::DEFAULT_EXTENSIONS],
102     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES,
103         TLSProxy::Message::CLIENT,
104         checkhandshake::PSK_KEX_MODES_EXTENSION],
105     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK,
106         TLSProxy::Message::CLIENT,
107         checkhandshake::PSK_CLI_EXTENSION],
108
109     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
110         TLSProxy::Message::SERVER,
111         checkhandshake::DEFAULT_EXTENSIONS],
112     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
113         TLSProxy::Message::SERVER,
114         checkhandshake::KEY_SHARE_HRR_EXTENSION],
115
116     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME,
117         TLSProxy::Message::CLIENT,
118         checkhandshake::SERVER_NAME_CLI_EXTENSION],
119     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST,
120         TLSProxy::Message::CLIENT,
121         checkhandshake::STATUS_REQUEST_CLI_EXTENSION],
122     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS,
123         TLSProxy::Message::CLIENT,
124         checkhandshake::DEFAULT_EXTENSIONS],
125     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS,
126         TLSProxy::Message::CLIENT,
127         checkhandshake::DEFAULT_EXTENSIONS],
128     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS,
129         TLSProxy::Message::CLIENT,
130         checkhandshake::DEFAULT_EXTENSIONS],
131     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN,
132         TLSProxy::Message::CLIENT,
133         checkhandshake::ALPN_CLI_EXTENSION],
134     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT,
135         TLSProxy::Message::CLIENT,
136         checkhandshake::SCT_CLI_EXTENSION],
137     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC,
138         TLSProxy::Message::CLIENT,
139         checkhandshake::DEFAULT_EXTENSIONS],
140     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET,
141         TLSProxy::Message::CLIENT,
142         checkhandshake::DEFAULT_EXTENSIONS],
143     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET,
144         TLSProxy::Message::CLIENT,
145         checkhandshake::DEFAULT_EXTENSIONS],
146     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
147         TLSProxy::Message::CLIENT,
148         checkhandshake::DEFAULT_EXTENSIONS],
149     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
150         TLSProxy::Message::CLIENT,
151         checkhandshake::DEFAULT_EXTENSIONS],
152     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES,
153         TLSProxy::Message::CLIENT,
154         checkhandshake::PSK_KEX_MODES_EXTENSION],
155     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK,
156         TLSProxy::Message::CLIENT,
157         checkhandshake::PSK_CLI_EXTENSION],
158
159     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
160         TLSProxy::Message::SERVER,
161         checkhandshake::DEFAULT_EXTENSIONS],
162     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
163         TLSProxy::Message::SERVER,
164         checkhandshake::KEY_SHARE_SRV_EXTENSION],
165     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_PSK,
166         TLSProxy::Message::SERVER,
167         checkhandshake::PSK_SRV_EXTENSION],
168
169     [TLSProxy::Message::MT_CERTIFICATE, TLSProxy::Message::EXT_STATUS_REQUEST,
170         TLSProxy::Message::SERVER,
171         checkhandshake::STATUS_REQUEST_SRV_EXTENSION],
172     [0,0,0,0]
173 );
174
175 use constant {
176     DELETE_EXTENSION => 0,
177     EMPTY_EXTENSION => 1,
178     NON_DHE_KEX_MODE_ONLY => 2,
179     DHE_KEX_MODE_ONLY => 3,
180     UNKNOWN_KEX_MODES => 4,
181     BOTH_KEX_MODES => 5
182 };
183
184 my $proxy = TLSProxy::Proxy->new(
185     undef,
186     cmdstr(app(["openssl"]), display => 1),
187     srctop_file("apps", "server.pem"),
188     (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
189 );
190
191 #Test 1: First get a session
192 (undef, my $session) = tempfile();
193 $proxy->clientflags("-sess_out ".$session);
194 $proxy->serverflags("-servername localhost");
195 $proxy->sessionfile($session);
196 $proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
197 plan tests => 11;
198 ok(TLSProxy::Message->success(), "Initial connection");
199
200 #Test 2: Attempt a resume with no kex modes extension. Should not resume
201 $proxy->clear();
202 $proxy->clientflags("-sess_in ".$session);
203 my $testtype = DELETE_EXTENSION;
204 $proxy->filter(\&modify_kex_modes_filter);
205 $proxy->start();
206 checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
207                checkhandshake::DEFAULT_EXTENSIONS
208                | checkhandshake::KEY_SHARE_SRV_EXTENSION
209                | checkhandshake::PSK_CLI_EXTENSION,
210                "Resume with no kex modes");
211
212 #Test 3: Attempt a resume with empty kex modes extension. Should fail (empty
213 #        extension is invalid)
214 $proxy->clear();
215 $proxy->clientflags("-sess_in ".$session);
216 $testtype = EMPTY_EXTENSION;
217 $proxy->start();
218 ok(TLSProxy::Message->fail(), "Resume with empty kex modes");
219
220 #Test 4: Attempt a resume with non-dhe kex mode only. Should resume without a
221 #        key_share
222 $proxy->clear();
223 $proxy->clientflags("-allow_no_dhe_kex -sess_in ".$session);
224 $proxy->serverflags("-allow_no_dhe_kex");
225 $testtype = NON_DHE_KEX_MODE_ONLY;
226 $proxy->start();
227 checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
228                checkhandshake::DEFAULT_EXTENSIONS
229                | checkhandshake::PSK_KEX_MODES_EXTENSION
230                | checkhandshake::PSK_CLI_EXTENSION
231                | checkhandshake::PSK_SRV_EXTENSION,
232                "Resume with non-dhe kex mode");
233
234 #Test 5: Attempt a resume with dhe kex mode only. Should resume with a key_share
235 $proxy->clear();
236 $proxy->clientflags("-sess_in ".$session);
237 $testtype = DHE_KEX_MODE_ONLY;
238 $proxy->start();
239 checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
240                checkhandshake::DEFAULT_EXTENSIONS
241                | checkhandshake::PSK_KEX_MODES_EXTENSION
242                | checkhandshake::KEY_SHARE_SRV_EXTENSION
243                | checkhandshake::PSK_CLI_EXTENSION
244                | checkhandshake::PSK_SRV_EXTENSION,
245                "Resume with non-dhe kex mode");
246
247 #Test 6: Attempt a resume with only unrecognised kex modes. Should not resume
248 $proxy->clear();
249 $proxy->clientflags("-sess_in ".$session);
250 $testtype = UNKNOWN_KEX_MODES;
251 $proxy->start();
252 checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
253                checkhandshake::DEFAULT_EXTENSIONS
254                | checkhandshake::PSK_KEX_MODES_EXTENSION
255                | checkhandshake::KEY_SHARE_SRV_EXTENSION
256                | checkhandshake::PSK_CLI_EXTENSION,
257                "Resume with empty kex modes");
258
259 #Test 7: Attempt a resume with both non-dhe and dhe kex mode. Should resume with
260 #        a key_share
261 $proxy->clear();
262 $proxy->clientflags("-sess_in ".$session);
263 $testtype = BOTH_KEX_MODES;
264 $proxy->start();
265 checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
266                checkhandshake::DEFAULT_EXTENSIONS
267                | checkhandshake::PSK_KEX_MODES_EXTENSION
268                | checkhandshake::KEY_SHARE_SRV_EXTENSION
269                | checkhandshake::PSK_CLI_EXTENSION
270                | checkhandshake::PSK_SRV_EXTENSION,
271                "Resume with non-dhe kex mode");
272
273 #Test 8: Attempt a resume with both non-dhe and dhe kex mode, but unacceptable
274 #        initial key_share. Should resume with a key_share following an HRR
275 $proxy->clear();
276 $proxy->clientflags("-sess_in ".$session);
277 $proxy->serverflags("-curves P-256");
278 $testtype = BOTH_KEX_MODES;
279 $proxy->start();
280 checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE,
281                checkhandshake::DEFAULT_EXTENSIONS
282                | checkhandshake::PSK_KEX_MODES_EXTENSION
283                | checkhandshake::KEY_SHARE_SRV_EXTENSION
284                | checkhandshake::KEY_SHARE_HRR_EXTENSION
285                | checkhandshake::PSK_CLI_EXTENSION
286                | checkhandshake::PSK_SRV_EXTENSION,
287                "Resume with both kex modes and HRR");
288
289 #Test 9: Attempt a resume with dhe kex mode only and an unacceptable initial
290 #        key_share. Should resume with a key_share following an HRR
291 $proxy->clear();
292 $proxy->clientflags("-sess_in ".$session);
293 $proxy->serverflags("-curves P-256");
294 $testtype = DHE_KEX_MODE_ONLY;
295 $proxy->start();
296 checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE,
297                checkhandshake::DEFAULT_EXTENSIONS
298                | checkhandshake::PSK_KEX_MODES_EXTENSION
299                | checkhandshake::KEY_SHARE_SRV_EXTENSION
300                | checkhandshake::KEY_SHARE_HRR_EXTENSION
301                | checkhandshake::PSK_CLI_EXTENSION
302                | checkhandshake::PSK_SRV_EXTENSION,
303                "Resume with dhe kex mode and HRR");
304
305 #Test 10: Attempt a resume with both non-dhe and dhe kex mode, unacceptable
306 #         initial key_share and no overlapping groups. Should resume without a
307 #         key_share
308 $proxy->clear();
309 $proxy->clientflags("-allow_no_dhe_kex -curves P-384 -sess_in ".$session);
310 $proxy->serverflags("-allow_no_dhe_kex -curves P-256");
311 $testtype = BOTH_KEX_MODES;
312 $proxy->start();
313 checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
314                checkhandshake::DEFAULT_EXTENSIONS
315                | checkhandshake::PSK_KEX_MODES_EXTENSION
316                | checkhandshake::PSK_CLI_EXTENSION
317                | checkhandshake::PSK_SRV_EXTENSION,
318                "Resume with both kex modes, no overlapping groups");
319
320 #Test 11: Attempt a resume with dhe kex mode only, unacceptable
321 #         initial key_share and no overlapping groups. Should fail
322 $proxy->clear();
323 $proxy->clientflags("-curves P-384 -sess_in ".$session);
324 $proxy->serverflags("-curves P-256");
325 $testtype = DHE_KEX_MODE_ONLY;
326 $proxy->start();
327 ok(TLSProxy::Message->fail(), "Resume with dhe kex mode, no overlapping groups");
328
329 unlink $session;
330
331 sub modify_kex_modes_filter
332 {
333     my $proxy = shift;
334
335     # We're only interested in the initial ClientHello
336     return if ($proxy->flight != 0);
337
338     foreach my $message (@{$proxy->message_list}) {
339         if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) {
340             my $ext;
341
342             if ($testtype == EMPTY_EXTENSION) {
343                 $ext = pack "C",
344                     0x00;       #List length
345             } elsif ($testtype == NON_DHE_KEX_MODE_ONLY) {
346                 $ext = pack "C2",
347                     0x01,       #List length
348                     0x00;       #psk_ke
349             } elsif ($testtype == DHE_KEX_MODE_ONLY) {
350                 $ext = pack "C2",
351                     0x01,       #List length
352                     0x01;       #psk_dhe_ke
353             } elsif ($testtype == UNKNOWN_KEX_MODES) {
354                 $ext = pack "C3",
355                     0x02,       #List length
356                     0xfe,       #unknown
357                     0xff;       #unknown
358             } elsif ($testtype == BOTH_KEX_MODES) {
359                 #We deliberately list psk_ke first...should still use psk_dhe_ke
360                 $ext = pack "C3",
361                     0x02,       #List length
362                     0x00,       #psk_ke
363                     0x01;       #psk_dhe_ke
364             }
365
366             if ($testtype == DELETE_EXTENSION) {
367                 $message->delete_extension(
368                     TLSProxy::Message::EXT_PSK_KEX_MODES);
369             } else {
370                 $message->set_extension(
371                     TLSProxy::Message::EXT_PSK_KEX_MODES, $ext);
372             }
373
374             $message->repack();
375         }
376     }
377 }