Refactor more TLS handshake tests in QUIC.

QuicCryptoServerStreamTest now only tests QUIC Crypto. The TLS tests from
that file have been moved to a new TlsServerHandshakerTest file. The
remaining tests from TlsHandshakerTest have also been moved to
TlsServerHandshakerTest (client tests were moved to TlsClientHandshakerTest
in cl/306682737) and removes TlsHandshakerTest.

gfe-relnote: n/a - test-only refactor.
PiperOrigin-RevId: 307452036
Change-Id: I3f7cb8d88fcc1da9789a65305a9d4079154dde93
diff --git a/quic/core/quic_crypto_client_stream.h b/quic/core/quic_crypto_client_stream.h
index a66dcba..5ec1b01 100644
--- a/quic/core/quic_crypto_client_stream.h
+++ b/quic/core/quic_crypto_client_stream.h
@@ -21,6 +21,10 @@
 
 namespace quic {
 
+namespace test {
+class QuicCryptoClientStreamPeer;
+}  // namespace test
+
 class QUIC_EXPORT_PRIVATE QuicCryptoClientStreamBase : public QuicCryptoStream {
  public:
   explicit QuicCryptoClientStreamBase(QuicSession* session);
@@ -221,6 +225,7 @@
   }
 
  private:
+  friend class test::QuicCryptoClientStreamPeer;
   std::unique_ptr<HandshakerInterface> handshaker_;
 };
 
diff --git a/quic/core/quic_crypto_server_stream_test.cc b/quic/core/quic_crypto_server_stream_test.cc
index a3f0d11..debfc3b 100644
--- a/quic/core/quic_crypto_server_stream_test.cc
+++ b/quic/core/quic_crypto_server_stream_test.cc
@@ -50,6 +50,8 @@
 const char kServerHostname[] = "test.example.com";
 const uint16_t kServerPort = 443;
 
+// This test tests the server-side of the QUIC crypto handshake. It does not
+// test the TLS handshake - that is in tls_server_handshaker_test.cc.
 class QuicCryptoServerStreamTest : public QuicTest {
  public:
   QuicCryptoServerStreamTest()
@@ -152,28 +154,6 @@
                                         server_connection_, server_stream(), 0);
   }
 
-  void UseTlsHandshake() {
-    client_options_.only_tls_versions = true;
-    supported_versions_.clear();
-    for (ParsedQuicVersion version : AllSupportedVersions()) {
-      if (version.handshake_protocol != PROTOCOL_TLS1_3) {
-        continue;
-      }
-      supported_versions_.push_back(version);
-    }
-  }
-
-  void UseQuicCryptoHandshake() {
-    client_options_.only_quic_crypto_versions = true;
-    supported_versions_.clear();
-    for (ParsedQuicVersion version : AllSupportedVersions()) {
-      if (version.handshake_protocol != PROTOCOL_QUIC_CRYPTO) {
-        continue;
-      }
-      supported_versions_.push_back(version);
-    }
-  }
-
  protected:
   // Every connection gets its own MockQuicConnectionHelper and
   // MockAlarmFactory, tracked separately from the server and client state so
@@ -197,7 +177,8 @@
   crypto_test_utils::FakeClientOptions client_options_;
 
   // Which QUIC versions the client and server support.
-  ParsedQuicVersionVector supported_versions_ = AllSupportedVersions();
+  ParsedQuicVersionVector supported_versions_ =
+      AllSupportedVersionsWithQuicCrypto();
 };
 
 TEST_F(QuicCryptoServerStreamTest, NotInitiallyConected) {
@@ -211,24 +192,13 @@
   // test should send:
   //   * One to get a source-address token and certificates.
   //   * One to complete the handshake.
-  UseQuicCryptoHandshake();
   Initialize();
   EXPECT_EQ(2, CompleteCryptoHandshake());
   EXPECT_TRUE(server_stream()->encryption_established());
   EXPECT_TRUE(server_stream()->one_rtt_keys_available());
 }
 
