Bug 1446571: Part 1 - Remove support for signed update.rdf files. r=aswan
authorKris Maglione <maglione.k@gmail.com>
Fri, 16 Mar 2018 17:51:11 -0700
changeset 462696 86939af02a1b6350f24fa54203df8ad234a10443
parent 462695 68e32f5b50e77717939fbf4f7a96bda0eaa2561b
child 462697 cf1de28c600148249a6b0bd24dcadbc026890fb0
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaswan
bugs1446571
milestone61.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 1446571: Part 1 - Remove support for signed update.rdf files. r=aswan 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
@@ -739,17 +739,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;
 }
@@ -2650,18 +2648,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
@@ -4771,18 +4771,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);
   }
 });