Delay delivering 1-RTT read key to QUIC

This change simulates the behavior pending in
https://boringssl-review.googlesource.com/c/boringssl/+/40127, so that when
BoringSSL is updated it will be a no-op.

gfe-relnote: Protected by reloadable flag quic_enable_version_draft_25_v2
PiperOrigin-RevId: 297650164
Change-Id: I6822ebbd3cb95abb5ef816a2629e5e4b6b61b630
diff --git a/quic/core/quic_version_manager.cc b/quic/core/quic_version_manager.cc
index b6a3c53..c5ccf62 100644
--- a/quic/core/quic_version_manager.cc
+++ b/quic/core/quic_version_manager.cc
@@ -17,7 +17,7 @@
     ParsedQuicVersionVector supported_versions)
     : enable_version_t099_(GetQuicReloadableFlag(quic_enable_version_t099)),
       enable_version_draft_25_(
-          GetQuicReloadableFlag(quic_enable_version_draft_25)),
+          GetQuicReloadableFlag(quic_enable_version_draft_25_v2)),
       disable_version_q050_(GetQuicReloadableFlag(quic_disable_version_q050)),
       enable_version_t050_(GetQuicReloadableFlag(quic_enable_version_t050)),
       disable_version_q049_(GetQuicReloadableFlag(quic_disable_version_q049)),
@@ -48,7 +48,7 @@
                 "Supported versions out of sync");
   if (enable_version_t099_ != GetQuicReloadableFlag(quic_enable_version_t099) ||
       enable_version_draft_25_ !=
-          GetQuicReloadableFlag(quic_enable_version_draft_25) ||
+          GetQuicReloadableFlag(quic_enable_version_draft_25_v2) ||
       disable_version_q050_ !=
           GetQuicReloadableFlag(quic_disable_version_q050) ||
       enable_version_t050_ != GetQuicReloadableFlag(quic_enable_version_t050) ||
@@ -62,7 +62,7 @@
           GetQuicReloadableFlag(quic_disable_version_q043)) {
     enable_version_t099_ = GetQuicReloadableFlag(quic_enable_version_t099);
     enable_version_draft_25_ =
-        GetQuicReloadableFlag(quic_enable_version_draft_25);
+        GetQuicReloadableFlag(quic_enable_version_draft_25_v2);
     disable_version_q050_ = GetQuicReloadableFlag(quic_disable_version_q050);
     enable_version_t050_ = GetQuicReloadableFlag(quic_enable_version_t050);
     disable_version_q049_ = GetQuicReloadableFlag(quic_disable_version_q049);
diff --git a/quic/core/quic_version_manager.h b/quic/core/quic_version_manager.h
index 19b4928..c434dae 100644
--- a/quic/core/quic_version_manager.h
+++ b/quic/core/quic_version_manager.h
@@ -43,7 +43,7 @@
   // Cached value of reloadable flags.
   // quic_enable_version_t099 flag
   bool enable_version_t099_;
-  // quic_enable_version_draft_25 flag
+  // quic_enable_version_draft_25_v2 flag
   bool enable_version_draft_25_;
   // quic_disable_version_q050 flag
   bool disable_version_q050_;
diff --git a/quic/core/quic_version_manager_test.cc b/quic/core/quic_version_manager_test.cc
index dd3c064..e64bc3a 100644
--- a/quic/core/quic_version_manager_test.cc
+++ b/quic/core/quic_version_manager_test.cc
@@ -19,7 +19,7 @@
   static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   SetQuicReloadableFlag(quic_enable_version_t099, false);
-  SetQuicReloadableFlag(quic_enable_version_draft_25, false);
+  SetQuicReloadableFlag(quic_enable_version_draft_25_v2, false);
   SetQuicReloadableFlag(quic_enable_version_t050, false);
   SetQuicReloadableFlag(quic_disable_version_q050, false);
   SetQuicReloadableFlag(quic_disable_version_q049, false);
@@ -52,7 +52,7 @@
   EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
             manager.GetSupportedVersions());
 
-  SetQuicReloadableFlag(quic_enable_version_draft_25, true);
+  SetQuicReloadableFlag(quic_enable_version_draft_25_v2, true);
   expected_parsed_versions.push_back(
       ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25));
   EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
