Move cert verification from TlsClientHandshaker to TlsHandshaker Protected by not protected. PiperOrigin-RevId: 340749853 Change-Id: If973adbd9d4edbbf9b1d06654f9d4067adfca38f
diff --git a/quic/core/crypto/tls_client_connection.cc b/quic/core/crypto/tls_client_connection.cc index 7908847..0591571 100644 --- a/quic/core/crypto/tls_client_connection.cc +++ b/quic/core/crypto/tls_client_connection.cc
@@ -13,9 +13,9 @@ // static bssl::UniquePtr<SSL_CTX> TlsClientConnection::CreateSslCtx( bool enable_early_data) { - bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsConnection::CreateSslCtx(); + bssl::UniquePtr<SSL_CTX> ssl_ctx = + TlsConnection::CreateSslCtx(SSL_VERIFY_PEER); // Configure certificate verification. - SSL_CTX_set_custom_verify(ssl_ctx.get(), SSL_VERIFY_PEER, &VerifyCallback); int reverify_on_resume_enabled = 1; SSL_CTX_set_reverify_on_resume(ssl_ctx.get(), reverify_on_resume_enabled); @@ -29,14 +29,6 @@ } // static -enum ssl_verify_result_t TlsClientConnection::VerifyCallback( - SSL* ssl, - uint8_t* out_alert) { - return static_cast<TlsClientConnection*>(ConnectionFromSsl(ssl)) - ->delegate_->VerifyCert(out_alert); -} - -// static int TlsClientConnection::NewSessionCallback(SSL* ssl, SSL_SESSION* session) { static_cast<TlsClientConnection*>(ConnectionFromSsl(ssl)) ->delegate_->InsertSession(bssl::UniquePtr<SSL_SESSION>(session));
diff --git a/quic/core/crypto/tls_client_connection.h b/quic/core/crypto/tls_client_connection.h index a7ef209..6bea641 100644 --- a/quic/core/crypto/tls_client_connection.h +++ b/quic/core/crypto/tls_client_connection.h
@@ -20,12 +20,6 @@ virtual ~Delegate() {} protected: - // Verifies the peer's certificate chain. It may use - // SSL_get0_peer_certificates to get the cert chain. This method returns - // ssl_verify_ok if the cert is valid, ssl_verify_invalid if it is invalid, - // or ssl_verify_retry if verification is happening asynchronously. - virtual enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) = 0; - // Called when a NewSessionTicket is received from the server. virtual void InsertSession(bssl::UniquePtr<SSL_SESSION> session) = 0; @@ -42,10 +36,6 @@ static bssl::UniquePtr<SSL_CTX> CreateSslCtx(bool enable_early_data); private: - // Registered as the callback for SSL_CTX_set_custom_verify. The - // implementation is delegated to Delegate::VerifyCert. - static enum ssl_verify_result_t VerifyCallback(SSL* ssl, uint8_t* out_alert); - // Registered as the callback for SSL_CTX_sess_set_new_cb, which calls // Delegate::InsertSession. static int NewSessionCallback(SSL* ssl, SSL_SESSION* session);
diff --git a/quic/core/crypto/tls_connection.cc b/quic/core/crypto/tls_connection.cc index 427474c..be274e2 100644 --- a/quic/core/crypto/tls_connection.cc +++ b/quic/core/crypto/tls_connection.cc
@@ -93,12 +93,15 @@ this); } // static -bssl::UniquePtr<SSL_CTX> TlsConnection::CreateSslCtx() { +bssl::UniquePtr<SSL_CTX> TlsConnection::CreateSslCtx(int cert_verify_mode) { CRYPTO_library_init(); bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_with_buffers_method())); SSL_CTX_set_min_proto_version(ssl_ctx.get(), TLS1_3_VERSION); SSL_CTX_set_max_proto_version(ssl_ctx.get(), TLS1_3_VERSION); SSL_CTX_set_quic_method(ssl_ctx.get(), &kSslQuicMethod); + if (cert_verify_mode != SSL_VERIFY_NONE) { + SSL_CTX_set_custom_verify(ssl_ctx.get(), cert_verify_mode, &VerifyCallback); + } return ssl_ctx; } @@ -108,6 +111,12 @@ ssl, SslIndexSingleton::GetInstance()->ssl_ex_data_index_connection())); } +// static +enum ssl_verify_result_t TlsConnection::VerifyCallback(SSL* ssl, + uint8_t* out_alert) { + return ConnectionFromSsl(ssl)->delegate_->VerifyCert(out_alert); +} + const SSL_QUIC_METHOD TlsConnection::kSslQuicMethod{ TlsConnection::SetReadSecretCallback, TlsConnection::SetWriteSecretCallback, TlsConnection::WriteMessageCallback, TlsConnection::FlushFlightCallback,
diff --git a/quic/core/crypto/tls_connection.h b/quic/core/crypto/tls_connection.h index ef5ca58..037e4b0 100644 --- a/quic/core/crypto/tls_connection.h +++ b/quic/core/crypto/tls_connection.h
@@ -31,6 +31,16 @@ virtual ~Delegate() {} protected: + // Certificate management functions: + + // Verifies the peer's certificate chain. It may use + // SSL_get0_peer_certificates to get the cert chain. This method returns + // ssl_verify_ok if the cert is valid, ssl_verify_invalid if it is invalid, + // or ssl_verify_retry if verification is happening asynchronously. + virtual enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) = 0; + + // QUIC-TLS interface functions: + // SetWriteSecret provides the encryption secret used to encrypt messages at // encryption level |level|. The secret provided here is the one from the // TLS 1.3 key schedule (RFC 8446 section 7.1), in particular the handshake @@ -87,7 +97,12 @@ // Creates an SSL_CTX and configures it with the options that are appropriate // for both client and server. The caller is responsible for ownership of the // newly created struct. - static bssl::UniquePtr<SSL_CTX> CreateSslCtx(); + // + // The provided |cert_verify_mode| is passed in as the |mode| argument for + // |SSL_CTX_set_verify|. See + // https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#SSL_VERIFY_NONE + // for a description of possible values. + static bssl::UniquePtr<SSL_CTX> CreateSslCtx(int cert_verify_mode); // From a given SSL* |ssl|, returns a pointer to the TlsConnection that it // belongs to. This helper method allows the callbacks set in BoringSSL to be @@ -96,6 +111,10 @@ static TlsConnection* ConnectionFromSsl(const SSL* ssl); private: + // Registered as the callback for SSL_CTX_set_custom_verify. The + // implementation is delegated to Delegate::VerifyCert. + static enum ssl_verify_result_t VerifyCallback(SSL* ssl, uint8_t* out_alert); + // TlsConnection implements SSL_QUIC_METHOD, which provides the interface // between BoringSSL's TLS stack and a QUIC implementation. static const SSL_QUIC_METHOD kSslQuicMethod;
diff --git a/quic/core/crypto/tls_server_connection.cc b/quic/core/crypto/tls_server_connection.cc index 9619ee7..f47e5ad 100644 --- a/quic/core/crypto/tls_server_connection.cc +++ b/quic/core/crypto/tls_server_connection.cc
@@ -18,7 +18,8 @@ // static bssl::UniquePtr<SSL_CTX> TlsServerConnection::CreateSslCtx( ProofSource* proof_source) { - bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsConnection::CreateSslCtx(); + bssl::UniquePtr<SSL_CTX> ssl_ctx = + TlsConnection::CreateSslCtx(SSL_VERIFY_NONE); SSL_CTX_set_tlsext_servername_callback(ssl_ctx.get(), &SelectCertificateCallback); SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), &SelectAlpnCallback, nullptr);
diff --git a/quic/core/tls_client_handshaker.cc b/quic/core/tls_client_handshaker.cc index 16864bf..fc69ad6 100644 --- a/quic/core/tls_client_handshaker.cc +++ b/quic/core/tls_client_handshaker.cc
@@ -20,35 +20,6 @@ namespace quic { -TlsClientHandshaker::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl( - TlsClientHandshaker* parent) - : parent_(parent) {} - -TlsClientHandshaker::ProofVerifierCallbackImpl::~ProofVerifierCallbackImpl() {} - -void TlsClientHandshaker::ProofVerifierCallbackImpl::Run( - bool ok, - const std::string& /*error_details*/, - std::unique_ptr<ProofVerifyDetails>* details) { - if (parent_ == nullptr) { - return; - } - - parent_->verify_details_ = std::move(*details); - parent_->verify_result_ = ok ? ssl_verify_ok : ssl_verify_invalid; - parent_->set_expected_ssl_error(SSL_ERROR_WANT_READ); - parent_->proof_verify_callback_ = nullptr; - if (parent_->verify_details_) { - parent_->proof_handler_->OnProofVerifyDetailsAvailable( - *parent_->verify_details_); - } - parent_->AdvanceHandshake(); -} - -void TlsClientHandshaker::ProofVerifierCallbackImpl::Cancel() { - parent_ = nullptr; -} - TlsClientHandshaker::TlsClientHandshaker( const QuicServerId& server_id, QuicCryptoStream* stream, @@ -70,11 +41,7 @@ has_application_state_(has_application_state), tls_connection_(crypto_config->ssl_ctx(), this) {} -TlsClientHandshaker::~TlsClientHandshaker() { - if (proof_verify_callback_) { - proof_verify_callback_->Cancel(); - } -} +TlsClientHandshaker::~TlsClientHandshaker() {} bool TlsClientHandshaker::CryptoConnect() { if (!pre_shared_key_.empty()) { @@ -405,6 +372,32 @@ handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE); } +QuicAsyncStatus TlsClientHandshaker::VerifyCertChain( + const std::vector<std::string>& certs, + std::string* error_details, + std::unique_ptr<ProofVerifyDetails>* details, + std::unique_ptr<ProofVerifierCallback> callback) { + const uint8_t* ocsp_response_raw; + size_t ocsp_response_len; + SSL_get0_ocsp_response(ssl(), &ocsp_response_raw, &ocsp_response_len); + std::string ocsp_response(reinterpret_cast<const char*>(ocsp_response_raw), + ocsp_response_len); + const uint8_t* sct_list_raw; + size_t sct_list_len; + SSL_get0_signed_cert_timestamp_list(ssl(), &sct_list_raw, &sct_list_len); + std::string sct_list(reinterpret_cast<const char*>(sct_list_raw), + sct_list_len); + + return proof_verifier_->VerifyCertChain( + server_id_.host(), server_id_.port(), certs, ocsp_response, sct_list, + verify_context_.get(), error_details, details, std::move(callback)); +} + +void TlsClientHandshaker::OnProofVerifyDetailsAvailable( + const ProofVerifyDetails& verify_details) { + proof_handler_->OnProofVerifyDetailsAvailable(verify_details); +} + void TlsClientHandshaker::FinishHandshake() { // Fill crypto_negotiated_params_: const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl()); @@ -493,61 +486,6 @@ AdvanceHandshake(); } -enum ssl_verify_result_t TlsClientHandshaker::VerifyCert(uint8_t* out_alert) { - if (verify_result_ != ssl_verify_retry || - expected_ssl_error() == SSL_ERROR_WANT_CERTIFICATE_VERIFY) { - enum ssl_verify_result_t result = verify_result_; - verify_result_ = ssl_verify_retry; - return result; - } - const STACK_OF(CRYPTO_BUFFER)* cert_chain = SSL_get0_peer_certificates(ssl()); - if (cert_chain == nullptr) { - *out_alert = SSL_AD_INTERNAL_ERROR; - return ssl_verify_invalid; - } - // TODO(nharper): Pass the CRYPTO_BUFFERs into the QUIC stack to avoid copies. - std::vector<std::string> certs; - for (CRYPTO_BUFFER* cert : cert_chain) { - certs.push_back( - std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert)), - CRYPTO_BUFFER_len(cert))); - } - const uint8_t* ocsp_response_raw; - size_t ocsp_response_len; - SSL_get0_ocsp_response(ssl(), &ocsp_response_raw, &ocsp_response_len); - std::string ocsp_response(reinterpret_cast<const char*>(ocsp_response_raw), - ocsp_response_len); - const uint8_t* sct_list_raw; - size_t sct_list_len; - SSL_get0_signed_cert_timestamp_list(ssl(), &sct_list_raw, &sct_list_len); - std::string sct_list(reinterpret_cast<const char*>(sct_list_raw), - sct_list_len); - - ProofVerifierCallbackImpl* proof_verify_callback = - new ProofVerifierCallbackImpl(this); - - QuicAsyncStatus verify_result = proof_verifier_->VerifyCertChain( - server_id_.host(), server_id_.port(), certs, ocsp_response, sct_list, - verify_context_.get(), &cert_verify_error_details_, &verify_details_, - std::unique_ptr<ProofVerifierCallback>(proof_verify_callback)); - switch (verify_result) { - case QUIC_SUCCESS: - if (verify_details_) { - proof_handler_->OnProofVerifyDetailsAvailable(*verify_details_); - } - return ssl_verify_ok; - case QUIC_PENDING: - proof_verify_callback_ = proof_verify_callback; - set_expected_ssl_error(SSL_ERROR_WANT_CERTIFICATE_VERIFY); - return ssl_verify_retry; - case QUIC_FAILURE: - default: - QUIC_LOG(INFO) << "Cert chain verification failed: " - << cert_verify_error_details_; - return ssl_verify_invalid; - } -} - void TlsClientHandshaker::InsertSession(bssl::UniquePtr<SSL_SESSION> session) { if (!received_transport_params_) { QUIC_BUG << "Transport parameters isn't received";
diff --git a/quic/core/tls_client_handshaker.h b/quic/core/tls_client_handshaker.h index 2f16620..c2707c7 100644 --- a/quic/core/tls_client_handshaker.h +++ b/quic/core/tls_client_handshaker.h
@@ -11,7 +11,6 @@ #include "absl/strings/string_view.h" #include "third_party/boringssl/src/include/openssl/ssl.h" -#include "net/third_party/quiche/src/quic/core/crypto/proof_verifier.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h" #include "net/third_party/quiche/src/quic/core/crypto/tls_client_connection.h" #include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h" @@ -89,32 +88,18 @@ void FinishHandshake() override; void ProcessPostHandshakeMessage() override; bool ShouldCloseConnectionOnUnexpectedError(int ssl_error) override; + QuicAsyncStatus VerifyCertChain( + const std::vector<std::string>& certs, + std::string* error_details, + std::unique_ptr<ProofVerifyDetails>* details, + std::unique_ptr<ProofVerifierCallback> callback) override; + void OnProofVerifyDetailsAvailable( + const ProofVerifyDetails& verify_details) override; // TlsClientConnection::Delegate implementation: - enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) override; TlsConnection::Delegate* ConnectionDelegate() override { return this; } private: - // ProofVerifierCallbackImpl handles the result of an asynchronous certificate - // verification operation. - class QUIC_EXPORT_PRIVATE ProofVerifierCallbackImpl - : public ProofVerifierCallback { - public: - explicit ProofVerifierCallbackImpl(TlsClientHandshaker* parent); - ~ProofVerifierCallbackImpl() override; - - // ProofVerifierCallback interface. - void Run(bool ok, - const std::string& error_details, - std::unique_ptr<ProofVerifyDetails>* details) override; - - // If called, Cancel causes the pending callback to be a no-op. - void Cancel(); - - private: - TlsClientHandshaker* parent_; - }; - bool SetAlpn(); bool SetTransportParameters(); bool ProcessTransportParameters(std::string* error_details); @@ -134,10 +119,10 @@ QuicServerId server_id_; // Objects used for verifying the server's certificate chain. - // |proof_verifier_| is owned by the caller of TlsClientHandshaker's - // constructor. + // |proof_verifier_| is owned by the caller of TlsHandshaker's 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. @@ -152,13 +137,6 @@ // Pre-shared key used during the handshake. std::string pre_shared_key_; - // ProofVerifierCallback used for async certificate verification. This object - // is owned by |proof_verifier_|. - ProofVerifierCallbackImpl* proof_verify_callback_ = nullptr; - std::unique_ptr<ProofVerifyDetails> verify_details_; - enum ssl_verify_result_t verify_result_ = ssl_verify_retry; - std::string cert_verify_error_details_; - HandshakeState state_ = HANDSHAKE_START; bool encryption_established_ = false; bool initial_keys_dropped_ = false;
diff --git a/quic/core/tls_handshaker.cc b/quic/core/tls_handshaker.cc index 6c45f84..1f20f32 100644 --- a/quic/core/tls_handshaker.cc +++ b/quic/core/tls_handshaker.cc
@@ -15,10 +15,42 @@ namespace quic { +TlsHandshaker::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl( + TlsHandshaker* parent) + : parent_(parent) {} + +TlsHandshaker::ProofVerifierCallbackImpl::~ProofVerifierCallbackImpl() {} + +void TlsHandshaker::ProofVerifierCallbackImpl::Run( + bool ok, + const std::string& /*error_details*/, + std::unique_ptr<ProofVerifyDetails>* details) { + if (parent_ == nullptr) { + return; + } + + parent_->verify_details_ = std::move(*details); + parent_->verify_result_ = ok ? ssl_verify_ok : ssl_verify_invalid; + parent_->set_expected_ssl_error(SSL_ERROR_WANT_READ); + parent_->proof_verify_callback_ = nullptr; + if (parent_->verify_details_) { + parent_->OnProofVerifyDetailsAvailable(*parent_->verify_details_); + } + parent_->AdvanceHandshake(); +} + +void TlsHandshaker::ProofVerifierCallbackImpl::Cancel() { + parent_ = nullptr; +} + TlsHandshaker::TlsHandshaker(QuicCryptoStream* stream, QuicSession* session) : stream_(stream), handshaker_delegate_(session) {} -TlsHandshaker::~TlsHandshaker() {} +TlsHandshaker::~TlsHandshaker() { + if (proof_verify_callback_) { + proof_verify_callback_->Cancel(); + } +} bool TlsHandshaker::ProcessInput(absl::string_view input, EncryptionLevel level) { @@ -109,6 +141,50 @@ return EVP_get_digestbynid(SSL_CIPHER_get_prf_nid(cipher)); } +enum ssl_verify_result_t TlsHandshaker::VerifyCert(uint8_t* out_alert) { + if (verify_result_ != ssl_verify_retry || + expected_ssl_error() == SSL_ERROR_WANT_CERTIFICATE_VERIFY) { + enum ssl_verify_result_t result = verify_result_; + verify_result_ = ssl_verify_retry; + return result; + } + const STACK_OF(CRYPTO_BUFFER)* cert_chain = SSL_get0_peer_certificates(ssl()); + if (cert_chain == nullptr) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return ssl_verify_invalid; + } + // TODO(nharper): Pass the CRYPTO_BUFFERs into the QUIC stack to avoid copies. + std::vector<std::string> certs; + for (CRYPTO_BUFFER* cert : cert_chain) { + certs.push_back( + std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert)), + CRYPTO_BUFFER_len(cert))); + } + + ProofVerifierCallbackImpl* proof_verify_callback = + new ProofVerifierCallbackImpl(this); + + QuicAsyncStatus verify_result = VerifyCertChain( + certs, &cert_verify_error_details_, &verify_details_, + std::unique_ptr<ProofVerifierCallback>(proof_verify_callback)); + switch (verify_result) { + case QUIC_SUCCESS: + if (verify_details_) { + OnProofVerifyDetailsAvailable(*verify_details_); + } + return ssl_verify_ok; + case QUIC_PENDING: + proof_verify_callback_ = proof_verify_callback; + set_expected_ssl_error(SSL_ERROR_WANT_CERTIFICATE_VERIFY); + return ssl_verify_retry; + case QUIC_FAILURE: + default: + QUIC_LOG(INFO) << "Cert chain verification failed: " + << cert_verify_error_details_; + return ssl_verify_invalid; + } +} + void TlsHandshaker::SetWriteSecret(EncryptionLevel level, const SSL_CIPHER* cipher, const std::vector<uint8_t>& write_secret) {
diff --git a/quic/core/tls_handshaker.h b/quic/core/tls_handshaker.h index 9288592..657c9c7 100644 --- a/quic/core/tls_handshaker.h +++ b/quic/core/tls_handshaker.h
@@ -10,6 +10,7 @@ #include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" #include "net/third_party/quiche/src/quic/core/crypto/crypto_message_parser.h" +#include "net/third_party/quiche/src/quic/core/crypto/proof_verifier.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h" #include "net/third_party/quiche/src/quic/core/crypto/tls_connection.h" @@ -83,6 +84,21 @@ } int expected_ssl_error() const { return expected_ssl_error_; } + // Called to verify a cert chain. This is a simple wrapper around + // ProofVerifier or ServerProofVerifier, which optionally gathers additional + // arguments to pass into their VerifyCertChain method. This class retains a + // non-owning pointer to |callback|; the callback must live until this + // function returns QUIC_SUCCESS or QUIC_FAILURE, or until the callback is + // run. + virtual QuicAsyncStatus VerifyCertChain( + const std::vector<std::string>& certs, + std::string* error_details, + std::unique_ptr<ProofVerifyDetails>* details, + std::unique_ptr<ProofVerifierCallback> callback) = 0; + // Called when certificate verification is completed. + virtual void OnProofVerifyDetailsAvailable( + const ProofVerifyDetails& verify_details) = 0; + // Returns the PRF used by the cipher suite negotiated in the TLS handshake. const EVP_MD* Prf(const SSL_CIPHER* cipher); @@ -95,6 +111,8 @@ return handshaker_delegate_; } + enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) override; + // SetWriteSecret provides the encryption secret used to encrypt messages at // encryption level |level|. The secret provided here is the one from the TLS // 1.3 key schedule (RFC 8446 section 7.1), in particular the handshake @@ -127,6 +145,36 @@ void SendAlert(EncryptionLevel level, uint8_t desc) override; private: + // ProofVerifierCallbackImpl handles the result of an asynchronous certificate + // verification operation. + class QUIC_EXPORT_PRIVATE ProofVerifierCallbackImpl + : public ProofVerifierCallback { + public: + explicit ProofVerifierCallbackImpl(TlsHandshaker* parent); + ~ProofVerifierCallbackImpl() override; + + // ProofVerifierCallback interface. + void Run(bool ok, + const std::string& error_details, + std::unique_ptr<ProofVerifyDetails>* details) override; + + // If called, Cancel causes the pending callback to be a no-op. + void Cancel(); + + private: + // Non-owning pointer to the TlsHandshaker responsible for this callback. + // |parent_| must be valid for the life of this callback or until |Cancel| + // is called. + TlsHandshaker* parent_; + }; + + // ProofVerifierCallback used for async certificate verification. Ownership of + // this object is transferred to |VerifyCertChain|; + ProofVerifierCallbackImpl* proof_verify_callback_ = nullptr; + std::unique_ptr<ProofVerifyDetails> verify_details_; + enum ssl_verify_result_t verify_result_ = ssl_verify_retry; + std::string cert_verify_error_details_; + int expected_ssl_error_ = SSL_ERROR_WANT_READ; bool is_connection_closed_ = false;
diff --git a/quic/core/tls_server_handshaker.cc b/quic/core/tls_server_handshaker.cc index c14deb0..a935741 100644 --- a/quic/core/tls_server_handshaker.cc +++ b/quic/core/tls_server_handshaker.cc
@@ -389,6 +389,18 @@ handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_ZERO_RTT); } +QuicAsyncStatus TlsServerHandshaker::VerifyCertChain( + const std::vector<std::string>& /*certs*/, + std::string* /*error_details*/, + std::unique_ptr<ProofVerifyDetails>* /*details*/, + std::unique_ptr<ProofVerifierCallback> /*callback*/) { + QUIC_BUG << "Client certificates are not yet supported on the server"; + return QUIC_FAILURE; +} + +void TlsServerHandshaker::OnProofVerifyDetailsAvailable( + const ProofVerifyDetails& /*verify_details*/) {} + ssl_private_key_result_t TlsServerHandshaker::PrivateKeySign( uint8_t* out, size_t* out_len,
diff --git a/quic/core/tls_server_handshaker.h b/quic/core/tls_server_handshaker.h index 41870f9..2fba611 100644 --- a/quic/core/tls_server_handshaker.h +++ b/quic/core/tls_server_handshaker.h
@@ -93,6 +93,13 @@ // TlsHandshaker implementation: void FinishHandshake() override; void ProcessPostHandshakeMessage() override {} + QuicAsyncStatus VerifyCertChain( + const std::vector<std::string>& certs, + std::string* error_details, + std::unique_ptr<ProofVerifyDetails>* details, + std::unique_ptr<ProofVerifierCallback> callback) override; + void OnProofVerifyDetailsAvailable( + const ProofVerifyDetails& verify_details) override; // TlsServerConnection::Delegate implementation: int SelectCertificate(int* out_alert) override;