Call ProofHandler::OnProofVerifyDetailsAvailable in TLS handshake in QUIC

gfe-relnote: Notify QuicCryptoClientStream::ProofHandler when VerifyCertChain completes, protected by quic_supports_tls_handshake
PiperOrigin-RevId: 272701332
Change-Id: Ie96d15a99421e43226feefb6e5889056868a1746
diff --git a/quic/core/quic_crypto_client_stream.cc b/quic/core/quic_crypto_client_stream.cc
index a05caee..097fc9b 100644
--- a/quic/core/quic_crypto_client_stream.cc
+++ b/quic/core/quic_crypto_client_stream.cc
@@ -44,7 +44,7 @@
     case PROTOCOL_TLS1_3:
       handshaker_ = std::make_unique<TlsClientHandshaker>(
           this, session, server_id, crypto_config->proof_verifier(),
-          crypto_config->ssl_ctx(), std::move(verify_context),
+          crypto_config->ssl_ctx(), std::move(verify_context), proof_handler,
           crypto_config->user_agent_id());
       break;
     case PROTOCOL_UNSUPPORTED:
diff --git a/quic/core/quic_crypto_client_stream_test.cc b/quic/core/quic_crypto_client_stream_test.cc
index 9969baf..5b49fad 100644
--- a/quic/core/quic_crypto_client_stream_test.cc
+++ b/quic/core/quic_crypto_client_stream_test.cc
@@ -95,10 +95,11 @@
 TEST_F(QuicCryptoClientStreamTest, ConnectedAfterTlsHandshake) {
   SetQuicReloadableFlag(quic_supports_tls_handshake, true);
   supported_versions_.clear();
-  for (QuicTransportVersion transport_version :
-       AllSupportedTransportVersions()) {
-    supported_versions_.push_back(
-        ParsedQuicVersion(PROTOCOL_TLS1_3, transport_version));
+  for (ParsedQuicVersion version : AllSupportedVersions()) {
+    if (version.handshake_protocol != PROTOCOL_TLS1_3) {
+      continue;
+    }
+    supported_versions_.push_back(version);
   }
   CreateConnection();
   CompleteCryptoHandshake();
@@ -107,6 +108,29 @@
   EXPECT_TRUE(stream()->handshake_confirmed());
 }
 
+TEST_F(QuicCryptoClientStreamTest,
+       ProofVerifyDetailsAvailableAfterTlsHandshake) {
+  SetQuicReloadableFlag(quic_supports_tls_handshake, true);
+  supported_versions_.clear();
+  for (ParsedQuicVersion version : AllSupportedVersions()) {
+    if (version.handshake_protocol != PROTOCOL_TLS1_3) {
+      continue;
+    }
+    supported_versions_.push_back(version);
+  }
+  CreateConnection();
+
+  EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_));
+  stream()->CryptoConnect();
+  QuicConfig config;
+  crypto_test_utils::HandshakeWithFakeServer(
+      &config, &server_helper_, &alarm_factory_, connection_, stream(),
+      AlpnForVersion(connection_->version()));
+  EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+  EXPECT_TRUE(stream()->encryption_established());
+  EXPECT_TRUE(stream()->handshake_confirmed());
+}
+
 TEST_F(QuicCryptoClientStreamTest, MessageAfterHandshake) {
   CompleteCryptoHandshake();
 
diff --git a/quic/core/tls_client_handshaker.cc b/quic/core/tls_client_handshaker.cc
index bb45602..88fea66 100644
--- a/quic/core/tls_client_handshaker.cc
+++ b/quic/core/tls_client_handshaker.cc
@@ -33,6 +33,8 @@
   parent_->verify_result_ = ok ? ssl_verify_ok : ssl_verify_invalid;
   parent_->state_ = STATE_HANDSHAKE_RUNNING;
   parent_->proof_verify_callback_ = nullptr;
+  parent_->proof_handler_->OnProofVerifyDetailsAvailable(
+      *parent_->verify_details_);
   parent_->AdvanceHandshake();
 }
 
@@ -47,11 +49,13 @@
     ProofVerifier* proof_verifier,
     SSL_CTX* ssl_ctx,
     std::unique_ptr<ProofVerifyContext> verify_context,
+    QuicCryptoClientStream::ProofHandler* proof_handler,
     const std::string& user_agent_id)
     : TlsHandshaker(stream, session, ssl_ctx),
       server_id_(server_id),
       proof_verifier_(proof_verifier),
       verify_context_(std::move(verify_context)),
