• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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