// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quiche/quic/core/crypto/quic_crypto_client_config.h"

#include <string>

#include "absl/strings/string_view.h"
#include "quiche/quic/core/crypto/proof_verifier.h"
#include "quiche/quic/core/quic_server_id.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/platform/api/quic_expect_bug.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/crypto_test_utils.h"
#include "quiche/quic/test_tools/mock_random.h"
#include "quiche/quic/test_tools/quic_test_utils.h"

using testing::StartsWith;

namespace quic {
namespace test {
namespace {

class TestProofVerifyDetails : public ProofVerifyDetails {
  ~TestProofVerifyDetails() override {}

  // ProofVerifyDetails implementation
  ProofVerifyDetails* Clone() const override {
    return new TestProofVerifyDetails;
  }
};

class OneServerIdFilter : public QuicCryptoClientConfig::ServerIdFilter {
 public:
  explicit OneServerIdFilter(const QuicServerId* server_id)
      : server_id_(*server_id) {}

  bool Matches(const QuicServerId& server_id) const override {
    return server_id == server_id_;
  }

 private:
  const QuicServerId server_id_;
};

class AllServerIdsFilter : public QuicCryptoClientConfig::ServerIdFilter {
 public:
  bool Matches(const QuicServerId& /*server_id*/) const override {
    return true;
  }
};

}  // namespace

class QuicCryptoClientConfigTest : public QuicTest {};

TEST_F(QuicCryptoClientConfigTest, CachedState_IsEmpty) {
  QuicCryptoClientConfig::CachedState state;
  EXPECT_TRUE(state.IsEmpty());
}

TEST_F(QuicCryptoClientConfigTest, CachedState_IsComplete) {
  QuicCryptoClientConfig::CachedState state;
  EXPECT_FALSE(state.IsComplete(QuicWallTime::FromUNIXSeconds(0)));
}

TEST_F(QuicCryptoClientConfigTest, CachedState_GenerationCounter) {
  QuicCryptoClientConfig::CachedState state;
  EXPECT_EQ(0u, state.generation_counter());
  state.SetProofInvalid();
  EXPECT_EQ(1u, state.generation_counter());
}

TEST_F(QuicCryptoClientConfigTest, CachedState_SetProofVerifyDetails) {
  QuicCryptoClientConfig::CachedState state;
  EXPECT_TRUE(state.proof_verify_details() == nullptr);
  ProofVerifyDetails* details = new TestProofVerifyDetails;
  state.SetProofVerifyDetails(details);
  EXPECT_EQ(details, state.proof_verify_details());
}

TEST_F(QuicCryptoClientConfigTest, CachedState_InitializeFrom) {
  QuicCryptoClientConfig::CachedState state;
  QuicCryptoClientConfig::CachedState other;
  state.set_source_address_token("TOKEN");
  // TODO(rch): Populate other fields of |state|.
  other.InitializeFrom(state);
  EXPECT_EQ(state.server_config(), other.server_config());
  EXPECT_EQ(state.source_address_token(), other.source_address_token());
  EXPECT_EQ(state.certs(), other.certs());
  EXPECT_EQ(1u, other.generation_counter());
}

TEST_F(QuicCryptoClientConfigTest, InchoateChlo) {
  QuicCryptoClientConfig::CachedState state;
  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
  config.set_user_agent_id("quic-tester");
  config.set_alpn("hq");
  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
      new QuicCryptoNegotiatedParameters);
  CryptoHandshakeMessage msg;
  QuicServerId server_id("www.google.com", 443, false);
  MockRandom rand;
  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
                                 /* demand_x509_proof= */ true, params, &msg);

  QuicVersionLabel cver;
  EXPECT_THAT(msg.GetVersionLabel(kVER, &cver), IsQuicNoError());
  EXPECT_EQ(CreateQuicVersionLabel(QuicVersionMax()), cver);
  absl::string_view proof_nonce;
  EXPECT_TRUE(msg.GetStringPiece(kNONP, &proof_nonce));
  EXPECT_EQ(std::string(32, 'r'), proof_nonce);
  absl::string_view user_agent_id;
  EXPECT_TRUE(msg.GetStringPiece(kUAID, &user_agent_id));
  EXPECT_EQ("quic-tester", user_agent_id);
  absl::string_view alpn;
  EXPECT_TRUE(msg.GetStringPiece(kALPN, &alpn));
  EXPECT_EQ("hq", alpn);
  EXPECT_EQ(msg.minimum_size(), 1u);
}

