Browse Source

feat: allow setting SSL config (#25461)

* feat: allow setting SSL config

* lint

* configure system network context with min TLS1.2

* fix

* note defaults
Jeremy Rose 4 years ago
parent
commit
27ea3fc069

+ 14 - 0
docs/api/session.md

@@ -492,6 +492,20 @@ will be temporary.
 
 Returns `String` - The user agent for this session.
 
+#### `ses.setSSLConfig(config)`
+
+* `config` Object
+  * `minVersion` String - Can be `tls1`, `tls1.1`, `tls1.2` or `tls1.3`. The
+    minimum SSL version to allow when connecting to remote servers. Defaults to
+    `tls1`.
+  * `maxVersion` String - Can be `tls1.2` or `tls1.3`. The maximum SSL version
+    to allow when connecting to remote servers. Defaults to `tls1.3`.
+
+Sets the SSL configuration for the session. All subsequent network requests
+will use the new configuration. Existing network connections (such as WebSocket
+connections) will not be terminated, but old sockets in the pool will not be
+reused for new connections.
+
 #### `ses.getBlobData(identifier)`
 
 * `identifier` String - Valid UUID.

+ 55 - 0
shell/browser/api/electron_api_session.cc

@@ -19,6 +19,7 @@
 #include "base/strings/string_util.h"
 #include "base/task/post_task.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "components/download/public/common/download_danger_type.h"
 #include "components/download/public/common/download_url_parameters.h"
@@ -180,6 +181,55 @@ struct Converter<ClearStorageDataOptions> {
   }
 };
 
