summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/webextensions/test/xpcshell/test_signed_verify.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/mozapps/webextensions/test/xpcshell/test_signed_verify.js')
-rw-r--r--toolkit/mozapps/webextensions/test/xpcshell/test_signed_verify.js234
1 files changed, 234 insertions, 0 deletions
diff --git a/toolkit/mozapps/webextensions/test/xpcshell/test_signed_verify.js b/toolkit/mozapps/webextensions/test/xpcshell/test_signed_verify.js
new file mode 100644
index 000000000..0b5b30d89
--- /dev/null
+++ b/toolkit/mozapps/webextensions/test/xpcshell/test_signed_verify.js
@@ -0,0 +1,234 @@
+// Enable signature checks for these tests
+gUseRealCertChecks = true;
+// Disable update security
+Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
+
+const DATA = "data/signing_checks/";
+const GOOD = [
+ ["signed_bootstrap_2.xpi", AddonManager.SIGNEDSTATE_SIGNED],
+ ["signed_nonbootstrap_2.xpi", AddonManager.SIGNEDSTATE_SIGNED]
+];
+const BAD = [
+ ["unsigned_bootstrap_2.xpi", AddonManager.SIGNEDSTATE_MISSING],
+ ["signed_bootstrap_badid_2.xpi", AddonManager.SIGNEDSTATE_BROKEN],
+ ["unsigned_nonbootstrap_2.xpi", AddonManager.SIGNEDSTATE_MISSING],
+ ["signed_nonbootstrap_badid_2.xpi", AddonManager.SIGNEDSTATE_BROKEN],
+];
+const ID = "test@tests.mozilla.org";
+
+const profileDir = gProfD.clone();
+profileDir.append("extensions");
+
+function verifySignatures() {
+ return new Promise(resolve => {
+ let observer = (subject, topic, data) => {
+ Services.obs.removeObserver(observer, "xpi-signature-changed");
+ resolve(JSON.parse(data));
+ }
+ Services.obs.addObserver(observer, "xpi-signature-changed", false);
+
+ do_print("Verifying signatures");
+ let XPIscope = Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm");
+ XPIscope.XPIProvider.verifySignatures();
+ });
+}
+
+function run_test() {
+ createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "4", "4");
+
+ run_next_test();
+}
+
+function verify_no_change([startFile, startState], [endFile, endState]) {
+ add_task(function*() {
+ do_print("A switch from " + startFile + " to " + endFile + " should cause no change.");
+
+ // Install the first add-on
+ manuallyInstall(do_get_file(DATA + startFile), profileDir, ID);
+ startupManager();
+
+ let addon = yield promiseAddonByID(ID);
+ do_check_neq(addon, null);
+ let wasAppDisabled = addon.appDisabled;
+ do_check_neq(addon.appDisabled, addon.isActive);
+ do_check_eq(addon.pendingOperations, AddonManager.PENDING_NONE);
+ do_check_eq(addon.signedState, startState);
+
+ // Swap in the files from the next add-on
+ manuallyUninstall(profileDir, ID);
+ manuallyInstall(do_get_file(DATA + endFile), profileDir, ID);
+
+ let events = {
+ [ID]: []
+ };
+
+ if (startState != endState)
+ events[ID].unshift(["onPropertyChanged", ["signedState"]]);
+
+ prepare_test(events);
+
+ // Trigger the check
+ let changes = yield verifySignatures();
+ do_check_eq(changes.enabled.length, 0);
+ do_check_eq(changes.disabled.length, 0);
+
+ do_check_eq(addon.appDisabled, wasAppDisabled);
+ do_check_neq(addon.appDisabled, addon.isActive);
+ do_check_eq(addon.pendingOperations, AddonManager.PENDING_NONE);
+ do_check_eq(addon.signedState, endState);
+
+ // Remove the add-on and restart to let it go away
+ manuallyUninstall(profileDir, ID);
+ yield promiseRestartManager();
+ yield promiseShutdownManager();
+ });
+}
+
+function verify_enables([startFile, startState], [endFile, endState]) {
+ add_task(function*() {
+ do_print("A switch from " + startFile + " to " + endFile + " should enable the add-on.");
+
+ // Install the first add-on
+ manuallyInstall(do_get_file(DATA + startFile), profileDir, ID);
+ startupManager();
+
+ let addon = yield promiseAddonByID(ID);
+ do_check_neq(addon, null);
+ do_check_false(addon.isActive);
+ do_check_eq(addon.pendingOperations, AddonManager.PENDING_NONE);
+ do_check_eq(addon.signedState, startState);
+
+ // Swap in the files from the next add-on
+ manuallyUninstall(profileDir, ID);
+ manuallyInstall(do_get_file(DATA + endFile), profileDir, ID);
+
+ let needsRestart = hasFlag(addon.operationsRequiringRestart, AddonManager.OP_NEEDS_RESTART_ENABLE);
+ do_print(needsRestart);
+
+ let events = {};
+ if (!needsRestart) {
+ events[ID] = [
+ ["onPropertyChanged", ["appDisabled"]],
+ ["onEnabling", false],
+ "onEnabled"
+ ];
+ }
+ else {
+ events[ID] = [
+ ["onPropertyChanged", ["appDisabled"]],
+ "onEnabling"
+ ];
+ }
+
+ if (startState != endState)
+ events[ID].unshift(["onPropertyChanged", ["signedState"]]);
+
+ prepare_test(events);
+
+ // Trigger the check
+ let changes = yield verifySignatures();
+ do_check_eq(changes.enabled.length, 1);
+ do_check_eq(changes.enabled[0], ID);
+ do_check_eq(changes.disabled.length, 0);
+
+ do_check_false(addon.appDisabled);
+ if (needsRestart)
+ do_check_neq(addon.pendingOperations, AddonManager.PENDING_NONE);
+ else
+ do_check_true(addon.isActive);
+ do_check_eq(addon.signedState, endState);
+
+ ensure_test_completed();
+
+ // Remove the add-on and restart to let it go away
+ manuallyUninstall(profileDir, ID);
+ yield promiseRestartManager();
+ yield promiseShutdownManager();
+ });
+}
+
+function verify_disables([startFile, startState], [endFile, endState]) {
+ add_task(function*() {
+ do_print("A switch from " + startFile + " to " + endFile + " should disable the add-on.");
+
+ // Install the first add-on
+ manuallyInstall(do_get_file(DATA + startFile), profileDir, ID);
+ startupManager();
+
+ let addon = yield promiseAddonByID(ID);
+ do_check_neq(addon, null);
+ do_check_true(addon.isActive);
+ do_check_eq(addon.pendingOperations, AddonManager.PENDING_NONE);
+ do_check_eq(addon.signedState, startState);
+
+ let needsRestart = hasFlag(addon.operationsRequiringRestart, AddonManager.OP_NEEDS_RESTART_DISABLE);
+
+ // Swap in the files from the next add-on
+ manuallyUninstall(profileDir, ID);
+ manuallyInstall(do_get_file(DATA + endFile), profileDir, ID);
+
+ let events = {};
+ if (!needsRestart) {
+ events[ID] = [
+ ["onPropertyChanged", ["appDisabled"]],
+ ["onDisabling", false],
+ "onDisabled"
+ ];
+ }
+ else {
+ events[ID] = [
+ ["onPropertyChanged", ["appDisabled"]],
+ "onDisabling"
+ ];
+ }
+
+ if (startState != endState)
+ events[ID].unshift(["onPropertyChanged", ["signedState"]]);
+
+ prepare_test(events);
+
+ // Trigger the check
+ let changes = yield verifySignatures();
+ do_check_eq(changes.enabled.length, 0);
+ do_check_eq(changes.disabled.length, 1);
+ do_check_eq(changes.disabled[0], ID);
+
+ do_check_true(addon.appDisabled);
+ if (needsRestart)
+ do_check_neq(addon.pendingOperations, AddonManager.PENDING_NONE);
+ else
+ do_check_false(addon.isActive);
+ do_check_eq(addon.signedState, endState);
+
+ ensure_test_completed();
+
+ // Remove the add-on and restart to let it go away
+ manuallyUninstall(profileDir, ID);
+ yield promiseRestartManager();
+ yield promiseShutdownManager();
+ });
+}
+
+for (let start of GOOD) {
+ for (let end of BAD) {
+ verify_disables(start, end);
+ }
+}
+
+for (let start of BAD) {
+ for (let end of GOOD) {
+ verify_enables(start, end);
+ }
+}
+
+for (let start of GOOD) {
+ for (let end of GOOD.filter(f => f != start)) {
+ verify_no_change(start, end);
+ }
+}
+
+for (let start of BAD) {
+ for (let end of BAD.filter(f => f != start)) {
+ verify_no_change(start, end);
+ }
+}