Bug 1446571: Part 1 - Remove support for signed update.rdf files. draft
authorKris Maglione <maglione.k@gmail.com>
Fri, 16 Mar 2018 17:51:11 -0700
changeset 768886 58db2320b1b710373f111df61089333f2248ad1f
parent 768843 74f745d7c4e0a7b0c84be6ede6a20311304042c5
child 768887 42b43717283274a8d6750329550f048ac555bcc2
push id103000
push usermaglione.k@gmail.com
push dateSat, 17 Mar 2018 00:55:04 +0000
bugs1446571
milestone61.0a1
Bug 1446571: Part 1 - Remove support for signed update.rdf files. MozReview-Commit-ID: FAXNRAivRcN
toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm
toolkit/mozapps/extensions/internal/XPIInstall.jsm
toolkit/mozapps/extensions/internal/XPIProvider.jsm
toolkit/mozapps/extensions/internal/XPIProviderUtils.js
toolkit/mozapps/extensions/test/browser/browser_updatessl.js
toolkit/mozapps/extensions/test/xpcshell/test_json_updatecheck.js
toolkit/mozapps/extensions/test/xpcshell/test_manifest.js
toolkit/mozapps/extensions/test/xpcshell/test_updatecheck.js
--- a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
@@ -721,17 +721,17 @@ var AddonTestUtils = {
 
   createInstallRDF(data) {
     var rdf = '<?xml version="1.0"?>\n';
     rdf += '<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"\n' +
            '     xmlns:em="http://www.mozilla.org/2004/em-rdf#">\n';
 
     rdf += '<Description about="urn:mozilla:install-manifest">\n';
 
-    let props = ["id", "version", "type", "internalName", "updateURL", "updateKey",
+    let props = ["id", "version", "type", "internalName", "updateURL",
                  "optionsURL", "optionsType", "aboutURL", "iconURL", "icon64URL",
                  "skinnable", "bootstrap", "unpack", "strictCompatibility",
                  "hasEmbeddedWebExtension"];
     rdf += this._writeProps(data, props);
 
     rdf += this._writeLocaleStrings(data);
 
     for (let platform of data.targetPlatforms || [])
--- a/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm
@@ -48,174 +48,16 @@ var gRDF = Cc["@mozilla.org/rdf/rdf-serv
 ChromeUtils.import("resource://gre/modules/Log.jsm");
 const LOGGER_ID = "addons.update-checker";
 
 // Create a new logger for use by the Addons Update Checker
 // (Requires AddonManager.jsm)
 var logger = Log.repository.getLogger(LOGGER_ID);
 
 /**
- * A serialisation method for RDF data that produces an identical string
- * for matching RDF graphs.
- * The serialisation is not complete, only assertions stemming from a given
- * resource are included, multiple references to the same resource are not
- * permitted, and the RDF prolog and epilog are not included.
- * RDF Blob and Date literals are not supported.
- */
-function RDFSerializer() {
-  this.cUtils = Cc["@mozilla.org/rdf/container-utils;1"].
-                getService(Ci.nsIRDFContainerUtils);
-  this.resources = [];
-}
-
-RDFSerializer.prototype = {
-  INDENT: "  ",      // The indent used for pretty-printing
-  resources: null,   // Array of the resources that have been found
-
-  /**
-   * Escapes characters from a string that should not appear in XML.
-   *
-   * @param  aString
-   *         The string to be escaped
-   * @return a string with all characters invalid in XML character data
-   *         converted to entity references.
-   */
-  escapeEntities(aString) {
-    aString = aString.replace(/&/g, "&amp;");
-    aString = aString.replace(/</g, "&lt;");
-    aString = aString.replace(/>/g, "&gt;");
-    return aString.replace(/"/g, "&quot;");
-  },
-
-  /**
-   * Serializes all the elements of an RDF container.
-   *
-   * @param  aDs
-   *         The RDF datasource
-   * @param  aContainer
-   *         The RDF container to output the child elements of
-   * @param  aIndent
-   *         The current level of indent for pretty-printing
-   * @return a string containing the serialized elements.
-   */
-  serializeContainerItems(aDs, aContainer, aIndent) {
-    var result = "";
-    var items = aContainer.GetElements();
-    while (items.hasMoreElements()) {
-      var item = items.getNext().QueryInterface(Ci.nsIRDFResource);
-      result += aIndent + "<RDF:li>\n";
-      result += this.serializeResource(aDs, item, aIndent + this.INDENT);
-      result += aIndent + "</RDF:li>\n";
-    }
-    return result;
-  },
-
-  /**
-   * Serializes all em:* (see EM_NS) properties of an RDF resource except for
-   * the em:signature property. As this serialization is to be compared against
-   * the manifest signature it cannot contain the em:signature property itself.
-   *
-   * @param  aDs
-   *         The RDF datasource
-   * @param  aResource
-   *         The RDF resource that contains the properties to serialize
-   * @param  aIndent
-   *         The current level of indent for pretty-printing
-   * @return a string containing the serialized properties.
-   * @throws if the resource contains a property that cannot be serialized
-   */
-  serializeResourceProperties(aDs, aResource, aIndent) {
-    var result = "";
-    var items = [];
-    var arcs = aDs.ArcLabelsOut(aResource);
-    while (arcs.hasMoreElements()) {
-      var arc = arcs.getNext().QueryInterface(Ci.nsIRDFResource);
-      if (arc.ValueUTF8.substring(0, PREFIX_NS_EM.length) != PREFIX_NS_EM)
-        continue;
-      var prop = arc.ValueUTF8.substring(PREFIX_NS_EM.length);
-      if (prop == "signature")
-        continue;
-
-      var targets = aDs.GetTargets(aResource, arc, true);
-      while (targets.hasMoreElements()) {
-        var target = targets.getNext();
-        if (target instanceof Ci.nsIRDFResource) {
-          var item = aIndent + "<em:" + prop + ">\n";
-          item += this.serializeResource(aDs, target, aIndent + this.INDENT);
-          item += aIndent + "</em:" + prop + ">\n";
-          items.push(item);
-        } else if (target instanceof Ci.nsIRDFLiteral) {
-          items.push(aIndent + "<em:" + prop + ">" +
-                     this.escapeEntities(target.Value) + "</em:" + prop + ">\n");
-        } else if (target instanceof Ci.nsIRDFInt) {
-          items.push(aIndent + "<em:" + prop + " NC:parseType=\"Integer\">" +
-                     target.Value + "</em:" + prop + ">\n");
-        } else {
-          throw Components.Exception("Cannot serialize unknown literal type");
-        }
-      }
-    }
-    items.sort();
-    result += items.join("");
-    return result;
-  },
-
-  /**
-   * Recursively serializes an RDF resource and all resources it links to.
-   * This will only output EM_NS properties and will ignore any em:signature
-   * property.
-   *
-   * @param  aDs
-   *         The RDF datasource
-   * @param  aResource
-   *         The RDF resource to serialize
-   * @param  aIndent
-   *         The current level of indent for pretty-printing. If undefined no
-   *         indent will be added
-   * @return a string containing the serialized resource.
-   * @throws if the RDF data contains multiple references to the same resource.
-   */
-  serializeResource(aDs, aResource, aIndent) {
-    if (this.resources.includes(aResource) ) {
-      // We cannot output multiple references to the same resource.
-      throw Components.Exception("Cannot serialize multiple references to " + aResource.Value);
-    }
-    if (aIndent === undefined)
-      aIndent = "";
-
-    this.resources.push(aResource);
-    var container = null;
-    var type = "Description";
-    if (this.cUtils.IsSeq(aDs, aResource)) {
-      type = "Seq";
-      container = this.cUtils.MakeSeq(aDs, aResource);
-    } else if (this.cUtils.IsAlt(aDs, aResource)) {
-      type = "Alt";
-      container = this.cUtils.MakeAlt(aDs, aResource);
-    } else if (this.cUtils.IsBag(aDs, aResource)) {
-      type = "Bag";
-      container = this.cUtils.MakeBag(aDs, aResource);
-    }
-
-    var result = aIndent + "<RDF:" + type;
-    if (!gRDF.IsAnonymousResource(aResource))
-      result += " about=\"" + this.escapeEntities(aResource.ValueUTF8) + "\"";
-    result += ">\n";
-
-    if (container)
-      result += this.serializeContainerItems(aDs, container, aIndent + this.INDENT);
-
-    result += this.serializeResourceProperties(aDs, aResource, aIndent + this.INDENT);
-
-    result += aIndent + "</RDF:" + type + ">\n";
-    return result;
-  }
-};
-
-/**
  * Sanitizes the update URL in an update item, as returned by
  * parseRDFManifest and parseJSONManifest. Ensures that:
  *
  * - The URL is secure, or secured by a strong enough hash.
  * - The security principal of the update manifest has permission to
  *   load the URL.
  *
  * @param aUpdate
@@ -252,26 +94,24 @@ function sanitizeUpdateURL(aUpdate, aReq
   }
 }
 
 /**
  * Parses an RDF style update manifest into an array of update objects.
  *
  * @param  aId
  *         The ID of the add-on being checked for updates
- * @param  aUpdateKey
- *         An optional update key for the add-on
  * @param  aRequest
  *         The XMLHttpRequest that has retrieved the update manifest
  * @param  aManifestData
  *         The pre-parsed manifest, as a bare XML DOM document
  * @return an array of update objects
  * @throws if the update manifest is invalid in any way
  */
-function parseRDFManifest(aId, aUpdateKey, aRequest, aManifestData) {
+function parseRDFManifest(aId, aRequest, aManifestData) {
   if (aManifestData.documentElement.namespaceURI != PREFIX_NS_RDF) {
     throw Components.Exception("Update manifest had an unrecognised namespace: " +
                                aManifestData.documentElement.namespaceURI);
   }
 
   function EM_R(aProp) {
     return gRDF.GetResource(PREFIX_NS_EM + aProp);
   }
@@ -317,46 +157,16 @@ function parseRDFManifest(aId, aUpdateKe
   let addonRes;
   if (ds.ArcLabelsOut(extensionRes).hasMoreElements())
     addonRes = extensionRes;
   else if (ds.ArcLabelsOut(themeRes).hasMoreElements())
     addonRes = themeRes;
   else
     addonRes = itemRes;
 
-  // If we have an update key then the update manifest must be signed
-  if (aUpdateKey) {
-    let signature = getProperty(ds, addonRes, "signature");
-    if (!signature)
-      throw Components.Exception("Update manifest for " + aId + " does not contain a required signature");
-    let serializer = new RDFSerializer();
-    let updateString = null;
-
-    try {
-      updateString = serializer.serializeResource(ds, addonRes);
-    } catch (e) {
-      throw Components.Exception("Failed to generate signed string for " + aId + ". Serializer threw " + e,
-                                 e.result);
-    }
-
-    let result = false;
-
-    try {
-      let verifier = Cc["@mozilla.org/security/datasignatureverifier;1"].
-                     getService(Ci.nsIDataSignatureVerifier);
-      result = verifier.verifyData(updateString, signature, aUpdateKey);
-    } catch (e) {
-      throw Components.Exception("The signature or updateKey for " + aId + " is malformed." +
-                                 "Verifier threw " + e, e.result);
-    }
-
-    if (!result)
-      throw Components.Exception("The signature for " + aId + " was not created by the add-on's updateKey");
-  }
-
   let updates = ds.GetTarget(addonRes, EM_R("updates"), true);
 
   // A missing updates property doesn't count as a failure, just as no avialable
   // update information
   if (!updates) {
     logger.warn("Update manifest for " + aId + " did not contain an updates property");
     return [];
   }
@@ -418,29 +228,24 @@ function parseRDFManifest(aId, aUpdateKe
   return results;
 }
 
 /**
  * Parses an JSON update manifest into an array of update objects.
  *
  * @param  aId
  *         The ID of the add-on being checked for updates
- * @param  aUpdateKey
- *         An optional update key for the add-on
  * @param  aRequest
  *         The XMLHttpRequest that has retrieved the update manifest
  * @param  aManifestData
  *         The pre-parsed manifest, as a JSON object tree
  * @return an array of update objects
  * @throws if the update manifest is invalid in any way
  */
-function parseJSONManifest(aId, aUpdateKey, aRequest, aManifestData) {
-  if (aUpdateKey)
-    throw Components.Exception("Update keys are not supported for JSON update manifests");
-
+function parseJSONManifest(aId, aRequest, aManifestData) {
   let TYPE_CHECK = {
     "array": val => Array.isArray(val),
     "object": val => val && typeof val == "object" && !Array.isArray(val),
   };
 
   function getProperty(aObj, aProperty, aType, aDefault = undefined) {
     if (!(aProperty in aObj))
       return aDefault;
@@ -540,26 +345,23 @@ function parseJSONManifest(aId, aUpdateK
 }
 
 /**
  * Starts downloading an update manifest and then passes it to an appropriate
  * parser to convert to an array of update objects
  *
  * @param  aId
  *         The ID of the add-on being checked for updates
- * @param  aUpdateKey
- *         An optional update key for the add-on
  * @param  aUrl
  *         The URL of the update manifest
  * @param  aObserver
  *         An observer to pass results to
  */
-function UpdateParser(aId, aUpdateKey, aUrl, aObserver) {
+function UpdateParser(aId, aUrl, aObserver) {
   this.id = aId;
-  this.updateKey = aUpdateKey;
   this.observer = aObserver;
   this.url = aUrl;
 
   let requireBuiltIn = Services.prefs.getBoolPref(PREF_UPDATE_REQUIREBUILTINCERTS, true);
 
   logger.debug("Requesting " + aUrl);
   try {
     this.request = new ServiceRequest();
@@ -577,17 +379,16 @@ function UpdateParser(aId, aUpdateKey, a
     this.request.send(null);
   } catch (e) {
     logger.error("Failed to request update manifest", e);
   }
 }
 
 UpdateParser.prototype = {
   id: null,
-  updateKey: null,
   observer: null,
   request: null,
   url: null,
 
   /**
    * Called when the manifest has been successfully loaded.
    */
   onLoad() {
@@ -621,27 +422,27 @@ UpdateParser.prototype = {
 
     // Detect the manifest type by first attempting to parse it as
     // JSON, and falling back to parsing it as XML if that fails.
     let parser;
     try {
       try {
         let json = JSON.parse(request.responseText);
 
-        parser = () => parseJSONManifest(this.id, this.updateKey, request, json);
+        parser = () => parseJSONManifest(this.id, request, json);
       } catch (e) {
         if (!(e instanceof SyntaxError))
           throw e;
         let domParser = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser);
         let xml = domParser.parseFromString(request.responseText, "text/xml");
 
         if (xml.documentElement.namespaceURI == XMLURI_PARSE_ERROR)
           throw new Error("Update manifest was not valid XML or JSON");
 
-        parser = () => parseRDFManifest(this.id, this.updateKey, request, xml);
+        parser = () => parseRDFManifest(this.id, request, xml);
       }
     } catch (e) {
       logger.warn("onUpdateCheckComplete failed to determine manifest type");
       this.notifyError(AddonManager.ERROR_UNKNOWN_FORMAT);
       return;
     }
 
     let results;
@@ -863,21 +664,19 @@ var AddonUpdateChecker = {
     return newest;
   },
 
   /**
    * Starts an update check.
    *
    * @param  aId
    *         The ID of the add-on being checked for updates
-   * @param  aUpdateKey
-   *         An optional update key for the add-on
    * @param  aUrl
    *         The URL of the add-on's update manifest
    * @param  aObserver
    *         An observer to notify of results
    * @return UpdateParser so that the caller can use UpdateParser.cancel() to shut
    *         down in-progress update requests
    */
-  checkForUpdates(aId, aUpdateKey, aUrl, aObserver) {
-    return new UpdateParser(aId, aUpdateKey, aUrl, aObserver);
+  checkForUpdates(aId, aUrl, aObserver) {
+    return new UpdateParser(aId, aUrl, aObserver);
   }
 };
--- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm
@@ -122,17 +122,17 @@ const FILE_WEB_MANIFEST               = 
 
 const KEY_TEMPDIR                     = "TmpD";
 
 const RDFURI_INSTALL_MANIFEST_ROOT    = "urn:mozilla:install-manifest";
 const PREFIX_NS_EM                    = "http://www.mozilla.org/2004/em-rdf#";
 
 // Properties that exist in the install manifest
 const PROP_METADATA      = ["id", "version", "type", "internalName", "updateURL",
-                            "updateKey", "optionsURL", "optionsType", "aboutURL",
+                            "optionsURL", "optionsType", "aboutURL",
                             "iconURL", "icon64URL"];
 const PROP_LOCALE_SINGLE = ["name", "description", "creator", "homepageURL"];
 const PROP_LOCALE_MULTI  = ["developers", "translators", "contributors"];
 const PROP_TARGETAPP     = ["id", "minVersion", "maxVersion"];
 
 // Map new string type identifiers to old style nsIUpdateItem types.
 // Retired values:
 // 32 = multipackage xpi file
@@ -321,17 +321,16 @@ async function loadManifestFromWebManife
   addon.id = bss.id;
   addon.version = manifest.version;
   addon.type = extension.type === "extension" ?
                "webextension" : `webextension-${extension.type}`;
   addon.strictCompatibility = true;
   addon.bootstrap = true;
   addon.internalName = null;
   addon.updateURL = bss.update_url;
-  addon.updateKey = null;
   addon.optionsBrowserStyle = true;
   addon.optionsURL = null;
   addon.optionsType = null;
   addon.aboutURL = null;
   addon.dependencies = Object.freeze(Array.from(extension.dependencies));
   addon.startupData = extension.startupData;
 
   if (manifest.options_ui) {
@@ -674,17 +673,16 @@ async function loadManifestFromRDF(aUri,
   addon.softDisabled = addon.blocklistState == nsIBlocklistService.STATE_SOFTBLOCKED;
   addon.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DEFAULT;
 
   // Experiments are managed and updated through an external "experiments
   // manager." So disable some built-in mechanisms.
   if (addon.type == "experiment") {
     addon.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE;
     addon.updateURL = null;
-    addon.updateKey = null;
   }
 
   // icons will be filled by the calling function
   addon.icons = {};
   addon.userPermissions = null;
 
   return addon;
 }
@@ -2637,18 +2635,17 @@ var UpdateChecker = function(aAddon, aLi
   const UPDATE_TYPE_COMPATIBILITY = 32;
   const UPDATE_TYPE_NEWVERSION = 64;
 
   aReason |= UPDATE_TYPE_COMPATIBILITY;
   if ("onUpdateAvailable" in this.listener)
     aReason |= UPDATE_TYPE_NEWVERSION;
 
   let url = escapeAddonURI(aAddon, updateURL, aReason, aAppVersion);
-  this._parser = AddonUpdateChecker.checkForUpdates(aAddon.id, aAddon.updateKey,
-                                                    url, this);
+  this._parser = AddonUpdateChecker.checkForUpdates(aAddon.id, url, this);
 };
 
 UpdateChecker.prototype = {
   addon: null,
   listener: null,
   appVersion: null,
   platformVersion: null,
   syncCompatibility: null,
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -4835,18 +4835,17 @@ AddonInternal.prototype = {
       this._selectedLocale = this.locales.find(loc =>
         loc.locales.includes(bestLocale));
     }
 
     return this._selectedLocale;
   },
 
   get providesUpdatesSecurely() {
-    return !!(this.updateKey || !this.updateURL ||
-              this.updateURL.substring(0, 6) == "https:");
+    return !this.updateURL || this.updateURL.startsWith("https:");
   },
 
   get isCorrectlySigned() {
     switch (this._installLocation.name) {
       case KEY_APP_SYSTEM_ADDONS:
         // System add-ons must be signed by the system key.
         return this.signedState == AddonManager.SIGNEDSTATE_SYSTEM;
 
--- a/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
+++ b/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
@@ -47,17 +47,17 @@ const PREF_EM_AUTO_DISABLED_SCOPES    = 
 
 const KEY_APP_SYSTEM_ADDONS           = "app-system-addons";
 const KEY_APP_SYSTEM_DEFAULTS         = "app-system-defaults";
 const KEY_APP_GLOBAL                  = "app-global";
 const KEY_APP_TEMPORARY               = "app-temporary";
 
 // Properties to save in JSON file
 const PROP_JSON_FIELDS = ["id", "syncGUID", "location", "version", "type",
-                          "internalName", "updateURL", "updateKey", "optionsURL",
+                          "internalName", "updateURL", "optionsURL",
                           "optionsType", "optionsBrowserStyle", "aboutURL",
                           "defaultLocale", "visible", "active", "userDisabled",
                           "appDisabled", "pendingUninstall", "installDate",
                           "updateDate", "applyBackgroundUpdates", "bootstrap", "path",
                           "skinnable", "size", "sourceURI", "releaseNotesURI",
                           "softDisabled", "foreignInstall",
                           "strictCompatibility", "locales", "targetApplications",
                           "targetPlatforms", "signedState",
--- a/toolkit/mozapps/extensions/test/browser/browser_updatessl.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_updatessl.js
@@ -82,18 +82,17 @@ function run_update_tests(callback) {
       var message = "Should have seen the right result for an update check redirected from " +
                     mainURL + " to " + redirectURL;
     } else {
       url = mainURL + updaterdf;
       message = "Should have seen the right result for an update check from " +
                 mainURL;
     }
 
-    AddonUpdateChecker.checkForUpdates("addon1@tests.mozilla.org",
-                                       null, url, {
+    AddonUpdateChecker.checkForUpdates("addon1@tests.mozilla.org", url, {
       onUpdateCheckComplete(updates) {
         is(updates.length, 1, "Should be the right number of results");
         is(SUCCESS, expectedStatus, message);
         info("Update test ran in " + (Date.now() - gLast) + "ms");
         run_next_update_test();
       },
 
       onUpdateCheckError(status) {
--- a/toolkit/mozapps/extensions/test/xpcshell/test_json_updatecheck.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_json_updatecheck.js
@@ -56,17 +56,17 @@ function checkUpdates(aData) {
   };
 
   mapManifest(path.replace(/\?.*/, ""),
               { data: JSON.stringify(manifestJSON),
                 contentType: aData.contentType || "application/json" });
 
 
   return new Promise((resolve, reject) => {
-    AddonUpdateChecker.checkForUpdates(aData.id, aData.updateKey, updateUrl, {
+    AddonUpdateChecker.checkForUpdates(aData.id, updateUrl, {
       onUpdateCheckComplete: resolve,
 
       onUpdateCheckError(status) {
         reject(new Error("Update check failed with status " + status));
       }
     });
   });
 }
@@ -270,38 +270,16 @@ add_task(async function test_update_url_
   equal(updates[0].updateURL, null, "privileged update URL was removed");
   equal(updates[1].updateURL, "http://example.com/update.xpi", "safe update URL was accepted");
 
   messages = messages.filter(msg => /http:\/\/localhost.*\/updates\/.*may not load or link to chrome:/.test(msg.message));
   equal(messages.length, 1, "privileged upate URL generated the expected console message");
 });
 
 
-add_task(async function test_no_update_key() {
-  // Checks that updates fail when an update key has been specified.
-
-  let { messages } = await promiseConsoleOutput(async function() {
-    await Assert.rejects(
-      checkUpdates({
-        id: "updatecheck-updatekey@tests.mozilla.org",
-        version: "0.1",
-        updateKey: "ayzzx=",
-        updates: [
-          { version: "0.2" },
-          { version: "0.3" },
-        ]
-      }),
-      null, "updated expected to fail");
-  });
-
-  messages = messages.filter(msg => /Update keys are not supported for JSON update manifests/.test(msg.message));
-  equal(messages.length, 1, "got expected update-key-unsupported error");
-});
-
-
 add_task(async function test_type_detection() {
   // Checks that JSON update manifests are detected correctly
   // regardless of extension or MIME type.
 
   let tests = [
     { contentType: "application/json",
       extension: "json",
       valid: true },
--- a/toolkit/mozapps/extensions/test/xpcshell/test_manifest.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_manifest.js
@@ -410,20 +410,20 @@ function run_test() {
     Assert.equal(a3.id, "addon3@tests.mozilla.org");
     Assert.ok(!a3.isActive);
     Assert.ok(!a3.userDisabled);
     Assert.ok(a3.appDisabled);
     Assert.ok(!a3.providesUpdatesSecurely);
 
     Assert.notEqual(a4, null);
     Assert.equal(a4.id, "addon4@tests.mozilla.org");
-    Assert.ok(a4.isActive);
+    Assert.ok(!a4.isActive);
     Assert.ok(!a4.userDisabled);
-    Assert.ok(!a4.appDisabled);
-    Assert.ok(a4.providesUpdatesSecurely);
+    Assert.ok(a4.appDisabled);
+    Assert.ok(!a4.providesUpdatesSecurely);
 
     Assert.notEqual(a5, null);
     Assert.ok(a5.isActive);
     Assert.ok(!a5.userDisabled);
     Assert.ok(!a5.appDisabled);
     Assert.ok(a5.isCompatible);
 
     Assert.notEqual(a6, null);
--- a/toolkit/mozapps/extensions/test/xpcshell/test_updatecheck.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_updatecheck.js
@@ -6,19 +6,19 @@
 
 ChromeUtils.import("resource://gre/modules/addons/AddonUpdateChecker.jsm");
 
 ChromeUtils.import("resource://testing-common/httpd.js");
 
 var testserver = createHttpServer(4444);
 testserver.registerDirectory("/data/", do_get_file("data"));
 
-function checkUpdates(aId, aUpdateKey, aUpdateFile) {
+function checkUpdates(aId, aUpdateFile) {
   return new Promise((resolve, reject) => {
-    AddonUpdateChecker.checkForUpdates(aId, aUpdateKey, `http://localhost:4444/data/${aUpdateFile}`, {
+    AddonUpdateChecker.checkForUpdates(aId, `http://localhost:4444/data/${aUpdateFile}`, {
       onUpdateCheckComplete: resolve,
 
       onUpdateCheckError(status) {
         let error = new Error("Update check failed with status " + status);
         error.status = status;
         reject(error);
       }
     });
@@ -29,17 +29,17 @@ function run_test() {
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
 
   run_next_test();
 }
 
 // Test that a basic update check returns the expected available updates
 add_task(async function() {
   for (let file of ["test_updatecheck.rdf", "test_updatecheck.json"]) {
-    let updates = await checkUpdates("updatecheck1@tests.mozilla.org", null, file);
+    let updates = await checkUpdates("updatecheck1@tests.mozilla.org", file);
 
     equal(updates.length, 5);
     let update = AddonUpdateChecker.getNewestCompatibleUpdate(updates);
     notEqual(update, null);
     equal(update.version, "3.0");
     update = AddonUpdateChecker.getCompatibilityUpdate(updates, "2");
     notEqual(update, null);
     equal(update.version, "2.0");
@@ -58,154 +58,149 @@ add_task(async function() {
  * 4        correct     absent      http         no update
  * 5        correct     sha1        http         update
  * 6        corrent     absent      https        update
  * 7        corrent     sha1        https        update
  * 8        corrent     md2         http         no update
  * 9        corrent     md2         https        update
  */
 
-var updateKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK426erD/H3XtsjvaB5+PJqbhj" +
-                "Zc9EDI5OCJS8R3FIObJ9ZHJK1TXeaE7JWqt9WUmBWTEFvwS+FI9vWu8058N9CHhD" +
-                "NyeP6i4LuUYjTURnn7Yw/IgzyIJ2oKsYa32RuxAyteqAWqPT/J63wBixIeCxmysf" +
-                "awB/zH4KaPiY3vnrzQIDAQAB";
-
 add_task(async function() {
   for (let file of ["test_updatecheck.rdf", "test_updatecheck.json"]) {
     try {
       await checkUpdates("test_bug378216_5@tests.mozilla.org",
-                         updateKey, file);
+                         file);
       throw "Expected the update check to fail";
     } catch (e) {}
   }
 });
 
 add_task(async function() {
   for (let file of ["test_updatecheck.rdf", "test_updatecheck.json"]) {
     try {
       await checkUpdates("test_bug378216_7@tests.mozilla.org",
-                         updateKey, file);
+                         file);
 
       throw "Expected the update check to fail";
     } catch (e) {}
   }
 });
 
 add_task(async function() {
   // Make sure that the JSON manifest is rejected when an update key is
   // required, but perform the remaining tests which aren't expected to fail
   // because of the update key, without requiring one for the JSON variant.
 
   try {
     await checkUpdates("test_bug378216_8@tests.mozilla.org",
-                       updateKey, "test_updatecheck.json");
+                       "test_updatecheck.json");
 
     throw "Expected the update check to fail";
   } catch (e) {}
 
-  for (let [file, key] of [["test_updatecheck.rdf", updateKey],
-                           ["test_updatecheck.json", null]]) {
+  for (let file of ["test_updatecheck.rdf",
+                    "test_updatecheck.json"]) {
     let updates = await checkUpdates("test_bug378216_8@tests.mozilla.org",
-                                     key, file);
+                                     file);
     equal(updates.length, 1);
     ok(!("updateURL" in updates[0]));
   }
 });
 
 add_task(async function() {
-  for (let [file, key] of [["test_updatecheck.rdf", updateKey],
-                           ["test_updatecheck.json", null]]) {
+  for (let file of ["test_updatecheck.rdf",
+                    "test_updatecheck.json"]) {
     let updates = await checkUpdates("test_bug378216_9@tests.mozilla.org",
-                                     key, file);
+                                     file);
     equal(updates.length, 1);
     equal(updates[0].version, "2.0");
     ok("updateURL" in updates[0]);
   }
 });
 
 add_task(async function() {
-  for (let [file, key] of [["test_updatecheck.rdf", updateKey],
-                           ["test_updatecheck.json", null]]) {
+  for (let file of ["test_updatecheck.rdf",
+                    "test_updatecheck.json"]) {
     let updates = await checkUpdates("test_bug378216_10@tests.mozilla.org",
-                                     key, file);
+                                     file);
     equal(updates.length, 1);
     equal(updates[0].version, "2.0");
     ok("updateURL" in updates[0]);
   }
 });
 
 add_task(async function() {
-  for (let [file, key] of [["test_updatecheck.rdf", updateKey],
-                           ["test_updatecheck.json", null]]) {
+  for (let file of ["test_updatecheck.rdf",
+                    "test_updatecheck.json"]) {
     let updates = await checkUpdates("test_bug378216_11@tests.mozilla.org",
-                                     key, file);
+                                     file);
     equal(updates.length, 1);
     equal(updates[0].version, "2.0");
     ok("updateURL" in updates[0]);
   }
 });
 
 add_task(async function() {
-  for (let [file, key] of [["test_updatecheck.rdf", updateKey],
-                           ["test_updatecheck.json", null]]) {
+  for (let file of ["test_updatecheck.rdf",
+                    "test_updatecheck.json"]) {
     let updates = await checkUpdates("test_bug378216_12@tests.mozilla.org",
-                                     key, file);
+                                     file);
     equal(updates.length, 1);
     Assert.equal(false, "updateURL" in updates[0]);
   }
 });
 
 add_task(async function() {
-  for (let [file, key] of [["test_updatecheck.rdf", updateKey],
-                           ["test_updatecheck.json", null]]) {
+  for (let file of ["test_updatecheck.rdf",
+                    "test_updatecheck.json"]) {
     let updates = await checkUpdates("test_bug378216_13@tests.mozilla.org",
-                                     key, file);
+                                     file);
     equal(updates.length, 1);
     equal(updates[0].version, "2.0");
     ok("updateURL" in updates[0]);
   }
 });
 
 add_task(async function() {
   for (let file of ["test_updatecheck.rdf", "test_updatecheck.json"]) {
     let updates = await checkUpdates("test_bug378216_14@tests.mozilla.org",
-                                     null, file);
+                                     file);
     equal(updates.length, 0);
   }
 });
 
 add_task(async function() {
   for (let file of ["test_updatecheck.rdf", "test_updatecheck.json"]) {
     try {
       await checkUpdates("test_bug378216_15@tests.mozilla.org",
-                         null, file);
+                         file);
 
       throw "Update check should have failed";
     } catch (e) {
       equal(e.status, AddonManager.ERROR_PARSE_ERROR);
     }
   }
 });
 
 add_task(async function() {
   for (let file of ["test_updatecheck.rdf", "test_updatecheck.json"]) {
     let updates = await checkUpdates("ignore-compat@tests.mozilla.org",
-                                     null, file);
+                                     file);
     equal(updates.length, 3);
     let update = AddonUpdateChecker.getNewestCompatibleUpdate(
       updates, null, null, true);
     notEqual(update, null);
     equal(update.version, 2);
   }
 });
 
 add_task(async function() {
   for (let file of ["test_updatecheck.rdf", "test_updatecheck.json"]) {
     let updates = await checkUpdates("compat-override@tests.mozilla.org",
-                                     null, file);
+                                     file);
     equal(updates.length, 3);
     let overrides = [{
       type: "incompatible",
       minVersion: 1,
       maxVersion: 2,
       appID: "xpcshell@tests.mozilla.org",
       appMinVersion: 0.1,
       appMaxVersion: 0.2
@@ -222,15 +217,15 @@ add_task(async function() {
     notEqual(update, null);
     equal(update.version, 1);
   }
 });
 
 add_task(async function() {
   for (let file of ["test_updatecheck.rdf", "test_updatecheck.json"]) {
     let updates = await checkUpdates("compat-strict-optin@tests.mozilla.org",
-                                     null, file);
+                                     file);
     equal(updates.length, 1);
     let update = AddonUpdateChecker.getNewestCompatibleUpdate(
       updates, null, null, true, false);
     equal(update, null);
   }
 });