Bug 1359428 - Remove preference to select OneCRL update mechanism r=keeler,leplatrem,rhelmer
authorMark Goodwin <mgoodwin@mozilla.com>
Fri, 29 Sep 2017 10:47:27 +0100
changeset 383737 a889835e4003387f9689ec189a3ba6578091c4fb
parent 383736 0740897533945af306fdafd8cb701bee95fd5023
child 383738 f63df3b6606aed7d05721647507008771c097da3
push id32601
push userkwierso@gmail.com
push dateFri, 29 Sep 2017 21:45:53 +0000
treeherdermozilla-central@64c8107a2a13 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler, leplatrem, rhelmer
bugs1359428
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1359428 - Remove preference to select OneCRL update mechanism r=keeler,leplatrem,rhelmer MozReview-Commit-ID: A6CwZrIDmTn
modules/libpref/init/all.js
security/manager/ssl/CertBlocklist.cpp
security/manager/ssl/tests/unit/test_cert_blocklist.js
security/manager/ssl/tests/unit/test_ev_certs.js
services/common/blocklist-updater.js
services/common/tests/unit/test_blocklist_updater.js
toolkit/mozapps/extensions/nsBlocklistService.js
toolkit/mozapps/extensions/test/xpcshell/test_blocklist_regexp.js
--- 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);
 }