Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/test_tools/crypto_test_utils_test.cc b/quic/test_tools/crypto_test_utils_test.cc
new file mode 100644
index 0000000..cecdaa2
--- /dev/null
+++ b/quic/test_tools/crypto_test_utils_test.cc
@@ -0,0 +1,172 @@
+// Copyright (c) 2012 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 "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
+
+#include "net/third_party/quiche/src/quic/core/proto/crypto_server_config.pb.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
+
+namespace quic {
+namespace test {
+
+class ShloVerifier {
+ public:
+  ShloVerifier(
+      QuicCryptoServerConfig* crypto_config,
+      QuicSocketAddress server_addr,
+      QuicSocketAddress client_addr,
+      const QuicClock* clock,
+      QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config,
+      QuicCompressedCertsCache* compressed_certs_cache)
+      : crypto_config_(crypto_config),
+        server_addr_(server_addr),
+        client_addr_(client_addr),
+        clock_(clock),
+        signed_config_(signed_config),
+        compressed_certs_cache_(compressed_certs_cache),
+        params_(new QuicCryptoNegotiatedParameters) {}
+
+  class ValidateClientHelloCallback : public ValidateClientHelloResultCallback {
+   public:
+    explicit ValidateClientHelloCallback(ShloVerifier* shlo_verifier)
+        : shlo_verifier_(shlo_verifier) {}
+    void Run(QuicReferenceCountedPointer<
+                 ValidateClientHelloResultCallback::Result> result,
+             std::unique_ptr<ProofSource::Details> /* details */) override {
+      shlo_verifier_->ValidateClientHelloDone(result);
+    }
+
+   private:
+    ShloVerifier* shlo_verifier_;
+  };
+
+  std::unique_ptr<ValidateClientHelloCallback>
+  GetValidateClientHelloCallback() {
+    return QuicMakeUnique<ValidateClientHelloCallback>(this);
+  }
+
+ private:
+  void ValidateClientHelloDone(
+      const QuicReferenceCountedPointer<
+          ValidateClientHelloResultCallback::Result>& result) {
+    result_ = result;
+    crypto_config_->ProcessClientHello(
+        result_, /*reject_only=*/false,
+        /*connection_id=*/TestConnectionId(1), server_addr_, client_addr_,
+        AllSupportedVersions().front(), AllSupportedVersions(),
+        /*use_stateless_rejects=*/true,
+        /*server_designated_connection_id=*/TestConnectionId(2), clock_,
+        QuicRandom::GetInstance(), compressed_certs_cache_, params_,
+        signed_config_, /*total_framing_overhead=*/50, kDefaultMaxPacketSize,
+        GetProcessClientHelloCallback());
+  }
+
+  class ProcessClientHelloCallback : public ProcessClientHelloResultCallback {
+   public:
+    explicit ProcessClientHelloCallback(ShloVerifier* shlo_verifier)
+        : shlo_verifier_(shlo_verifier) {}
+    void Run(
+        QuicErrorCode error,
+        const QuicString& error_details,
+        std::unique_ptr<CryptoHandshakeMessage> message,
+        std::unique_ptr<DiversificationNonce> diversification_nonce,
+        std::unique_ptr<ProofSource::Details> proof_source_details) override {
+      shlo_verifier_->ProcessClientHelloDone(std::move(message));
+    }
+
+   private:
+    ShloVerifier* shlo_verifier_;
+  };
+
+  std::unique_ptr<ProcessClientHelloCallback> GetProcessClientHelloCallback() {
+    return QuicMakeUnique<ProcessClientHelloCallback>(this);
+  }
+
+  void ProcessClientHelloDone(std::unique_ptr<CryptoHandshakeMessage> message) {
+    // Verify output is a SHLO.
+    EXPECT_EQ(message->tag(), kSHLO)
+        << "Fail to pass validation. Get " << message->DebugString();
+  }
+
+  QuicCryptoServerConfig* crypto_config_;
+  QuicSocketAddress server_addr_;
+  QuicSocketAddress client_addr_;
+  const QuicClock* clock_;
+  QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
+  QuicCompressedCertsCache* compressed_certs_cache_;
+
+  QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
+  QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
+      result_;
+};
+
+class CryptoTestUtilsTest : public QuicTest {};
+
+TEST_F(CryptoTestUtilsTest, TestGenerateFullCHLO) {
+  MockClock clock;
+  QuicCryptoServerConfig crypto_config(
+      QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
+      crypto_test_utils::ProofSourceForTesting(), KeyExchangeSource::Default(),
+      TlsServerHandshaker::CreateSslCtx());
+  QuicSocketAddress server_addr(QuicIpAddress::Any4(), 5);
+  QuicSocketAddress client_addr(QuicIpAddress::Loopback4(), 1);
+  QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config(
+      new QuicSignedServerConfig);
+  QuicCompressedCertsCache compressed_certs_cache(
+      QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
+  CryptoHandshakeMessage full_chlo;
+
+  QuicCryptoServerConfig::ConfigOptions old_config_options;
+  old_config_options.id = "old-config-id";
+  delete crypto_config.AddDefaultConfig(QuicRandom::GetInstance(), &clock,
+                                        old_config_options);
+  QuicCryptoServerConfig::ConfigOptions new_config_options;
+  std::unique_ptr<QuicServerConfigProtobuf> primary_config(
+      crypto_config.GenerateConfig(QuicRandom::GetInstance(), &clock,
+                                   new_config_options));
+  primary_config->set_primary_time(clock.WallNow().ToUNIXSeconds());
+  std::unique_ptr<CryptoHandshakeMessage> msg(
+      crypto_config.AddConfig(std::move(primary_config), clock.WallNow()));
+  QuicStringPiece orbit;
+  ASSERT_TRUE(msg->GetStringPiece(kORBT, &orbit));
+  QuicString nonce;
+  CryptoUtils::GenerateNonce(clock.WallNow(), QuicRandom::GetInstance(), orbit,
+                             &nonce);
+  QuicString nonce_hex = "#" + QuicTextUtils::HexEncode(nonce);
+
+  char public_value[32];
+  memset(public_value, 42, sizeof(public_value));
+  QuicString pub_hex =
+      "#" + QuicTextUtils::HexEncode(public_value, sizeof(public_value));
+
+  QuicTransportVersion version(AllSupportedTransportVersions().front());
+  CryptoHandshakeMessage inchoate_chlo = crypto_test_utils::CreateCHLO(
+      {{"PDMD", "X509"},
+       {"AEAD", "AESG"},
+       {"KEXS", "C255"},
+       {"COPT", "SREJ"},
+       {"PUBS", pub_hex},
+       {"NONC", nonce_hex},
+       {"VER\0",
+        QuicVersionLabelToString(QuicVersionToQuicVersionLabel(version))}},
+      kClientHelloMinimumSize);
+
+  crypto_test_utils::GenerateFullCHLO(
+      inchoate_chlo, &crypto_config, server_addr, client_addr, version, &clock,
+      signed_config, &compressed_certs_cache, &full_chlo);
+  // Verify that full_chlo can pass crypto_config's verification.
+  ShloVerifier shlo_verifier(&crypto_config, server_addr, client_addr, &clock,
+                             signed_config, &compressed_certs_cache);
+  crypto_config.ValidateClientHello(
+      full_chlo, client_addr.host(), server_addr, version, &clock,
+      signed_config, shlo_verifier.GetValidateClientHelloCallback());
+}
+
+}  // namespace test
+}  // namespace quic