Bug 1546912 - Dedicated signature tests for Remote Settings r=glasserc
authorMathieu Leplatre <mathieu@mozilla.com>
Mon, 13 May 2019 17:04:26 +0000
changeset 532648 ebef76ce78f70c8f4a3b26ce0dbf7d3e556eba8d
parent 532647 bfa4ce8a0ef6b464e349f252b1f8e46cbf9bba11
child 532649 13d43fe66caea88e8923b7329ec194b26cfa2481
push id11270
push userrgurzau@mozilla.com
push dateWed, 15 May 2019 15:07:19 +0000
treeherdermozilla-beta@571bc76da583 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglasserc
bugs1546912
milestone68.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 1546912 - Dedicated signature tests for Remote Settings r=glasserc Differential Revision: https://phabricator.services.mozilla.com/D30650
services/common/tests/unit/moz.build
services/common/tests/unit/test_blocklist_signatures.js
services/common/tests/unit/test_blocklist_signatures/collection_signing_ee.pem.certspec
services/common/tests/unit/test_blocklist_signatures/collection_signing_int.pem.certspec
services/common/tests/unit/test_blocklist_signatures/collection_signing_root.pem.certspec
services/common/tests/unit/test_blocklist_signatures/moz.build
services/common/tests/unit/xpcshell.ini
services/settings/moz.build
services/settings/test/moz.build
services/settings/test/unit/moz.build
services/settings/test/unit/test_remote_settings_signatures.js
services/settings/test/unit/test_remote_settings_signatures/collection_signing_ee.pem.certspec
services/settings/test/unit/test_remote_settings_signatures/collection_signing_int.pem.certspec
services/settings/test/unit/test_remote_settings_signatures/collection_signing_root.pem.certspec
services/settings/test/unit/test_remote_settings_signatures/moz.build
services/settings/test/unit/xpcshell.ini
--- a/services/common/tests/unit/moz.build
+++ b/services/common/tests/unit/moz.build
@@ -1,9 +1,5 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
-
-TEST_DIRS += [
-    'test_blocklist_signatures'
-]
--- a/services/common/tests/unit/xpcshell.ini
+++ b/services/common/tests/unit/xpcshell.ini
@@ -1,29 +1,26 @@
 [DEFAULT]
 head = head_global.js head_helpers.js head_http.js
 firefox-appdir = browser
 support-files =
   test_storage_adapter/**
-  test_blocklist_signatures/**
 
 # Test load modules first so syntax failures are caught early.
 [test_load_modules.js]
 
 [test_blocklist_onecrl.js]
 # Skip signature tests for Thunderbird (Bug 1341983).
 skip-if = appname == "thunderbird"
 tags = blocklist
 [test_blocklist_pinning.js]
 tags = blocklist
 
 [test_kinto.js]
 tags = blocklist
-[test_blocklist_signatures.js]
-tags = remote-settings blocklist
 [test_storage_adapter.js]
 tags = remote-settingsblocklist
 [test_storage_adapter_shutdown.js]
 tags = remote-settings blocklist
 
 [test_utils_atob.js]
 [test_utils_convert_string.js]
 [test_utils_dateprefs.js]
--- a/services/settings/moz.build
+++ b/services/settings/moz.build
@@ -1,15 +1,17 @@
 # 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/.
 
 with Files('**'):
     BUG_COMPONENT = ('Firefox', 'Remote Settings Client')
 
+TEST_DIRS += ['test']
+
 DIRS += [
     'dumps',
 ]
 
 EXTRA_COMPONENTS += [
     'servicesSettings.manifest',
 ]
 
new file mode 100644
--- /dev/null
+++ b/services/settings/test/moz.build
@@ -0,0 +1,9 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+TEST_DIRS += [
+    'unit'
+]
copy from services/common/tests/moz.build
copy to services/settings/test/unit/moz.build
--- a/services/common/tests/moz.build
+++ b/services/settings/test/unit/moz.build
@@ -1,11 +1,9 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
-XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
-
 TEST_DIRS += [
-    'unit'
+    'test_remote_settings_signatures'
 ]
rename from services/common/tests/unit/test_blocklist_signatures.js
rename to services/settings/test/unit/test_remote_settings_signatures.js
--- a/services/common/tests/unit/test_blocklist_signatures.js
+++ b/services/settings/test/unit/test_remote_settings_signatures.js
@@ -1,22 +1,22 @@
+/* import-globals-from ../../../common/tests/unit/head_helpers.js */
 "use strict";
 
 const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