diff --git a/quic/core/quic_versions.cc b/quic/core/quic_versions.cc
index cbfdcaa..e6efcc5 100644
--- a/quic/core/quic_versions.cc
+++ b/quic/core/quic_versions.cc
@@ -293,7 +293,7 @@
       }
     } else if (version.transport_version == QUIC_VERSION_IETF_DRAFT_25) {
       QUIC_BUG_IF(version.handshake_protocol != PROTOCOL_TLS1_3);
-      if (GetQuicReloadableFlag(quic_enable_version_draft_25)) {
+      if (GetQuicReloadableFlag(quic_enable_version_draft_25_v2)) {
         filtered_versions.push_back(version);
       }
     } else if (version.transport_version == QUIC_VERSION_50) {
@@ -548,7 +548,7 @@
     SetQuicReloadableFlag(quic_enable_version_t099, true);
   } else if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_25) {
     QUIC_BUG_IF(parsed_version.handshake_protocol != PROTOCOL_TLS1_3);
-    SetQuicReloadableFlag(quic_enable_version_draft_25, true);
+    SetQuicReloadableFlag(quic_enable_version_draft_25_v2, true);
   } else if (parsed_version.transport_version == QUIC_VERSION_50) {
     if (parsed_version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
       SetQuicReloadableFlag(quic_disable_version_q050, false);
diff --git a/quic/core/quic_versions_test.cc b/quic/core/quic_versions_test.cc
index 55c38bd..78f3f3b 100644
--- a/quic/core/quic_versions_test.cc
+++ b/quic/core/quic_versions_test.cc
@@ -270,7 +270,7 @@
   static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   SetQuicReloadableFlag(quic_enable_version_t099, true);
-  SetQuicReloadableFlag(quic_enable_version_draft_25, true);
+  SetQuicReloadableFlag(quic_enable_version_draft_25_v2, true);
   SetQuicReloadableFlag(quic_enable_version_t050, true);
   SetQuicReloadableFlag(quic_disable_version_q050, false);
   SetQuicReloadableFlag(quic_disable_version_q049, false);
@@ -305,7 +305,7 @@
   static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   SetQuicReloadableFlag(quic_enable_version_t099, false);
-  SetQuicReloadableFlag(quic_enable_version_draft_25, true);
+  SetQuicReloadableFlag(quic_enable_version_draft_25_v2, true);
   SetQuicReloadableFlag(quic_enable_version_t050, true);
   SetQuicReloadableFlag(quic_disable_version_q050, false);
   SetQuicReloadableFlag(quic_disable_version_q049, false);
@@ -337,7 +337,7 @@
   static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   SetQuicReloadableFlag(quic_enable_version_t099, false);
-  SetQuicReloadableFlag(quic_enable_version_draft_25, false);
+  SetQuicReloadableFlag(quic_enable_version_draft_25_v2, false);
   SetQuicReloadableFlag(quic_enable_version_t050, false);
   SetQuicReloadableFlag(quic_disable_version_q050, false);
   SetQuicReloadableFlag(quic_disable_version_q049, false);
@@ -458,9 +458,9 @@
 
   {
     QuicFlagSaver flag_saver;
-    SetQuicReloadableFlag(quic_enable_version_draft_25, false);
+    SetQuicReloadableFlag(quic_enable_version_draft_25_v2, false);
     QuicEnableVersion(parsed_version_draft_25);
-    EXPECT_TRUE(GetQuicReloadableFlag(quic_enable_version_draft_25));
+    EXPECT_TRUE(GetQuicReloadableFlag(quic_enable_version_draft_25_v2));
   }
 
   {
diff --git a/quic/core/tls_handshaker.cc b/quic/core/tls_handshaker.cc
index d8cf338..ac8bcee 100644
--- a/quic/core/tls_handshaker.cc
+++ b/quic/core/tls_handshaker.cc
@@ -56,9 +56,8 @@
       ssl(), TlsConnection::BoringEncryptionLevel(level));
 }
 
-const EVP_MD* TlsHandshaker::Prf() {
-  return EVP_get_digestbynid(
-      SSL_CIPHER_get_prf_nid(SSL_get_pending_cipher(ssl())));
+const EVP_MD* TlsHandshaker::Prf(const SSL_CIPHER* cipher) {
+  return EVP_get_digestbynid(SSL_CIPHER_get_prf_nid(cipher));
 }
 
 void TlsHandshaker::SetWriteSecret(EncryptionLevel level,
@@ -66,7 +65,7 @@
                                    const std::vector<uint8_t>& write_secret) {
   std::unique_ptr<QuicEncrypter> encrypter =
       QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
-  CryptoUtils::SetKeyAndIV(Prf(), write_secret, encrypter.get());
+  CryptoUtils::SetKeyAndIV(Prf(cipher), write_secret, encrypter.get());
   handshaker_delegate_->OnNewEncryptionKeyAvailable(level,
                                                     std::move(encrypter));
 }
@@ -76,7 +75,7 @@
                                   const std::vector<uint8_t>& read_secret) {
   std::unique_ptr<QuicDecrypter> decrypter =
       QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
-  CryptoUtils::SetKeyAndIV(Prf(), read_secret, decrypter.get());
+  CryptoUtils::SetKeyAndIV(Prf(cipher), read_secret, decrypter.get());
   return handshaker_delegate_->OnNewDecryptionKeyAvailable(
       level, std::move(decrypter),
       /*set_alternative_decrypter=*/false,
diff --git a/quic/core/tls_handshaker.h b/quic/core/tls_handshaker.h
index ab84e3b..3d5f1e2 100644
--- a/quic/core/tls_handshaker.h
+++ b/quic/core/tls_handshaker.h
@@ -60,7 +60,7 @@
                                const std::string& reason_phrase) = 0;
 
   // Returns the PRF used by the cipher suite negotiated in the TLS handshake.
-  const EVP_MD* Prf();
+  const EVP_MD* Prf(const SSL_CIPHER* cipher);
 
   virtual const TlsConnection* tls_connection() const = 0;
 
diff --git a/quic/core/tls_server_handshaker.cc b/quic/core/tls_server_handshaker.cc
index e5587cd..bb8a821 100644
--- a/quic/core/tls_server_handshaker.cc
+++ b/quic/core/tls_server_handshaker.cc
@@ -160,6 +160,19 @@
   return TlsHandshaker::BufferSizeLimitForLevel(level);
 }
 
+bool TlsServerHandshaker::SetReadSecret(
+    EncryptionLevel level,
+    const SSL_CIPHER* cipher,
+    const std::vector<uint8_t>& read_secret) {
+  if (level != ENCRYPTION_FORWARD_SECURE || one_rtt_keys_available_) {
+    return TlsHandshaker::SetReadSecret(level, cipher, read_secret);
+  }
+  // Delay setting read secret for ENCRYPTION_FORWARD_SECURE until handshake
+  // completes.
+  app_data_read_secret_ = read_secret;
+  return true;
+}
+
 void TlsServerHandshaker::AdvanceHandshake() {
   if (state_ == STATE_CONNECTION_CLOSED) {
     QUIC_LOG(INFO) << "TlsServerHandshaker received handshake message after "
@@ -287,6 +300,16 @@
   }
   crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
 
+  if (!app_data_read_secret_.empty()) {
+    if (!SetReadSecret(ENCRYPTION_FORWARD_SECURE, cipher,
+                       app_data_read_secret_)) {
+      QUIC_BUG << "Failed to set forward secure read key.";
+      CloseConnection(QUIC_HANDSHAKE_FAILED, "Failed to set app data read key");
+      return;
+    }
+    app_data_read_secret_.clear();
+  }
+
   handshaker_delegate()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
   handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE);
   handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE);
