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 <algorithm>
6 #include <cstdint>
7 #include <memory>
8 #include <ostream>
9 #include <string>
10 #include <utility>
11 #include <vector>
12
13 #include "absl/base/macros.h"
14 #include "absl/strings/escaping.h"
15 #include "absl/strings/match.h"
16 #include "absl/strings/str_cat.h"
17 #include "absl/strings/string_view.h"
18 #include "openssl/sha.h"
19 #include "quiche/quic/core/crypto/cert_compressor.h"
20 #include "quiche/quic/core/crypto/crypto_handshake.h"
21 #include "quiche/quic/core/crypto/crypto_utils.h"
22 #include "quiche/quic/core/crypto/proof_source.h"
23 #include "quiche/quic/core/crypto/quic_crypto_server_config.h"
24 #include "quiche/quic/core/crypto/quic_random.h"
25 #include "quiche/quic/core/proto/crypto_server_config_proto.h"
26 #include "quiche/quic/core/quic_socket_address_coder.h"
27 #include "quiche/quic/core/quic_utils.h"
28 #include "quiche/quic/platform/api/quic_flags.h"
29 #include "quiche/quic/platform/api/quic_test.h"
30 #include "quiche/quic/test_tools/crypto_test_utils.h"
31 #include "quiche/quic/test_tools/failing_proof_source.h"
32 #include "quiche/quic/test_tools/mock_clock.h"
33 #include "quiche/quic/test_tools/mock_random.h"
34 #include "quiche/quic/test_tools/quic_crypto_server_config_peer.h"
35 #include "quiche/quic/test_tools/quic_test_utils.h"
36 #include "quiche/common/quiche_endian.h"
37
38 namespace quic {
39 namespace test {
40
41 namespace {
42
43 class DummyProofVerifierCallback : public ProofVerifierCallback {
44 public:
DummyProofVerifierCallback()45 DummyProofVerifierCallback() {}
~DummyProofVerifierCallback()46 ~DummyProofVerifierCallback() override {}
47
Run(bool,const std::string &,std::unique_ptr<ProofVerifyDetails> *)48 void Run(bool /*ok*/, const std::string& /*error_details*/,
49 std::unique_ptr<ProofVerifyDetails>* /*details*/) override {
50 QUICHE_DCHECK(false);
51 }
52 };
53
54 const char kOldConfigId[] = "old-config-id";
55
56 } // namespace
57
58 struct TestParams {
operator <<(std::ostream & os,const TestParams & p)59 friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
60 os << " versions: "
61 << ParsedQuicVersionVectorToString(p.supported_versions) << " }";
62 return os;
63 }
64
65 // Versions supported by client and server.
66 ParsedQuicVersionVector supported_versions;
67 };
68
69 // Used by ::testing::PrintToStringParamName().
PrintToString(const TestParams & p)70 std::string PrintToString(const TestParams& p) {
71 std::string rv = ParsedQuicVersionVectorToString(p.supported_versions);
72 std::replace(rv.begin(), rv.end(), ',', '_');
73 return rv;
74 }
75
76 // Constructs various test permutations.
GetTestParams()77 std::vector<TestParams> GetTestParams() {
78 std::vector<TestParams> params;
79
80 // Start with all versions, remove highest on each iteration.
81 ParsedQuicVersionVector supported_versions = AllSupportedVersions();
82 while (!supported_versions.empty()) {
83 params.push_back({supported_versions});
84 supported_versions.erase(supported_versions.begin());
85 }
86
87 return params;
88 }
89
90 class CryptoServerTest : public QuicTestWithParam<TestParams> {
91 public:
CryptoServerTest()92 CryptoServerTest()
93 : rand_(QuicRandom::GetInstance()),
94 client_address_(QuicIpAddress::Loopback4(), 1234),
95 client_version_(UnsupportedQuicVersion()),
96 config_(QuicCryptoServerConfig::TESTING, rand_,
97 crypto_test_utils::ProofSourceForTesting(),
98 KeyExchangeSource::Default()),
99 peer_(&config_),
100 compressed_certs_cache_(
101 QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
102 params_(new QuicCryptoNegotiatedParameters),
103 signed_config_(new QuicSignedServerConfig),
104 chlo_packet_size_(kDefaultMaxPacketSize) {
105 supported_versions_ = GetParam().supported_versions;
106 config_.set_enable_serving_sct(true);
107
108 client_version_ = supported_versions_.front();
109 client_version_label_ = CreateQuicVersionLabel(client_version_);
110 client_version_string_ =
111 std::string(reinterpret_cast<const char*>(&client_version_label_),
112 sizeof(client_version_label_));
113 }
114
SetUp()115 void SetUp() override {
116 QuicCryptoServerConfig::ConfigOptions old_config_options;
117 old_config_options.id = kOldConfigId;
118 config_.AddDefaultConfig(rand_, &clock_, old_config_options);
119 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
120 QuicServerConfigProtobuf primary_config =
121 config_.GenerateConfig(rand_, &clock_, config_options_);
122 primary_config.set_primary_time(clock_.WallNow().ToUNIXSeconds());
123 std::unique_ptr<CryptoHandshakeMessage> msg(
124 config_.AddConfig(primary_config, clock_.WallNow()));
125
126 absl::string_view orbit;
127 QUICHE_CHECK(msg->GetStringPiece(kORBT, &orbit));
128 QUICHE_CHECK_EQ(sizeof(orbit_), orbit.size());
129 memcpy(orbit_, orbit.data(), orbit.size());
130
131 char public_value[32];
132 memset(public_value, 42, sizeof(public_value));
133
134 nonce_hex_ = "#" + absl::BytesToHexString(GenerateNonce());
135 pub_hex_ = "#" + absl::BytesToHexString(
136 absl::string_view(public_value, sizeof(public_value)));
137
138 CryptoHandshakeMessage client_hello =
139 crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
140 {"AEAD", "AESG"},
141 {"KEXS", "C255"},
142 {"PUBS", pub_hex_},
143 {"NONC", nonce_hex_},
144 {"CSCT", ""},
145 {"VER\0", client_version_string_}},
146 kClientHelloMinimumSize);
147 ShouldSucceed(client_hello);
148 // The message should be rejected because the source-address token is
149 // missing.
150 CheckRejectTag();
151 const HandshakeFailureReason kRejectReasons[] = {
152 SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
153 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
154
155 absl::string_view srct;
156 ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct));
157 srct_hex_ = "#" + absl::BytesToHexString(srct);
158
159 absl::string_view scfg;
160 ASSERT_TRUE(out_.GetStringPiece(kSCFG, &scfg));
161 server_config_ = CryptoFramer::ParseMessage(scfg);
162
163 absl::string_view scid;
164 ASSERT_TRUE(server_config_->GetStringPiece(kSCID, &scid));
165 scid_hex_ = "#" + absl::BytesToHexString(scid);
166
167 signed_config_ =
168 quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>(
169 new QuicSignedServerConfig());
170 QUICHE_DCHECK(signed_config_->chain.get() == nullptr);
171 }
172
173 // Helper used to accept the result of ValidateClientHello and pass
174 // it on to ProcessClientHello.
175 class ValidateCallback : public ValidateClientHelloResultCallback {
176 public:
ValidateCallback(CryptoServerTest * test,bool should_succeed,const char * error_substr,bool * called)177 ValidateCallback(CryptoServerTest* test, bool should_succeed,
178 const char* error_substr, bool* called)
179 : test_(test),
180 should_succeed_(should_succeed),
181 error_substr_(error_substr),
182 called_(called) {
183 *called_ = false;
184 }
185
Run(quiche::QuicheReferenceCountedPointer<Result> result,std::unique_ptr<ProofSource::Details>)186 void Run(quiche::QuicheReferenceCountedPointer<Result> result,
187 std::unique_ptr<ProofSource::Details> /* details */) override {
188 ASSERT_FALSE(*called_);
189 test_->ProcessValidationResult(std::move(result), should_succeed_,
190 error_substr_);
191 *called_ = true;
192 }
193
194 private:
195 CryptoServerTest* test_;
196 const bool should_succeed_;
197 const char* const error_substr_;
198 bool* called_;
199 };
200
CheckServerHello(const CryptoHandshakeMessage & server_hello)201 void CheckServerHello(const CryptoHandshakeMessage& server_hello) {
202 QuicVersionLabelVector versions;
203 server_hello.GetVersionLabelList(kVER, &versions);
204 ASSERT_EQ(supported_versions_.size(), versions.size());
205 for (size_t i = 0; i < versions.size(); ++i) {
206 EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[i]), versions[i]);
207 }
208
209 absl::string_view address;
210 ASSERT_TRUE(server_hello.GetStringPiece(kCADR, &address));
211 QuicSocketAddressCoder decoder;
212 ASSERT_TRUE(decoder.Decode(address.data(), address.size()));
213 EXPECT_EQ(client_address_.host(), decoder.ip());
214 EXPECT_EQ(client_address_.port(), decoder.port());
215 }
216
ShouldSucceed(const CryptoHandshakeMessage & message)217 void ShouldSucceed(const CryptoHandshakeMessage& message) {
218 bool called = false;
219 QuicSocketAddress server_address(QuicIpAddress::Any4(), 5);
220 config_.ValidateClientHello(
221 message, client_address_, server_address,
222 supported_versions_.front().transport_version, &clock_, signed_config_,
223 std::make_unique<ValidateCallback>(this, true, "", &called));
224 EXPECT_TRUE(called);
225 }
226
ShouldFailMentioning(const char * error_substr,const CryptoHandshakeMessage & message)227 void ShouldFailMentioning(const char* error_substr,
228 const CryptoHandshakeMessage& message) {
229 bool called = false;
230 ShouldFailMentioning(error_substr, message, &called);
231 EXPECT_TRUE(called);
232 }
233
ShouldFailMentioning(const char * error_substr,const CryptoHandshakeMessage & message,bool * called)234 void ShouldFailMentioning(const char* error_substr,
235 const CryptoHandshakeMessage& message,
236 bool* called) {
237 QuicSocketAddress server_address(QuicIpAddress::Any4(), 5);
238 config_.ValidateClientHello(
239 message, client_address_, server_address,
240 supported_versions_.front().transport_version, &clock_, signed_config_,
241 std::make_unique<ValidateCallback>(this, false, error_substr, called));
242 }
243
244 class ProcessCallback : public ProcessClientHelloResultCallback {
245 public:
ProcessCallback(quiche::QuicheReferenceCountedPointer<ValidateCallback::Result> result,bool should_succeed,const char * error_substr,bool * called,CryptoHandshakeMessage * out)246 ProcessCallback(
247 quiche::QuicheReferenceCountedPointer<ValidateCallback::Result> result,
248 bool should_succeed, const char* error_substr, bool* called,
249 CryptoHandshakeMessage* out)
250 : result_(std::move(result)),
251 should_succeed_(should_succeed),
252 error_substr_(error_substr),
253 called_(called),
254 out_(out) {
255 *called_ = false;
256 }
257
Run(QuicErrorCode error,const std::string & error_details,std::unique_ptr<CryptoHandshakeMessage> message,std::unique_ptr<DiversificationNonce>,std::unique_ptr<ProofSource::Details>)258 void Run(QuicErrorCode error, const std::string& error_details,
259 std::unique_ptr<CryptoHandshakeMessage> message,
260 std::unique_ptr<DiversificationNonce> /*diversification_nonce*/,
261 std::unique_ptr<ProofSource::Details> /*proof_source_details*/)
262 override {
263 if (should_succeed_) {
264 ASSERT_EQ(error, QUIC_NO_ERROR)
265 << "Message failed with error " << error_details << ": "
266 << result_->client_hello.DebugString();
267 } else {
268 ASSERT_NE(error, QUIC_NO_ERROR)
269 << "Message didn't fail: " << result_->client_hello.DebugString();
270 EXPECT_TRUE(absl::StrContains(error_details, error_substr_))
271 << error_substr_ << " not in " << error_details;
272 }
273 if (message != nullptr) {
274 *out_ = *message;
275 }
276 *called_ = true;
277 }
278
279 private:
280 const quiche::QuicheReferenceCountedPointer<ValidateCallback::Result>
281 result_;
282 const bool should_succeed_;
283 const char* const error_substr_;
284 bool* called_;
285 CryptoHandshakeMessage* out_;
286 };
287
ProcessValidationResult(quiche::QuicheReferenceCountedPointer<ValidateCallback::Result> result,bool should_succeed,const char * error_substr)288 void ProcessValidationResult(
289 quiche::QuicheReferenceCountedPointer<ValidateCallback::Result> result,
290 bool should_succeed, const char* error_substr) {
291 QuicSocketAddress server_address(QuicIpAddress::Any4(), 5);
292 bool called;
293 config_.ProcessClientHello(
294 result, /*reject_only=*/false,
295 /*connection_id=*/TestConnectionId(1), server_address, client_address_,
296 supported_versions_.front(), supported_versions_, &clock_, rand_,
297 &compressed_certs_cache_, params_, signed_config_,
298 /*total_framing_overhead=*/50, chlo_packet_size_,
299 std::make_unique<ProcessCallback>(result, should_succeed, error_substr,
300 &called, &out_));
301 EXPECT_TRUE(called);
302 }
303
GenerateNonce()304 std::string GenerateNonce() {
305 std::string nonce;
306 CryptoUtils::GenerateNonce(
307 clock_.WallNow(), rand_,
308 absl::string_view(reinterpret_cast<const char*>(orbit_),
309 sizeof(orbit_)),
310 &nonce);
311 return nonce;
312 }
313
CheckRejectReasons(const HandshakeFailureReason * expected_handshake_failures,size_t expected_count)314 void CheckRejectReasons(
315 const HandshakeFailureReason* expected_handshake_failures,
316 size_t expected_count) {
317 QuicTagVector reject_reasons;
318 static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
319 QuicErrorCode error_code = out_.GetTaglist(kRREJ, &reject_reasons);
320 ASSERT_THAT(error_code, IsQuicNoError());
321
322 EXPECT_EQ(expected_count, reject_reasons.size());
323 for (size_t i = 0; i < reject_reasons.size(); ++i) {
324 EXPECT_EQ(static_cast<QuicTag>(expected_handshake_failures[i]),
325 reject_reasons[i]);
326 }
327 }
328
CheckRejectTag()329 void CheckRejectTag() {
330 ASSERT_EQ(kREJ, out_.tag()) << QuicTagToString(out_.tag());
331 }
332
XlctHexString()333 std::string XlctHexString() {
334 uint64_t xlct = crypto_test_utils::LeafCertHashForTesting();
335 return "#" + absl::BytesToHexString(absl::string_view(
336 reinterpret_cast<char*>(&xlct), sizeof(xlct)));
337 }
338
339 protected:
340 QuicRandom* const rand_;
341 MockRandom rand_for_id_generation_;
342 MockClock clock_;
343 QuicSocketAddress client_address_;
344 ParsedQuicVersionVector supported_versions_;
345 ParsedQuicVersion client_version_;
346 QuicVersionLabel client_version_label_;
347 std::string client_version_string_;
348 QuicCryptoServerConfig config_;
349 QuicCryptoServerConfigPeer peer_;
350 QuicCompressedCertsCache compressed_certs_cache_;
351 QuicCryptoServerConfig::ConfigOptions config_options_;
352 quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
353 quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
354 CryptoHandshakeMessage out_;
355 uint8_t orbit_[kOrbitSize];
356 size_t chlo_packet_size_;
357
358 // These strings contain hex escaped values from the server suitable for using
359 // when constructing client hello messages.
360 std::string nonce_hex_, pub_hex_, srct_hex_, scid_hex_;
361 std::unique_ptr<CryptoHandshakeMessage> server_config_;
362 };
363
364 INSTANTIATE_TEST_SUITE_P(CryptoServerTests, CryptoServerTest,
365 ::testing::ValuesIn(GetTestParams()),
366 ::testing::PrintToStringParamName());
367
TEST_P(CryptoServerTest,BadSNI)368 TEST_P(CryptoServerTest, BadSNI) {
369 // clang-format off
370 std::vector<std::string> badSNIs = {
371 "",
372 "#00",
373 "#ff00",
374 "127.0.0.1",
375 "ffee::1",
376 };
377 // clang-format on
378
379 for (const std::string& bad_sni : badSNIs) {
380 CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
381 {{"PDMD", "X509"}, {"SNI", bad_sni}, {"VER\0", client_version_string_}},
382 kClientHelloMinimumSize);
383 ShouldFailMentioning("SNI", msg);
384 const HandshakeFailureReason kRejectReasons[] = {
385 SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
386 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
387 }
388
389 // Check that SNIs without dots are allowed
390 CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
391 {{"PDMD", "X509"}, {"SNI", "foo"}, {"VER\0", client_version_string_}},
392 kClientHelloMinimumSize);
393 ShouldSucceed(msg);
394 }
395
TEST_P(CryptoServerTest,DefaultCert)396 TEST_P(CryptoServerTest, DefaultCert) {
397 // Check that the server replies with a default certificate when no SNI is
398 // specified. The CHLO is constructed to generate a REJ with certs, so must
399 // not contain a valid STK, and must include PDMD.
400 CryptoHandshakeMessage msg =
401 crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
402 {"KEXS", "C255"},
403 {"PUBS", pub_hex_},
404 {"NONC", nonce_hex_},
405 {"PDMD", "X509"},
406 {"VER\0", client_version_string_}},
407 kClientHelloMinimumSize);
408
409 ShouldSucceed(msg);
410 absl::string_view cert, proof, cert_sct;
411 EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
412 EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
413 EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
414 EXPECT_NE(0u, cert.size());
415 EXPECT_NE(0u, proof.size());
416 const HandshakeFailureReason kRejectReasons[] = {
417 SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
418 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
419 EXPECT_LT(0u, cert_sct.size());
420 }
421
TEST_P(CryptoServerTest,RejectTooLarge)422 TEST_P(CryptoServerTest, RejectTooLarge) {
423 // Check that the server replies with no certificate when a CHLO is
424 // constructed with a PDMD but no SKT when the REJ would be too large.
425 CryptoHandshakeMessage msg =
426 crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
427 {"AEAD", "AESG"},
428 {"KEXS", "C255"},
429 {"PUBS", pub_hex_},
430 {"NONC", nonce_hex_},
431 {"PDMD", "X509"},
432 {"VER\0", client_version_string_}},
433 kClientHelloMinimumSize);
434
435 // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
436 config_.set_chlo_multiplier(1);
437
438 ShouldSucceed(msg);
439 absl::string_view cert, proof, cert_sct;
440 EXPECT_FALSE(out_.GetStringPiece(kCertificateTag, &cert));
441 EXPECT_FALSE(out_.GetStringPiece(kPROF, &proof));
442 EXPECT_FALSE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
443 const HandshakeFailureReason kRejectReasons[] = {
444 SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
445 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
446 }
447
TEST_P(CryptoServerTest,RejectNotTooLarge)448 TEST_P(CryptoServerTest, RejectNotTooLarge) {
449 // When the CHLO packet is large enough, ensure that a full REJ is sent.
450 chlo_packet_size_ *= 5;
451
452 CryptoHandshakeMessage msg =
453 crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
454 {"AEAD", "AESG"},
455 {"KEXS", "C255"},
456 {"PUBS", pub_hex_},
457 {"NONC", nonce_hex_},
458 {"PDMD", "X509"},
459 {"VER\0", client_version_string_}},
460 kClientHelloMinimumSize);
461
462 // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
463 config_.set_chlo_multiplier(1);
464
465 ShouldSucceed(msg);
466 absl::string_view cert, proof, cert_sct;
467 EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
468 EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
469 EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
470 const HandshakeFailureReason kRejectReasons[] = {
471 SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
472 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
473 }
474
TEST_P(CryptoServerTest,RejectTooLargeButValidSTK)475 TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) {
476 // Check that the server replies with no certificate when a CHLO is
477 // constructed with a PDMD but no SKT when the REJ would be too large.
478 CryptoHandshakeMessage msg =
479 crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
480 {"AEAD", "AESG"},
481 {"KEXS", "C255"},
482 {"PUBS", pub_hex_},
483 {"NONC", nonce_hex_},
484 {"#004b5453", srct_hex_},
485 {"PDMD", "X509"},
486 {"VER\0", client_version_string_}},
487 kClientHelloMinimumSize);
488
489 // The REJ will be larger than the CHLO so no PROF or CRT will be sent.
490 config_.set_chlo_multiplier(1);
491
492 ShouldSucceed(msg);
493 absl::string_view cert, proof, cert_sct;
494 EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
495 EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
496 EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
497 EXPECT_NE(0u, cert.size());
498 EXPECT_NE(0u, proof.size());
499 const HandshakeFailureReason kRejectReasons[] = {
500 SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
501 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
502 }
503
TEST_P(CryptoServerTest,BadSourceAddressToken)504 TEST_P(CryptoServerTest, BadSourceAddressToken) {
505 // Invalid source-address tokens should be ignored.
506 // clang-format off
507 static const char* const kBadSourceAddressTokens[] = {
508 "",
509 "foo",
510 "#0000",
511 "#0000000000000000000000000000000000000000",
512 };
513 // clang-format on
514
515 for (size_t i = 0; i < ABSL_ARRAYSIZE(kBadSourceAddressTokens); i++) {
516 CryptoHandshakeMessage msg =
517 crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
518 {"STK", kBadSourceAddressTokens[i]},
519 {"VER\0", client_version_string_}},
520 kClientHelloMinimumSize);
521 ShouldSucceed(msg);
522 const HandshakeFailureReason kRejectReasons[] = {
523 SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
524 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
525 }
526 }
527
TEST_P(CryptoServerTest,BadClientNonce)528 TEST_P(CryptoServerTest, BadClientNonce) {
529 // clang-format off
530 static const char* const kBadNonces[] = {
531 "",
532 "#0000",
533 "#0000000000000000000000000000000000000000",
534 };
535 // clang-format on
536
537 for (size_t i = 0; i < ABSL_ARRAYSIZE(kBadNonces); i++) {
538 // Invalid nonces should be ignored, in an inchoate CHLO.
539
540 CryptoHandshakeMessage msg =
541 crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
542 {"NONC", kBadNonces[i]},
543 {"VER\0", client_version_string_}},
544 kClientHelloMinimumSize);
545
546 ShouldSucceed(msg);
547 const HandshakeFailureReason kRejectReasons[] = {
548 SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
549 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
550
551 // Invalid nonces should result in CLIENT_NONCE_INVALID_FAILURE.
552 CryptoHandshakeMessage msg1 =
553 crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
554 {"AEAD", "AESG"},
555 {"KEXS", "C255"},
556 {"SCID", scid_hex_},
557 {"#004b5453", srct_hex_},
558 {"PUBS", pub_hex_},
559 {"NONC", kBadNonces[i]},
560 {"NONP", kBadNonces[i]},
561 {"XLCT", XlctHexString()},
562 {"VER\0", client_version_string_}},
563 kClientHelloMinimumSize);
564
565 ShouldSucceed(msg1);
566
567 CheckRejectTag();
568 const HandshakeFailureReason kRejectReasons1[] = {
569 CLIENT_NONCE_INVALID_FAILURE};
570 CheckRejectReasons(kRejectReasons1, ABSL_ARRAYSIZE(kRejectReasons1));
571 }
572 }
573
TEST_P(CryptoServerTest,NoClientNonce)574 TEST_P(CryptoServerTest, NoClientNonce) {
575 // No client nonces should result in INCHOATE_HELLO_FAILURE.
576
577 CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
578 {{"PDMD", "X509"}, {"VER\0", client_version_string_}},
579 kClientHelloMinimumSize);
580
581 ShouldSucceed(msg);
582 const HandshakeFailureReason kRejectReasons[] = {
583 SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
584 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
585
586 CryptoHandshakeMessage msg1 =
587 crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
588 {"AEAD", "AESG"},
589 {"KEXS", "C255"},
590 {"SCID", scid_hex_},
591 {"#004b5453", srct_hex_},
592 {"PUBS", pub_hex_},
593 {"XLCT", XlctHexString()},
594 {"VER\0", client_version_string_}},
595 kClientHelloMinimumSize);
596
597 ShouldSucceed(msg1);
598 CheckRejectTag();
599 const HandshakeFailureReason kRejectReasons1[] = {
600 SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
601 CheckRejectReasons(kRejectReasons1, ABSL_ARRAYSIZE(kRejectReasons1));
602 }
603
TEST_P(CryptoServerTest,DowngradeAttack)604 TEST_P(CryptoServerTest, DowngradeAttack) {
605 if (supported_versions_.size() == 1) {
606 // No downgrade attack is possible if the server only supports one version.
607 return;
608 }
609 // Set the client's preferred version to a supported version that
610 // is not the "current" version (supported_versions_.front()).
611 std::string bad_version =
612 ParsedQuicVersionToString(supported_versions_.back());
613
614 CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
615 {{"PDMD", "X509"}, {"VER\0", bad_version}}, kClientHelloMinimumSize);
616
617 ShouldFailMentioning("Downgrade", msg);
618 const HandshakeFailureReason kRejectReasons[] = {
619 SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
620 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
621 }
622
TEST_P(CryptoServerTest,CorruptServerConfig)623 TEST_P(CryptoServerTest, CorruptServerConfig) {
624 // This tests corrupted server config.
625 CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
626 {{"PDMD", "X509"},
627 {"AEAD", "AESG"},
628 {"KEXS", "C255"},
629 {"SCID", (std::string(1, 'X') + scid_hex_)},
630 {"#004b5453", srct_hex_},
631 {"PUBS", pub_hex_},
632 {"NONC", nonce_hex_},
633 {"VER\0", client_version_string_}},
634 kClientHelloMinimumSize);
635
636 ShouldSucceed(msg);
637 CheckRejectTag();
638 const HandshakeFailureReason kRejectReasons[] = {
639 SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE};
640 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
641 }
642
TEST_P(CryptoServerTest,CorruptSourceAddressToken)643 TEST_P(CryptoServerTest, CorruptSourceAddressToken) {
644 // This tests corrupted source address token.
645 CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
646 {{"PDMD", "X509"},
647 {"AEAD", "AESG"},
648 {"KEXS", "C255"},
649 {"SCID", scid_hex_},
650 {"#004b5453", (std::string(1, 'X') + srct_hex_)},
651 {"PUBS", pub_hex_},
652 {"NONC", nonce_hex_},
653 {"XLCT", XlctHexString()},
654 {"VER\0", client_version_string_}},
655 kClientHelloMinimumSize);
656
657 ShouldSucceed(msg);
658 CheckRejectTag();
659 const HandshakeFailureReason kRejectReasons[] = {
660 SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE};
661 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
662 }
663
TEST_P(CryptoServerTest,CorruptSourceAddressTokenIsStillAccepted)664 TEST_P(CryptoServerTest, CorruptSourceAddressTokenIsStillAccepted) {
665 // This tests corrupted source address token.
666 CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
667 {{"PDMD", "X509"},
668 {"AEAD", "AESG"},
669 {"KEXS", "C255"},
670 {"SCID", scid_hex_},
671 {"#004b5453", (std::string(1, 'X') + srct_hex_)},
672 {"PUBS", pub_hex_},
673 {"NONC", nonce_hex_},
674 {"XLCT", XlctHexString()},
675 {"VER\0", client_version_string_}},
676 kClientHelloMinimumSize);
677
678 config_.set_validate_source_address_token(false);
679
680 ShouldSucceed(msg);
681 EXPECT_EQ(kSHLO, out_.tag());
682 }
683
TEST_P(CryptoServerTest,CorruptClientNonceAndSourceAddressToken)684 TEST_P(CryptoServerTest, CorruptClientNonceAndSourceAddressToken) {
685 // This test corrupts client nonce and source address token.
686 CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
687 {{"PDMD", "X509"},
688 {"AEAD", "AESG"},
689 {"KEXS", "C255"},
690 {"SCID", scid_hex_},
691 {"#004b5453", (std::string(1, 'X') + srct_hex_)},
692 {"PUBS", pub_hex_},
693 {"NONC", (std::string(1, 'X') + nonce_hex_)},
694 {"XLCT", XlctHexString()},
695 {"VER\0", client_version_string_}},
696 kClientHelloMinimumSize);
697
698 ShouldSucceed(msg);
699 CheckRejectTag();
700 const HandshakeFailureReason kRejectReasons[] = {
701 SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE};
702 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
703 }
704
TEST_P(CryptoServerTest,CorruptMultipleTags)705 TEST_P(CryptoServerTest, CorruptMultipleTags) {
706 // This test corrupts client nonce, server nonce and source address token.
707 CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
708 {{"PDMD", "X509"},
709 {"AEAD", "AESG"},
710 {"KEXS", "C255"},
711 {"SCID", scid_hex_},
712 {"#004b5453", (std::string(1, 'X') + srct_hex_)},
713 {"PUBS", pub_hex_},
714 {"NONC", (std::string(1, 'X') + nonce_hex_)},
715 {"NONP", (std::string(1, 'X') + nonce_hex_)},
716 {"SNO\0", (std::string(1, 'X') + nonce_hex_)},
717 {"XLCT", XlctHexString()},
718 {"VER\0", client_version_string_}},
719 kClientHelloMinimumSize);
720
721 ShouldSucceed(msg);
722 CheckRejectTag();
723
724 const HandshakeFailureReason kRejectReasons[] = {
725 SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE};
726 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
727 }
728
TEST_P(CryptoServerTest,NoServerNonce)729 TEST_P(CryptoServerTest, NoServerNonce) {
730 // When no server nonce is present and no strike register is configured,
731 // the CHLO should be rejected.
732 CryptoHandshakeMessage msg =
733 crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
734 {"AEAD", "AESG"},
735 {"KEXS", "C255"},
736 {"SCID", scid_hex_},
737 {"#004b5453", srct_hex_},
738 {"PUBS", pub_hex_},
739 {"NONC", nonce_hex_},
740 {"NONP", nonce_hex_},
741 {"XLCT", XlctHexString()},
742 {"VER\0", client_version_string_}},
743 kClientHelloMinimumSize);
744
745 ShouldSucceed(msg);
746
747 // Even without a server nonce, this ClientHello should be accepted in
748 // version 33.
749 ASSERT_EQ(kSHLO, out_.tag());
750 CheckServerHello(out_);
751 }
752
TEST_P(CryptoServerTest,ProofForSuppliedServerConfig)753 TEST_P(CryptoServerTest, ProofForSuppliedServerConfig) {
754 client_address_ = QuicSocketAddress(QuicIpAddress::Loopback6(), 1234);
755
756 CryptoHandshakeMessage msg =
757 crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
758 {"KEXS", "C255"},
759 {"PDMD", "X509"},
760 {"SCID", kOldConfigId},
761 {"#004b5453", srct_hex_},
762 {"PUBS", pub_hex_},
763 {"NONC", nonce_hex_},
764 {"NONP", "123456789012345678901234567890"},
765 {"VER\0", client_version_string_},
766 {"XLCT", XlctHexString()}},
767 kClientHelloMinimumSize);
768
769 ShouldSucceed(msg);
770 // The message should be rejected because the source-address token is no
771 // longer valid.
772 CheckRejectTag();
773 const HandshakeFailureReason kRejectReasons[] = {
774 SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE};
775 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
776
777 absl::string_view cert, proof, scfg_str;
778 EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
779 EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
780 EXPECT_TRUE(out_.GetStringPiece(kSCFG, &scfg_str));
781 std::unique_ptr<CryptoHandshakeMessage> scfg(
782 CryptoFramer::ParseMessage(scfg_str));
783 absl::string_view scid;
784 EXPECT_TRUE(scfg->GetStringPiece(kSCID, &scid));
785 EXPECT_NE(scid, kOldConfigId);
786
787 // Get certs from compressed certs.
788 std::vector<std::string> cached_certs;
789
790 std::vector<std::string> certs;
791 ASSERT_TRUE(CertCompressor::DecompressChain(cert, cached_certs, &certs));
792
793 // Check that the proof in the REJ message is valid.
794 std::unique_ptr<ProofVerifier> proof_verifier(
795 crypto_test_utils::ProofVerifierForTesting());
796 std::unique_ptr<ProofVerifyContext> verify_context(
797 crypto_test_utils::ProofVerifyContextForTesting());
798 std::unique_ptr<ProofVerifyDetails> details;
799 std::string error_details;
800 std::unique_ptr<ProofVerifierCallback> callback(
801 new DummyProofVerifierCallback());
802 const std::string chlo_hash =
803 CryptoUtils::HashHandshakeMessage(msg, Perspective::IS_SERVER);
804 EXPECT_EQ(QUIC_SUCCESS,
805 proof_verifier->VerifyProof(
806 "test.example.com", 443, (std::string(scfg_str)),
807 client_version_.transport_version, chlo_hash, certs, "",
808 (std::string(proof)), verify_context.get(), &error_details,
809 &details, std::move(callback)));
810 }
811
TEST_P(CryptoServerTest,RejectInvalidXlct)812 TEST_P(CryptoServerTest, RejectInvalidXlct) {
813 CryptoHandshakeMessage msg =
814 crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
815 {"AEAD", "AESG"},
816 {"KEXS", "C255"},
817 {"SCID", scid_hex_},
818 {"#004b5453", srct_hex_},
819 {"PUBS", pub_hex_},
820 {"NONC", nonce_hex_},
821 {"VER\0", client_version_string_},
822 {"XLCT", "#0102030405060708"}},
823 kClientHelloMinimumSize);
824
825 // If replay protection isn't disabled, then
826 // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
827 // and cause ProcessClientHello to exit early (and generate a REJ message).
828 config_.set_replay_protection(false);
829
830 ShouldSucceed(msg);
831
832 const HandshakeFailureReason kRejectReasons[] = {
833 INVALID_EXPECTED_LEAF_CERTIFICATE};
834
835 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
836 }
837
TEST_P(CryptoServerTest,ValidXlct)838 TEST_P(CryptoServerTest, ValidXlct) {
839 CryptoHandshakeMessage msg =
840 crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
841 {"AEAD", "AESG"},
842 {"KEXS", "C255"},
843 {"SCID", scid_hex_},
844 {"#004b5453", srct_hex_},
845 {"PUBS", pub_hex_},
846 {"NONC", nonce_hex_},
847 {"VER\0", client_version_string_},
848 {"XLCT", XlctHexString()}},
849 kClientHelloMinimumSize);
850
851 // If replay protection isn't disabled, then
852 // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
853 // and cause ProcessClientHello to exit early (and generate a REJ message).
854 config_.set_replay_protection(false);
855
856 ShouldSucceed(msg);
857 EXPECT_EQ(kSHLO, out_.tag());
858 }
859
TEST_P(CryptoServerTest,NonceInSHLO)860 TEST_P(CryptoServerTest, NonceInSHLO) {
861 CryptoHandshakeMessage msg =
862 crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
863 {"AEAD", "AESG"},
864 {"KEXS", "C255"},
865 {"SCID", scid_hex_},
866 {"#004b5453", srct_hex_},
867 {"PUBS", pub_hex_},
868 {"NONC", nonce_hex_},
869 {"VER\0", client_version_string_},
870 {"XLCT", XlctHexString()}},
871 kClientHelloMinimumSize);
872
873 // If replay protection isn't disabled, then
874 // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
875 // and cause ProcessClientHello to exit early (and generate a REJ message).
876 config_.set_replay_protection(false);
877
878 ShouldSucceed(msg);
879 EXPECT_EQ(kSHLO, out_.tag());
880
881 absl::string_view nonce;
882 EXPECT_TRUE(out_.GetStringPiece(kServerNonceTag, &nonce));
883 }
884
TEST_P(CryptoServerTest,ProofSourceFailure)885 TEST_P(CryptoServerTest, ProofSourceFailure) {
886 // Install a ProofSource which will unconditionally fail
887 peer_.ResetProofSource(std::unique_ptr<ProofSource>(new FailingProofSource));
888
889 CryptoHandshakeMessage msg =
890 crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
891 {"KEXS", "C255"},
892 {"SCID", scid_hex_},
893 {"PUBS", pub_hex_},
894 {"NONC", nonce_hex_},
895 {"PDMD", "X509"},
896 {"VER\0", client_version_string_}},
897 kClientHelloMinimumSize);
898
899 // Just ensure that we don't crash as occurred in b/33916924.
900 ShouldFailMentioning("", msg);
901 }
902
903 // Regression test for crbug.com/723604
904 // For 2RTT, if the first CHLO from the client contains hashes of cached
905 // certs (stored in CCRT tag) but the second CHLO does not, then the second REJ
906 // from the server should not contain hashes of cached certs.
TEST_P(CryptoServerTest,TwoRttServerDropCachedCerts)907 TEST_P(CryptoServerTest, TwoRttServerDropCachedCerts) {
908 // Send inchoate CHLO to get cert chain from server. This CHLO is only for
909 // the purpose of getting the server's certs; it is not part of the 2RTT
910 // handshake.
911 CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
912 {{"PDMD", "X509"}, {"VER\0", client_version_string_}},
913 kClientHelloMinimumSize);
914 ShouldSucceed(msg);
915
916 // Decompress cert chain from server to individual certs.
917 absl::string_view certs_compressed;
918 ASSERT_TRUE(out_.GetStringPiece(kCertificateTag, &certs_compressed));
919 ASSERT_NE(0u, certs_compressed.size());
920 std::vector<std::string> certs;
921 ASSERT_TRUE(CertCompressor::DecompressChain(certs_compressed,
922 /*cached_certs=*/{}, &certs));
923
924 // Start 2-RTT. Client sends CHLO with bad source-address token and hashes of
925 // the certs, which tells the server that the client has cached those certs.
926 config_.set_chlo_multiplier(1);
927 const char kBadSourceAddressToken[] = "";
928 msg.SetStringPiece(kSourceAddressTokenTag, kBadSourceAddressToken);
929 std::vector<uint64_t> hashes(certs.size());
930 for (size_t i = 0; i < certs.size(); ++i) {
931 hashes[i] = QuicUtils::QuicUtils::FNV1a_64_Hash(certs[i]);
932 }
933 msg.SetVector(kCCRT, hashes);
934 ShouldSucceed(msg);
935
936 // Server responds with inchoate REJ containing valid source-address token.
937 absl::string_view srct;
938 ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct));
939
940 // Client now drops cached certs; sends CHLO with updated source-address
941 // token but no hashes of certs.
942 msg.SetStringPiece(kSourceAddressTokenTag, srct);
943 msg.Erase(kCCRT);
944 ShouldSucceed(msg);
945
946 // Server response's cert chain should not contain hashes of
947 // previously-cached certs.
948 ASSERT_TRUE(out_.GetStringPiece(kCertificateTag, &certs_compressed));
949 ASSERT_NE(0u, certs_compressed.size());
950 ASSERT_TRUE(CertCompressor::DecompressChain(certs_compressed,
951 /*cached_certs=*/{}, &certs));
952 }
953
954 class CryptoServerConfigGenerationTest : public QuicTest {};
955
TEST_F(CryptoServerConfigGenerationTest,Determinism)956 TEST_F(CryptoServerConfigGenerationTest, Determinism) {
957 // Test that using a deterministic PRNG causes the server-config to be
958 // deterministic.
959
960 MockRandom rand_a, rand_b;
961 const QuicCryptoServerConfig::ConfigOptions options;
962 MockClock clock;
963
964 QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
965 crypto_test_utils::ProofSourceForTesting(),
966 KeyExchangeSource::Default());
967 QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b,
968 crypto_test_utils::ProofSourceForTesting(),
969 KeyExchangeSource::Default());
970 std::unique_ptr<CryptoHandshakeMessage> scfg_a(
971 a.AddDefaultConfig(&rand_a, &clock, options));
972 std::unique_ptr<CryptoHandshakeMessage> scfg_b(
973 b.AddDefaultConfig(&rand_b, &clock, options));
974
975 ASSERT_EQ(scfg_a->DebugString(), scfg_b->DebugString());
976 }
977
TEST_F(CryptoServerConfigGenerationTest,SCIDVaries)978 TEST_F(CryptoServerConfigGenerationTest, SCIDVaries) {
979 // This test ensures that the server config ID varies for different server
980 // configs.
981
982 MockRandom rand_a, rand_b;
983 const QuicCryptoServerConfig::ConfigOptions options;
984 MockClock clock;
985
986 QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
987 crypto_test_utils::ProofSourceForTesting(),
988 KeyExchangeSource::Default());
989 rand_b.ChangeValue();
990 QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b,
991 crypto_test_utils::ProofSourceForTesting(),
992 KeyExchangeSource::Default());
993 std::unique_ptr<CryptoHandshakeMessage> scfg_a(
994 a.AddDefaultConfig(&rand_a, &clock, options));
995 std::unique_ptr<CryptoHandshakeMessage> scfg_b(
996 b.AddDefaultConfig(&rand_b, &clock, options));
997
998 absl::string_view scid_a, scid_b;
999 EXPECT_TRUE(scfg_a->GetStringPiece(kSCID, &scid_a));
1000 EXPECT_TRUE(scfg_b->GetStringPiece(kSCID, &scid_b));
1001
1002 EXPECT_NE(scid_a, scid_b);
1003 }
1004
TEST_F(CryptoServerConfigGenerationTest,SCIDIsHashOfServerConfig)1005 TEST_F(CryptoServerConfigGenerationTest, SCIDIsHashOfServerConfig) {
1006 MockRandom rand_a;
1007 const QuicCryptoServerConfig::ConfigOptions options;
1008 MockClock clock;
1009
1010 QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
1011 crypto_test_utils::ProofSourceForTesting(),
1012 KeyExchangeSource::Default());
1013 std::unique_ptr<CryptoHandshakeMessage> scfg(
1014 a.AddDefaultConfig(&rand_a, &clock, options));
1015
1016 absl::string_view scid;
1017 EXPECT_TRUE(scfg->GetStringPiece(kSCID, &scid));
1018 // Need to take a copy of |scid| has we're about to call |Erase|.
1019 const std::string scid_str(scid);
1020
1021 scfg->Erase(kSCID);
1022 scfg->MarkDirty();
1023 const QuicData& serialized(scfg->GetSerialized());
1024
1025 uint8_t digest[SHA256_DIGEST_LENGTH];
1026 SHA256(reinterpret_cast<const uint8_t*>(serialized.data()),
1027 serialized.length(), digest);
1028
1029 // scid is a SHA-256 hash, truncated to 16 bytes.
1030 ASSERT_EQ(scid.size(), 16u);
1031 EXPECT_EQ(0, memcmp(digest, scid_str.c_str(), scid.size()));
1032 }
1033
1034 // Those tests were declared incorrectly and thus never ran in first place.
1035 // TODO(b/147891553): figure out if we should fix or delete those.
1036 #if 0
1037
1038 class CryptoServerTestNoConfig : public CryptoServerTest {
1039 public:
1040 void SetUp() override {
1041 // Deliberately don't add a config so that we can test this situation.
1042 }
1043 };
1044
1045 INSTANTIATE_TEST_SUITE_P(CryptoServerTestsNoConfig,
1046 CryptoServerTestNoConfig,
1047 ::testing::ValuesIn(GetTestParams()),
1048 ::testing::PrintToStringParamName());
1049
1050 TEST_P(CryptoServerTestNoConfig, DontCrash) {
1051 CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
1052 {{"PDMD", "X509"}, {"VER\0", client_version_string_}},
1053 kClientHelloMinimumSize);
1054
1055 ShouldFailMentioning("No config", msg);
1056
1057 const HandshakeFailureReason kRejectReasons[] = {
1058 SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
1059 CheckRejectReasons(kRejectReasons, ABSL_ARRAYSIZE(kRejectReasons));
1060 }
1061
1062 class CryptoServerTestOldVersion : public CryptoServerTest {
1063 public:
1064 void SetUp() override {
1065 client_version_ = supported_versions_.back();
1066 client_version_string_ = ParsedQuicVersionToString(client_version_);
1067 CryptoServerTest::SetUp();
1068 }
1069 };
1070
1071 INSTANTIATE_TEST_SUITE_P(CryptoServerTestsOldVersion,
1072 CryptoServerTestOldVersion,
1073 ::testing::ValuesIn(GetTestParams()),
1074 ::testing::PrintToStringParamName());
1075
1076 TEST_P(CryptoServerTestOldVersion, ServerIgnoresXlct) {
1077 CryptoHandshakeMessage msg =
1078 crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
1079 {"AEAD", "AESG"},
1080 {"KEXS", "C255"},
1081 {"SCID", scid_hex_},
1082 {"#004b5453", srct_hex_},
1083 {"PUBS", pub_hex_},
1084 {"NONC", nonce_hex_},
1085 {"VER\0", client_version_string_},
1086 {"XLCT", "#0100000000000000"}},
1087 kClientHelloMinimumSize);
1088
1089 // If replay protection isn't disabled, then
1090 // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
1091 // and cause ProcessClientHello to exit early (and generate a REJ message).
1092 config_.set_replay_protection(false);
1093
1094 ShouldSucceed(msg);
1095 EXPECT_EQ(kSHLO, out_.tag());
1096 }
1097
1098 TEST_P(CryptoServerTestOldVersion, XlctNotRequired) {
1099 CryptoHandshakeMessage msg =
1100 crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
1101 {"AEAD", "AESG"},
1102 {"KEXS", "C255"},
1103 {"SCID", scid_hex_},
1104 {"#004b5453", srct_hex_},
1105 {"PUBS", pub_hex_},
1106 {"NONC", nonce_hex_},
1107 {"VER\0", client_version_string_}},
1108 kClientHelloMinimumSize);
1109
1110 // If replay protection isn't disabled, then
1111 // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false
1112 // and cause ProcessClientHello to exit early (and generate a REJ message).
1113 config_.set_replay_protection(false);
1114
1115 ShouldSucceed(msg);
1116 EXPECT_EQ(kSHLO, out_.tag());
1117 }
1118
1119 #endif // 0
1120
1121 } // namespace test
1122 } // namespace quic
1123