+      proof_handler_(proof_handler),
       user_agent_id_(user_agent_id),
       crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
       tls_connection_(ssl_ctx, this) {}
@@ -366,6 +370,7 @@
       std::unique_ptr<ProofVerifierCallback>(proof_verify_callback));
   switch (verify_result) {
     case QUIC_SUCCESS:
+      proof_handler_->OnProofVerifyDetailsAvailable(*verify_details_);
       return ssl_verify_ok;
     case QUIC_PENDING:
       proof_verify_callback_ = proof_verify_callback;
diff --git a/quic/core/tls_client_handshaker.h b/quic/core/tls_client_handshaker.h
index f3e90ce..4672821 100644
--- a/quic/core/tls_client_handshaker.h
+++ b/quic/core/tls_client_handshaker.h
@@ -30,6 +30,7 @@
                       ProofVerifier* proof_verifier,
                       SSL_CTX* ssl_ctx,
                       std::unique_ptr<ProofVerifyContext> verify_context,
+                      QuicCryptoClientStream::ProofHandler* proof_handler,
                       const std::string& user_agent_id);
   TlsClientHandshaker(const TlsClientHandshaker&) = delete;
   TlsClientHandshaker& operator=(const TlsClientHandshaker&) = delete;
@@ -109,6 +110,10 @@
   // constructor.
   ProofVerifier* proof_verifier_;
   std::unique_ptr<ProofVerifyContext> verify_context_;
+  // Unowned pointer to the proof handler which has the
+  // OnProofVerifyDetailsAvailable callback to use for notifying the result of
+  // certificate verification.
+  QuicCryptoClientStream::ProofHandler* proof_handler_;
 
   std::string user_agent_id_;
 
diff --git a/quic/core/tls_handshaker_test.cc b/quic/core/tls_handshaker_test.cc
index 168dc55..1d34321 100644
--- a/quic/core/tls_handshaker_test.cc
+++ b/quic/core/tls_handshaker_test.cc
@@ -210,6 +210,15 @@
   std::vector<std::pair<std::string, EncryptionLevel>> pending_writes_;
 };
 
+class MockProofHandler : public QuicCryptoClientStream::ProofHandler {
+ public:
+  MockProofHandler() = default;
+  ~MockProofHandler() override {}
+
+  MOCK_METHOD1(OnProofValid, void(const QuicCryptoClientConfig::CachedState&));
+  MOCK_METHOD1(OnProofVerifyDetailsAvailable, void(const ProofVerifyDetails&));
+};
+
 class TestQuicCryptoClientStream : public TestQuicCryptoStream {
  public:
   explicit TestQuicCryptoClientStream(QuicSession* session)
@@ -223,12 +232,14 @@
             proof_verifier_.get(),
             ssl_ctx_.get(),
             crypto_test_utils::ProofVerifyContextForTesting(),
+            &proof_handler_,
             "quic-tester")) {}
 
   ~TestQuicCryptoClientStream() override = default;
 
   TlsHandshaker* handshaker() const override { return handshaker_.get(); }
   TlsClientHandshaker* client_handshaker() const { return handshaker_.get(); }
+  const MockProofHandler& proof_handler() { return proof_handler_; }
 
   bool CryptoConnect() { return handshaker_->CryptoConnect(); }
 
@@ -238,6 +249,7 @@
 
  private:
   std::unique_ptr<FakeProofVerifier> proof_verifier_;
+  MockProofHandler proof_handler_;
   bssl::UniquePtr<SSL_CTX> ssl_ctx_;
   std::unique_ptr<TlsClientHandshaker> handshaker_;
 };
@@ -341,6 +353,7 @@
               OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED));
   EXPECT_CALL(server_session_,
               OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED));
+  EXPECT_CALL(client_stream_->proof_handler(), OnProofVerifyDetailsAvailable);
   client_stream_->CryptoConnect();
   ExchangeHandshakeMessages(client_stream_, server_stream_);
 
@@ -401,6 +414,8 @@
   FakeProofVerifier* proof_verifier = client_stream_->GetFakeProofVerifier();
   proof_verifier->Activate();
 
+  EXPECT_CALL(client_stream_->proof_handler(), OnProofVerifyDetailsAvailable);
+
   // Start handshake.
   client_stream_->CryptoConnect();
   ExchangeHandshakeMessages(client_stream_, server_stream_);