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