TEST_F(QuicCryptoClientConfigTest, InchoateChloIsNotPadded) {
  QuicCryptoClientConfig::CachedState state;
  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
  config.set_pad_inchoate_hello(false);
  config.set_user_agent_id("quic-tester");
  config.set_alpn("hq");
  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
      new QuicCryptoNegotiatedParameters);
  CryptoHandshakeMessage msg;
  QuicServerId server_id("www.google.com", 443, false);
  MockRandom rand;
  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
                                 /* demand_x509_proof= */ true, params, &msg);

  EXPECT_EQ(msg.minimum_size(), 1u);
}

// Make sure AES-GCM is the preferred encryption algorithm if it has hardware
// acceleration.
TEST_F(QuicCryptoClientConfigTest, PreferAesGcm) {
  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
  if (EVP_has_aes_hardware() == 1) {
    EXPECT_EQ(kAESG, config.aead[0]);
  } else {
    EXPECT_EQ(kCC20, config.aead[0]);
  }
}

TEST_F(QuicCryptoClientConfigTest, InchoateChloSecure) {
  QuicCryptoClientConfig::CachedState state;
  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
      new QuicCryptoNegotiatedParameters);
  CryptoHandshakeMessage msg;
  QuicServerId server_id("www.google.com", 443, false);
  MockRandom rand;
  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
                                 /* demand_x509_proof= */ true, params, &msg);

  QuicTag pdmd;
  EXPECT_THAT(msg.GetUint32(kPDMD, &pdmd), IsQuicNoError());
  EXPECT_EQ(kX509, pdmd);
  absl::string_view scid;
  EXPECT_FALSE(msg.GetStringPiece(kSCID, &scid));
}

TEST_F(QuicCryptoClientConfigTest, InchoateChloSecureWithSCIDNoEXPY) {
  // Test that a config with no EXPY is still valid when a non-zero
  // expiry time is passed in.
  QuicCryptoClientConfig::CachedState state;
  CryptoHandshakeMessage scfg;
  scfg.set_tag(kSCFG);
  scfg.SetStringPiece(kSCID, "12345678");
  std::string details;
  QuicWallTime now = QuicWallTime::FromUNIXSeconds(1);
  QuicWallTime expiry = QuicWallTime::FromUNIXSeconds(2);
  state.SetServerConfig(scfg.GetSerialized().AsStringPiece(), now, expiry,
                        &details);
  EXPECT_FALSE(state.IsEmpty());

  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
      new QuicCryptoNegotiatedParameters);
  CryptoHandshakeMessage msg;
  QuicServerId server_id("www.google.com", 443, false);
  MockRandom rand;
  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
                                 /* demand_x509_proof= */ true, params, &msg);

  absl::string_view scid;
  EXPECT_TRUE(msg.GetStringPiece(kSCID, &scid));
  EXPECT_EQ("12345678", scid);
}

TEST_F(QuicCryptoClientConfigTest, InchoateChloSecureWithSCID) {
  QuicCryptoClientConfig::CachedState state;
  CryptoHandshakeMessage scfg;
  scfg.set_tag(kSCFG);
  uint64_t future = 1;
  scfg.SetValue(kEXPY, future);
  scfg.SetStringPiece(kSCID, "12345678");
  std::string details;
  state.SetServerConfig(scfg.GetSerialized().AsStringPiece(),
                        QuicWallTime::FromUNIXSeconds(1),
                        QuicWallTime::FromUNIXSeconds(0), &details);
  EXPECT_FALSE(state.IsEmpty());

  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
      new QuicCryptoNegotiatedParameters);
  CryptoHandshakeMessage msg;
  QuicServerId server_id("www.google.com", 443, false);
  MockRandom rand;
  config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
                                 /* demand_x509_proof= */ true, params, &msg);

  absl::string_view scid;
  EXPECT_TRUE(msg.GetStringPiece(kSCID, &scid));
  EXPECT_EQ("12345678", scid);
}

TEST_F(QuicCryptoClientConfigTest, FillClientHello) {
  QuicCryptoClientConfig::CachedState state;
  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
      new QuicCryptoNegotiatedParameters);
  QuicConnectionId kConnectionId = TestConnectionId(1234);
  std::string error_details;
  MockRandom rand;
  CryptoHandshakeMessage chlo;
  QuicServerId server_id("www.google.com", 443, false);
  config.FillClientHello(server_id, kConnectionId, QuicVersionMax(),
                         QuicVersionMax(), &state, QuicWallTime::Zero(), &rand,
                         params, &chlo, &error_details);

  // Verify that the version label has been set correctly in the CHLO.
  QuicVersionLabel cver;
  EXPECT_THAT(chlo.GetVersionLabel(kVER, &cver), IsQuicNoError());
  EXPECT_EQ(CreateQuicVersionLabel(QuicVersionMax()), cver);
}