diff --git a/quic/core/tls_server_handshaker.h b/quic/core/tls_server_handshaker.h
index d377f4d..ff0d6b9 100644
--- a/quic/core/tls_server_handshaker.h
+++ b/quic/core/tls_server_handshaker.h
@@ -65,6 +65,13 @@
     return &tls_connection_;
   }
 
+  // Override of TlsHandshaker::SetReadSecret so that setting the read secret
+  // for ENCRYPTION_FORWARD_SECURE can be delayed until the handshake is
+  // complete.
+  bool SetReadSecret(EncryptionLevel level,
+                     const SSL_CIPHER* cipher,
+                     const std::vector<uint8_t>& read_secret) override;
+
   // Called when a new message is received on the crypto stream and is available
   // for the TLS stack to read.
   void AdvanceHandshake() override;
@@ -127,6 +134,11 @@
   std::string hostname_;
   std::string cert_verify_sig_;
 
+  // Used to hold the ENCRYPTION_FORWARD_SECURE read secret until the handshake
+  // is complete. This is temporary until
+  // https://bugs.chromium.org/p/boringssl/issues/detail?id=303 is resolved.
+  std::vector<uint8_t> app_data_read_secret_;
+
   bool encryption_established_ = false;
   bool one_rtt_keys_available_ = false;
   bool valid_alpn_received_ = false;
