forked from openkylin/platform_build
Merge "releasetools: Allow skipping PRESIGNED APEXes."
This commit is contained in:
commit
2812fd32ac
|
@ -166,7 +166,7 @@ def GetApkCerts(certmap):
|
|||
def GetApexKeys(keys_info, key_map):
|
||||
"""Gets APEX payload and container signing keys by applying the mapping rules.
|
||||
|
||||
We currently don't allow PRESIGNED payload / container keys.
|
||||
Presigned payload / container keys will be set accordingly.
|
||||
|
||||
Args:
|
||||
keys_info: A dict that maps from APEX filenames to a tuple of (payload_key,
|
||||
|
@ -180,7 +180,8 @@ def GetApexKeys(keys_info, key_map):
|
|||
# Apply all the --extra_apex_payload_key options to override the payload
|
||||
# signing keys in the given keys_info.
|
||||
for apex, key in OPTIONS.extra_apex_payload_keys.items():
|
||||
assert key, 'Presigned APEX payload for {} is not allowed'.format(apex)
|
||||
if not key:
|
||||
key = 'PRESIGNED'
|
||||
keys_info[apex] = (key, keys_info[apex][1])
|
||||
|
||||
# Apply the key remapping to container keys.
|
||||
|
@ -192,7 +193,8 @@ def GetApexKeys(keys_info, key_map):
|
|||
# Skip non-APEX containers.
|
||||
if apex not in keys_info:
|
||||
continue
|
||||
assert key, 'Presigned APEX container for {} is not allowed'.format(apex)
|
||||
if not key:
|
||||
key = 'PRESIGNED'
|
||||
keys_info[apex] = (keys_info[apex][0], key_map.get(key, key))
|
||||
|
||||
return keys_info
|
||||
|
@ -245,7 +247,7 @@ def GetApkFileInfo(filename, compressed_extension, skipped_prefixes):
|
|||
|
||||
|
||||
def CheckApkAndApexKeysAvailable(input_tf_zip, known_keys,
|
||||
compressed_extension):
|
||||
compressed_extension, apex_keys):
|
||||
"""Checks that all the APKs and APEXes have keys specified.
|
||||
|
||||
Args:
|
||||
|
@ -253,6 +255,8 @@ def CheckApkAndApexKeysAvailable(input_tf_zip, known_keys,
|
|||
known_keys: A set of APKs and APEXes that have known signing keys.
|
||||
compressed_extension: The extension string of compressed APKs, such as
|
||||
'.gz', or None if there's no compressed APKs.
|
||||
apex_keys: A dict that contains the key mapping from APEX name to
|
||||
(payload_key, container_key).
|
||||
|
||||
Raises:
|
||||
AssertionError: On finding unknown APKs and APEXes.
|
||||
|
@ -284,6 +288,31 @@ def CheckApkAndApexKeysAvailable(input_tf_zip, known_keys,
|
|||
"Use '-e <apkname>=' to specify a key (which may be an empty string to "
|
||||
"not sign this apk).".format("\n ".join(unknown_files)))
|
||||
|
||||
# For all the APEXes, double check that we won't have an APEX that has only
|
||||
# one of the payload / container keys set.
|
||||
if not apex_keys:
|
||||
return
|
||||
|
||||
invalid_apexes = []
|
||||
for info in input_tf_zip.infolist():
|
||||
if (not info.filename.startswith('SYSTEM/apex') or
|
||||
not info.filename.endswith('.apex')):
|
||||
continue
|
||||
|
||||
name = os.path.basename(info.filename)
|
||||
(payload_key, container_key) = apex_keys[name]
|
||||
if ((payload_key in common.SPECIAL_CERT_STRINGS and
|
||||
container_key not in common.SPECIAL_CERT_STRINGS) or
|
||||
(payload_key not in common.SPECIAL_CERT_STRINGS and
|
||||
container_key in common.SPECIAL_CERT_STRINGS)):
|
||||
invalid_apexes.append(
|
||||
"{}: payload_key {}, container_key {}".format(
|
||||
name, payload_key, container_key))
|
||||
|
||||
assert not invalid_apexes, \
|
||||
"Invalid APEX keys specified:\n {}\n".format(
|
||||
"\n ".join(invalid_apexes))
|
||||
|
||||
|
||||
def SignApk(data, keyname, pw, platform_api_level, codename_to_api_level_map,
|
||||
is_compressed):
|
||||
|
@ -468,19 +497,29 @@ def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
|
|||
name = os.path.basename(filename)
|
||||
payload_key, container_key = apex_keys[name]
|
||||
|
||||
print(" signing: %-*s container (%s)" % (maxsize, name, container_key))
|
||||
print(" : %-*s payload (%s)" % (maxsize, name, payload_key))
|
||||
# We've asserted not having a case with only one of them PRESIGNED.
|
||||
if (payload_key not in common.SPECIAL_CERT_STRINGS and
|
||||
container_key not in common.SPECIAL_CERT_STRINGS):
|
||||
print(" signing: %-*s container (%s)" % (
|
||||
maxsize, name, container_key))
|
||||
print(" : %-*s payload (%s)" % (
|
||||
maxsize, name, payload_key))
|
||||
|
||||
(signed_apex, payload_key_name) = SignApex(
|
||||
data,
|
||||
payload_key,
|
||||
container_key,
|
||||
key_passwords[container_key],
|
||||
codename_to_api_level_map,
|
||||
OPTIONS.avb_extra_args.get('apex'))
|
||||
common.ZipWrite(output_tf_zip, signed_apex, filename)
|
||||
(signed_apex, payload_key_name) = SignApex(
|
||||
data,
|
||||
payload_key,
|
||||
container_key,
|
||||
key_passwords[container_key],
|
||||
codename_to_api_level_map,
|
||||
OPTIONS.avb_extra_args.get('apex'))
|
||||
common.ZipWrite(output_tf_zip, signed_apex, filename)
|
||||
updated_apex_payload_keys[payload_key_name] = payload_key
|
||||
|
||||
updated_apex_payload_keys[payload_key_name] = payload_key
|
||||
else:
|
||||
print(
|
||||
"NOT signing: %s\n"
|
||||
" (skipped due to special cert string)" % (name,))
|
||||
common.ZipWriteStr(output_tf_zip, out_info, data)
|
||||
|
||||
# AVB public keys for the installed APEXes, which will be updated later.
|
||||
elif (os.path.dirname(filename) == 'SYSTEM/etc/security/apex' and
|
||||
|
@ -557,8 +596,10 @@ def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
|
|||
continue
|
||||
|
||||
name = os.path.basename(filename)
|
||||
assert name in updated_apex_payload_keys, \
|
||||
'Unsigned APEX payload key: {}'.format(filename)
|
||||
|
||||
# Skip PRESIGNED APEXes.
|
||||
if name not in updated_apex_payload_keys:
|
||||
continue
|
||||
|
||||
key_path = updated_apex_payload_keys[name]
|
||||
if not os.path.exists(key_path) and not key_path.endswith('.pem'):
|
||||
|
@ -1181,7 +1222,8 @@ def main(argv):
|
|||
CheckApkAndApexKeysAvailable(
|
||||
input_zip,
|
||||
set(apk_keys.keys()) | set(apex_keys.keys()),
|
||||
compressed_extension)
|
||||
compressed_extension,
|
||||
apex_keys)
|
||||
|
||||
key_passwords = common.GetKeyPasswords(
|
||||
set(apk_keys.values()) | set(itertools.chain(*apex_keys.values())))
|
||||
|
|
|
@ -33,6 +33,7 @@ class SignTargetFilesApksTest(test_utils.ReleaseToolsTestCase):
|
|||
<signer signature="{}"><seinfo value="media"/></signer>
|
||||
</policy>"""
|
||||
|
||||
# pylint: disable=line-too-long
|
||||
APEX_KEYS_TXT = """name="apex.apexd_test.apex" public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package.avbpubkey" private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem" container_certificate="build/target/product/security/testkey.x509.pem" container_private_key="build/target/product/security/testkey.pk8"
|
||||
name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.avbpubkey" private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem" container_certificate="build/target/product/security/testkey.x509.pem" container_private_key="build/target/product/security/testkey.pk8"
|
||||
"""
|
||||
|
@ -223,17 +224,50 @@ name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_te
|
|||
'App3.apk' : 'key3',
|
||||
}
|
||||
with zipfile.ZipFile(input_file) as input_zip:
|
||||
CheckApkAndApexKeysAvailable(input_zip, apk_key_map, None)
|
||||
CheckApkAndApexKeysAvailable(input_zip, apk_key_map, '.gz')
|
||||
CheckApkAndApexKeysAvailable(input_zip, apk_key_map, None, {})
|
||||
CheckApkAndApexKeysAvailable(input_zip, apk_key_map, '.gz', {})
|
||||
|
||||
# 'App2.apk.gz' won't be considered as an APK.
|
||||
CheckApkAndApexKeysAvailable(input_zip, apk_key_map, None)
|
||||
CheckApkAndApexKeysAvailable(input_zip, apk_key_map, '.xz')
|
||||
CheckApkAndApexKeysAvailable(input_zip, apk_key_map, None, {})
|
||||
CheckApkAndApexKeysAvailable(input_zip, apk_key_map, '.xz', {})
|
||||
|
||||
del apk_key_map['App2.apk']
|
||||
self.assertRaises(
|
||||
AssertionError, CheckApkAndApexKeysAvailable, input_zip, apk_key_map,
|
||||
'.gz')
|
||||
'.gz', {})
|
||||
|
||||
def test_CheckApkAndApexKeysAvailable_invalidApexKeys(self):
|
||||
input_file = common.MakeTempFile(suffix='.zip')
|
||||
with zipfile.ZipFile(input_file, 'w') as input_zip:
|
||||
input_zip.writestr('SYSTEM/apex/Apex1.apex', "Apex1-content")
|
||||
input_zip.writestr('SYSTEM/apex/Apex2.apex', "Apex2-content")
|
||||
|
||||
apk_key_map = {
|
||||
'Apex1.apex' : 'key1',
|
||||
'Apex2.apex' : 'key2',
|
||||
'Apex3.apex' : 'key3',
|
||||
}
|
||||
apex_keys = {
|
||||
'Apex1.apex' : ('payload-key1', 'container-key1'),
|
||||
'Apex2.apex' : ('payload-key2', 'container-key2'),
|
||||
}
|
||||
with zipfile.ZipFile(input_file) as input_zip:
|
||||
CheckApkAndApexKeysAvailable(input_zip, apk_key_map, None, apex_keys)
|
||||
|
||||
# Fine to have both keys as PRESIGNED.
|
||||
apex_keys['Apex2.apex'] = ('PRESIGNED', 'PRESIGNED')
|
||||
CheckApkAndApexKeysAvailable(input_zip, apk_key_map, None, apex_keys)
|
||||
|
||||
# Having only one of them as PRESIGNED is not allowed.
|
||||
apex_keys['Apex2.apex'] = ('payload-key2', 'PRESIGNED')
|
||||
self.assertRaises(
|
||||
AssertionError, CheckApkAndApexKeysAvailable, input_zip, apk_key_map,
|
||||
None, apex_keys)
|
||||
|
||||
apex_keys['Apex2.apex'] = ('PRESIGNED', 'container-key1')
|
||||
self.assertRaises(
|
||||
AssertionError, CheckApkAndApexKeysAvailable, input_zip, apk_key_map,
|
||||
None, apex_keys)
|
||||
|
||||
def test_GetApkFileInfo(self):
|
||||
(is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
|
||||
|
@ -358,16 +392,14 @@ name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_te
|
|||
with zipfile.ZipFile(target_files) as target_files_zip:
|
||||
keys_info = ReadApexKeysInfo(target_files_zip)
|
||||
|
||||
self.assertEqual(
|
||||
{
|
||||
'apex.apexd_test.apex': (
|
||||
'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
|
||||
'build/target/product/security/testkey'),
|
||||
'apex.apexd_test_different_app.apex': (
|
||||
'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
|
||||
'build/target/product/security/testkey'),
|
||||
},
|
||||
keys_info)
|
||||
self.assertEqual({
|
||||
'apex.apexd_test.apex': (
|
||||
'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
|
||||
'build/target/product/security/testkey'),
|
||||
'apex.apexd_test_different_app.apex': (
|
||||
'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
|
||||
'build/target/product/security/testkey'),
|
||||
}, keys_info)
|
||||
|
||||
def test_ReadApexKeysInfo_mismatchingKeys(self):
|
||||
# Mismatching payload public / private keys.
|
||||
|
@ -398,13 +430,11 @@ name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_te
|
|||
with zipfile.ZipFile(target_files) as target_files_zip:
|
||||
keys_info = ReadApexKeysInfo(target_files_zip)
|
||||
|
||||
self.assertEqual(
|
||||
{
|
||||
'apex.apexd_test.apex': (
|
||||
'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
|
||||
'build/target/product/security/testkey'),
|
||||
'apex.apexd_test_different_app.apex': (
|
||||
'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
|
||||
'build/target/product/security/testkey'),
|
||||
},
|
||||
keys_info)
|
||||
self.assertEqual({
|
||||
'apex.apexd_test.apex': (
|
||||
'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
|
||||
'build/target/product/security/testkey'),
|
||||
'apex.apexd_test_different_app.apex': (
|
||||
'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
|
||||
'build/target/product/security/testkey'),
|
||||
}, keys_info)
|
||||
|
|
Loading…
Reference in New Issue