--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -2650,19 +2650,16 @@ pref("services.blocklist.gfx.checked", 0
// Controls whether signing should be enforced on signature-capable blocklist
// collections.
pref("services.blocklist.signing.enforced", true);
// Enable blocklists via the services settings mechanism
pref("services.blocklist.update_enabled", true);
-// Enable certificate blocklist updates via services settings
-pref("security.onecrl.via.amo", false);
-
// Modifier key prefs: default to Windows settings,
// menu access key = alt, accelerator key = control.
// Use 17 for Ctrl, 18 for Alt, 224 for Meta, 91 for Win, 0 for none. Mac settings in macprefs.js
pref("ui.key.accelKey", 17);
pref("ui.key.menuAccessKey", 18);
pref("ui.key.generalAccessKey", -1);
--- a/security/manager/ssl/CertBlocklist.cpp
+++ b/security/manager/ssl/CertBlocklist.cpp
@@ -32,24 +32,21 @@
NS_IMPL_ISUPPORTS(CertBlocklist, nsICertBlocklist)
using namespace mozilla;
using namespace mozilla::pkix;
#define PREF_BACKGROUND_UPDATE_TIMER "app.update.lastUpdateTime.blocklist-background-update-timer"
#define PREF_BLOCKLIST_ONECRL_CHECKED "services.blocklist.onecrl.checked"
#define PREF_MAX_STALENESS_IN_SECONDS "security.onecrl.maximum_staleness_in_seconds"
-#define PREF_ONECRL_VIA_AMO "security.onecrl.via.amo"
static LazyLogModule gCertBlockPRLog("CertBlock");
uint32_t CertBlocklist::sLastBlocklistUpdate = 0U;
-uint32_t CertBlocklist::sLastKintoUpdate = 0U;
uint32_t CertBlocklist::sMaxStaleness = 0U;
-bool CertBlocklist::sUseAMO = true;
CertBlocklistItem::CertBlocklistItem(const uint8_t* DNData,
size_t DNLength,
const uint8_t* otherData,
size_t otherLength,
CertBlocklistItemMechanism itemMechanism)
: mIsCurrent(false)
, mItemMechanism(itemMechanism)
@@ -135,25 +132,19 @@ CertBlocklist::CertBlocklist()
, mBackingFileIsInitialized(false)
, mBackingFile(nullptr)
{
}
CertBlocklist::~CertBlocklist()
{
Preferences::UnregisterCallback(CertBlocklist::PreferenceChanged,
- PREF_BACKGROUND_UPDATE_TIMER,
- this);
- Preferences::UnregisterCallback(CertBlocklist::PreferenceChanged,
PREF_MAX_STALENESS_IN_SECONDS,
this);
Preferences::UnregisterCallback(CertBlocklist::PreferenceChanged,
- PREF_ONECRL_VIA_AMO,
- this);
- Preferences::UnregisterCallback(CertBlocklist::PreferenceChanged,
PREF_BLOCKLIST_ONECRL_CHECKED,
this);
}
nsresult
CertBlocklist::Init()
{
MOZ_LOG(gCertBlockPRLog, LogLevel::Debug, ("CertBlocklist::Init"));
@@ -161,36 +152,23 @@ CertBlocklist::Init()
// Init must be on main thread for getting the profile directory
if (!NS_IsMainThread()) {
MOZ_LOG(gCertBlockPRLog, LogLevel::Debug,
("CertBlocklist::Init - called off main thread"));
return NS_ERROR_NOT_SAME_THREAD;
}
// Register preference callbacks
- nsresult rv =
- Preferences::RegisterCallbackAndCall(CertBlocklist::PreferenceChanged,
- PREF_BACKGROUND_UPDATE_TIMER,
- this);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = Preferences::RegisterCallbackAndCall(CertBlocklist::PreferenceChanged,
+ nsresult rv = Preferences::RegisterCallbackAndCall(CertBlocklist::PreferenceChanged,
PREF_MAX_STALENESS_IN_SECONDS,
this);
if (NS_FAILED(rv)) {
return rv;
}
rv = Preferences::RegisterCallbackAndCall(CertBlocklist::PreferenceChanged,
- PREF_ONECRL_VIA_AMO,
- this);
- if (NS_FAILED(rv)) {
- return rv;
- }
- rv = Preferences::RegisterCallbackAndCall(CertBlocklist::PreferenceChanged,
PREF_BLOCKLIST_ONECRL_CHECKED,
this);
if (NS_FAILED(rv)) {
return rv;
}
// Get the profile directory
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
@@ -626,23 +604,22 @@ CertBlocklist::IsCertRevoked(const uint8
NS_IMETHODIMP
CertBlocklist::IsBlocklistFresh(bool* _retval)
{
MutexAutoLock lock(mMutex);
*_retval = false;
uint32_t now = uint32_t(PR_Now() / PR_USEC_PER_SEC);
- uint32_t lastUpdate = sUseAMO ? sLastBlocklistUpdate : sLastKintoUpdate;
MOZ_LOG(gCertBlockPRLog, LogLevel::Warning,
- ("CertBlocklist::IsBlocklistFresh using AMO? %i lastUpdate is %i",
- sUseAMO, lastUpdate));
+ ("CertBlocklist::IsBlocklistFresh ? lastUpdate is %i",
+ sLastBlocklistUpdate));
- if (now > lastUpdate) {
- int64_t interval = now - lastUpdate;
+ if (now > sLastBlocklistUpdate) {
+ int64_t interval = now - sLastBlocklistUpdate;
MOZ_LOG(gCertBlockPRLog, LogLevel::Warning,
("CertBlocklist::IsBlocklistFresh we're after the last BlocklistUpdate "
"interval is %" PRId64 ", staleness %u", interval, sMaxStaleness));
*_retval = sMaxStaleness > interval;
}
MOZ_LOG(gCertBlockPRLog, LogLevel::Warning,
("CertBlocklist::IsBlocklistFresh ? %s", *_retval ? "true" : "false"));
return NS_OK;
@@ -654,21 +631,16 @@ void
CertBlocklist::PreferenceChanged(const char* aPref, void* aClosure)
{
auto blocklist = static_cast<CertBlocklist*>(aClosure);
MutexAutoLock lock(blocklist->mMutex);
MOZ_LOG(gCertBlockPRLog, LogLevel::Warning,
("CertBlocklist::PreferenceChanged %s changed", aPref));
- if (strcmp(aPref, PREF_BACKGROUND_UPDATE_TIMER) == 0) {
- sLastBlocklistUpdate = Preferences::GetUint(PREF_BACKGROUND_UPDATE_TIMER,
+ if (strcmp(aPref, PREF_BLOCKLIST_ONECRL_CHECKED) == 0) {
+ sLastBlocklistUpdate = Preferences::GetUint(PREF_BLOCKLIST_ONECRL_CHECKED,
uint32_t(0));
- } else if (strcmp(aPref, PREF_BLOCKLIST_ONECRL_CHECKED) == 0) {
- sLastKintoUpdate = Preferences::GetUint(PREF_BLOCKLIST_ONECRL_CHECKED,
- uint32_t(0));
} else if (strcmp(aPref, PREF_MAX_STALENESS_IN_SECONDS) == 0) {
sMaxStaleness = Preferences::GetUint(PREF_MAX_STALENESS_IN_SECONDS,
uint32_t(0));
- } else if (strcmp(aPref, PREF_ONECRL_VIA_AMO) == 0) {
- sUseAMO = Preferences::GetBool(PREF_ONECRL_VIA_AMO, true);
}
}
--- a/security/manager/ssl/tests/unit/test_cert_blocklist.js
+++ b/security/manager/ssl/tests/unit/test_cert_blocklist.js
@@ -1,22 +1,24 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* 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";
// This test checks a number of things:
// * it ensures that data loaded from revocations.txt on startup is present
-// * it ensures that certItems in blocklist.xml are persisted correctly
+// * it ensures that data served from OneCRL are persisted correctly
// * it ensures that items in the CertBlocklist are seen as revoked by the
// cert verifier
// * it does a sanity check to ensure other cert verifier behavior is
// unmodified
+const { setTimeout } = Cu.import("resource://gre/modules/Timer.jsm", {});
+
// First, we need to setup appInfo for the blocklist service to work
var id = "xpcshell@tests.mozilla.org";
var appName = "XPCShell";
var version = "1";
var platformVersion = "1.9.2";
Cu.import("resource://testing-common/AppInfo.jsm", this);
/* global updateAppInfo:false */ // Imported via AppInfo.jsm.
updateAppInfo({
@@ -26,104 +28,132 @@ updateAppInfo({
platformVersion: platformVersion ? platformVersion : "1.0",
crashReporter: true,
});
// we need to ensure we setup revocation data before certDB, or we'll start with
// no revocation.txt in the profile
var gProfile = do_get_profile();
-// Write out an empty blocklist.xml file to the profile to ensure nothing
-// is blocklisted by default
-var blockFile = gProfile.clone();
-blockFile.append("blocklist.xml");
-var stream = Cc["@mozilla.org/network/file-output-stream;1"]
- .createInstance(Ci.nsIFileOutputStream);
-stream.init(blockFile,
- FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE,
- FileUtils.PERMS_FILE, 0);
-
-var data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
- "<blocklist xmlns=\"http://www.mozilla.org/2006/addons-blocklist\">\n" +
- "</blocklist>\n";
-stream.write(data, data.length);
-stream.close();
-
-const PREF_BLOCKLIST_UPDATE_ENABLED = "services.blocklist.update_enabled";
-const PREF_ONECRL_VIA_AMO = "security.onecrl.via.amo";
-
var gRevocations = gProfile.clone();
gRevocations.append("revocations.txt");
if (!gRevocations.exists()) {
let existing = do_get_file("test_onecrl/sample_revocations.txt", false);
existing.copyTo(gProfile, "revocations.txt");
}
var certDB = Cc["@mozilla.org/security/x509certdb;1"]
.getService(Ci.nsIX509CertDB);
-// set up a test server to serve the blocklist.xml
+// set up a test server to serve the kinto views.
var testserver = new HttpServer();
-var initialBlocklist = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
- "<blocklist xmlns=\"http://www.mozilla.org/2006/addons-blocklist\">" +
- // test with some bad data ...
- "<certItems><certItem issuerName='Some nonsense in issuer'>" +
- "<serialNumber>AkHVNA==</serialNumber>" +
- "</certItem><certItem issuerName='MA0xCzAJBgNVBAMMAmNh'>" +
- "<serialNumber>some nonsense in serial</serialNumber>" +
- "</certItem><certItem issuerName='some nonsense in both issuer'>" +
- "<serialNumber>and serial</serialNumber></certItem>" +
- // some mixed
- // In this case, the issuer name and the valid serialNumber correspond
- // to test-int.pem in bad_certs/
- "<certItem issuerName='MBIxEDAOBgNVBAMMB1Rlc3QgQ0E='>" +
- "<serialNumber>oops! more nonsense.</serialNumber>" +
- "<serialNumber>BVio/iQ21GCi2iUven8oJ/gae74=</serialNumber></certItem>" +
- // ... and some good
- // In this case, the issuer name and the valid serialNumber correspond
- // to other-test-ca.pem in bad_certs/ (for testing root revocation)
- "<certItem issuerName='MBgxFjAUBgNVBAMMDU90aGVyIHRlc3QgQ0E='>" +
- "<serialNumber>exJUIJpq50jgqOwQluhVrAzTF74=</serialNumber></certItem>" +
- // This item corresponds to an entry in sample_revocations.txt where:
- // isser name is "another imaginary issuer" base-64 encoded, and
- // serialNumbers are:
- // "serial2." base-64 encoded, and
- // "another serial." base-64 encoded
- // We need this to ensure that existing items are retained if they're
- // also in the blocklist
- "<certItem issuerName='YW5vdGhlciBpbWFnaW5hcnkgaXNzdWVy'>" +
- "<serialNumber>c2VyaWFsMi4=</serialNumber>" +
- "<serialNumber>YW5vdGhlciBzZXJpYWwu</serialNumber></certItem>" +
- // This item revokes same-issuer-ee.pem by subject and pubKeyHash.
- "<certItem subject='MCIxIDAeBgNVBAMMF0Fub3RoZXIgVGVzdCBFbmQtZW50aXR5'" +
- " pubKeyHash='VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8='>" +
- "</certItem></certItems></blocklist>";
-var updatedBlocklist = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
- "<blocklist xmlns=\"http://www.mozilla.org/2006/addons-blocklist\">" +
- "<certItems>" +
- "<certItem issuerName='something new in both the issuer'>" +
- "<serialNumber>and the serial number</serialNumber></certItem>" +
- "</certItems></blocklist>";
-
+const kintoHelloViewJSON = `{"settings":{"batch_max_requests":25}}`;
+const kintoChangesJSON = `{
+ "data": [
+ {
+ "host": "firefox.settings.services.mozilla.com",
+ "id": "3ace9d8e-00b5-a353-7fd5-1f081ff482ba",
+ "last_modified": 100000000000000000001,
+ "bucket": "blocklists",
+ "collection": "certificates"
+ }
+ ]
+}`;
+const certMetadataJSON = `{"data": {}}`;
+const certBlocklistJSON = `{
+ "data": [` +
+ // test with some bad data ...
+ ` {
+ "id": "1",
+ "last_modified": 100000000000000000001,
+ "issuerName": "Some nonsense in issuer",
+ "serialNumber": "AkHVNA=="
+ },
+ {
+ "id": "2",
+ "last_modified": 100000000000000000002,
+ "issuerName": "MA0xCzAJBgNVBAMMAmNh",
+ "serialNumber": "some nonsense in serial"
+ },
+ {
+ "id": "3",
+ "last_modified": 100000000000000000003,
+ "issuerName": "and serial",
+ "serialNumber": "some nonsense in both issuer"
+ },` +
+ // some mixed
+ // In these case, the issuer name and the valid serialNumber correspond
+ // to test-int.pem in bad_certs/
+ ` {
+ "id": "4",
+ "last_modified": 100000000000000000004,
+ "issuerName": "MBIxEDAOBgNVBAMMB1Rlc3QgQ0E=",
+ "serialNumber": "oops! more nonsense."
+ },` +
+ ` {
+ "id": "5",
+ "last_modified": 100000000000000000004,
+ "issuerName": "MBIxEDAOBgNVBAMMB1Rlc3QgQ0E=",
+ "serialNumber": "BVio/iQ21GCi2iUven8oJ/gae74="
+ },` +
+ // ... and some good
+ // In this case, the issuer name and the valid serialNumber correspond
+ // to other-test-ca.pem in bad_certs/ (for testing root revocation)
+ ` {
+ "id": "6",
+ "last_modified": 100000000000000000005,
+ "issuerName": "MBgxFjAUBgNVBAMMDU90aGVyIHRlc3QgQ0E=",
+ "serialNumber": "exJUIJpq50jgqOwQluhVrAzTF74="
+ },` +
+ // These items correspond to an entry in sample_revocations.txt where:
+ // isser name is "another imaginary issuer" base-64 encoded, and
+ // serialNumbers are:
+ // "serial2." base-64 encoded, and
+ // "another serial." base-64 encoded
+ // We need this to ensure that existing items are retained if they're
+ // also in the blocklist
+ ` {
+ "id": "7",
+ "last_modified": 100000000000000000006,
+ "issuerName": "YW5vdGhlciBpbWFnaW5hcnkgaXNzdWVy",
+ "serialNumber": "c2VyaWFsMi4="
+ },` +
+ ` {
+ "id": "8",
+ "last_modified": 100000000000000000006,
+ "issuerName": "YW5vdGhlciBpbWFnaW5hcnkgaXNzdWVy",
+ "serialNumber": "YW5vdGhlciBzZXJpYWwu"
+ },` +
+ // This item revokes same-issuer-ee.pem by subject and pubKeyHash.
+ ` {
+ "id": "9",
+ "last_modified": 100000000000000000007,
+ "subject": "MCIxIDAeBgNVBAMMF0Fub3RoZXIgVGVzdCBFbmQtZW50aXR5",
+ "pubKeyHash": "VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8="
+ }
+ ]
+}`;
-var blocklists = {
- "/initialBlocklist/": initialBlocklist,
- "/updatedBlocklist/": updatedBlocklist
-};
-
-function serveResponse(request, response) {
- do_print("Serving for path " + request.path + "\n");
- response.write(blocklists[request.path]);
+function serveResponse(body) {
+ return (req, response) => {
+ response.setStatusLine(null, 200, "OK");
+ response.write(body);
+ };
}
-for (var path in blocklists) {
- testserver.registerPathHandler(path, serveResponse);
-}
+testserver.registerPathHandler("/v1/",
+ serveResponse(kintoHelloViewJSON));
+testserver.registerPathHandler("/v1/buckets/monitor/collections/changes/records",
+ serveResponse(kintoChangesJSON));
+testserver.registerPathHandler("/v1/buckets/blocklists/collections/certificates",
+ serveResponse(certMetadataJSON));
+testserver.registerPathHandler("/v1/buckets/blocklists/collections/certificates/records",
+ serveResponse(certBlocklistJSON));
// start the test server
testserver.start(-1);
var port = testserver.identity.primaryPort;
// Setup the addonManager
var addonManager = Cc["@mozilla.org/addons/integration;1"]
.getService(Ci.nsIObserver)
@@ -167,31 +197,38 @@ function test_is_revoked(certList, issue
serial,
serialString ? serialString.length : 0,
subject,
subjectString ? subjectString.length : 0,
pubKey,
pubKeyString ? pubKeyString.length : 0);
}
-function fetch_blocklist(blocklistPath) {
- do_print("path is " + blocklistPath + "\n");
- let certblockObserver = {
- observe(aSubject, aTopic, aData) {
- Services.obs.removeObserver(this, "blocklist-updated");
- run_next_test();
- }
- };
-
- Services.obs.addObserver(certblockObserver, "blocklist-updated");
+function fetch_blocklist() {
+ Services.prefs.setBoolPref("services.blocklist.load_dump", false);
+ Services.prefs.setBoolPref("services.blocklist.signing.enforced", false);
+ Services.prefs.setCharPref("services.settings.server",
+ `http://localhost:${port}/v1`);
Services.prefs.setCharPref("extensions.blocklist.url",
- `http://localhost:${port}/${blocklistPath}`);
+ `http://localhost:${port}/blocklist.xml`);
let blocklist = Cc["@mozilla.org/extensions/blocklist;1"]
.getService(Ci.nsITimerCallback);
- blocklist.notify(null);
+
+ return new Promise((resolve) => {
+ let certblockObserver = {
+ observe(aSubject, aTopic, aData) {
+ Services.obs.removeObserver(this, "blocklist-updater-versions-checked");
+ resolve();
+ }
+ };
+
+ Services.obs.addObserver(certblockObserver, "blocklist-updater-versions-checked");
+
+ blocklist.notify(null);
+ });
}
function* generate_revocations_txt_lines() {
let profile = do_get_profile();
let revocations = profile.clone();
revocations.append("revocations.txt");
ok(revocations.exists(), "the revocations file should exist");
let inputStream = Cc["@mozilla.org/network/file-input-stream;1"]
@@ -259,29 +296,25 @@ function run_test() {
load_cert("test-int", ",,");
load_cert("other-test-ca", "CTu,CTu,CTu");
let certList = Cc["@mozilla.org/security/certblocklist;1"]
.getService(Ci.nsICertBlocklist);
let expected = { "MCIxIDAeBgNVBAMMF0Fub3RoZXIgVGVzdCBFbmQtZW50aXR5":
{ "\tVCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8=": true },
+ "MBgxFjAUBgNVBAMMDU90aGVyIHRlc3QgQ0E=":
+ { " exJUIJpq50jgqOwQluhVrAzTF74=": true},
"MBIxEDAOBgNVBAMMB1Rlc3QgQ0E=":
- { " BVio/iQ21GCi2iUven8oJ/gae74=": true },
- "MBgxFjAUBgNVBAMMDU90aGVyIHRlc3QgQ0E=":
- { " exJUIJpq50jgqOwQluhVrAzTF74=": true },
+ { " BVio/iQ21GCi2iUven8oJ/gae74=": true},
"YW5vdGhlciBpbWFnaW5hcnkgaXNzdWVy":
{ " YW5vdGhlciBzZXJpYWwu": true,
" c2VyaWFsMi4=": true }
};
- // This test assumes OneCRL updates via AMO
- Services.prefs.setBoolPref(PREF_BLOCKLIST_UPDATE_ENABLED, false);
- Services.prefs.setBoolPref(PREF_ONECRL_VIA_AMO, true);
-
add_test(function () {
// check some existing items in revocations.txt are blocked. Since the
// CertBlocklistItems don't know about the data they contain, we can use
// arbitrary data (not necessarily DER) to test if items are revoked or not.
// This test corresponds to:
// issuer: c29tZSBpbWFnaW5hcnkgaXNzdWVy
// serial: c2VyaWFsLg==
ok(test_is_revoked(certList, "some imaginary issuer", "serial."),
@@ -315,24 +348,24 @@ function run_test() {
// Check the cert validates before we load the blocklist
file = "test_onecrl/same-issuer-ee.pem";
verify_cert(file, PRErrorCodeSuccess);
run_next_test();
});
// blocklist load is async so we must use add_test from here
- add_test(function() {
- fetch_blocklist("initialBlocklist/");
+ add_task(function* () {
+ yield fetch_blocklist();
});
add_test(function() {
// The blocklist will be loaded now. Let's check the data is sane.
// In particular, we should still have the revoked issuer / serial pair
- // that was in both revocations.txt and the blocklist.xml
+ // that was in both revocations.txt and the blocklist.
ok(test_is_revoked(certList, "another imaginary issuer", "serial2."),
"issuer / serial pair should be blocked");
// Check that both serials in the certItem with multiple serials were read
// properly
ok(test_is_revoked(certList, "another imaginary issuer", "serial2."),
"issuer / serial pair should be blocked");
ok(test_is_revoked(certList, "another imaginary issuer", "another serial."),
@@ -378,23 +411,16 @@ function run_test() {
certList.saveEntries();
let newModified = gRevocations.lastModifiedTime;
equal(lastModified, newModified,
"saveEntries with no modifications should not update the backing file");
run_next_test();
});
- // disable AMO cert blocklist - and check blocklist.xml changes do not
- // affect the data stored.
- add_test(function() {
- Services.prefs.setBoolPref("security.onecrl.via.amo", false);
- fetch_blocklist("updatedBlocklist/");
- });
-
add_test(function() {
// Check the blocklist entry has not changed
check_revocations_txt_contents(expected);
run_next_test();
});
run_next_test();
}
--- a/security/manager/ssl/tests/unit/test_ev_certs.js
+++ b/security/manager/ssl/tests/unit/test_ev_certs.js
@@ -274,48 +274,43 @@ add_task(async function oneCRLTests() {
Services.prefs.setIntPref(
"app.update.lastUpdateTime.blocklist-background-update-timer",
Math.floor(Date.now() / 1000) - 108080);
await ensureVerifiesAsEV("anyPolicy-int-path");
await ensureVerifiesAsDV("no-ocsp-int-path");
await ensureVerifiesAsEV("test-oid-path");
clearOCSPCache();
- // test that setting "security.onecrl.via.amo" results in the correct
- // OCSP behavior when services.blocklist.onecrl.checked is in the distant past
- // and blacklist-background-update-timer is recent
- Services.prefs.setBoolPref("security.onecrl.via.amo", false);
+ // test the OCSP behavior when services.blocklist.onecrl.checked is in the
+ // distant past and blacklist-background-update-timer is recent
// enable OneCRL OCSP skipping - allow staleness of up to 30 hours
Services.prefs.setIntPref("security.onecrl.maximum_staleness_in_seconds",
108000);
// set the blocklist-background-update-timer value to the recent past
// (services.blocklist.onecrl.checked defaults to 0)
Services.prefs.setIntPref(
"app.update.lastUpdateTime.blocklist-background-update-timer",
Math.floor(Date.now() / 1000) - 1);
await ensureVerifiesAsEV("anyPolicy-int-path");
await ensureVerifiesAsDV("no-ocsp-int-path");
await ensureVerifiesAsEV("test-oid-path");
clearOCSPCache();
- // test that setting "security.onecrl.via.amo" results in the correct
- // OCSP behavior when services.blocklist.onecrl.checked is recent
- Services.prefs.setBoolPref("security.onecrl.via.amo", false);
+ // test the OCSP behavior when services.blocklist.onecrl.checked is recent
// enable OneCRL OCSP skipping - allow staleness of up to 30 hours
Services.prefs.setIntPref("security.onecrl.maximum_staleness_in_seconds",
108000);
// now set services.blocklist.onecrl.checked to a recent value
Services.prefs.setIntPref("services.blocklist.onecrl.checked",
Math.floor(Date.now() / 1000) - 1);
await ensureOneCRLSkipsOCSPForIntermediates("anyPolicy-int-path");
await ensureOneCRLSkipsOCSPForIntermediates("no-ocsp-int-path");
await ensureOneCRLSkipsOCSPForIntermediates("test-oid-path");
- Services.prefs.clearUserPref("security.onecrl.via.amo");
Services.prefs.clearUserPref("security.onecrl.maximum_staleness_in_seconds");
Services.prefs.clearUserPref("services.blocklist.onecrl.checked");
Services.prefs.clearUserPref(
"app.update.lastUpdateTime.blocklist-background-update-timer");
});
// Prime the OCSP cache and then ensure that we can validate certificates as EV
// without hitting the network. There's two cases here: one where we simply
--- a/services/common/blocklist-updater.js
+++ b/services/common/blocklist-updater.js
@@ -13,16 +13,17 @@ XPCOMUtils.defineLazyModuleGetter(this,
"resource://services-common/uptake-telemetry.js");
const PREF_SETTINGS_SERVER = "services.settings.server";
const PREF_SETTINGS_SERVER_BACKOFF = "services.settings.server.backoff";
const PREF_BLOCKLIST_CHANGES_PATH = "services.blocklist.changes.path";
const PREF_BLOCKLIST_LAST_UPDATE = "services.blocklist.last_update_seconds";
const PREF_BLOCKLIST_LAST_ETAG = "services.blocklist.last_etag";
const PREF_BLOCKLIST_CLOCK_SKEW_SECONDS = "services.blocklist.clock_skew_seconds";
+const PREF_BLOCKLIST_LOAD_DUMP = "services.blocklist.load_dump";
// Telemetry update source identifier.
const TELEMETRY_HISTOGRAM_KEY = "settings-changes-monitoring";
XPCOMUtils.defineLazyGetter(this, "gBlocklistClients", function() {
const BlocklistClients = Cu.import("resource://services-common/blocklist-clients.js", {});
return {
@@ -172,9 +173,11 @@ this.checkVersions = async function() {
// cause the promise to reject by throwing the first observed error
throw firstError;
}
// Save current Etag for next poll.
if (currentEtag) {
Services.prefs.setCharPref(PREF_BLOCKLIST_LAST_ETAG, currentEtag);
}
+
+ Services.obs.notifyObservers(null, "blocklist-updater-versions-checked");
};
--- a/services/common/tests/unit/test_blocklist_updater.js
+++ b/services/common/tests/unit/test_blocklist_updater.js
@@ -66,18 +66,32 @@ add_task(async function test_check_maybe
maybeSync(lastModified, serverTime) {
do_check_eq(lastModified, 1000);
do_check_eq(serverTime, 2000);
}
});
const startHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY);
+ let notificationObserved = false;
+
+ // Ensure that the blocklist-updater-versions-checked notification works
+ let certblockObserver = {
+ observe(aSubject, aTopic, aData) {
+ Services.obs.removeObserver(this, "blocklist-updater-versions-checked");
+ notificationObserved = true;
+ }
+ };
+
+ Services.obs.addObserver(certblockObserver, "blocklist-updater-versions-checked");
+
await updater.checkVersions();
+ do_check_true(notificationObserved, "a notification should have been observed");
+
// check the last_update is updated
do_check_eq(Services.prefs.getIntPref(PREF_LAST_UPDATE), 2);
// How does the clock difference look?
let endTime = Date.now();
let clockDifference = Services.prefs.getIntPref(PREF_CLOCK_SKEW_SECONDS);
// we previously set the serverTime to 2 (seconds past epoch)
do_check_true(clockDifference <= endTime / 1000
@@ -105,23 +119,26 @@ add_task(async function test_check_maybe
code: 503,
errno: 999,
error: "Service Unavailable",
}));
response.setStatusLine(null, 503, "Service Unavailable");
}
server.registerPathHandler(changesPath, simulateErrorResponse);
- // checkVersions() fails with adequate error.
+ // checkVersions() fails with adequate error and no notification.
let error;
+ notificationObserved = false;
+ Services.obs.addObserver(certblockObserver, "blocklist-updater-versions-checked");
try {
await updater.checkVersions();
} catch (e) {
error = e;
}
+ do_check_false(notificationObserved, "a notification should not have been observed");
do_check_true(/Polling for changes failed/.test(error.message));
// When an error occurs, last update was not overwritten (see Date header above).
do_check_eq(Services.prefs.getIntPref(PREF_LAST_UPDATE), 2);
// check negative clock skew times
// set to a time in the future
server.registerPathHandler(changesPath, handleResponse.bind(null, Date.now() + 10000));
--- a/toolkit/mozapps/extensions/nsBlocklistService.js
+++ b/toolkit/mozapps/extensions/nsBlocklistService.js
@@ -46,17 +46,16 @@ const FILE_BLOCKLIST =
const PREF_BLOCKLIST_LASTUPDATETIME = "app.update.lastUpdateTime.blocklist-background-update-timer";
const PREF_BLOCKLIST_URL = "extensions.blocklist.url";
const PREF_BLOCKLIST_ITEM_URL = "extensions.blocklist.itemURL";
const PREF_BLOCKLIST_ENABLED = "extensions.blocklist.enabled";
const PREF_BLOCKLIST_LEVEL = "extensions.blocklist.level";
const PREF_BLOCKLIST_PINGCOUNTTOTAL = "extensions.blocklist.pingCountTotal";
const PREF_BLOCKLIST_PINGCOUNTVERSION = "extensions.blocklist.pingCountVersion";
const PREF_BLOCKLIST_SUPPRESSUI = "extensions.blocklist.suppressUI";
-const PREF_ONECRL_VIA_AMO = "security.onecrl.via.amo";
const PREF_BLOCKLIST_UPDATE_ENABLED = "services.blocklist.update_enabled";
const PREF_APP_DISTRIBUTION = "distribution.id";
const PREF_APP_DISTRIBUTION_VERSION = "distribution.version";
const PREF_EM_LOGGING_ENABLED = "extensions.logging.enabled";
const XMLURI_BLOCKLIST = "http://www.mozilla.org/2006/addons-blocklist";
const XMLURI_PARSE_ERROR = "http://www.mozilla.org/newlayout/xml/parsererror.xml"
const URI_BLOCKLIST_DIALOG = "chrome://mozapps/content/extensions/blocklist.xul"
const DEFAULT_SEVERITY = 3;
@@ -76,20 +75,16 @@ var gBlocklistLevel = DEFAULT_LEVEL;
XPCOMUtils.defineLazyServiceGetter(this, "gConsole",
"@mozilla.org/consoleservice;1",
"nsIConsoleService");
XPCOMUtils.defineLazyServiceGetter(this, "gVersionChecker",
"@mozilla.org/xpcom/version-comparator;1",
"nsIVersionComparator");
-XPCOMUtils.defineLazyServiceGetter(this, "gCertBlocklistService",
- "@mozilla.org/security/certblocklist;1",
- "nsICertBlocklist");
-
XPCOMUtils.defineLazyGetter(this, "gPref", function() {
return Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService).
QueryInterface(Ci.nsIPrefBranch);
});
// From appinfo in Services.jsm. It is not possible to use the one in
// Services.jsm since it will not successfully QueryInterface nsIXULAppInfo in
// xpcshell tests due to other code calling Services.appinfo before the
@@ -905,49 +900,38 @@ Blocklist.prototype = {
var doc = parser.parseFromString(text, "text/xml");
if (doc.documentElement.namespaceURI != XMLURI_BLOCKLIST) {
LOG("Blocklist::_loadBlocklistFromFile: aborting due to incorrect " +
"XML Namespace.\r\nExpected: " + XMLURI_BLOCKLIST + "\r\n" +
"Received: " + doc.documentElement.namespaceURI);
return;
}
- var populateCertBlocklist = getPref("getBoolPref", PREF_ONECRL_VIA_AMO, true);
-
var childNodes = doc.documentElement.childNodes;
for (let element of childNodes) {
if (!(element instanceof Ci.nsIDOMElement))
continue;
switch (element.localName) {
case "emItems":
this._addonEntries = this._processItemNodes(element.childNodes, "emItem",
this._handleEmItemNode);
break;
case "pluginItems":
this._pluginEntries = this._processItemNodes(element.childNodes, "pluginItem",
this._handlePluginItemNode);
break;
- case "certItems":
- if (populateCertBlocklist) {
- this._processItemNodes(element.childNodes, "certItem",
- this._handleCertItemNode.bind(this));
- }
- break;
case "gfxItems":
// Parse as simple list of objects.
this._gfxEntries = this._processItemNodes(element.childNodes, "gfxBlacklistEntry",
this._handleGfxBlacklistNode);
break;
default:
LOG("Blocklist::_loadBlocklistFromString: ignored entries " + element.localName);
}
}
- if (populateCertBlocklist) {
- gCertBlocklistService.saveEntries();
- }
if (this._gfxEntries.length > 0) {
this._notifyObserversBlocklistGFX();
}
} catch (e) {
LOG("Blocklist::_loadBlocklistFromFile: Error constructing blocklist " + e);
}
},
@@ -959,43 +943,16 @@ Blocklist.prototype = {
blocklistElement.localName != itemName)
continue;
handler(blocklistElement, result);
}
return result;
},
- _handleCertItemNode(blocklistElement, result) {
- let issuer = blocklistElement.getAttribute("issuerName");
- if (issuer) {
- for (let snElement of blocklistElement.children) {
- try {
- gCertBlocklistService.revokeCertByIssuerAndSerial(issuer, snElement.textContent);
- } catch (e) {
- // we want to keep trying other elements since missing all items
- // is worse than missing one
- LOG("Blocklist::_handleCertItemNode: Error adding revoked cert by Issuer and Serial" + e);
- }
- }
- return;
- }
-
- let pubKeyHash = blocklistElement.getAttribute("pubKeyHash");
- let subject = blocklistElement.getAttribute("subject");
-
- if (pubKeyHash && subject) {
- try {
- gCertBlocklistService.revokeCertBySubjectAndPubKey(subject, pubKeyHash);
- } catch (e) {
- LOG("Blocklist::_handleCertItemNode: Error adding revoked cert by Subject and PubKey" + e);
- }
- }
- },
-
_handleEmItemNode(blocklistElement, result) {
if (!matchesOSABI(blocklistElement))
return;
let blockEntry = {
versions: [],
prefs: [],
blockID: null,
--- a/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_regexp.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_regexp.js
@@ -59,22 +59,18 @@ function load_blocklist(aFile, aCallback
do_execute_soon(aCallback);
}, "blocklist-updated");
Services.prefs.setCharPref("extensions.blocklist.url", "http://localhost:" +
gPort + "/data/" + aFile);
var blocklist = Cc["@mozilla.org/extensions/blocklist;1"].
getService(Ci.nsITimerCallback);
- // if we're not using the blocklist.xml for certificate blocklist state,
- // ensure that kinto update is enabled
- if (!Services.prefs.getBoolPref("security.onecrl.via.amo")) {
- ok(Services.prefs.getBoolPref("services.blocklist.update_enabled"),
- "Kinto update should be enabled");
- }
+ ok(Services.prefs.getBoolPref("services.blocklist.update_enabled"),
+ "Kinto update should be enabled");
blocklist.notify(null);
}
function end_test() {
testserver.stop(do_test_finished);
}