Add payload_hash/metadata_hash to update scripts

This makes debugging signature related OTA problems easier, developers
can easily inspect the actual hashes of an OTA package.

Test: th
Change-Id: Ia7f6e8f313a5fda4dc9f9ee4416fd9c9e9b80d5c
diff --git a/scripts/update_device.py b/scripts/update_device.py
index 18968aa..f515140 100755
--- a/scripts/update_device.py
+++ b/scripts/update_device.py
@@ -35,11 +35,10 @@
 import threading
 import xml.etree.ElementTree
 import zipfile
+import shutil
 
 from six.moves import BaseHTTPServer
 
-import update_payload.payload
-
 
 # The path used to store the OTA package when applying the package from a file.
 OTA_PACKAGE_PATH = '/data/ota_package'
@@ -323,19 +322,25 @@
 
 
 def PushMetadata(dut, otafile, metadata_path):
-  payload = update_payload.Payload(otafile)
-  payload.Init()
+  header_format = ">4sQQL"
   with tempfile.TemporaryDirectory() as tmpdir:
     with zipfile.ZipFile(otafile, "r") as zfp:
       extracted_path = os.path.join(tmpdir, "payload.bin")
       with zfp.open("payload.bin") as payload_fp, \
               open(extracted_path, "wb") as output_fp:
-          # Only extract the first |data_offset| bytes from the payload.
-          # This is because allocateSpaceForPayload only needs to see
-          # the manifest, not the entire payload.
-          # Extracting the entire payload works, but is slow for full
-          # OTA.
-        output_fp.write(payload_fp.read(payload.data_offset))
+        # Only extract the first |data_offset| bytes from the payload.
+        # This is because allocateSpaceForPayload only needs to see
+        # the manifest, not the entire payload.
+        # Extracting the entire payload works, but is slow for full
+        # OTA.
+        header = payload_fp.read(struct.calcsize(header_format))
+        magic, major_version, manifest_size, metadata_signature_size = struct.unpack(header_format, header)
+        assert magic == b"CrAU", "Invalid magic {}, expected CrAU".format(magic)
+        assert major_version == 2, "Invalid major version {}, only version 2 is supported".format(major_version)
+        output_fp.write(header)
+
+        shutil.copyfileobj(payload_fp, output_fp, manifest_size + metadata_signature_size)
+
 
       return dut.adb([
           "push",
diff --git a/scripts/update_payload/payload.py b/scripts/update_payload/payload.py
index 4abd63e..8771ee4 100644
--- a/scripts/update_payload/payload.py
+++ b/scripts/update_payload/payload.py
@@ -152,6 +152,19 @@
     self.Init()
 
   @property
+  def metadata_hash(self):
+    return self.manifest_hasher.digest()
+
+  @property
+  def payload_hash(self):
+    hasher = hashlib.sha256()
+    self.payload_file.seek(0)
+    hasher.update(self.payload_file.read(self.metadata_size))
+    self.payload_file.seek(self.header.metadata_signature_len, io.SEEK_CUR)
+    hasher.update(self.payload_file.read(self.total_data_length))
+    return hasher.digest()
+
+  @property
   def is_incremental(self):
     return any([part.HasField("old_partition_info") for part in self.manifest.partitions])