blob: 18e48580ca1fdf7acde66e4cf40f9106f6bc1467 [file] [log] [blame]
Tao Baoa7054ee2017-12-08 14:42:16 -08001#
2# Copyright (C) 2017 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
Tao Bao66472632017-12-04 17:16:36 -080017import base64
Tao Baobb733882019-07-24 23:31:19 -070018import io
Tao Baode1d4792018-02-20 10:05:46 -080019import os.path
Tao Baoe838d142017-12-23 23:44:48 -080020import zipfile
Tao Baoa7054ee2017-12-08 14:42:16 -080021
Tao Baoe838d142017-12-23 23:44:48 -080022import common
Tao Baode1d4792018-02-20 10:05:46 -080023import test_utils
Tao Bao66472632017-12-04 17:16:36 -080024from sign_target_files_apks import (
Tao Baoaa7e9932019-03-15 09:37:01 -070025 CheckApkAndApexKeysAvailable, EditTags, GetApkFileInfo, ReadApexKeysInfo,
Tao Bao19b02fe2019-10-09 00:04:28 -070026 ReplaceCerts, ReplaceVerityKeyId, RewriteAvbProps, RewriteProps,
27 WriteOtacerts)
Tao Baoa7054ee2017-12-08 14:42:16 -080028
29
Tao Bao65b94e92018-10-11 21:57:26 -070030class SignTargetFilesApksTest(test_utils.ReleaseToolsTestCase):
Tao Baoa7054ee2017-12-08 14:42:16 -080031
Tao Bao66472632017-12-04 17:16:36 -080032 MAC_PERMISSIONS_XML = """<?xml version="1.0" encoding="iso-8859-1"?>
33<policy>
34 <signer signature="{}"><seinfo value="platform"/></signer>
35 <signer signature="{}"><seinfo value="media"/></signer>
36</policy>"""
37
Bill Peckham5c7b0342020-04-03 15:36:23 -070038 # Note that we test one apex with the partition tag, and another without to
39 # make sure that new OTA tools can process an older target files package that
40 # does not include the partition tag.
41
Tao Baoe1343992019-03-19 12:24:03 -070042 # pylint: disable=line-too-long
Bill Peckham19c3feb2020-03-20 18:31:43 -070043 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/make/target/product/security/testkey.x509.pem" container_private_key="build/make/target/product/security/testkey.pk8" partition="system"
Bill Peckham5c7b0342020-04-03 15:36:23 -070044name="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/make/target/product/security/testkey.x509.pem" container_private_key="build/make/target/product/security/testkey.pk8"
Tao Baoaa7e9932019-03-15 09:37:01 -070045"""
46
Tao Baoe838d142017-12-23 23:44:48 -080047 def setUp(self):
Tao Baode1d4792018-02-20 10:05:46 -080048 self.testdata_dir = test_utils.get_testdata_dir()
Tao Baoe838d142017-12-23 23:44:48 -080049
Tao Baoa7054ee2017-12-08 14:42:16 -080050 def test_EditTags(self):
51 self.assertEqual(EditTags('dev-keys'), ('release-keys'))
52 self.assertEqual(EditTags('test-keys'), ('release-keys'))
53
54 # Multiple tags.
55 self.assertEqual(EditTags('abc,dev-keys,xyz'), ('abc,release-keys,xyz'))
56
57 # Tags are sorted.
58 self.assertEqual(EditTags('xyz,abc,dev-keys,xyz'), ('abc,release-keys,xyz'))
59
Tao Bao19b02fe2019-10-09 00:04:28 -070060 def test_RewriteAvbProps(self):
61 misc_info = {
62 'avb_boot_add_hash_footer_args':
63 ('--prop com.android.build.boot.os_version:R '
64 '--prop com.android.build.boot.security_patch:2019-09-05'),
65 'avb_system_add_hashtree_footer_args':
66 ('--prop com.android.build.system.os_version:R '
67 '--prop com.android.build.system.security_patch:2019-09-05 '
68 '--prop com.android.build.system.fingerprint:'
69 'Android/aosp_taimen/taimen:R/QT/foo:userdebug/test-keys'),
70 'avb_vendor_add_hashtree_footer_args':
71 ('--prop com.android.build.vendor.os_version:R '
72 '--prop com.android.build.vendor.security_patch:2019-09-05 '
73 '--prop com.android.build.vendor.fingerprint:'
74 'Android/aosp_taimen/taimen:R/QT/foo:userdebug/dev-keys'),
75 }
76 expected_dict = {
77 'avb_boot_add_hash_footer_args':
78 ('--prop com.android.build.boot.os_version:R '
79 '--prop com.android.build.boot.security_patch:2019-09-05'),
80 'avb_system_add_hashtree_footer_args':
81 ('--prop com.android.build.system.os_version:R '
82 '--prop com.android.build.system.security_patch:2019-09-05 '
83 '--prop com.android.build.system.fingerprint:'
84 'Android/aosp_taimen/taimen:R/QT/foo:userdebug/release-keys'),
85 'avb_vendor_add_hashtree_footer_args':
86 ('--prop com.android.build.vendor.os_version:R '
87 '--prop com.android.build.vendor.security_patch:2019-09-05 '
88 '--prop com.android.build.vendor.fingerprint:'
89 'Android/aosp_taimen/taimen:R/QT/foo:userdebug/release-keys'),
90 }
91 RewriteAvbProps(misc_info)
92 self.assertDictEqual(expected_dict, misc_info)
93
Tao Baoa7054ee2017-12-08 14:42:16 -080094 def test_RewriteProps(self):
95 props = (
Magnus Strandh234f4b42019-05-01 23:09:30 +020096 ('', ''),
Tao Baoa7054ee2017-12-08 14:42:16 -080097 ('ro.build.fingerprint=foo/bar/dev-keys',
Magnus Strandh234f4b42019-05-01 23:09:30 +020098 'ro.build.fingerprint=foo/bar/release-keys'),
Tao Baoa7054ee2017-12-08 14:42:16 -080099 ('ro.build.thumbprint=foo/bar/dev-keys',
Magnus Strandh234f4b42019-05-01 23:09:30 +0200100 'ro.build.thumbprint=foo/bar/release-keys'),
Tao Baoa7054ee2017-12-08 14:42:16 -0800101 ('ro.vendor.build.fingerprint=foo/bar/dev-keys',
Magnus Strandh234f4b42019-05-01 23:09:30 +0200102 'ro.vendor.build.fingerprint=foo/bar/release-keys'),
Tao Baoa7054ee2017-12-08 14:42:16 -0800103 ('ro.vendor.build.thumbprint=foo/bar/dev-keys',
Magnus Strandh234f4b42019-05-01 23:09:30 +0200104 'ro.vendor.build.thumbprint=foo/bar/release-keys'),
105 ('ro.odm.build.fingerprint=foo/bar/test-keys',
106 'ro.odm.build.fingerprint=foo/bar/release-keys'),
107 ('ro.odm.build.thumbprint=foo/bar/test-keys',
108 'ro.odm.build.thumbprint=foo/bar/release-keys'),
109 ('ro.product.build.fingerprint=foo/bar/dev-keys',
110 'ro.product.build.fingerprint=foo/bar/release-keys'),
111 ('ro.product.build.thumbprint=foo/bar/dev-keys',
112 'ro.product.build.thumbprint=foo/bar/release-keys'),
Justin Yun6151e3f2019-06-25 15:58:13 +0900113 ('ro.system_ext.build.fingerprint=foo/bar/test-keys',
114 'ro.system_ext.build.fingerprint=foo/bar/release-keys'),
115 ('ro.system_ext.build.thumbprint=foo/bar/test-keys',
116 'ro.system_ext.build.thumbprint=foo/bar/release-keys'),
Magnus Strandh234f4b42019-05-01 23:09:30 +0200117 ('# comment line 1', '# comment line 1'),
Tao Baoa7054ee2017-12-08 14:42:16 -0800118 ('ro.bootimage.build.fingerprint=foo/bar/dev-keys',
Magnus Strandh234f4b42019-05-01 23:09:30 +0200119 'ro.bootimage.build.fingerprint=foo/bar/release-keys'),
Tao Baoa7054ee2017-12-08 14:42:16 -0800120 ('ro.build.description='
121 'sailfish-user 8.0.0 OPR6.170623.012 4283428 dev-keys',
122 'ro.build.description='
Magnus Strandh234f4b42019-05-01 23:09:30 +0200123 'sailfish-user 8.0.0 OPR6.170623.012 4283428 release-keys'),
124 ('ro.build.tags=dev-keys', 'ro.build.tags=release-keys'),
125 ('ro.build.tags=test-keys', 'ro.build.tags=release-keys'),
126 ('ro.system.build.tags=dev-keys',
127 'ro.system.build.tags=release-keys'),
128 ('ro.vendor.build.tags=dev-keys',
129 'ro.vendor.build.tags=release-keys'),
130 ('ro.odm.build.tags=dev-keys',
131 'ro.odm.build.tags=release-keys'),
132 ('ro.product.build.tags=dev-keys',
133 'ro.product.build.tags=release-keys'),
Justin Yun6151e3f2019-06-25 15:58:13 +0900134 ('ro.system_ext.build.tags=dev-keys',
135 'ro.system_ext.build.tags=release-keys'),
Magnus Strandh234f4b42019-05-01 23:09:30 +0200136 ('# comment line 2', '# comment line 2'),
Tao Baoa7054ee2017-12-08 14:42:16 -0800137 ('ro.build.display.id=OPR6.170623.012 dev-keys',
Magnus Strandh234f4b42019-05-01 23:09:30 +0200138 'ro.build.display.id=OPR6.170623.012'),
139 ('# comment line 3', '# comment line 3'),
Tao Baoa7054ee2017-12-08 14:42:16 -0800140 )
141
142 # Assert the case for each individual line.
Magnus Strandh234f4b42019-05-01 23:09:30 +0200143 for prop, expected in props:
144 self.assertEqual(expected + '\n', RewriteProps(prop))
Tao Baoa7054ee2017-12-08 14:42:16 -0800145
146 # Concatenate all the input lines.
Magnus Strandh234f4b42019-05-01 23:09:30 +0200147 self.assertEqual(
148 '\n'.join([prop[1] for prop in props]) + '\n',
149 RewriteProps('\n'.join([prop[0] for prop in props])))
Tao Baoe838d142017-12-23 23:44:48 -0800150
151 def test_ReplaceVerityKeyId(self):
152 BOOT_CMDLINE1 = (
153 "console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0 "
154 "androidboot.hardware=marlin user_debug=31 ehci-hcd.park=3 "
155 "lpm_levels.sleep_disabled=1 cma=32M@0-0xffffffff loop.max_part=7 "
156 "buildvariant=userdebug "
157 "veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f\n")
158
159 BOOT_CMDLINE2 = (
160 "console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0 "
161 "androidboot.hardware=marlin user_debug=31 ehci-hcd.park=3 "
162 "lpm_levels.sleep_disabled=1 cma=32M@0-0xffffffff loop.max_part=7 "
163 "buildvariant=userdebug "
Tao Baode1d4792018-02-20 10:05:46 -0800164 "veritykeyid=id:d24f2590e9abab5cff5f59da4c4f0366e3f43e94\n")
Tao Baoe838d142017-12-23 23:44:48 -0800165
Tao Baode1d4792018-02-20 10:05:46 -0800166 input_file = common.MakeTempFile(suffix='.zip')
Kelvin Zhang928c2342020-09-22 16:15:57 -0400167 with zipfile.ZipFile(input_file, 'w', allowZip64=True) as input_zip:
Tao Baoe838d142017-12-23 23:44:48 -0800168 input_zip.writestr('BOOT/cmdline', BOOT_CMDLINE1)
169
170 # Test with the first certificate.
Tao Baode1d4792018-02-20 10:05:46 -0800171 cert_file = os.path.join(self.testdata_dir, 'verity.x509.pem')
Tao Baoe838d142017-12-23 23:44:48 -0800172
Tao Baode1d4792018-02-20 10:05:46 -0800173 output_file = common.MakeTempFile(suffix='.zip')
Kelvin Zhang928c2342020-09-22 16:15:57 -0400174 with zipfile.ZipFile(input_file, 'r', allowZip64=True) as input_zip, \
175 zipfile.ZipFile(output_file, 'w', allowZip64=True) as output_zip:
Tao Baode1d4792018-02-20 10:05:46 -0800176 ReplaceVerityKeyId(input_zip, output_zip, cert_file)
Tao Baoe838d142017-12-23 23:44:48 -0800177
Tao Baode1d4792018-02-20 10:05:46 -0800178 with zipfile.ZipFile(output_file) as output_zip:
Tao Baoa3705452019-06-24 15:33:41 -0700179 self.assertEqual(BOOT_CMDLINE1, output_zip.read('BOOT/cmdline').decode())
Tao Baoe838d142017-12-23 23:44:48 -0800180
181 # Test with the second certificate.
Tao Baode1d4792018-02-20 10:05:46 -0800182 cert_file = os.path.join(self.testdata_dir, 'testkey.x509.pem')
Tao Baoe838d142017-12-23 23:44:48 -0800183
Kelvin Zhang928c2342020-09-22 16:15:57 -0400184 with zipfile.ZipFile(input_file, 'r', allowZip64=True) as input_zip, \
185 zipfile.ZipFile(output_file, 'w', allowZip64=True) as output_zip:
Tao Baode1d4792018-02-20 10:05:46 -0800186 ReplaceVerityKeyId(input_zip, output_zip, cert_file)
Tao Baoe838d142017-12-23 23:44:48 -0800187
Tao Baode1d4792018-02-20 10:05:46 -0800188 with zipfile.ZipFile(output_file) as output_zip:
Tao Baoa3705452019-06-24 15:33:41 -0700189 self.assertEqual(BOOT_CMDLINE2, output_zip.read('BOOT/cmdline').decode())
Tao Baoe838d142017-12-23 23:44:48 -0800190
191 def test_ReplaceVerityKeyId_no_veritykeyid(self):
192 BOOT_CMDLINE = (
193 "console=ttyHSL0,115200,n8 androidboot.hardware=bullhead boot_cpus=0-5 "
194 "lpm_levels.sleep_disabled=1 msm_poweroff.download_mode=0 "
195 "loop.max_part=7\n")
196
Tao Baode1d4792018-02-20 10:05:46 -0800197 input_file = common.MakeTempFile(suffix='.zip')
Kelvin Zhang928c2342020-09-22 16:15:57 -0400198 with zipfile.ZipFile(input_file, 'w', allowZip64=True) as input_zip:
Tao Baoe838d142017-12-23 23:44:48 -0800199 input_zip.writestr('BOOT/cmdline', BOOT_CMDLINE)
200
Tao Baode1d4792018-02-20 10:05:46 -0800201 output_file = common.MakeTempFile(suffix='.zip')
Kelvin Zhang928c2342020-09-22 16:15:57 -0400202 with zipfile.ZipFile(input_file, 'r', allowZip64=True) as input_zip, \
203 zipfile.ZipFile(output_file, 'w', allowZip64=True) as output_zip:
Tao Baoe838d142017-12-23 23:44:48 -0800204 ReplaceVerityKeyId(input_zip, output_zip, None)
205
Tao Baode1d4792018-02-20 10:05:46 -0800206 with zipfile.ZipFile(output_file) as output_zip:
Tao Baoa3705452019-06-24 15:33:41 -0700207 self.assertEqual(BOOT_CMDLINE, output_zip.read('BOOT/cmdline').decode())
Tao Bao66472632017-12-04 17:16:36 -0800208
209 def test_ReplaceCerts(self):
210 cert1_path = os.path.join(self.testdata_dir, 'platform.x509.pem')
211 with open(cert1_path) as cert1_fp:
212 cert1 = cert1_fp.read()
213 cert2_path = os.path.join(self.testdata_dir, 'media.x509.pem')
214 with open(cert2_path) as cert2_fp:
215 cert2 = cert2_fp.read()
216 cert3_path = os.path.join(self.testdata_dir, 'testkey.x509.pem')
217 with open(cert3_path) as cert3_fp:
218 cert3 = cert3_fp.read()
219
220 # Replace cert1 with cert3.
221 input_xml = self.MAC_PERMISSIONS_XML.format(
222 base64.b16encode(common.ParseCertificate(cert1)).lower(),
223 base64.b16encode(common.ParseCertificate(cert2)).lower())
224
225 output_xml = self.MAC_PERMISSIONS_XML.format(
226 base64.b16encode(common.ParseCertificate(cert3)).lower(),
227 base64.b16encode(common.ParseCertificate(cert2)).lower())
228
229 common.OPTIONS.key_map = {
230 cert1_path[:-9] : cert3_path[:-9],
231 }
232
233 self.assertEqual(output_xml, ReplaceCerts(input_xml))
234
235 def test_ReplaceCerts_duplicateEntries(self):
236 cert1_path = os.path.join(self.testdata_dir, 'platform.x509.pem')
237 with open(cert1_path) as cert1_fp:
238 cert1 = cert1_fp.read()
239 cert2_path = os.path.join(self.testdata_dir, 'media.x509.pem')
240 with open(cert2_path) as cert2_fp:
241 cert2 = cert2_fp.read()
242
243 # Replace cert1 with cert2, which leads to duplicate entries.
244 input_xml = self.MAC_PERMISSIONS_XML.format(
245 base64.b16encode(common.ParseCertificate(cert1)).lower(),
246 base64.b16encode(common.ParseCertificate(cert2)).lower())
247
248 common.OPTIONS.key_map = {
249 cert1_path[:-9] : cert2_path[:-9],
250 }
251 self.assertRaises(AssertionError, ReplaceCerts, input_xml)
252
253 def test_ReplaceCerts_skipNonExistentCerts(self):
254 cert1_path = os.path.join(self.testdata_dir, 'platform.x509.pem')
255 with open(cert1_path) as cert1_fp:
256 cert1 = cert1_fp.read()
257 cert2_path = os.path.join(self.testdata_dir, 'media.x509.pem')
258 with open(cert2_path) as cert2_fp:
259 cert2 = cert2_fp.read()
260 cert3_path = os.path.join(self.testdata_dir, 'testkey.x509.pem')
261 with open(cert3_path) as cert3_fp:
262 cert3 = cert3_fp.read()
263
264 input_xml = self.MAC_PERMISSIONS_XML.format(
265 base64.b16encode(common.ParseCertificate(cert1)).lower(),
266 base64.b16encode(common.ParseCertificate(cert2)).lower())
267
268 output_xml = self.MAC_PERMISSIONS_XML.format(
269 base64.b16encode(common.ParseCertificate(cert3)).lower(),
270 base64.b16encode(common.ParseCertificate(cert2)).lower())
271
272 common.OPTIONS.key_map = {
273 cert1_path[:-9] : cert3_path[:-9],
274 'non-existent' : cert3_path[:-9],
275 cert2_path[:-9] : 'non-existent',
276 }
277 self.assertEqual(output_xml, ReplaceCerts(input_xml))
Tao Bao11f955c2018-06-19 12:19:35 -0700278
Tao Baobb733882019-07-24 23:31:19 -0700279 def test_WriteOtacerts(self):
280 certs = [
281 os.path.join(self.testdata_dir, 'platform.x509.pem'),
282 os.path.join(self.testdata_dir, 'media.x509.pem'),
283 os.path.join(self.testdata_dir, 'testkey.x509.pem'),
284 ]
285 entry_name = 'SYSTEM/etc/security/otacerts.zip'
286 output_file = common.MakeTempFile(suffix='.zip')
Kelvin Zhang928c2342020-09-22 16:15:57 -0400287 with zipfile.ZipFile(output_file, 'w', allowZip64=True) as output_zip:
Tao Baobb733882019-07-24 23:31:19 -0700288 WriteOtacerts(output_zip, entry_name, certs)
289 with zipfile.ZipFile(output_file) as input_zip:
290 self.assertIn(entry_name, input_zip.namelist())
291 otacerts_file = io.BytesIO(input_zip.read(entry_name))
292 with zipfile.ZipFile(otacerts_file) as otacerts_zip:
293 self.assertEqual(3, len(otacerts_zip.namelist()))
294
Tao Baoaa7e9932019-03-15 09:37:01 -0700295 def test_CheckApkAndApexKeysAvailable(self):
Tao Bao11f955c2018-06-19 12:19:35 -0700296 input_file = common.MakeTempFile(suffix='.zip')
Kelvin Zhang928c2342020-09-22 16:15:57 -0400297 with zipfile.ZipFile(input_file, 'w', allowZip64=True) as input_zip:
Tao Bao11f955c2018-06-19 12:19:35 -0700298 input_zip.writestr('SYSTEM/app/App1.apk', "App1-content")
299 input_zip.writestr('SYSTEM/app/App2.apk.gz', "App2-content")
300
301 apk_key_map = {
302 'App1.apk' : 'key1',
303 'App2.apk' : 'key2',
304 'App3.apk' : 'key3',
305 }
306 with zipfile.ZipFile(input_file) as input_zip:
Tao Baoe1343992019-03-19 12:24:03 -0700307 CheckApkAndApexKeysAvailable(input_zip, apk_key_map, None, {})
308 CheckApkAndApexKeysAvailable(input_zip, apk_key_map, '.gz', {})
Tao Bao11f955c2018-06-19 12:19:35 -0700309
310 # 'App2.apk.gz' won't be considered as an APK.
Tao Baoe1343992019-03-19 12:24:03 -0700311 CheckApkAndApexKeysAvailable(input_zip, apk_key_map, None, {})
312 CheckApkAndApexKeysAvailable(input_zip, apk_key_map, '.xz', {})
Tao Bao11f955c2018-06-19 12:19:35 -0700313
314 del apk_key_map['App2.apk']
315 self.assertRaises(
Tao Baoaa7e9932019-03-15 09:37:01 -0700316 AssertionError, CheckApkAndApexKeysAvailable, input_zip, apk_key_map,
Tao Baoe1343992019-03-19 12:24:03 -0700317 '.gz', {})
318
319 def test_CheckApkAndApexKeysAvailable_invalidApexKeys(self):
320 input_file = common.MakeTempFile(suffix='.zip')
Kelvin Zhang928c2342020-09-22 16:15:57 -0400321 with zipfile.ZipFile(input_file, 'w', allowZip64=True) as input_zip:
Tao Baoe1343992019-03-19 12:24:03 -0700322 input_zip.writestr('SYSTEM/apex/Apex1.apex', "Apex1-content")
323 input_zip.writestr('SYSTEM/apex/Apex2.apex', "Apex2-content")
324
325 apk_key_map = {
326 'Apex1.apex' : 'key1',
327 'Apex2.apex' : 'key2',
328 'Apex3.apex' : 'key3',
329 }
330 apex_keys = {
331 'Apex1.apex' : ('payload-key1', 'container-key1'),
332 'Apex2.apex' : ('payload-key2', 'container-key2'),
333 }
334 with zipfile.ZipFile(input_file) as input_zip:
335 CheckApkAndApexKeysAvailable(input_zip, apk_key_map, None, apex_keys)
336
337 # Fine to have both keys as PRESIGNED.
338 apex_keys['Apex2.apex'] = ('PRESIGNED', 'PRESIGNED')
339 CheckApkAndApexKeysAvailable(input_zip, apk_key_map, None, apex_keys)
340
341 # Having only one of them as PRESIGNED is not allowed.
342 apex_keys['Apex2.apex'] = ('payload-key2', 'PRESIGNED')
343 self.assertRaises(
344 AssertionError, CheckApkAndApexKeysAvailable, input_zip, apk_key_map,
345 None, apex_keys)
346
347 apex_keys['Apex2.apex'] = ('PRESIGNED', 'container-key1')
348 self.assertRaises(
349 AssertionError, CheckApkAndApexKeysAvailable, input_zip, apk_key_map,
350 None, apex_keys)
Tao Bao11f955c2018-06-19 12:19:35 -0700351
352 def test_GetApkFileInfo(self):
Tao Bao93c2a012018-06-19 12:19:35 -0700353 (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
354 "PRODUCT/apps/Chats.apk", None, [])
Tao Bao11f955c2018-06-19 12:19:35 -0700355 self.assertTrue(is_apk)
356 self.assertFalse(is_compressed)
Tao Bao93c2a012018-06-19 12:19:35 -0700357 self.assertFalse(should_be_skipped)
Tao Bao11f955c2018-06-19 12:19:35 -0700358
Tao Bao93c2a012018-06-19 12:19:35 -0700359 (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
360 "PRODUCT/apps/Chats.apk", None, [])
361 self.assertTrue(is_apk)
362 self.assertFalse(is_compressed)
363 self.assertFalse(should_be_skipped)
364
365 (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
366 "PRODUCT/apps/Chats.dat", None, [])
Tao Bao11f955c2018-06-19 12:19:35 -0700367 self.assertFalse(is_apk)
368 self.assertFalse(is_compressed)
Tao Bao93c2a012018-06-19 12:19:35 -0700369 self.assertFalse(should_be_skipped)
Tao Bao11f955c2018-06-19 12:19:35 -0700370
371 def test_GetApkFileInfo_withCompressedApks(self):
Tao Bao93c2a012018-06-19 12:19:35 -0700372 (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
373 "PRODUCT/apps/Chats.apk.gz", ".gz", [])
Tao Bao11f955c2018-06-19 12:19:35 -0700374 self.assertTrue(is_apk)
375 self.assertTrue(is_compressed)
Tao Bao93c2a012018-06-19 12:19:35 -0700376 self.assertFalse(should_be_skipped)
Tao Bao11f955c2018-06-19 12:19:35 -0700377
Tao Bao93c2a012018-06-19 12:19:35 -0700378 (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
379 "PRODUCT/apps/Chats.apk.gz", ".xz", [])
Tao Bao11f955c2018-06-19 12:19:35 -0700380 self.assertFalse(is_apk)
381 self.assertFalse(is_compressed)
Tao Bao93c2a012018-06-19 12:19:35 -0700382 self.assertFalse(should_be_skipped)
Tao Bao11f955c2018-06-19 12:19:35 -0700383
384 self.assertRaises(
Tao Bao93c2a012018-06-19 12:19:35 -0700385 AssertionError, GetApkFileInfo, "PRODUCT/apps/Chats.apk", "", [])
Tao Bao11f955c2018-06-19 12:19:35 -0700386
387 self.assertRaises(
Tao Bao93c2a012018-06-19 12:19:35 -0700388 AssertionError, GetApkFileInfo, "PRODUCT/apps/Chats.apk", "apk", [])
389
390 def test_GetApkFileInfo_withSkippedPrefixes(self):
391 (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
392 "PRODUCT/preloads/apps/Chats.apk", None, set())
393 self.assertTrue(is_apk)
394 self.assertFalse(is_compressed)
395 self.assertFalse(should_be_skipped)
396
397 (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
398 "PRODUCT/preloads/apps/Chats.apk",
399 None,
400 set(["PRODUCT/preloads/"]))
401 self.assertTrue(is_apk)
402 self.assertFalse(is_compressed)
403 self.assertTrue(should_be_skipped)
404
405 (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
406 "SYSTEM_OTHER/preloads/apps/Chats.apk",
407 None,
408 set(["SYSTEM/preloads/", "SYSTEM_OTHER/preloads/"]))
409 self.assertTrue(is_apk)
410 self.assertFalse(is_compressed)
411 self.assertTrue(should_be_skipped)
412
413 (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
414 "SYSTEM_OTHER/preloads/apps/Chats.apk.gz",
415 ".gz",
416 set(["PRODUCT/prebuilts/", "SYSTEM_OTHER/preloads/"]))
417 self.assertTrue(is_apk)
418 self.assertTrue(is_compressed)
419 self.assertTrue(should_be_skipped)
420
421 (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
422 "SYSTEM_OTHER/preloads/apps/Chats.dat",
423 None,
424 set(["SYSTEM_OTHER/preloads/"]))
425 self.assertFalse(is_apk)
426 self.assertFalse(is_compressed)
427 self.assertFalse(should_be_skipped)
428
429 def test_GetApkFileInfo_checkSkippedPrefixesInput(self):
430 # set
431 (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
432 "SYSTEM_OTHER/preloads/apps/Chats.apk",
433 None,
434 set(["SYSTEM_OTHER/preloads/"]))
435 self.assertTrue(is_apk)
436 self.assertFalse(is_compressed)
437 self.assertTrue(should_be_skipped)
438
439 # tuple
440 (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
441 "SYSTEM_OTHER/preloads/apps/Chats.apk",
442 None,
443 ("SYSTEM_OTHER/preloads/",))
444 self.assertTrue(is_apk)
445 self.assertFalse(is_compressed)
446 self.assertTrue(should_be_skipped)
447
448 # list
449 (is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
450 "SYSTEM_OTHER/preloads/apps/Chats.apk",
451 None,
452 ["SYSTEM_OTHER/preloads/"])
453 self.assertTrue(is_apk)
454 self.assertFalse(is_compressed)
455 self.assertTrue(should_be_skipped)
456
457 # str is invalid.
458 self.assertRaises(
459 AssertionError, GetApkFileInfo, "SYSTEM_OTHER/preloads/apps/Chats.apk",
460 None, "SYSTEM_OTHER/preloads/")
461
462 # None is invalid.
463 self.assertRaises(
464 AssertionError, GetApkFileInfo, "SYSTEM_OTHER/preloads/apps/Chats.apk",
465 None, None)
Tao Baoaa7e9932019-03-15 09:37:01 -0700466
467 def test_ReadApexKeysInfo(self):
468 target_files = common.MakeTempFile(suffix='.zip')
Kelvin Zhang928c2342020-09-22 16:15:57 -0400469 with zipfile.ZipFile(target_files, 'w', allowZip64=True) as target_files_zip:
Tao Baoaa7e9932019-03-15 09:37:01 -0700470 target_files_zip.writestr('META/apexkeys.txt', self.APEX_KEYS_TXT)
471
Kelvin Zhang928c2342020-09-22 16:15:57 -0400472 with zipfile.ZipFile(target_files, allowZip64=True) as target_files_zip:
Tao Baoaa7e9932019-03-15 09:37:01 -0700473 keys_info = ReadApexKeysInfo(target_files_zip)
474
Tao Baoe1343992019-03-19 12:24:03 -0700475 self.assertEqual({
476 'apex.apexd_test.apex': (
477 'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
Dan Willemsen0ab1be62019-04-09 21:35:37 -0700478 'build/make/target/product/security/testkey'),
Tao Baoe1343992019-03-19 12:24:03 -0700479 'apex.apexd_test_different_app.apex': (
480 'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
Dan Willemsen0ab1be62019-04-09 21:35:37 -0700481 'build/make/target/product/security/testkey'),
Tao Baoe1343992019-03-19 12:24:03 -0700482 }, keys_info)
Tao Baoaa7e9932019-03-15 09:37:01 -0700483
Tao Bao6d9e3da2019-03-26 12:59:25 -0700484 def test_ReadApexKeysInfo_mismatchingContainerKeys(self):
Tao Baoaa7e9932019-03-15 09:37:01 -0700485 # Mismatching payload public / private keys.
486 apex_keys = self.APEX_KEYS_TXT + (
487 'name="apex.apexd_test_different_app2.apex" '
488 'public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.avbpubkey" '
Tao Bao6d9e3da2019-03-26 12:59:25 -0700489 'private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem" '
Dan Willemsen0ab1be62019-04-09 21:35:37 -0700490 'container_certificate="build/make/target/product/security/testkey.x509.pem" '
Bill Peckham19c3feb2020-03-20 18:31:43 -0700491 'container_private_key="build/make/target/product/security/testkey2.pk8" '
492 'partition="system"')
Tao Baoaa7e9932019-03-15 09:37:01 -0700493 target_files = common.MakeTempFile(suffix='.zip')
Kelvin Zhang928c2342020-09-22 16:15:57 -0400494 with zipfile.ZipFile(target_files, 'w', allowZip64=True) as target_files_zip:
Tao Baoaa7e9932019-03-15 09:37:01 -0700495 target_files_zip.writestr('META/apexkeys.txt', apex_keys)
496
Kelvin Zhang928c2342020-09-22 16:15:57 -0400497 with zipfile.ZipFile(target_files, allowZip64=True) as target_files_zip:
Tao Baoaa7e9932019-03-15 09:37:01 -0700498 self.assertRaises(ValueError, ReadApexKeysInfo, target_files_zip)
499
Tao Bao6d9e3da2019-03-26 12:59:25 -0700500 def test_ReadApexKeysInfo_missingPayloadPrivateKey(self):
Tao Baoaa7e9932019-03-15 09:37:01 -0700501 # Invalid lines will be skipped.
502 apex_keys = self.APEX_KEYS_TXT + (
503 'name="apex.apexd_test_different_app2.apex" '
504 'public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.avbpubkey" '
Dan Willemsen0ab1be62019-04-09 21:35:37 -0700505 'container_certificate="build/make/target/product/security/testkey.x509.pem" '
506 'container_private_key="build/make/target/product/security/testkey.pk8"')
Tao Baoaa7e9932019-03-15 09:37:01 -0700507 target_files = common.MakeTempFile(suffix='.zip')
Kelvin Zhang928c2342020-09-22 16:15:57 -0400508 with zipfile.ZipFile(target_files, 'w', allowZip64=True) as target_files_zip:
Tao Baoaa7e9932019-03-15 09:37:01 -0700509 target_files_zip.writestr('META/apexkeys.txt', apex_keys)
510
Kelvin Zhang928c2342020-09-22 16:15:57 -0400511 with zipfile.ZipFile(target_files, allowZip64=True) as target_files_zip:
Tao Baoaa7e9932019-03-15 09:37:01 -0700512 keys_info = ReadApexKeysInfo(target_files_zip)
513
Tao Baoe1343992019-03-19 12:24:03 -0700514 self.assertEqual({
515 'apex.apexd_test.apex': (
516 'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
Dan Willemsen0ab1be62019-04-09 21:35:37 -0700517 'build/make/target/product/security/testkey'),
Tao Baoe1343992019-03-19 12:24:03 -0700518 'apex.apexd_test_different_app.apex': (
519 'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
Dan Willemsen0ab1be62019-04-09 21:35:37 -0700520 'build/make/target/product/security/testkey'),
Tao Baoe1343992019-03-19 12:24:03 -0700521 }, keys_info)
Tao Bao6d9e3da2019-03-26 12:59:25 -0700522
523 def test_ReadApexKeysInfo_missingPayloadPublicKey(self):
524 # Invalid lines will be skipped.
525 apex_keys = self.APEX_KEYS_TXT + (
526 'name="apex.apexd_test_different_app2.apex" '
527 'private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem" '
Dan Willemsen0ab1be62019-04-09 21:35:37 -0700528 'container_certificate="build/make/target/product/security/testkey.x509.pem" '
529 'container_private_key="build/make/target/product/security/testkey.pk8"')
Tao Bao6d9e3da2019-03-26 12:59:25 -0700530 target_files = common.MakeTempFile(suffix='.zip')
Kelvin Zhang928c2342020-09-22 16:15:57 -0400531 with zipfile.ZipFile(target_files, 'w', allowZip64=True) as target_files_zip:
Tao Bao6d9e3da2019-03-26 12:59:25 -0700532 target_files_zip.writestr('META/apexkeys.txt', apex_keys)
533
Kelvin Zhang928c2342020-09-22 16:15:57 -0400534 with zipfile.ZipFile(target_files, allowZip64=True) as target_files_zip:
Tao Bao6d9e3da2019-03-26 12:59:25 -0700535 keys_info = ReadApexKeysInfo(target_files_zip)
536
537 self.assertEqual({
538 'apex.apexd_test.apex': (
539 'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
Dan Willemsen0ab1be62019-04-09 21:35:37 -0700540 'build/make/target/product/security/testkey'),
Tao Bao6d9e3da2019-03-26 12:59:25 -0700541 'apex.apexd_test_different_app.apex': (
542 'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
Dan Willemsen0ab1be62019-04-09 21:35:37 -0700543 'build/make/target/product/security/testkey'),
Tao Bao6d9e3da2019-03-26 12:59:25 -0700544 }, keys_info)
Tao Baof454c3a2019-04-24 23:53:42 -0700545
546 def test_ReadApexKeysInfo_presignedKeys(self):
547 apex_keys = self.APEX_KEYS_TXT + (
548 'name="apex.apexd_test_different_app2.apex" '
549 'private_key="PRESIGNED" '
550 'public_key="PRESIGNED" '
551 'container_certificate="PRESIGNED" '
552 'container_private_key="PRESIGNED"')
553 target_files = common.MakeTempFile(suffix='.zip')
Kelvin Zhang928c2342020-09-22 16:15:57 -0400554 with zipfile.ZipFile(target_files, 'w', allowZip64=True) as target_files_zip:
Tao Baof454c3a2019-04-24 23:53:42 -0700555 target_files_zip.writestr('META/apexkeys.txt', apex_keys)
556
Kelvin Zhang928c2342020-09-22 16:15:57 -0400557 with zipfile.ZipFile(target_files, allowZip64=True) as target_files_zip:
Tao Baof454c3a2019-04-24 23:53:42 -0700558 keys_info = ReadApexKeysInfo(target_files_zip)
559
560 self.assertEqual({
561 'apex.apexd_test.apex': (
562 'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
563 'build/make/target/product/security/testkey'),
564 'apex.apexd_test_different_app.apex': (
565 'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
566 'build/make/target/product/security/testkey'),
567 }, keys_info)
Tao Bao548db7d2019-04-24 23:53:42 -0700568
569 def test_ReadApexKeysInfo_presignedKeys(self):
570 apex_keys = self.APEX_KEYS_TXT + (
571 'name="apex.apexd_test_different_app2.apex" '
572 'private_key="PRESIGNED" '
573 'public_key="PRESIGNED" '
574 'container_certificate="PRESIGNED" '
575 'container_private_key="PRESIGNED"')
576 target_files = common.MakeTempFile(suffix='.zip')
Kelvin Zhang928c2342020-09-22 16:15:57 -0400577 with zipfile.ZipFile(target_files, 'w', allowZip64=True) as target_files_zip:
Tao Bao548db7d2019-04-24 23:53:42 -0700578 target_files_zip.writestr('META/apexkeys.txt', apex_keys)
579
Kelvin Zhang928c2342020-09-22 16:15:57 -0400580 with zipfile.ZipFile(target_files, allowZip64=True) as target_files_zip:
Tao Bao548db7d2019-04-24 23:53:42 -0700581 keys_info = ReadApexKeysInfo(target_files_zip)
582
583 self.assertEqual({
584 'apex.apexd_test.apex': (
585 'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
586 'build/make/target/product/security/testkey'),
587 'apex.apexd_test_different_app.apex': (
588 'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
589 'build/make/target/product/security/testkey'),
590 }, keys_info)