xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_utils_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/core/crypto/crypto_utils.h"
6 
7 #include <string>
8 
9 #include "absl/base/macros.h"
10 #include "absl/strings/escaping.h"
11 #include "absl/strings/string_view.h"
12 #include "quiche/quic/core/quic_utils.h"
13 #include "quiche/quic/platform/api/quic_test.h"
14 #include "quiche/quic/test_tools/quic_test_utils.h"
15 #include "quiche/common/test_tools/quiche_test_utils.h"
16 
17 namespace quic {
18 namespace test {
19 namespace {
20 
21 class CryptoUtilsTest : public QuicTest {};
22 
TEST_F(CryptoUtilsTest,HandshakeFailureReasonToString)23 TEST_F(CryptoUtilsTest, HandshakeFailureReasonToString) {
24   EXPECT_STREQ("HANDSHAKE_OK",
25                CryptoUtils::HandshakeFailureReasonToString(HANDSHAKE_OK));
26   EXPECT_STREQ("CLIENT_NONCE_UNKNOWN_FAILURE",
27                CryptoUtils::HandshakeFailureReasonToString(
28                    CLIENT_NONCE_UNKNOWN_FAILURE));
29   EXPECT_STREQ("CLIENT_NONCE_INVALID_FAILURE",
30                CryptoUtils::HandshakeFailureReasonToString(
31                    CLIENT_NONCE_INVALID_FAILURE));
32   EXPECT_STREQ("CLIENT_NONCE_NOT_UNIQUE_FAILURE",
33                CryptoUtils::HandshakeFailureReasonToString(
34                    CLIENT_NONCE_NOT_UNIQUE_FAILURE));
35   EXPECT_STREQ("CLIENT_NONCE_INVALID_ORBIT_FAILURE",
36                CryptoUtils::HandshakeFailureReasonToString(
37                    CLIENT_NONCE_INVALID_ORBIT_FAILURE));
38   EXPECT_STREQ("CLIENT_NONCE_INVALID_TIME_FAILURE",
39                CryptoUtils::HandshakeFailureReasonToString(
40                    CLIENT_NONCE_INVALID_TIME_FAILURE));
41   EXPECT_STREQ("CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT",
42                CryptoUtils::HandshakeFailureReasonToString(
43                    CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT));
44   EXPECT_STREQ("CLIENT_NONCE_STRIKE_REGISTER_FAILURE",
45                CryptoUtils::HandshakeFailureReasonToString(
46                    CLIENT_NONCE_STRIKE_REGISTER_FAILURE));
47   EXPECT_STREQ("SERVER_NONCE_DECRYPTION_FAILURE",
48                CryptoUtils::HandshakeFailureReasonToString(
49                    SERVER_NONCE_DECRYPTION_FAILURE));
50   EXPECT_STREQ("SERVER_NONCE_INVALID_FAILURE",
51                CryptoUtils::HandshakeFailureReasonToString(
52                    SERVER_NONCE_INVALID_FAILURE));
53   EXPECT_STREQ("SERVER_NONCE_NOT_UNIQUE_FAILURE",
54                CryptoUtils::HandshakeFailureReasonToString(
55                    SERVER_NONCE_NOT_UNIQUE_FAILURE));
56   EXPECT_STREQ("SERVER_NONCE_INVALID_TIME_FAILURE",
57                CryptoUtils::HandshakeFailureReasonToString(
58                    SERVER_NONCE_INVALID_TIME_FAILURE));
59   EXPECT_STREQ("SERVER_NONCE_REQUIRED_FAILURE",
60                CryptoUtils::HandshakeFailureReasonToString(
61                    SERVER_NONCE_REQUIRED_FAILURE));
62   EXPECT_STREQ("SERVER_CONFIG_INCHOATE_HELLO_FAILURE",
63                CryptoUtils::HandshakeFailureReasonToString(
64                    SERVER_CONFIG_INCHOATE_HELLO_FAILURE));
65   EXPECT_STREQ("SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE",
66                CryptoUtils::HandshakeFailureReasonToString(
67                    SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE));
68   EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_INVALID_FAILURE",
69                CryptoUtils::HandshakeFailureReasonToString(
70                    SOURCE_ADDRESS_TOKEN_INVALID_FAILURE));
71   EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE",
72                CryptoUtils::HandshakeFailureReasonToString(
73                    SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE));
74   EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_PARSE_FAILURE",
75                CryptoUtils::HandshakeFailureReasonToString(
76                    SOURCE_ADDRESS_TOKEN_PARSE_FAILURE));
77   EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE",
78                CryptoUtils::HandshakeFailureReasonToString(
79                    SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE));
80   EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE",
81                CryptoUtils::HandshakeFailureReasonToString(
82                    SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE));
83   EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE",
84                CryptoUtils::HandshakeFailureReasonToString(
85                    SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE));
86   EXPECT_STREQ("INVALID_EXPECTED_LEAF_CERTIFICATE",
87                CryptoUtils::HandshakeFailureReasonToString(
88                    INVALID_EXPECTED_LEAF_CERTIFICATE));
89   EXPECT_STREQ("MAX_FAILURE_REASON",
90                CryptoUtils::HandshakeFailureReasonToString(MAX_FAILURE_REASON));
91   EXPECT_STREQ(
92       "INVALID_HANDSHAKE_FAILURE_REASON",
93       CryptoUtils::HandshakeFailureReasonToString(
94           static_cast<HandshakeFailureReason>(MAX_FAILURE_REASON + 1)));
95 }
96 
TEST_F(CryptoUtilsTest,AuthTagLengths)97 TEST_F(CryptoUtilsTest, AuthTagLengths) {
98   for (const auto& version : AllSupportedVersions()) {
99     for (QuicTag algo : {kAESG, kCC20}) {
100       SCOPED_TRACE(version);
101       std::unique_ptr<QuicEncrypter> encrypter(
102           QuicEncrypter::Create(version, algo));
103       size_t auth_tag_size = 12;
104       if (version.UsesInitialObfuscators()) {
105         auth_tag_size = 16;
106       }
107       EXPECT_EQ(encrypter->GetCiphertextSize(0), auth_tag_size);
108     }
109   }
110 }
111 
TEST_F(CryptoUtilsTest,ValidateChosenVersion)112 TEST_F(CryptoUtilsTest, ValidateChosenVersion) {
113   for (const ParsedQuicVersion& v1 : AllSupportedVersions()) {
114     for (const ParsedQuicVersion& v2 : AllSupportedVersions()) {
115       std::string error_details;
116       bool success = CryptoUtils::ValidateChosenVersion(
117           CreateQuicVersionLabel(v1), v2, &error_details);
118       EXPECT_EQ(success, v1 == v2);
119       EXPECT_EQ(success, error_details.empty());
120     }
121   }
122 }
123 
TEST_F(CryptoUtilsTest,ValidateServerVersionsNoVersionNegotiation)124 TEST_F(CryptoUtilsTest, ValidateServerVersionsNoVersionNegotiation) {
125   QuicVersionLabelVector version_information_other_versions;
126   ParsedQuicVersionVector client_original_supported_versions;
127   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
128     std::string error_details;
129     EXPECT_TRUE(CryptoUtils::ValidateServerVersions(
130         version_information_other_versions, version,
131         client_original_supported_versions, &error_details));
132     EXPECT_TRUE(error_details.empty());
133   }
134 }
135 
TEST_F(CryptoUtilsTest,ValidateServerVersionsWithVersionNegotiation)136 TEST_F(CryptoUtilsTest, ValidateServerVersionsWithVersionNegotiation) {
137   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
138     QuicVersionLabelVector version_information_other_versions{
139         CreateQuicVersionLabel(version)};
140     ParsedQuicVersionVector client_original_supported_versions{
141         ParsedQuicVersion::ReservedForNegotiation(), version};
142     std::string error_details;
143     EXPECT_TRUE(CryptoUtils::ValidateServerVersions(
144         version_information_other_versions, version,
145         client_original_supported_versions, &error_details));
146     EXPECT_TRUE(error_details.empty());
147   }
148 }
149 
TEST_F(CryptoUtilsTest,ValidateServerVersionsWithDowngrade)150 TEST_F(CryptoUtilsTest, ValidateServerVersionsWithDowngrade) {
151   if (AllSupportedVersions().size() <= 1) {
152     // We are not vulnerable to downgrade if we only support one version.
153     return;
154   }
155   ParsedQuicVersion client_version = AllSupportedVersions().front();
156   ParsedQuicVersion server_version = AllSupportedVersions().back();
157   ASSERT_NE(client_version, server_version);
158   QuicVersionLabelVector version_information_other_versions{
159       CreateQuicVersionLabel(client_version)};
160   ParsedQuicVersionVector client_original_supported_versions{
161       ParsedQuicVersion::ReservedForNegotiation(), server_version};
162   std::string error_details;
163   EXPECT_FALSE(CryptoUtils::ValidateServerVersions(
164       version_information_other_versions, server_version,
165       client_original_supported_versions, &error_details));
166   EXPECT_FALSE(error_details.empty());
167 }
168 
169 // Test that the library is using the correct labels for each version, and
170 // therefore generating correct obfuscators, using the test vectors in appendix
171 // A of each RFC or internet-draft.
TEST_F(CryptoUtilsTest,ValidateCryptoLabels)172 TEST_F(CryptoUtilsTest, ValidateCryptoLabels) {
173   // if the number of HTTP/3 QUIC versions has changed, we need to change the
174   // expected_keys hardcoded into this test. Regrettably, this is not a
175   // compile-time constant.
176   EXPECT_EQ(AllSupportedVersionsWithTls().size(), 3u);
177   const char draft_29_key[] = {// test vector from draft-ietf-quic-tls-29, A.1
178                                0x14,
179                                static_cast<char>(0x9d),
180                                0x0b,
181                                0x16,
182                                0x62,
183                                static_cast<char>(0xab),
184                                static_cast<char>(0x87),
185                                0x1f,
186                                static_cast<char>(0xbe),
187                                0x63,
188                                static_cast<char>(0xc4),
189                                static_cast<char>(0x9b),
190                                0x5e,
191                                0x65,
192                                0x5a,
193                                0x5d};
194   const char v1_key[] = {// test vector from RFC 9001, A.1
195                          static_cast<char>(0xcf),
196                          0x3a,
197                          0x53,
198                          0x31,
199                          0x65,
200                          0x3c,
201                          0x36,
202                          0x4c,
203                          static_cast<char>(0x88),
204                          static_cast<char>(0xf0),
205                          static_cast<char>(0xf3),
206                          0x79,
207                          static_cast<char>(0xb6),
208                          0x06,
209                          0x7e,
210                          0x37};
211   const char v2_08_key[] = {// test vector from draft-ietf-quic-v2-08
212                             static_cast<char>(0x82),
213                             static_cast<char>(0xdb),
214                             static_cast<char>(0x63),
215                             static_cast<char>(0x78),
216                             static_cast<char>(0x61),
217                             static_cast<char>(0xd5),
218                             static_cast<char>(0x5e),
219                             0x1d,
220                             static_cast<char>(0x01),
221                             static_cast<char>(0x1f),
222                             0x19,
223                             static_cast<char>(0xea),
224                             0x71,
225                             static_cast<char>(0xd5),
226                             static_cast<char>(0xd2),
227                             static_cast<char>(0xa7)};
228   const char connection_id[] =  // test vector from both docs
229       {static_cast<char>(0x83),
230        static_cast<char>(0x94),
231        static_cast<char>(0xc8),
232        static_cast<char>(0xf0),
233        0x3e,
234        0x51,
235        0x57,
236        0x08};
237   const QuicConnectionId cid(connection_id, sizeof(connection_id));
238   const char* key_str;
239   size_t key_size;
240   for (const ParsedQuicVersion& version : AllSupportedVersionsWithTls()) {
241     if (version == ParsedQuicVersion::Draft29()) {
242       key_str = draft_29_key;
243       key_size = sizeof(draft_29_key);
244     } else if (version == ParsedQuicVersion::RFCv1()) {
245       key_str = v1_key;
246       key_size = sizeof(v1_key);
247     } else {  // draft-ietf-quic-v2-01
248       key_str = v2_08_key;
249       key_size = sizeof(v2_08_key);
250     }
251     const absl::string_view expected_key{key_str, key_size};
252 
253     CrypterPair crypters;
254     CryptoUtils::CreateInitialObfuscators(Perspective::IS_SERVER, version, cid,
255                                           &crypters);
256     EXPECT_EQ(crypters.encrypter->GetKey(), expected_key);
257   }
258 }
259 
260 }  // namespace
261 }  // namespace test
262 }  // namespace quic
263