Beispiel #1
0
  def construct_zip_package_withValidPayload(with_metadata=False):
    # Cannot use construct_zip_package() since we need a "valid" payload.bin.
    target_file = construct_target_files()
    payload = Payload()
    payload.Generate(target_file)

    payload_signer = PayloadSigner()
    payload.Sign(payload_signer)

    zip_file = common.MakeTempFile(suffix='.zip')
    with zipfile.ZipFile(zip_file, 'w') as zip_fp:
      # 'payload.bin',
      payload.WriteToZip(zip_fp)

      # Other entries.
      entries = ['care_map.txt', 'compatibility.zip']

      # Put META-INF/com/android/metadata if needed.
      if with_metadata:
        entries.append('META-INF/com/android/metadata')

      for entry in entries:
        zip_fp.writestr(
            entry, entry.replace('.', '-').upper(), zipfile.ZIP_STORED)

    return zip_file
Beispiel #2
0
 def test_Generate_additionalArgs(self):
   target_file = construct_target_files()
   source_file = construct_target_files()
   payload = Payload()
   # This should work the same as calling payload.Generate(target_file,
   # source_file).
   payload.Generate(
       target_file, additional_args=["--source_image", source_file])
   self.assertTrue(os.path.exists(payload.payload_file))
  def test_GetPayloadMetadataOffsetAndSize(self):
    target_file = construct_target_files()
    payload = Payload()
    payload.Generate(target_file)

    payload_signer = PayloadSigner()
    payload.Sign(payload_signer)

    output_file = common.MakeTempFile(suffix='.zip')
    with zipfile.ZipFile(output_file, 'w') as output_zip:
      payload.WriteToZip(output_zip)

    # Find out the payload metadata offset and size.
    property_files = AbOtaPropertyFiles()
    with zipfile.ZipFile(output_file) as input_zip:
      # pylint: disable=protected-access
      payload_offset, metadata_total = (
          property_files._GetPayloadMetadataOffsetAndSize(input_zip))

    # Read in the metadata signature directly.
    with open(output_file, 'rb') as verify_fp:
      verify_fp.seek(payload_offset + metadata_total - self.SIGNATURE_SIZE)
      metadata_signature = verify_fp.read(self.SIGNATURE_SIZE)

    # Now we extract the metadata hash via brillo_update_payload script, which
    # will serve as the oracle result.
    payload_sig_file = common.MakeTempFile(prefix="sig-", suffix=".bin")
    metadata_sig_file = common.MakeTempFile(prefix="sig-", suffix=".bin")
    cmd = ['brillo_update_payload', 'hash',
           '--unsigned_payload', payload.payload_file,
           '--signature_size', str(self.SIGNATURE_SIZE),
           '--metadata_hash_file', metadata_sig_file,
           '--payload_hash_file', payload_sig_file]
    proc = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    stdoutdata, _ = proc.communicate()
    self.assertEqual(
        0, proc.returncode,
        'Failed to run brillo_update_payload: {}'.format(stdoutdata))

    signed_metadata_sig_file = payload_signer.Sign(metadata_sig_file)

    # Finally we can compare the two signatures.
    with open(signed_metadata_sig_file, 'rb') as verify_fp:
      self.assertEqual(verify_fp.read(), metadata_signature)
Beispiel #4
0
  def test_GetPayloadMetadataOffsetAndSize(self):
    target_file = construct_target_files()
    payload = Payload()
    payload.Generate(target_file)

    payload_signer = PayloadSigner()
    payload.Sign(payload_signer)

    output_file = common.MakeTempFile(suffix='.zip')
    with zipfile.ZipFile(output_file, 'w') as output_zip:
      payload.WriteToZip(output_zip)

    # Find out the payload metadata offset and size.
    property_files = AbOtaPropertyFiles()
    with zipfile.ZipFile(output_file) as input_zip:
      # pylint: disable=protected-access
      payload_offset, metadata_total = (
          property_files._GetPayloadMetadataOffsetAndSize(input_zip))

    # The signature proto has the following format (details in
    #  /platform/system/update_engine/update_metadata.proto):
    #  message Signature {
    #    optional uint32 version = 1;
    #    optional bytes data = 2;
    #    optional fixed32 unpadded_signature_size = 3;
    #  }
    #
    # According to the protobuf encoding, the tail of the signature message will
    # be [signature string(256 bytes) + encoding of the fixed32 number 256]. And
    # 256 is encoded as 'x1d\x00\x01\x00\x00':
    # [3 (field number) << 3 | 5 (type) + byte reverse of 0x100 (256)].
    # Details in (https://developers.google.com/protocol-buffers/docs/encoding)
    signature_tail_length = self.SIGNATURE_SIZE + 5
    self.assertGreater(metadata_total, signature_tail_length)
    with open(output_file, 'rb') as verify_fp:
      verify_fp.seek(payload_offset + metadata_total - signature_tail_length)
      metadata_signature_proto_tail = verify_fp.read(signature_tail_length)

    self.assertEqual(b'\x1d\x00\x01\x00\x00',
                     metadata_signature_proto_tail[-5:])
    metadata_signature = metadata_signature_proto_tail[:-5]

    # Now we extract the metadata hash via brillo_update_payload script, which
    # will serve as the oracle result.
    payload_sig_file = common.MakeTempFile(prefix="sig-", suffix=".bin")
    metadata_sig_file = common.MakeTempFile(prefix="sig-", suffix=".bin")
    cmd = ['brillo_update_payload', 'hash',
           '--unsigned_payload', payload.payload_file,
           '--signature_size', str(self.SIGNATURE_SIZE),
           '--metadata_hash_file', metadata_sig_file,
           '--payload_hash_file', payload_sig_file]
    proc = common.Run(cmd)
    stdoutdata, _ = proc.communicate()
    self.assertEqual(
        0, proc.returncode,
        'Failed to run brillo_update_payload:\n{}'.format(stdoutdata))

    signed_metadata_sig_file = payload_signer.Sign(metadata_sig_file)

    # Finally we can compare the two signatures.
    with open(signed_metadata_sig_file, 'rb') as verify_fp:
      self.assertEqual(verify_fp.read(), metadata_signature)
Beispiel #5
0
 def test_Generate_invalidInput(self):
   target_file = construct_target_files()
   common.ZipDelete(target_file, 'IMAGES/vendor.img')
   payload = Payload()
   self.assertRaises(common.ExternalError, payload.Generate, target_file)
Beispiel #6
0
 def _create_payload_incremental():
   target_file = construct_target_files()
   source_file = construct_target_files()
   payload = Payload()
   payload.Generate(target_file, source_file)
   return payload
Beispiel #7
0
 def _create_payload_full(secondary=False):
   target_file = construct_target_files(secondary)
   payload = Payload(secondary)
   payload.Generate(target_file)
   return payload