-const { BlocklistClients } = ChromeUtils.import("resource://services-common/blocklist-clients.js");
+const { RemoteSettings } = ChromeUtils.import("resource://services-settings/remote-settings.js");
 const { UptakeTelemetry } = ChromeUtils.import("resource://services-common/uptake-telemetry.js");
 
-let server;
+const PREF_SETTINGS_SERVER = "services.settings.server";
+const PREF_SIGNATURE_ROOT  = "security.content.signature.root_hash";
+const SIGNER_NAME          = "onecrl.content-signature.mozilla.org";
 
-const PREF_SETTINGS_SERVER             = "services.settings.server";
-const PREF_SIGNATURE_ROOT              = "security.content.signature.root_hash";
-
-const CERT_DIR = "test_blocklist_signatures/";
+const CERT_DIR = "test_remote_settings_signatures/";
 const CHAIN_FILES =
     ["collection_signing_ee.pem",
      "collection_signing_int.pem",
      "collection_signing_root.pem"];
 
 function getFileData(file) {
   const stream = Cc["@mozilla.org/network/file-input-stream;1"]
                    .createInstance(Ci.nsIFileInputStream);
@@ -43,42 +43,69 @@ function setRoot() {
 function getCertChain() {
   const chain = [];
   for (let file of CHAIN_FILES) {
     chain.push(getFileData(do_get_file(CERT_DIR + file)));
   }
   return chain.join("\n");
 }
 
-async function checkRecordCount(client, count) {
-  // Check we have the expected number of records
-  const records = await client.get();
-  Assert.equal(count, records.length);
+let server;
+let client;
+
+function run_test() {
+  // Signature verification is enabled by default. We use a custom signer
+  // because these tests were originally written for OneCRL.
+  client = RemoteSettings("signed", { signerName: SIGNER_NAME });
+
+  // set the content signing root to our test root
+  setRoot();
+
+  // Set up an HTTP Server
+  server = new HttpServer();
+  server.start(-1);
+
+  run_next_test();
+
+  registerCleanupFunction(() => server.stop(() => {}));
 }
 
-let OneCRLBlocklistClient;
+add_task(async function test_check_signatures() {
+  // First, perform a signature verification with known data and signature
+  // to ensure things are working correctly
+  let verifier = Cc["@mozilla.org/security/contentsignatureverifier;1"]
+                   .createInstance(Ci.nsIContentSignatureVerifier);
+
+  const emptyData = "[]";
+  const emptySignature = "p384ecdsa=zbugm2FDitsHwk5-IWsas1PpWwY29f0Fg5ZHeqD8fzep7AVl2vfcaHA7LdmCZ28qZLOioGKvco3qT117Q4-HlqFTJM7COHzxGyU2MMJ0ZTnhJrPOC1fP3cVQjU1PTWi9";
 
-// Check to ensure maybeSync is called with correct values when a changes
-// document contains information on when a collection was last modified
-add_task(async function test_check_signatures() {
+  ok(await verifier.asyncVerifyContentSignature(emptyData, emptySignature, getCertChain(), SIGNER_NAME));
+
+  const collectionData = '[{"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","created":"2016-01-18T14:43:37Z","name":"GlobalSign certs","who":".","why":"."},"enabled":true,"id":"97fbf7c4-3ef2-f54f-0029-1ba6540c63ea","issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","last_modified":2000,"serialNumber":"BAAAAAABA/A35EU="},{"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","created":"2016-01-18T14:48:11Z","name":"GlobalSign certs","who":".","why":"."},"enabled":true,"id":"e3bd531e-1ee4-7407-27ce-6fdc9cecbbdc","issuerName":"MIGBMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTElMCMGA1UECxMcUHJpbWFyeSBPYmplY3QgUHVibGlzaGluZyBDQTEwMC4GA1UEAxMnR2xvYmFsU2lnbiBQcmltYXJ5IE9iamVjdCBQdWJsaXNoaW5nIENB","last_modified":3000,"serialNumber":"BAAAAAABI54PryQ="}]';
+  const collectionSignature = "p384ecdsa=f4pA2tYM5jQgWY6YUmhUwQiBLj6QO5sHLD_5MqLePz95qv-7cNCuQoZnPQwxoptDtW8hcWH3kLb0quR7SB-r82gkpR9POVofsnWJRA-ETb0BcIz6VvI3pDT49ZLlNg3p";
+
+  ok(await verifier.asyncVerifyContentSignature(collectionData, collectionSignature, getCertChain(), SIGNER_NAME));
+});
+
+add_task(async function test_check_synchronization_with_signatures() {
   const port = server.identity.primaryPort;
 
   // Telemetry reports.
-  const TELEMETRY_HISTOGRAM_KEY = OneCRLBlocklistClient.identifier;
+  const TELEMETRY_HISTOGRAM_KEY = client.identifier;
 
   // a response to give the client when the cert chain is expected
   function makeMetaResponseBody(lastModified, signature) {
     return {
       data: {
-        id: "certificates",
+        id: "signed",
         last_modified: lastModified,
         signature: {
-          x5u: `http://localhost:${port}/test_blocklist_signatures/test_cert_chain.pem`,
+          x5u: `http://localhost:${port}/test_remote_settings_signatures/test_cert_chain.pem`,
           public_key: "fake",
-          "content-signature": `x5u=http://localhost:${port}/test_blocklist_signatures/test_cert_chain.pem;p384ecdsa=${signature}`,
+          "content-signature": `x5u=http://localhost:${port}/test_remote_settings_signatures/test_cert_chain.pem;p384ecdsa=${signature}`,
           signature_encoding: "rs_base64url",
           signature,
           hash_algorithm: "sha384",
           ref: "1yryrnmzou5rf31ou80znpnq8n",
         },
       },
     };
   }
@@ -122,33 +149,16 @@ add_task(async function test_check_signa
       const keyParts = key.split(":");
       const valueParts = keyParts[1].split("?");
       const path = valueParts[0];
 
       server.registerPathHandler(path, handleResponse.bind(null, 2000));
     }
   }
 
-  // First, perform a signature verification with known data and signature
-  // to ensure things are working correctly
-  let verifier = Cc["@mozilla.org/security/contentsignatureverifier;1"]
-                   .createInstance(Ci.nsIContentSignatureVerifier);
-
-  const emptyData = "[]";
-  const emptySignature = "p384ecdsa=zbugm2FDitsHwk5-IWsas1PpWwY29f0Fg5ZHeqD8fzep7AVl2vfcaHA7LdmCZ28qZLOioGKvco3qT117Q4-HlqFTJM7COHzxGyU2MMJ0ZTnhJrPOC1fP3cVQjU1PTWi9";
-  const name = "onecrl.content-signature.mozilla.org";
-  ok(await verifier.asyncVerifyContentSignature(emptyData, emptySignature,
-                                                getCertChain(), name));
-
-  const collectionData = '[{"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","created":"2016-01-18T14:43:37Z","name":"GlobalSign certs","who":".","why":"."},"enabled":true,"id":"97fbf7c4-3ef2-f54f-0029-1ba6540c63ea","issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","last_modified":2000,"serialNumber":"BAAAAAABA/A35EU="},{"details":{"bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","created":"2016-01-18T14:48:11Z","name":"GlobalSign certs","who":".","why":"."},"enabled":true,"id":"e3bd531e-1ee4-7407-27ce-6fdc9cecbbdc","issuerName":"MIGBMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTElMCMGA1UECxMcUHJpbWFyeSBPYmplY3QgUHVibGlzaGluZyBDQTEwMC4GA1UEAxMnR2xvYmFsU2lnbiBQcmltYXJ5IE9iamVjdCBQdWJsaXNoaW5nIENB","last_modified":3000,"serialNumber":"BAAAAAABI54PryQ="}]';
-  const collectionSignature = "p384ecdsa=f4pA2tYM5jQgWY6YUmhUwQiBLj6QO5sHLD_5MqLePz95qv-7cNCuQoZnPQwxoptDtW8hcWH3kLb0quR7SB-r82gkpR9POVofsnWJRA-ETb0BcIz6VvI3pDT49ZLlNg3p";
-
-  ok(await verifier.asyncVerifyContentSignature(collectionData, collectionSignature,
-                                                getCertChain(), name));
-
   // set up prefs so the kinto updater talks to the test server
   Services.prefs.setCharPref(PREF_SETTINGS_SERVER,
     `http://localhost:${server.identity.primaryPort}/v1`);
 
   // These are records we'll use in the test collections
   const RECORD1 = {
     details: {
       bug: "https://bugzilla.mozilla.org/show_bug.cgi?id=1155145",
@@ -270,33 +280,32 @@ add_task(async function test_check_signa
   // The collection metadata containing the signature for the empty
   // collection.
   const RESPONSE_META_EMPTY_SIG =
     makeMetaResponse(1000, RESPONSE_BODY_META_EMPTY_SIG,
                      "RESPONSE_META_EMPTY_SIG");
 
   // Here, we map request method and path to the available responses
   const emptyCollectionResponses = {
-    "GET:/test_blocklist_signatures/test_cert_chain.pem?": [RESPONSE_CERT_CHAIN],
+    "GET:/test_remote_settings_signatures/test_cert_chain.pem?": [RESPONSE_CERT_CHAIN],
     "GET:/v1/?": [RESPONSE_SERVER_SETTINGS],
-    "GET:/v1/buckets/security-state/collections/onecrl/records?_expected=1000&_sort=-last_modified":
+    "GET:/v1/buckets/main/collections/signed/records?_expected=1000&_sort=-last_modified":
       [RESPONSE_EMPTY_INITIAL],
-    "GET:/v1/buckets/security-state/collections/onecrl?_expected=1000":
+    "GET:/v1/buckets/main/collections/signed?_expected=1000":
       [RESPONSE_META_EMPTY_SIG],
   };
 
   // .. and use this map to register handlers for each path
   registerHandlers(emptyCollectionResponses);
 
   let startHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY);
 
   // With all of this set up, we attempt a sync. This will resolve if all is
   // well and throw if something goes wrong.
-  // We don't want to load initial json dumps in this test suite.
-  await OneCRLBlocklistClient.maybeSync(1000, { loadDump: false });
+  await client.maybeSync(1000);
 
   let endHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY);
 
   // ensure that a success histogram is tracked when a succesful sync occurs.
   let expectedIncrements = {[UptakeTelemetry.STATUS.SUCCESS]: 1};
   checkUptakeTelemetry(startHistogram, endHistogram, expectedIncrements);
 
 
@@ -318,23 +327,23 @@ add_task(async function test_check_signa
     "dwhJeypadNIyzGj3QdI0KMRTPnHhFPF_j73mNrsPAHKMW46S2Ftf4BzsPMvPMB8h0TjDus13wo_R4l432DHe7tYyMIWXY0PBeMcoe5BREhFIxMxTsh9eGVXBD1e3UwRy");
 
   // A signature response for the collection containg RECORD1 and RECORD2
   const RESPONSE_META_TWO_ITEMS_SIG =
     makeMetaResponse(3000, RESPONSE_BODY_META_TWO_ITEMS_SIG,
                      "RESPONSE_META_TWO_ITEMS_SIG");
 
   const twoItemsResponses = {
-    "GET:/v1/buckets/security-state/collections/onecrl/records?_expected=3000&_sort=-last_modified&_since=1000":
+    "GET:/v1/buckets/main/collections/signed/records?_expected=3000&_sort=-last_modified&_since=1000":
       [RESPONSE_TWO_ADDED],
-    "GET:/v1/buckets/security-state/collections/onecrl?_expected=3000":
+    "GET:/v1/buckets/main/collections/signed?_expected=3000":
       [RESPONSE_META_TWO_ITEMS_SIG],
   };
   registerHandlers(twoItemsResponses);
-  await OneCRLBlocklistClient.maybeSync(3000);
+  await client.maybeSync(3000);
 
 
   // Check the collection with one addition and one removal has a valid
   // signature
 
   // Remove RECORD1, add RECORD3
   const RESPONSE_ONE_ADDED_ONE_REMOVED = {
     comment: "RESPONSE_ONE_ADDED_ONE_REMOVED ",
@@ -350,45 +359,45 @@ add_task(async function test_check_signa
     "MIEmNghKnkz12UodAAIc3q_Y4a3IJJ7GhHF4JYNYmm8avAGyPM9fYU7NzVo94pzjotG7vmtiYuHyIX2rTHTbT587w0LdRWxipgFd_PC1mHiwUyjFYNqBBG-kifYk7kEw");
 
   // signature response for the collection containing RECORD2 and RECORD3
   const RESPONSE_META_THREE_ITEMS_SIG =
     makeMetaResponse(4000, RESPONSE_BODY_META_THREE_ITEMS_SIG,
                      "RESPONSE_META_THREE_ITEMS_SIG");
 
   const oneAddedOneRemovedResponses = {
-    "GET:/v1/buckets/security-state/collections/onecrl/records?_expected=4000&_sort=-last_modified&_since=3000":
+    "GET:/v1/buckets/main/collections/signed/records?_expected=4000&_sort=-last_modified&_since=3000":
       [RESPONSE_ONE_ADDED_ONE_REMOVED],
-    "GET:/v1/buckets/security-state/collections/onecrl?_expected=4000":
+    "GET:/v1/buckets/main/collections/signed?_expected=4000":
       [RESPONSE_META_THREE_ITEMS_SIG],
   };
   registerHandlers(oneAddedOneRemovedResponses);
-  await OneCRLBlocklistClient.maybeSync(4000);
+  await client.maybeSync(4000);
 
   // Check the signature is still valid with no operation (no changes)
 
   // Leave the collection unchanged
   const RESPONSE_EMPTY_NO_UPDATE = {
     comment: "RESPONSE_EMPTY_NO_UPDATE ",
     sampleHeaders: [
       "Content-Type: application/json; charset=UTF-8",
       "ETag: \"4000\"",
     ],
     status: {status: 200, statusText: "OK"},
     responseBody: JSON.stringify({"data": []}),
   };
 
   const noOpResponses = {
-    "GET:/v1/buckets/security-state/collections/onecrl/records?_expected=4100&_sort=-last_modified&_since=4000":
+    "GET:/v1/buckets/main/collections/signed/records?_expected=4100&_sort=-last_modified&_since=4000":
       [RESPONSE_EMPTY_NO_UPDATE],
-    "GET:/v1/buckets/security-state/collections/onecrl?_expected=4100":
+    "GET:/v1/buckets/main/collections/signed?_expected=4100":
       [RESPONSE_META_THREE_ITEMS_SIG],
   };
   registerHandlers(noOpResponses);
-  await OneCRLBlocklistClient.maybeSync(4100);
+  await client.maybeSync(4100);
 
 
   // Check the collection is reset when the signature is invalid
 
   // Prepare a (deliberately) bad signature to check the collection state is
   // reset if something is inconsistent
   const RESPONSE_COMPLETE_INITIAL = {
     comment: "RESPONSE_COMPLETE_INITIAL ",
@@ -415,41 +424,41 @@ add_task(async function test_check_signa
 
   const RESPONSE_META_BAD_SIG =
       makeMetaResponse(4000, RESPONSE_BODY_META_BAD_SIG, "RESPONSE_META_BAD_SIG");
 
   const badSigGoodSigResponses = {
     // In this test, we deliberately serve a bad signature initially. The
     // subsequent signature returned is a valid one for the three item
     // collection.
-    "GET:/v1/buckets/security-state/collections/onecrl?_expected=5000":
+    "GET:/v1/buckets/main/collections/signed?_expected=5000":
       [RESPONSE_META_BAD_SIG, RESPONSE_META_THREE_ITEMS_SIG],
     // The first collection state is the three item collection (since
     // there's a sync with no updates) - but, since the signature is wrong,
     // another request will be made...
-    "GET:/v1/buckets/security-state/collections/onecrl/records?_expected=5000&_sort=-last_modified&_since=4000":
+    "GET:/v1/buckets/main/collections/signed/records?_expected=5000&_sort=-last_modified&_since=4000":
       [RESPONSE_EMPTY_NO_UPDATE],
     // The next request is for the full collection. This will be checked
     // against the valid signature - so the sync should succeed.
-    "GET:/v1/buckets/security-state/collections/onecrl/records?_sort=-last_modified":
+    "GET:/v1/buckets/main/collections/signed/records?_sort=-last_modified":
       [RESPONSE_COMPLETE_INITIAL],
     // The next request is for the full collection sorted by id. This will be
     // checked against the valid signature - so the sync should succeed.
-    "GET:/v1/buckets/security-state/collections/onecrl/records?_expected=5000&_sort=id":
+    "GET:/v1/buckets/main/collections/signed/records?_expected=5000&_sort=id":
       [RESPONSE_COMPLETE_INITIAL_SORTED_BY_ID],
   };
 
   registerHandlers(badSigGoodSigResponses);
 
   startHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY);
 
   let syncEventSent = false;
-  OneCRLBlocklistClient.on("sync", ({ data }) => { syncEventSent = true; });
+  client.on("sync", ({ data }) => { syncEventSent = true; });
 
-  await OneCRLBlocklistClient.maybeSync(5000);
+  await client.maybeSync(5000);
 
   endHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY);
 
   // since we only fixed the signature, and no data was changed, the sync event
   // was not sent.
   equal(syncEventSent, false);
 
   // ensure that the failure count is incremented for a succesful sync with an
@@ -458,155 +467,133 @@ add_task(async function test_check_signa
   expectedIncrements = {[UptakeTelemetry.STATUS.SIGNATURE_ERROR]: 1};
   checkUptakeTelemetry(startHistogram, endHistogram, expectedIncrements);
 
 
   const badSigGoodOldResponses = {
     // In this test, we deliberately serve a bad signature initially. The
     // subsequent sitnature returned is a valid one for the three item
     // collection.
-    "GET:/v1/buckets/security-state/collections/onecrl?_expected=5000":
+    "GET:/v1/buckets/main/collections/signed?_expected=5000":
       [RESPONSE_META_BAD_SIG, RESPONSE_META_EMPTY_SIG],
     // The first collection state is the current state (since there's no update
     // - but, since the signature is wrong, another request will be made)
-    "GET:/v1/buckets/security-state/collections/onecrl/records?_expected=5000&_sort=-last_modified&_since=4000":
+    "GET:/v1/buckets/main/collections/signed/records?_expected=5000&_sort=-last_modified&_since=4000":
       [RESPONSE_EMPTY_NO_UPDATE],
     // The next request is for the full collection sorted by id. This will be
     // checked against the valid signature and last_modified times will be
     // compared. Sync should fail, even though the signature is good,
     // because the local collection is newer.
-    "GET:/v1/buckets/security-state/collections/onecrl/records?_expected=5000&_sort=id":
+    "GET:/v1/buckets/main/collections/signed/records?_expected=5000&_sort=id":
       [RESPONSE_EMPTY_INITIAL],
   };
 
   // ensure our collection hasn't been replaced with an older, empty one
-  await checkRecordCount(OneCRLBlocklistClient, 2);
+  equal((await client.get()).length, 2);
 
   registerHandlers(badSigGoodOldResponses);
 
   syncEventSent = false;
-  OneCRLBlocklistClient.on("sync", ({ data }) => { syncEventSent = true; });
+  client.on("sync", ({ data }) => { syncEventSent = true; });
 
-  await OneCRLBlocklistClient.maybeSync(5000);
+  await client.maybeSync(5000);
 
   // Local data was unchanged, since it was never than the one returned by the server,
   // thus the sync event is not sent.
   equal(syncEventSent, false);
 
   const badLocalContentGoodSigResponses = {
     // In this test, we deliberately serve a bad signature initially. The
     // subsequent signature returned is a valid one for the three item
     // collection.
-    "GET:/v1/buckets/security-state/collections/onecrl?_expected=5000":
+    "GET:/v1/buckets/main/collections/signed?_expected=5000":
       [RESPONSE_META_BAD_SIG, RESPONSE_META_THREE_ITEMS_SIG],
     // The next request is for the full collection. This will be checked
     // against the valid signature - so the sync should succeed.
-    "GET:/v1/buckets/security-state/collections/onecrl/records?_expected=5000&_sort=-last_modified":
+    "GET:/v1/buckets/main/collections/signed/records?_expected=5000&_sort=-last_modified":
       [RESPONSE_COMPLETE_INITIAL],
     // The next request is for the full collection sorted by id. This will be
     // checked against the valid signature - so the sync should succeed.
-    "GET:/v1/buckets/security-state/collections/onecrl/records?_expected=5000&_sort=id":
+    "GET:/v1/buckets/main/collections/signed/records?_expected=5000&_sort=id":
       [RESPONSE_COMPLETE_INITIAL_SORTED_BY_ID],
   };
 
   registerHandlers(badLocalContentGoodSigResponses);
 
   // we create a local state manually here, in order to test that the sync event data
   // properly contains created, updated, and deleted records.
   // the final server collection contains RECORD2 and RECORD3
-  const kintoCol = await OneCRLBlocklistClient.openCollection();
+  const kintoCol = await client.openCollection();
   await kintoCol.clear();
   await kintoCol.create({ ...RECORD2, last_modified: 1234567890, serialNumber: "abc" }, { synced: true, useRecordId: true });
   const localId = "0602b1b2-12ab-4d3a-b6fb-593244e7b035";
   await kintoCol.create({ id: localId }, { synced: true, useRecordId: true });
 
   let syncData;
-  OneCRLBlocklistClient.on("sync", ({ data }) => { syncData = data; });
+  client.on("sync", ({ data }) => { syncData = data; });
 
-  await OneCRLBlocklistClient.maybeSync(5000, { loadDump: false });
+  await client.maybeSync(5000);
 
   // Local data was unchanged, since it was never than the one returned by the server.
   equal(syncData.current.length, 2);
   equal(syncData.created.length, 1);
   equal(syncData.created[0].id, RECORD3.id);
   equal(syncData.updated.length, 1);
   equal(syncData.updated[0].old.serialNumber, "abc");
   equal(syncData.updated[0].new.serialNumber, RECORD2.serialNumber);
   equal(syncData.deleted.length, 1);
   equal(syncData.deleted[0].id, localId);
 
 
   const allBadSigResponses = {
     // In this test, we deliberately serve only a bad signature.
-    "GET:/v1/buckets/security-state/collections/onecrl?_expected=6000":
+    "GET:/v1/buckets/main/collections/signed?_expected=6000":
       [RESPONSE_META_BAD_SIG],
     // The first collection state is the three item collection (since
     // there's a sync with no updates) - but, since the signature is wrong,
     // another request will be made...
-    "GET:/v1/buckets/security-state/collections/onecrl/records?_expected=6000&_sort=-last_modified&_since=4000":
+    "GET:/v1/buckets/main/collections/signed/records?_expected=6000&_sort=-last_modified&_since=4000":
       [RESPONSE_EMPTY_NO_UPDATE],
     // The next request is for the full collection sorted by id. This will be
     // checked against the valid signature - so the sync should succeed.
-    "GET:/v1/buckets/security-state/collections/onecrl/records?_expected=6000&_sort=id":
+    "GET:/v1/buckets/main/collections/signed/records?_expected=6000&_sort=id":
       [RESPONSE_COMPLETE_INITIAL_SORTED_BY_ID],
   };
 
   startHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY);
   registerHandlers(allBadSigResponses);
   try {
-    await OneCRLBlocklistClient.maybeSync(6000);
+    await client.maybeSync(6000);
     do_throw("Sync should fail (the signature is intentionally bad)");
   } catch (e) {
-    await checkRecordCount(OneCRLBlocklistClient, 2);
+    equal((await client.get()).length, 2);
   }
 
   // Ensure that the failure is reflected in the accumulated telemetry:
   endHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY);
   expectedIncrements = {[UptakeTelemetry.STATUS.SIGNATURE_RETRY_ERROR]: 1};
   checkUptakeTelemetry(startHistogram, endHistogram, expectedIncrements);
 
 
   const missingSigResponses = {
     // In this test, we deliberately serve metadata without the signature attribute.
     // As if the collection was not signed.
-    "GET:/v1/buckets/security-state/collections/onecrl?_expected=6000":
+    "GET:/v1/buckets/main/collections/signed?_expected=6000":
       [RESPONSE_META_NO_SIG],
   };
 
   startHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY);
   registerHandlers(missingSigResponses);
   try {
-    await OneCRLBlocklistClient.maybeSync(6000);
+    await client.maybeSync(6000);
     do_throw("Sync should fail (the signature is missing)");
   } catch (e) {
-    await checkRecordCount(OneCRLBlocklistClient, 2);
+    equal((await client.get()).length, 2);
   }
 
   // Ensure that the failure is reflected in the accumulated telemetry:
   endHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY);
   expectedIncrements = {
     [UptakeTelemetry.STATUS.SIGNATURE_ERROR]: 1,
     [UptakeTelemetry.STATUS.SIGNATURE_RETRY_ERROR]: 0,  // Not retried since missing.
   };
   checkUptakeTelemetry(startHistogram, endHistogram, expectedIncrements);
 });
-
-function run_test() {
-  // Signature verification is evabled by default.
-  ({OneCRLBlocklistClient} = BlocklistClients.initialize());
-
-  // get a signature verifier to ensure nsNSSComponent is initialized
-  Cc["@mozilla.org/security/contentsignatureverifier;1"]
-    .createInstance(Ci.nsIContentSignatureVerifier);
-
-  // set the content signing root to our test root
-  setRoot();
-
-  // Set up an HTTP Server
-  server = new HttpServer();
-  server.start(-1);
-
-  run_next_test();
-
-  registerCleanupFunction(function() {
-    server.stop(function() { });
-  });
-}
rename from services/common/tests/unit/test_blocklist_signatures/collection_signing_ee.pem.certspec
rename to services/settings/test/unit/test_remote_settings_signatures/collection_signing_ee.pem.certspec
rename from services/common/tests/unit/test_blocklist_signatures/collection_signing_int.pem.certspec
rename to services/settings/test/unit/test_remote_settings_signatures/collection_signing_int.pem.certspec
rename from services/common/tests/unit/test_blocklist_signatures/collection_signing_root.pem.certspec
rename to services/settings/test/unit/test_remote_settings_signatures/collection_signing_root.pem.certspec
rename from services/common/tests/unit/test_blocklist_signatures/moz.build
rename to services/settings/test/unit/test_remote_settings_signatures/moz.build
--- a/services/common/tests/unit/test_blocklist_signatures/moz.build
+++ b/services/settings/test/unit/test_remote_settings_signatures/moz.build
@@ -7,12 +7,8 @@
 test_certificates = (
     'collection_signing_root.pem',
     'collection_signing_int.pem',
     'collection_signing_ee.pem',
 )
 
 for test_certificate in test_certificates:
     GeneratedTestCertificate(test_certificate)
-
-with Files('**'):
-    BUG_COMPONENT = ('Toolkit', 'Blocklist Implementation')
-
--- a/services/settings/test/unit/xpcshell.ini
+++ b/services/settings/test/unit/xpcshell.ini
@@ -1,11 +1,14 @@
 [DEFAULT]
 head = ../../../common/tests/unit/head_global.js ../../../common/tests/unit/head_helpers.js
 firefox-appdir = browser
 tags = remote-settings
+support-files =
+  test_remote_settings_signatures/**
 
 [test_attachments_downloader.js]
 support-files = test_attachments_downloader/**
 [test_remote_settings.js]
 [test_remote_settings_poll.js]
 [test_remote_settings_worker.js]
 [test_remote_settings_jexl_filters.js]
+[test_remote_settings_signatures.js]