 Chromium Code Reviews
 Chromium Code Reviews Issue 2898573002:
  Refactor client cert private key handling.  (Closed)
    
  
    Issue 2898573002:
  Refactor client cert private key handling.  (Closed) 
  | OLD | NEW | 
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "chrome/browser/ui/views/ssl_client_certificate_selector.h" | 5 #include "chrome/browser/ui/views/ssl_client_certificate_selector.h" | 
| 6 | 6 | 
| 7 #include <utility> | 7 #include <utility> | 
| 8 | 8 | 
| 9 #include "base/bind.h" | 9 #include "base/bind.h" | 
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" | 
| 11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" | 
| 12 #include "build/build_config.h" | 12 #include "build/build_config.h" | 
| 13 #include "chrome/browser/ui/browser_dialogs.h" | 13 #include "chrome/browser/ui/browser_dialogs.h" | 
| 14 #include "chrome/grit/generated_resources.h" | 14 #include "chrome/grit/generated_resources.h" | 
| 15 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" | 
| 16 #include "content/public/browser/client_certificate_delegate.h" | 16 #include "content/public/browser/client_certificate_delegate.h" | 
| 17 #include "content/public/browser/web_contents.h" | 17 #include "content/public/browser/web_contents.h" | 
| 18 #include "net/cert/x509_certificate.h" | 18 #include "net/cert/x509_certificate.h" | 
| 19 #include "net/ssl/ssl_cert_request_info.h" | 19 #include "net/ssl/ssl_cert_request_info.h" | 
| 20 #include "ui/base/l10n/l10n_util.h" | 20 #include "ui/base/l10n/l10n_util.h" | 
| 21 #include "ui/views/controls/label.h" | 21 #include "ui/views/controls/label.h" | 
| 22 #include "ui/views/widget/widget.h" | 22 #include "ui/views/widget/widget.h" | 
| 23 | 23 | 
| 24 #if defined(USE_NSS_CERTS) && !defined(OS_CHROMEOS) | 24 #if defined(USE_NSS_CERTS) && !defined(OS_CHROMEOS) | 
| 25 #include "chrome/browser/ui/crypto_module_password_dialog_nss.h" | 25 #include "chrome/browser/ui/crypto_module_password_dialog_nss.h" | 
| 
davidben
2017/06/07 23:06:17
No longer used? (Yay!)
 
mattm
2017/06/08 21:47:56
Yep! removed.
 | |
