From 27c39b0af23c16c0d3d9ba4b14a2b2b19527c680 Mon Sep 17 00:00:00 2001 From: Bowgo Tsai Date: Fri, 12 Mar 2021 21:40:32 +0800 Subject: [PATCH] Support GKI boot.img v4 signing Commit I9967d06bde0e18a12b84b5b0b568db09765fe305 supports adding a generic boot_signature into boot.img v4. This change allows replacing the boot_signture signing key with a release key during the release process. The default GKI signing key can be specified in a BoardConfig.mk via: BOARD_GKI_SIGNING_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_GKI_SIGNING_ALGORITHM := SHA256_RSA2048 BOARD_GKI_SIGNING_SIGNATURE_ARGS := --prop foo:bar The release signing key/algorithm can be specified by the following options when invoking sign_target_files_apks: --gki_signing_key=external/avb/test/data/testkey_rsa4096.pem --gki_signing_algorithm=SHA256_RSA4096 Additional arguments for generating the GKI signature can be specified as below: --gki_signing_extra_args="--prop gki:prop1 --prop gki:prop2" Bug: 177862434 Test: make dist Test: sign_target_files_apks \ --gki_signing_key=external/avb/test/data/testkey_rsa4096.pem \ --gki_signing_algorithm=SHA256_RSA4096 \ --gki_signing_extra_args="--prop gki:prop1 --prop gki:prop2" \ ./out/dist/*-target_files-eng.*.zip signed.zip Test: Checks GKI boot_signature is expected after signing: `unzip signed.zip IMAGES/boot.img` `unpack_bootimg --boot_img IMAGES/boot.img --out unpack` `avbtool info_image --image unpack/boot_signature` Test: unit test: releasetools_test and releasetools_py3_test Change-Id: I61dadbc242360e4cab3dc70295931b4a5b9422a9 --- core/Makefile | 53 ++++++-- tools/releasetools/common.py | 31 +++++ tools/releasetools/sign_target_files_apks.py | 48 +++++++ tools/releasetools/test_common.py | 121 ++++++++++++++++++ .../test_sign_target_files_apks.py | 53 +++++++- 5 files changed, 293 insertions(+), 13 deletions(-) diff --git a/core/Makefile b/core/Makefile index 0d993d057..24166160a 100644 --- a/core/Makefile +++ b/core/Makefile @@ -856,6 +856,23 @@ INTERNAL_MKBOOTIMG_VERSION_ARGS := \ --os_version $(PLATFORM_VERSION_LAST_STABLE) \ --os_patch_level $(PLATFORM_SECURITY_PATCH) +ifdef BOARD_GKI_SIGNING_KEY_PATH +ifndef BOARD_GKI_SIGNING_ALGORITHM +$(error BOARD_GKI_SIGNING_ALGORITHM should be defined with BOARD_GKI_SIGNING_KEY_PATH) +endif +INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS := \ + --gki_signing_key $(BOARD_GKI_SIGNING_KEY_PATH) \ + --gki_signing_algorithm $(BOARD_GKI_SIGNING_ALGORITHM) \ + --gki_signing_avbtool_path $(AVBTOOL) +endif + +# Using double quote to pass BOARD_GKI_SIGNING_SIGNATURE_ARGS as a single string +# to MKBOOTIMG, although it may contain multiple args. +ifdef BOARD_GKI_SIGNING_SIGNATURE_ARGS +INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS += \ + --gki_signing_signature_args "$(BOARD_GKI_SIGNING_SIGNATURE_ARGS)" +endif + # Define these only if we are building boot ifdef BUILDING_BOOT_IMAGE INSTALLED_BOOTIMAGE_TARGET := $(BUILT_BOOTIMAGE_TARGET) @@ -870,7 +887,8 @@ ifeq (true,$(BOARD_AVB_ENABLE)) # $1: boot image target define build_boot_board_avb_enabled - $(MKBOOTIMG) --kernel $(call bootimage-to-kernel,$(1)) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1) + $(MKBOOTIMG) --kernel $(call bootimage-to-kernel,$(1)) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) \ + $(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1) $(call assert-max-image-size,$(1),$(call get-hash-image-max-size,$(call get-bootimage-partition-size,$(1),boot))) $(AVBTOOL) add_hash_footer \ --image $(1) \ @@ -879,12 +897,12 @@ define build_boot_board_avb_enabled $(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS) endef -$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(AVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(BOARD_AVB_BOOT_KEY_PATH) +$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(AVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(BOARD_AVB_BOOT_KEY_PATH) $(BOARD_GKI_SIGNING_KEY_PATH) $(call pretty,"Target boot image: $@") $(call build_boot_board_avb_enabled,$@) .PHONY: bootimage-nodeps -bootimage-nodeps: $(MKBOOTIMG) $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH) +bootimage-nodeps: $(MKBOOTIMG) $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH) $(BOARD_GKI_SIGNING_KEY_PATH) @echo "make $@: ignoring dependencies" $(foreach b,$(INSTALLED_BOOTIMAGE_TARGET),$(call build_boot_board_avb_enabled,$(b))) @@ -2149,8 +2167,8 @@ define build-recoveryimage-target $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_RECOVERY_MKBOOTIMG_ARGS) \ --output $(1).unsigned, \ $(MKBOOTIMG) $(if $(strip $(2)),--kernel $(strip $(2))) $(INTERNAL_RECOVERYIMAGE_ARGS) \ - $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_RECOVERY_MKBOOTIMG_ARGS) \ - --output $(1)) + $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) \ + $(BOARD_RECOVERY_MKBOOTIMG_ARGS) --output $(1)) $(if $(filter true,$(PRODUCT_SUPPORTS_BOOT_SIGNER)),\ $(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\ $(BOOT_SIGNER) /boot $(1) $(PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCT_VERITY_SIGNING_KEY).x509.pem $(1),\ @@ -2178,6 +2196,9 @@ endif ifeq (true,$(BOARD_AVB_ENABLE)) recoveryimage-deps += $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH) endif +ifdef BOARD_GKI_SIGNING_KEY_PATH + recoveryimage-deps += $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL) +endif ifdef BOARD_INCLUDE_RECOVERY_DTBO ifdef BOARD_PREBUILT_RECOVERY_DTBOIMAGE recoveryimage-deps += $(BOARD_PREBUILT_RECOVERY_DTBOIMAGE) @@ -2353,17 +2374,18 @@ endef # $(1): output file define build-debug-bootimage-target $(MKBOOTIMG) --kernel $(PRODUCT_OUT)/$(subst .img,,$(subst boot-debug,kernel,$(notdir $(1)))) \ - $(INTERNAL_DEBUG_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $1 + $(INTERNAL_DEBUG_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) \ + $(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $1 $(if $(BOARD_AVB_BOOT_KEY_PATH),$(call test-key-sign-bootimage,$1,boot-debug)) endef # Depends on original boot.img and ramdisk-debug.img, to build the new boot-debug.img -$(INSTALLED_DEBUG_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_BOOTIMAGE_TARGET) $(INSTALLED_DEBUG_RAMDISK_TARGET) +$(INSTALLED_DEBUG_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_BOOTIMAGE_TARGET) $(INSTALLED_DEBUG_RAMDISK_TARGET) $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL) $(call pretty,"Target boot debug image: $@") $(call build-debug-bootimage-target, $@) .PHONY: bootimage_debug-nodeps -bootimage_debug-nodeps: $(MKBOOTIMG) +bootimage_debug-nodeps: $(MKBOOTIMG) $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL) echo "make $@: ignoring dependencies" $(foreach b,$(INSTALLED_DEBUG_BOOTIMAGE_TARGET),$(call build-debug-bootimage-target,$b)) @@ -2528,17 +2550,19 @@ endif # $(1): output file define build-boot-test-harness-target $(MKBOOTIMG) --kernel $(PRODUCT_OUT)/$(subst .img,,$(subst boot-test-harness,kernel,$(notdir $(1)))) \ - $(INTERNAL_TEST_HARNESS_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@ + $(INTERNAL_TEST_HARNESS_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) \ + $(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@ $(if $(BOARD_AVB_BOOT_KEY_PATH),$(call test-key-sign-bootimage,$@,boot-test-harness)) endef # Build the new boot-test-harness.img, based on boot-debug.img and ramdisk-test-harness.img. -$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_DEBUG_BOOTIMAGE_TARGET) $(INSTALLED_TEST_HARNESS_RAMDISK_TARGET) +$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_DEBUG_BOOTIMAGE_TARGET) $(INSTALLED_TEST_HARNESS_RAMDISK_TARGET) \ +$(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL) $(call pretty,"Target boot test harness image: $@") $(call build-boot-test-harness-target,$@) .PHONY: bootimage_test_harness-nodeps -bootimage_test_harness-nodeps: $(MKBOOTIMG) +bootimage_test_harness-nodeps: $(MKBOOTIMG) $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL) echo "make $@: ignoring dependencies" $(foreach b,$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET),$(call build-boot-test-harness-target,$b)) @@ -4323,6 +4347,13 @@ endif $(hide) echo 'mkbootimg_args=$(BOARD_MKBOOTIMG_ARGS)' >> $@ $(hide) echo 'recovery_mkbootimg_args=$(BOARD_RECOVERY_MKBOOTIMG_ARGS)' >> $@ $(hide) echo 'mkbootimg_version_args=$(INTERNAL_MKBOOTIMG_VERSION_ARGS)' >> $@ +ifdef BOARD_GKI_SIGNING_KEY_PATH + $(hide) echo 'gki_signing_key_path=$(BOARD_GKI_SIGNING_KEY_PATH)' >> $@ + $(hide) echo 'gki_signing_algorithm=$(BOARD_GKI_SIGNING_ALGORITHM)' >> $@ +endif +ifdef BOARD_GKI_SIGNING_SIGNATURE_ARGS + $(hide) echo 'gki_signing_signature_args=$(BOARD_GKI_SIGNING_SIGNATURE_ARGS)' >> $@ +endif $(hide) echo "multistage_support=1" >> $@ $(hide) echo "blockimgdiff_versions=3,4" >> $@ ifeq ($(PRODUCT_BUILD_GENERIC_OTA_PACKAGE),true) diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py index 006181985..414ab9748 100644 --- a/tools/releasetools/common.py +++ b/tools/releasetools/common.py @@ -1339,6 +1339,35 @@ def AddAftlInclusionProof(output_image): RunAndCheckOutput(verify_cmd) +def AppendGkiSigningArgs(cmd): + """Append GKI signing arguments for mkbootimg.""" + # e.g., --gki_signing_key path/to/signing_key + # --gki_signing_algorithm SHA256_RSA4096" + + key_path = OPTIONS.info_dict.get("gki_signing_key_path") + # It's fine that a non-GKI boot.img has no gki_signing_key_path. + if not key_path: + return + + if not os.path.exists(key_path) and OPTIONS.search_path: + new_key_path = os.path.join(OPTIONS.search_path, key_path) + if os.path.exists(new_key_path): + key_path = new_key_path + + # Checks key_path exists, before appending --gki_signing_* args. + if not os.path.exists(key_path): + raise ExternalError('gki_signing_key_path: "{}" not found'.format(key_path)) + + algorithm = OPTIONS.info_dict.get("gki_signing_algorithm") + if key_path and algorithm: + cmd.extend(["--gki_signing_key", key_path, + "--gki_signing_algorithm", algorithm]) + + signature_args = OPTIONS.info_dict.get("gki_signing_signature_args") + if signature_args: + cmd.extend(["--gki_signing_signature_args", signature_args]) + + def BuildVBMeta(image_path, partitions, name, needed_partitions): """Creates a VBMeta image. @@ -1520,6 +1549,8 @@ def _BuildBootableImage(image_name, sourcedir, fs_config_file, info_dict=None, if has_ramdisk: cmd.extend(["--ramdisk", ramdisk_img.name]) + AppendGkiSigningArgs(cmd) + img_unsigned = None if info_dict.get("vboot"): img_unsigned = tempfile.NamedTemporaryFile() diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py index 00acd980e..3db555974 100755 --- a/tools/releasetools/sign_target_files_apks.py +++ b/tools/releasetools/sign_target_files_apks.py @@ -123,6 +123,17 @@ Usage: sign_target_files_apks [flags] input_target_files output_target_files mounted on the partition (e.g. "--signing_helper /path/to/helper"). The args will be appended to the existing ones in info dict. + --gki_signing_algorithm + --gki_signing_key + Use the specified algorithm (e.g. SHA256_RSA4096) and the key to generate + 'boot signature' in a v4 boot.img. Otherwise it uses the existing values + in info dict. + + --gki_signing_extra_args + Specify any additional args that are needed to generate 'boot signature' + (e.g. --prop foo:bar). The args will be appended to the existing ones + in info dict. + --android_jar_path Path to the android.jar to repack the apex file. """ @@ -174,6 +185,9 @@ OPTIONS.tag_changes = ("-test-keys", "-dev-keys", "+release-keys") OPTIONS.avb_keys = {} OPTIONS.avb_algorithms = {} OPTIONS.avb_extra_args = {} +OPTIONS.gki_signing_key = None +OPTIONS.gki_signing_algorithm = None +OPTIONS.gki_signing_extra_args = None OPTIONS.android_jar_path = None @@ -677,6 +691,9 @@ def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info, if misc_info.get('avb_enable') == 'true': RewriteAvbProps(misc_info) + # Replace the GKI signing key for boot.img, if any. + ReplaceGkiSigningKey(misc_info) + # Write back misc_info with the latest values. ReplaceMiscInfoTxt(input_tf_zip, output_tf_zip, misc_info) @@ -995,6 +1012,28 @@ def RewriteAvbProps(misc_info): misc_info[args_key] = result +def ReplaceGkiSigningKey(misc_info): + """Replaces the GKI signing key.""" + + key = OPTIONS.gki_signing_key + if not key: + return + + algorithm = OPTIONS.gki_signing_algorithm + if not algorithm: + raise ValueError("Missing --gki_signing_algorithm") + + print('Replacing GKI signing key with "%s" (%s)' % (key, algorithm)) + misc_info["gki_signing_algorithm"] = algorithm + misc_info["gki_signing_key_path"] = key + + extra_args = OPTIONS.gki_signing_extra_args + if extra_args: + print('Setting extra GKI signing args: "%s"' % (extra_args)) + misc_info["gki_signing_signature_args"] = ( + misc_info.get("gki_signing_signature_args", '') + ' ' + extra_args) + + def BuildKeyMap(misc_info, key_mapping_options): for s, d in key_mapping_options: if s is None: # -d option @@ -1226,6 +1265,12 @@ def main(argv): # 'oem=--signing_helper_with_files=/tmp/avbsigner.sh'. partition, extra_args = a.split("=", 1) OPTIONS.avb_extra_args[partition] = extra_args + elif o == "--gki_signing_key": + OPTIONS.gki_signing_key = a + elif o == "--gki_signing_algorithm": + OPTIONS.gki_signing_algorithm = a + elif o == "--gki_signing_extra_args": + OPTIONS.gki_signing_extra_args = a else: return False return True @@ -1273,6 +1318,9 @@ def main(argv): "avb_extra_custom_image_key=", "avb_extra_custom_image_algorithm=", "avb_extra_custom_image_extra_args=", + "gki_signing_key=", + "gki_signing_algorithm=", + "gki_signing_extra_args=", ], extra_option_handler=option_handler) diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py index ecd759c80..a516366ec 100644 --- a/tools/releasetools/test_common.py +++ b/tools/releasetools/test_common.py @@ -1670,6 +1670,127 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): common.OPTIONS.aftl_key_path] common.RunAndCheckOutput(verify_cmd) + @test_utils.SkipIfExternalToolsUnavailable() + def test_AppendGkiSigningArgs_NoSigningKeyPath(self): + # A non-GKI boot.img has no gki_signing_key_path. + common.OPTIONS.info_dict = { + # 'gki_signing_key_path': pubkey, + 'gki_signing_algorithm': 'SHA256_RSA4096', + 'gki_signing_signature_args': '--prop foo:bar', + } + + # Tests no --gki_signing_* args are appended if there is no + # gki_signing_key_path. + cmd = ['mkbootimg', '--header_version', '4'] + expected_cmd = ['mkbootimg', '--header_version', '4'] + common.AppendGkiSigningArgs(cmd) + self.assertEqual(cmd, expected_cmd) + + def test_AppendGkiSigningArgs_NoSigningAlgorithm(self): + pubkey = os.path.join(self.testdata_dir, 'testkey_gki.pem') + with open(pubkey, 'wb') as f: + f.write(b'\x00' * 100) + self.assertTrue(os.path.exists(pubkey)) + + # Tests no --gki_signing_* args are appended if there is no + # gki_signing_algorithm. + common.OPTIONS.info_dict = { + 'gki_signing_key_path': pubkey, + # 'gki_signing_algorithm': 'SHA256_RSA4096', + 'gki_signing_signature_args': '--prop foo:bar', + } + + cmd = ['mkbootimg', '--header_version', '4'] + expected_cmd = ['mkbootimg', '--header_version', '4'] + common.AppendGkiSigningArgs(cmd) + self.assertEqual(cmd, expected_cmd) + + @test_utils.SkipIfExternalToolsUnavailable() + def test_AppendGkiSigningArgs(self): + pubkey = os.path.join(self.testdata_dir, 'testkey_gki.pem') + with open(pubkey, 'wb') as f: + f.write(b'\x00' * 100) + self.assertTrue(os.path.exists(pubkey)) + + common.OPTIONS.info_dict = { + 'gki_signing_key_path': pubkey, + 'gki_signing_algorithm': 'SHA256_RSA4096', + 'gki_signing_signature_args': '--prop foo:bar', + } + cmd = ['mkbootimg', '--header_version', '4'] + common.AppendGkiSigningArgs(cmd) + + expected_cmd = [ + 'mkbootimg', '--header_version', '4', + '--gki_signing_key', pubkey, + '--gki_signing_algorithm', 'SHA256_RSA4096', + '--gki_signing_signature_args', '--prop foo:bar' + ] + self.assertEqual(cmd, expected_cmd) + + @test_utils.SkipIfExternalToolsUnavailable() + def test_AppendGkiSigningArgs_KeyPathNotFound(self): + pubkey = os.path.join(self.testdata_dir, 'no_testkey_gki.pem') + self.assertFalse(os.path.exists(pubkey)) + + common.OPTIONS.info_dict = { + 'gki_signing_key_path': pubkey, + 'gki_signing_algorithm': 'SHA256_RSA4096', + 'gki_signing_signature_args': '--prop foo:bar', + } + cmd = ['mkbootimg', '--header_version', '4'] + self.assertRaises(common.ExternalError, common.AppendGkiSigningArgs, cmd) + + @test_utils.SkipIfExternalToolsUnavailable() + def test_AppendGkiSigningArgs_SearchKeyPath(self): + pubkey = 'testkey_gki.pem' + self.assertFalse(os.path.exists(pubkey)) + + # Tests it should replace the pubkey with an existed key under + # OPTIONS.search_path, i.e., os.path.join(OPTIONS.search_path, pubkey). + search_path_dir = common.MakeTempDir() + search_pubkey = os.path.join(search_path_dir, pubkey) + with open(search_pubkey, 'wb') as f: + f.write(b'\x00' * 100) + self.assertTrue(os.path.exists(search_pubkey)) + + common.OPTIONS.search_path = search_path_dir + common.OPTIONS.info_dict = { + 'gki_signing_key_path': pubkey, + 'gki_signing_algorithm': 'SHA256_RSA4096', + 'gki_signing_signature_args': '--prop foo:bar', + } + cmd = ['mkbootimg', '--header_version', '4'] + common.AppendGkiSigningArgs(cmd) + + expected_cmd = [ + 'mkbootimg', '--header_version', '4', + '--gki_signing_key', search_pubkey, + '--gki_signing_algorithm', 'SHA256_RSA4096', + '--gki_signing_signature_args', '--prop foo:bar' + ] + self.assertEqual(cmd, expected_cmd) + + @test_utils.SkipIfExternalToolsUnavailable() + def test_AppendGkiSigningArgs_SearchKeyPathNotFound(self): + pubkey = 'no_testkey_gki.pem' + self.assertFalse(os.path.exists(pubkey)) + + # Tests it should raise ExternalError if no key found under + # OPTIONS.search_path. + search_path_dir = common.MakeTempDir() + search_pubkey = os.path.join(search_path_dir, pubkey) + self.assertFalse(os.path.exists(search_pubkey)) + + common.OPTIONS.search_path = search_path_dir + common.OPTIONS.info_dict = { + 'gki_signing_key_path': pubkey, + 'gki_signing_algorithm': 'SHA256_RSA4096', + 'gki_signing_signature_args': '--prop foo:bar', + } + cmd = ['mkbootimg', '--header_version', '4'] + self.assertRaises(common.ExternalError, common.AppendGkiSigningArgs, cmd) + class InstallRecoveryScriptFormatTest(test_utils.ReleaseToolsTestCase): """Checks the format of install-recovery.sh. diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py index 18e48580c..64e27a28d 100644 --- a/tools/releasetools/test_sign_target_files_apks.py +++ b/tools/releasetools/test_sign_target_files_apks.py @@ -23,8 +23,8 @@ import common import test_utils from sign_target_files_apks import ( CheckApkAndApexKeysAvailable, EditTags, GetApkFileInfo, ReadApexKeysInfo, - ReplaceCerts, ReplaceVerityKeyId, RewriteAvbProps, RewriteProps, - WriteOtacerts) + ReplaceCerts, ReplaceGkiSigningKey, ReplaceVerityKeyId, RewriteAvbProps, + RewriteProps, WriteOtacerts) class SignTargetFilesApksTest(test_utils.ReleaseToolsTestCase): @@ -588,3 +588,52 @@ name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_te 'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem', 'build/make/target/product/security/testkey'), }, keys_info) + + def test_ReplaceGkiSigningKey(self): + common.OPTIONS.gki_signing_key = 'release_gki_key' + common.OPTIONS.gki_signing_algorithm = 'release_gki_algorithm' + common.OPTIONS.gki_signing_extra_args = 'release_gki_signature_extra_args' + + misc_info = { + 'gki_signing_key_path': 'default_gki_key', + 'gki_signing_algorithm': 'default_gki_algorithm', + 'gki_signing_signature_args': 'default_gki_signature_args', + } + expected_dict = { + 'gki_signing_key_path': 'release_gki_key', + 'gki_signing_algorithm': 'release_gki_algorithm', + 'gki_signing_signature_args': 'default_gki_signature_args release_gki_signature_extra_args', + } + ReplaceGkiSigningKey(misc_info) + self.assertDictEqual(expected_dict, misc_info) + + def test_ReplaceGkiSigningKey_MissingSigningAlgorithm(self): + common.OPTIONS.gki_signing_key = 'release_gki_key' + common.OPTIONS.gki_signing_algorithm = None + common.OPTIONS.gki_signing_extra_args = 'release_gki_signature_extra_args' + + misc_info = { + 'gki_signing_key_path': 'default_gki_key', + 'gki_signing_algorithm': 'default_gki_algorithm', + 'gki_signing_signature_args': 'default_gki_signature_args', + } + self.assertRaises(ValueError, ReplaceGkiSigningKey, misc_info) + + def test_ReplaceGkiSigningKey_MissingSigningKeyNop(self): + common.OPTIONS.gki_signing_key = None + common.OPTIONS.gki_signing_algorithm = 'release_gki_algorithm' + common.OPTIONS.gki_signing_extra_args = 'release_gki_signature_extra_args' + + # No change to misc_info if common.OPTIONS.gki_signing_key is missing. + misc_info = { + 'gki_signing_key_path': 'default_gki_key', + 'gki_signing_algorithm': 'default_gki_algorithm', + 'gki_signing_signature_args': 'default_gki_signature_args', + } + expected_dict = { + 'gki_signing_key_path': 'default_gki_key', + 'gki_signing_algorithm': 'default_gki_algorithm', + 'gki_signing_signature_args': 'default_gki_signature_args', + } + ReplaceGkiSigningKey(misc_info) + self.assertDictEqual(expected_dict, misc_info)