forked from openkylin/platform_build
rebuild recovery patch in sign_target_files_apks
The target_files zip should now contain the recovery-from-boot patch and the script to install it. This means that sign_target_files_apks, which generates a signed target_files from an unsigned target_files, now needs to recompute the patch and script (taking into account the key replacement, property changes, etc., that it does) so its output contains the correct patch. Change-Id: I18afd73864ba5c480b7ec11de19d1f5e7763a8c0
This commit is contained in:
parent
ca389b9048
commit
412c02fffb
|
@ -990,7 +990,8 @@ def ParseCertificate(data):
|
||||||
return cert
|
return cert
|
||||||
|
|
||||||
|
|
||||||
def MakeRecoveryPatch(input_dir, output_sink, recovery_img, boot_img):
|
def MakeRecoveryPatch(input_dir, output_sink, recovery_img, boot_img,
|
||||||
|
info_dict=None):
|
||||||
"""Generate a binary patch that creates the recovery image starting
|
"""Generate a binary patch that creates the recovery image starting
|
||||||
with the boot image. (Most of the space in these images is just the
|
with the boot image. (Most of the space in these images is just the
|
||||||
kernel, which is identical for the two, so the resulting patch
|
kernel, which is identical for the two, so the resulting patch
|
||||||
|
@ -1003,6 +1004,9 @@ def MakeRecoveryPatch(input_dir, output_sink, recovery_img, boot_img):
|
||||||
common.LoadInfoDict() on the input target_files.
|
common.LoadInfoDict() on the input target_files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if info_dict is None:
|
||||||
|
info_dict = OPTIONS.info_dict
|
||||||
|
|
||||||
diff_program = ["imgdiff"]
|
diff_program = ["imgdiff"]
|
||||||
path = os.path.join(input_dir, "SYSTEM", "etc", "recovery-resource.dat")
|
path = os.path.join(input_dir, "SYSTEM", "etc", "recovery-resource.dat")
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
|
@ -1016,8 +1020,8 @@ def MakeRecoveryPatch(input_dir, output_sink, recovery_img, boot_img):
|
||||||
_, _, patch = d.ComputePatch()
|
_, _, patch = d.ComputePatch()
|
||||||
output_sink("recovery-from-boot.p", patch)
|
output_sink("recovery-from-boot.p", patch)
|
||||||
|
|
||||||
boot_type, boot_device = GetTypeAndDevice("/boot", OPTIONS.info_dict)
|
boot_type, boot_device = GetTypeAndDevice("/boot", info_dict)
|
||||||
recovery_type, recovery_device = GetTypeAndDevice("/recovery", OPTIONS.info_dict)
|
recovery_type, recovery_device = GetTypeAndDevice("/recovery", info_dict)
|
||||||
|
|
||||||
sh = """#!/system/bin/sh
|
sh = """#!/system/bin/sh
|
||||||
if ! applypatch -c %(recovery_type)s:%(recovery_device)s:%(recovery_size)d:%(recovery_sha1)s; then
|
if ! applypatch -c %(recovery_type)s:%(recovery_device)s:%(recovery_size)d:%(recovery_sha1)s; then
|
||||||
|
|
|
@ -77,6 +77,7 @@ import copy
|
||||||
import errno
|
import errno
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
import zipfile
|
import zipfile
|
||||||
|
@ -139,14 +140,40 @@ def SignApk(data, keyname, pw):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def SignApks(input_tf_zip, output_tf_zip, apk_key_map, key_passwords):
|
def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
|
||||||
|
apk_key_map, key_passwords):
|
||||||
maxsize = max([len(os.path.basename(i.filename))
|
maxsize = max([len(os.path.basename(i.filename))
|
||||||
for i in input_tf_zip.infolist()
|
for i in input_tf_zip.infolist()
|
||||||
if i.filename.endswith('.apk')])
|
if i.filename.endswith('.apk')])
|
||||||
|
rebuild_recovery = False
|
||||||
|
|
||||||
|
tmpdir = tempfile.mkdtemp()
|
||||||
|
def write_to_temp(fn, attr, data):
|
||||||
|
fn = os.path.join(tmpdir, fn)
|
||||||
|
if fn.endswith("/"):
|
||||||
|
fn = os.path.join(tmpdir, fn)
|
||||||
|
os.mkdir(fn)
|
||||||
|
else:
|
||||||
|
d = os.path.dirname(fn)
|
||||||
|
if d and not os.path.exists(d):
|
||||||
|
os.makedirs(d)
|
||||||
|
|
||||||
|
if attr >> 16 == 0xa1ff:
|
||||||
|
os.symlink(data, fn)
|
||||||
|
else:
|
||||||
|
with open(fn, "wb") as f:
|
||||||
|
f.write(data)
|
||||||
|
|
||||||
for info in input_tf_zip.infolist():
|
for info in input_tf_zip.infolist():
|
||||||
data = input_tf_zip.read(info.filename)
|
data = input_tf_zip.read(info.filename)
|
||||||
out_info = copy.copy(info)
|
out_info = copy.copy(info)
|
||||||
|
|
||||||
|
if (info.filename.startswith("BOOT/") or
|
||||||
|
info.filename.startswith("RECOVERY/") or
|
||||||
|
info.filename.startswith("META/") or
|
||||||
|
info.filename == "SYSTEM/etc/recovery-resource.dat"):
|
||||||
|
write_to_temp(info.filename, info.external_attr, data)
|
||||||
|
|
||||||
if info.filename.endswith(".apk"):
|
if info.filename.endswith(".apk"):
|
||||||
name = os.path.basename(info.filename)
|
name = os.path.basename(info.filename)
|
||||||
key = apk_key_map[name]
|
key = apk_key_map[name]
|
||||||
|
@ -163,14 +190,43 @@ def SignApks(input_tf_zip, output_tf_zip, apk_key_map, key_passwords):
|
||||||
print "rewriting %s:" % (info.filename,)
|
print "rewriting %s:" % (info.filename,)
|
||||||
new_data = RewriteProps(data)
|
new_data = RewriteProps(data)
|
||||||
output_tf_zip.writestr(out_info, new_data)
|
output_tf_zip.writestr(out_info, new_data)
|
||||||
|
if info.filename == "RECOVERY/RAMDISK/default.prop":
|
||||||
|
write_to_temp(info.filename, info.external_attr, new_data)
|
||||||
elif info.filename.endswith("mac_permissions.xml"):
|
elif info.filename.endswith("mac_permissions.xml"):
|
||||||
print "rewriting %s with new keys." % (info.filename,)
|
print "rewriting %s with new keys." % (info.filename,)
|
||||||
new_data = ReplaceCerts(data)
|
new_data = ReplaceCerts(data)
|
||||||
output_tf_zip.writestr(out_info, new_data)
|
output_tf_zip.writestr(out_info, new_data)
|
||||||
|
elif info.filename in ("SYSTEM/recovery-from-boot.p",
|
||||||
|
"SYSTEM/bin/install-recovery.sh"):
|
||||||
|
rebuild_recovery = True
|
||||||
|
elif (OPTIONS.replace_ota_keys and
|
||||||
|
info.filename in ("RECOVERY/RAMDISK/res/keys",
|
||||||
|
"SYSTEM/etc/security/otacerts.zip")):
|
||||||
|
# don't copy these files if we're regenerating them below
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
# a non-APK file; copy it verbatim
|
# a non-APK file; copy it verbatim
|
||||||
output_tf_zip.writestr(out_info, data)
|
output_tf_zip.writestr(out_info, data)
|
||||||
|
|
||||||
|
if OPTIONS.replace_ota_keys:
|
||||||
|
new_recovery_keys = ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info)
|
||||||
|
if new_recovery_keys:
|
||||||
|
write_to_temp("RECOVERY/RAMDISK/res/keys", 0755 << 16, new_recovery_keys)
|
||||||
|
|
||||||
|
if rebuild_recovery:
|
||||||
|
recovery_img = common.GetBootableImage(
|
||||||
|
"recovery.img", "recovery.img", tmpdir, "RECOVERY", info_dict=misc_info)
|
||||||
|
boot_img = common.GetBootableImage(
|
||||||
|
"boot.img", "boot.img", tmpdir, "BOOT", info_dict=misc_info)
|
||||||
|
|
||||||
|
def output_sink(fn, data):
|
||||||
|
output_tf_zip.writestr("SYSTEM/"+fn, data)
|
||||||
|
|
||||||
|
common.MakeRecoveryPatch(tmpdir, output_sink, recovery_img, boot_img,
|
||||||
|
info_dict=misc_info)
|
||||||
|
|
||||||
|
shutil.rmtree(tmpdir)
|
||||||
|
|
||||||
|
|
||||||
def ReplaceCerts(data):
|
def ReplaceCerts(data):
|
||||||
"""Given a string of data, replace all occurences of a set
|
"""Given a string of data, replace all occurences of a set
|
||||||
|
@ -265,7 +321,8 @@ def ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info):
|
||||||
for k in keylist:
|
for k in keylist:
|
||||||
m = re.match(r"^(.*)\.x509\.pem$", k)
|
m = re.match(r"^(.*)\.x509\.pem$", k)
|
||||||
if not m:
|
if not m:
|
||||||
raise common.ExternalError("can't parse \"%s\" from META/otakeys.txt" % (k,))
|
raise common.ExternalError(
|
||||||
|
"can't parse \"%s\" from META/otakeys.txt" % (k,))
|
||||||
k = m.group(1)
|
k = m.group(1)
|
||||||
mapped_keys.append(OPTIONS.key_map.get(k, k) + ".x509.pem")
|
mapped_keys.append(OPTIONS.key_map.get(k, k) + ".x509.pem")
|
||||||
|
|
||||||
|
@ -287,10 +344,11 @@ def ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info):
|
||||||
os.path.join(OPTIONS.search_path, "framework", "dumpkey.jar")]
|
os.path.join(OPTIONS.search_path, "framework", "dumpkey.jar")]
|
||||||
+ mapped_keys + extra_recovery_keys,
|
+ mapped_keys + extra_recovery_keys,
|
||||||
stdout=subprocess.PIPE)
|
stdout=subprocess.PIPE)
|
||||||
data, _ = p.communicate()
|
new_recovery_keys, _ = p.communicate()
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise common.ExternalError("failed to run dumpkeys")
|
raise common.ExternalError("failed to run dumpkeys")
|
||||||
common.ZipWriteStr(output_tf_zip, "RECOVERY/RAMDISK/res/keys", data)
|
common.ZipWriteStr(output_tf_zip, "RECOVERY/RAMDISK/res/keys",
|
||||||
|
new_recovery_keys)
|
||||||
|
|
||||||
# SystemUpdateActivity uses the x509.pem version of the keys, but
|
# SystemUpdateActivity uses the x509.pem version of the keys, but
|
||||||
# put into a zipfile system/etc/security/otacerts.zip.
|
# put into a zipfile system/etc/security/otacerts.zip.
|
||||||
|
@ -304,6 +362,8 @@ def ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info):
|
||||||
common.ZipWriteStr(output_tf_zip, "SYSTEM/etc/security/otacerts.zip",
|
common.ZipWriteStr(output_tf_zip, "SYSTEM/etc/security/otacerts.zip",
|
||||||
tempfile.getvalue())
|
tempfile.getvalue())
|
||||||
|
|
||||||
|
return new_recovery_keys
|
||||||
|
|
||||||
|
|
||||||
def BuildKeyMap(misc_info, key_mapping_options):
|
def BuildKeyMap(misc_info, key_mapping_options):
|
||||||
for s, d in key_mapping_options:
|
for s, d in key_mapping_options:
|
||||||
|
@ -375,10 +435,8 @@ def main(argv):
|
||||||
CheckAllApksSigned(input_zip, apk_key_map)
|
CheckAllApksSigned(input_zip, apk_key_map)
|
||||||
|
|
||||||
key_passwords = common.GetKeyPasswords(set(apk_key_map.values()))
|
key_passwords = common.GetKeyPasswords(set(apk_key_map.values()))
|
||||||
SignApks(input_zip, output_zip, apk_key_map, key_passwords)
|
ProcessTargetFiles(input_zip, output_zip, misc_info,
|
||||||
|
apk_key_map, key_passwords)
|
||||||
if OPTIONS.replace_ota_keys:
|
|
||||||
ReplaceOtaKeys(input_zip, output_zip, misc_info)
|
|
||||||
|
|
||||||
input_zip.close()
|
input_zip.close()
|
||||||
output_zip.close()
|
output_zip.close()
|
||||||
|
|
Loading…
Reference in New Issue