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
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)
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)
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)
def _create_payload_incremental(): target_file = construct_target_files() source_file = construct_target_files() payload = Payload() payload.Generate(target_file, source_file) return payload
def _create_payload_full(secondary=False): target_file = construct_target_files(secondary) payload = Payload(secondary) payload.Generate(target_file) return payload