Avi Drissman | 4e1b7bc3 | 2022-09-15 14:03:50 | [diff] [blame] | 1 | // Copyright 2012 The Chromium Authors |
[email protected] | ce2b6226 | 2009-06-27 05:11:41 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | 74b962a | 2011-06-03 21:22:54 | [diff] [blame] | 5 | #include "content/browser/ssl/ssl_client_auth_handler.h" |
[email protected] | ce2b6226 | 2009-06-27 05:11:41 | [diff] [blame] | 6 | |
dcheng | 36b6aec9 | 2015-12-26 06:16:36 | [diff] [blame] | 7 | #include <utility> |
| 8 | |
Hans Wennborg | 0917de89 | 2020-04-28 20:21:15 | [diff] [blame] | 9 | #include "base/check_op.h" |
Avi Drissman | adac2199 | 2023-01-11 23:46:39 | [diff] [blame] | 10 | #include "base/functional/bind.h" |
Eric Seckler | 8652dcd5 | 2018-09-20 10:42:28 | [diff] [blame] | 11 | #include "content/public/browser/browser_task_traits.h" |
[email protected] | c38831a1 | 2011-10-28 12:44:49 | [diff] [blame] | 12 | #include "content/public/browser/browser_thread.h" |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 13 | #include "content/public/browser/client_certificate_delegate.h" |
[email protected] | 87f3c08 | 2011-10-19 18:07:44 | [diff] [blame] | 14 | #include "content/public/browser/content_browser_client.h" |
Hans Wennborg | 5ffd139 | 2019-10-16 11:00:02 | [diff] [blame] | 15 | #include "content/public/common/content_client.h" |
[email protected] | 1ccb699d | 2013-10-30 04:46:20 | [diff] [blame] | 16 | #include "net/ssl/client_cert_store.h" |
mattm | 436ccfe | 2017-06-19 20:24:08 | [diff] [blame] | 17 | #include "net/ssl/ssl_private_key.h" |
[email protected] | ce2b6226 | 2009-06-27 05:11:41 | [diff] [blame] | 18 | |
[email protected] | 89f23a3 | 2012-10-24 22:31:24 | [diff] [blame] | 19 | namespace content { |
[email protected] | 631bb74 | 2011-11-02 11:29:39 | [diff] [blame] | 20 | |
David Benjamin | f6a3409 | 2019-11-07 19:55:10 | [diff] [blame] | 21 | class SSLClientAuthHandler::ClientCertificateDelegateImpl |
| 22 | : public ClientCertificateDelegate { |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 23 | public: |
| 24 | explicit ClientCertificateDelegateImpl( |
David Benjamin | f6a3409 | 2019-11-07 19:55:10 | [diff] [blame] | 25 | base::WeakPtr<SSLClientAuthHandler> handler) |
| 26 | : handler_(std::move(handler)) {} |
davidben | 6cd57dd | 2014-12-12 19:23:57 | [diff] [blame] | 27 | |
Peter Boström | 828b902 | 2021-09-21 02:28:43 | [diff] [blame] | 28 | ClientCertificateDelegateImpl(const ClientCertificateDelegateImpl&) = delete; |
| 29 | ClientCertificateDelegateImpl& operator=( |
| 30 | const ClientCertificateDelegateImpl&) = delete; |
| 31 | |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 32 | ~ClientCertificateDelegateImpl() override { |
David Benjamin | f6a3409 | 2019-11-07 19:55:10 | [diff] [blame] | 33 | if (!continue_called_ && handler_) { |
| 34 | handler_->delegate_->CancelCertificateSelection(); |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 35 | } |
| 36 | } |
| 37 | |
| 38 | // ClientCertificateDelegate implementation: |
mattm | 436ccfe | 2017-06-19 20:24:08 | [diff] [blame] | 39 | void ContinueWithCertificate(scoped_refptr<net::X509Certificate> cert, |
| 40 | scoped_refptr<net::SSLPrivateKey> key) override { |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 41 | DCHECK(!continue_called_); |
| 42 | continue_called_ = true; |
David Benjamin | f6a3409 | 2019-11-07 19:55:10 | [diff] [blame] | 43 | if (handler_) { |
| 44 | handler_->delegate_->ContinueWithCertificate(std::move(cert), |
| 45 | std::move(key)); |
| 46 | } |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 47 | } |
| 48 | |
| 49 | private: |
| 50 | base::WeakPtr<SSLClientAuthHandler> handler_; |
David Benjamin | f6a3409 | 2019-11-07 19:55:10 | [diff] [blame] | 51 | bool continue_called_ = false; |
davidben | 3b8455ae7 | 2015-03-11 19:42:19 | [diff] [blame] | 52 | }; |
davidben | 6cd57dd | 2014-12-12 19:23:57 | [diff] [blame] | 53 | |
[email protected] | ce2b6226 | 2009-06-27 05:11:41 | [diff] [blame] | 54 | SSLClientAuthHandler::SSLClientAuthHandler( |
dcheng | 5971627 | 2016-04-09 05:19:08 | [diff] [blame] | 55 | std::unique_ptr<net::ClientCertStore> client_cert_store, |
Erik Chen | 7776c8d | 2024-01-24 04:46:11 | [diff] [blame] | 56 | base::WeakPtr<BrowserContext> browser_context, |
Devlin Cronin | df260f5e | 2024-07-03 02:13:39 | [diff] [blame] | 57 | int process_id, |
Erik Chen | 7776c8d | 2024-01-24 04:46:11 | [diff] [blame] | 58 | base::WeakPtr<WebContents> web_contents, |
davidben | 5b6618d | 2014-12-08 20:41:39 | [diff] [blame] | 59 | net::SSLCertRequestInfo* cert_request_info, |
Jun Cai | 9409ded | 2018-01-30 00:19:46 | [diff] [blame] | 60 | Delegate* delegate) |
Erik Chen | 7776c8d | 2024-01-24 04:46:11 | [diff] [blame] | 61 | : browser_context_(browser_context), |
Devlin Cronin | df260f5e | 2024-07-03 02:13:39 | [diff] [blame] | 62 | process_id_(process_id), |
Erik Chen | 7776c8d | 2024-01-24 04:46:11 | [diff] [blame] | 63 | web_contents_(web_contents), |
[email protected] | 1ccb699d | 2013-10-30 04:46:20 | [diff] [blame] | 64 | cert_request_info_(cert_request_info), |
Arno Renevier | b733ea8 | 2024-05-02 22:46:33 | [diff] [blame] | 65 | client_cert_store_(std::move(client_cert_store)), |
Jeremy Roman | 3bca4bf | 2019-07-11 03:41:25 | [diff] [blame] | 66 | delegate_(delegate) { |
David Benjamin | f6a3409 | 2019-11-07 19:55:10 | [diff] [blame] | 67 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Erik Chen | 7776c8d | 2024-01-24 04:46:11 | [diff] [blame] | 68 | if (web_contents_) { |
| 69 | CHECK_EQ(web_contents_->GetBrowserContext(), browser_context_.get()); |
| 70 | } |
[email protected] | ce2b6226 | 2009-06-27 05:11:41 | [diff] [blame] | 71 | } |
| 72 | |
| 73 | SSLClientAuthHandler::~SSLClientAuthHandler() { |
Daniel McArdle | 15311a9 | 2020-02-07 18:17:41 | [diff] [blame] | 74 | // Invalidate our WeakPtrs in case invoking the cancellation callback would |
| 75 | // cause |this| to be destructed again. |
| 76 | weak_factory_.InvalidateWeakPtrs(); |
Daniel McArdle | 85735f5 | 2019-06-25 03:27:06 | [diff] [blame] | 77 | if (cancellation_callback_) { |
David Benjamin | f6a3409 | 2019-11-07 19:55:10 | [diff] [blame] | 78 | std::move(cancellation_callback_).Run(); |
Daniel McArdle | 85735f5 | 2019-06-25 03:27:06 | [diff] [blame] | 79 | } |
[email protected] | ce2b6226 | 2009-06-27 05:11:41 | [diff] [blame] | 80 | } |
| 81 | |
| 82 | void SSLClientAuthHandler::SelectCertificate() { |
David Benjamin | f6a3409 | 2019-11-07 19:55:10 | [diff] [blame] | 83 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
[email protected] | ce2b6226 | 2009-06-27 05:11:41 | [diff] [blame] | 84 | |
Arno Renevier | b733ea8 | 2024-05-02 22:46:33 | [diff] [blame] | 85 | 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 | } |
davidben | 78fee7d | 2014-12-03 19:41:51 | [diff] [blame] | 93 | } |
| 94 | |
mattm | 7ed243f | 2017-04-28 05:28:58 | [diff] [blame] | 95 | void SSLClientAuthHandler::DidGetClientCerts( |
mattm | 436ccfe | 2017-06-19 20:24:08 | [diff] [blame] | 96 | net::ClientCertIdentityList client_certs) { |
Arno Renevier | b733ea8 | 2024-05-02 22:46:33 | [diff] [blame] | 97 | // 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 | |
| 104 | void SSLClientAuthHandler::DidGetClientCertsOnPostTask( |
| 105 | net::ClientCertIdentityList client_certs) { |
David Benjamin | f6a3409 | 2019-11-07 19:55:10 | [diff] [blame] | 106 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 107 | |
Erik Chen | 7776c8d | 2024-01-24 04:46:11 | [diff] [blame] | 108 | if (!browser_context_) { |
Devlin Cronin | 9459117 | 2023-07-18 00:46:07 | [diff] [blame] | 109 | delegate_->CancelCertificateSelection(); |
[email protected] | 1ccb699d | 2013-10-30 04:46:20 | [diff] [blame] | 110 | return; |
| 111 | } |
| 112 | |
David Benjamin | f6a3409 | 2019-11-07 19:55:10 | [diff] [blame] | 113 | // 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 Cronin | df260f5e | 2024-07-03 02:13:39 | [diff] [blame] | 118 | browser_context_.get(), process_id_, web_contents_.get(), |
| 119 | cert_request_info_.get(), std::move(client_certs), |
David Benjamin | f6a3409 | 2019-11-07 19:55:10 | [diff] [blame] | 120 | 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] | d39dbf1 | 2011-04-18 23:37:31 | [diff] [blame] | 126 | } |
[email protected] | 89f23a3 | 2012-10-24 22:31:24 | [diff] [blame] | 127 | |
| 128 | } // namespace content |