1eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker#!/usr/bin/env python 2eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# 3eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# Copyright (C) 2008 The Android Open Source Project 4eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# 5eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# Licensed under the Apache License, Version 2.0 (the "License"); 6eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# you may not use this file except in compliance with the License. 7eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# You may obtain a copy of the License at 8eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# 9eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# http://www.apache.org/licenses/LICENSE-2.0 10eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# 11eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# Unless required by applicable law or agreed to in writing, software 12eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# distributed under the License is distributed on an "AS IS" BASIS, 13eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# See the License for the specific language governing permissions and 15eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# limitations under the License. 16eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 17eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker""" 18eef3944eb3673329b5e89cf188ac592805a0b08dDoug ZongkerSigns all the APK files in a target-files zipfile, producing a new 19eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkertarget-files zip. 20eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 21eef3944eb3673329b5e89cf188ac592805a0b08dDoug ZongkerUsage: sign_target_files_apks [flags] input_target_files output_target_files 22eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 23eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker -e (--extra_apks) <name,name,...=key> 24eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker Add extra APK name/key pairs as though they appeared in 25ad88c7ce4f3a65827d4cd5b5ed01324b3b368dd9Doug Zongker apkcerts.txt (so mappings specified by -k and -d are applied). 26ad88c7ce4f3a65827d4cd5b5ed01324b3b368dd9Doug Zongker Keys specified in -e override any value for that app contained 27ad88c7ce4f3a65827d4cd5b5ed01324b3b368dd9Doug Zongker in the apkcerts.txt file. Option may be repeated to give 28ad88c7ce4f3a65827d4cd5b5ed01324b3b368dd9Doug Zongker multiple extra packages. 29eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 30eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker -k (--key_mapping) <src_key=dest_key> 31eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker Add a mapping from the key name as specified in apkcerts.txt (the 32eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker src_key) to the real key you wish to sign the package with 33eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker (dest_key). Option may be repeated to give multiple key 34eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker mappings. 35eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 36eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker -d (--default_key_mappings) <dir> 37eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker Set up the following key mappings: 38eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 39831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker $devkey/devkey ==> $dir/releasekey 40831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker $devkey/testkey ==> $dir/releasekey 41831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker $devkey/media ==> $dir/media 42831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker $devkey/shared ==> $dir/shared 43831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker $devkey/platform ==> $dir/platform 44831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker 45831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker where $devkey is the directory part of the value of 46831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker default_system_dev_certificate from the input target-files's 47831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker META/misc_info.txt. (Defaulting to "build/target/product/security" 48831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker if the value is not present in misc_info. 49eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 50eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker -d and -k options are added to the set of mappings in the order 51eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker in which they appear on the command line. 528e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 538e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker -o (--replace_ota_keys) 548e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker Replace the certificate (public key) used by OTA package 558e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker verification with the one specified in the input target_files 568e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker zip (in the META/otakeys.txt file). Key remapping (-k and -d) 578e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker is performed on this key. 5817aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker 59ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker -t (--tag_changes) <+tag>,<-tag>,... 60ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker Comma-separated list of changes to make to the set of tags (in 61ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker the last component of the build fingerprint). Prefix each with 62ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker '+' or '-' to indicate whether that tag should be added or 63ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker removed. Changes are processed in the order they appear. 64831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker Default value is "-test-keys,-dev-keys,+release-keys". 65ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker 66eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker""" 67eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 68eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport sys 69eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 70cf6d5a90740e50e03d9f16c6fd449d90d396f924Doug Zongkerif sys.hexversion < 0x02070000: 71cf6d5a90740e50e03d9f16c6fd449d90d396f924Doug Zongker print >> sys.stderr, "Python 2.7 or newer is required." 72eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker sys.exit(1) 73eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 74817c574d753191c52acd5787da02bb853d4ac090Robert Craigimport base64 758e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongkerimport cStringIO 768e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongkerimport copy 77817c574d753191c52acd5787da02bb853d4ac090Robert Craigimport errno 78eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport os 79eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport re 80412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongkerimport shutil 81eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport subprocess 82eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport tempfile 83eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport zipfile 84eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 853c84f569487c4e59baa332be33b5430fdefb76b3Doug Zongkerimport add_img_to_target_files 86eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport common 87eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 88eef3944eb3673329b5e89cf188ac592805a0b08dDoug ZongkerOPTIONS = common.OPTIONS 89eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 90eef3944eb3673329b5e89cf188ac592805a0b08dDoug ZongkerOPTIONS.extra_apks = {} 91eef3944eb3673329b5e89cf188ac592805a0b08dDoug ZongkerOPTIONS.key_map = {} 928e931bf999693cac54c99deb1ef668d0e6164ecfDoug ZongkerOPTIONS.replace_ota_keys = False 93f19b365cc9021104586d65385d246db06639fc46Geremy CondraOPTIONS.replace_verity_public_key = False 94f19b365cc9021104586d65385d246db06639fc46Geremy CondraOPTIONS.replace_verity_private_key = False 95831840e51b0403671f746ebc32090b7d6e548c08Doug ZongkerOPTIONS.tag_changes = ("-test-keys", "-dev-keys", "+release-keys") 96eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 97eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerdef GetApkCerts(tf_zip): 98f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker certmap = common.ReadApkCerts(tf_zip) 99f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker 100f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker # apply the key remapping to the contents of the file 101f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker for apk, cert in certmap.iteritems(): 102f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker certmap[apk] = OPTIONS.key_map.get(cert, cert) 103f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker 104f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker # apply all the -e options, overriding anything in the file 105ad88c7ce4f3a65827d4cd5b5ed01324b3b368dd9Doug Zongker for apk, cert in OPTIONS.extra_apks.iteritems(): 106decf995c5956e6f64f858d1c4e51a3f3b9829a51Doug Zongker if not cert: 107decf995c5956e6f64f858d1c4e51a3f3b9829a51Doug Zongker cert = "PRESIGNED" 108ad88c7ce4f3a65827d4cd5b5ed01324b3b368dd9Doug Zongker certmap[apk] = OPTIONS.key_map.get(cert, cert) 109f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker 110eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker return certmap 111eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 112eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 113eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongkerdef CheckAllApksSigned(input_tf_zip, apk_key_map): 114eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker """Check that all the APKs we want to sign have keys specified, and 115eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker error out if they don't.""" 116eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker unknown_apks = [] 117eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker for info in input_tf_zip.infolist(): 118eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker if info.filename.endswith(".apk"): 119eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker name = os.path.basename(info.filename) 120eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker if name not in apk_key_map: 121eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker unknown_apks.append(name) 122eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker if unknown_apks: 123eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker print "ERROR: no key specified for:\n\n ", 124eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker print "\n ".join(unknown_apks) 125eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker print "\nUse '-e <apkname>=' to specify a key (which may be an" 126eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker print "empty string to not sign this apk)." 127eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker sys.exit(1) 128eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker 129eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker 130eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerdef SignApk(data, keyname, pw): 131eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker unsigned = tempfile.NamedTemporaryFile() 132eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker unsigned.write(data) 133eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker unsigned.flush() 134eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 135eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker signed = tempfile.NamedTemporaryFile() 136eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 137eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker common.SignFile(unsigned.name, signed.name, keyname, pw, align=4) 138eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 139eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker data = signed.read() 140eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker unsigned.close() 141eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker signed.close() 142eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 143eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker return data 144eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 145eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 146412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongkerdef ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info, 147412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker apk_key_map, key_passwords): 148dc2661afe263de054be8ecf5f1252a6fbde776c6Michael Runge 149eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker maxsize = max([len(os.path.basename(i.filename)) 150eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker for i in input_tf_zip.infolist() 151eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker if i.filename.endswith('.apk')]) 152412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker rebuild_recovery = False 153412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker 154412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker tmpdir = tempfile.mkdtemp() 155412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker def write_to_temp(fn, attr, data): 156412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker fn = os.path.join(tmpdir, fn) 157412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker if fn.endswith("/"): 158412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker fn = os.path.join(tmpdir, fn) 159412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker os.mkdir(fn) 160412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker else: 161412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker d = os.path.dirname(fn) 162412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker if d and not os.path.exists(d): 163412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker os.makedirs(d) 164412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker 165412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker if attr >> 16 == 0xa1ff: 166412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker os.symlink(data, fn) 167412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker else: 168412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker with open(fn, "wb") as f: 169412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker f.write(data) 170eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 171eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker for info in input_tf_zip.infolist(): 1723c84f569487c4e59baa332be33b5430fdefb76b3Doug Zongker if info.filename.startswith("IMAGES/"): continue 1733c84f569487c4e59baa332be33b5430fdefb76b3Doug Zongker 174eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker data = input_tf_zip.read(info.filename) 1758e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker out_info = copy.copy(info) 176412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker 177f19b365cc9021104586d65385d246db06639fc46Geremy Condra if (info.filename == "META/misc_info.txt" and 178947894f87edd9ae3429d33011447346240200fdbMichael Runge OPTIONS.replace_verity_private_key): 179f19b365cc9021104586d65385d246db06639fc46Geremy Condra ReplaceVerityPrivateKey(input_tf_zip, output_tf_zip, misc_info, OPTIONS.replace_verity_private_key[1]) 180f19b365cc9021104586d65385d246db06639fc46Geremy Condra elif (info.filename == "BOOT/RAMDISK/verity_key" and 181947894f87edd9ae3429d33011447346240200fdbMichael Runge OPTIONS.replace_verity_public_key): 182f19b365cc9021104586d65385d246db06639fc46Geremy Condra ReplaceVerityPublicKey(output_tf_zip, OPTIONS.replace_verity_public_key[1]) 183f19b365cc9021104586d65385d246db06639fc46Geremy Condra elif (info.filename.startswith("BOOT/") or 184412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker info.filename.startswith("RECOVERY/") or 185412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker info.filename.startswith("META/") or 186412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker info.filename == "SYSTEM/etc/recovery-resource.dat"): 187412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker write_to_temp(info.filename, info.external_attr, data) 188412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker 189eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker if info.filename.endswith(".apk"): 190eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker name = os.path.basename(info.filename) 19143874f8c864972b9dae7e4927aa347455b774c94Doug Zongker key = apk_key_map[name] 192f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker if key not in common.SPECIAL_CERT_STRINGS: 19343874f8c864972b9dae7e4927aa347455b774c94Doug Zongker print " signing: %-*s (%s)" % (maxsize, name, key) 194eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker signed_data = SignApk(data, key, key_passwords[key]) 1958e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker output_tf_zip.writestr(out_info, signed_data) 196eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker else: 197eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker # an APK we're not supposed to sign. 19843874f8c864972b9dae7e4927aa347455b774c94Doug Zongker print "NOT signing: %s" % (name,) 1998e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker output_tf_zip.writestr(out_info, data) 2008e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker elif info.filename in ("SYSTEM/build.prop", 2018e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker "RECOVERY/RAMDISK/default.prop"): 20217aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker print "rewriting %s:" % (info.filename,) 203dc2661afe263de054be8ecf5f1252a6fbde776c6Michael Runge new_data = RewriteProps(data, misc_info) 20417aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker output_tf_zip.writestr(out_info, new_data) 205412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker if info.filename == "RECOVERY/RAMDISK/default.prop": 206412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker write_to_temp(info.filename, info.external_attr, new_data) 207817c574d753191c52acd5787da02bb853d4ac090Robert Craig elif info.filename.endswith("mac_permissions.xml"): 208817c574d753191c52acd5787da02bb853d4ac090Robert Craig print "rewriting %s with new keys." % (info.filename,) 209817c574d753191c52acd5787da02bb853d4ac090Robert Craig new_data = ReplaceCerts(data) 210817c574d753191c52acd5787da02bb853d4ac090Robert Craig output_tf_zip.writestr(out_info, new_data) 211412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker elif info.filename in ("SYSTEM/recovery-from-boot.p", 212412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker "SYSTEM/bin/install-recovery.sh"): 213412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker rebuild_recovery = True 214412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker elif (OPTIONS.replace_ota_keys and 215412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker info.filename in ("RECOVERY/RAMDISK/res/keys", 216412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker "SYSTEM/etc/security/otacerts.zip")): 217412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker # don't copy these files if we're regenerating them below 218412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker pass 219947894f87edd9ae3429d33011447346240200fdbMichael Runge elif (OPTIONS.replace_verity_private_key and 220f19b365cc9021104586d65385d246db06639fc46Geremy Condra info.filename == "META/misc_info.txt"): 221f19b365cc9021104586d65385d246db06639fc46Geremy Condra pass 222947894f87edd9ae3429d33011447346240200fdbMichael Runge elif (OPTIONS.replace_verity_public_key and 223f19b365cc9021104586d65385d246db06639fc46Geremy Condra info.filename == "BOOT/RAMDISK/verity_key"): 224f19b365cc9021104586d65385d246db06639fc46Geremy Condra pass 225eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker else: 226eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker # a non-APK file; copy it verbatim 2278e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker output_tf_zip.writestr(out_info, data) 2288e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 229412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker if OPTIONS.replace_ota_keys: 230412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker new_recovery_keys = ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info) 231412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker if new_recovery_keys: 232412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker write_to_temp("RECOVERY/RAMDISK/res/keys", 0755 << 16, new_recovery_keys) 233412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker 234412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker if rebuild_recovery: 235412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker recovery_img = common.GetBootableImage( 236412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker "recovery.img", "recovery.img", tmpdir, "RECOVERY", info_dict=misc_info) 237412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker boot_img = common.GetBootableImage( 238412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker "boot.img", "boot.img", tmpdir, "BOOT", info_dict=misc_info) 239412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker 240412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker def output_sink(fn, data): 241412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker output_tf_zip.writestr("SYSTEM/"+fn, data) 242412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker 243412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker common.MakeRecoveryPatch(tmpdir, output_sink, recovery_img, boot_img, 244412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker info_dict=misc_info) 245412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker 246412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker shutil.rmtree(tmpdir) 247412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker 2488e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 249817c574d753191c52acd5787da02bb853d4ac090Robert Craigdef ReplaceCerts(data): 250817c574d753191c52acd5787da02bb853d4ac090Robert Craig """Given a string of data, replace all occurences of a set 251817c574d753191c52acd5787da02bb853d4ac090Robert Craig of X509 certs with a newer set of X509 certs and return 252817c574d753191c52acd5787da02bb853d4ac090Robert Craig the updated data string.""" 253817c574d753191c52acd5787da02bb853d4ac090Robert Craig for old, new in OPTIONS.key_map.iteritems(): 254817c574d753191c52acd5787da02bb853d4ac090Robert Craig try: 255817c574d753191c52acd5787da02bb853d4ac090Robert Craig if OPTIONS.verbose: 256817c574d753191c52acd5787da02bb853d4ac090Robert Craig print " Replacing %s.x509.pem with %s.x509.pem" % (old, new) 257817c574d753191c52acd5787da02bb853d4ac090Robert Craig f = open(old + ".x509.pem") 258817c574d753191c52acd5787da02bb853d4ac090Robert Craig old_cert16 = base64.b16encode(common.ParseCertificate(f.read())).lower() 259817c574d753191c52acd5787da02bb853d4ac090Robert Craig f.close() 260817c574d753191c52acd5787da02bb853d4ac090Robert Craig f = open(new + ".x509.pem") 261817c574d753191c52acd5787da02bb853d4ac090Robert Craig new_cert16 = base64.b16encode(common.ParseCertificate(f.read())).lower() 262817c574d753191c52acd5787da02bb853d4ac090Robert Craig f.close() 263817c574d753191c52acd5787da02bb853d4ac090Robert Craig # Only match entire certs. 264817c574d753191c52acd5787da02bb853d4ac090Robert Craig pattern = "\\b"+old_cert16+"\\b" 265817c574d753191c52acd5787da02bb853d4ac090Robert Craig (data, num) = re.subn(pattern, new_cert16, data, flags=re.IGNORECASE) 266817c574d753191c52acd5787da02bb853d4ac090Robert Craig if OPTIONS.verbose: 267817c574d753191c52acd5787da02bb853d4ac090Robert Craig print " Replaced %d occurence(s) of %s.x509.pem with " \ 268817c574d753191c52acd5787da02bb853d4ac090Robert Craig "%s.x509.pem" % (num, old, new) 269817c574d753191c52acd5787da02bb853d4ac090Robert Craig except IOError, e: 270817c574d753191c52acd5787da02bb853d4ac090Robert Craig if (e.errno == errno.ENOENT and not OPTIONS.verbose): 271817c574d753191c52acd5787da02bb853d4ac090Robert Craig continue 272817c574d753191c52acd5787da02bb853d4ac090Robert Craig 273817c574d753191c52acd5787da02bb853d4ac090Robert Craig print " Error accessing %s. %s. Skip replacing %s.x509.pem " \ 274817c574d753191c52acd5787da02bb853d4ac090Robert Craig "with %s.x509.pem." % (e.filename, e.strerror, old, new) 275817c574d753191c52acd5787da02bb853d4ac090Robert Craig 276817c574d753191c52acd5787da02bb853d4ac090Robert Craig return data 277817c574d753191c52acd5787da02bb853d4ac090Robert Craig 278817c574d753191c52acd5787da02bb853d4ac090Robert Craig 279c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongkerdef EditTags(tags): 280c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker """Given a string containing comma-separated tags, apply the edits 281c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker specified in OPTIONS.tag_changes and return the updated string.""" 282c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker tags = set(tags.split(",")) 283c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker for ch in OPTIONS.tag_changes: 284c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker if ch[0] == "-": 285c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker tags.discard(ch[1:]) 286c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker elif ch[0] == "+": 287c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker tags.add(ch[1:]) 288c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker return ",".join(sorted(tags)) 289c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker 290c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker 291dc2661afe263de054be8ecf5f1252a6fbde776c6Michael Rungedef RewriteProps(data, misc_info): 29217aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker output = [] 29317aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker for line in data.split("\n"): 29417aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker line = line.strip() 29517aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker original_line = line 296dc2661afe263de054be8ecf5f1252a6fbde776c6Michael Runge if line and line[0] != '#' and "=" in line: 29717aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker key, value = line.split("=", 1) 298dc2661afe263de054be8ecf5f1252a6fbde776c6Michael Runge if (key == "ro.build.fingerprint" 299dc2661afe263de054be8ecf5f1252a6fbde776c6Michael Runge and misc_info.get("oem_fingerprint_properties") is None): 300dc2661afe263de054be8ecf5f1252a6fbde776c6Michael Runge pieces = value.split("/") 301dc2661afe263de054be8ecf5f1252a6fbde776c6Michael Runge pieces[-1] = EditTags(pieces[-1]) 302dc2661afe263de054be8ecf5f1252a6fbde776c6Michael Runge value = "/".join(pieces) 303dc2661afe263de054be8ecf5f1252a6fbde776c6Michael Runge elif (key == "ro.build.thumbprint" 304dc2661afe263de054be8ecf5f1252a6fbde776c6Michael Runge and misc_info.get("oem_fingerprint_properties") is not None): 305c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker pieces = value.split("/") 306c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker pieces[-1] = EditTags(pieces[-1]) 307c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker value = "/".join(pieces) 30817aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker elif key == "ro.build.description": 309c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker pieces = value.split(" ") 31017aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker assert len(pieces) == 5 311c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker pieces[-1] = EditTags(pieces[-1]) 312c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker value = " ".join(pieces) 313c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker elif key == "ro.build.tags": 314c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker value = EditTags(value) 315a8608a7f7cee388192780f8988b5dc5966423eefDoug Zongker elif key == "ro.build.display.id": 316a8608a7f7cee388192780f8988b5dc5966423eefDoug Zongker # change, eg, "JWR66N dev-keys" to "JWR66N" 317a8608a7f7cee388192780f8988b5dc5966423eefDoug Zongker value = value.split() 318dc2661afe263de054be8ecf5f1252a6fbde776c6Michael Runge if len(value) > 1 and value[-1].endswith("-keys"): 31973d5abbd3f26d086ab4082f66b322f28a32bf7e5Andrew Boie value.pop() 32073d5abbd3f26d086ab4082f66b322f28a32bf7e5Andrew Boie value = " ".join(value) 321c09abc8103a4c029cc2c6d59226a2a74be57d082Doug Zongker line = key + "=" + value 32217aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker if line != original_line: 32317aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker print " replace: ", original_line 32417aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker print " with: ", line 32517aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker output.append(line) 32617aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker return "\n".join(output) + "\n" 32717aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker 32817aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker 329831840e51b0403671f746ebc32090b7d6e548c08Doug Zongkerdef ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info): 3308e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker try: 3318e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker keylist = input_tf_zip.read("META/otakeys.txt").split() 3328e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker except KeyError: 333a28acc6972ce35e9dfab061f175e229859d3e4dbT.R. Fullhart raise common.ExternalError("can't read META/otakeys.txt from input") 3348e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 335e121d6acf47c3056e079ff62c82171e889cec3e0Doug Zongker extra_recovery_keys = misc_info.get("extra_recovery_keys", None) 336e121d6acf47c3056e079ff62c82171e889cec3e0Doug Zongker if extra_recovery_keys: 337e121d6acf47c3056e079ff62c82171e889cec3e0Doug Zongker extra_recovery_keys = [OPTIONS.key_map.get(k, k) + ".x509.pem" 338e121d6acf47c3056e079ff62c82171e889cec3e0Doug Zongker for k in extra_recovery_keys.split()] 339e121d6acf47c3056e079ff62c82171e889cec3e0Doug Zongker if extra_recovery_keys: 340e121d6acf47c3056e079ff62c82171e889cec3e0Doug Zongker print "extra recovery-only key(s): " + ", ".join(extra_recovery_keys) 341e121d6acf47c3056e079ff62c82171e889cec3e0Doug Zongker else: 342e121d6acf47c3056e079ff62c82171e889cec3e0Doug Zongker extra_recovery_keys = [] 343e121d6acf47c3056e079ff62c82171e889cec3e0Doug Zongker 3448e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker mapped_keys = [] 3458e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker for k in keylist: 3468e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker m = re.match(r"^(.*)\.x509\.pem$", k) 3478e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker if not m: 348412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker raise common.ExternalError( 349412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker "can't parse \"%s\" from META/otakeys.txt" % (k,)) 3508e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker k = m.group(1) 3518e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker mapped_keys.append(OPTIONS.key_map.get(k, k) + ".x509.pem") 3528e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 353e05628cc8df4ec4b69befa9652d81eb81f0ab008Doug Zongker if mapped_keys: 354e05628cc8df4ec4b69befa9652d81eb81f0ab008Doug Zongker print "using:\n ", "\n ".join(mapped_keys) 355e05628cc8df4ec4b69befa9652d81eb81f0ab008Doug Zongker print "for OTA package verification" 356e05628cc8df4ec4b69befa9652d81eb81f0ab008Doug Zongker else: 357831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker devkey = misc_info.get("default_system_dev_certificate", 358831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker "build/target/product/security/testkey") 359e05628cc8df4ec4b69befa9652d81eb81f0ab008Doug Zongker mapped_keys.append( 360831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker OPTIONS.key_map.get(devkey, devkey) + ".x509.pem") 361e05628cc8df4ec4b69befa9652d81eb81f0ab008Doug Zongker print "META/otakeys.txt has no keys; using", mapped_keys[0] 3628e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 3638e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker # recovery uses a version of the key that has been slightly 3648e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker # predigested (by DumpPublicKey.java) and put in res/keys. 365e121d6acf47c3056e079ff62c82171e889cec3e0Doug Zongker # extra_recovery_keys are used only in recovery. 3668e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 367602a84e0bbf1807a9403cfa50184241f6fc035c4Doug Zongker p = common.Run(["java", "-jar", 368602a84e0bbf1807a9403cfa50184241f6fc035c4Doug Zongker os.path.join(OPTIONS.search_path, "framework", "dumpkey.jar")] 369e121d6acf47c3056e079ff62c82171e889cec3e0Doug Zongker + mapped_keys + extra_recovery_keys, 3708e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker stdout=subprocess.PIPE) 371412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker new_recovery_keys, _ = p.communicate() 3728e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker if p.returncode != 0: 373a28acc6972ce35e9dfab061f175e229859d3e4dbT.R. Fullhart raise common.ExternalError("failed to run dumpkeys") 374412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker common.ZipWriteStr(output_tf_zip, "RECOVERY/RAMDISK/res/keys", 375412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker new_recovery_keys) 3768e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 3778e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker # SystemUpdateActivity uses the x509.pem version of the keys, but 3788e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker # put into a zipfile system/etc/security/otacerts.zip. 379e121d6acf47c3056e079ff62c82171e889cec3e0Doug Zongker # We DO NOT include the extra_recovery_keys (if any) here. 3808e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 3818e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker tempfile = cStringIO.StringIO() 3828e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker certs_zip = zipfile.ZipFile(tempfile, "w") 3838e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker for k in mapped_keys: 3848e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker certs_zip.write(k) 3858e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker certs_zip.close() 386048e7ca15f6391681490ce564bc71194adf146aaDoug Zongker common.ZipWriteStr(output_tf_zip, "SYSTEM/etc/security/otacerts.zip", 387048e7ca15f6391681490ce564bc71194adf146aaDoug Zongker tempfile.getvalue()) 388eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 389412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker return new_recovery_keys 390412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker 391f19b365cc9021104586d65385d246db06639fc46Geremy Condradef ReplaceVerityPublicKey(targetfile_zip, key_path): 392f19b365cc9021104586d65385d246db06639fc46Geremy Condra print "Replacing verity public key with %s" % key_path 393f19b365cc9021104586d65385d246db06639fc46Geremy Condra with open(key_path) as f: 394f19b365cc9021104586d65385d246db06639fc46Geremy Condra common.ZipWriteStr(targetfile_zip, "BOOT/RAMDISK/verity_key", f.read()) 395f19b365cc9021104586d65385d246db06639fc46Geremy Condra 396f19b365cc9021104586d65385d246db06639fc46Geremy Condradef ReplaceVerityPrivateKey(targetfile_input_zip, targetfile_output_zip, misc_info, key_path): 397f19b365cc9021104586d65385d246db06639fc46Geremy Condra print "Replacing verity private key with %s" % key_path 398f19b365cc9021104586d65385d246db06639fc46Geremy Condra current_key = misc_info["verity_key"] 399f19b365cc9021104586d65385d246db06639fc46Geremy Condra original_misc_info = targetfile_input_zip.read("META/misc_info.txt") 400f19b365cc9021104586d65385d246db06639fc46Geremy Condra new_misc_info = original_misc_info.replace(current_key, key_path) 401f19b365cc9021104586d65385d246db06639fc46Geremy Condra common.ZipWriteStr(targetfile_output_zip, "META/misc_info.txt", new_misc_info) 402eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 403831840e51b0403671f746ebc32090b7d6e548c08Doug Zongkerdef BuildKeyMap(misc_info, key_mapping_options): 404831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker for s, d in key_mapping_options: 405831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker if s is None: # -d option 406831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker devkey = misc_info.get("default_system_dev_certificate", 407831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker "build/target/product/security/testkey") 408831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker devkeydir = os.path.dirname(devkey) 409831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker 410831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker OPTIONS.key_map.update({ 411831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker devkeydir + "/testkey": d + "/releasekey", 412831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker devkeydir + "/devkey": d + "/releasekey", 413831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker devkeydir + "/media": d + "/media", 414831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker devkeydir + "/shared": d + "/shared", 415831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker devkeydir + "/platform": d + "/platform", 416831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker }) 417831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker else: 418831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker OPTIONS.key_map[s] = d 419831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker 420831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker 421eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerdef main(argv): 422eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 423831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker key_mapping_options = [] 424831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker 425eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker def option_handler(o, a): 42605d3dea519688b61d86e30c2d4b99ff494aeca73Doug Zongker if o in ("-e", "--extra_apks"): 427eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker names, key = a.split("=") 428eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker names = names.split(",") 429eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker for n in names: 430eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker OPTIONS.extra_apks[n] = key 431eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker elif o in ("-d", "--default_key_mappings"): 432831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker key_mapping_options.append((None, a)) 433eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker elif o in ("-k", "--key_mapping"): 434831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker key_mapping_options.append(a.split("=", 1)) 4358e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker elif o in ("-o", "--replace_ota_keys"): 4368e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker OPTIONS.replace_ota_keys = True 437ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker elif o in ("-t", "--tag_changes"): 438ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker new = [] 439ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker for i in a.split(","): 440ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker i = i.strip() 441ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker if not i or i[0] not in "-+": 442ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker raise ValueError("Bad tag change '%s'" % (i,)) 443ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker new.append(i[0] + i[1:].strip()) 444ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker OPTIONS.tag_changes = tuple(new) 445f19b365cc9021104586d65385d246db06639fc46Geremy Condra elif o == "--replace_verity_public_key": 446f19b365cc9021104586d65385d246db06639fc46Geremy Condra OPTIONS.replace_verity_public_key = (True, a) 447f19b365cc9021104586d65385d246db06639fc46Geremy Condra elif o == "--replace_verity_private_key": 448f19b365cc9021104586d65385d246db06639fc46Geremy Condra OPTIONS.replace_verity_private_key = (True, a) 449eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker else: 450eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker return False 451eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker return True 452eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 453eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker args = common.ParseOptions(argv, __doc__, 45405d3dea519688b61d86e30c2d4b99ff494aeca73Doug Zongker extra_opts="e:d:k:ot:", 45505d3dea519688b61d86e30c2d4b99ff494aeca73Doug Zongker extra_long_opts=["extra_apks=", 456eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker "default_key_mappings=", 4578e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker "key_mapping=", 45817aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker "replace_ota_keys", 459f19b365cc9021104586d65385d246db06639fc46Geremy Condra "tag_changes=", 460f19b365cc9021104586d65385d246db06639fc46Geremy Condra "replace_verity_public_key=", 461f19b365cc9021104586d65385d246db06639fc46Geremy Condra "replace_verity_private_key="], 462eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker extra_option_handler=option_handler) 463eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 464eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker if len(args) != 2: 465eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker common.Usage(__doc__) 466eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker sys.exit(1) 467eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 468eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker input_zip = zipfile.ZipFile(args[0], "r") 469eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker output_zip = zipfile.ZipFile(args[1], "w") 470eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 471831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker misc_info = common.LoadInfoDict(input_zip) 472831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker 473831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker BuildKeyMap(misc_info, key_mapping_options) 474831840e51b0403671f746ebc32090b7d6e548c08Doug Zongker 475eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker apk_key_map = GetApkCerts(input_zip) 476eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker CheckAllApksSigned(input_zip, apk_key_map) 477eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker 478eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker key_passwords = common.GetKeyPasswords(set(apk_key_map.values())) 479412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker ProcessTargetFiles(input_zip, output_zip, misc_info, 480412c02fffbeb137868945f6485b249cc4b49eaeaDoug Zongker apk_key_map, key_passwords) 4818e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 482eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker input_zip.close() 483eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker output_zip.close() 484eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 4853c84f569487c4e59baa332be33b5430fdefb76b3Doug Zongker add_img_to_target_files.AddImagesToTargetFiles(args[1]) 4863c84f569487c4e59baa332be33b5430fdefb76b3Doug Zongker 487eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker print "done." 488eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 489eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 490eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerif __name__ == '__main__': 491eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker try: 492eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker main(sys.argv[1:]) 493eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker except common.ExternalError, e: 494eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker print 495eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker print " ERROR: %s" % (e,) 496eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker print 497eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker sys.exit(1) 498