-TEST_F(QuicCryptoServerStreamTest, ConnectedAfterTlsHandshake) {
-  UseTlsHandshake();
-  Initialize();
-  CompleteCryptoHandshake();
-  EXPECT_EQ(PROTOCOL_TLS1_3, server_stream()->handshake_protocol());
-  EXPECT_TRUE(server_stream()->encryption_established());
-  EXPECT_TRUE(server_stream()->one_rtt_keys_available());
-}
-
 TEST_F(QuicCryptoServerStreamTest, ForwardSecureAfterCHLO) {
-  UseQuicCryptoHandshake();
   Initialize();
   InitializeFakeClient();
 
@@ -250,7 +220,6 @@
 }
 
 TEST_F(QuicCryptoServerStreamTest, ZeroRTT) {
-  UseQuicCryptoHandshake();
   Initialize();
   InitializeFakeClient();
 
@@ -282,7 +251,6 @@
 }
 
 TEST_F(QuicCryptoServerStreamTest, FailByPolicy) {
-  UseQuicCryptoHandshake();
   Initialize();
   InitializeFakeClient();
 
@@ -295,7 +263,6 @@
 }
 
 TEST_F(QuicCryptoServerStreamTest, MessageAfterHandshake) {
-  UseQuicCryptoHandshake();
   Initialize();
   CompleteCryptoHandshake();
   EXPECT_CALL(
@@ -307,7 +274,6 @@
 }
 
 TEST_F(QuicCryptoServerStreamTest, BadMessageType) {
-  UseQuicCryptoHandshake();
   Initialize();
 
   message_.set_tag(kSHLO);
@@ -326,7 +292,6 @@
 }
 
 TEST_F(QuicCryptoServerStreamTest, SendSCUPAfterHandshakeComplete) {
-  UseQuicCryptoHandshake();
   Initialize();
 
   InitializeFakeClient();
@@ -359,7 +324,6 @@
 };
 
 TEST_F(QuicCryptoServerStreamTestWithFailingProofSource, Test) {
-  UseQuicCryptoHandshake();
   Initialize();
   InitializeFakeClient();
 
@@ -393,7 +357,6 @@
 // connection in close succession could cause a crash, especially when the use
 // of Mentat signing meant that it took a while for each CHLO to be processed.
 TEST_F(QuicCryptoServerStreamTestWithFakeProofSource, MultipleChlo) {
-  UseQuicCryptoHandshake();
   Initialize();
   GetFakeProofSource()->Activate();
   EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
diff --git a/quic/core/tls_client_handshaker_test.cc b/quic/core/tls_client_handshaker_test.cc
index 0283169..bb859c1 100644
--- a/quic/core/tls_client_handshaker_test.cc
+++ b/quic/core/tls_client_handshaker_test.cc
@@ -256,7 +256,7 @@
   EXPECT_FALSE(stream()->IsResumption());
 }
 
-TEST_P(TlsClientHandshakerTest, ConnecitonClosedOnTlsError) {
+TEST_P(TlsClientHandshakerTest, ConnectionClosedOnTlsError) {
   // Have client send ClientHello.
   stream()->CryptoConnect();
   EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
diff --git a/quic/core/tls_handshaker_test.cc b/quic/core/tls_handshaker_test.cc
index de3a8a4..6103743 100644
--- a/quic/core/tls_handshaker_test.cc
+++ b/quic/core/tls_handshaker_test.cc
@@ -434,138 +434,6 @@
   ExpectHandshakeSuccessful();
 }
 
-TEST_P(TlsHandshakerTest, HandshakeWithAsyncProofSource) {
-  EXPECT_CALL(*client_conn_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_CALL(*server_conn_, CloseConnection(_, _, _)).Times(0);
-  // Enable FakeProofSource to capture call to ComputeTlsSignature and run it
-  // asynchronously.
-  FakeProofSource* proof_source = server_stream_->GetFakeProofSource();
-  proof_source->Activate();
-
-  // Start handshake.
-  client_stream_->CryptoConnect();
-  ExchangeHandshakeMessages(client_stream_, server_stream_);
-
-  ASSERT_EQ(proof_source->NumPendingCallbacks(), 1);
-  proof_source->InvokePendingCallback(0);
-
-  ExchangeHandshakeMessages(client_stream_, server_stream_);
-
-  ExpectHandshakeSuccessful();
-}
-
-TEST_P(TlsHandshakerTest, CancelPendingProofSource) {
-  EXPECT_CALL(*client_conn_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_CALL(*server_conn_, CloseConnection(_, _, _)).Times(0);
-  // Enable FakeProofSource to capture call to ComputeTlsSignature and run it
-  // asynchronously.
-  FakeProofSource* proof_source = server_stream_->GetFakeProofSource();
-  proof_source->Activate();
-
-  // Start handshake.
-  client_stream_->CryptoConnect();
-  ExchangeHandshakeMessages(client_stream_, server_stream_);
-
-  ASSERT_EQ(proof_source->NumPendingCallbacks(), 1);
-  server_stream_ = nullptr;
-
-  proof_source->InvokePendingCallback(0);
-}
-
-TEST_P(TlsHandshakerTest, ServerExtractSNI) {
-  EXPECT_CALL(*client_conn_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_CALL(*server_conn_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_CALL(client_stream_->proof_handler(), OnProofVerifyDetailsAvailable);
-  client_stream_->CryptoConnect();
-  ExchangeHandshakeMessages(client_stream_, server_stream_);
-  ExpectHandshakeSuccessful();
-
-  EXPECT_EQ(server_stream_->crypto_negotiated_params().sni, "test.example.com");
-}
-
-TEST_P(TlsHandshakerTest, ServerConnectionClosedOnTlsError) {
-  EXPECT_CALL(*server_conn_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
-
-  // Send a zero-length ClientHello from client to server.
-  char bogus_handshake_message[] = {
-      // Handshake struct (RFC 8446 appendix B.3)
-      1,        // HandshakeType client_hello
-      0, 0, 0,  // uint24 length
-  };
-  client_stream_->WriteCryptoData(
-      ENCRYPTION_INITIAL,
-      quiche::QuicheStringPiece(bogus_handshake_message,
-                                QUICHE_ARRAYSIZE(bogus_handshake_message)));
-  client_stream_->SendCryptoMessagesToPeer(server_stream_);
-
-  EXPECT_FALSE(server_stream_->one_rtt_keys_available());
-}
-
-TEST_P(TlsHandshakerTest, ClientNotSendingALPN) {
-  client_stream_->client_handshaker()->AllowEmptyAlpnForTests();
-  EXPECT_CALL(client_session_, GetAlpnsToOffer())
-      .WillOnce(Return(std::vector<std::string>()));
-  EXPECT_CALL(*client_conn_, CloseConnection(QUIC_HANDSHAKE_FAILED,
-                                             "Server did not select ALPN", _));
-  EXPECT_CALL(*server_conn_,
-              CloseConnection(QUIC_HANDSHAKE_FAILED,
-                              "Server did not receive a known ALPN", _));
-  client_stream_->CryptoConnect();
-  ExchangeHandshakeMessages(client_stream_, server_stream_);
-
-  EXPECT_FALSE(client_stream_->one_rtt_keys_available());
-  EXPECT_EQ(GetQuicRestartFlag(quic_send_settings_on_write_key_available),
-            client_stream_->encryption_established());
-  EXPECT_FALSE(server_stream_->one_rtt_keys_available());
-  EXPECT_EQ(GetQuicRestartFlag(quic_send_settings_on_write_key_available),
-            server_stream_->encryption_established());
-}
-
-TEST_P(TlsHandshakerTest, ClientSendingBadALPN) {
-  const std::string kTestBadClientAlpn = "bad-client-alpn";
-  EXPECT_CALL(client_session_, GetAlpnsToOffer())
-      .WillOnce(Return(std::vector<std::string>({kTestBadClientAlpn})));
-  EXPECT_CALL(*client_conn_, CloseConnection(QUIC_HANDSHAKE_FAILED,
-                                             "Server did not select ALPN", _));
-  EXPECT_CALL(*server_conn_,
-              CloseConnection(QUIC_HANDSHAKE_FAILED,
-                              "Server did not receive a known ALPN", _));
-  client_stream_->CryptoConnect();
-  ExchangeHandshakeMessages(client_stream_, server_stream_);
-
-  EXPECT_FALSE(client_stream_->one_rtt_keys_available());
-  EXPECT_EQ(GetQuicRestartFlag(quic_send_settings_on_write_key_available),
-            client_stream_->encryption_established());
-  EXPECT_FALSE(server_stream_->one_rtt_keys_available());
-  EXPECT_EQ(GetQuicRestartFlag(quic_send_settings_on_write_key_available),
-            server_stream_->encryption_established());
-}
-
-TEST_P(TlsHandshakerTest, CustomALPNNegotiation) {
-  EXPECT_CALL(*client_conn_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_CALL(*server_conn_, CloseConnection(_, _, _)).Times(0);
-
-  const std::string kTestAlpn = "A Custom ALPN Value";
-  const std::vector<std::string> kTestAlpns(
-      {"foo", "bar", kTestAlpn, "something else"});
-  EXPECT_CALL(client_session_, GetAlpnsToOffer())
-      .WillRepeatedly(Return(kTestAlpns));
-  EXPECT_CALL(server_session_, SelectAlpn(_))
-      .WillOnce([kTestAlpn, kTestAlpns](
-                    const std::vector<quiche::QuicheStringPiece>& alpns) {
-        EXPECT_THAT(alpns, ElementsAreArray(kTestAlpns));
-        return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn);
-      });
-  EXPECT_CALL(client_session_,
-              OnAlpnSelected(quiche::QuicheStringPiece(kTestAlpn)));
-  EXPECT_CALL(server_session_,
-              OnAlpnSelected(quiche::QuicheStringPiece(kTestAlpn)));
-  client_stream_->CryptoConnect();
-  ExchangeHandshakeMessages(client_stream_, server_stream_);
-
-  ExpectHandshakeSuccessful();
-}
-
 }  // namespace
 }  // namespace test
 }  // namespace quic
diff --git a/quic/core/tls_server_handshaker_test.cc b/quic/core/tls_server_handshaker_test.cc
new file mode 100644
index 0000000..7a30a13
--- /dev/null
+++ b/quic/core/tls_server_handshaker_test.cc
@@ -0,0 +1,352 @@
+// 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 <memory>
+#include <utility>
+#include <vector>
+
+#include "net/third_party/quiche/src/quic/core/crypto/proof_source.h"
+#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
+#include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_session.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/core/quic_versions.h"
+#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/fake_proof_source.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
+#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
+
+namespace quic {
+class QuicConnection;
+class QuicStream;
+}  // namespace quic
+
+using testing::_;
+using testing::NiceMock;
+using testing::Return;
+
+namespace quic {
+namespace test {
+
+namespace {
+
+const char kServerHostname[] = "test.example.com";
+const uint16_t kServerPort = 443;
+
+class TlsServerHandshakerTest : public QuicTest {
+ public:
+  TlsServerHandshakerTest()
+      : proof_source_(new FakeProofSource()),
+        server_crypto_config_(QuicCryptoServerConfig::TESTING,
+                              QuicRandom::GetInstance(),
+                              std::unique_ptr<ProofSource>(proof_source_),
+                              KeyExchangeSource::Default()),
+        server_compressed_certs_cache_(
+            QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
+        server_id_(kServerHostname, kServerPort, false),
+        client_crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {
+    InitializeServer();
+    InitializeFakeClient();
+  }
+
+  ~TlsServerHandshakerTest() override {
+    // Ensure that anything that might reference |helpers_| is destroyed before
+    // |helpers_| is destroyed.
+    server_session_.reset();
+    client_session_.reset();
+    helpers_.clear();
+    alarm_factories_.clear();
+  }
+
+  // Initializes the crypto server stream state for testing.  May be
+  // called multiple times.
+  void InitializeServer() {
+    TestQuicSpdyServerSession* server_session = nullptr;
+    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
+    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
+    CreateServerSessionForTest(
+        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
+        helpers_.back().get(), alarm_factories_.back().get(),
+        &server_crypto_config_, &server_compressed_certs_cache_,
+        &server_connection_, &server_session);
+    CHECK(server_session);
+    server_session_.reset(server_session);
+    EXPECT_CALL(*server_session_->helper(), CanAcceptClientHello(_, _, _, _, _))
+        .Times(testing::AnyNumber());
+    EXPECT_CALL(*server_session_, SelectAlpn(_))
+        .WillRepeatedly(
+            [this](const std::vector<quiche::QuicheStringPiece>& alpns) {
+              return std::find(
+                  alpns.cbegin(), alpns.cend(),
+                  AlpnForVersion(server_session_->connection()->version()));
+            });
+    crypto_test_utils::SetupCryptoServerConfigForTest(
+        server_connection_->clock(), server_connection_->random_generator(),
+        &server_crypto_config_);
+  }
+
+  QuicCryptoServerStreamBase* server_stream() {
+    return server_session_->GetMutableCryptoStream();
+  }
+
+  QuicCryptoClientStream* client_stream() {
+    return client_session_->GetMutableCryptoStream();
+  }
+
+  // Initializes a fake client, and all its associated state, for
+  // testing.  May be called multiple times.
+  void InitializeFakeClient() {
+    TestQuicSpdyClientSession* client_session = nullptr;
+    helpers_.push_back(std::make_unique<NiceMock<MockQuicConnectionHelper>>());
+    alarm_factories_.push_back(std::make_unique<MockAlarmFactory>());
+    CreateClientSessionForTest(
+        server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
+        helpers_.back().get(), alarm_factories_.back().get(),
+        &client_crypto_config_, &client_connection_, &client_session);
+    const std::string default_alpn =
+        AlpnForVersion(client_connection_->version());
+    ON_CALL(*client_session, GetAlpnsToOffer())
+        .WillByDefault(Return(std::vector<std::string>({default_alpn})));
+    CHECK(client_session);
+    client_session_.reset(client_session);
+  }
+
+  void CompleteCryptoHandshake() {
+    while (!client_stream()->one_rtt_keys_available() ||
+           !server_stream()->one_rtt_keys_available()) {
+      auto previous_moved_messages_counts = moved_messages_counts_;
+      AdvanceHandshakeWithFakeClient();
+      // Check that the handshake has made forward progress
+      ASSERT_NE(previous_moved_messages_counts, moved_messages_counts_);
+    }
+  }
+
+  // Performs a single round of handshake message-exchange between the
+  // client and server.
+  void AdvanceHandshakeWithFakeClient() {
+    CHECK(server_connection_);
+    CHECK(client_session_ != nullptr);
+
+    EXPECT_CALL(*client_session_, OnProofValid(_)).Times(testing::AnyNumber());
+    EXPECT_CALL(*client_session_, OnProofVerifyDetailsAvailable(_))
+        .Times(testing::AnyNumber());
+    EXPECT_CALL(*client_connection_, OnCanWrite()).Times(testing::AnyNumber());
+    EXPECT_CALL(*server_connection_, OnCanWrite()).Times(testing::AnyNumber());
+    // Call CryptoConnect if we haven't moved any client messages yet.
+    if (moved_messages_counts_.first == 0) {
+      client_stream()->CryptoConnect();
+    }
+    moved_messages_counts_ = crypto_test_utils::AdvanceHandshake(
+        client_connection_, client_stream(), moved_messages_counts_.first,
+        server_connection_, server_stream(), moved_messages_counts_.second);
+  }
+
+  void ExpectHandshakeSuccessful() {
+    EXPECT_TRUE(client_stream()->one_rtt_keys_available());
+    EXPECT_TRUE(client_stream()->encryption_established());
+    EXPECT_TRUE(server_stream()->one_rtt_keys_available());
+    EXPECT_TRUE(server_stream()->encryption_established());
+    EXPECT_EQ(HANDSHAKE_COMPLETE, client_stream()->GetHandshakeState());
+    EXPECT_EQ(HANDSHAKE_CONFIRMED, server_stream()->GetHandshakeState());
+
+    const auto& client_crypto_params =
+        client_stream()->crypto_negotiated_params();
+    const auto& server_crypto_params =
+        server_stream()->crypto_negotiated_params();
+    // The TLS params should be filled in on the client.
+    EXPECT_NE(0, client_crypto_params.cipher_suite);
+    EXPECT_NE(0, client_crypto_params.key_exchange_group);
+    EXPECT_NE(0, client_crypto_params.peer_signature_algorithm);
+
+    // The cipher suite and key exchange group should match on the client and
+    // server.
+    EXPECT_EQ(client_crypto_params.cipher_suite,
+              server_crypto_params.cipher_suite);
+    EXPECT_EQ(client_crypto_params.key_exchange_group,
+              server_crypto_params.key_exchange_group);
+    // We don't support client certs on the server (yet), so the server
+    // shouldn't have a peer signature algorithm to report.
+    EXPECT_EQ(0, server_crypto_params.peer_signature_algorithm);
+  }
+
+ protected:
+  // Every connection gets its own MockQuicConnectionHelper and
+  // MockAlarmFactory, tracked separately from the server and client state so
+  // their lifetimes persist through the whole test.
+  std::vector<std::unique_ptr<MockQuicConnectionHelper>> helpers_;
+  std::vector<std::unique_ptr<MockAlarmFactory>> alarm_factories_;
+
+  // Server state.
+  PacketSavingConnection* server_connection_;
+  std::unique_ptr<TestQuicSpdyServerSession> server_session_;
+  FakeProofSource* proof_source_;  // owned by server_crypto_config_
+  QuicCryptoServerConfig server_crypto_config_;
+  QuicCompressedCertsCache server_compressed_certs_cache_;
+  QuicServerId server_id_;
+
+  // Client state.
+  PacketSavingConnection* client_connection_;
+  QuicCryptoClientConfig client_crypto_config_;
+  std::unique_ptr<TestQuicSpdyClientSession> client_session_;
+
+  crypto_test_utils::FakeClientOptions client_options_;
+  // How many handshake messages have been moved from client to server and
+  // server to client.
+  std::pair<size_t, size_t> moved_messages_counts_ = {0, 0};
+
+  // Which QUIC versions the client and server support.
+  ParsedQuicVersionVector supported_versions_ = AllSupportedVersionsWithTls();
+};
+
+TEST_F(TlsServerHandshakerTest, NotInitiallyConected) {
+  EXPECT_FALSE(server_stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+}
+
+TEST_F(TlsServerHandshakerTest, ConnectedAfterTlsHandshake) {
+  CompleteCryptoHandshake();
+  EXPECT_EQ(PROTOCOL_TLS1_3, server_stream()->handshake_protocol());
+  ExpectHandshakeSuccessful();
+}
+
+TEST_F(TlsServerHandshakerTest, HandshakeWithAsyncProofSource) {
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
+  // Enable FakeProofSource to capture call to ComputeTlsSignature and run it
+  // asynchronously.
+  proof_source_->Activate();
+
+  // Start handshake.
+  AdvanceHandshakeWithFakeClient();
+
+  ASSERT_EQ(proof_source_->NumPendingCallbacks(), 1);
+  proof_source_->InvokePendingCallback(0);
+
+  CompleteCryptoHandshake();
+
+  ExpectHandshakeSuccessful();
+}
+
+TEST_F(TlsServerHandshakerTest, CancelPendingProofSource) {
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
+  // Enable FakeProofSource to capture call to ComputeTlsSignature and run it
+  // asynchronously.
+  proof_source_->Activate();
+
+  // Start handshake.
+  AdvanceHandshakeWithFakeClient();
+
+  ASSERT_EQ(proof_source_->NumPendingCallbacks(), 1);
+  server_session_ = nullptr;
+
+  proof_source_->InvokePendingCallback(0);
+}
+
+TEST_F(TlsServerHandshakerTest, ExtractSNI) {
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+
+  EXPECT_EQ(server_stream()->crypto_negotiated_params().sni,
+            "test.example.com");
+}
+
+TEST_F(TlsServerHandshakerTest, ConnectionClosedOnTlsError) {
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
+
+  // Send a zero-length ClientHello from client to server.
+  char bogus_handshake_message[] = {
+      // Handshake struct (RFC 8446 appendix B.3)
+      1,        // HandshakeType client_hello
+      0, 0, 0,  // uint24 length
+  };
+  server_stream()->crypto_message_parser()->ProcessInput(
+      quiche::QuicheStringPiece(bogus_handshake_message,
+                                QUICHE_ARRAYSIZE(bogus_handshake_message)),
+      ENCRYPTION_INITIAL);
+
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+}
+
+TEST_F(TlsServerHandshakerTest, ClientNotSendingALPN) {
+  static_cast<TlsClientHandshaker*>(
+      QuicCryptoClientStreamPeer::GetHandshaker(client_stream()))
+      ->AllowEmptyAlpnForTests();
+  EXPECT_CALL(*client_session_, GetAlpnsToOffer())
+      .WillOnce(Return(std::vector<std::string>()));
+  EXPECT_CALL(
+      *client_connection_,
+      CloseConnection(QUIC_HANDSHAKE_FAILED, "Server did not select ALPN", _));
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_HANDSHAKE_FAILED,
+                              "Server did not receive a known ALPN", _));
+
+  // Process two flights of handshake messages.
+  AdvanceHandshakeWithFakeClient();
+  AdvanceHandshakeWithFakeClient();
+
+  EXPECT_FALSE(client_stream()->one_rtt_keys_available());
+  EXPECT_EQ(GetQuicRestartFlag(quic_send_settings_on_write_key_available),
+            client_stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+  EXPECT_EQ(GetQuicRestartFlag(quic_send_settings_on_write_key_available),
+            server_stream()->encryption_established());
+}
+
+TEST_F(TlsServerHandshakerTest, ClientSendingBadALPN) {
+  const std::string kTestBadClientAlpn = "bad-client-alpn";
+  EXPECT_CALL(*client_session_, GetAlpnsToOffer())
+      .WillOnce(Return(std::vector<std::string>({kTestBadClientAlpn})));
+  EXPECT_CALL(
+      *client_connection_,
+      CloseConnection(QUIC_HANDSHAKE_FAILED, "Server did not select ALPN", _));
+  EXPECT_CALL(*server_connection_,
+              CloseConnection(QUIC_HANDSHAKE_FAILED,
+                              "Server did not receive a known ALPN", _));
+
+  // Process two flights of handshake messages.
+  AdvanceHandshakeWithFakeClient();
+  AdvanceHandshakeWithFakeClient();
+
+  EXPECT_FALSE(client_stream()->one_rtt_keys_available());
+  EXPECT_EQ(GetQuicRestartFlag(quic_send_settings_on_write_key_available),
+            client_stream()->encryption_established());
+  EXPECT_FALSE(server_stream()->one_rtt_keys_available());
+  EXPECT_EQ(GetQuicRestartFlag(quic_send_settings_on_write_key_available),
+            server_stream()->encryption_established());
+}
+
+TEST_F(TlsServerHandshakerTest, CustomALPNNegotiation) {
+  EXPECT_CALL(*client_connection_, CloseConnection(_, _, _)).Times(0);
+  EXPECT_CALL(*server_connection_, CloseConnection(_, _, _)).Times(0);
+
+  const std::string kTestAlpn = "A Custom ALPN Value";
+  const std::vector<std::string> kTestAlpns(
+      {"foo", "bar", kTestAlpn, "something else"});
+  EXPECT_CALL(*client_session_, GetAlpnsToOffer())
+      .WillRepeatedly(Return(kTestAlpns));
+  EXPECT_CALL(*server_session_, SelectAlpn(_))
+      .WillOnce([kTestAlpn, kTestAlpns](
+                    const std::vector<quiche::QuicheStringPiece>& alpns) {
+        EXPECT_THAT(alpns, testing::ElementsAreArray(kTestAlpns));
+        return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn);
+      });
+  EXPECT_CALL(*client_session_,
+              OnAlpnSelected(quiche::QuicheStringPiece(kTestAlpn)));
+  EXPECT_CALL(*server_session_,
+              OnAlpnSelected(quiche::QuicheStringPiece(kTestAlpn)));
+
+  CompleteCryptoHandshake();
+  ExpectHandshakeSuccessful();
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic
diff --git a/quic/test_tools/crypto_test_utils.cc b/quic/test_tools/crypto_test_utils.cc
index 1e3f14d..21561d9 100644
--- a/quic/test_tools/crypto_test_utils.cc
+++ b/quic/test_tools/crypto_test_utils.cc
@@ -756,6 +756,8 @@
       // packets should ever be encrypted with the NullEncrypter, instead
       // they're encrypted with an obfuscation cipher based on QUIC version and
       // connection ID.
+      QUIC_LOG(INFO) << "Attempting to decrypt with NullDecrypter: "
+                        "expect a decryption failure on the next log line.";
       ASSERT_FALSE(null_encryption_framer.ProcessPacket(
           *source_conn->encrypted_packets_[index]))
           << "No TLS packets should be encrypted with the NullEncrypter";
diff --git a/quic/test_tools/quic_test_utils.cc b/quic/test_tools/quic_test_utils.cc
index b534635..47fd05f 100644
--- a/quic/test_tools/quic_test_utils.cc
+++ b/quic/test_tools/quic_test_utils.cc
@@ -1091,6 +1091,12 @@
 MockSessionNotifier::MockSessionNotifier() {}
 MockSessionNotifier::~MockSessionNotifier() {}
 
+// static
+QuicCryptoClientStream::HandshakerInterface*
+QuicCryptoClientStreamPeer::GetHandshaker(QuicCryptoClientStream* stream) {
+  return stream->handshaker_.get();
+}
+
 void CreateClientSessionForTest(
     QuicServerId server_id,
     QuicTime::Delta connection_start_time,
diff --git a/quic/test_tools/quic_test_utils.h b/quic/test_tools/quic_test_utils.h
index fafe8d0..b8e0eae 100644
--- a/quic/test_tools/quic_test_utils.h
+++ b/quic/test_tools/quic_test_utils.h
@@ -858,6 +858,7 @@
   MOCK_CONST_METHOD1(SelectAlpn,
                      std::vector<quiche::QuicheStringPiece>::const_iterator(
                          const std::vector<quiche::QuicheStringPiece>&));
+  MOCK_METHOD(void, OnAlpnSelected, (quiche::QuicheStringPiece));
   std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
       const QuicCryptoServerConfig* crypto_config,
       QuicCompressedCertsCache* compressed_certs_cache) override;
@@ -924,6 +925,7 @@
   MOCK_METHOD0(ShouldCreateOutgoingBidirectionalStream, bool());
   MOCK_METHOD0(ShouldCreateOutgoingUnidirectionalStream, bool());
   MOCK_CONST_METHOD0(GetAlpnsToOffer, std::vector<std::string>());
+  MOCK_METHOD(void, OnAlpnSelected, (quiche::QuicheStringPiece));
 
   QuicCryptoClientStream* GetMutableCryptoStream() override;
   const QuicCryptoClientStream* GetCryptoStream() const override;
@@ -1190,6 +1192,14 @@
   MOCK_CONST_METHOD0(HasUnackedStreamData, bool());
 };
 
+class QuicCryptoClientStreamPeer {
+ public:
+  QuicCryptoClientStreamPeer() = delete;
+
+  static QuicCryptoClientStream::HandshakerInterface* GetHandshaker(
+      QuicCryptoClientStream* stream);
+};
+
 // Creates a client session for testing.
 //
 // server_id: The server id associated with this stream.