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;