Verified Commit fc8bfcf0 authored by Kathleen Brade's avatar Kathleen Brade Committed by Pier Angelo Vendrame
Browse files

Bug 19121: reinstate the update.xml hash check

This is a partial revert of commit f1241db6.

Revert most changes from Mozilla Bug 862173 "don't verify mar file hash
when using mar signing to verify the mar file (lessens main thread I/O)."

We kept the addition to the AppConstants API in case other JS code
references it in the future.
parent 03743f6a
Loading
Loading
Loading
Loading
+62 −1
Original line number Diff line number Diff line
@@ -2127,6 +2127,8 @@ function UpdatePatch(patch) {
        }
        break;
      case "finalURL":
      case "hashFunction":
      case "hashValue":
      case "state":
      case "type":
      case "URL":
@@ -2146,6 +2148,8 @@ UpdatePatch.prototype = {
  // over writing nsIUpdatePatch attributes.
  _attrNames: [
    "errorCode",
    "hashFunction",
    "hashValue",
    "finalURL",
    "selected",
    "size",
@@ -2159,6 +2163,8 @@ UpdatePatch.prototype = {
   */
  serialize: function UpdatePatch_serialize(updates) {
    var patch = updates.createElementNS(URI_UPDATE_NS, "patch");
    patch.setAttribute("hashFunction", this.hashFunction);
    patch.setAttribute("hashValue", this.hashValue);
    patch.setAttribute("size", this.size);
    patch.setAttribute("type", this.type);
    patch.setAttribute("URL", this.URL);
@@ -5786,7 +5792,56 @@ Downloader.prototype = {
    }

    LOG("Downloader:_verifyDownload downloaded size == expected size.");
    let fileStream = Cc[
      "@mozilla.org/network/file-input-stream;1"
    ].createInstance(Ci.nsIFileInputStream);
    fileStream.init(
      destination,
      FileUtils.MODE_RDONLY,
      FileUtils.PERMS_FILE,
      0
    );

    let digest;
    try {
      let hash = Cc["@mozilla.org/security/hash;1"].createInstance(
        Ci.nsICryptoHash
      );
      var hashFunction =
        Ci.nsICryptoHash[this._patch.hashFunction.toUpperCase()];
      if (hashFunction == undefined) {
        throw Components.Exception("", Cr.NS_ERROR_UNEXPECTED);
      }
      hash.init(hashFunction);
      hash.updateFromStream(fileStream, -1);
      // NOTE: For now, we assume that the format of _patch.hashValue is hex
      // encoded binary (such as what is typically output by programs like
      // sha1sum).  In the future, this may change to base64 depending on how
      // we choose to compute these hashes.
      hash = hash.finish(false);
      digest = Array.from(hash, (c, i) =>
        hash.charCodeAt(i).toString(16).padStart(2, "0")
      ).join("");
    } catch (e) {
      LOG(
        "Downloader:_verifyDownload - failed to compute hash of the downloaded update archive"
      );
      digest = "";
    }

    fileStream.close();

    if (digest == this._patch.hashValue.toLowerCase()) {
      LOG("Downloader:_verifyDownload hashes match.");
      return true;
    }

    LOG("Downloader:_verifyDownload hashes do not match. ");
    AUSTLMY.pingDownloadCode(
      this.isCompleteUpdate,
      AUSTLMY.DWNLD_ERR_VERIFY_NO_HASH_MATCH
    );
    return false;
  },

  /**
@@ -6422,6 +6477,9 @@ Downloader.prototype = {
          " is higher than patch size: " +
          this._patch.size
      );
      // It's important that we use a different code than
      // NS_ERROR_CORRUPTED_CONTENT so that tests can verify the difference
      // between a hash error and a wrong download error.
      AUSTLMY.pingDownloadCode(
        this.isCompleteUpdate,
        AUSTLMY.DWNLD_ERR_PATCH_SIZE_LARGER
@@ -6440,6 +6498,9 @@ Downloader.prototype = {
          " is not equal to expected patch size: " +
          this._patch.size
      );
      // It's important that we use a different code than
      // NS_ERROR_CORRUPTED_CONTENT so that tests can verify the difference
      // between a hash error and a wrong download error.
      AUSTLMY.pingDownloadCode(
        this.isCompleteUpdate,
        AUSTLMY.DWNLD_ERR_PATCH_SIZE_NOT_EQUAL
+1 −0
Original line number Diff line number Diff line
@@ -190,6 +190,7 @@ export var AUSTLMY = {
  DWNLD_ERR_VERIFY_NO_REQUEST: 13,
  DWNLD_ERR_VERIFY_PATCH_SIZE_NOT_EQUAL: 14,
  DWNLD_ERR_WRITE_FAILURE: 15,
  DWNLD_ERR_VERIFY_NO_HASH_MATCH: 16,
  // Temporary failure code to see if there are failures without an update phase
  DWNLD_UNKNOWN_PHASE_ERR_WRITE_FAILURE: 40,

+11 −0
Original line number Diff line number Diff line
@@ -39,6 +39,17 @@ interface nsIUpdatePatch : nsISupports
   */
  attribute AString finalURL;

  /**
   * The hash function to use when determining this file's integrity
   */
  attribute AString hashFunction;

  /**
   * The value of the hash function named above that should be computed if
   * this file is not corrupt.
   */
  attribute AString hashValue;

  /**
   * The size of this file, in bytes.
   */