cert.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  3. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. "use strict";
  5. const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
  6. Cu.import("resource://gre/modules/Preferences.jsm");
  7. Cu.import("resource://gre/modules/XPCOMUtils.jsm");
  8. this.EXPORTED_SYMBOLS = ["cert"];
  9. const registrar =
  10. Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
  11. const sss = Cc["@mozilla.org/ssservice;1"]
  12. .getService(Ci.nsISiteSecurityService);
  13. const CONTRACT_ID = "@mozilla.org/security/certoverride;1";
  14. const CERT_PINNING_ENFORCEMENT_PREF =
  15. "security.cert_pinning.enforcement_level";
  16. const HSTS_PRELOAD_LIST_PREF =
  17. "network.stricttransportsecurity.preloadlist";
  18. /** TLS certificate service override management for Marionette. */
  19. this.cert = {
  20. Error: {
  21. Untrusted: 1,
  22. Mismatch: 2,
  23. Time: 4,
  24. },
  25. currentOverride: null,
  26. };
  27. /**
  28. * Installs a TLS certificate service override.
  29. *
  30. * The provided |service| must implement the |register| and |unregister|
  31. * functions that causes a new |nsICertOverrideService| interface
  32. * implementation to be registered with the |nsIComponentRegistrar|.
  33. *
  34. * After |service| is registered and made the |cert.currentOverride|,
  35. * |nsICertOverrideService| is reinitialised to cause all Gecko components
  36. * to pick up the new service.
  37. *
  38. * If an override is already installed, i.e. when |cert.currentOverride|
  39. * is not null, this functions acts as a NOOP.
  40. *
  41. * @param {cert.Override} service
  42. * Service generator that registers and unregisters the XPCOM service.
  43. *
  44. * @throws {Components.Exception}
  45. * If unable to register or initialise |service|.
  46. */
  47. cert.installOverride = function (service) {
  48. if (this.currentOverride) {
  49. return;
  50. }
  51. service.register();
  52. cert.currentOverride = service;
  53. };
  54. /**
  55. * Uninstall a TLS certificate service override.
  56. *
  57. * After the service has been unregistered, |cert.currentOverride|
  58. * is reset to null.
  59. *
  60. * If there no current override installed, i.e. if |cert.currentOverride|
  61. * is null, this function acts as a NOOP.
  62. */
  63. cert.uninstallOverride = function() {
  64. if (!cert.currentOverride) {
  65. return;
  66. }
  67. cert.currentOverride.unregister();
  68. this.currentOverride = null;
  69. };
  70. /**
  71. * Certificate override service that acts in an all-inclusive manner
  72. * on TLS certificates.
  73. *
  74. * When an invalid certificate is encountered, it is overriden
  75. * with the |matching| bit level, which is typically a combination of
  76. * |cert.Error.Untrusted|, |cert.Error.Mismatch|, and |cert.Error.Time|.
  77. *
  78. * @type cert.Override
  79. *
  80. * @throws {Components.Exception}
  81. * If there are any problems registering the service.
  82. */
  83. cert.InsecureSweepingOverride = function() {
  84. const CID = Components.ID("{4b67cce0-a51c-11e6-9598-0800200c9a66}");
  85. const DESC = "All-encompassing cert service that matches on a bitflag";
  86. // This needs to be an old-style class with a function constructor
  87. // and prototype assignment because... XPCOM. Any attempt at
  88. // modernisation will be met with cryptic error messages which will
  89. // make your life miserable.
  90. let service = function() {};
  91. service.prototype = {
  92. hasMatchingOverride: function (
  93. aHostName, aPort, aCert, aOverrideBits, aIsTemporary) {
  94. aIsTemporary.value = false;
  95. aOverrideBits.value =
  96. cert.Error.Untrusted | cert.Error.Mismatch | cert.Error.Time;
  97. return true;
  98. },
  99. QueryInterface: XPCOMUtils.generateQI([Ci.nsICertOverrideService]),
  100. };
  101. let factory = XPCOMUtils.generateSingletonFactory(service);
  102. return {
  103. register: function() {
  104. // make it possible to register certificate overrides for domains
  105. // that use HSTS or HPKP
  106. Preferences.set(HSTS_PRELOAD_LIST_PREF, false);
  107. Preferences.set(CERT_PINNING_ENFORCEMENT_PREF, 0);
  108. registrar.registerFactory(CID, DESC, CONTRACT_ID, factory);
  109. },
  110. unregister: function() {
  111. registrar.unregisterFactory(CID, factory);
  112. Preferences.reset(HSTS_PRELOAD_LIST_PREF);
  113. Preferences.reset(CERT_PINNING_ENFORCEMENT_PREF);
  114. // clear collected HSTS and HPKP state
  115. // through the site security service
  116. sss.clearAll();
  117. },
  118. };
  119. };