| 26 #endif | 26 #endif | 
| 27 | 27 | 
| 28 SSLClientCertificateSelector::SSLClientCertificateSelector( | 28 SSLClientCertificateSelector::SSLClientCertificateSelector( | 
| 29 content::WebContents* web_contents, | 29 content::WebContents* web_contents, | 
| 30 const scoped_refptr<net::SSLCertRequestInfo>& cert_request_info, | 30 const scoped_refptr<net::SSLCertRequestInfo>& cert_request_info, | 
| 31 net::CertificateList client_certs, | 31 net::ClientCertIdentityList client_certs, | 
| 32 std::unique_ptr<content::ClientCertificateDelegate> delegate) | 32 std::unique_ptr<content::ClientCertificateDelegate> delegate) | 
| 33 : CertificateSelector(std::move(client_certs), web_contents), | 33 : CertificateSelector(std::move(client_certs), web_contents), | 
| 34 SSLClientAuthObserver(web_contents->GetBrowserContext(), | 34 SSLClientAuthObserver(web_contents->GetBrowserContext(), | 
| 35 cert_request_info, | 35 cert_request_info, | 
| 36 std::move(delegate)), | 36 std::move(delegate)), | 
| 37 WebContentsObserver(web_contents) { | 37 WebContentsObserver(web_contents) { | 
| 38 chrome::RecordDialogCreation( | 38 chrome::RecordDialogCreation( | 
| 39 chrome::DialogIdentifier::SSL_CLIENT_CERTIFICATE_SELECTOR); | 39 chrome::DialogIdentifier::SSL_CLIENT_CERTIFICATE_SELECTOR); | 
| 40 } | 40 } | 
| 41 | 41 | 
| (...skipping 14 matching lines...) Expand all Loading... | |
| 56 | 56 | 
| 57 void SSLClientCertificateSelector::OnCertSelectedByNotification() { | 57 void SSLClientCertificateSelector::OnCertSelectedByNotification() { | 
| 58 GetWidget()->Close(); | 58 GetWidget()->Close(); | 
| 59 } | 59 } | 
| 60 | 60 | 
| 61 void SSLClientCertificateSelector::DeleteDelegate() { | 61 void SSLClientCertificateSelector::DeleteDelegate() { | 
| 62 // This is here and not in Cancel() to give WebContentsDestroyed a chance | 62 // This is here and not in Cancel() to give WebContentsDestroyed a chance | 
| 63 // to abort instead of proceeding with a null certificate. (This will be | 63 // to abort instead of proceeding with a null certificate. (This will be | 
| 64 // ignored if there was a previous call to CertificateSelected or | 64 // ignored if there was a previous call to CertificateSelected or | 
| 65 // CancelCertificateSelection.) | 65 // CancelCertificateSelection.) | 
| 66 CertificateSelected(nullptr); | 66 CertificateSelected(nullptr, nullptr); | 
| 67 chrome::CertificateSelector::DeleteDelegate(); | 67 chrome::CertificateSelector::DeleteDelegate(); | 
| 68 } | 68 } | 
| 69 | 69 | 
| 70 bool SSLClientCertificateSelector::Accept() { | 70 bool SSLClientCertificateSelector::Accept() { | 
| 71 scoped_refptr<net::X509Certificate> cert = GetSelectedCert(); | 71 net::ClientCertIdentity* identity = GetSelectedCert(); | 
| 72 if (cert.get()) { | 72 if (identity) { | 
| 73 // Remove the observer before we try unlocking, otherwise we might act on a | 73 // Remove the observer before we try acquiring private key, otherwise we | 
| 74 // notification while waiting for the unlock dialog, causing us to delete | 74 // might act on a notification while waiting for the callback, causing us | 
| 75 // ourself before the Unlocked callback gets called. | 75 // to delete ourself before the callback gets called. | 
| 76 StopObserving(); | 76 StopObserving(); | 
| 77 #if defined(USE_NSS_CERTS) && !defined(OS_CHROMEOS) | 77 identity->AcquirePrivateKey(base::Bind( | 
| 78 chrome::UnlockCertSlotIfNecessary( | 78 &SSLClientCertificateSelector::GotPrivateKey, base::Unretained(this), | 
| 
davidben
2017/06/07 23:06:17
Existing issue, but I'm not sure base::Unretained
 
mattm
2017/06/08 21:47:56
Yep. Crash :/
I think at one point these used to
 | |
| 79 cert.get(), chrome::kCryptoModulePasswordClientAuth, | 79 base::Unretained(identity->certificate()))); | 
| 80 cert_request_info()->host_and_port, GetWidget()->GetNativeView(), | 80 // GotPrivateKey() will close the dialog. It may be run synchronously. | 
| 81 base::Bind(&SSLClientCertificateSelector::Unlocked, | 81 return false; | 
| 82 base::Unretained(this), base::RetainedRef(cert))); | |
| 83 #else | |
| 84 Unlocked(cert.get()); | |
| 85 #endif | |
| 86 return false; // Unlocked() will close the dialog. | |
| 87 } | 82 } | 
| 88 | 83 | 
| 89 return false; | 84 return false; | 
| 90 } | 85 } | 
| 91 | 86 | 
| 92 void SSLClientCertificateSelector::WebContentsDestroyed() { | 87 void SSLClientCertificateSelector::WebContentsDestroyed() { | 
| 93 // If the dialog is closed by closing the containing tab, abort the request. | 88 // If the dialog is closed by closing the containing tab, abort the request. | 
| 94 CancelCertificateSelection(); | 89 CancelCertificateSelection(); | 
| 95 } | 90 } | 
| 96 | 91 | 
| 97 void SSLClientCertificateSelector::Unlocked(net::X509Certificate* cert) { | 92 void SSLClientCertificateSelector::GotPrivateKey( | 
| 98 CertificateSelected(cert); | 93 net::X509Certificate* cert, | 
| 94 scoped_refptr<net::SSLPrivateKey> private_key) { | |
| 95 CertificateSelected(cert, private_key.get()); | |
| 99 GetWidget()->Close(); | 96 GetWidget()->Close(); | 
| 100 } | 97 } | 
| 101 | 98 | 
| 102 namespace chrome { | 99 namespace chrome { | 
| 103 | 100 | 
| 104 void ShowSSLClientCertificateSelector( | 101 void ShowSSLClientCertificateSelector( | 
| 105 content::WebContents* contents, | 102 content::WebContents* contents, | 
| 106 net::SSLCertRequestInfo* cert_request_info, | 103 net::SSLCertRequestInfo* cert_request_info, | 
| 107 net::CertificateList client_certs, | 104 net::ClientCertIdentityList client_certs, | 
| 108 std::unique_ptr<content::ClientCertificateDelegate> delegate) { | 105 std::unique_ptr<content::ClientCertificateDelegate> delegate) { | 
| 109 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 106 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 
| 110 | 107 | 
| 111 // Not all WebContentses can show modal dialogs. | 108 // Not all WebContentses can show modal dialogs. | 
| 112 // | 109 // | 
| 113 // TODO(davidben): Move this hook to the WebContentsDelegate and only try to | 110 // TODO(davidben): Move this hook to the WebContentsDelegate and only try to | 
| 114 // show a dialog in Browser's implementation. https://crbug.com/456255 | 111 // show a dialog in Browser's implementation. https://crbug.com/456255 | 
| 115 if (!SSLClientCertificateSelector::CanShow(contents)) | 112 if (!SSLClientCertificateSelector::CanShow(contents)) | 
| 116 return; | 113 return; | 
| 117 | 114 | 
| 118 SSLClientCertificateSelector* selector = new SSLClientCertificateSelector( | 115 SSLClientCertificateSelector* selector = new SSLClientCertificateSelector( | 
| 119 contents, cert_request_info, std::move(client_certs), | 116 contents, cert_request_info, std::move(client_certs), | 
| 120 std::move(delegate)); | 117 std::move(delegate)); | 
| 121 selector->Init(); | 118 selector->Init(); | 
| 122 selector->Show(); | 119 selector->Show(); | 
| 123 } | 120 } | 
| 124 | 121 | 
| 125 } // namespace chrome | 122 } // namespace chrome | 
| OLD | NEW |