TEST_F(QuicCryptoClientConfigTest, FillClientHelloNoPadding) {
  QuicCryptoClientConfig::CachedState state;
  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
  config.set_pad_full_hello(false);
  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
      new QuicCryptoNegotiatedParameters);
  QuicConnectionId kConnectionId = TestConnectionId(1234);
  std::string error_details;
  MockRandom rand;
  CryptoHandshakeMessage chlo;
  QuicServerId server_id("www.google.com", 443, false);
  config.FillClientHello(server_id, kConnectionId, QuicVersionMax(),
                         QuicVersionMax(), &state, QuicWallTime::Zero(), &rand,
                         params, &chlo, &error_details);

  // Verify that the version label has been set correctly in the CHLO.
  QuicVersionLabel cver;
  EXPECT_THAT(chlo.GetVersionLabel(kVER, &cver), IsQuicNoError());
  EXPECT_EQ(CreateQuicVersionLabel(QuicVersionMax()), cver);
  EXPECT_EQ(chlo.minimum_size(), 1u);
}

TEST_F(QuicCryptoClientConfigTest, ProcessServerDowngradeAttack) {
  ParsedQuicVersionVector supported_versions = AllSupportedVersions();
  if (supported_versions.size() == 1) {
    // No downgrade attack is possible if the client only supports one version.
    return;
  }

  ParsedQuicVersionVector supported_version_vector;
  for (size_t i = supported_versions.size(); i > 0; --i) {
    supported_version_vector.push_back(supported_versions[i - 1]);
  }

  CryptoHandshakeMessage msg;
  msg.set_tag(kSHLO);
  msg.SetVersionVector(kVER, supported_version_vector);

  QuicCryptoClientConfig::CachedState cached;
  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
      out_params(new QuicCryptoNegotiatedParameters);
  std::string error;
  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
  EXPECT_THAT(config.ProcessServerHello(
                  msg, EmptyQuicConnectionId(), supported_versions.front(),
                  supported_versions, &cached, out_params, &error),
              IsError(QUIC_VERSION_NEGOTIATION_MISMATCH));
  EXPECT_THAT(error, StartsWith("Downgrade attack detected: ServerVersions"));
}

TEST_F(QuicCryptoClientConfigTest, InitializeFrom) {
  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
  QuicServerId canonical_server_id("www.google.com", 443, false);
  QuicCryptoClientConfig::CachedState* state =
      config.LookupOrCreate(canonical_server_id);
  // TODO(rch): Populate other fields of |state|.
  state->set_source_address_token("TOKEN");
  state->SetProofValid();

  QuicServerId other_server_id("mail.google.com", 443, false);
  config.InitializeFrom(other_server_id, canonical_server_id, &config);
  QuicCryptoClientConfig::CachedState* other =
      config.LookupOrCreate(other_server_id);

  EXPECT_EQ(state->server_config(), other->server_config());
  EXPECT_EQ(state->source_address_token(), other->source_address_token());
  EXPECT_EQ(state->certs(), other->certs());
  EXPECT_EQ(1u, other->generation_counter());
}

TEST_F(QuicCryptoClientConfigTest, Canonical) {
  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
  config.AddCanonicalSuffix(".google.com");
  QuicServerId canonical_id1("www.google.com", 443, false);
  QuicServerId canonical_id2("mail.google.com", 443, false);
  QuicCryptoClientConfig::CachedState* state =
      config.LookupOrCreate(canonical_id1);
  // TODO(rch): Populate other fields of |state|.
  state->set_source_address_token("TOKEN");
  state->SetProofValid();

  QuicCryptoClientConfig::CachedState* other =
      config.LookupOrCreate(canonical_id2);

  EXPECT_TRUE(state->IsEmpty());
  EXPECT_EQ(state->server_config(), other->server_config());
  EXPECT_EQ(state->source_address_token(), other->source_address_token());
  EXPECT_EQ(state->certs(), other->certs());
  EXPECT_EQ(1u, other->generation_counter());

  QuicServerId different_id("mail.google.org", 443, false);
  EXPECT_TRUE(config.LookupOrCreate(different_id)->IsEmpty());
}

TEST_F(QuicCryptoClientConfigTest, CanonicalNotUsedIfNotValid) {
  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
  config.AddCanonicalSuffix(".google.com");
  QuicServerId canonical_id1("www.google.com", 443, false);
  QuicServerId canonical_id2("mail.google.com", 443, false);
  QuicCryptoClientConfig::CachedState* state =
      config.LookupOrCreate(canonical_id1);
  // TODO(rch): Populate other fields of |state|.
  state->set_source_address_token("TOKEN");

  // Do not set the proof as valid, and check that it is not used
  // as a canonical entry.
  EXPECT_TRUE(config.LookupOrCreate(canonical_id2)->IsEmpty());
}

