High firefox Logic Error 🔧 Commit mapped

Overview

High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionCryptographic issue in the Security Block-lists, Allow-lists, and other State component
ComponentSecurity/NSS
Bug ClassLogic Error
Tracker2084311
Fix commit2e02d8d098d0 (firefox) +84/-0
CISA KEVNot listed
CreditedWayne
Disclosed2026-10-21

Changed Functions

FunctionChangeNotes
add_task
security/manager/ssl/tests/unit/test_onecrl_loads_bundle.js
modified

Files Changed

  • security/manager/ssl/RemoteSecuritySettings.sys.mjs
  • security/manager/ssl/tests/unit/test_onecrl_loads_bundle.js
  • security/manager/ssl/tests/unit/xpcshell.toml
diff --git a/security/manager/ssl/RemoteSecuritySettings.sys.mjs b/security/manager/ssl/RemoteSecuritySettings.sys.mjs
index 0c896c80d53..3e5f9f35ae3 100644
--- a/security/manager/ssl/RemoteSecuritySettings.sys.mjs
+++ b/security/manager/ssl/RemoteSecuritySettings.sys.mjs
@@ -259,6 +259,28 @@ export var RemoteSecuritySettings = {
       signerName: SECURITY_STATE_SIGNER,
     });
     this.OneCRLBlocklistClient.on("sync", updateCertBlocklist);
+    // Ensure the bundled list of revocations is loaded.
+    this.OneCRLBlocklistClient.get()
+      .then(records => {
+        return updateCertBlocklist({
+          data: {
+            current: records,
+            created: records,
+            updated: [],
+            deleted: [],
+          },
+        });
+      })
+      .catch(e => {
+        lazy.log.error(e);
+      })
+      .finally(() => {
+        // Only used by tests, to know when the bundled list is in cert_storage.
+        Services.obs.notifyObservers(
+          null,
+          "remote-security-settings:onecrl-bundle-loaded"
+        );
+      });
 
     this.IntermediatePreloadsClient = new IntermediatePreloads();
 
diff --git a/security/manager/ssl/tests/unit/test_onecrl_loads_bundle.js b/security/manager/ssl/tests/unit/test_onecrl_loads_bundle.js
new file mode 100644
index 00000000000..8b641e86d64
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_onecrl_loads_bundle.js
@@ -0,0 +1,60 @@
+// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
+
+"use strict";
+
+// Checks that OneCRL loads its remote settings bundle at startup by ensuring
+// that each of the listed eMudhra intermediate certificates is revoked.
+
+do_get_profile();
+
+const { TestUtils } = ChromeUtils.importESModule(
+  "resource://testing-common/TestUtils.sys.mjs"
+);
+const { RemoteSecuritySettings } = ChromeUtils.importESModule(
+  "resource://gre/modules/psm/RemoteSecuritySettings.sys.mjs"
+);
+
+// DER encoding of the issuer name (CN=emSign Root TLS CA - G3), base64.
+const ISSUER =
+  "MFYxCzAJBgNVBAYTAklOMSUwIwYDVQQKDBxlTXVkaHJhIFRlY2hub2xvZ2llcyBMaW1pdGVkMSAwHgYDVQQDDBdlbVNpZ24gUm9vdCBUTFMgQ0EgLSBHMw==";
+
+// Serial numbers are the contents of the DER INTEGER, in hex.
+const SERIALS = {
+  "EM DV TLS CA - G3B": "00a4aee678f23362b4c0e460b772f214",
+  "EM OV TLS CA - G3B": "6cada367fb1c100088120ea202d568",
+  "EM EV TLS CA - G3B": "00c7c41efe92d825f05eae841a4a82c1",
+  "EM DV TLS CA - G3C": "588b2e3c2bb8cda13e1a1209254321",
+  "EM OV TLS CA - G3C": "296926c227a3a1526392b19482a504",
+  "EM EV TLS CA - G3C": "008009928a64107601af05fa2f19f109",
+};
+
+function base64ToBytes(base64) {
+  return Array.from(atob(base64), c => c.charCodeAt(0));
+}
+
+function hexToBytes(hex) {
+  return hex.match(/../g).map(byte => parseInt(byte, 16));
+}
+
+add_task(async function test_emsign_intermediates_are_revoked() {
+  let loaded = TestUtils.topicObserved(
+    "remote-security-settings:onecrl-bundle-loaded"
+  );
+  RemoteSecuritySettings.init();
+  await loaded;
+
+  let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService(
+    Ci.nsICertStorage
+  );
+  let issuer = base64ToBytes(ISSUER);
+
+  for (let [name, serial] of Object.entries(SERIALS)) {
+    Assert.equal(
+      certStorage.getRevocationState(issuer, hexToBytes(serial), [], []),
+      Ci.nsICertStorage.STATE_ENFORCE,
+      `${name} should be revoked`
+    );
+  }
+});
diff --git a/security/manager/ssl/tests/unit/xpcshell.toml b/security/manager/ssl/tests/unit/xpcshell.toml
index add143b9691..120ffa18b1d 100644
--- a/security/manager/ssl/tests/unit/xpcshell.toml
+++ b/security/manager/ssl/tests/unit/xpcshell.toml
@@ -304,6 +304,8 @@ run-sequentially = ["true"] # hardcoded ports
 ["test_ocsp_url.js"]
 run-sequentially = ["true"] # hardcoded ports
 