diff --git a/quic/quartc/quartc_multiplexer_test.cc b/quic/quartc/quartc_multiplexer_test.cc
index dcdef66..df05f7a 100644
--- a/quic/quartc/quartc_multiplexer_test.cc
+++ b/quic/quartc/quartc_multiplexer_test.cc
@@ -203,7 +203,7 @@
     // TODO(b/150224094): Re-enable TLS handshake.
     // TODO(b/150236522): Parametrize by QUIC version.
     SetQuicReloadableFlag(quic_enable_version_t099, false);
-    SetQuicReloadableFlag(quic_enable_version_draft_25, false);
+    SetQuicReloadableFlag(quic_enable_version_draft_25_v2, false);
     SetQuicReloadableFlag(quic_enable_version_t050, false);
   }
 
diff --git a/quic/quartc/quartc_session_test.cc b/quic/quartc/quartc_session_test.cc
index 0a01f81..10d3128 100644
--- a/quic/quartc/quartc_session_test.cc
+++ b/quic/quartc/quartc_session_test.cc
@@ -57,7 +57,7 @@
     // TODO(b/150224094): Re-enable TLS handshake.
     // TODO(b/150236522): Parametrize by QUIC version.
     SetQuicReloadableFlag(quic_enable_version_t099, false);
-    SetQuicReloadableFlag(quic_enable_version_draft_25, false);
+    SetQuicReloadableFlag(quic_enable_version_draft_25_v2, false);
     SetQuicReloadableFlag(quic_enable_version_t050, false);
 
     client_transport_ =
diff --git a/quic/quartc/test/quartc_bidi_test.cc b/quic/quartc/test/quartc_bidi_test.cc
index 836c276..1d11d99 100644
--- a/quic/quartc/test/quartc_bidi_test.cc
+++ b/quic/quartc/test/quartc_bidi_test.cc
@@ -29,7 +29,7 @@
     // TODO(b/150224094): Re-enable TLS handshake.
     // TODO(b/150236522): Parametrize by QUIC version.
     SetQuicReloadableFlag(quic_enable_version_t099, false);
-    SetQuicReloadableFlag(quic_enable_version_draft_25, false);
+    SetQuicReloadableFlag(quic_enable_version_draft_25_v2, false);
     SetQuicReloadableFlag(quic_enable_version_t050, false);
 
     uint64_t seed = QuicRandom::GetInstance()->RandUint64();
diff --git a/quic/quartc/test/quartc_peer_test.cc b/quic/quartc/test/quartc_peer_test.cc
index 563eb02..0f0d0a6 100644
--- a/quic/quartc/test/quartc_peer_test.cc
+++ b/quic/quartc/test/quartc_peer_test.cc
@@ -38,7 +38,7 @@
     // TODO(b/150224094): Re-enable TLS handshake.
     // TODO(b/150236522): Parametrize by QUIC version.
     SetQuicReloadableFlag(quic_enable_version_t099, false);
-    SetQuicReloadableFlag(quic_enable_version_draft_25, false);
+    SetQuicReloadableFlag(quic_enable_version_draft_25_v2, false);
     SetQuicReloadableFlag(quic_enable_version_t050, false);
 
     SetQuicReloadableFlag(quic_default_to_bbr, true);