]>
Commit | Line | Data |
---|---|---|
bc349281 | 1 | #! /usr/bin/env perl |
7ed6de99 | 2 | # Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. |
bc349281 | 3 | # |
909f1a2e | 4 | # Licensed under the Apache License 2.0 (the "License"). You may not use |
bc349281 MC |
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; | |
972ee925 | 10 | use List::Util 'first'; |
bc349281 MC |
11 | use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/; |
12 | use OpenSSL::Test::Utils; | |
13 | use TLSProxy::Proxy; | |
14 | ||
15 | my $test_name = "test_renegotiation"; | |
16 | setup($test_name); | |
17 | ||
18 | plan skip_all => "TLSProxy isn't usable on $^O" | |
c5856878 | 19 | if $^O =~ /^(VMS)$/; |
bc349281 MC |
20 | |
21 | plan skip_all => "$test_name needs the dynamic engine feature enabled" | |
22 | if disabled("engine") || disabled("dynamic-engine"); | |
23 | ||
24 | plan skip_all => "$test_name needs the sock feature enabled" | |
25 | if disabled("sock"); | |
26 | ||
27 | plan skip_all => "$test_name needs TLS <= 1.2 enabled" | |
28 | if alldisabled(("ssl3", "tls1", "tls1_1", "tls1_2")); | |
29 | ||
972ee925 | 30 | plan tests => 9; |
55373bfd | 31 | |
bc349281 MC |
32 | my $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 | #Test 1: A basic renegotiation test | |
40 | $proxy->clientflags("-no_tls1_3"); | |
55373bfd | 41 | $proxy->serverflags("-client_renegotiation"); |
bc349281 MC |
42 | $proxy->reneg(1); |
43 | $proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; | |
bc349281 MC |
44 | ok(TLSProxy::Message->success(), "Basic renegotiation"); |
45 | ||
972ee925 | 46 | #Test 2: Seclevel 0 client does not send the Reneg SCSV. Reneg should fail |
bc349281 | 47 | $proxy->clear(); |
972ee925 TP |
48 | $proxy->filter(\&reneg_scsv_filter); |
49 | $proxy->cipherc("DEFAULT:\@SECLEVEL=0"); | |
bc349281 | 50 | $proxy->clientflags("-no_tls1_3"); |
55373bfd | 51 | $proxy->serverflags("-client_renegotiation"); |
bc349281 MC |
52 | $proxy->reneg(1); |
53 | $proxy->start(); | |
54 | ok(TLSProxy::Message->fail(), "No client SCSV"); | |
55 | ||
972ee925 TP |
56 | SKIP: { |
57 | skip "TLSv1.2 disabled", 1 | |
58 | if disabled("tls1_2"); | |
59 | ||
60 | #Test 3: TLS 1.2 client does not send the Reneg extension. Reneg should fail | |
61 | ||
62 | $proxy->clear(); | |
63 | $proxy->filter(\&reneg_ext_filter); | |
64 | $proxy->clientflags("-no_tls1_3"); | |
65 | $proxy->serverflags("-client_renegotiation"); | |
66 | $proxy->reneg(1); | |
67 | $proxy->start(); | |
68 | ok(TLSProxy::Message->fail(), "No client extension"); | |
69 | } | |
70 | ||
6862de63 MC |
71 | SKIP: { |
72 | skip "TLSv1.2 or TLSv1.1 disabled", 1 | |
73 | if disabled("tls1_2") || disabled("tls1_1"); | |
972ee925 | 74 | #Test 4: Check that the ClientHello version remains the same in the reneg |
6862de63 MC |
75 | # handshake |
76 | $proxy->clear(); | |
77 | $proxy->filter(undef); | |
aba03ae5 KR |
78 | $proxy->ciphers("DEFAULT:\@SECLEVEL=0"); |
79 | $proxy->clientflags("-no_tls1_3 -cipher AES128-SHA:\@SECLEVEL=0"); | |
55373bfd | 80 | $proxy->serverflags("-no_tls1_3 -no_tls1_2 -client_renegotiation"); |
6862de63 MC |
81 | $proxy->reneg(1); |
82 | $proxy->start(); | |
83 | my $chversion; | |
84 | my $chmatch = 0; | |
85 | foreach my $message (@{$proxy->message_list}) { | |
86 | if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) { | |
87 | if (!defined $chversion) { | |
88 | $chversion = $message->client_version; | |
89 | } else { | |
90 | if ($chversion == $message->client_version) { | |
91 | $chmatch = 1; | |
92 | } | |
93 | } | |
94 | } | |
95 | } | |
96 | ok(TLSProxy::Message->success() && $chmatch, | |
97 | "Check ClientHello version is the same"); | |
98 | } | |
99 | ||
112580c2 MC |
100 | SKIP: { |
101 | skip "TLSv1.2 disabled", 1 | |
102 | if disabled("tls1_2"); | |
103 | ||
972ee925 | 104 | #Test 5: Test for CVE-2021-3449. client_sig_algs instead of sig_algs in |
112580c2 MC |
105 | # resumption ClientHello |
106 | $proxy->clear(); | |
107 | $proxy->filter(\&sigalgs_filter); | |
108 | $proxy->clientflags("-tls1_2"); | |
55373bfd | 109 | $proxy->serverflags("-client_renegotiation"); |
112580c2 MC |
110 | $proxy->reneg(1); |
111 | $proxy->start(); | |
112 | ok(TLSProxy::Message->fail(), "client_sig_algs instead of sig_algs"); | |
113 | } | |
114 | ||
55373bfd RS |
115 | SKIP: { |
116 | skip "TLSv1.2 and TLSv1.1 disabled", 1 | |
117 | if disabled("tls1_2") && disabled("tls1_1"); | |
972ee925 | 118 | #Test 6: Client fails to do renegotiation |
55373bfd RS |
119 | $proxy->clear(); |
120 | $proxy->filter(undef); | |
121 | $proxy->serverflags("-no_tls1_3"); | |
122 | $proxy->clientflags("-no_tls1_3"); | |
123 | $proxy->reneg(1); | |
124 | $proxy->start(); | |
125 | ok(TLSProxy::Message->fail(), | |
126 | "Check client renegotiation failed"); | |
127 | } | |
128 | ||
972ee925 TP |
129 | SKIP: { |
130 | skip "TLSv1 disabled", 1 | |
131 | if disabled("tls1"); | |
132 | ||
133 | #Test 7: Check that SECLEVEL 0 sends SCSV not RI extension | |
134 | $proxy->clear(); | |
135 | $proxy->filter(undef); | |
136 | $proxy->cipherc("DEFAULT:\@SECLEVEL=0"); | |
137 | $proxy->start(); | |
138 | ||
139 | my $clientHello = first { $_->mt == TLSProxy::Message::MT_CLIENT_HELLO } @{$proxy->message_list}; | |
140 | my $has_scsv = 255 ~~ @{$clientHello->ciphersuites}; | |
141 | my $has_ri_extension = exists $clientHello->extension_data()->{TLSProxy::Message::EXT_RENEGOTIATE}; | |
142 | ||
143 | ok($has_scsv && !$has_ri_extension, "SECLEVEL=0 should use SCSV not RI extension by default"); | |
144 | } | |
145 | ||
146 | SKIP: { | |
147 | skip "TLSv1.2 disabled", 1 | |
148 | if disabled("tls1_2"); | |
149 | ||
150 | #Test 8: Check that SECLEVEL0 + TLS 1.2 sends RI extension not SCSV | |
151 | $proxy->clear(); | |
152 | $proxy->filter(undef); | |
153 | $proxy->cipherc("DEFAULT:\@SECLEVEL=0"); | |
154 | $proxy->clientflags("-tls1_2"); | |
155 | $proxy->start(); | |
156 | ||
157 | my $clientHello = first { $_->mt == TLSProxy::Message::MT_CLIENT_HELLO } @{$proxy->message_list}; | |
158 | my $has_scsv = 255 ~~ @{$clientHello->ciphersuites}; | |
159 | my $has_ri_extension = exists $clientHello->extension_data()->{TLSProxy::Message::EXT_RENEGOTIATE}; | |
160 | ||
161 | ok(!$has_scsv && $has_ri_extension, "TLS1.2 should use RI extension despite SECLEVEL=0"); | |
162 | } | |
163 | ||
164 | ||
165 | SKIP: { | |
166 | skip "TLSv1.3 disabled", 1 | |
167 | if disabled("tls1_3"); | |
168 | ||
169 | #Test 9: Check that TLS 1.3 sends neither RI extension nor SCSV | |
170 | $proxy->clear(); | |
171 | $proxy->filter(undef); | |
172 | $proxy->clientflags("-tls1_3"); | |
173 | $proxy->start(); | |
174 | ||
175 | my $clientHello = first { $_->mt == TLSProxy::Message::MT_CLIENT_HELLO } @{$proxy->message_list}; | |
176 | my $has_scsv = 255 ~~ @{$clientHello->ciphersuites}; | |
177 | my $has_ri_extension = exists $clientHello->extension_data()->{TLSProxy::Message::EXT_RENEGOTIATE}; | |
178 | ||
179 | ok(!$has_scsv && !$has_ri_extension, "TLS1.3 should not use RI extension or SCSV"); | |
180 | } | |
181 | ||
182 | sub reneg_scsv_filter | |
bc349281 MC |
183 | { |
184 | my $proxy = shift; | |
185 | ||
186 | # We're only interested in the initial ClientHello message | |
187 | if ($proxy->flight != 0) { | |
188 | return; | |
189 | } | |
190 | ||
191 | foreach my $message (@{$proxy->message_list}) { | |
192 | if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) { | |
193 | #Remove any SCSV ciphersuites - just leave AES128-SHA (0x002f) | |
194 | my @ciphersuite = (0x002f); | |
195 | $message->ciphersuites(\@ciphersuite); | |
196 | $message->ciphersuite_len(2); | |
197 | $message->repack(); | |
198 | } | |
199 | } | |
200 | } | |
112580c2 | 201 | |
972ee925 TP |
202 | sub reneg_ext_filter |
203 | { | |
204 | my $proxy = shift; | |
205 | ||
206 | # We're only interested in the initial ClientHello message | |
207 | if ($proxy->flight != 0) { | |
208 | return; | |
209 | } | |
210 | ||
211 | foreach my $message (@{$proxy->message_list}) { | |
212 | if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) { | |
213 | $message->delete_extension(TLSProxy::Message::EXT_RENEGOTIATE); | |
214 | $message->repack(); | |
215 | } | |
216 | } | |
217 | } | |
218 | ||
112580c2 MC |
219 | sub sigalgs_filter |
220 | { | |
221 | my $proxy = shift; | |
222 | my $cnt = 0; | |
223 | ||
224 | # We're only interested in the second ClientHello message | |
225 | foreach my $message (@{$proxy->message_list}) { | |
226 | if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) { | |
227 | next if ($cnt++ == 0); | |
228 | ||
229 | my $sigs = pack "C10", 0x00, 0x08, | |
230 | # rsa_pkcs_sha{256,384,512,1} | |
231 | 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x02, 0x01; | |
232 | $message->set_extension(TLSProxy::Message::EXT_SIG_ALGS_CERT, $sigs); | |
233 | $message->delete_extension(TLSProxy::Message::EXT_SIG_ALGS); | |
234 | $message->repack(); | |
235 | } | |
236 | } | |
237 | } |