summaryrefslogtreecommitdiff
path: root/testing/marionette/cert.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/marionette/cert.js')
-rw-r--r--testing/marionette/cert.js140
1 files changed, 140 insertions, 0 deletions
diff --git a/testing/marionette/cert.js b/testing/marionette/cert.js
new file mode 100644
index 0000000000..c0b24d23bf
--- /dev/null
+++ b/testing/marionette/cert.js
@@ -0,0 +1,140 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/Preferences.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+this.EXPORTED_SYMBOLS = ["cert"];
+
+const registrar =
+ Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+const sss = Cc["@mozilla.org/ssservice;1"]
+ .getService(Ci.nsISiteSecurityService);
+
+const CONTRACT_ID = "@mozilla.org/security/certoverride;1";
+const CERT_PINNING_ENFORCEMENT_PREF =
+ "security.cert_pinning.enforcement_level";
+const HSTS_PRELOAD_LIST_PREF =
+ "network.stricttransportsecurity.preloadlist";
+
+/** TLS certificate service override management for Marionette. */
+this.cert = {
+ Error: {
+ Untrusted: 1,
+ Mismatch: 2,
+ Time: 4,
+ },
+
+ currentOverride: null,
+};
+
+/**
+ * Installs a TLS certificate service override.
+ *
+ * The provided |service| must implement the |register| and |unregister|
+ * functions that causes a new |nsICertOverrideService| interface
+ * implementation to be registered with the |nsIComponentRegistrar|.
+ *
+ * After |service| is registered and made the |cert.currentOverride|,
+ * |nsICertOverrideService| is reinitialised to cause all Gecko components
+ * to pick up the new service.
+ *
+ * If an override is already installed, i.e. when |cert.currentOverride|
+ * is not null, this functions acts as a NOOP.
+ *
+ * @param {cert.Override} service
+ * Service generator that registers and unregisters the XPCOM service.
+ *
+ * @throws {Components.Exception}
+ * If unable to register or initialise |service|.
+ */
+cert.installOverride = function (service) {
+ if (this.currentOverride) {
+ return;
+ }
+
+ service.register();
+ cert.currentOverride = service;
+};
+
+/**
+ * Uninstall a TLS certificate service override.
+ *
+ * After the service has been unregistered, |cert.currentOverride|
+ * is reset to null.
+ *
+ * If there no current override installed, i.e. if |cert.currentOverride|
+ * is null, this function acts as a NOOP.
+ */
+cert.uninstallOverride = function() {
+ if (!cert.currentOverride) {
+ return;
+ }
+ cert.currentOverride.unregister();
+ this.currentOverride = null;
+};
+
+/**
+ * Certificate override service that acts in an all-inclusive manner
+ * on TLS certificates.
+ *
+ * When an invalid certificate is encountered, it is overriden
+ * with the |matching| bit level, which is typically a combination of
+ * |cert.Error.Untrusted|, |cert.Error.Mismatch|, and |cert.Error.Time|.
+ *
+ * @type cert.Override
+ *
+ * @throws {Components.Exception}
+ * If there are any problems registering the service.
+ */
+cert.InsecureSweepingOverride = function() {
+ const CID = Components.ID("{4b67cce0-a51c-11e6-9598-0800200c9a66}");
+ const DESC = "All-encompassing cert service that matches on a bitflag";
+
+ // This needs to be an old-style class with a function constructor
+ // and prototype assignment because... XPCOM. Any attempt at
+ // modernisation will be met with cryptic error messages which will
+ // make your life miserable.
+ let service = function() {};
+ service.prototype = {
+ hasMatchingOverride: function (
+ aHostName, aPort, aCert, aOverrideBits, aIsTemporary) {
+ aIsTemporary.value = false;
+ aOverrideBits.value =
+ cert.Error.Untrusted | cert.Error.Mismatch | cert.Error.Time;
+
+ return true;
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsICertOverrideService]),
+ };
+ let factory = XPCOMUtils.generateSingletonFactory(service);
+
+ return {
+ register: function() {
+ // make it possible to register certificate overrides for domains
+ // that use HSTS or HPKP
+ Preferences.set(HSTS_PRELOAD_LIST_PREF, false);
+ Preferences.set(CERT_PINNING_ENFORCEMENT_PREF, 0);
+
+ registrar.registerFactory(CID, DESC, CONTRACT_ID, factory);
+ },
+
+ unregister: function() {
+ registrar.unregisterFactory(CID, factory);
+
+ Preferences.reset(HSTS_PRELOAD_LIST_PREF);
+ Preferences.reset(CERT_PINNING_ENFORCEMENT_PREF);
+
+ // clear collected HSTS and HPKP state
+ // through the site security service
+ sss.clearAll();
+ sss.clearPreloads();
+ },
+ };
+};