releasetools: Support signing APEXes.

Bug: 123716522
Test: Run sign_target_files_apks.py to sign a target_files with APEXes.
Test: Run check_target_files_signatures.py on signed artifact.
Test: python -m unittest test_sign_target_files_apks
Change-Id: I3fa13e3d9461cf5e0838e0572d436e218164fe41
diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py
index 18762ee..9d21429 100644
--- a/tools/releasetools/test_sign_target_files_apks.py
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -21,8 +21,8 @@
 import common
 import test_utils
 from sign_target_files_apks import (
-    CheckAllApksSigned, EditTags, GetApkFileInfo, ReplaceCerts,
-    ReplaceVerityKeyId, RewriteProps)
+    CheckApkAndApexKeysAvailable, EditTags, GetApkFileInfo, ReadApexKeysInfo,
+    ReplaceCerts, ReplaceVerityKeyId, RewriteProps)
 
 
 class SignTargetFilesApksTest(test_utils.ReleaseToolsTestCase):
@@ -33,6 +33,10 @@
   <signer signature="{}"><seinfo value="media"/></signer>
 </policy>"""
 
+  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"
+"""
+
   def setUp(self):
     self.testdata_dir = test_utils.get_testdata_dir()
 
@@ -207,7 +211,7 @@
     }
     self.assertEqual(output_xml, ReplaceCerts(input_xml))
 
-  def test_CheckAllApksSigned(self):
+  def test_CheckApkAndApexKeysAvailable(self):
     input_file = common.MakeTempFile(suffix='.zip')
     with zipfile.ZipFile(input_file, 'w') as input_zip:
       input_zip.writestr('SYSTEM/app/App1.apk', "App1-content")
@@ -219,16 +223,17 @@
         'App3.apk' : 'key3',
     }
     with zipfile.ZipFile(input_file) as input_zip:
-      CheckAllApksSigned(input_zip, apk_key_map, None)
-      CheckAllApksSigned(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.
-      CheckAllApksSigned(input_zip, apk_key_map, None)
-      CheckAllApksSigned(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, CheckAllApksSigned, input_zip, apk_key_map, '.gz')
+          AssertionError, CheckApkAndApexKeysAvailable, input_zip, apk_key_map,
+          '.gz')
 
   def test_GetApkFileInfo(self):
     (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
@@ -344,3 +349,62 @@
     self.assertRaises(
         AssertionError, GetApkFileInfo, "SYSTEM_OTHER/preloads/apps/Chats.apk",
         None, None)
+
+  def test_ReadApexKeysInfo(self):
+    target_files = common.MakeTempFile(suffix='.zip')
+    with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+      target_files_zip.writestr('META/apexkeys.txt', self.APEX_KEYS_TXT)
+
+    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)
+
+  def test_ReadApexKeysInfo_mismatchingKeys(self):
+    # Mismatching payload public / private keys.
+    apex_keys = self.APEX_KEYS_TXT + (
+        'name="apex.apexd_test_different_app2.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_3.pem" '
+        'container_certificate="build/target/product/security/testkey.x509.pem" '
+        'container_private_key="build/target/product/security/testkey.pk8"')
+    target_files = common.MakeTempFile(suffix='.zip')
+    with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+      target_files_zip.writestr('META/apexkeys.txt', apex_keys)
+
+    with zipfile.ZipFile(target_files) as target_files_zip:
+      self.assertRaises(ValueError, ReadApexKeysInfo, target_files_zip)
+
+  def test_ReadApexKeysInfo_missingPrivateKey(self):
+    # Invalid lines will be skipped.
+    apex_keys = self.APEX_KEYS_TXT + (
+        'name="apex.apexd_test_different_app2.apex" '
+        'public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.avbpubkey" '
+        'container_certificate="build/target/product/security/testkey.x509.pem" '
+        'container_private_key="build/target/product/security/testkey.pk8"')
+    target_files = common.MakeTempFile(suffix='.zip')
+    with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+      target_files_zip.writestr('META/apexkeys.txt', apex_keys)
+
+    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)