| 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
|
|
|