Add support for accepting 0-RTT in TlsServerHandshaker

This adds support at the crypto handshake layer for supporting 0-RTT TLS
handshakes on the server. Part of this support includes receiving a signal
from the application layer, via a new method
QuicCryptoStream::SetServerApplicationStateForResumption. This method
replaces the previously client-only
QuicCryptoClientStream::OnApplicationState.

Introduce quic 0-rtt tls support, protected by quic_enable_zero_rtt_for_tls

PiperOrigin-RevId: 315331343
Change-Id: Ife83cf526be38bd4f5c8a3de0e6cd4c40be6f7ae
diff --git a/quic/core/tls_server_handshaker.cc b/quic/core/tls_server_handshaker.cc
index 60aa64f..057e86d 100644
--- a/quic/core/tls_server_handshaker.cc
+++ b/quic/core/tls_server_handshaker.cc
@@ -15,6 +15,7 @@
 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.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"
+#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
 
 namespace quic {
 
@@ -95,15 +96,6 @@
 
   // Configure the SSL to be a server.
   SSL_set_accept_state(ssl());
-
-  if (GetQuicReloadableFlag(quic_enable_zero_rtt_for_tls)) {
-    // TODO(b/152551499): Properly set early data context. This change is to
-    // temporarily unblock QuicSpdyClientSessionTest.IetfZeroRttSetup which
-    // assumes that the server will sent an early data capable ticket, and then
-    // accept early data on resumption.
-    uint8_t context[] = {0};
-    SSL_set_quic_early_data_context(ssl(), context, QUICHE_ARRAYSIZE(context));
-  }
 }
 
 TlsServerHandshaker::~TlsServerHandshaker() {
@@ -133,8 +125,7 @@
 }
 
 bool TlsServerHandshaker::IsZeroRtt() const {
-  // TODO(nharper): Support 0-RTT with TLS 1.3 in QUIC.
-  return false;
+  return SSL_early_data_accepted(ssl());
 }
 
 bool TlsServerHandshaker::IsResumption() const {
@@ -207,6 +198,11 @@
   return HANDSHAKE_START;
 }
 
+void TlsServerHandshaker::SetServerApplicationStateForResumption(
+    std::unique_ptr<ApplicationState> state) {
+  application_state_ = std::move(state);
+}
+
 size_t TlsServerHandshaker::BufferSizeLimitForLevel(
     EncryptionLevel level) const {
   return TlsHandshaker::BufferSizeLimitForLevel(level);
@@ -329,6 +325,17 @@
                                     server_params_bytes.size()) != 1) {
     return false;
   }
+  if (application_state_) {
+    std::vector<uint8_t> early_data_context;
+    if (!SerializeTransportParametersForTicket(
+            server_params, *application_state_, &early_data_context)) {
+      QUIC_BUG << "Failed to serialize Transport Parameters for ticket.";
+      return false;
+    }
+    SSL_set_quic_early_data_context(ssl(), early_data_context.data(),
+                                    early_data_context.size());
+    application_state_.reset(nullptr);
+  }
   return true;
 }