In QUIC, when TLS 0-rtt is rejected, disable early data in all cached session tickets that are associated with that server.

Protected by disabled flag quic_enable_zero_rtt_for_tls.

Merge instructions: Please leave the implementation for the new API empty. I will fix that.

PiperOrigin-RevId: 312771280
Change-Id: Ib96b050d088ce1629c67c4f443e89d224d4432d2
diff --git a/quic/core/crypto/quic_crypto_client_config.h b/quic/core/crypto/quic_crypto_client_config.h
index 9a87556..6f057c2 100644
--- a/quic/core/crypto/quic_crypto_client_config.h
+++ b/quic/core/crypto/quic_crypto_client_config.h
@@ -76,6 +76,10 @@
   virtual std::unique_ptr<QuicResumptionState> Lookup(
       const QuicServerId& server_id,
       const SSL_CTX* ctx) = 0;
+
+  // Called when 0-RTT is rejected. Disables early data for all the TLS tickets
+  // associated with |server_id|.
+  virtual void ClearEarlyData(const QuicServerId& server_id) = 0;
 };
 
 // QuicCryptoClientConfig contains crypto-related configuration settings for a
diff --git a/quic/core/tls_client_handshaker.cc b/quic/core/tls_client_handshaker.cc
index b3cfc0a..4c4dbab 100644
--- a/quic/core/tls_client_handshaker.cc
+++ b/quic/core/tls_client_handshaker.cc
@@ -520,8 +520,10 @@
 
 void TlsClientHandshaker::HandleZeroRttReject() {
   QUIC_LOG(INFO) << "0-RTT handshake attempted but was rejected by the server";
+  DCHECK(session_cache_);
   handshaker_delegate()->OnZeroRttRejected();
   SSL_reset_early_data_reject(ssl());
+  session_cache_->ClearEarlyData(server_id_);
   AdvanceHandshake();
 }
 
diff --git a/quic/test_tools/simple_session_cache.cc b/quic/test_tools/simple_session_cache.cc
index 6a0cafb..94b8764 100644
--- a/quic/test_tools/simple_session_cache.cc
+++ b/quic/test_tools/simple_session_cache.cc
@@ -34,6 +34,12 @@
   if (it == cache_entries_.end()) {
     return nullptr;
   }
+
+  if (!it->second.session) {
+    cache_entries_.erase(it);
+    return nullptr;
+  }
+
   auto state = std::make_unique<QuicResumptionState>();
   state->tls_session = std::move(it->second.session);
   state->application_state = it->second.application_state.get();
@@ -41,5 +47,10 @@
   return state;
 }
 
+void SimpleSessionCache::ClearEarlyData(const QuicServerId& /*server_id*/) {
+  // The simple session cache only stores 1 SSL ticket per entry, so no need to
+  // do anything here.
+}
+
 }  // namespace test
 }  // namespace quic
diff --git a/quic/test_tools/simple_session_cache.h b/quic/test_tools/simple_session_cache.h
index cfe3f4a..6043a43 100644
--- a/quic/test_tools/simple_session_cache.h
+++ b/quic/test_tools/simple_session_cache.h
@@ -28,6 +28,7 @@
               const ApplicationState* application_state) override;
   std::unique_ptr<QuicResumptionState> Lookup(const QuicServerId& server_id,
                                               const SSL_CTX* ctx) override;
+  void ClearEarlyData(const QuicServerId& server_id) override;
 
  private:
   struct Entry {