blob: 0c239e1bc45763e6f9722e287b04d27c026c1726 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2012 The Chromium Authors
[email protected]ce2b62262009-06-27 05:11:412// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]74b962a2011-06-03 21:22:545#include "content/browser/ssl/ssl_client_auth_handler.h"
[email protected]ce2b62262009-06-27 05:11:416
dcheng36b6aec92015-12-26 06:16:367#include <utility>
8
Hans Wennborg0917de892020-04-28 20:21:159#include "base/check_op.h"
Avi Drissmanadac21992023-01-11 23:46:3910#include "base/functional/bind.h"
Eric Seckler8652dcd52018-09-20 10:42:2811#include "content/public/browser/browser_task_traits.h"
[email protected]c38831a12011-10-28 12:44:4912#include "content/public/browser/browser_thread.h"
davidben3b8455ae72015-03-11 19:42:1913#include "content/public/browser/client_certificate_delegate.h"
[email protected]87f3c082011-10-19 18:07:4414#include "content/public/browser/content_browser_client.h"
Hans Wennborg5ffd1392019-10-16 11:00:0215#include "content/public/common/content_client.h"
[email protected]1ccb699d2013-10-30 04:46:2016#include "net/ssl/client_cert_store.h"
mattm436ccfe2017-06-19 20:24:0817#include "net/ssl/ssl_private_key.h"
[email protected]ce2b62262009-06-27 05:11:4118
[email protected]89f23a32012-10-24 22:31:2419namespace content {
[email protected]631bb742011-11-02 11:29:3920
David Benjaminf6a34092019-11-07 19:55:1021class SSLClientAuthHandler::ClientCertificateDelegateImpl
22 : public ClientCertificateDelegate {
davidben3b8455ae72015-03-11 19:42:1923 public:
24 explicit ClientCertificateDelegateImpl(
David Benjaminf6a34092019-11-07 19:55:1025 base::WeakPtr<SSLClientAuthHandler> handler)
26 : handler_(std::move(handler)) {}
davidben6cd57dd2014-12-12 19:23:5727
Peter Boström828b9022021-09-21 02:28:4328 ClientCertificateDelegateImpl(const ClientCertificateDelegateImpl&) = delete;
29 ClientCertificateDelegateImpl& operator=(
30 const ClientCertificateDelegateImpl&) = delete;
31
davidben3b8455ae72015-03-11 19:42:1932 ~ClientCertificateDelegateImpl() override {
David Benjaminf6a34092019-11-07 19:55:1033 if (!continue_called_ && handler_) {
34 handler_->delegate_->CancelCertificateSelection();
davidben3b8455ae72015-03-11 19:42:1935 }
36 }
37
38 // ClientCertificateDelegate implementation:
mattm436ccfe2017-06-19 20:24:0839 void ContinueWithCertificate(scoped_refptr<net::X509Certificate> cert,
40 scoped_refptr<net::SSLPrivateKey> key) override {
davidben3b8455ae72015-03-11 19:42:1941 DCHECK(!continue_called_);
42 continue_called_ = true;
David Benjaminf6a34092019-11-07 19:55:1043 if (handler_) {
44 handler_->delegate_->ContinueWithCertificate(std::move(cert),
45 std::move(key));
46 }
davidben3b8455ae72015-03-11 19:42:1947 }
48
49 private:
50 base::WeakPtr<SSLClientAuthHandler> handler_;
David Benjaminf6a34092019-11-07 19:55:1051 bool continue_called_ = false;
davidben3b8455ae72015-03-11 19:42:1952};
davidben6cd57dd2014-12-12 19:23:5753
[email protected]ce2b62262009-06-27 05:11:4154SSLClientAuthHandler::SSLClientAuthHandler(
dcheng59716272016-04-09 05:19:0855 std::unique_ptr<net::ClientCertStore> client_cert_store,
Erik Chen7776c8d2024-01-24 04:46:1156 base::WeakPtr<BrowserContext> browser_context,
Devlin Cronindf260f5e2024-07-03 02:13:3957 int process_id,
Erik Chen7776c8d2024-01-24 04:46:1158 base::WeakPtr<WebContents> web_contents,
davidben5b6618d2014-12-08 20:41:3959 net::SSLCertRequestInfo* cert_request_info,
Jun Cai9409ded2018-01-30 00:19:4660 Delegate* delegate)
Erik Chen7776c8d2024-01-24 04:46:1161 : browser_context_(browser_context),
Devlin Cronindf260f5e2024-07-03 02:13:3962 process_id_(process_id),
Erik Chen7776c8d2024-01-24 04:46:1163 web_contents_(web_contents),
[email protected]1ccb699d2013-10-30 04:46:2064 cert_request_info_(cert_request_info),
Arno Renevierb733ea82024-05-02 22:46:3365 client_cert_store_(std::move(client_cert_store)),
Jeremy Roman3bca4bf2019-07-11 03:41:2566 delegate_(delegate) {
David Benjaminf6a34092019-11-07 19:55:1067 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Erik Chen7776c8d2024-01-24 04:46:1168 if (web_contents_) {
69 CHECK_EQ(web_contents_->GetBrowserContext(), browser_context_.get());
70 }
[email protected]ce2b62262009-06-27 05:11:4171}
72
73SSLClientAuthHandler::~SSLClientAuthHandler() {
Daniel McArdle15311a92020-02-07 18:17:4174 // Invalidate our WeakPtrs in case invoking the cancellation callback would
75 // cause |this| to be destructed again.
76 weak_factory_.InvalidateWeakPtrs();
Daniel McArdle85735f52019-06-25 03:27:0677 if (cancellation_callback_) {
David Benjaminf6a34092019-11-07 19:55:1078 std::move(cancellation_callback_).Run();
Daniel McArdle85735f52019-06-25 03:27:0679 }
[email protected]ce2b62262009-06-27 05:11:4180}
81
82void SSLClientAuthHandler::SelectCertificate() {
David Benjaminf6a34092019-11-07 19:55:1083 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]ce2b62262009-06-27 05:11:4184
Arno Renevierb733ea82024-05-02 22:46:3385 if (client_cert_store_) {
86 client_cert_store_->GetClientCerts(
87 cert_request_info_,
88 base::BindOnce(&SSLClientAuthHandler::DidGetClientCerts,
89 weak_factory_.GetWeakPtr()));
90 } else {
91 DidGetClientCerts(net::ClientCertIdentityList());
92 }
davidben78fee7d2014-12-03 19:41:5193}
94
mattm7ed243f2017-04-28 05:28:5895void SSLClientAuthHandler::DidGetClientCerts(
mattm436ccfe2017-06-19 20:24:0896 net::ClientCertIdentityList client_certs) {
Arno Renevierb733ea82024-05-02 22:46:3397 // Run this on a PostTask to avoid reentrancy problems.
98 GetUIThreadTaskRunner({})->PostTask(
99 FROM_HERE,
100 base::BindOnce(&SSLClientAuthHandler::DidGetClientCertsOnPostTask,
101 weak_factory_.GetWeakPtr(), std::move(client_certs)));
102}
103
104void SSLClientAuthHandler::DidGetClientCertsOnPostTask(
105 net::ClientCertIdentityList client_certs) {
David Benjaminf6a34092019-11-07 19:55:10106 DCHECK_CURRENTLY_ON(BrowserThread::UI);
107
Erik Chen7776c8d2024-01-24 04:46:11108 if (!browser_context_) {
Devlin Cronin94591172023-07-18 00:46:07109 delegate_->CancelCertificateSelection();
[email protected]1ccb699d2013-10-30 04:46:20110 return;
111 }
112
David Benjaminf6a34092019-11-07 19:55:10113 // SelectClientCertificate() may call back into |delegate_| synchronously and
114 // destroy this object, so guard the cancellation callback logic by a WeakPtr.
115 base::WeakPtr<SSLClientAuthHandler> weak_self = weak_factory_.GetWeakPtr();
116 base::OnceClosure cancellation_callback =
117 GetContentClient()->browser()->SelectClientCertificate(
Devlin Cronindf260f5e2024-07-03 02:13:39118 browser_context_.get(), process_id_, web_contents_.get(),
119 cert_request_info_.get(), std::move(client_certs),
David Benjaminf6a34092019-11-07 19:55:10120 std::make_unique<ClientCertificateDelegateImpl>(weak_self));
121 if (weak_self) {
122 cancellation_callback_ = std::move(cancellation_callback);
123 } else if (!cancellation_callback.is_null()) {
124 std::move(cancellation_callback).Run();
125 }
[email protected]d39dbf12011-04-18 23:37:31126}
[email protected]89f23a32012-10-24 22:31:24127
128} // namespace content