1#! /usr/bin/env perl
2# Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved.
3#
4# Licensed under the OpenSSL license (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
9use strict;
10use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file srctop_dir bldtop_dir/;
11use OpenSSL::Test::Utils;
12use File::Temp qw(tempfile);
13use TLSProxy::Proxy;
14use checkhandshake qw(checkhandshake @handmessages @extensions);
15
16my $test_name = "test_tls13messages";
17setup($test_name);
18
19plan skip_all => "TLSProxy isn't usable on $^O"
20    if $^O =~ /^(VMS)$/;
21
22plan skip_all => "$test_name needs the dynamic engine feature enabled"
23    if disabled("engine") || disabled("dynamic-engine");
24
25plan skip_all => "$test_name needs the sock feature enabled"
26    if disabled("sock");
27
28plan skip_all => "$test_name needs TLSv1.3 enabled"
29    if disabled("tls1_3");
30
31$ENV{OPENSSL_ia32cap} = '~0x200000200000000';
32$ENV{CTLOG_FILE} = srctop_file("test", "ct", "log_list.conf");
33
34
35@handmessages = (
36    [TLSProxy::Message::MT_CLIENT_HELLO,
37        checkhandshake::ALL_HANDSHAKES],
38    [TLSProxy::Message::MT_SERVER_HELLO,
39        checkhandshake::HRR_HANDSHAKE | checkhandshake::HRR_RESUME_HANDSHAKE],
40    [TLSProxy::Message::MT_CLIENT_HELLO,
41        checkhandshake::HRR_HANDSHAKE | checkhandshake::HRR_RESUME_HANDSHAKE],
42    [TLSProxy::Message::MT_SERVER_HELLO,
43        checkhandshake::ALL_HANDSHAKES],
44    [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS,
45        checkhandshake::ALL_HANDSHAKES],
46    [TLSProxy::Message::MT_CERTIFICATE_REQUEST,
47        checkhandshake::CLIENT_AUTH_HANDSHAKE],
48    [TLSProxy::Message::MT_CERTIFICATE,
49        checkhandshake::ALL_HANDSHAKES & ~(checkhandshake::RESUME_HANDSHAKE | checkhandshake::HRR_RESUME_HANDSHAKE)],
50    [TLSProxy::Message::MT_CERTIFICATE_VERIFY,
51        checkhandshake::ALL_HANDSHAKES & ~(checkhandshake::RESUME_HANDSHAKE | checkhandshake::HRR_RESUME_HANDSHAKE)],
52    [TLSProxy::Message::MT_FINISHED,
53        checkhandshake::ALL_HANDSHAKES],
54    [TLSProxy::Message::MT_CERTIFICATE,
55        checkhandshake::CLIENT_AUTH_HANDSHAKE],
56    [TLSProxy::Message::MT_CERTIFICATE_VERIFY,
57        checkhandshake::CLIENT_AUTH_HANDSHAKE],
58    [TLSProxy::Message::MT_FINISHED,
59        checkhandshake::ALL_HANDSHAKES],
60    [0, 0]
61);
62
63@extensions = (
64    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME,
65        TLSProxy::Message::CLIENT,
66        checkhandshake::SERVER_NAME_CLI_EXTENSION],
67    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST,
68        TLSProxy::Message::CLIENT,
69        checkhandshake::STATUS_REQUEST_CLI_EXTENSION],
70    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS,
71        TLSProxy::Message::CLIENT,
72        checkhandshake::DEFAULT_EXTENSIONS],
73    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS,
74        TLSProxy::Message::CLIENT,
75        checkhandshake::DEFAULT_EXTENSIONS],
76    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS,
77        TLSProxy::Message::CLIENT,
78        checkhandshake::DEFAULT_EXTENSIONS],
79    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN,
80        TLSProxy::Message::CLIENT,
81        checkhandshake::ALPN_CLI_EXTENSION],
82    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT,
83        TLSProxy::Message::CLIENT,
84        checkhandshake::SCT_CLI_EXTENSION],
85    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC,
86        TLSProxy::Message::CLIENT,
87        checkhandshake::DEFAULT_EXTENSIONS],
88    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET,
89        TLSProxy::Message::CLIENT,
90        checkhandshake::DEFAULT_EXTENSIONS],
91    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET,
92        TLSProxy::Message::CLIENT,
93        checkhandshake::DEFAULT_EXTENSIONS],
94    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
95        TLSProxy::Message::CLIENT,
96        checkhandshake::DEFAULT_EXTENSIONS],
97    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
98        TLSProxy::Message::CLIENT,
99        checkhandshake::DEFAULT_EXTENSIONS],
100    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES,
101        TLSProxy::Message::CLIENT,
102        checkhandshake::DEFAULT_EXTENSIONS],
103    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK,
104        TLSProxy::Message::CLIENT,
105        checkhandshake::PSK_CLI_EXTENSION],
106    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_POST_HANDSHAKE_AUTH,
107        TLSProxy::Message::CLIENT,
108        checkhandshake::POST_HANDSHAKE_AUTH_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::DEFAULT_EXTENSIONS],
156    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK,
157        TLSProxy::Message::CLIENT,
158        checkhandshake::PSK_CLI_EXTENSION],
159    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_POST_HANDSHAKE_AUTH,
160        TLSProxy::Message::CLIENT,
161        checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION],
162
163    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
164        TLSProxy::Message::SERVER,
165        checkhandshake::DEFAULT_EXTENSIONS],
166    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
167        TLSProxy::Message::SERVER,
168        checkhandshake::DEFAULT_EXTENSIONS],
169    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_PSK,
170        TLSProxy::Message::SERVER,
171        checkhandshake::PSK_SRV_EXTENSION],
172
173    [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_SERVER_NAME,
174        TLSProxy::Message::SERVER,
175        checkhandshake::SERVER_NAME_SRV_EXTENSION],
176    [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_ALPN,
177        TLSProxy::Message::SERVER,
178        checkhandshake::ALPN_SRV_EXTENSION],
179    [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_SUPPORTED_GROUPS,
180        TLSProxy::Message::SERVER,
181        checkhandshake::SUPPORTED_GROUPS_SRV_EXTENSION],
182
183    [TLSProxy::Message::MT_CERTIFICATE_REQUEST, TLSProxy::Message::EXT_SIG_ALGS,
184        TLSProxy::Message::SERVER,
185        checkhandshake::DEFAULT_EXTENSIONS],
186
187    [TLSProxy::Message::MT_CERTIFICATE, TLSProxy::Message::EXT_STATUS_REQUEST,
188        TLSProxy::Message::SERVER,
189        checkhandshake::STATUS_REQUEST_SRV_EXTENSION],
190    [TLSProxy::Message::MT_CERTIFICATE, TLSProxy::Message::EXT_SCT,
191        TLSProxy::Message::SERVER,
192        checkhandshake::SCT_SRV_EXTENSION],
193
194    [0,0,0,0]
195);
196
197my $proxy = TLSProxy::Proxy->new(
198    undef,
199    cmdstr(app(["openssl"]), display => 1),
200    srctop_file("apps", "server.pem"),
201    (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
202);
203
204#Test 1: Check we get all the right messages for a default handshake
205(undef, my $session) = tempfile();
206$proxy->serverconnects(2);
207$proxy->clientflags("-sess_out ".$session);
208$proxy->sessionfile($session);
209$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
210plan tests => 17;
211checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
212               checkhandshake::DEFAULT_EXTENSIONS,
213               "Default handshake test");
214
215#Test 2: Resumption handshake
216$proxy->clearClient();
217$proxy->clientflags("-sess_in ".$session);
218$proxy->clientstart();
219checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
220               (checkhandshake::DEFAULT_EXTENSIONS
221                | checkhandshake::PSK_CLI_EXTENSION
222                | checkhandshake::PSK_SRV_EXTENSION),
223               "Resumption handshake test");
224
225SKIP: {
226    skip "No OCSP support in this OpenSSL build", 4
227        if disabled("ct") || disabled("ec") || disabled("ocsp");
228    #Test 3: A status_request handshake (client request only)
229    $proxy->clear();
230    $proxy->clientflags("-status");
231    $proxy->start();
232    checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
233                   checkhandshake::DEFAULT_EXTENSIONS
234                   | checkhandshake::STATUS_REQUEST_CLI_EXTENSION,
235                   "status_request handshake test (client)");
236
237    #Test 4: A status_request handshake (server support only)
238    $proxy->clear();
239    $proxy->serverflags("-status_file "
240                        .srctop_file("test", "recipes", "ocsp-response.der"));
241    $proxy->start();
242    checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
243                   checkhandshake::DEFAULT_EXTENSIONS,
244                   "status_request handshake test (server)");
245
246    #Test 5: A status_request handshake (client and server)
247    $proxy->clear();
248    $proxy->clientflags("-status");
249    $proxy->serverflags("-status_file "
250                        .srctop_file("test", "recipes", "ocsp-response.der"));
251    $proxy->start();
252    checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
253                   checkhandshake::DEFAULT_EXTENSIONS
254                   | checkhandshake::STATUS_REQUEST_CLI_EXTENSION
255                   | checkhandshake::STATUS_REQUEST_SRV_EXTENSION,
256                   "status_request handshake test");
257
258    #Test 6: A status_request handshake (client and server) with client auth
259    $proxy->clear();
260    $proxy->clientflags("-status -enable_pha -cert "
261                        .srctop_file("apps", "server.pem"));
262    $proxy->serverflags("-Verify 5 -status_file "
263                        .srctop_file("test", "recipes", "ocsp-response.der"));
264    $proxy->start();
265    checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE,
266                   checkhandshake::DEFAULT_EXTENSIONS
267                   | checkhandshake::STATUS_REQUEST_CLI_EXTENSION
268                   | checkhandshake::STATUS_REQUEST_SRV_EXTENSION
269                   | checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION,
270                   "status_request handshake with client auth test");
271}
272
273#Test 7: A client auth handshake
274$proxy->clear();
275$proxy->clientflags("-enable_pha -cert ".srctop_file("apps", "server.pem"));
276$proxy->serverflags("-Verify 5");
277$proxy->start();
278checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE,
279               checkhandshake::DEFAULT_EXTENSIONS |
280               checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION,
281               "Client auth handshake test");
282
283#Test 8: Server name handshake (no client request)
284$proxy->clear();
285$proxy->clientflags("-noservername");
286$proxy->start();
287checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
288               checkhandshake::DEFAULT_EXTENSIONS
289               & ~checkhandshake::SERVER_NAME_CLI_EXTENSION,
290               "Server name handshake test (client)");
291
292#Test 9: Server name handshake (server support only)
293$proxy->clear();
294$proxy->clientflags("-noservername");
295$proxy->serverflags("-servername testhost");
296$proxy->start();
297checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
298               checkhandshake::DEFAULT_EXTENSIONS
299               & ~checkhandshake::SERVER_NAME_CLI_EXTENSION,
300               "Server name handshake test (server)");
301
302#Test 10: Server name handshake (client and server)
303$proxy->clear();
304$proxy->clientflags("-servername testhost");
305$proxy->serverflags("-servername testhost");
306$proxy->start();
307checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
308               checkhandshake::DEFAULT_EXTENSIONS
309               | checkhandshake::SERVER_NAME_SRV_EXTENSION,
310               "Server name handshake test");
311
312#Test 11: ALPN handshake (client request only)
313$proxy->clear();
314$proxy->clientflags("-alpn test");
315$proxy->start();
316checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
317               checkhandshake::DEFAULT_EXTENSIONS
318               | checkhandshake::ALPN_CLI_EXTENSION,
319               "ALPN handshake test (client)");
320
321#Test 12: ALPN handshake (server support only)
322$proxy->clear();
323$proxy->serverflags("-alpn test");
324$proxy->start();
325checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
326               checkhandshake::DEFAULT_EXTENSIONS,
327               "ALPN handshake test (server)");
328
329#Test 13: ALPN handshake (client and server)
330$proxy->clear();
331$proxy->clientflags("-alpn test");
332$proxy->serverflags("-alpn test");
333$proxy->start();
334checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
335               checkhandshake::DEFAULT_EXTENSIONS
336               | checkhandshake::ALPN_CLI_EXTENSION
337               | checkhandshake::ALPN_SRV_EXTENSION,
338               "ALPN handshake test");
339
340SKIP: {
341    skip "No CT, EC or OCSP support in this OpenSSL build", 1
342        if disabled("ct") || disabled("ec") || disabled("ocsp");
343
344    #Test 14: SCT handshake (client request only)
345    $proxy->clear();
346    #Note: -ct also sends status_request
347    $proxy->clientflags("-ct");
348    $proxy->serverflags("-status_file "
349                        .srctop_file("test", "recipes", "ocsp-response.der")
350                        ." -serverinfo ".srctop_file("test", "serverinfo2.pem"));
351    $proxy->start();
352    checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
353                   checkhandshake::DEFAULT_EXTENSIONS
354                   | checkhandshake::SCT_CLI_EXTENSION
355                   | checkhandshake::SCT_SRV_EXTENSION
356                   | checkhandshake::STATUS_REQUEST_CLI_EXTENSION
357                   | checkhandshake::STATUS_REQUEST_SRV_EXTENSION,
358                   "SCT handshake test");
359}
360
361#Test 15: HRR Handshake
362$proxy->clear();
363$proxy->serverflags("-curves P-256");
364$proxy->start();
365checkhandshake($proxy, checkhandshake::HRR_HANDSHAKE,
366               checkhandshake::DEFAULT_EXTENSIONS
367               | checkhandshake::KEY_SHARE_HRR_EXTENSION,
368               "HRR handshake test");
369
370#Test 16: Resumption handshake with HRR
371$proxy->clear();
372$proxy->clientflags("-sess_in ".$session);
373$proxy->serverflags("-curves P-256");
374$proxy->start();
375checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE,
376               (checkhandshake::DEFAULT_EXTENSIONS
377                | checkhandshake::KEY_SHARE_HRR_EXTENSION
378                | checkhandshake::PSK_CLI_EXTENSION
379                | checkhandshake::PSK_SRV_EXTENSION),
380               "Resumption handshake with HRR test");
381
382#Test 17: Acceptable but non preferred key_share
383$proxy->clear();
384$proxy->clientflags("-curves P-256");
385$proxy->start();
386checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
387               checkhandshake::DEFAULT_EXTENSIONS
388               | checkhandshake::SUPPORTED_GROUPS_SRV_EXTENSION,
389               "Acceptable but non preferred key_share");
390
391unlink $session;
392