Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 76a4c62f authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Support custom APEX signing tool"

parents 3f35c935 8caba5e1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -4323,6 +4323,7 @@ INTERNAL_OTATOOLS_MODULES := \
  shflags \
  sign_apex \
  sign_target_files_apks \
  sign_virt_apex \
  signapk \
  simg2img \
  sload_f2fs \
+1 −0
Original line number Diff line number Diff line
@@ -142,6 +142,7 @@ class ApexApkSigner(object):
      has_signed_content = True

    if self.sign_tool:
      logger.info('Signing payload contents in apex %s with %s', self.apex_path, self.sign_tool)
      cmd = [self.sign_tool, '--avbtool', self.avbtool, payload_key, payload_dir]
      common.RunAndCheckOutput(cmd)
      has_signed_content = True
+1 −1
Original line number Diff line number Diff line
@@ -2107,7 +2107,7 @@ def GetKeyPasswords(keylist):
  devnull = open("/dev/null", "w+b")
  for k in sorted(keylist):
    # We don't need a password for things that aren't really keys.
    if k in SPECIAL_CERT_STRINGS:
    if k in SPECIAL_CERT_STRINGS or k is None:
      no_passwords.append(k)
      continue

+21 −17
Original line number Diff line number Diff line
@@ -262,7 +262,7 @@ def GetApexKeys(keys_info, key_map):

  Args:
    keys_info: A dict that maps from APEX filenames to a tuple of (payload_key,
        container_key).
        container_key, sign_tool).
    key_map: A dict that overrides the keys, specified via command-line input.

  Returns:
@@ -280,11 +280,11 @@ def GetApexKeys(keys_info, key_map):
    if apex not in keys_info:
      logger.warning('Failed to find %s in target_files; Ignored', apex)
      continue
    keys_info[apex] = (key, keys_info[apex][1])
    keys_info[apex] = (key, keys_info[apex][1], keys_info[apex][2])

  # Apply the key remapping to container keys.
  for apex, (payload_key, container_key) in keys_info.items():
    keys_info[apex] = (payload_key, key_map.get(container_key, container_key))
  for apex, (payload_key, container_key, sign_tool) in keys_info.items():
    keys_info[apex] = (payload_key, key_map.get(container_key, container_key), sign_tool)

  # Apply all the --extra_apks options to override the container keys.
  for apex, key in OPTIONS.extra_apks.items():
@@ -293,13 +293,13 @@ def GetApexKeys(keys_info, key_map):
      continue
    if not key:
      key = 'PRESIGNED'
    keys_info[apex] = (keys_info[apex][0], key_map.get(key, key))
    keys_info[apex] = (keys_info[apex][0], key_map.get(key, key), keys_info[apex][2])

  # A PRESIGNED container entails a PRESIGNED payload. Apply this to all the
  # APEX key pairs. However, a PRESIGNED container with non-PRESIGNED payload
  # (overridden via commandline) indicates a config error, which should not be
  # allowed.
  for apex, (payload_key, container_key) in keys_info.items():
  for apex, (payload_key, container_key, sign_tool) in keys_info.items():
    if container_key != 'PRESIGNED':
      continue
    if apex in OPTIONS.extra_apex_payload_keys:
@@ -311,7 +311,7 @@ def GetApexKeys(keys_info, key_map):
      print(
          "Setting {} payload as PRESIGNED due to PRESIGNED container".format(
              apex))
    keys_info[apex] = ('PRESIGNED', 'PRESIGNED')
    keys_info[apex] = ('PRESIGNED', 'PRESIGNED', None)

  return keys_info

@@ -372,7 +372,7 @@ def CheckApkAndApexKeysAvailable(input_tf_zip, known_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).
        (payload_key, container_key, sign_tool).

  Raises:
    AssertionError: On finding unknown APKs and APEXes.