+["test_onecrl_loads_bundle.js"]
+
 ["test_oskeystore.js"]
 
 ["test_osreauthenticator.js"]
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/security/manager/ssl/tests/unit/test_onecrl_loads_bundle.js b/security/manager/ssl/tests/unit/test_onecrl_loads_bundle.js
new file mode 100644
index 00000000000..8b641e86d64
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_onecrl_loads_bundle.js
@@ -0,0 +1,60 @@
+// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
+
+"use strict";
+
+// Checks that OneCRL loads its remote settings bundle at startup by ensuring
+// that each of the listed eMudhra intermediate certificates is revoked.
+
+do_get_profile();
+
+const { TestUtils } = ChromeUtils.importESModule(
+  "resource://testing-common/TestUtils.sys.mjs"
+);
+const { RemoteSecuritySettings } = ChromeUtils.importESModule(
+  "resource://gre/modules/psm/RemoteSecuritySettings.sys.mjs"
+);
+
+// DER encoding of the issuer name (CN=emSign Root TLS CA - G3), base64.
+const ISSUER =
+  "MFYxCzAJBgNVBAYTAklOMSUwIwYDVQQKDBxlTXVkaHJhIFRlY2hub2xvZ2llcyBMaW1pdGVkMSAwHgYDVQQDDBdlbVNpZ24gUm9vdCBUTFMgQ0EgLSBHMw==";
+
+// Serial numbers are the contents of the DER INTEGER, in hex.
+const SERIALS = {
+  "EM DV TLS CA - G3B": "00a4aee678f23362b4c0e460b772f214",
+  "EM OV TLS CA - G3B": "6cada367fb1c100088120ea202d568",
+  "EM EV TLS CA - G3B": "00c7c41efe92d825f05eae841a4a82c1",
+  "EM DV TLS CA - G3C": "588b2e3c2bb8cda13e1a1209254321",
+  "EM OV TLS CA - G3C": "296926c227a3a1526392b19482a504",
+  "EM EV TLS CA - G3C": "008009928a64107601af05fa2f19f109",
+};
+
+function base64ToBytes(base64) {
+  return Array.from(atob(base64), c => c.charCodeAt(0));
+}
+
+function hexToBytes(hex) {
+  return hex.match(/../g).map(byte => parseInt(byte, 16));
+}
+
+add_task(async function test_emsign_intermediates_are_revoked() {
+  let loaded = TestUtils.topicObserved(
+    "remote-security-settings:onecrl-bundle-loaded"
+  );
+  RemoteSecuritySettings.init();
+  await loaded;
+
+  let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService(
+    Ci.nsICertStorage
+  );
+  let issuer = base64ToBytes(ISSUER);
+
+  for (let [name, serial] of Object.entries(SERIALS)) {
+    Assert.equal(
+      certStorage.getRevocationState(issuer, hexToBytes(serial), [], []),
+      Ci.nsICertStorage.STATE_ENFORCE,
+      `${name} should be revoked`
+    );
+  }
+});
diff --git a/security/manager/ssl/tests/unit/xpcshell.toml b/security/manager/ssl/tests/unit/xpcshell.toml
index add143b9691..120ffa18b1d 100644
--- a/security/manager/ssl/tests/unit/xpcshell.toml
+++ b/security/manager/ssl/tests/unit/xpcshell.toml
@@ -304,6 +304,8 @@ run-sequentially = ["true"] # hardcoded ports
 ["test_ocsp_url.js"]
 run-sequentially = ["true"] # hardcoded ports
 
+["test_onecrl_loads_bundle.js"]
+
 ["test_oskeystore.js"]
 
 ["test_osreauthenticator.js"]
Loading diff…