From 2de5f9de6c47e866da692655222692900212a617 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Thu, 4 Jun 2015 02:27:06 +0530 Subject: [PATCH 1/2] browser: support client certificate --- atom/browser/atom_browser_client.cc | 36 ++++++++++++++++++++++++ atom/browser/atom_browser_client.h | 9 ++++++ atom/common/options_switches.cc | 3 ++ atom/common/options_switches.h | 1 + docs/api/chrome-command-line-switches.md | 4 +++ 5 files changed, 53 insertions(+) diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 88aa5b77755c..2d5db4d17d13 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -19,11 +19,14 @@ #include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h" #include "chrome/browser/speech/tts_message_filter.h" #include "content/public/browser/browser_ppapi_host.h" +#include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" #include "content/public/common/web_preferences.h" +#include "net/cert/x509_certificate.h" +#include "net/ssl/ssl_cert_request_info.h" #include "ppapi/host/ppapi_host.h" #include "ui/base/l10n/l10n_util.h" @@ -67,6 +70,23 @@ ProcessOwner GetProcessOwner(int process_id, return OWNER_NONE; } +scoped_refptr ImportCertFromFile( + const base::FilePath& path) { + std::string cert_data; + if (!base::ReadFileToString(path, &cert_data)) + return nullptr; + + net::CertificateList certs = + net::X509Certificate::CreateCertificateListFromBytes( + cert_data.data(), cert_data.size(), + net::X509Certificate::FORMAT_AUTO); + + if (certs.empty()) + return nullptr; + + return certs[0]; +} + } // namespace // static @@ -189,6 +209,22 @@ content::QuotaPermissionContext* return new AtomQuotaPermissionContext; } +void AtomBrowserClient::SelectClientCertificate( + content::WebContents* web_contents, + net::SSLCertRequestInfo* cert_request_info, + scoped_ptr delegate) { + auto command_line = base::CommandLine::ForCurrentProcess(); + auto cert_path = command_line->GetSwitchValueNative( + switches::kClientCertificate); + + if (cert_path.empty()) + return; + + scoped_refptr certificate = + ImportCertFromFile(base::FilePath(cert_path)); + delegate->ContinueWithCertificate(certificate.get()); +} + brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( const content::MainFunctionParams&) { v8::V8::Initialize(); // Init V8 before creating main parts. diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index 6aebc3128a48..c8a26da7099f 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -11,6 +11,11 @@ namespace content { class QuotaPermissionContext; +class ClientCertificateDelegate; +} + +namespace net { +class SSLCertRequestInfo; } namespace atom { @@ -41,6 +46,10 @@ class AtomBrowserClient : public brightray::BrowserClient { int child_process_id) override; void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override; content::QuotaPermissionContext* CreateQuotaPermissionContext() override; + void SelectClientCertificate( + content::WebContents* web_contents, + net::SSLCertRequestInfo* cert_request_info, + scoped_ptr delegate) override; private: brightray::BrowserMainParts* OverrideCreateBrowserMainParts( diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index c9997996fed8..2764f86a5fcf 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -87,6 +87,9 @@ const char kDisableAutoHideCursor[] = "disable-auto-hide-cursor"; // Use the OS X's standard window instead of the textured window. const char kStandardWindow[] = "standard-window"; +// Path to client certificate. +const char kClientCertificate[] = "client-certificate"; + // Web runtime features. const char kExperimentalFeatures[] = "experimental-features"; const char kExperimentalCanvasFeatures[] = "experimental-canvas-features"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 071459afac73..e6d85063341a 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -45,6 +45,7 @@ extern const char kTransparent[]; extern const char kType[]; extern const char kDisableAutoHideCursor[]; extern const char kStandardWindow[]; +extern const char kClientCertificate[]; extern const char kExperimentalFeatures[]; extern const char kExperimentalCanvasFeatures[]; diff --git a/docs/api/chrome-command-line-switches.md b/docs/api/chrome-command-line-switches.md index 316211e4db0c..37b0e6fbca54 100644 --- a/docs/api/chrome-command-line-switches.md +++ b/docs/api/chrome-command-line-switches.md @@ -14,6 +14,10 @@ app.on('ready', function() { }); ``` +## --client-certificate + +Path to client certificate file. + ## --disable-http-cache Disables the disk cache for HTTP requests. From 52b2c0d27f7c050f8b032e5173c167d617cf393f Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 8 Jun 2015 21:35:32 +0530 Subject: [PATCH 2/2] default to first certificate from cert store --- atom/browser/atom_browser_client.cc | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 2d5db4d17d13..d0f2df2122cd 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -217,12 +217,19 @@ void AtomBrowserClient::SelectClientCertificate( auto cert_path = command_line->GetSwitchValueNative( switches::kClientCertificate); - if (cert_path.empty()) - return; + // TODO(zcbenz): allow users to select certificate from + // client_cert list. Right now defaults to first certificate + // in the list. + scoped_refptr certificate; + if (cert_path.empty()) { + if (!cert_request_info->client_certs.empty()) + certificate = cert_request_info->client_certs[0]; + } else { + certificate = ImportCertFromFile(base::FilePath(cert_path)); + } - scoped_refptr certificate = - ImportCertFromFile(base::FilePath(cert_path)); - delegate->ContinueWithCertificate(certificate.get()); + if (certificate.get()) + delegate->ContinueWithCertificate(certificate.get()); } brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(