Add support for using custom signapk.jar.

Details:
* New --signapk_path, --extra_signapk_args, --java_path.
* New --public_key_suffix, --private_key_suffix so you can change the filenames.
* Fixes raising exceptions on error.

Change-Id: I0b7014b6d779d52ae896f95dfecb1bcccf536cf4
(cherry picked from commit a28acc6972)
This commit is contained in:
T.R. Fullhart 2013-03-18 10:31:26 -07:00
parent 49d8686488
commit 37e1052c99
2 changed files with 55 additions and 15 deletions

View file

@ -20,6 +20,7 @@ import imp
import os
import platform
import re
import shlex
import shutil
import subprocess
import sys
@ -40,6 +41,11 @@ if not hasattr(os, "SEEK_SET"):
class Options(object): pass
OPTIONS = Options()
OPTIONS.search_path = "out/host/linux-x86"
OPTIONS.signapk_path = "framework/signapk.jar" # Relative to search_path
OPTIONS.extra_signapk_args = []
OPTIONS.java_path = "java" # Use the one on the path by default.
OPTIONS.public_key_suffix = ".x509.pem"
OPTIONS.private_key_suffix = ".pk8"
OPTIONS.verbose = False
OPTIONS.tempfiles = []
OPTIONS.device_specific = None
@ -379,6 +385,7 @@ def GetKeyPasswords(keylist):
no_passwords = []
need_passwords = []
key_passwords = {}
devnull = open("/dev/null", "w+b")
for k in sorted(keylist):
# We don't need a password for things that aren't really keys.
@ -386,19 +393,36 @@ def GetKeyPasswords(keylist):
no_passwords.append(k)
continue
p = Run(["openssl", "pkcs8", "-in", k+".pk8",
p = Run(["openssl", "pkcs8", "-in", k+OPTIONS.private_key_suffix,
"-inform", "DER", "-nocrypt"],
stdin=devnull.fileno(),
stdout=devnull.fileno(),
stderr=subprocess.STDOUT)
p.communicate()
if p.returncode == 0:
# Definitely an unencrypted key.
no_passwords.append(k)
else:
need_passwords.append(k)
p = Run(["openssl", "pkcs8", "-in", k+OPTIONS.private_key_suffix,
"-inform", "DER", "-passin", "pass:"],
stdin=devnull.fileno(),
stdout=devnull.fileno(),
stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode == 0:
# Encrypted key with empty string as password.
key_passwords[k] = ''
elif stderr.startswith('Error decrypting key'):
# Definitely encrypted key.
# It would have said "Error reading key" if it didn't parse correctly.
need_passwords.append(k)
else:
# Potentially, a type of key that openssl doesn't understand.
# We'll let the routines in signapk.jar handle it.
no_passwords.append(k)
devnull.close()
key_passwords = PasswordManager().GetPasswords(need_passwords)
key_passwords.update(PasswordManager().GetPasswords(need_passwords))
key_passwords.update(dict.fromkeys(no_passwords, None))
return key_passwords
@ -426,11 +450,13 @@ def SignFile(input_name, output_name, key, password, align=None,
else:
sign_name = output_name
cmd = ["java", "-Xmx2048m", "-jar",
os.path.join(OPTIONS.search_path, "framework", "signapk.jar")]
cmd = [OPTIONS.java_path, "-Xmx2048m", "-jar",
os.path.join(OPTIONS.search_path, OPTIONS.signapk_path)]
cmd.extend(OPTIONS.extra_signapk_args)
if whole_file:
cmd.append("-w")
cmd.extend([key + ".x509.pem", key + ".pk8",
cmd.extend([key + OPTIONS.public_key_suffix,
key + OPTIONS.private_key_suffix,
input_name, sign_name])
p = Run(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
@ -494,12 +520,14 @@ def ReadApkCerts(tf_zip):
r'private_key="(.*)"$', line)
if m:
name, cert, privkey = m.groups()
public_key_suffix_len = len(OPTIONS.public_key_suffix)
private_key_suffix_len = len(OPTIONS.private_key_suffix)
if cert in SPECIAL_CERT_STRINGS and not privkey:
certmap[name] = cert
elif (cert.endswith(".x509.pem") and
privkey.endswith(".pk8") and
cert[:-9] == privkey[:-4]):
certmap[name] = cert[:-9]
elif (cert.endswith(OPTIONS.public_key_suffix) and
privkey.endswith(OPTIONS.private_key_suffix) and
cert[:-public_key_suffix_len] == privkey[:-private_key_suffix_len]):
certmap[name] = cert[:-public_key_suffix_len]
else:
raise ValueError("failed to parse line from apkcerts.txt:\n" + line)
return certmap
@ -543,8 +571,10 @@ def ParseOptions(argv,
try:
opts, args = getopt.getopt(
argv, "hvp:s:x:" + extra_opts,
["help", "verbose", "path=", "device_specific=", "extra="] +
list(extra_long_opts))
["help", "verbose", "path=", "signapk_path=", "extra_signapk_args=",
"java_path=", "public_key_suffix=", "private_key_suffix=",
"device_specific=", "extra="] +
list(extra_long_opts))
except getopt.GetoptError, err:
Usage(docstring)
print "**", str(err), "**"
@ -560,6 +590,16 @@ def ParseOptions(argv,
OPTIONS.verbose = True
elif o in ("-p", "--path"):
OPTIONS.search_path = a
elif o in ("--signapk_path",):
OPTIONS.signapk_path = a
elif o in ("--extra_signapk_args",):
OPTIONS.extra_signapk_args = shlex.split(a)
elif o in ("--java_path",):
OPTIONS.java_path = a
elif o in ("--public_key_suffix",):
OPTIONS.public_key_suffix = a
elif o in ("--private_key_suffix",):
OPTIONS.private_key_suffix = a
elif o in ("-s", "--device_specific"):
OPTIONS.device_specific = a
elif o in ("-x", "--extra"):

View file

@ -208,7 +208,7 @@ def ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info):
try:
keylist = input_tf_zip.read("META/otakeys.txt").split()
except KeyError:
raise ExternalError("can't read META/otakeys.txt from input")
raise common.ExternalError("can't read META/otakeys.txt from input")
extra_recovery_keys = misc_info.get("extra_recovery_keys", None)
if extra_recovery_keys:
@ -223,7 +223,7 @@ def ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info):
for k in keylist:
m = re.match(r"^(.*)\.x509\.pem$", k)
if not m:
raise 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)
mapped_keys.append(OPTIONS.key_map.get(k, k) + ".x509.pem")
@ -247,7 +247,7 @@ def ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info):
stdout=subprocess.PIPE)
data, _ = p.communicate()
if p.returncode != 0:
raise ExternalError("failed to run dumpkeys")
raise common.ExternalError("failed to run dumpkeys")
common.ZipWriteStr(output_tf_zip, "RECOVERY/RAMDISK/res/keys", data)
# SystemUpdateActivity uses the x509.pem version of the keys, but