xref: /freebsd/crypto/openssl/test/recipes/70-test_sslmessages.t (revision 4b15965daa99044daf184221b7c283bf7f2d7e66)
1#! /usr/bin/env perl
2# Copyright 2015-2024 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_sslmessages";
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 TLS enabled"
29    if alldisabled(available_protocols("tls"))
30       || (!disabled("tls1_3") && disabled("tls1_2"));
31
32my $proxy = TLSProxy::Proxy->new(
33    undef,
34    cmdstr(app(["openssl"]), display => 1),
35    srctop_file("apps", "server.pem"),
36    (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
37);
38
39@handmessages = (
40    [TLSProxy::Message::MT_CLIENT_HELLO,
41        checkhandshake::ALL_HANDSHAKES],
42    [TLSProxy::Message::MT_SERVER_HELLO,
43        checkhandshake::ALL_HANDSHAKES],
44    [TLSProxy::Message::MT_CERTIFICATE,
45        checkhandshake::ALL_HANDSHAKES
46        & ~checkhandshake::RESUME_HANDSHAKE],
47    (disabled("ec") ? () :
48                      [TLSProxy::Message::MT_SERVER_KEY_EXCHANGE,
49                          checkhandshake::EC_HANDSHAKE]),
50    [TLSProxy::Message::MT_CERTIFICATE_STATUS,
51        checkhandshake::OCSP_HANDSHAKE],
52    #ServerKeyExchange handshakes not currently supported by TLSProxy
53    [TLSProxy::Message::MT_CERTIFICATE_REQUEST,
54        checkhandshake::CLIENT_AUTH_HANDSHAKE],
55    [TLSProxy::Message::MT_SERVER_HELLO_DONE,
56        checkhandshake::ALL_HANDSHAKES
57        & ~checkhandshake::RESUME_HANDSHAKE],
58    [TLSProxy::Message::MT_CERTIFICATE,
59        checkhandshake::CLIENT_AUTH_HANDSHAKE],
60    [TLSProxy::Message::MT_CLIENT_KEY_EXCHANGE,
61        checkhandshake::ALL_HANDSHAKES
62        & ~checkhandshake::RESUME_HANDSHAKE],
63    [TLSProxy::Message::MT_CERTIFICATE_VERIFY,
64        checkhandshake::CLIENT_AUTH_HANDSHAKE],
65    [TLSProxy::Message::MT_NEXT_PROTO,
66        checkhandshake::NPN_HANDSHAKE],
67    [TLSProxy::Message::MT_FINISHED,
68        checkhandshake::ALL_HANDSHAKES],
69    [TLSProxy::Message::MT_NEW_SESSION_TICKET,
70        checkhandshake::ALL_HANDSHAKES
71        & ~checkhandshake::RESUME_HANDSHAKE],
72    [TLSProxy::Message::MT_FINISHED,
73        checkhandshake::ALL_HANDSHAKES],
74    [TLSProxy::Message::MT_CLIENT_HELLO,
75        checkhandshake::RENEG_HANDSHAKE],
76    [TLSProxy::Message::MT_SERVER_HELLO,
77        checkhandshake::RENEG_HANDSHAKE],
78    [TLSProxy::Message::MT_CERTIFICATE,
79        checkhandshake::RENEG_HANDSHAKE],
80    [TLSProxy::Message::MT_SERVER_HELLO_DONE,
81        checkhandshake::RENEG_HANDSHAKE],
82    [TLSProxy::Message::MT_CLIENT_KEY_EXCHANGE,
83        checkhandshake::RENEG_HANDSHAKE],
84    [TLSProxy::Message::MT_FINISHED,
85        checkhandshake::RENEG_HANDSHAKE],
86    [TLSProxy::Message::MT_NEW_SESSION_TICKET,
87        checkhandshake::RENEG_HANDSHAKE],
88    [TLSProxy::Message::MT_FINISHED,
89        checkhandshake::RENEG_HANDSHAKE],
90    [0, 0]
91);
92
93@extensions = (
94    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME,
95        TLSProxy::Message::CLIENT,
96        checkhandshake::SERVER_NAME_CLI_EXTENSION],
97    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST,
98        TLSProxy::Message::CLIENT,
99        checkhandshake::STATUS_REQUEST_CLI_EXTENSION],
100    (disabled("ec") ? () :
101                      [TLSProxy::Message::MT_CLIENT_HELLO,
102                       TLSProxy::Message::EXT_SUPPORTED_GROUPS,
103                       TLSProxy::Message::CLIENT,
104                       checkhandshake::DEFAULT_EXTENSIONS]),
105    (disabled("ec") ? () :
106                      [TLSProxy::Message::MT_CLIENT_HELLO,
107                       TLSProxy::Message::EXT_EC_POINT_FORMATS,
108                       TLSProxy::Message::CLIENT,
109                       checkhandshake::DEFAULT_EXTENSIONS]),
110    (disabled("tls1_2") ? () :
111     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS,
112        TLSProxy::Message::CLIENT,
113         checkhandshake::DEFAULT_EXTENSIONS]),
114    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN,
115        TLSProxy::Message::CLIENT,
116        checkhandshake::ALPN_CLI_EXTENSION],
117    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT,
118        TLSProxy::Message::CLIENT,
119        checkhandshake::SCT_CLI_EXTENSION],
120    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC,
121        TLSProxy::Message::CLIENT,
122        checkhandshake::DEFAULT_EXTENSIONS],
123    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET,
124        TLSProxy::Message::CLIENT,
125        checkhandshake::DEFAULT_EXTENSIONS],
126    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET,
127        TLSProxy::Message::CLIENT,
128        checkhandshake::DEFAULT_EXTENSIONS],
129    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_RENEGOTIATE,
130        TLSProxy::Message::CLIENT,
131        checkhandshake::DEFAULT_EXTENSIONS],
132    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_NPN,
133        TLSProxy::Message::CLIENT,
134        checkhandshake::NPN_CLI_EXTENSION],
135    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SRP,
136        TLSProxy::Message::CLIENT,
137        checkhandshake::SRP_CLI_EXTENSION],
138
139    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_RENEGOTIATE,
140        TLSProxy::Message::SERVER,
141        checkhandshake::DEFAULT_EXTENSIONS],
142    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC,
143        TLSProxy::Message::SERVER,
144        checkhandshake::DEFAULT_EXTENSIONS],
145    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET,
146        TLSProxy::Message::SERVER,
147        checkhandshake::DEFAULT_EXTENSIONS],
148    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SESSION_TICKET,
149        TLSProxy::Message::SERVER,
150        checkhandshake::SESSION_TICKET_SRV_EXTENSION],
151    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SERVER_NAME,
152        TLSProxy::Message::SERVER,
153        checkhandshake::SERVER_NAME_SRV_EXTENSION],
154    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST,
155        TLSProxy::Message::SERVER,
156        checkhandshake::STATUS_REQUEST_SRV_EXTENSION],
157    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_ALPN,
158        TLSProxy::Message::SERVER,
159        checkhandshake::ALPN_SRV_EXTENSION],
160    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SCT,
161        TLSProxy::Message::SERVER,
162        checkhandshake::SCT_SRV_EXTENSION],
163    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_NPN,
164        TLSProxy::Message::SERVER,
165        checkhandshake::NPN_SRV_EXTENSION],
166    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS,
167        TLSProxy::Message::SERVER,
168        checkhandshake::EC_POINT_FORMAT_SRV_EXTENSION],
169    [0,0,0,0]
170);
171
172#Test 1: Check we get all the right messages for a default handshake
173(undef, my $session) = tempfile();
174$proxy->serverconnects(2);
175$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
176$proxy->clientflags("-no_tls1_3 -sess_out ".$session);
177$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
178plan tests => 21;
179checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
180               checkhandshake::DEFAULT_EXTENSIONS,
181               "Default handshake test");
182
183#Test 2: Resumption handshake
184$proxy->clearClient();
185$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
186$proxy->clientflags("-no_tls1_3 -sess_in ".$session);
187$proxy->clientstart();
188checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
189               checkhandshake::DEFAULT_EXTENSIONS
190               & ~checkhandshake::SESSION_TICKET_SRV_EXTENSION,
191               "Resumption handshake test");
192unlink $session;
193
194SKIP: {
195    skip "No OCSP support in this OpenSSL build", 3
196        if disabled("ocsp");
197
198    #Test 3: A status_request handshake (client request only)
199    $proxy->clear();
200    $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
201    $proxy->clientflags("-no_tls1_3 -status");
202    $proxy->start();
203    checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
204                   checkhandshake::DEFAULT_EXTENSIONS
205                   | checkhandshake::STATUS_REQUEST_CLI_EXTENSION,
206                   "status_request handshake test (client)");
207
208    #Test 4: A status_request handshake (server support only)
209    $proxy->clear();
210    $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
211    $proxy->clientflags("-no_tls1_3");
212    $proxy->serverflags("-status_file "
213                        .srctop_file("test", "recipes", "ocsp-response.der"));
214    $proxy->start();
215    checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
216                   checkhandshake::DEFAULT_EXTENSIONS,
217                   "status_request handshake test (server)");
218
219    #Test 5: A status_request handshake (client and server)
220    $proxy->clear();
221    $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
222    $proxy->clientflags("-no_tls1_3 -status");
223    $proxy->serverflags("-status_file "
224                        .srctop_file("test", "recipes", "ocsp-response.der"));
225    $proxy->start();
226    checkhandshake($proxy, checkhandshake::OCSP_HANDSHAKE,
227                   checkhandshake::DEFAULT_EXTENSIONS
228                   | checkhandshake::STATUS_REQUEST_CLI_EXTENSION
229                   | checkhandshake::STATUS_REQUEST_SRV_EXTENSION,
230                   "status_request handshake test");
231}
232
233#Test 6: A client auth handshake
234$proxy->clear();
235$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
236$proxy->clientflags("-no_tls1_3 -cert ".srctop_file("apps", "server.pem"));
237$proxy->serverflags("-Verify 5");
238$proxy->start();
239checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE,
240               checkhandshake::DEFAULT_EXTENSIONS,
241               "Client auth handshake test");
242
243#Test 7: A handshake with a renegotiation
244$proxy->clear();
245$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
246$proxy->clientflags("-no_tls1_3");
247$proxy->serverflags("-client_renegotiation");
248$proxy->reneg(1);
249$proxy->start();
250checkhandshake($proxy, checkhandshake::RENEG_HANDSHAKE,
251               checkhandshake::DEFAULT_EXTENSIONS,
252               "Renegotiation handshake test");
253
254#Test 8: Server name handshake (no client request)
255$proxy->clear();
256$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
257$proxy->clientflags("-no_tls1_3 -noservername");
258$proxy->start();
259checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
260               checkhandshake::DEFAULT_EXTENSIONS
261               & ~checkhandshake::SERVER_NAME_CLI_EXTENSION,
262               "Server name handshake test (client)");
263
264#Test 9: Server name handshake (server support only)
265$proxy->clear();
266$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
267$proxy->clientflags("-no_tls1_3 -noservername");
268$proxy->serverflags("-servername testhost");
269$proxy->start();
270checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
271               checkhandshake::DEFAULT_EXTENSIONS
272               & ~checkhandshake::SERVER_NAME_CLI_EXTENSION,
273               "Server name handshake test (server)");
274
275#Test 10: Server name handshake (client and server)
276$proxy->clear();
277$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
278$proxy->clientflags("-no_tls1_3 -servername testhost");
279$proxy->serverflags("-servername testhost");
280$proxy->start();
281checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
282               checkhandshake::DEFAULT_EXTENSIONS
283               | checkhandshake::SERVER_NAME_SRV_EXTENSION,
284               "Server name handshake test");
285
286#Test 11: ALPN handshake (client request only)
287$proxy->clear();
288$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
289$proxy->clientflags("-no_tls1_3 -alpn test");
290$proxy->start();
291checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
292               checkhandshake::DEFAULT_EXTENSIONS
293               | checkhandshake::ALPN_CLI_EXTENSION,
294               "ALPN handshake test (client)");
295
296#Test 12: ALPN handshake (server support only)
297$proxy->clear();
298$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
299$proxy->clientflags("-no_tls1_3");
300$proxy->serverflags("-alpn test");
301$proxy->start();
302checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
303               checkhandshake::DEFAULT_EXTENSIONS,
304               "ALPN handshake test (server)");
305
306#Test 13: ALPN handshake (client and server)
307$proxy->clear();
308$proxy->cipherc("DEFAULT:\@SECLEVEL=2");
309$proxy->clientflags("-no_tls1_3 -alpn test");
310$proxy->serverflags("-alpn test");
311$proxy->start();
312checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
313               checkhandshake::DEFAULT_EXTENSIONS
314               | checkhandshake::ALPN_CLI_EXTENSION
315               | checkhandshake::ALPN_SRV_EXTENSION,
316               "ALPN handshake test");
317
318SKIP: {
319    skip "No CT, EC or OCSP support in this OpenSSL build", 1
320        if disabled("ct") || disabled("ec") || disabled("ocsp");
321
322    #Test 14: SCT handshake (client request only)
323    $proxy->clear();
324    $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
325    #Note: -ct also sends status_request
326    $proxy->clientflags("-no_tls1_3 -ct");
327    $proxy->serverflags("-status_file "
328                        .srctop_file("test", "recipes", "ocsp-response.der"));
329    $proxy->start();
330    checkhandshake($proxy, checkhandshake::OCSP_HANDSHAKE,
331                   checkhandshake::DEFAULT_EXTENSIONS
332                   | checkhandshake::SCT_CLI_EXTENSION
333                   | checkhandshake::STATUS_REQUEST_CLI_EXTENSION
334                   | checkhandshake::STATUS_REQUEST_SRV_EXTENSION,
335                   "SCT handshake test (client)");
336}
337
338SKIP: {
339    skip "No OCSP support in this OpenSSL build", 1
340        if disabled("ocsp");
341
342    #Test 15: SCT handshake (server support only)
343    $proxy->clear();
344    $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
345    #Note: -ct also sends status_request
346    $proxy->clientflags("-no_tls1_3");
347    $proxy->serverflags("-status_file "
348                        .srctop_file("test", "recipes", "ocsp-response.der"));
349    $proxy->start();
350    checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
351                   checkhandshake::DEFAULT_EXTENSIONS,
352                   "SCT handshake test (server)");
353}
354
355SKIP: {
356    skip "No CT, EC or OCSP support in this OpenSSL build", 1
357        if disabled("ct") || disabled("ec") || disabled("ocsp");
358
359    #Test 16: SCT handshake (client and server)
360    #There is no built-in server side support for this so we are actually also
361    #testing custom extensions here
362    $proxy->clear();
363    $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
364    #Note: -ct also sends status_request
365    $proxy->clientflags("-no_tls1_3 -ct");
366    $proxy->serverflags("-status_file "
367                        .srctop_file("test", "recipes", "ocsp-response.der")
368                        ." -serverinfo ".srctop_file("test", "serverinfo.pem"));
369    $proxy->start();
370    checkhandshake($proxy, checkhandshake::OCSP_HANDSHAKE,
371                   checkhandshake::DEFAULT_EXTENSIONS
372                   | checkhandshake::SCT_CLI_EXTENSION
373                   | checkhandshake::SCT_SRV_EXTENSION
374                   | checkhandshake::STATUS_REQUEST_CLI_EXTENSION
375                   | checkhandshake::STATUS_REQUEST_SRV_EXTENSION,
376                   "SCT handshake test");
377}
378
379
380SKIP: {
381    skip "No NPN support in this OpenSSL build", 3
382        if disabled("nextprotoneg");
383
384    #Test 17: NPN handshake (client request only)
385    $proxy->clear();
386    $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
387    $proxy->clientflags("-no_tls1_3 -nextprotoneg test");
388    $proxy->start();
389    checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
390                   checkhandshake::DEFAULT_EXTENSIONS
391                   | checkhandshake::NPN_CLI_EXTENSION,
392                   "NPN handshake test (client)");
393
394    #Test 18: NPN handshake (server support only)
395    $proxy->clear();
396    $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
397    $proxy->clientflags("-no_tls1_3");
398    $proxy->serverflags("-nextprotoneg test");
399    $proxy->start();
400    checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
401                   checkhandshake::DEFAULT_EXTENSIONS,
402                   "NPN handshake test (server)");
403
404    #Test 19: NPN handshake (client and server)
405    $proxy->clear();
406    $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
407    $proxy->clientflags("-no_tls1_3 -nextprotoneg test");
408    $proxy->serverflags("-nextprotoneg test");
409    $proxy->start();
410    checkhandshake($proxy, checkhandshake::NPN_HANDSHAKE,
411                   checkhandshake::DEFAULT_EXTENSIONS
412                   | checkhandshake::NPN_CLI_EXTENSION
413                   | checkhandshake::NPN_SRV_EXTENSION,
414                   "NPN handshake test");
415}
416
417SKIP: {
418    skip "No SRP support in this OpenSSL build", 1
419        if disabled("srp");
420
421    #Test 20: SRP extension
422    #Note: We are not actually going to perform an SRP handshake (TLSProxy
423    #does not support it). However it is sufficient for us to check that the
424    #SRP extension gets added on the client side. There is no SRP extension
425    #generated on the server side anyway.
426    $proxy->clear();
427    $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
428    $proxy->clientflags("-no_tls1_3 -srpuser user -srppass pass:pass");
429    $proxy->start();
430    checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
431                   checkhandshake::DEFAULT_EXTENSIONS
432                   | checkhandshake::SRP_CLI_EXTENSION,
433                   "SRP extension test");
434}
435
436#Test 21: EC handshake
437SKIP: {
438    skip "No EC support in this OpenSSL build", 1 if disabled("ec");
439    $proxy->clear();
440    $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
441    $proxy->clientflags("-no_tls1_3");
442    $proxy->serverflags("-no_tls1_3");
443    $proxy->ciphers("ECDHE-RSA-AES128-SHA");
444    $proxy->start();
445    checkhandshake($proxy, checkhandshake::EC_HANDSHAKE,
446                   checkhandshake::DEFAULT_EXTENSIONS
447                   | checkhandshake::EC_POINT_FORMAT_SRV_EXTENSION,
448                   "EC handshake test");
449}
450