Index: chrome/browser/ssl/ssl_add_certificate.cc |
diff --git a/chrome/browser/ssl/ssl_add_certificate.cc b/chrome/browser/ssl/ssl_add_certificate.cc |
index 27b57ce50972c16fa7e940cd30e4819557fa8283..e12c00c7d404bd0bb5151bf20200051c7c38962e 100644 |
--- a/chrome/browser/ssl/ssl_add_certificate.cc |
+++ b/chrome/browser/ssl/ssl_add_certificate.cc |
@@ -4,18 +4,130 @@ |
#include "chrome/browser/ssl/ssl_add_certificate.h" |
-#include "chrome/browser/ssl/ssl_add_cert_handler.h" |
+#include "base/basictypes.h" |
+#include "base/strings/string_number_conversions.h" |
+#include "base/strings/utf_string_conversions.h" |
+#include "chrome/browser/certificate_viewer.h" |
+#include "chrome/browser/infobars/infobar_service.h" |
+#include "chrome/browser/infobars/simple_alert_infobar_delegate.h" |
+#include "components/infobars/core/confirm_infobar_delegate.h" |
+#include "components/infobars/core/infobar.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/render_frame_host.h" |
+#include "content/public/browser/web_contents.h" |
+#include "grit/generated_resources.h" |
+#include "grit/theme_resources.h" |
+#include "net/base/net_errors.h" |
+#include "net/cert/cert_database.h" |
#include "net/cert/x509_certificate.h" |
+#include "ui/base/l10n/l10n_util.h" |
+ |
+using content::BrowserThread; |
+using content::RenderFrameHost; |
+using content::WebContents; |
namespace chrome { |
+namespace { |
+ |
+class SSLAddCertificateInfoBarDelegate : public ConfirmInfoBarDelegate { |
+ public: |
+ // Creates an SSL certificate enrollment result infobar and delegate. |
+ static void Create(InfoBarService* infobar_service, |
+ net::X509Certificate* cert) { |
+ infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar( |
+ scoped_ptr<ConfirmInfoBarDelegate>( |
+ new SSLAddCertificateInfoBarDelegate(cert)))); |
+ } |
+ |
+ private: |
+ explicit SSLAddCertificateInfoBarDelegate(net::X509Certificate* cert) |
+ : cert_(cert) {} |
+ virtual ~SSLAddCertificateInfoBarDelegate() {} |
+ |
+ // ConfirmInfoBarDelegate implementation: |
+ virtual int GetIconID() const OVERRIDE { |
+ // TODO(davidben): Use a more appropriate icon. |
+ return IDR_INFOBAR_SAVE_PASSWORD; |
+ } |
+ |
+ virtual Type GetInfoBarType() const OVERRIDE { |
+ return PAGE_ACTION_TYPE; |
+ } |
+ |
+ virtual base::string16 GetMessageText() const OVERRIDE { |
+ // TODO(evanm): GetDisplayName should return UTF-16. |
+ return l10n_util::GetStringFUTF16(IDS_ADD_CERT_SUCCESS_INFOBAR_LABEL, |
+ base::UTF8ToUTF16( |
+ cert_->issuer().GetDisplayName())); |
+ } |
+ |
+ virtual int GetButtons() const OVERRIDE { |
+ return BUTTON_OK; |
+ } |
+ |
+ virtual base::string16 GetButtonLabel(InfoBarButton button) const OVERRIDE { |
+ DCHECK_EQ(BUTTON_OK, button); |
+ return l10n_util::GetStringUTF16(IDS_ADD_CERT_SUCCESS_INFOBAR_BUTTON); |
+ } |
+ |
+ virtual bool Accept() OVERRIDE { |
+ WebContents* web_contents = |
+ InfoBarService::WebContentsFromInfoBar(infobar()); |
+ ShowCertificateViewer(web_contents, |
+ web_contents->GetTopLevelNativeWindow(), |
+ cert_.get()); |
+ // It looks weird to hide the infobar just as the dialog opens. |
+ return false; |
+ } |
+ |
+ // The certificate that was added. |
+ scoped_refptr<net::X509Certificate> cert_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(SSLAddCertificateInfoBarDelegate); |
+}; |
+ |
+void ShowErrorInfoBar(int message_id, |
+ int render_process_id, |
+ int render_frame_id, |
+ int cert_error) { |
+ WebContents* web_contents = WebContents::FromRenderFrameHost( |
+ RenderFrameHost::FromID(render_process_id, render_frame_id)); |
+ if (!web_contents) |
+ return; |
+ |
+ // TODO(davidben): Use a more appropriate icon. |
+ // TODO(davidben): Display a more user-friendly error string. |
+ SimpleAlertInfoBarDelegate::Create( |
+ InfoBarService::FromWebContents(web_contents), |
+ IDR_INFOBAR_SAVE_PASSWORD, |
+ l10n_util::GetStringFUTF16(IDS_ADD_CERT_ERR_INVALID_CERT, |
+ base::IntToString16(-cert_error), |
+ base::ASCIIToUTF16( |
+ net::ErrorToString(cert_error))), |
+ true); |
+} |
+ |
+void ShowSuccessInfoBar(int render_process_id, |
+ int render_frame_id, |
+ net::X509Certificate* cert) { |
+ WebContents* web_contents = WebContents::FromRenderFrameHost( |
+ RenderFrameHost::FromID(render_process_id, render_frame_id)); |
+ if (!web_contents) |
+ return; |
+ |
+ SSLAddCertificateInfoBarDelegate::Create( |
+ InfoBarService::FromWebContents(web_contents), cert); |
+} |
+ |
+} // namespace |
+ |
void SSLAddCertificate( |
- net::URLRequest* request, |
net::CertificateMimeType cert_type, |
const void* cert_data, |
size_t cert_size, |
int render_process_id, |
- int render_view_id) { |
+ int render_frame_id) { |
// Chromium only supports X.509 User certificates on non-Android |
// platforms. Note that this method should not be called for other |
// certificate mime types. |
@@ -30,8 +142,35 @@ void SSLAddCertificate( |
// NOTE: Passing a NULL cert pointer if |cert_data| was NULL is |
// intentional here. |
- // The handler will run the UI and delete itself when it's finished. |
- new SSLAddCertHandler(request, cert.get(), render_process_id, render_view_id); |
+ // Check if we have a corresponding private key. |
+ int cert_error = net::CertDatabase::GetInstance()->CheckUserCert(cert.get()); |
+ if (cert_error != net::OK) { |
+ LOG_IF(ERROR, cert_error == net::ERR_NO_PRIVATE_KEY_FOR_CERT) |
+ << "No corresponding private key in store for cert: " |
+ << (cert.get() ? cert->subject().GetDisplayName() : "NULL"); |
+ |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, FROM_HERE, |
+ base::Bind(&ShowErrorInfoBar, IDS_ADD_CERT_ERR_INVALID_CERT, |
+ render_process_id, render_frame_id, cert_error)); |
+ return; |
+ } |
+ |
+ // Install it. |
+ cert_error = net::CertDatabase::GetInstance()->AddUserCert(cert.get()); |
+ |
+ // Show the appropriate infobar. |
+ if (cert_error != net::OK) { |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, FROM_HERE, |
+ base::Bind(&ShowErrorInfoBar, IDS_ADD_CERT_ERR_FAILED, |
+ render_process_id, render_frame_id, cert_error)); |
+ } else { |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, FROM_HERE, |
+ base::Bind(&ShowSuccessInfoBar, |
+ render_process_id, render_frame_id, cert)); |
+ } |
} |
} // namespace chrome |