sign_target_files_apks revision f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5
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 39eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker build/target/product/security/testkey ==> $dir/releasekey 40eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker build/target/product/security/media ==> $dir/media 41eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker build/target/product/security/shared ==> $dir/shared 42eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker build/target/product/security/platform ==> $dir/platform 43eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 44eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker -d and -k options are added to the set of mappings in the order 45eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker in which they appear on the command line. 468e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 478e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker -o (--replace_ota_keys) 488e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker Replace the certificate (public key) used by OTA package 498e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker verification with the one specified in the input target_files 508e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker zip (in the META/otakeys.txt file). Key remapping (-k and -d) 518e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker is performed on this key. 5217aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker 53ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker -t (--tag_changes) <+tag>,<-tag>,... 54ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker Comma-separated list of changes to make to the set of tags (in 55ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker the last component of the build fingerprint). Prefix each with 56ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker '+' or '-' to indicate whether that tag should be added or 57ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker removed. Changes are processed in the order they appear. 585f5f08dd226a153ff4c73c0b1918bd5cc1afcffbDoug Zongker Default value is "-test-keys,+release-keys". 59ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker 60eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker""" 61eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 62eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport sys 63eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 64eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerif sys.hexversion < 0x02040000: 65eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker print >> sys.stderr, "Python 2.4 or newer is required." 66eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker sys.exit(1) 67eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 688e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongkerimport cStringIO 698e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongkerimport copy 70eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport os 71eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport re 72eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport subprocess 73eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport tempfile 74eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport zipfile 75eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 76eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport common 77eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 78eef3944eb3673329b5e89cf188ac592805a0b08dDoug ZongkerOPTIONS = common.OPTIONS 79eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 80eef3944eb3673329b5e89cf188ac592805a0b08dDoug ZongkerOPTIONS.extra_apks = {} 81eef3944eb3673329b5e89cf188ac592805a0b08dDoug ZongkerOPTIONS.key_map = {} 828e931bf999693cac54c99deb1ef668d0e6164ecfDoug ZongkerOPTIONS.replace_ota_keys = False 835f5f08dd226a153ff4c73c0b1918bd5cc1afcffbDoug ZongkerOPTIONS.tag_changes = ("-test-keys", "+release-keys") 84eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 85eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerdef GetApkCerts(tf_zip): 86f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker certmap = common.ReadApkCerts(tf_zip) 87f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker 88f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker # apply the key remapping to the contents of the file 89f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker for apk, cert in certmap.iteritems(): 90f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker certmap[apk] = OPTIONS.key_map.get(cert, cert) 91f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker 92f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker # apply all the -e options, overriding anything in the file 93ad88c7ce4f3a65827d4cd5b5ed01324b3b368dd9Doug Zongker for apk, cert in OPTIONS.extra_apks.iteritems(): 94ad88c7ce4f3a65827d4cd5b5ed01324b3b368dd9Doug Zongker certmap[apk] = OPTIONS.key_map.get(cert, cert) 95f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker 96eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker return certmap 97eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 98eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 99eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongkerdef CheckAllApksSigned(input_tf_zip, apk_key_map): 100eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker """Check that all the APKs we want to sign have keys specified, and 101eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker error out if they don't.""" 102eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker unknown_apks = [] 103eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker for info in input_tf_zip.infolist(): 104eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker if info.filename.endswith(".apk"): 105eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker name = os.path.basename(info.filename) 106eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker if name not in apk_key_map: 107eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker unknown_apks.append(name) 108eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker if unknown_apks: 109eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker print "ERROR: no key specified for:\n\n ", 110eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker print "\n ".join(unknown_apks) 111eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker print "\nUse '-e <apkname>=' to specify a key (which may be an" 112eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker print "empty string to not sign this apk)." 113eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker sys.exit(1) 114eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker 115eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker 116eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerdef SignApk(data, keyname, pw): 117eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker unsigned = tempfile.NamedTemporaryFile() 118eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker unsigned.write(data) 119eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker unsigned.flush() 120eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 121eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker signed = tempfile.NamedTemporaryFile() 122eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 123eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker common.SignFile(unsigned.name, signed.name, keyname, pw, align=4) 124eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 125eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker data = signed.read() 126eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker unsigned.close() 127eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker signed.close() 128eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 129eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker return data 130eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 131eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 132eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongkerdef SignApks(input_tf_zip, output_tf_zip, apk_key_map, key_passwords): 133eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker maxsize = max([len(os.path.basename(i.filename)) 134eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker for i in input_tf_zip.infolist() 135eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker if i.filename.endswith('.apk')]) 136eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 137eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker for info in input_tf_zip.infolist(): 138eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker data = input_tf_zip.read(info.filename) 1398e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker out_info = copy.copy(info) 140eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker if info.filename.endswith(".apk"): 141eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker name = os.path.basename(info.filename) 14243874f8c864972b9dae7e4927aa347455b774c94Doug Zongker key = apk_key_map[name] 143f6a53aa5f24878ad9098409ed3d3f41bb5c63fb5Doug Zongker if key not in common.SPECIAL_CERT_STRINGS: 14443874f8c864972b9dae7e4927aa347455b774c94Doug Zongker print " signing: %-*s (%s)" % (maxsize, name, key) 145eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker signed_data = SignApk(data, key, key_passwords[key]) 1468e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker output_tf_zip.writestr(out_info, signed_data) 147eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker else: 148eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker # an APK we're not supposed to sign. 14943874f8c864972b9dae7e4927aa347455b774c94Doug Zongker print "NOT signing: %s" % (name,) 1508e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker output_tf_zip.writestr(out_info, data) 1518e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker elif info.filename in ("SYSTEM/build.prop", 1528e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker "RECOVERY/RAMDISK/default.prop"): 15317aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker print "rewriting %s:" % (info.filename,) 15417aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker new_data = RewriteProps(data) 15517aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker output_tf_zip.writestr(out_info, new_data) 156eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker else: 157eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker # a non-APK file; copy it verbatim 1588e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker output_tf_zip.writestr(out_info, data) 1598e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 1608e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 16117aa944001e7ae2425beec75d3ebc280413631eeDoug Zongkerdef RewriteProps(data): 16217aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker output = [] 16317aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker for line in data.split("\n"): 16417aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker line = line.strip() 16517aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker original_line = line 16617aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker if line and line[0] != '#': 16717aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker key, value = line.split("=", 1) 16817aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker if key == "ro.build.fingerprint": 16917aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker pieces = line.split("/") 17017aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker tags = set(pieces[-1].split(",")) 171ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker for ch in OPTIONS.tag_changes: 172ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker if ch[0] == "-": 173ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker tags.discard(ch[1:]) 174ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker elif ch[0] == "+": 175ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker tags.add(ch[1:]) 17617aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker line = "/".join(pieces[:-1] + [",".join(sorted(tags))]) 17717aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker elif key == "ro.build.description": 17817aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker pieces = line.split(" ") 17917aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker assert len(pieces) == 5 18017aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker tags = set(pieces[-1].split(",")) 181ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker for ch in OPTIONS.tag_changes: 182ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker if ch[0] == "-": 183ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker tags.discard(ch[1:]) 184ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker elif ch[0] == "+": 185ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker tags.add(ch[1:]) 18617aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker line = " ".join(pieces[:-1] + [",".join(sorted(tags))]) 18717aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker if line != original_line: 18817aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker print " replace: ", original_line 18917aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker print " with: ", line 19017aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker output.append(line) 19117aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker return "\n".join(output) + "\n" 19217aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker 19317aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker 1948e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongkerdef ReplaceOtaKeys(input_tf_zip, output_tf_zip): 1958e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker try: 1968e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker keylist = input_tf_zip.read("META/otakeys.txt").split() 1978e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker except KeyError: 1988e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker raise ExternalError("can't read META/otakeys.txt from input") 1998e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 2008e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker mapped_keys = [] 2018e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker for k in keylist: 2028e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker m = re.match(r"^(.*)\.x509\.pem$", k) 2038e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker if not m: 2048e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker raise ExternalError("can't parse \"%s\" from META/otakeys.txt" % (k,)) 2058e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker k = m.group(1) 2068e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker mapped_keys.append(OPTIONS.key_map.get(k, k) + ".x509.pem") 2078e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 208e05628cc8df4ec4b69befa9652d81eb81f0ab008Doug Zongker if mapped_keys: 209e05628cc8df4ec4b69befa9652d81eb81f0ab008Doug Zongker print "using:\n ", "\n ".join(mapped_keys) 210e05628cc8df4ec4b69befa9652d81eb81f0ab008Doug Zongker print "for OTA package verification" 211e05628cc8df4ec4b69befa9652d81eb81f0ab008Doug Zongker else: 212e05628cc8df4ec4b69befa9652d81eb81f0ab008Doug Zongker mapped_keys.append( 213e05628cc8df4ec4b69befa9652d81eb81f0ab008Doug Zongker OPTIONS.key_map["build/target/product/security/testkey"] + ".x509.pem") 214e05628cc8df4ec4b69befa9652d81eb81f0ab008Doug Zongker print "META/otakeys.txt has no keys; using", mapped_keys[0] 2158e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 2168e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker # recovery uses a version of the key that has been slightly 2178e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker # predigested (by DumpPublicKey.java) and put in res/keys. 2188e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 219602a84e0bbf1807a9403cfa50184241f6fc035c4Doug Zongker p = common.Run(["java", "-jar", 220602a84e0bbf1807a9403cfa50184241f6fc035c4Doug Zongker os.path.join(OPTIONS.search_path, "framework", "dumpkey.jar")] 221602a84e0bbf1807a9403cfa50184241f6fc035c4Doug Zongker + mapped_keys, 2228e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker stdout=subprocess.PIPE) 2238e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker data, _ = p.communicate() 2248e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker if p.returncode != 0: 2258e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker raise ExternalError("failed to run dumpkeys") 226048e7ca15f6391681490ce564bc71194adf146aaDoug Zongker common.ZipWriteStr(output_tf_zip, "RECOVERY/RAMDISK/res/keys", data) 2278e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 2288e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker # SystemUpdateActivity uses the x509.pem version of the keys, but 2298e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker # put into a zipfile system/etc/security/otacerts.zip. 2308e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 2318e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker tempfile = cStringIO.StringIO() 2328e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker certs_zip = zipfile.ZipFile(tempfile, "w") 2338e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker for k in mapped_keys: 2348e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker certs_zip.write(k) 2358e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker certs_zip.close() 236048e7ca15f6391681490ce564bc71194adf146aaDoug Zongker common.ZipWriteStr(output_tf_zip, "SYSTEM/etc/security/otacerts.zip", 237048e7ca15f6391681490ce564bc71194adf146aaDoug Zongker tempfile.getvalue()) 238eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 239eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 240eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerdef main(argv): 241eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 242eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker def option_handler(o, a): 24305d3dea519688b61d86e30c2d4b99ff494aeca73Doug Zongker if o in ("-e", "--extra_apks"): 244eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker names, key = a.split("=") 245eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker names = names.split(",") 246eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker for n in names: 247eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker OPTIONS.extra_apks[n] = key 248eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker elif o in ("-d", "--default_key_mappings"): 249eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker OPTIONS.key_map.update({ 250eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker "build/target/product/security/testkey": "%s/releasekey" % (a,), 251eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker "build/target/product/security/media": "%s/media" % (a,), 252eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker "build/target/product/security/shared": "%s/shared" % (a,), 253eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker "build/target/product/security/platform": "%s/platform" % (a,), 254eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker }) 255eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker elif o in ("-k", "--key_mapping"): 256eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker s, d = a.split("=") 257eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker OPTIONS.key_map[s] = d 2588e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker elif o in ("-o", "--replace_ota_keys"): 2598e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker OPTIONS.replace_ota_keys = True 260ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker elif o in ("-t", "--tag_changes"): 261ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker new = [] 262ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker for i in a.split(","): 263ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker i = i.strip() 264ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker if not i or i[0] not in "-+": 265ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker raise ValueError("Bad tag change '%s'" % (i,)) 266ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker new.append(i[0] + i[1:].strip()) 267ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker OPTIONS.tag_changes = tuple(new) 268eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker else: 269eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker return False 270eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker return True 271eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 272eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker args = common.ParseOptions(argv, __doc__, 27305d3dea519688b61d86e30c2d4b99ff494aeca73Doug Zongker extra_opts="e:d:k:ot:", 27405d3dea519688b61d86e30c2d4b99ff494aeca73Doug Zongker extra_long_opts=["extra_apks=", 275eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker "default_key_mappings=", 2768e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker "key_mapping=", 27717aa944001e7ae2425beec75d3ebc280413631eeDoug Zongker "replace_ota_keys", 278ae877013ab8d87b9f0da111adcb7621f477451c6Doug Zongker "tag_changes="], 279eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker extra_option_handler=option_handler) 280eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 281eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker if len(args) != 2: 282eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker common.Usage(__doc__) 283eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker sys.exit(1) 284eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 285eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker input_zip = zipfile.ZipFile(args[0], "r") 286eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker output_zip = zipfile.ZipFile(args[1], "w") 287eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 288eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker apk_key_map = GetApkCerts(input_zip) 289eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker CheckAllApksSigned(input_zip, apk_key_map) 290eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker 291eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker key_passwords = common.GetKeyPasswords(set(apk_key_map.values())) 292eb338efd2eae20962c7ca75baf161be540b3d664Doug Zongker SignApks(input_zip, output_zip, apk_key_map, key_passwords) 293eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 2948e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker if OPTIONS.replace_ota_keys: 2958e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker ReplaceOtaKeys(input_zip, output_zip) 2968e931bf999693cac54c99deb1ef668d0e6164ecfDoug Zongker 297eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker input_zip.close() 298eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker output_zip.close() 299eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 300eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker print "done." 301eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 302eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker 303eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerif __name__ == '__main__': 304eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker try: 305eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker main(sys.argv[1:]) 306eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker except common.ExternalError, e: 307eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker print 308eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker print " ERROR: %s" % (e,) 309eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker print 310eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker sys.exit(1) 311