summaryrefslogtreecommitdiff
path: root/chromium/net/cert/multi_threaded_cert_verifier.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/cert/multi_threaded_cert_verifier.cc')
-rw-r--r--chromium/net/cert/multi_threaded_cert_verifier.cc71
1 files changed, 55 insertions, 16 deletions
diff --git a/chromium/net/cert/multi_threaded_cert_verifier.cc b/chromium/net/cert/multi_threaded_cert_verifier.cc
index 91b1c5948a4..8b0ff51d732 100644
--- a/chromium/net/cert/multi_threaded_cert_verifier.cc
+++ b/chromium/net/cert/multi_threaded_cert_verifier.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/check_op.h"
#include "base/memory/weak_ptr.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
@@ -33,8 +34,8 @@ class MultiThreadedCertVerifierScopedAllowBaseSyncPrimitives
namespace {
-// Used to pass the result of CertVerifierJob::DoVerifyOnWorkerThread() to
-// CertVerifierJob::OnJobCompleted().
+// Used to pass the result of DoVerifyOnWorkerThread() to
+// MultiThreadedCertVerifier::InternalRequest::OnJobComplete().
struct ResultHelper {
int error;
CertVerifyResult result;
@@ -56,8 +57,7 @@ int GetFlagsForConfig(const CertVerifier::Config& config) {
return flags;
}
-// DoVerifyOnWorkerThread runs the verification synchronously on a worker
-// thread.
+// Runs the verification synchronously on a worker thread.
std::unique_ptr<ResultHelper> DoVerifyOnWorkerThread(
const scoped_refptr<CertVerifyProc>& verify_proc,
const scoped_refptr<X509Certificate>& cert,
@@ -83,11 +83,15 @@ std::unique_ptr<ResultHelper> DoVerifyOnWorkerThread(
return verify_result;
}
+} // namespace
+
// Helper to allow callers to cancel pending CertVerifier::Verify requests.
// Note that because the CertVerifyProc is blocking, it's not actually
// possible to cancel the in-progress request; instead, this simply guarantees
// that the provided callback will not be invoked if the Request is deleted.
-class InternalRequest : public CertVerifier::Request {
+class MultiThreadedCertVerifier::InternalRequest
+ : public CertVerifier::Request,
+ public base::LinkNode<InternalRequest> {
public:
InternalRequest(CompletionOnceCallback callback,
CertVerifyResult* caller_result);
@@ -98,6 +102,8 @@ class InternalRequest : public CertVerifier::Request {
const CertVerifier::RequestParams& params,
const NetLogWithSource& caller_net_log);
+ void ResetCallback() { callback_.Reset(); }
+
private:
// This is a static method with a |self| weak pointer instead of a regular
// method, so that PostTask will still run it even if the weakptr is no
@@ -111,16 +117,25 @@ class InternalRequest : public CertVerifier::Request {
base::WeakPtrFactory<InternalRequest> weak_factory_{this};
};
-InternalRequest::InternalRequest(CompletionOnceCallback callback,
- CertVerifyResult* caller_result)
+MultiThreadedCertVerifier::InternalRequest::InternalRequest(
+ CompletionOnceCallback callback,
+ CertVerifyResult* caller_result)
: callback_(std::move(callback)), caller_result_(caller_result) {}
-InternalRequest::~InternalRequest() = default;
+MultiThreadedCertVerifier::InternalRequest::~InternalRequest() {
+ if (callback_) {
+ // This InternalRequest was eagerly cancelled as the callback is still
+ // valid, so |this| needs to be removed from MultiThreadedCertVerifier's
+ // list.
+ RemoveFromList();
+ }
+}
-void InternalRequest::Start(const scoped_refptr<CertVerifyProc>& verify_proc,
- const CertVerifier::Config& config,
- const CertVerifier::RequestParams& params,
- const NetLogWithSource& caller_net_log) {
+void MultiThreadedCertVerifier::InternalRequest::Start(
+ const scoped_refptr<CertVerifyProc>& verify_proc,
+ const CertVerifier::Config& config,
+ const CertVerifier::RequestParams& params,
+ const NetLogWithSource& caller_net_log) {
const NetLogWithSource net_log(NetLogWithSource::Make(
caller_net_log.net_log(), NetLogSourceType::CERT_VERIFIER_TASK));
net_log.BeginEvent(NetLogEventType::CERT_VERIFIER_TASK);
@@ -140,12 +155,12 @@ void InternalRequest::Start(const scoped_refptr<CertVerifyProc>& verify_proc,
params.hostname(), params.ocsp_response(),
params.sct_list(), flags, config.crl_set,
config.additional_trust_anchors, net_log),
- base::BindOnce(&InternalRequest::OnJobComplete,
+ base::BindOnce(&MultiThreadedCertVerifier::InternalRequest::OnJobComplete,
weak_factory_.GetWeakPtr()));
}
// static
-void InternalRequest::OnJobComplete(
+void MultiThreadedCertVerifier::InternalRequest::OnJobComplete(
base::WeakPtr<InternalRequest> self,
std::unique_ptr<ResultHelper> verify_result) {
// Always log the EndEvent, even if the Request has been destroyed.
@@ -155,13 +170,23 @@ void InternalRequest::OnJobComplete(
if (!self)
return;
+ DCHECK(verify_result);
+
+ // If the MultiThreadedCertVerifier has been deleted, the callback will have
+ // been reset to null.
+ if (!self->callback_)
+ return;
+
+ // If ~MultiThreadedCertVerifier has not Reset() our callback, then this
+ // InternalRequest will not have been removed from MultiThreadedCertVerifier's
+ // list yet.
+ self->RemoveFromList();
+
*self->caller_result_ = verify_result->result;
// Note: May delete |self|.
std::move(self->callback_).Run(verify_result->error);
}
-} // namespace
-
MultiThreadedCertVerifier::MultiThreadedCertVerifier(
scoped_refptr<CertVerifyProc> verify_proc)
: verify_proc_(std::move(verify_proc)) {
@@ -171,6 +196,13 @@ MultiThreadedCertVerifier::MultiThreadedCertVerifier(
MultiThreadedCertVerifier::~MultiThreadedCertVerifier() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // Reset the callbacks for each InternalRequest to fulfill the respective
+ // net::CertVerifier contract.
+ while (!request_list_.empty()) {
+ base::LinkNode<InternalRequest>* curr = request_list_.head();
+ curr->value()->ResetCallback();
+ curr->RemoveFromList();
+ }
}
int MultiThreadedCertVerifier::Verify(const RequestParams& params,
@@ -188,11 +220,18 @@ int MultiThreadedCertVerifier::Verify(const RequestParams& params,
std::unique_ptr<InternalRequest> request =
std::make_unique<InternalRequest>(std::move(callback), verify_result);
request->Start(verify_proc_, config_, params, net_log);
+ request_list_.Append(request.get());
*out_req = std::move(request);
return ERR_IO_PENDING;
}
void MultiThreadedCertVerifier::SetConfig(const CertVerifier::Config& config) {
+ LOG_IF(DFATAL, verify_proc_ &&
+ !verify_proc_->SupportsAdditionalTrustAnchors() &&
+ !config.additional_trust_anchors.empty())
+ << "Attempted to set a CertVerifier::Config with additional trust "
+ "anchors, but |verify_proc_| does not support additional trust "
+ "anchors.";
config_ = config;
if (!config_.crl_set)
config_.crl_set = CRLSet::BuiltinCRLSet();