TEST_F(QuicCryptoClientConfigTest, ClearCachedStates) {
  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());

  // Create two states on different origins.
  struct TestCase {
    TestCase(const std::string& host, QuicCryptoClientConfig* config)
        : server_id(host, 443, false),
          state(config->LookupOrCreate(server_id)) {
      // TODO(rch): Populate other fields of |state|.
      CryptoHandshakeMessage scfg;
      scfg.set_tag(kSCFG);
      uint64_t future = 1;
      scfg.SetValue(kEXPY, future);
      scfg.SetStringPiece(kSCID, "12345678");
      std::string details;
      state->SetServerConfig(scfg.GetSerialized().AsStringPiece(),
                             QuicWallTime::FromUNIXSeconds(0),
                             QuicWallTime::FromUNIXSeconds(future), &details);

      std::vector<std::string> certs(1);
      certs[0] = "Hello Cert for " + host;
      state->SetProof(certs, "cert_sct", "chlo_hash", "signature");
      state->set_source_address_token("TOKEN");
      state->SetProofValid();

      // The generation counter starts at 2, because proof has been once
      // invalidated in SetServerConfig().
      EXPECT_EQ(2u, state->generation_counter());
    }

    QuicServerId server_id;
    QuicCryptoClientConfig::CachedState* state;
  } test_cases[] = {TestCase("www.google.com", &config),
                    TestCase("www.example.com", &config)};

  // Verify LookupOrCreate returns the same data.
  for (const TestCase& test_case : test_cases) {
    QuicCryptoClientConfig::CachedState* other =
        config.LookupOrCreate(test_case.server_id);
    EXPECT_EQ(test_case.state, other);
    EXPECT_EQ(2u, other->generation_counter());
  }

  // Clear the cached state for www.google.com.
  OneServerIdFilter google_com_filter(&test_cases[0].server_id);
  config.ClearCachedStates(google_com_filter);

  // Verify LookupOrCreate doesn't have any data for google.com.
  QuicCryptoClientConfig::CachedState* cleared_cache =
      config.LookupOrCreate(test_cases[0].server_id);

  EXPECT_EQ(test_cases[0].state, cleared_cache);
  EXPECT_FALSE(cleared_cache->proof_valid());
  EXPECT_TRUE(cleared_cache->server_config().empty());
  EXPECT_TRUE(cleared_cache->certs().empty());
  EXPECT_TRUE(cleared_cache->cert_sct().empty());
  EXPECT_TRUE(cleared_cache->signature().empty());
  EXPECT_EQ(3u, cleared_cache->generation_counter());

  // But it still does for www.example.com.
  QuicCryptoClientConfig::CachedState* existing_cache =
      config.LookupOrCreate(test_cases[1].server_id);

  EXPECT_EQ(test_cases[1].state, existing_cache);
  EXPECT_TRUE(existing_cache->proof_valid());
  EXPECT_FALSE(existing_cache->server_config().empty());
  EXPECT_FALSE(existing_cache->certs().empty());
  EXPECT_FALSE(existing_cache->cert_sct().empty());
  EXPECT_FALSE(existing_cache->signature().empty());
  EXPECT_EQ(2u, existing_cache->generation_counter());

  // Clear all cached states.
  AllServerIdsFilter all_server_ids;
  config.ClearCachedStates(all_server_ids);

  // The data for www.example.com should now be cleared as well.
  cleared_cache = config.LookupOrCreate(test_cases[1].server_id);

  EXPECT_EQ(test_cases[1].state, cleared_cache);
  EXPECT_FALSE(cleared_cache->proof_valid());
  EXPECT_TRUE(cleared_cache->server_config().empty());
  EXPECT_TRUE(cleared_cache->certs().empty());
  EXPECT_TRUE(cleared_cache->cert_sct().empty());
  EXPECT_TRUE(cleared_cache->signature().empty());
  EXPECT_EQ(3u, cleared_cache->generation_counter());
}

TEST_F(QuicCryptoClientConfigTest, ProcessReject) {
  CryptoHandshakeMessage rej;
  crypto_test_utils::FillInDummyReject(&rej);

  // Now process the rejection.
  QuicCryptoClientConfig::CachedState cached;
  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
      out_params(new QuicCryptoNegotiatedParameters);
  std::string error;
  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
  EXPECT_THAT(
      config.ProcessRejection(
          rej, QuicWallTime::FromUNIXSeconds(0),
          AllSupportedVersionsWithQuicCrypto().front().transport_version, "",
          &cached, out_params, &error),
      IsQuicNoError());
}

