1e1051a39Sopenharmony_ci#! /usr/bin/env perl
2e1051a39Sopenharmony_ci# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci#
4e1051a39Sopenharmony_ci# Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci# this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci# in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci# https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci
9e1051a39Sopenharmony_ciuse strict;
10e1051a39Sopenharmony_ciuse OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/;
11e1051a39Sopenharmony_ciuse OpenSSL::Test::Utils;
12e1051a39Sopenharmony_ciuse TLSProxy::Proxy;
13e1051a39Sopenharmony_ci
14e1051a39Sopenharmony_cimy $test_name = "test_sslsigalgs";
15e1051a39Sopenharmony_cisetup($test_name);
16e1051a39Sopenharmony_ci
17e1051a39Sopenharmony_ciplan skip_all => "TLSProxy isn't usable on $^O"
18e1051a39Sopenharmony_ci    if $^O =~ /^(VMS)$/;
19e1051a39Sopenharmony_ci
20e1051a39Sopenharmony_ciplan skip_all => "$test_name needs the dynamic engine feature enabled"
21e1051a39Sopenharmony_ci    if disabled("engine") || disabled("dynamic-engine");
22e1051a39Sopenharmony_ci
23e1051a39Sopenharmony_ciplan skip_all => "$test_name needs the sock feature enabled"
24e1051a39Sopenharmony_ci    if disabled("sock");
25e1051a39Sopenharmony_ci
26e1051a39Sopenharmony_ciplan skip_all => "$test_name needs TLS1.2 or TLS1.3 enabled"
27e1051a39Sopenharmony_ci    if disabled("tls1_2") && disabled("tls1_3");
28e1051a39Sopenharmony_ci
29e1051a39Sopenharmony_ci$ENV{OPENSSL_ia32cap} = '~0x200000200000000';
30e1051a39Sopenharmony_cimy $proxy = TLSProxy::Proxy->new(
31e1051a39Sopenharmony_ci    undef,
32e1051a39Sopenharmony_ci    cmdstr(app(["openssl"]), display => 1),
33e1051a39Sopenharmony_ci    srctop_file("apps", "server.pem"),
34e1051a39Sopenharmony_ci    (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
35e1051a39Sopenharmony_ci);
36e1051a39Sopenharmony_ci
37e1051a39Sopenharmony_ciuse constant {
38e1051a39Sopenharmony_ci    NO_SIG_ALGS_EXT => 0,
39e1051a39Sopenharmony_ci    EMPTY_SIG_ALGS_EXT => 1,
40e1051a39Sopenharmony_ci    NO_KNOWN_SIG_ALGS => 2,
41e1051a39Sopenharmony_ci    NO_PSS_SIG_ALGS => 3,
42e1051a39Sopenharmony_ci    PSS_ONLY_SIG_ALGS => 4,
43e1051a39Sopenharmony_ci    PURE_SIGALGS => 5,
44e1051a39Sopenharmony_ci    COMPAT_SIGALGS => 6,
45e1051a39Sopenharmony_ci    SIGALGS_CERT_ALL => 7,
46e1051a39Sopenharmony_ci    SIGALGS_CERT_PKCS => 8,
47e1051a39Sopenharmony_ci    SIGALGS_CERT_INVALID => 9,
48e1051a39Sopenharmony_ci    UNRECOGNIZED_SIGALGS_CERT => 10,
49e1051a39Sopenharmony_ci    UNRECOGNIZED_SIGALG => 11
50e1051a39Sopenharmony_ci};
51e1051a39Sopenharmony_ci
52e1051a39Sopenharmony_ci#Note: Throughout this test we override the default ciphersuites where TLSv1.2
53e1051a39Sopenharmony_ci#      is expected to ensure that a ServerKeyExchange message is sent that uses
54e1051a39Sopenharmony_ci#      the sigalgs
55e1051a39Sopenharmony_ci
56e1051a39Sopenharmony_ci#Test 1: Default sig algs should succeed
57e1051a39Sopenharmony_ci$proxy->clientflags("-no_tls1_3") if disabled("ec") && disabled("dh");
58e1051a39Sopenharmony_ci$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
59e1051a39Sopenharmony_ciplan tests => 26;
60e1051a39Sopenharmony_ciok(TLSProxy::Message->success, "Default sigalgs");
61e1051a39Sopenharmony_cimy $testtype;
62e1051a39Sopenharmony_ci
63e1051a39Sopenharmony_ciSKIP: {
64e1051a39Sopenharmony_ci    skip "TLSv1.3 disabled", 6
65e1051a39Sopenharmony_ci        if disabled("tls1_3") || (disabled("ec") && disabled("dh"));
66e1051a39Sopenharmony_ci
67e1051a39Sopenharmony_ci    $proxy->filter(\&sigalgs_filter);
68e1051a39Sopenharmony_ci
69e1051a39Sopenharmony_ci    #Test 2: Sending no sig algs extension in TLSv1.3 should fail
70e1051a39Sopenharmony_ci    $proxy->clear();
71e1051a39Sopenharmony_ci    $testtype = NO_SIG_ALGS_EXT;
72e1051a39Sopenharmony_ci    $proxy->start();
73e1051a39Sopenharmony_ci    ok(TLSProxy::Message->fail, "No TLSv1.3 sigalgs");
74e1051a39Sopenharmony_ci
75e1051a39Sopenharmony_ci    #Test 3: Sending an empty sig algs extension in TLSv1.3 should fail
76e1051a39Sopenharmony_ci    $proxy->clear();
77e1051a39Sopenharmony_ci    $testtype = EMPTY_SIG_ALGS_EXT;
78e1051a39Sopenharmony_ci    $proxy->start();
79e1051a39Sopenharmony_ci    ok(TLSProxy::Message->fail, "Empty TLSv1.3 sigalgs");
80e1051a39Sopenharmony_ci
81e1051a39Sopenharmony_ci    #Test 4: Sending a list with no recognised sig algs in TLSv1.3 should fail
82e1051a39Sopenharmony_ci    $proxy->clear();
83e1051a39Sopenharmony_ci    $testtype = NO_KNOWN_SIG_ALGS;
84e1051a39Sopenharmony_ci    $proxy->start();
85e1051a39Sopenharmony_ci    ok(TLSProxy::Message->fail, "No known TLSv1.3 sigalgs");
86e1051a39Sopenharmony_ci
87e1051a39Sopenharmony_ci    #Test 5: Sending a sig algs list without pss for an RSA cert in TLSv1.3
88e1051a39Sopenharmony_ci    #        should fail
89e1051a39Sopenharmony_ci    $proxy->clear();
90e1051a39Sopenharmony_ci    $testtype = NO_PSS_SIG_ALGS;
91e1051a39Sopenharmony_ci    $proxy->start();
92e1051a39Sopenharmony_ci    ok(TLSProxy::Message->fail, "No PSS TLSv1.3 sigalgs");
93e1051a39Sopenharmony_ci
94e1051a39Sopenharmony_ci    #Test 6: Sending only TLSv1.3 PSS sig algs in TLSv1.3 should succeed
95e1051a39Sopenharmony_ci    #TODO(TLS1.3): Do we need to verify the cert to make sure its a PSS only
96e1051a39Sopenharmony_ci    #cert in this case?
97e1051a39Sopenharmony_ci    $proxy->clear();
98e1051a39Sopenharmony_ci    $testtype = PSS_ONLY_SIG_ALGS;
99e1051a39Sopenharmony_ci    $proxy->start();
100e1051a39Sopenharmony_ci    ok(TLSProxy::Message->success, "PSS only sigalgs in TLSv1.3");
101e1051a39Sopenharmony_ci
102e1051a39Sopenharmony_ci    #Test 7: Modify the CertificateVerify sigalg from rsa_pss_rsae_sha256 to
103e1051a39Sopenharmony_ci    #        rsa_pss_pss_sha256. This should fail because the public key OID
104e1051a39Sopenharmony_ci    #        in the certificate is rsaEncryption and not rsassaPss
105e1051a39Sopenharmony_ci    $proxy->filter(\&modify_cert_verify_sigalg);
106e1051a39Sopenharmony_ci    $proxy->clear();
107e1051a39Sopenharmony_ci    $proxy->start();
108e1051a39Sopenharmony_ci    ok(TLSProxy::Message->fail,
109e1051a39Sopenharmony_ci       "Mismatch between CertVerify sigalg and public key OID");
110e1051a39Sopenharmony_ci}
111e1051a39Sopenharmony_ci
112e1051a39Sopenharmony_ciSKIP: {
113e1051a39Sopenharmony_ci    skip "EC or TLSv1.3 disabled", 1
114e1051a39Sopenharmony_ci        if disabled("tls1_3") || disabled("ec");
115e1051a39Sopenharmony_ci    #Test 8: Sending a valid sig algs list but not including a sig type that
116e1051a39Sopenharmony_ci    #        matches the certificate should fail in TLSv1.3.
117e1051a39Sopenharmony_ci    $proxy->clear();
118e1051a39Sopenharmony_ci    $proxy->clientflags("-sigalgs ECDSA+SHA256");
119e1051a39Sopenharmony_ci    $proxy->filter(undef);
120e1051a39Sopenharmony_ci    $proxy->start();
121e1051a39Sopenharmony_ci    ok(TLSProxy::Message->fail, "No matching TLSv1.3 sigalgs");
122e1051a39Sopenharmony_ci}
123e1051a39Sopenharmony_ci
124e1051a39Sopenharmony_ciSKIP: {
125e1051a39Sopenharmony_ci    skip "EC, TLSv1.3 or TLSv1.2 disabled", 1
126e1051a39Sopenharmony_ci        if disabled("tls1_2") || disabled("tls1_3") || disabled("ec");
127e1051a39Sopenharmony_ci
128e1051a39Sopenharmony_ci    #Test 9: Sending a full list of TLSv1.3 sig algs but negotiating TLSv1.2
129e1051a39Sopenharmony_ci    #        should succeed
130e1051a39Sopenharmony_ci    $proxy->clear();
131e1051a39Sopenharmony_ci    $proxy->serverflags("-no_tls1_3");
132e1051a39Sopenharmony_ci    $proxy->ciphers("ECDHE-RSA-AES128-SHA");
133e1051a39Sopenharmony_ci    $proxy->filter(undef);
134e1051a39Sopenharmony_ci    $proxy->start();
135e1051a39Sopenharmony_ci    ok(TLSProxy::Message->success, "TLSv1.3 client TLSv1.2 server");
136e1051a39Sopenharmony_ci}
137e1051a39Sopenharmony_ci
138e1051a39Sopenharmony_ciSKIP: {
139e1051a39Sopenharmony_ci    skip "EC or TLSv1.2 disabled", 10 if disabled("tls1_2") || disabled("ec");
140e1051a39Sopenharmony_ci
141e1051a39Sopenharmony_ci    $proxy->filter(\&sigalgs_filter);
142e1051a39Sopenharmony_ci
143e1051a39Sopenharmony_ci    #Test 10: Sending no sig algs extension in TLSv1.2 will make it use
144e1051a39Sopenharmony_ci    #         SHA1, which is only supported at security level 0.
145e1051a39Sopenharmony_ci    $proxy->clear();
146e1051a39Sopenharmony_ci    $testtype = NO_SIG_ALGS_EXT;
147e1051a39Sopenharmony_ci    $proxy->clientflags("-no_tls1_3 -cipher DEFAULT:\@SECLEVEL=0");
148e1051a39Sopenharmony_ci    $proxy->ciphers("ECDHE-RSA-AES128-SHA:\@SECLEVEL=0");
149e1051a39Sopenharmony_ci    $proxy->start();
150e1051a39Sopenharmony_ci    ok(TLSProxy::Message->success, "No TLSv1.2 sigalgs seclevel 0");
151e1051a39Sopenharmony_ci
152e1051a39Sopenharmony_ci    #Test 11: Sending no sig algs extension in TLSv1.2 should fail at security
153e1051a39Sopenharmony_ci    #         level 1 since it will try to use SHA1. Testing client at level 0,
154e1051a39Sopenharmony_ci    #         server level 1.
155e1051a39Sopenharmony_ci    $proxy->clear();
156e1051a39Sopenharmony_ci    $testtype = NO_SIG_ALGS_EXT;
157e1051a39Sopenharmony_ci    $proxy->clientflags("-tls1_2 -cipher DEFAULT:\@SECLEVEL=0");
158e1051a39Sopenharmony_ci    $proxy->ciphers("DEFAULT:\@SECLEVEL=1");
159e1051a39Sopenharmony_ci    $proxy->start();
160e1051a39Sopenharmony_ci    ok(TLSProxy::Message->fail, "No TLSv1.2 sigalgs server seclevel 1");
161e1051a39Sopenharmony_ci
162e1051a39Sopenharmony_ci    #Test 12: Sending no sig algs extension in TLSv1.2 should fail at security
163e1051a39Sopenharmony_ci    #         level 1 since it will try to use SHA1. Testing client at level 1,
164e1051a39Sopenharmony_ci    #         server level 0.
165e1051a39Sopenharmony_ci    $proxy->clear();
166e1051a39Sopenharmony_ci    $testtype = NO_SIG_ALGS_EXT;
167e1051a39Sopenharmony_ci    $proxy->clientflags("-tls1_2 -cipher DEFAULT:\@SECLEVEL=1");
168e1051a39Sopenharmony_ci    $proxy->ciphers("DEFAULT:\@SECLEVEL=0");
169e1051a39Sopenharmony_ci    $proxy->start();
170e1051a39Sopenharmony_ci    ok(TLSProxy::Message->fail, "No TLSv1.2 sigalgs client seclevel 2");
171e1051a39Sopenharmony_ci
172e1051a39Sopenharmony_ci    #Test 13: Sending an empty sig algs extension in TLSv1.2 should fail
173e1051a39Sopenharmony_ci    $proxy->clear();
174e1051a39Sopenharmony_ci    $testtype = EMPTY_SIG_ALGS_EXT;
175e1051a39Sopenharmony_ci    $proxy->clientflags("-no_tls1_3");
176e1051a39Sopenharmony_ci    $proxy->ciphers("ECDHE-RSA-AES128-SHA");
177e1051a39Sopenharmony_ci    $proxy->start();
178e1051a39Sopenharmony_ci    ok(TLSProxy::Message->fail, "Empty TLSv1.2 sigalgs");
179e1051a39Sopenharmony_ci
180e1051a39Sopenharmony_ci    #Test 14: Sending a list with no recognised sig algs in TLSv1.2 should fail
181e1051a39Sopenharmony_ci    $proxy->clear();
182e1051a39Sopenharmony_ci    $testtype = NO_KNOWN_SIG_ALGS;
183e1051a39Sopenharmony_ci    $proxy->clientflags("-no_tls1_3");
184e1051a39Sopenharmony_ci    $proxy->ciphers("ECDHE-RSA-AES128-SHA");
185e1051a39Sopenharmony_ci    $proxy->start();
186e1051a39Sopenharmony_ci    ok(TLSProxy::Message->fail, "No known TLSv1.3 sigalgs");
187e1051a39Sopenharmony_ci
188e1051a39Sopenharmony_ci    #Test 15: Sending a sig algs list without pss for an RSA cert in TLSv1.2
189e1051a39Sopenharmony_ci    #         should succeed
190e1051a39Sopenharmony_ci    $proxy->clear();
191e1051a39Sopenharmony_ci    $testtype = NO_PSS_SIG_ALGS;
192e1051a39Sopenharmony_ci    $proxy->clientflags("-no_tls1_3");
193e1051a39Sopenharmony_ci    $proxy->ciphers("ECDHE-RSA-AES128-SHA");
194e1051a39Sopenharmony_ci    $proxy->start();
195e1051a39Sopenharmony_ci    ok(TLSProxy::Message->success, "No PSS TLSv1.2 sigalgs");
196e1051a39Sopenharmony_ci
197e1051a39Sopenharmony_ci    #Test 16: Sending only TLSv1.3 PSS sig algs in TLSv1.2 should succeed
198e1051a39Sopenharmony_ci    $proxy->clear();
199e1051a39Sopenharmony_ci    $testtype = PSS_ONLY_SIG_ALGS;
200e1051a39Sopenharmony_ci    $proxy->serverflags("-no_tls1_3");
201e1051a39Sopenharmony_ci    $proxy->ciphers("ECDHE-RSA-AES128-SHA");
202e1051a39Sopenharmony_ci    $proxy->start();
203e1051a39Sopenharmony_ci    ok(TLSProxy::Message->success, "PSS only sigalgs in TLSv1.2");
204e1051a39Sopenharmony_ci
205e1051a39Sopenharmony_ci    #Test 17: Responding with a sig alg we did not send in TLSv1.2 should fail
206e1051a39Sopenharmony_ci    #         We send rsa_pkcs1_sha256 and respond with rsa_pss_rsae_sha256
207e1051a39Sopenharmony_ci    #         TODO(TLS1.3): Add a similar test to the TLSv1.3 section above
208e1051a39Sopenharmony_ci    #         when we have an API capable of configuring the TLSv1.3 sig algs
209e1051a39Sopenharmony_ci    $proxy->clear();
210e1051a39Sopenharmony_ci    $testtype = PSS_ONLY_SIG_ALGS;
211e1051a39Sopenharmony_ci    $proxy->clientflags("-no_tls1_3 -sigalgs RSA+SHA256");
212e1051a39Sopenharmony_ci    $proxy->ciphers("ECDHE-RSA-AES128-SHA");
213e1051a39Sopenharmony_ci    $proxy->start();
214e1051a39Sopenharmony_ci    ok(TLSProxy::Message->fail, "Sigalg we did not send in TLSv1.2");
215e1051a39Sopenharmony_ci
216e1051a39Sopenharmony_ci    #Test 18: Sending a valid sig algs list but not including a sig type that
217e1051a39Sopenharmony_ci    #         matches the certificate should fail in TLSv1.2
218e1051a39Sopenharmony_ci    $proxy->clear();
219e1051a39Sopenharmony_ci    $proxy->clientflags("-no_tls1_3 -sigalgs ECDSA+SHA256");
220e1051a39Sopenharmony_ci    $proxy->ciphers("ECDHE-RSA-AES128-SHA");
221e1051a39Sopenharmony_ci    $proxy->filter(undef);
222e1051a39Sopenharmony_ci    $proxy->start();
223e1051a39Sopenharmony_ci    ok(TLSProxy::Message->fail, "No matching TLSv1.2 sigalgs");
224e1051a39Sopenharmony_ci    $proxy->filter(\&sigalgs_filter);
225e1051a39Sopenharmony_ci
226e1051a39Sopenharmony_ci    #Test 19: No sig algs extension, ECDSA cert, will use SHA1,
227e1051a39Sopenharmony_ci    #         TLSv1.2 should succeed at security level 0
228e1051a39Sopenharmony_ci    $proxy->clear();
229e1051a39Sopenharmony_ci    $testtype = NO_SIG_ALGS_EXT;
230e1051a39Sopenharmony_ci    $proxy->clientflags("-no_tls1_3 -cipher DEFAULT:\@SECLEVEL=0");
231e1051a39Sopenharmony_ci    $proxy->serverflags("-cert " . srctop_file("test", "certs",
232e1051a39Sopenharmony_ci                                               "server-ecdsa-cert.pem") .
233e1051a39Sopenharmony_ci                        " -key " . srctop_file("test", "certs",
234e1051a39Sopenharmony_ci                                               "server-ecdsa-key.pem")),
235e1051a39Sopenharmony_ci    $proxy->ciphers("ECDHE-ECDSA-AES128-SHA:\@SECLEVEL=0");
236e1051a39Sopenharmony_ci    $proxy->start();
237e1051a39Sopenharmony_ci    ok(TLSProxy::Message->success, "No TLSv1.2 sigalgs, ECDSA");
238e1051a39Sopenharmony_ci}
239e1051a39Sopenharmony_ci
240e1051a39Sopenharmony_cimy ($dsa_status, $sha1_status, $sha224_status);
241e1051a39Sopenharmony_ciSKIP: {
242e1051a39Sopenharmony_ci    skip "TLSv1.3 disabled", 2
243e1051a39Sopenharmony_ci        if disabled("tls1_3")
244e1051a39Sopenharmony_ci           || disabled("dsa")
245e1051a39Sopenharmony_ci           || (disabled("ec") && disabled("dh"));
246e1051a39Sopenharmony_ci    #Test 20: signature_algorithms with 1.3-only ClientHello
247e1051a39Sopenharmony_ci    $testtype = PURE_SIGALGS;
248e1051a39Sopenharmony_ci    $dsa_status = $sha1_status = $sha224_status = 0;
249e1051a39Sopenharmony_ci    $proxy->clear();
250e1051a39Sopenharmony_ci    $proxy->clientflags("-tls1_3");
251e1051a39Sopenharmony_ci    $proxy->filter(\&modify_sigalgs_filter);
252e1051a39Sopenharmony_ci    $proxy->start();
253e1051a39Sopenharmony_ci    ok($dsa_status && $sha1_status && $sha224_status,
254e1051a39Sopenharmony_ci       "DSA and SHA1 sigalgs not sent for 1.3-only ClientHello");
255e1051a39Sopenharmony_ci
256e1051a39Sopenharmony_ci    #Test 21: signature_algorithms with backwards compatible ClientHello
257e1051a39Sopenharmony_ci    SKIP: {
258e1051a39Sopenharmony_ci        skip "TLSv1.2 disabled", 1 if disabled("tls1_2");
259e1051a39Sopenharmony_ci        $testtype = COMPAT_SIGALGS;
260e1051a39Sopenharmony_ci        $dsa_status = $sha1_status = $sha224_status = 0;
261e1051a39Sopenharmony_ci        $proxy->clear();
262e1051a39Sopenharmony_ci        $proxy->clientflags("-cipher AES128-SHA\@SECLEVEL=0");
263e1051a39Sopenharmony_ci        $proxy->filter(\&modify_sigalgs_filter);
264e1051a39Sopenharmony_ci        $proxy->start();
265e1051a39Sopenharmony_ci        ok($dsa_status && $sha1_status && $sha224_status,
266e1051a39Sopenharmony_ci           "backwards compatible sigalg sent for compat ClientHello");
267e1051a39Sopenharmony_ci   }
268e1051a39Sopenharmony_ci}
269e1051a39Sopenharmony_ci
270e1051a39Sopenharmony_ciSKIP: {
271e1051a39Sopenharmony_ci    skip "TLSv1.3 disabled", 5
272e1051a39Sopenharmony_ci        if disabled("tls1_3") || (disabled("ec") && disabled("dh"));
273e1051a39Sopenharmony_ci    #Test 22: Insert signature_algorithms_cert that match normal sigalgs
274e1051a39Sopenharmony_ci    $testtype = SIGALGS_CERT_ALL;
275e1051a39Sopenharmony_ci    $proxy->clear();
276e1051a39Sopenharmony_ci    $proxy->filter(\&modify_sigalgs_cert_filter);
277e1051a39Sopenharmony_ci    $proxy->start();
278e1051a39Sopenharmony_ci    ok(TLSProxy::Message->success, "sigalgs_cert in TLSv1.3");
279e1051a39Sopenharmony_ci
280e1051a39Sopenharmony_ci    #Test 23: Insert signature_algorithms_cert that forces PKCS#1 cert
281e1051a39Sopenharmony_ci    $testtype = SIGALGS_CERT_PKCS;
282e1051a39Sopenharmony_ci    $proxy->clear();
283e1051a39Sopenharmony_ci    $proxy->filter(\&modify_sigalgs_cert_filter);
284e1051a39Sopenharmony_ci    $proxy->start();
285e1051a39Sopenharmony_ci    ok(TLSProxy::Message->success, "sigalgs_cert in TLSv1.3 with PKCS#1 cert");
286e1051a39Sopenharmony_ci
287e1051a39Sopenharmony_ci    #Test 24: Insert signature_algorithms_cert that fails
288e1051a39Sopenharmony_ci    $testtype = SIGALGS_CERT_INVALID;
289e1051a39Sopenharmony_ci    $proxy->clear();
290e1051a39Sopenharmony_ci    $proxy->filter(\&modify_sigalgs_cert_filter);
291e1051a39Sopenharmony_ci    $proxy->start();
292e1051a39Sopenharmony_ci    ok(TLSProxy::Message->fail, "No matching certificate for sigalgs_cert");
293e1051a39Sopenharmony_ci
294e1051a39Sopenharmony_ci    #Test 25: Send an unrecognized signature_algorithms_cert
295e1051a39Sopenharmony_ci    #        We should be able to skip over the unrecognized value and use a
296e1051a39Sopenharmony_ci    #        valid one that appears later in the list.
297e1051a39Sopenharmony_ci    $proxy->clear();
298e1051a39Sopenharmony_ci    $proxy->filter(\&inject_unrecognized_sigalg);
299e1051a39Sopenharmony_ci    $proxy->clientflags("-tls1_3");
300e1051a39Sopenharmony_ci    # Use -xcert to get SSL_check_chain() to run in the cert_cb.  This is
301e1051a39Sopenharmony_ci    # needed to trigger (e.g.) CVE-2020-1967
302e1051a39Sopenharmony_ci    $proxy->serverflags("" .
303e1051a39Sopenharmony_ci            " -xcert " . srctop_file("test", "certs", "servercert.pem") .
304e1051a39Sopenharmony_ci            " -xkey " . srctop_file("test", "certs", "serverkey.pem") .
305e1051a39Sopenharmony_ci            " -xchain " . srctop_file("test", "certs", "rootcert.pem"));
306e1051a39Sopenharmony_ci    $testtype = UNRECOGNIZED_SIGALGS_CERT;
307e1051a39Sopenharmony_ci    $proxy->start();
308e1051a39Sopenharmony_ci    ok(TLSProxy::Message->success(), "Unrecognized sigalg_cert in ClientHello");
309e1051a39Sopenharmony_ci
310e1051a39Sopenharmony_ci    #Test 26: Send an unrecognized signature_algorithms
311e1051a39Sopenharmony_ci    #        We should be able to skip over the unrecognized value and use a
312e1051a39Sopenharmony_ci    #        valid one that appears later in the list.
313e1051a39Sopenharmony_ci    $proxy->clear();
314e1051a39Sopenharmony_ci    $proxy->filter(\&inject_unrecognized_sigalg);
315e1051a39Sopenharmony_ci    $proxy->clientflags("-tls1_3");
316e1051a39Sopenharmony_ci    $proxy->serverflags("" .
317e1051a39Sopenharmony_ci            " -xcert " . srctop_file("test", "certs", "servercert.pem") .
318e1051a39Sopenharmony_ci            " -xkey " . srctop_file("test", "certs", "serverkey.pem") .
319e1051a39Sopenharmony_ci            " -xchain " . srctop_file("test", "certs", "rootcert.pem"));
320e1051a39Sopenharmony_ci    $testtype = UNRECOGNIZED_SIGALG;
321e1051a39Sopenharmony_ci    $proxy->start();
322e1051a39Sopenharmony_ci    ok(TLSProxy::Message->success(), "Unrecognized sigalg in ClientHello");
323e1051a39Sopenharmony_ci}
324e1051a39Sopenharmony_ci
325e1051a39Sopenharmony_ci
326e1051a39Sopenharmony_ci
327e1051a39Sopenharmony_cisub sigalgs_filter
328e1051a39Sopenharmony_ci{
329e1051a39Sopenharmony_ci    my $proxy = shift;
330e1051a39Sopenharmony_ci
331e1051a39Sopenharmony_ci    # We're only interested in the initial ClientHello
332e1051a39Sopenharmony_ci    if ($proxy->flight != 0) {
333e1051a39Sopenharmony_ci        return;
334e1051a39Sopenharmony_ci    }
335e1051a39Sopenharmony_ci
336e1051a39Sopenharmony_ci    foreach my $message (@{$proxy->message_list}) {
337e1051a39Sopenharmony_ci        if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) {
338e1051a39Sopenharmony_ci            if ($testtype == NO_SIG_ALGS_EXT) {
339e1051a39Sopenharmony_ci                $message->delete_extension(TLSProxy::Message::EXT_SIG_ALGS);
340e1051a39Sopenharmony_ci            } else {
341e1051a39Sopenharmony_ci                my $sigalg;
342e1051a39Sopenharmony_ci                if ($testtype == EMPTY_SIG_ALGS_EXT) {
343e1051a39Sopenharmony_ci                    $sigalg = pack "C2", 0x00, 0x00;
344e1051a39Sopenharmony_ci                } elsif ($testtype == NO_KNOWN_SIG_ALGS) {
345e1051a39Sopenharmony_ci                    $sigalg = pack "C4", 0x00, 0x02, 0xff, 0xff;
346e1051a39Sopenharmony_ci                } elsif ($testtype == NO_PSS_SIG_ALGS) {
347e1051a39Sopenharmony_ci                    #No PSS sig algs - just send rsa_pkcs1_sha256
348e1051a39Sopenharmony_ci                    $sigalg = pack "C4", 0x00, 0x02, 0x04, 0x01;
349e1051a39Sopenharmony_ci                } else {
350e1051a39Sopenharmony_ci                    #PSS sig algs only - just send rsa_pss_rsae_sha256
351e1051a39Sopenharmony_ci                    $sigalg = pack "C4", 0x00, 0x02, 0x08, 0x04;
352e1051a39Sopenharmony_ci                }
353e1051a39Sopenharmony_ci                $message->set_extension(TLSProxy::Message::EXT_SIG_ALGS, $sigalg);
354e1051a39Sopenharmony_ci            }
355e1051a39Sopenharmony_ci
356e1051a39Sopenharmony_ci            $message->repack();
357e1051a39Sopenharmony_ci        }
358e1051a39Sopenharmony_ci    }
359e1051a39Sopenharmony_ci}
360e1051a39Sopenharmony_ci
361e1051a39Sopenharmony_cisub modify_sigalgs_filter
362e1051a39Sopenharmony_ci{
363e1051a39Sopenharmony_ci    my $proxy = shift;
364e1051a39Sopenharmony_ci
365e1051a39Sopenharmony_ci    # We're only interested in the initial ClientHello
366e1051a39Sopenharmony_ci    return if ($proxy->flight != 0);
367e1051a39Sopenharmony_ci
368e1051a39Sopenharmony_ci    foreach my $message (@{$proxy->message_list}) {
369e1051a39Sopenharmony_ci        my $ext;
370e1051a39Sopenharmony_ci        my @algs;
371e1051a39Sopenharmony_ci
372e1051a39Sopenharmony_ci        if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) {
373e1051a39Sopenharmony_ci            if ($testtype == PURE_SIGALGS) {
374e1051a39Sopenharmony_ci                my $ok = 1;
375e1051a39Sopenharmony_ci                $ext = $message->extension_data->{TLSProxy::Message::EXT_SIG_ALGS};
376e1051a39Sopenharmony_ci                @algs = unpack('S>*', $ext);
377e1051a39Sopenharmony_ci                # unpack will unpack the length as well
378e1051a39Sopenharmony_ci                shift @algs;
379e1051a39Sopenharmony_ci                foreach (@algs) {
380e1051a39Sopenharmony_ci                    if ($_ == TLSProxy::Message::SIG_ALG_DSA_SHA256
381e1051a39Sopenharmony_ci                        || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA384
382e1051a39Sopenharmony_ci                        || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA512
383e1051a39Sopenharmony_ci                        || $_ == TLSProxy::Message::OSSL_SIG_ALG_DSA_SHA224
384e1051a39Sopenharmony_ci                        || $_ == TLSProxy::Message::SIG_ALG_RSA_PKCS1_SHA1
385e1051a39Sopenharmony_ci                        || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA1
386e1051a39Sopenharmony_ci                        || $_ == TLSProxy::Message::SIG_ALG_ECDSA_SHA1) {
387e1051a39Sopenharmony_ci                        $ok = 0;
388e1051a39Sopenharmony_ci                    }
389e1051a39Sopenharmony_ci                }
390e1051a39Sopenharmony_ci                $sha1_status = $dsa_status = $sha224_status = 1 if ($ok);
391e1051a39Sopenharmony_ci            } elsif ($testtype == COMPAT_SIGALGS) {
392e1051a39Sopenharmony_ci                $ext = $message->extension_data->{TLSProxy::Message::EXT_SIG_ALGS};
393e1051a39Sopenharmony_ci                @algs = unpack('S>*', $ext);
394e1051a39Sopenharmony_ci                # unpack will unpack the length as well
395e1051a39Sopenharmony_ci                shift @algs;
396e1051a39Sopenharmony_ci                foreach (@algs) {
397e1051a39Sopenharmony_ci                    if ($_ == TLSProxy::Message::SIG_ALG_DSA_SHA256
398e1051a39Sopenharmony_ci                        || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA384
399e1051a39Sopenharmony_ci                        || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA512) {
400e1051a39Sopenharmony_ci                        $dsa_status = 1;
401e1051a39Sopenharmony_ci                    }
402e1051a39Sopenharmony_ci                    if ($_ == TLSProxy::Message::SIG_ALG_RSA_PKCS1_SHA1
403e1051a39Sopenharmony_ci                        || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA1
404e1051a39Sopenharmony_ci                        || $_ == TLSProxy::Message::SIG_ALG_ECDSA_SHA1) {
405e1051a39Sopenharmony_ci                        $sha1_status = 1;
406e1051a39Sopenharmony_ci                    }
407e1051a39Sopenharmony_ci                    if ($_ == TLSProxy::Message::OSSL_SIG_ALG_RSA_PKCS1_SHA224
408e1051a39Sopenharmony_ci                        || $_ == TLSProxy::Message::OSSL_SIG_ALG_DSA_SHA224
409e1051a39Sopenharmony_ci                        || $_ == TLSProxy::Message::OSSL_SIG_ALG_ECDSA_SHA224) {
410e1051a39Sopenharmony_ci                        $sha224_status = 1;
411e1051a39Sopenharmony_ci                    }
412e1051a39Sopenharmony_ci                }
413e1051a39Sopenharmony_ci            }
414e1051a39Sopenharmony_ci        }
415e1051a39Sopenharmony_ci    }
416e1051a39Sopenharmony_ci}
417e1051a39Sopenharmony_ci
418e1051a39Sopenharmony_cisub modify_sigalgs_cert_filter
419e1051a39Sopenharmony_ci{
420e1051a39Sopenharmony_ci    my $proxy = shift;
421e1051a39Sopenharmony_ci
422e1051a39Sopenharmony_ci    # We're only interested in the initial ClientHello
423e1051a39Sopenharmony_ci    if ($proxy->flight != 0) {
424e1051a39Sopenharmony_ci        return;
425e1051a39Sopenharmony_ci    }
426e1051a39Sopenharmony_ci
427e1051a39Sopenharmony_ci    foreach my $message (@{$proxy->message_list}) {
428e1051a39Sopenharmony_ci        if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) {
429e1051a39Sopenharmony_ci            my $sigs;
430e1051a39Sopenharmony_ci            # two byte length at front of sigs, then two-byte sigschemes
431e1051a39Sopenharmony_ci            if ($testtype == SIGALGS_CERT_ALL) {
432e1051a39Sopenharmony_ci                $sigs = pack "C26", 0x00, 0x18,
433e1051a39Sopenharmony_ci                             # rsa_pkcs_sha{256,512}  rsa_pss_rsae_sha{256,512}
434e1051a39Sopenharmony_ci                             0x04, 0x01,  0x06, 0x01,  0x08, 0x04,  0x08, 0x06,
435e1051a39Sopenharmony_ci                             # ed25518    ed448        rsa_pss_pss_sha{256,512}
436e1051a39Sopenharmony_ci                             0x08, 0x07,  0x08, 0x08,  0x08, 0x09,  0x08, 0x0b,
437e1051a39Sopenharmony_ci                             # ecdsa_secp{256,512}     rsa+sha1     ecdsa+sha1
438e1051a39Sopenharmony_ci                             0x04, 0x03,  0x06, 0x03,  0x02, 0x01,  0x02, 0x03;
439e1051a39Sopenharmony_ci            } elsif ($testtype == SIGALGS_CERT_PKCS) {
440e1051a39Sopenharmony_ci                $sigs = pack "C10", 0x00, 0x08,
441e1051a39Sopenharmony_ci                             # rsa_pkcs_sha{256,384,512,1}
442e1051a39Sopenharmony_ci                             0x04, 0x01,  0x05, 0x01,  0x06, 0x01,  0x02, 0x01;
443e1051a39Sopenharmony_ci            } elsif ($testtype == SIGALGS_CERT_INVALID) {
444e1051a39Sopenharmony_ci                $sigs = pack "C4", 0x00, 0x02,
445e1051a39Sopenharmony_ci                             # unregistered codepoint
446e1051a39Sopenharmony_ci                             0xb2, 0x6f;
447e1051a39Sopenharmony_ci            }
448e1051a39Sopenharmony_ci            $message->set_extension(TLSProxy::Message::EXT_SIG_ALGS_CERT, $sigs);
449e1051a39Sopenharmony_ci            $message->repack();
450e1051a39Sopenharmony_ci        }
451e1051a39Sopenharmony_ci    }
452e1051a39Sopenharmony_ci}
453e1051a39Sopenharmony_ci
454e1051a39Sopenharmony_cisub modify_cert_verify_sigalg
455e1051a39Sopenharmony_ci{
456e1051a39Sopenharmony_ci    my $proxy = shift;
457e1051a39Sopenharmony_ci
458e1051a39Sopenharmony_ci    # We're only interested in the CertificateVerify
459e1051a39Sopenharmony_ci    if ($proxy->flight != 1) {
460e1051a39Sopenharmony_ci        return;
461e1051a39Sopenharmony_ci    }
462e1051a39Sopenharmony_ci
463e1051a39Sopenharmony_ci    foreach my $message (@{$proxy->message_list}) {
464e1051a39Sopenharmony_ci        if ($message->mt == TLSProxy::Message::MT_CERTIFICATE_VERIFY) {
465e1051a39Sopenharmony_ci            $message->sigalg(TLSProxy::Message::SIG_ALG_RSA_PSS_PSS_SHA256);
466e1051a39Sopenharmony_ci            $message->repack();
467e1051a39Sopenharmony_ci        }
468e1051a39Sopenharmony_ci    }
469e1051a39Sopenharmony_ci}
470e1051a39Sopenharmony_ci
471e1051a39Sopenharmony_cisub inject_unrecognized_sigalg
472e1051a39Sopenharmony_ci{
473e1051a39Sopenharmony_ci    my $proxy = shift;
474e1051a39Sopenharmony_ci    my $type;
475e1051a39Sopenharmony_ci
476e1051a39Sopenharmony_ci    # We're only interested in the initial ClientHello
477e1051a39Sopenharmony_ci    if ($proxy->flight != 0) {
478e1051a39Sopenharmony_ci        return;
479e1051a39Sopenharmony_ci    }
480e1051a39Sopenharmony_ci    if ($testtype == UNRECOGNIZED_SIGALGS_CERT) {
481e1051a39Sopenharmony_ci        $type = TLSProxy::Message::EXT_SIG_ALGS_CERT;
482e1051a39Sopenharmony_ci    } elsif ($testtype == UNRECOGNIZED_SIGALG) {
483e1051a39Sopenharmony_ci        $type = TLSProxy::Message::EXT_SIG_ALGS;
484e1051a39Sopenharmony_ci    } else {
485e1051a39Sopenharmony_ci        return;
486e1051a39Sopenharmony_ci    }
487e1051a39Sopenharmony_ci
488e1051a39Sopenharmony_ci    my $ext = pack "C8",
489e1051a39Sopenharmony_ci        0x00, 0x06, #Extension length
490e1051a39Sopenharmony_ci        0xfe, 0x18, #private use
491e1051a39Sopenharmony_ci        0x04, 0x01, #rsa_pkcs1_sha256
492e1051a39Sopenharmony_ci        0x08, 0x04; #rsa_pss_rsae_sha256;
493e1051a39Sopenharmony_ci    my $message = ${$proxy->message_list}[0];
494e1051a39Sopenharmony_ci    $message->set_extension($type, $ext);
495e1051a39Sopenharmony_ci    $message->repack;
496e1051a39Sopenharmony_ci}
497