+bool SSLProtocolVersionFromString(const std::string& version_str,
+                                  network::mojom::SSLVersion* version) {
+  if (version_str == switches::kSSLVersionTLSv1) {
+    *version = network::mojom::SSLVersion::kTLS1;
+    return true;
+  }
+  if (version_str == switches::kSSLVersionTLSv11) {
+    *version = network::mojom::SSLVersion::kTLS11;
+    return true;
+  }
+  if (version_str == switches::kSSLVersionTLSv12) {
+    *version = network::mojom::SSLVersion::kTLS12;
+    return true;
+  }
+  if (version_str == switches::kSSLVersionTLSv13) {
+    *version = network::mojom::SSLVersion::kTLS13;
+    return true;
+  }
+  return false;
+}
+
+template <>
+struct Converter<network::mojom::SSLConfigPtr> {
+  static bool FromV8(v8::Isolate* isolate,
+                     v8::Local<v8::Value> val,
+                     network::mojom::SSLConfigPtr* out) {
+    gin_helper::Dictionary options;
+    if (!ConvertFromV8(isolate, val, &options))
+      return false;
+    *out = network::mojom::SSLConfig::New();
+    std::string version_min_str;
+    if (options.Get("minVersion", &version_min_str)) {
+      if (!SSLProtocolVersionFromString(version_min_str, &(*out)->version_min))
+        return false;
+    }
+    std::string version_max_str;
+    if (options.Get("maxVersion", &version_max_str)) {
+      if (!SSLProtocolVersionFromString(version_max_str,
+                                        &(*out)->version_max) ||
+          (*out)->version_max < network::mojom::SSLVersion::kTLS12)
+        return false;
+    }
+
+    // TODO(nornagon): also support client_cert_pooling_policy and
+    // disabled_cipher_suites. Maybe other SSLConfig properties too?
+    return true;
+  }
+};
+
 }  // namespace gin
 
 namespace electron {
@@ -617,6 +667,10 @@ std::string Session::GetUserAgent() {
   return browser_context_->GetUserAgent();
 }
 
+void Session::SetSSLConfig(network::mojom::SSLConfigPtr config) {
+  browser_context_->SetSSLConfig(std::move(config));
+}
+
 bool Session::IsPersistent() {
   return !browser_context_->IsOffTheRecord();
 }
@@ -1024,6 +1078,7 @@ gin::ObjectTemplateBuilder Session::GetObjectTemplateBuilder(
       .SetMethod("isPersistent", &Session::IsPersistent)
       .SetMethod("setUserAgent", &Session::SetUserAgent)
       .SetMethod("getUserAgent", &Session::GetUserAgent)
+      .SetMethod("setSSLConfig", &Session::SetSSLConfig)
       .SetMethod("getBlobData", &Session::GetBlobData)
       .SetMethod("downloadURL", &Session::DownloadURL)
       .SetMethod("createInterruptedDownload",

+ 2 - 0
shell/browser/api/electron_api_session.h

@@ -13,6 +13,7 @@
 #include "electron/buildflags/buildflags.h"
 #include "gin/handle.h"
 #include "gin/wrappable.h"
+#include "services/network/public/mojom/ssl_config.mojom.h"
 #include "shell/browser/event_emitter_mixin.h"
 #include "shell/browser/net/resolve_proxy_helper.h"
 #include "shell/common/gin_helper/cleaned_up_at_exit.h"
@@ -107,6 +108,7 @@ class Session : public gin::Wrappable<Session>,
   void AllowNTLMCredentialsForDomains(const std::string& domains);
   void SetUserAgent(const std::string& user_agent, gin::Arguments* args);
   std::string GetUserAgent();
+  void SetSSLConfig(network::mojom::SSLConfigPtr config);
   bool IsPersistent();
   v8::Local<v8::Promise> GetBlobData(v8::Isolate* isolate,
                                      const std::string& uuid);

+ 17 - 0
shell/browser/electron_browser_context.cc

@@ -106,6 +106,7 @@ ElectronBrowserContext::ElectronBrowserContext(const std::string& partition,
       storage_policy_(new SpecialStoragePolicy),
       protocol_registry_(new ProtocolRegistry),
       in_memory_(in_memory),
+      ssl_config_(network::mojom::SSLConfig::New()),
       weak_factory_(this) {
   // TODO(nornagon): remove once https://crbug.com/1048822 is fixed.
   base::ScopedAllowBlockingForTesting allow_blocking;
@@ -446,6 +447,22 @@ ResolveProxyHelper* ElectronBrowserContext::GetResolveProxyHelper() {
   return resolve_proxy_helper_.get();
 }
 
+network::mojom::SSLConfigPtr ElectronBrowserContext::GetSSLConfig() {
+  return ssl_config_.Clone();
+}
+
+void ElectronBrowserContext::SetSSLConfig(network::mojom::SSLConfigPtr config) {
+  ssl_config_ = std::move(config);
+  if (ssl_config_client_) {
+    ssl_config_client_->OnSSLConfigUpdated(ssl_config_.Clone());
+  }
+}
+
+void ElectronBrowserContext::SetSSLConfigClient(
+    mojo::Remote<network::mojom::SSLConfigClient> client) {
+  ssl_config_client_ = std::move(client);
+}
+
 // static
 ElectronBrowserContext* ElectronBrowserContext::From(
     const std::string& partition,

+ 7 - 0
shell/browser/electron_browser_context.h

@@ -147,6 +147,10 @@ class ElectronBrowserContext
     return protocol_registry_.get();
   }
 
+  void SetSSLConfig(network::mojom::SSLConfigPtr config);
+  network::mojom::SSLConfigPtr GetSSLConfig();
+  void SetSSLConfigClient(mojo::Remote<network::mojom::SSLConfigClient> client);
+
   ~ElectronBrowserContext() override;
 
  private:
@@ -190,6 +194,9 @@ class ElectronBrowserContext
   scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
   mojo::Receiver<network::mojom::TrustedURLLoaderAuthClient> auth_client_{this};
 
+  network::mojom::SSLConfigPtr ssl_config_;
+  mojo::Remote<network::mojom::SSLConfigClient> ssl_config_client_;
+
   base::WeakPtrFactory<ElectronBrowserContext> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ElectronBrowserContext);

+ 9 - 0
shell/browser/net/network_context_service.cc

@@ -4,6 +4,8 @@
 
 #include "shell/browser/net/network_context_service.h"
 
+#include <utility>
+
 #include "chrome/common/chrome_constants.h"
 #include "content/public/browser/network_service_instance.h"
 #include "net/net_buildflags.h"
@@ -29,6 +31,13 @@ void NetworkContextService::ConfigureNetworkContextParams(
   g_browser_process->system_network_context_manager()
       ->ConfigureDefaultNetworkContextParams(network_context_params);
 
+  mojo::Remote<network::mojom::SSLConfigClient> ssl_config_client;
+  network_context_params->ssl_config_client_receiver =
+      ssl_config_client.BindNewPipeAndPassReceiver();
+  browser_context_->SetSSLConfigClient(std::move(ssl_config_client));
+
+  network_context_params->initial_ssl_config = browser_context_->GetSSLConfig();
+
   network_context_params->user_agent = browser_context_->GetUserAgent();
 
   network_context_params->accept_language =

+ 4 - 0
shell/browser/net/system_network_context_manager.cc

@@ -229,6 +229,10 @@ SystemNetworkContextManager::CreateNetworkContextParams() {
 
   network_context_params->http_cache_enabled = false;
 
+  auto ssl_config = network::mojom::SSLConfig::New();
+  ssl_config->version_min = network::mojom::SSLVersion::kTLS12;
+  network_context_params->initial_ssl_config = std::move(ssl_config);
+
   proxy_config_monitor_.AddToNetworkContextParams(network_context_params.get());
 
   return network_context_params;