TEST_F(QuicCryptoClientConfigTest, ProcessRejectWithLongTTL) {
  CryptoHandshakeMessage rej;
  crypto_test_utils::FillInDummyReject(&rej);
  QuicTime::Delta one_week = QuicTime::Delta::FromSeconds(kNumSecondsPerWeek);
  int64_t long_ttl = 3 * one_week.ToSeconds();
  rej.SetValue(kSTTL, long_ttl);

  // Now process the rejection.
  QuicCryptoClientConfig::CachedState cached;
  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
      out_params(new QuicCryptoNegotiatedParameters);
  std::string error;
  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
  EXPECT_THAT(
      config.ProcessRejection(
          rej, QuicWallTime::FromUNIXSeconds(0),
          AllSupportedVersionsWithQuicCrypto().front().transport_version, "",
          &cached, out_params, &error),
      IsQuicNoError());
  cached.SetProofValid();
  EXPECT_FALSE(cached.IsComplete(QuicWallTime::FromUNIXSeconds(long_ttl)));
  EXPECT_FALSE(
      cached.IsComplete(QuicWallTime::FromUNIXSeconds(one_week.ToSeconds())));
  EXPECT_TRUE(cached.IsComplete(
      QuicWallTime::FromUNIXSeconds(one_week.ToSeconds() - 1)));
}

TEST_F(QuicCryptoClientConfigTest, ServerNonceinSHLO) {
  // Test that the server must include a nonce in the SHLO.
  CryptoHandshakeMessage msg;
  msg.set_tag(kSHLO);
  // Choose the latest version.
  ParsedQuicVersionVector supported_versions;
  ParsedQuicVersion version = AllSupportedVersions().front();
  supported_versions.push_back(version);
  msg.SetVersionVector(kVER, supported_versions);

  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
  QuicCryptoClientConfig::CachedState cached;
  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
      out_params(new QuicCryptoNegotiatedParameters);
  std::string error_details;
  EXPECT_THAT(config.ProcessServerHello(msg, EmptyQuicConnectionId(), version,
                                        supported_versions, &cached, out_params,
                                        &error_details),
              IsError(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER));
  EXPECT_EQ("server hello missing server nonce", error_details);
}

// Test that PopulateFromCanonicalConfig() handles the case of multiple entries
// in |canonical_server_map_|.
TEST_F(QuicCryptoClientConfigTest, MultipleCanonicalEntries) {
  QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
  config.AddCanonicalSuffix(".google.com");
  QuicServerId canonical_server_id1("www.google.com", 443, false);
  QuicCryptoClientConfig::CachedState* state1 =
      config.LookupOrCreate(canonical_server_id1);

  CryptoHandshakeMessage scfg;
  scfg.set_tag(kSCFG);
  scfg.SetStringPiece(kSCID, "12345678");
  std::string details;
  QuicWallTime now = QuicWallTime::FromUNIXSeconds(1);
  QuicWallTime expiry = QuicWallTime::FromUNIXSeconds(2);
  state1->SetServerConfig(scfg.GetSerialized().AsStringPiece(), now, expiry,
                          &details);
  state1->set_source_address_token("TOKEN");
  state1->SetProofValid();
  EXPECT_FALSE(state1->IsEmpty());

  // This will have the same |suffix_server_id| as |canonical_server_id1|,
  // therefore |*state2| will be initialized from |*state1|.
  QuicServerId canonical_server_id2("mail.google.com", 443, false);
  QuicCryptoClientConfig::CachedState* state2 =
      config.LookupOrCreate(canonical_server_id2);
  EXPECT_FALSE(state2->IsEmpty());
  const CryptoHandshakeMessage* const scfg2 = state2->GetServerConfig();
  ASSERT_TRUE(scfg2);
  EXPECT_EQ(kSCFG, scfg2->tag());

  // With a different |suffix_server_id|, this will return an empty CachedState.
  config.AddCanonicalSuffix(".example.com");
  QuicServerId canonical_server_id3("www.example.com", 443, false);
  QuicCryptoClientConfig::CachedState* state3 =
      config.LookupOrCreate(canonical_server_id3);
  EXPECT_TRUE(state3->IsEmpty());
  const CryptoHandshakeMessage* const scfg3 = state3->GetServerConfig();
  EXPECT_FALSE(scfg3);
}

}  // namespace test
}  // namespace quic
