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