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_tls13certcomp";
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
34plan skip_all => "$test_name needs compression and algorithms enabled"
35    if disabled("comp") || (disabled("brotli") && disabled("zlib") && disabled("zstd"));
36
37@handmessages = (
38    [TLSProxy::Message::MT_CLIENT_HELLO,
39        checkhandshake::ALL_HANDSHAKES],
40    [TLSProxy::Message::MT_SERVER_HELLO,
41        checkhandshake::ALL_HANDSHAKES],
42    [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS,
43        checkhandshake::ALL_HANDSHAKES],
44    [TLSProxy::Message::MT_CERTIFICATE_REQUEST,
45        checkhandshake::CERT_COMP_CLI_HANDSHAKE | checkhandshake::CERT_COMP_BOTH_HANDSHAKE],
46    [TLSProxy::Message::MT_CERTIFICATE,
47        checkhandshake::ALL_HANDSHAKES & ~(checkhandshake::CERT_COMP_SRV_HANDSHAKE | checkhandshake::CERT_COMP_BOTH_HANDSHAKE)],
48    [TLSProxy::Message::MT_COMPRESSED_CERTIFICATE,
49        checkhandshake::CERT_COMP_SRV_HANDSHAKE | checkhandshake::CERT_COMP_BOTH_HANDSHAKE],
50    [TLSProxy::Message::MT_CERTIFICATE_VERIFY,
51        checkhandshake::ALL_HANDSHAKES],
52    [TLSProxy::Message::MT_FINISHED,
53        checkhandshake::ALL_HANDSHAKES],
54    [TLSProxy::Message::MT_COMPRESSED_CERTIFICATE,
55        checkhandshake::CERT_COMP_CLI_HANDSHAKE | checkhandshake::CERT_COMP_BOTH_HANDSHAKE],
56    [TLSProxy::Message::MT_CERTIFICATE_VERIFY,
57        checkhandshake::CERT_COMP_CLI_HANDSHAKE | checkhandshake::CERT_COMP_BOTH_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    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_COMPRESS_CERTIFICATE,
110        TLSProxy::Message::CLIENT,
111        checkhandshake::CERT_COMP_CLI_EXTENSION],
112    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_RENEGOTIATE,
113        TLSProxy::Message::CLIENT,
114        checkhandshake::DEFAULT_EXTENSIONS],
115
116    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
117        TLSProxy::Message::SERVER,
118        checkhandshake::DEFAULT_EXTENSIONS],
119    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
120        TLSProxy::Message::SERVER,
121        checkhandshake::KEY_SHARE_HRR_EXTENSION],
122
123    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME,
124        TLSProxy::Message::CLIENT,
125        checkhandshake::SERVER_NAME_CLI_EXTENSION],
126    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST,
127        TLSProxy::Message::CLIENT,
128        checkhandshake::STATUS_REQUEST_CLI_EXTENSION],
129    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS,
130        TLSProxy::Message::CLIENT,
131        checkhandshake::DEFAULT_EXTENSIONS],
132    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS,
133        TLSProxy::Message::CLIENT,
134        checkhandshake::DEFAULT_EXTENSIONS],
135    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS,
136        TLSProxy::Message::CLIENT,
137        checkhandshake::DEFAULT_EXTENSIONS],
138    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN,
139        TLSProxy::Message::CLIENT,
140        checkhandshake::ALPN_CLI_EXTENSION],
141    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT,
142        TLSProxy::Message::CLIENT,
143        checkhandshake::SCT_CLI_EXTENSION],
144    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC,
145        TLSProxy::Message::CLIENT,
146        checkhandshake::DEFAULT_EXTENSIONS],
147    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET,
148        TLSProxy::Message::CLIENT,
149        checkhandshake::DEFAULT_EXTENSIONS],
150    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET,
151        TLSProxy::Message::CLIENT,
152        checkhandshake::DEFAULT_EXTENSIONS],
153    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
154        TLSProxy::Message::CLIENT,
155        checkhandshake::DEFAULT_EXTENSIONS],
156    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
157        TLSProxy::Message::CLIENT,
158        checkhandshake::DEFAULT_EXTENSIONS],
159    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES,
160        TLSProxy::Message::CLIENT,
161        checkhandshake::DEFAULT_EXTENSIONS],
162    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK,
163        TLSProxy::Message::CLIENT,
164        checkhandshake::PSK_CLI_EXTENSION],
165    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_POST_HANDSHAKE_AUTH,
166        TLSProxy::Message::CLIENT,
167        checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION],
168    [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_COMPRESS_CERTIFICATE,
169        TLSProxy::Message::CLIENT,
170        checkhandshake::CERT_COMP_CLI_EXTENSION],
171
172    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
173        TLSProxy::Message::SERVER,
174        checkhandshake::DEFAULT_EXTENSIONS],
175    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
176        TLSProxy::Message::SERVER,
177        checkhandshake::DEFAULT_EXTENSIONS],
178    [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_PSK,
179        TLSProxy::Message::SERVER,
180        checkhandshake::PSK_SRV_EXTENSION],
181
182    [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_SERVER_NAME,
183        TLSProxy::Message::SERVER,
184        checkhandshake::SERVER_NAME_SRV_EXTENSION],
185    [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_ALPN,
186        TLSProxy::Message::SERVER,
187        checkhandshake::ALPN_SRV_EXTENSION],
188    [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_SUPPORTED_GROUPS,
189        TLSProxy::Message::SERVER,
190        checkhandshake::SUPPORTED_GROUPS_SRV_EXTENSION],
191
192    [TLSProxy::Message::MT_CERTIFICATE_REQUEST, TLSProxy::Message::EXT_SIG_ALGS,
193        TLSProxy::Message::SERVER,
194        checkhandshake::DEFAULT_EXTENSIONS],
195    [TLSProxy::Message::MT_CERTIFICATE_REQUEST, TLSProxy::Message::EXT_COMPRESS_CERTIFICATE,
196        TLSProxy::Message::SERVER,
197        checkhandshake::CERT_COMP_SRV_EXTENSION],
198
199    [TLSProxy::Message::MT_CERTIFICATE, TLSProxy::Message::EXT_STATUS_REQUEST,
200        TLSProxy::Message::SERVER,
201        checkhandshake::STATUS_REQUEST_SRV_EXTENSION],
202    [TLSProxy::Message::MT_CERTIFICATE, TLSProxy::Message::EXT_SCT,
203        TLSProxy::Message::SERVER,
204        checkhandshake::SCT_SRV_EXTENSION],
205
206    [0,0,0,0]
207);
208
209my $proxy = TLSProxy::Proxy->new(
210    undef,
211    cmdstr(app(["openssl"]), display => 1),
212    srctop_file("apps", "server.pem"),
213    (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
214);
215
216
217#Test 1: Client sends cert comp, but no client auth
218$proxy->serverconnects(2);
219$proxy->clear();
220$proxy->serverflags("-no_tx_cert_comp -no_rx_cert_comp");
221# One final skip check
222$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
223plan tests => 8;
224checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
225               checkhandshake::DEFAULT_EXTENSIONS
226               | checkhandshake::CERT_COMP_CLI_EXTENSION,
227               "Client supports certificate compression");
228
229#Test 2: Server sends cert comp, no client auth
230$proxy->clear();
231$proxy->clientflags("-no_tx_cert_comp -no_rx_cert_comp");
232$proxy->serverflags("-cert_comp");
233$proxy->start();
234checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
235               checkhandshake::DEFAULT_EXTENSIONS
236               | checkhandshake::CERT_COMP_SRV_EXTENSION,
237               "Server supports certificate compression, but no client auth");
238
239#Test 3: Both send cert comp, no client auth
240$proxy->clear();
241$proxy->serverflags("-cert_comp");
242$proxy->start();
243checkhandshake($proxy, checkhandshake::CERT_COMP_SRV_HANDSHAKE,
244               checkhandshake::DEFAULT_EXTENSIONS
245               | checkhandshake::CERT_COMP_CLI_EXTENSION
246               | checkhandshake::CERT_COMP_SRV_EXTENSION,
247               "Both support certificate compression, but no client auth");
248
249#Test 4: Both send cert comp, with client auth
250$proxy->clear();
251$proxy->clientflags("-cert ".srctop_file("apps", "server.pem"));
252$proxy->serverflags("-Verify 5 -cert_comp");
253$proxy->start();
254checkhandshake($proxy, checkhandshake::CERT_COMP_BOTH_HANDSHAKE,
255               checkhandshake::DEFAULT_EXTENSIONS
256               | checkhandshake::CERT_COMP_CLI_EXTENSION
257               | checkhandshake::CERT_COMP_SRV_EXTENSION,
258               "Both support certificate compression, with client auth");
259
260#Test 5: Client-to-server-only certificate compression, with client auth
261$proxy->clear();
262$proxy->clientflags("-no_rx_cert_comp -cert ".srctop_file("apps", "server.pem"));
263$proxy->serverflags("-no_tx_cert_comp -Verify 5 -cert_comp");
264$proxy->start();
265checkhandshake($proxy, checkhandshake::CERT_COMP_CLI_HANDSHAKE,
266               checkhandshake::DEFAULT_EXTENSIONS
267               | checkhandshake::CERT_COMP_SRV_EXTENSION,
268               "Client-to-server-only certificate compression, with client auth");
269
270#Test 6: Server-to-client-only certificate compression
271$proxy->clear();
272$proxy->clientflags("-no_tx_cert_comp");
273$proxy->serverflags("-no_rx_cert_comp -cert_comp");
274$proxy->start();
275checkhandshake($proxy, checkhandshake::CERT_COMP_SRV_HANDSHAKE,
276               checkhandshake::DEFAULT_EXTENSIONS
277               | checkhandshake::CERT_COMP_CLI_EXTENSION,
278               "Server-to-client-only certificate compression");
279
280#Test 7: Neither side wants to send a compressed cert, but will accept one
281$proxy->clear();
282$proxy->clientflags("-no_tx_cert_comp");
283$proxy->serverflags("-no_tx_cert_comp -cert_comp");
284$proxy->start();
285checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
286               checkhandshake::DEFAULT_EXTENSIONS
287               | checkhandshake::CERT_COMP_CLI_EXTENSION
288               | checkhandshake::CERT_COMP_SRV_EXTENSION,
289               "Accept but not send compressed certificates");
290
291#Test 8: Neither side wants to receive a compressed cert, but will send one
292$proxy->clear();
293$proxy->clientflags("-no_rx_cert_comp");
294$proxy->serverflags("-no_rx_cert_comp -cert_comp");
295$proxy->start();
296checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
297               checkhandshake::DEFAULT_EXTENSIONS,
298               "Send but not accept compressed certificates");
299