@@ -417,7 +417,7 @@ def CheckApkAndApexKeysAvailable(input_tf_zip, known_keys,

    name = GetApexFilename(info.filename)

    (payload_key, container_key) = apex_keys[name]
    (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
@@ -569,7 +569,7 @@ def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
    elif IsApexFile(filename):
      name = GetApexFilename(filename)

      payload_key, container_key = apex_keys[name]
      payload_key, container_key, sign_tool = apex_keys[name]

      # We've asserted not having a case with only one of them PRESIGNED.
      if (payload_key not in common.SPECIAL_CERT_STRINGS and
@@ -588,7 +588,8 @@ def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
            apk_keys,
            codename_to_api_level_map,
            no_hashtree=None,  # Let apex_util determine if hash tree is needed
            signing_args=OPTIONS.avb_extra_args.get('apex'))
            signing_args=OPTIONS.avb_extra_args.get('apex'),
            sign_tool=sign_tool)
        common.ZipWrite(output_tf_zip, signed_apex, filename)

      else:
@@ -1147,15 +1148,16 @@ def ReadApexKeysInfo(tf_zip):

  Given a target-files ZipFile, parses the META/apexkeys.txt entry and returns a
  dict that contains the mapping from APEX names (e.g. com.android.tzdata) to a
  tuple of (payload_key, container_key).
  tuple of (payload_key, container_key, sign_tool).

  Args:
    tf_zip: The input target_files ZipFile (already open).

  Returns:
    (payload_key, container_key): payload_key contains the path to the payload
        signing key; container_key contains the path to the container signing
        key.
    (payload_key, container_key, sign_tool):
      - payload_key contains the path to the payload signing key
      - container_key contains the path to the container signing key
      - sign_tool is an apex-specific signing tool for its payload contents
  """
  keys = {}
  for line in tf_zip.read('META/apexkeys.txt').decode().split('\n'):
@@ -1168,7 +1170,8 @@ def ReadApexKeysInfo(tf_zip):
        r'private_key="(?P<PAYLOAD_PRIVATE_KEY>.*)"\s+'
        r'container_certificate="(?P<CONTAINER_CERT>.*)"\s+'
        r'container_private_key="(?P<CONTAINER_PRIVATE_KEY>.*?)"'
        r'(\s+partition="(?P<PARTITION>.*?)")?$',
        r'(\s+partition="(?P<PARTITION>.*?)")?'
        r'(\s+sign_tool="(?P<SIGN_TOOL>.*?)")?$',
        line)
    if not matches:
      continue
@@ -1197,7 +1200,8 @@ def ReadApexKeysInfo(tf_zip):
    else:
      raise ValueError("Failed to parse container keys: \n{}".format(line))

    keys[name] = (payload_private_key, container_key)
    sign_tool = matches.group("SIGN_TOOL")
    keys[name] = (payload_private_key, container_key, sign_tool)

  return keys

+15 −15
Original line number Diff line number Diff line
@@ -328,23 +328,23 @@ name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_te
        'Apex3.apex' : 'key3',
    }
    apex_keys = {
        'Apex1.apex' : ('payload-key1', 'container-key1'),
        'Apex2.apex' : ('payload-key2', 'container-key2'),
        'Apex1.apex' : ('payload-key1', 'container-key1', None),
        'Apex2.apex' : ('payload-key2', 'container-key2', None),
    }
    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')
      apex_keys['Apex2.apex'] = ('PRESIGNED', 'PRESIGNED', None)
      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')
      apex_keys['Apex2.apex'] = ('payload-key2', 'PRESIGNED', None)
      self.assertRaises(
          AssertionError, CheckApkAndApexKeysAvailable, input_zip, apk_key_map,
          None, apex_keys)

      apex_keys['Apex2.apex'] = ('PRESIGNED', 'container-key1')
      apex_keys['Apex2.apex'] = ('PRESIGNED', 'container-key1', None)
      self.assertRaises(
          AssertionError, CheckApkAndApexKeysAvailable, input_zip, apk_key_map,
          None, apex_keys)
@@ -475,10 +475,10 @@ name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_te
    self.assertEqual({
        'apex.apexd_test.apex': (
            'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
            'build/make/target/product/security/testkey'),
            'build/make/target/product/security/testkey', None),
        'apex.apexd_test_different_app.apex': (
            'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
            'build/make/target/product/security/testkey'),
            'build/make/target/product/security/testkey', None),
        }, keys_info)

  def test_ReadApexKeysInfo_mismatchingContainerKeys(self):
@@ -514,10 +514,10 @@ name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_te
    self.assertEqual({
        'apex.apexd_test.apex': (
            'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
            'build/make/target/product/security/testkey'),
            'build/make/target/product/security/testkey', None),
        'apex.apexd_test_different_app.apex': (
            'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
            'build/make/target/product/security/testkey'),
            'build/make/target/product/security/testkey', None),
        }, keys_info)

  def test_ReadApexKeysInfo_missingPayloadPublicKey(self):
@@ -537,10 +537,10 @@ name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_te
    self.assertEqual({
        'apex.apexd_test.apex': (
            'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
            'build/make/target/product/security/testkey'),
            'build/make/target/product/security/testkey', None),
        'apex.apexd_test_different_app.apex': (
            'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
            'build/make/target/product/security/testkey'),
            'build/make/target/product/security/testkey', None),
        }, keys_info)

  def test_ReadApexKeysInfo_presignedKeys(self):
@@ -560,10 +560,10 @@ name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_te
    self.assertEqual({
        'apex.apexd_test.apex': (
            'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
            'build/make/target/product/security/testkey'),
            'build/make/target/product/security/testkey', None),
        'apex.apexd_test_different_app.apex': (
            'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
            'build/make/target/product/security/testkey'),
            'build/make/target/product/security/testkey', None),
        }, keys_info)

  def test_ReadApexKeysInfo_presignedKeys(self):
@@ -583,10 +583,10 @@ name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_te
    self.assertEqual({
        'apex.apexd_test.apex': (
            'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
            'build/make/target/product/security/testkey'),
            'build/make/target/product/security/testkey', None),
        'apex.apexd_test_different_app.apex': (
            'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
            'build/make/target/product/security/testkey'),
            'build/make/target/product/security/testkey', None),
        }, keys_info)

  def test_ReplaceGkiSigningKey(self):