forked from openkylin/platform_build
Merge "Add support for using custom signapk.jar."
This commit is contained in:
commit
e9a1f47e65
|
@ -20,6 +20,7 @@ import imp
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import re
|
import re
|
||||||
|
import shlex
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
@ -40,6 +41,11 @@ if not hasattr(os, "SEEK_SET"):
|
||||||
class Options(object): pass
|
class Options(object): pass
|
||||||
OPTIONS = Options()
|
OPTIONS = Options()
|
||||||
OPTIONS.search_path = "out/host/linux-x86"
|
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.verbose = False
|
||||||
OPTIONS.tempfiles = []
|
OPTIONS.tempfiles = []
|
||||||
OPTIONS.device_specific = None
|
OPTIONS.device_specific = None
|
||||||
|
@ -379,6 +385,7 @@ def GetKeyPasswords(keylist):
|
||||||
|
|
||||||
no_passwords = []
|
no_passwords = []
|
||||||
need_passwords = []
|
need_passwords = []
|
||||||
|
key_passwords = {}
|
||||||
devnull = open("/dev/null", "w+b")
|
devnull = open("/dev/null", "w+b")
|
||||||
for k in sorted(keylist):
|
for k in sorted(keylist):
|
||||||
# We don't need a password for things that aren't really keys.
|
# We don't need a password for things that aren't really keys.
|
||||||
|
@ -386,19 +393,36 @@ def GetKeyPasswords(keylist):
|
||||||
no_passwords.append(k)
|
no_passwords.append(k)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
p = Run(["openssl", "pkcs8", "-in", k+".pk8",
|
p = Run(["openssl", "pkcs8", "-in", k+OPTIONS.private_key_suffix,
|
||||||
"-inform", "DER", "-nocrypt"],
|
"-inform", "DER", "-nocrypt"],
|
||||||
stdin=devnull.fileno(),
|
stdin=devnull.fileno(),
|
||||||
stdout=devnull.fileno(),
|
stdout=devnull.fileno(),
|
||||||
stderr=subprocess.STDOUT)
|
stderr=subprocess.STDOUT)
|
||||||
p.communicate()
|
p.communicate()
|
||||||
if p.returncode == 0:
|
if p.returncode == 0:
|
||||||
|
# Definitely an unencrypted key.
|
||||||
no_passwords.append(k)
|
no_passwords.append(k)
|
||||||
else:
|
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()
|
devnull.close()
|
||||||
|
|
||||||
key_passwords = PasswordManager().GetPasswords(need_passwords)
|
key_passwords.update(PasswordManager().GetPasswords(need_passwords))
|
||||||
key_passwords.update(dict.fromkeys(no_passwords, None))
|
key_passwords.update(dict.fromkeys(no_passwords, None))
|
||||||
return key_passwords
|
return key_passwords
|
||||||
|
|
||||||
|
@ -426,11 +450,13 @@ def SignFile(input_name, output_name, key, password, align=None,
|
||||||
else:
|
else:
|
||||||
sign_name = output_name
|
sign_name = output_name
|
||||||
|
|
||||||
cmd = ["java", "-Xmx2048m", "-jar",
|
cmd = [OPTIONS.java_path, "-Xmx2048m", "-jar",
|
||||||
os.path.join(OPTIONS.search_path, "framework", "signapk.jar")]
|
os.path.join(OPTIONS.search_path, OPTIONS.signapk_path)]
|
||||||
|
cmd.extend(OPTIONS.extra_signapk_args)
|
||||||
if whole_file:
|
if whole_file:
|
||||||
cmd.append("-w")
|
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])
|
input_name, sign_name])
|
||||||
|
|
||||||
p = Run(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
p = Run(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||||
|
@ -494,12 +520,14 @@ def ReadApkCerts(tf_zip):
|
||||||
r'private_key="(.*)"$', line)
|
r'private_key="(.*)"$', line)
|
||||||
if m:
|
if m:
|
||||||
name, cert, privkey = m.groups()
|
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:
|
if cert in SPECIAL_CERT_STRINGS and not privkey:
|
||||||
certmap[name] = cert
|
certmap[name] = cert
|
||||||
elif (cert.endswith(".x509.pem") and
|
elif (cert.endswith(OPTIONS.public_key_suffix) and
|
||||||
privkey.endswith(".pk8") and
|
privkey.endswith(OPTIONS.private_key_suffix) and
|
||||||
cert[:-9] == privkey[:-4]):
|
cert[:-public_key_suffix_len] == privkey[:-private_key_suffix_len]):
|
||||||
certmap[name] = cert[:-9]
|
certmap[name] = cert[:-public_key_suffix_len]
|
||||||
else:
|
else:
|
||||||
raise ValueError("failed to parse line from apkcerts.txt:\n" + line)
|
raise ValueError("failed to parse line from apkcerts.txt:\n" + line)
|
||||||
return certmap
|
return certmap
|
||||||
|
@ -543,8 +571,10 @@ def ParseOptions(argv,
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(
|
opts, args = getopt.getopt(
|
||||||
argv, "hvp:s:x:" + extra_opts,
|
argv, "hvp:s:x:" + extra_opts,
|
||||||
["help", "verbose", "path=", "device_specific=", "extra="] +
|
["help", "verbose", "path=", "signapk_path=", "extra_signapk_args=",
|
||||||
list(extra_long_opts))
|
"java_path=", "public_key_suffix=", "private_key_suffix=",
|
||||||
|
"device_specific=", "extra="] +
|
||||||
|
list(extra_long_opts))
|
||||||
except getopt.GetoptError, err:
|
except getopt.GetoptError, err:
|
||||||
Usage(docstring)
|
Usage(docstring)
|
||||||
print "**", str(err), "**"
|
print "**", str(err), "**"
|
||||||
|
@ -560,6 +590,16 @@ def ParseOptions(argv,
|
||||||
OPTIONS.verbose = True
|
OPTIONS.verbose = True
|
||||||
elif o in ("-p", "--path"):
|
elif o in ("-p", "--path"):
|
||||||
OPTIONS.search_path = a
|
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"):
|
elif o in ("-s", "--device_specific"):
|
||||||
OPTIONS.device_specific = a
|
OPTIONS.device_specific = a
|
||||||
elif o in ("-x", "--extra"):
|
elif o in ("-x", "--extra"):
|
||||||
|
|
|
@ -208,7 +208,7 @@ def ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info):
|
||||||
try:
|
try:
|
||||||
keylist = input_tf_zip.read("META/otakeys.txt").split()
|
keylist = input_tf_zip.read("META/otakeys.txt").split()
|
||||||
except KeyError:
|
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)
|
extra_recovery_keys = misc_info.get("extra_recovery_keys", None)
|
||||||
if extra_recovery_keys:
|
if extra_recovery_keys:
|
||||||
|
@ -223,7 +223,7 @@ 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 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")
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ def ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info):
|
||||||
stdout=subprocess.PIPE)
|
stdout=subprocess.PIPE)
|
||||||
data, _ = p.communicate()
|
data, _ = p.communicate()
|
||||||
if p.returncode != 0:
|
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)
|
common.ZipWriteStr(output_tf_zip, "RECOVERY/RAMDISK/res/keys", data)
|
||||||
|
|
||||||
# SystemUpdateActivity uses the x509.pem version of the keys, but
|
# SystemUpdateActivity uses the x509.pem version of the keys, but
|
||||||
|
|
Loading…
Reference in New Issue