1 /* 2 * Copyright (C) 2020 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 17 package android.content.pm.cts; 18 19 import static android.Manifest.permission.INSTALL_PACKAGES; 20 import static android.Manifest.permission.USE_INSTALLER_V2; 21 import static android.Manifest.permission.USE_SYSTEM_DATA_LOADERS; 22 import static android.content.pm.Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256; 23 import static android.content.pm.Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512; 24 import static android.content.pm.Checksum.TYPE_WHOLE_MD5; 25 import static android.content.pm.Checksum.TYPE_WHOLE_MERKLE_ROOT_4K_SHA256; 26 import static android.content.pm.Checksum.TYPE_WHOLE_SHA1; 27 import static android.content.pm.Checksum.TYPE_WHOLE_SHA256; 28 import static android.content.pm.Checksum.TYPE_WHOLE_SHA512; 29 import static android.content.pm.PackageInstaller.LOCATION_DATA_APP; 30 import static android.content.pm.PackageManager.GET_SIGNING_CERTIFICATES; 31 import static android.content.pm.PackageManager.TRUST_ALL; 32 import static android.content.pm.PackageManager.TRUST_NONE; 33 34 import static com.google.common.truth.Truth.assertThat; 35 36 import static org.junit.Assert.assertNull; 37 import static org.junit.Assert.assertTrue; 38 import static org.junit.Assume.assumeTrue; 39 import static org.testng.Assert.assertEquals; 40 import static org.testng.Assert.assertNotNull; 41 import static org.testng.Assert.assertThrows; 42 43 import android.app.UiAutomation; 44 import android.content.ComponentName; 45 import android.content.Context; 46 import android.content.IIntentReceiver; 47 import android.content.IIntentSender; 48 import android.content.Intent; 49 import android.content.IntentSender; 50 import android.content.pm.ApkChecksum; 51 import android.content.pm.Checksum; 52 import android.content.pm.DataLoaderParams; 53 import android.content.pm.PackageInfo; 54 import android.content.pm.PackageInstaller; 55 import android.content.pm.PackageInstaller.Session; 56 import android.content.pm.PackageInstaller.SessionParams; 57 import android.content.pm.PackageManager; 58 import android.content.pm.Signature; 59 import android.content.pm.cts.util.AbandonAllPackageSessionsRule; 60 import android.os.Build; 61 import android.os.Bundle; 62 import android.os.Environment; 63 import android.os.IBinder; 64 import android.os.ParcelFileDescriptor; 65 import android.os.SystemProperties; 66 import android.platform.test.annotations.AppModeFull; 67 import android.platform.test.annotations.RequiresFlagsDisabled; 68 import android.platform.test.annotations.RequiresFlagsEnabled; 69 import android.platform.test.flag.junit.CheckFlagsRule; 70 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 71 import android.util.ExceptionUtils; 72 73 import androidx.annotation.NonNull; 74 import androidx.test.InstrumentationRegistry; 75 import androidx.test.filters.LargeTest; 76 import androidx.test.runner.AndroidJUnit4; 77 78 import com.android.compatibility.common.util.CpuFeatures; 79 import com.android.compatibility.common.util.FileUtils; 80 import com.android.compatibility.common.util.SystemUtil; 81 import com.android.internal.util.HexDump; 82 import com.android.server.pm.ApkChecksums; 83 import com.android.server.pm.PackageManagerShellCommandDataLoader; 84 import com.android.server.pm.PackageManagerShellCommandDataLoader.Metadata; 85 86 import org.junit.AfterClass; 87 import org.junit.Assert; 88 import org.junit.Rule; 89 import org.junit.Test; 90 import org.junit.runner.RunWith; 91 92 import java.io.ByteArrayInputStream; 93 import java.io.ByteArrayOutputStream; 94 import java.io.DataInputStream; 95 import java.io.DataOutputStream; 96 import java.io.EOFException; 97 import java.io.File; 98 import java.io.FileInputStream; 99 import java.io.FileOutputStream; 100 import java.io.IOException; 101 import java.io.InputStream; 102 import java.io.OutputStream; 103 import java.nio.file.Files; 104 import java.nio.file.Paths; 105 import java.security.SecureRandom; 106 import java.security.cert.Certificate; 107 import java.security.cert.CertificateException; 108 import java.security.cert.CertificateFactory; 109 import java.security.cert.X509Certificate; 110 import java.util.ArrayList; 111 import java.util.Arrays; 112 import java.util.List; 113 import java.util.Objects; 114 import java.util.concurrent.LinkedBlockingQueue; 115 import java.util.concurrent.TimeUnit; 116 117 import javax.annotation.Nonnull; 118 119 @RunWith(AndroidJUnit4.class) 120 @AppModeFull 121 public class ChecksumsTest { 122 private static final String CTS_PACKAGE_NAME = "android.content.cts"; 123 private static final String V2V3_PACKAGE_NAME = "android.content.cts"; 124 private static final String V4_PACKAGE_NAME = "com.example.helloworld"; 125 private static final String FIXED_PACKAGE_NAME = "android.appsecurity.cts.tinyapp"; 126 private static final String FIXED_FSVERITY_PACKAGE_NAME = 127 "android.appsecurity.cts.apkveritytestapp"; 128 129 private static final String TEST_APK_PATH = "/data/local/tmp/cts/content/"; 130 131 private static final String TEST_V4_APK = "HelloWorld5.apk"; 132 private static final String TEST_V4_SPLIT0 = "HelloWorld5_hdpi-v4.apk"; 133 private static final String TEST_V4_SPLIT1 = "HelloWorld5_mdpi-v4.apk"; 134 private static final String TEST_V4_SPLIT2 = "HelloWorld5_xhdpi-v4.apk"; 135 private static final String TEST_V4_SPLIT3 = "HelloWorld5_xxhdpi-v4.apk"; 136 private static final String TEST_V4_SPLIT4 = "HelloWorld5_xxxhdpi-v4.apk"; 137 138 private static final String TEST_FIXED_APK = "CtsPkgInstallTinyAppV2V3V4.apk"; 139 private static final String TEST_FIXED_APK_DIGESTS_FILE = 140 "CtsPkgInstallTinyAppV2V3V4.digests"; 141 private static final String TEST_FIXED_APK_DIGESTS_SIGNATURE = 142 "CtsPkgInstallTinyAppV2V3V4.digests.signature"; 143 private static final String TEST_CERTIFICATE = "test-cert.x509.pem"; 144 private static final String TEST_FIXED_APK_V1 = "CtsPkgInstallTinyAppV1.apk"; 145 private static final String TEST_FIXED_APK_SHA512 = 146 "CtsPkgInstallTinyAppV2V3V4-Sha512withEC.apk"; 147 private static final String TEST_FIXED_APK_VERITY = "CtsPkgInstallTinyAppV2V3V4-Verity.apk"; 148 149 private static final String TEST_FIXED_APK_FSVERITY = "CtsApkVerityTestAppPrebuilt.apk"; 150 private static final String TEST_FIXED_APK_FSVERITY_FSVSIG = 151 "CtsApkVerityTestAppPrebuilt.apk.fsv_sig"; 152 private static final String TEST_FIXED_APK_FSVERITY_SHA256_ARM64 = 153 "84c9974e74258a9c5abbc8a797358fe8ebf8918edf62383ea621e9e9e6461864"; 154 private static final String TEST_FIXED_APK_FSVERITY_SHA256_X86_64 = 155 "5073070ee9e9a7821b4044b457d95a2bb81f349ba32d31acd0952e4a2617075a"; 156 157 private static final String TEST_FIXED_APK_V2_SHA256 = 158 "1eec9e86e322b8d7e48e255fc3f2df2dbc91036e63982ff9850597c6a37bbeb3"; 159 private static final String TEST_FIXED_APK_SHA256 = 160 "91aa30c1ce8d0474052f71cb8210691d41f534989c5521e27e794ec4f754c5ef"; 161 private static final String TEST_FIXED_APK_MD5 = "c19868da017dc01467169f8ea7c5bc57"; 162 private static final Checksum[] TEST_FIXED_APK_DIGESTS = new Checksum[]{ 163 new Checksum(TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256, 164 hexStringToBytes(TEST_FIXED_APK_V2_SHA256)), 165 new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes(TEST_FIXED_APK_SHA256)), 166 new Checksum(TYPE_WHOLE_MD5, hexStringToBytes(TEST_FIXED_APK_MD5))}; 167 private static final Checksum[] TEST_FIXED_APK_WRONG_DIGESTS = new Checksum[]{ 168 new Checksum(TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256, hexStringToBytes("850597c6a37bbeb3")), 169 new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes(TEST_FIXED_APK_SHA256)), 170 new Checksum(TYPE_WHOLE_MD5, hexStringToBytes(TEST_FIXED_APK_MD5))}; 171 172 /** Default is to not use fs-verity since it depends on kernel support. */ 173 private static final int FSVERITY_DISABLED = 0; 174 175 /** Standard fs-verity. */ 176 private static final int FSVERITY_ENABLED = 2; 177 178 private static final byte[] NO_SIGNATURE = null; 179 180 private static final int ALL_CHECKSUMS = 181 TYPE_WHOLE_MERKLE_ROOT_4K_SHA256 | TYPE_WHOLE_MD5 | TYPE_WHOLE_SHA1 | TYPE_WHOLE_SHA256 182 | TYPE_WHOLE_SHA512 183 | TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256 | TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512; 184 getUiAutomation()185 private static UiAutomation getUiAutomation() { 186 return InstrumentationRegistry.getInstrumentation().getUiAutomation(); 187 } 188 getContext()189 private static Context getContext() { 190 return InstrumentationRegistry.getContext(); 191 } 192 getPackageManager()193 private static PackageManager getPackageManager() { 194 return getContext().getPackageManager(); 195 } 196 getPackageInstaller()197 private static PackageInstaller getPackageInstaller() { 198 return getPackageManager().getPackageInstaller(); 199 } 200 201 @Rule 202 public AbandonAllPackageSessionsRule mAbandonSessionsRule = new AbandonAllPackageSessionsRule(); 203 204 @Rule 205 public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); 206 207 @AfterClass onAfterClass()208 public static void onAfterClass() throws Exception { 209 uninstallPackageSilently(V4_PACKAGE_NAME); 210 uninstallPackageSilently(FIXED_PACKAGE_NAME); 211 uninstallPackageSilently(FIXED_FSVERITY_PACKAGE_NAME); 212 } 213 214 @Test testNameNotFound()215 public void testNameNotFound() throws Exception { 216 uninstallPackageSilently(V4_PACKAGE_NAME); 217 LocalListener receiver = new LocalListener(); 218 PackageManager pm = getPackageManager(); 219 assertThrows(PackageManager.NameNotFoundException.class, 220 () -> pm.requestChecksums(V4_PACKAGE_NAME, true, 0, TRUST_NONE, receiver)); 221 } 222 223 @Test testReadWriteChecksums()224 public void testReadWriteChecksums() throws Exception { 225 // Read checksums from file and confirm they are the same as hardcoded. 226 checkStoredChecksums(TEST_FIXED_APK_DIGESTS, TEST_FIXED_APK_DIGESTS_FILE); 227 228 // Write checksums and confirm that the file stays the same. 229 try (ByteArrayOutputStream os = new ByteArrayOutputStream(); 230 DataOutputStream dos = new DataOutputStream(os)) { 231 for (Checksum checksum : TEST_FIXED_APK_DIGESTS) { 232 Checksum.writeToStream(dos, checksum); 233 } 234 final byte[] fileBytes = Files.readAllBytes( 235 Paths.get(createApkPath(TEST_FIXED_APK_DIGESTS_FILE))); 236 final byte[] localBytes = os.toByteArray(); 237 Assert.assertArrayEquals(fileBytes, localBytes); 238 } 239 } 240 241 @Test testDefaultChecksums()242 public void testDefaultChecksums() throws Exception { 243 LocalListener receiver = new LocalListener(); 244 PackageManager pm = getPackageManager(); 245 pm.requestChecksums(V2V3_PACKAGE_NAME, true, 0, TRUST_NONE, receiver); 246 ApkChecksum[] checksums = receiver.getResult(); 247 assertNotNull(checksums); 248 assertEquals(checksums.length, 1, Arrays.toString(checksums)); 249 assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 250 } 251 252 @Test testSplitsDefaultChecksums()253 public void testSplitsDefaultChecksums() throws Exception { 254 uninstallPackageSilently(V4_PACKAGE_NAME); 255 installSplits(new String[]{TEST_V4_APK, TEST_V4_SPLIT0, TEST_V4_SPLIT1, TEST_V4_SPLIT2, 256 TEST_V4_SPLIT3, TEST_V4_SPLIT4}); 257 assertTrue(isAppInstalled(V4_PACKAGE_NAME)); 258 259 LocalListener receiver = new LocalListener(); 260 PackageManager pm = getPackageManager(); 261 pm.requestChecksums(V4_PACKAGE_NAME, true, 0, TRUST_NONE, receiver); 262 ApkChecksum[] checksums = receiver.getResult(); 263 assertNotNull(checksums); 264 assertEquals(checksums.length, 6, Arrays.toString(checksums)); 265 // v2/v3 signature use 1M merkle tree. 266 assertEquals(checksums[0].getSplitName(), null); 267 assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 268 assertEquals(checksums[1].getSplitName(), "config.hdpi"); 269 assertEquals(checksums[1].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 270 assertEquals(checksums[2].getSplitName(), "config.mdpi"); 271 assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 272 assertEquals(checksums[3].getSplitName(), "config.xhdpi"); 273 assertEquals(checksums[3].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 274 assertEquals(checksums[4].getSplitName(), "config.xxhdpi"); 275 assertEquals(checksums[4].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 276 assertEquals(checksums[5].getSplitName(), "config.xxxhdpi"); 277 assertEquals(checksums[5].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 278 } 279 280 @Test testFixedDefaultChecksums()281 public void testFixedDefaultChecksums() throws Exception { 282 uninstallPackageSilently(FIXED_PACKAGE_NAME); 283 installPackage(TEST_FIXED_APK); 284 assertTrue(isAppInstalled(FIXED_PACKAGE_NAME)); 285 286 LocalListener receiver = new LocalListener(); 287 PackageManager pm = getPackageManager(); 288 pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_NONE, receiver); 289 ApkChecksum[] checksums = receiver.getResult(); 290 assertNotNull(checksums); 291 assertEquals(checksums.length, 1, Arrays.toString(checksums)); 292 // v2/v3 signature use 1M merkle tree. 293 assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 294 assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_V2_SHA256); 295 assertNull(checksums[0].getInstallerCertificate()); 296 } 297 298 @Test testFixedV1DefaultChecksums()299 public void testFixedV1DefaultChecksums() throws Exception { 300 uninstallPackageSilently(FIXED_PACKAGE_NAME); 301 installPackage(TEST_FIXED_APK_V1); 302 assertTrue(isAppInstalled(FIXED_PACKAGE_NAME)); 303 304 LocalListener receiver = new LocalListener(); 305 PackageManager pm = getPackageManager(); 306 pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_NONE, receiver); 307 ApkChecksum[] checksums = receiver.getResult(); 308 assertNotNull(checksums); 309 assertEquals(checksums.length, 0, Arrays.toString(checksums)); 310 } 311 312 @Test testFixedSha512DefaultChecksums()313 public void testFixedSha512DefaultChecksums() throws Exception { 314 uninstallPackageSilently(FIXED_PACKAGE_NAME); 315 installPackage(TEST_FIXED_APK_SHA512); 316 assertTrue(isAppInstalled(FIXED_PACKAGE_NAME)); 317 318 LocalListener receiver = new LocalListener(); 319 PackageManager pm = getPackageManager(); 320 pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_NONE, receiver); 321 ApkChecksum[] checksums = receiver.getResult(); 322 assertNotNull(checksums); 323 assertEquals(checksums.length, 1, Arrays.toString(checksums)); 324 // v2/v3 signature use 1M merkle tree. 325 assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512); 326 assertEquals(bytesToHexString(checksums[0].getValue()), 327 "6b866e8a54a3e358dfc20007960fb96123845f6c6d6c45f5fddf88150d71677f" 328 + "4c3081a58921c88651f7376118aca312cf764b391cdfb8a18c6710f9f27916a0"); 329 assertNull(checksums[0].getInstallerCertificate()); 330 } 331 332 @LargeTest 333 @Test 334 @RequiresFlagsDisabled(android.security.Flags.FLAG_DEPRECATE_FSV_SIG) testFixedFSVerityDefaultChecksums()335 public void testFixedFSVerityDefaultChecksums() throws Exception { 336 assumeTrue(isApkVerityEnabled()); 337 uninstallPackageSilently(FIXED_FSVERITY_PACKAGE_NAME); 338 installApkWithFSVerity(TEST_FIXED_APK_FSVERITY, TEST_FIXED_APK_FSVERITY_FSVSIG); 339 assertTrue(isAppInstalled(FIXED_FSVERITY_PACKAGE_NAME)); 340 341 LocalListener receiver = new LocalListener(); 342 PackageManager pm = getPackageManager(); 343 pm.requestChecksums(FIXED_FSVERITY_PACKAGE_NAME, true, 0, TRUST_NONE, receiver); 344 ApkChecksum[] checksums = receiver.getResult(); 345 assertNotNull(checksums); 346 assertEquals(checksums.length, 2, Arrays.toString(checksums)); 347 assertEquals(checksums[0].getType(), TYPE_WHOLE_MERKLE_ROOT_4K_SHA256); 348 if (CpuFeatures.isArm64Cpu() || CpuFeatures.isArmCpu()) { 349 assertEquals(bytesToHexString(checksums[0].getValue()), 350 TEST_FIXED_APK_FSVERITY_SHA256_ARM64); 351 assertEquals(bytesToHexString(checksums[1].getValue()), 352 "8c61bc2548521aa0005276af68e42253957e1e24c122f7d8bf10f1832d4014e5"); 353 } else if (CpuFeatures.isX86_64Cpu() || CpuFeatures.isX86Cpu()) { 354 assertEquals(bytesToHexString(checksums[0].getValue()), 355 TEST_FIXED_APK_FSVERITY_SHA256_X86_64); 356 assertEquals(bytesToHexString(checksums[1].getValue()), 357 "6f7cfa569c4a25d7241e26c1c8ff274badbdefd7854d91b842b1a97a985d5917"); 358 } else { 359 Assert.fail("Unsupported CPU ABI"); 360 } 361 assertEquals(checksums[1].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 362 } 363 364 @LargeTest 365 @Test 366 @RequiresFlagsDisabled(android.security.Flags.FLAG_DEPRECATE_FSV_SIG) testFixedFSVerityDefaultChecksumsIncremental()367 public void testFixedFSVerityDefaultChecksumsIncremental() throws Exception { 368 assumeTrue(checkIncrementalDeliveryFeature()); 369 370 uninstallPackageSilently(FIXED_FSVERITY_PACKAGE_NAME); 371 installFilesIncrementally( 372 new String[]{TEST_FIXED_APK_FSVERITY, TEST_FIXED_APK_FSVERITY_FSVSIG}); 373 assertTrue(isAppInstalled(FIXED_FSVERITY_PACKAGE_NAME)); 374 375 LocalListener receiver = new LocalListener(); 376 PackageManager pm = getPackageManager(); 377 pm.requestChecksums(FIXED_FSVERITY_PACKAGE_NAME, true, 0, TRUST_NONE, receiver); 378 ApkChecksum[] checksums = receiver.getResult(); 379 assertNotNull(checksums); 380 assertEquals(checksums.length, 1, Arrays.toString(checksums)); 381 assertEquals(checksums[0].getType(), TYPE_WHOLE_MERKLE_ROOT_4K_SHA256); 382 if (CpuFeatures.isArm64Cpu() || CpuFeatures.isArmCpu()) { 383 assertEquals(bytesToHexString(checksums[0].getValue()), 384 TEST_FIXED_APK_FSVERITY_SHA256_ARM64); 385 } else if (CpuFeatures.isX86_64Cpu() || CpuFeatures.isX86Cpu()) { 386 assertEquals(bytesToHexString(checksums[0].getValue()), 387 TEST_FIXED_APK_FSVERITY_SHA256_X86_64); 388 } else { 389 Assert.fail("Unsupported CPU ABI"); 390 } 391 } 392 393 @Test testFixedVerityDefaultChecksums()394 public void testFixedVerityDefaultChecksums() throws Exception { 395 uninstallPackageSilently(FIXED_PACKAGE_NAME); 396 installPackage(TEST_FIXED_APK_VERITY); 397 assertTrue(isAppInstalled(FIXED_PACKAGE_NAME)); 398 399 LocalListener receiver = new LocalListener(); 400 PackageManager pm = getPackageManager(); 401 pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_NONE, receiver); 402 ApkChecksum[] checksums = receiver.getResult(); 403 assertNotNull(checksums); 404 // No usable hashes as verity-in-v2-signature does not cover the whole file. 405 assertEquals(checksums.length, 0, Arrays.toString(checksums)); 406 } 407 408 @Test 409 @RequiresFlagsEnabled(android.content.pm.Flags.FLAG_ARCHIVING) testArchivedDefaultChecksums()410 public void testArchivedDefaultChecksums() throws Exception { 411 uninstallPackageSilently(FIXED_PACKAGE_NAME); 412 installPackage(TEST_FIXED_APK); 413 assertTrue(isAppInstalled(FIXED_PACKAGE_NAME)); 414 415 byte[] archivedPackage = SystemUtil.runShellCommandByteOutput( 416 getUiAutomation(), 417 "pm get-archived-package-metadata " + FIXED_PACKAGE_NAME); 418 uninstallPackageSilently(FIXED_PACKAGE_NAME); 419 420 // Install as archived. 421 Assert.assertEquals("Success\n", executeShellCommand( 422 String.format("pm install-archived --bypass-low-target-sdk-block -r -i %s -t -S %s", 423 getContext().getPackageName(), archivedPackage.length), archivedPackage)); 424 assertTrue(isPackagePresent(FIXED_PACKAGE_NAME)); 425 426 LocalListener receiver = new LocalListener(); 427 PackageManager pm = getPackageManager(); 428 assertThrows(PackageManager.NameNotFoundException.class, () -> 429 pm.requestChecksums( 430 FIXED_PACKAGE_NAME, true, 0, TRUST_NONE, receiver)); 431 } 432 433 @LargeTest 434 @Test testFixedAllChecksums()435 public void testFixedAllChecksums() throws Exception { 436 uninstallPackageSilently(FIXED_PACKAGE_NAME); 437 installPackage(TEST_FIXED_APK); 438 assertTrue(isAppInstalled(FIXED_PACKAGE_NAME)); 439 440 LocalListener receiver = new LocalListener(); 441 PackageManager pm = getPackageManager(); 442 pm.requestChecksums(FIXED_PACKAGE_NAME, true, ALL_CHECKSUMS, TRUST_NONE, 443 receiver); 444 ApkChecksum[] checksums = receiver.getResult(); 445 assertNotNull(checksums); 446 assertEquals(checksums.length, 7, Arrays.toString(checksums)); 447 assertEquals(checksums[0].getType(), TYPE_WHOLE_MERKLE_ROOT_4K_SHA256); 448 assertEquals(bytesToHexString(checksums[0].getValue()), 449 "759626c33083fbf43215cb5b17156977d963d4c6850c0cb4e73162a665db560b"); 450 assertEquals(checksums[1].getType(), TYPE_WHOLE_MD5); 451 assertEquals(bytesToHexString(checksums[1].getValue()), TEST_FIXED_APK_MD5); 452 assertEquals(checksums[2].getType(), TYPE_WHOLE_SHA1); 453 assertEquals(bytesToHexString(checksums[2].getValue()), 454 "331eef6bc57671de28cbd7e32089d047285ade6a"); 455 assertEquals(checksums[3].getType(), TYPE_WHOLE_SHA256); 456 assertEquals(bytesToHexString(checksums[3].getValue()), TEST_FIXED_APK_SHA256); 457 assertEquals(checksums[4].getType(), TYPE_WHOLE_SHA512); 458 assertEquals(bytesToHexString(checksums[4].getValue()), 459 "b59467fe578ebc81974ab3aaa1e0d2a76fef3e4ea7212a6f2885cec1af5253571" 460 + "1e2e94496224cae3eba8dc992144ade321540ebd458ec5b9e6a4cc51170e018"); 461 assertEquals(checksums[5].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 462 assertEquals(bytesToHexString(checksums[5].getValue()), TEST_FIXED_APK_V2_SHA256); 463 assertEquals(checksums[6].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512); 464 assertEquals(bytesToHexString(checksums[6].getValue()), 465 "ef80a8630283f60108e8557c924307d0ccdfb6bbbf2c0176bd49af342f43bc84" 466 + "5f2888afcb71524196dda0d6dd16a6a3292bb75b431b8ff74fb60d796e882f80"); 467 } 468 469 @LargeTest 470 @Test testFixedV1AllChecksums()471 public void testFixedV1AllChecksums() throws Exception { 472 uninstallPackageSilently(FIXED_PACKAGE_NAME); 473 installPackage(TEST_FIXED_APK_V1); 474 assertTrue(isAppInstalled(FIXED_PACKAGE_NAME)); 475 476 LocalListener receiver = new LocalListener(); 477 PackageManager pm = getPackageManager(); 478 pm.requestChecksums(FIXED_PACKAGE_NAME, true, ALL_CHECKSUMS, TRUST_NONE, 479 receiver); 480 ApkChecksum[] checksums = receiver.getResult(); 481 assertNotNull(checksums); 482 assertEquals(checksums.length, 5, Arrays.toString(checksums)); 483 assertEquals(checksums[0].getType(), TYPE_WHOLE_MERKLE_ROOT_4K_SHA256); 484 assertEquals(bytesToHexString(checksums[0].getValue()), 485 "0b9bd6ef683e0c4e8940aba6460382b33e607c0fcf487f3dc6a44b715615d166"); 486 assertEquals(checksums[1].getType(), TYPE_WHOLE_MD5); 487 assertEquals(bytesToHexString(checksums[1].getValue()), "78e51e8c51e4adc6870cd71389e0f3db"); 488 assertEquals(checksums[2].getType(), TYPE_WHOLE_SHA1); 489 assertEquals(bytesToHexString(checksums[2].getValue()), 490 "f6654505f2274fd9bfc098b660cdfdc2e4da6d53"); 491 assertEquals(checksums[3].getType(), TYPE_WHOLE_SHA256); 492 assertEquals(bytesToHexString(checksums[3].getValue()), 493 "43755d36ec944494f6275ee92662aca95079b3aa6639f2d35208c5af15adff78"); 494 assertEquals(checksums[4].getType(), TYPE_WHOLE_SHA512); 495 assertEquals(bytesToHexString(checksums[4].getValue()), 496 "030fc815a4957c163af2bc6f30dd5b48ac09c94c25a824a514609e1476f91421" 497 + "e2c8b6baa16ef54014ad6c5b90c37b26b0f5c8aeb01b63a1db2eca133091c8d1"); 498 } 499 500 @Test testDefaultIncrementalChecksums()501 public void testDefaultIncrementalChecksums() throws Exception { 502 assumeTrue(checkIncrementalDeliveryFeature()); 503 uninstallPackageSilently(V4_PACKAGE_NAME); 504 505 installPackageIncrementally(TEST_V4_APK); 506 assertTrue(isAppInstalled(V4_PACKAGE_NAME)); 507 508 LocalListener receiver = new LocalListener(); 509 PackageManager pm = getPackageManager(); 510 pm.requestChecksums(V4_PACKAGE_NAME, true, 0, TRUST_NONE, receiver); 511 ApkChecksum[] checksums = receiver.getResult(); 512 assertNotNull(checksums); 513 assertEquals(checksums.length, 1, Arrays.toString(checksums)); 514 assertEquals(checksums[0].getType(), TYPE_WHOLE_MERKLE_ROOT_4K_SHA256); 515 } 516 517 @Test testFixedDefaultIncrementalChecksums()518 public void testFixedDefaultIncrementalChecksums() throws Exception { 519 assumeTrue(checkIncrementalDeliveryFeature()); 520 uninstallPackageSilently(FIXED_PACKAGE_NAME); 521 522 installPackageIncrementally(TEST_FIXED_APK); 523 assertTrue(isAppInstalled(FIXED_PACKAGE_NAME)); 524 525 LocalListener receiver = new LocalListener(); 526 PackageManager pm = getPackageManager(); 527 pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_NONE, receiver); 528 ApkChecksum[] checksums = receiver.getResult(); 529 assertNotNull(checksums); 530 assertEquals(checksums.length, 1, Arrays.toString(checksums)); 531 assertEquals(checksums[0].getType(), TYPE_WHOLE_MERKLE_ROOT_4K_SHA256); 532 assertEquals(bytesToHexString(checksums[0].getValue()), 533 "759626c33083fbf43215cb5b17156977d963d4c6850c0cb4e73162a665db560b"); 534 } 535 536 @LargeTest 537 @Test testFixedAllIncrementalChecksums()538 public void testFixedAllIncrementalChecksums() throws Exception { 539 assumeTrue(checkIncrementalDeliveryFeature()); 540 uninstallPackageSilently(FIXED_PACKAGE_NAME); 541 542 installPackageIncrementally(TEST_FIXED_APK); 543 assertTrue(isAppInstalled(FIXED_PACKAGE_NAME)); 544 545 LocalListener receiver = new LocalListener(); 546 PackageManager pm = getPackageManager(); 547 pm.requestChecksums(FIXED_PACKAGE_NAME, true, ALL_CHECKSUMS, TRUST_NONE, 548 receiver); 549 ApkChecksum[] checksums = receiver.getResult(); 550 assertNotNull(checksums); 551 assertEquals(checksums.length, 7, Arrays.toString(checksums)); 552 assertEquals(checksums[0].getType(), TYPE_WHOLE_MERKLE_ROOT_4K_SHA256); 553 assertEquals(bytesToHexString(checksums[0].getValue()), 554 "759626c33083fbf43215cb5b17156977d963d4c6850c0cb4e73162a665db560b"); 555 assertEquals(checksums[1].getType(), TYPE_WHOLE_MD5); 556 assertEquals(bytesToHexString(checksums[1].getValue()), TEST_FIXED_APK_MD5); 557 assertEquals(checksums[2].getType(), TYPE_WHOLE_SHA1); 558 assertEquals(bytesToHexString(checksums[2].getValue()), 559 "331eef6bc57671de28cbd7e32089d047285ade6a"); 560 assertEquals(checksums[3].getType(), TYPE_WHOLE_SHA256); 561 assertEquals(bytesToHexString(checksums[3].getValue()), TEST_FIXED_APK_SHA256); 562 assertEquals(checksums[4].getType(), TYPE_WHOLE_SHA512); 563 assertEquals(bytesToHexString(checksums[4].getValue()), 564 "b59467fe578ebc81974ab3aaa1e0d2a76fef3e4ea7212a6f2885cec1af5253571" 565 + "1e2e94496224cae3eba8dc992144ade321540ebd458ec5b9e6a4cc51170e018"); 566 assertEquals(checksums[5].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 567 assertEquals(bytesToHexString(checksums[5].getValue()), TEST_FIXED_APK_V2_SHA256); 568 assertEquals(checksums[6].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512); 569 assertEquals(bytesToHexString(checksums[6].getValue()), 570 "ef80a8630283f60108e8557c924307d0ccdfb6bbbf2c0176bd49af342f43bc84" 571 + "5f2888afcb71524196dda0d6dd16a6a3292bb75b431b8ff74fb60d796e882f80"); 572 } 573 574 575 @Test testInstallerChecksumsTrustNone()576 public void testInstallerChecksumsTrustNone() throws Exception { 577 uninstallPackageSilently(FIXED_PACKAGE_NAME); 578 installApkWithChecksums(TEST_FIXED_APK_DIGESTS); 579 580 LocalListener receiver = new LocalListener(); 581 PackageManager pm = getPackageManager(); 582 pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_NONE, receiver); 583 ApkChecksum[] checksums = receiver.getResult(); 584 assertNotNull(checksums); 585 assertEquals(checksums.length, 1, Arrays.toString(checksums)); 586 assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 587 assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_V2_SHA256); 588 assertNull(checksums[0].getInstallerPackageName()); 589 assertNull(checksums[0].getInstallerCertificate()); 590 } 591 592 @Test testInstallerWrongChecksumsTrustAll()593 public void testInstallerWrongChecksumsTrustAll() throws Exception { 594 uninstallPackageSilently(FIXED_PACKAGE_NAME); 595 installApkWithChecksums(TEST_FIXED_APK_WRONG_DIGESTS); 596 597 LocalListener receiver = new LocalListener(); 598 PackageManager pm = getPackageManager(); 599 pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_ALL, receiver); 600 ApkChecksum[] checksums = receiver.getResult(); 601 assertNotNull(checksums); 602 assertEquals(checksums.length, 1, Arrays.toString(checksums)); 603 assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 604 assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_V2_SHA256); 605 assertNull(checksums[0].getInstallerPackageName()); 606 assertNull(checksums[0].getInstallerCertificate()); 607 } 608 609 @Test testInstallerSignedChecksumsInvalidSignature()610 public void testInstallerSignedChecksumsInvalidSignature() throws Exception { 611 uninstallPackageSilently(FIXED_PACKAGE_NAME); 612 adoptShellPermissionIdentity(); 613 try { 614 final PackageInstaller installer = getPackageInstaller(); 615 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 616 params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 617 params.installFlags |= PackageManager.INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK; 618 619 final int sessionId = installer.createSession(params); 620 Session session = installer.openSession(sessionId); 621 writeFileToSession(session, "file", TEST_FIXED_APK); 622 623 assertThrows(IllegalArgumentException.class, () -> session.setChecksums("file", 624 Arrays.asList(TEST_FIXED_APK_DIGESTS), hexStringToBytes("1eec9e86"))); 625 } finally { 626 dropShellPermissionIdentity(); 627 } 628 } 629 createRandomArray(int size)630 private static byte[] createRandomArray(int size) { 631 byte[] array = new byte[size]; 632 (new SecureRandom()).nextBytes(array); 633 return array; 634 } 635 636 @Test testInstallerSignedChecksumsSignatureTooBig()637 public void testInstallerSignedChecksumsSignatureTooBig() throws Exception { 638 uninstallPackageSilently(FIXED_PACKAGE_NAME); 639 adoptShellPermissionIdentity(); 640 try { 641 final PackageInstaller installer = getPackageInstaller(); 642 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 643 params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 644 645 final int sessionId = installer.createSession(params); 646 Session session = installer.openSession(sessionId); 647 writeFileToSession(session, "file", TEST_FIXED_APK); 648 649 try { 650 session.setChecksums("file", 651 Arrays.asList(TEST_FIXED_APK_DIGESTS), createRandomArray(50000)); 652 Assert.fail("setChecksums should throw exception."); 653 } catch (IllegalArgumentException e) { 654 assertThat(e.getMessage()).contains("Invalid signature"); 655 } 656 } finally { 657 dropShellPermissionIdentity(); 658 } 659 } 660 661 @Test testInstallerSignedChecksumsInvalidChecksum()662 public void testInstallerSignedChecksumsInvalidChecksum() throws Exception { 663 final Checksum[] invalidChecksums = new Checksum[]{new Checksum( 664 TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256, hexStringToBytes( 665 "6b866e8a54a3e358dfc20007960fb96123845f6c6d6c45f5fddf8" 666 + "8150d71677f4c3081a58921c88651f7376118aca312cf764" 667 + "b391cdfb8a18c6710f9f27916a0a0"))}; 668 669 uninstallPackageSilently(FIXED_PACKAGE_NAME); 670 adoptShellPermissionIdentity(); 671 try { 672 final PackageInstaller installer = getPackageInstaller(); 673 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 674 params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 675 params.installFlags |= PackageManager.INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK; 676 677 final int sessionId = installer.createSession(params); 678 Session session = installer.openSession(sessionId); 679 writeFileToSession(session, "file", TEST_FIXED_APK); 680 assertThrows(IllegalArgumentException.class, () -> session.setChecksums("file", 681 Arrays.asList(invalidChecksums), NO_SIGNATURE)); 682 } finally { 683 dropShellPermissionIdentity(); 684 } 685 } 686 687 @Test testInstallerSignedChecksumsTrustNone()688 public void testInstallerSignedChecksumsTrustNone() throws Exception { 689 uninstallPackageSilently(FIXED_PACKAGE_NAME); 690 final byte[] signature = readSignature(); 691 692 CommitIntentReceiver.checkSuccess( 693 installApkWithChecksums(TEST_FIXED_APK, "file", "file", TEST_FIXED_APK_DIGESTS, 694 signature)); 695 696 LocalListener receiver = new LocalListener(); 697 PackageManager pm = getPackageManager(); 698 pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_NONE, receiver); 699 ApkChecksum[] checksums = receiver.getResult(); 700 assertNotNull(checksums); 701 assertEquals(checksums.length, 1, Arrays.toString(checksums)); 702 assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 703 assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_V2_SHA256); 704 assertNull(checksums[0].getInstallerPackageName()); 705 assertNull(checksums[0].getInstallerCertificate()); 706 } 707 708 @Test testInstallerSignedChecksumsTrustAll()709 public void testInstallerSignedChecksumsTrustAll() throws Exception { 710 uninstallPackageSilently(FIXED_PACKAGE_NAME); 711 final byte[] signature = readSignature(); 712 final Certificate certificate = readCertificate(); 713 714 CommitIntentReceiver.checkSuccess( 715 installApkWithChecksums(TEST_FIXED_APK, "file", "file", TEST_FIXED_APK_DIGESTS, 716 signature)); 717 718 LocalListener receiver = new LocalListener(); 719 PackageManager pm = getPackageManager(); 720 pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_ALL, receiver); 721 ApkChecksum[] checksums = receiver.getResult(); 722 assertNotNull(checksums); 723 // v2/v3+installer provided. 724 assertEquals(checksums.length, 3, Arrays.toString(checksums)); 725 726 assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5); 727 assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_MD5); 728 assertEquals(checksums[0].getSplitName(), null); 729 assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME); 730 assertEquals(checksums[0].getInstallerCertificate(), certificate); 731 assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256); 732 assertEquals(bytesToHexString(checksums[1].getValue()), TEST_FIXED_APK_SHA256); 733 assertEquals(checksums[1].getSplitName(), null); 734 assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME); 735 assertEquals(checksums[1].getInstallerCertificate(), certificate); 736 assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 737 assertEquals(bytesToHexString(checksums[2].getValue()), TEST_FIXED_APK_V2_SHA256); 738 assertEquals(checksums[2].getSplitName(), null); 739 assertNull(checksums[2].getInstallerPackageName()); 740 assertNull(checksums[2].getInstallerCertificate()); 741 } 742 743 @Test testInstallerChecksumsTrustAll()744 public void testInstallerChecksumsTrustAll() throws Exception { 745 uninstallPackageSilently(FIXED_PACKAGE_NAME); 746 installApkWithChecksums(TEST_FIXED_APK_DIGESTS); 747 748 final Certificate installerCertificate = getInstallerCertificate(); 749 750 LocalListener receiver = new LocalListener(); 751 getPackageManager().requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_ALL, 752 receiver); 753 ApkChecksum[] checksums = receiver.getResult(); 754 assertNotNull(checksums); 755 // v2/v3+installer provided. 756 assertEquals(checksums.length, 3, Arrays.toString(checksums)); 757 758 assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5); 759 assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_MD5); 760 assertEquals(checksums[0].getSplitName(), null); 761 assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME); 762 assertEquals(checksums[0].getInstallerCertificate(), installerCertificate); 763 assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256); 764 assertEquals(bytesToHexString(checksums[1].getValue()), TEST_FIXED_APK_SHA256); 765 assertEquals(checksums[1].getSplitName(), null); 766 assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME); 767 assertEquals(checksums[1].getInstallerCertificate(), installerCertificate); 768 assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 769 assertEquals(bytesToHexString(checksums[2].getValue()), TEST_FIXED_APK_V2_SHA256); 770 assertEquals(checksums[2].getSplitName(), null); 771 assertNull(checksums[2].getInstallerPackageName()); 772 assertNull(checksums[2].getInstallerCertificate()); 773 } 774 775 @Test testInstallerChecksumsTrustInstaller()776 public void testInstallerChecksumsTrustInstaller() throws Exception { 777 uninstallPackageSilently(FIXED_PACKAGE_NAME); 778 installApkWithChecksums(TEST_FIXED_APK_DIGESTS); 779 780 // Using the installer's certificate(s). 781 PackageManager pm = getPackageManager(); 782 PackageInfo packageInfo = pm.getPackageInfo(CTS_PACKAGE_NAME, 783 PackageManager.PackageInfoFlags.of(GET_SIGNING_CERTIFICATES)); 784 final List<Certificate> signatures = convertSignaturesToCertificates( 785 packageInfo.signingInfo.getApkContentsSigners()); 786 787 LocalListener receiver = new LocalListener(); 788 pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, signatures, receiver); 789 ApkChecksum[] checksums = receiver.getResult(); 790 assertNotNull(checksums); 791 assertEquals(checksums.length, 3, Arrays.toString(checksums)); 792 assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5); 793 assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_MD5); 794 assertEquals(checksums[0].getSplitName(), null); 795 assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME); 796 assertEquals(checksums[0].getInstallerCertificate(), signatures.get(0)); 797 assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256); 798 assertEquals(bytesToHexString(checksums[1].getValue()), TEST_FIXED_APK_SHA256); 799 assertEquals(checksums[1].getSplitName(), null); 800 assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME); 801 assertEquals(checksums[1].getInstallerCertificate(), signatures.get(0)); 802 assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 803 assertEquals(bytesToHexString(checksums[2].getValue()), TEST_FIXED_APK_V2_SHA256); 804 assertEquals(checksums[2].getSplitName(), null); 805 assertNull(checksums[2].getInstallerPackageName()); 806 assertNull(checksums[2].getInstallerCertificate()); 807 } 808 809 @LargeTest 810 @Test testInstallerFileChecksumsDuringInstall()811 public void testInstallerFileChecksumsDuringInstall() throws Exception { 812 uninstallPackageSilently(V4_PACKAGE_NAME); 813 Checksum[] digestsBase = new Checksum[]{new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes( 814 "ed8c7ae1220fe16d558e00cfc37256e6f7088ab90eb04c1bfcb39922a8a5248e")), 815 new Checksum(TYPE_WHOLE_MD5, hexStringToBytes("dd93e23bb8cdab0382fdca0d21a4f1cb"))}; 816 Checksum[] digestsSplit0 = new Checksum[]{new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes( 817 "bd9b095a49a9068498b018ce8cb7cc18d411b13a5a5f7fb417d2ff9808ae838e")), 818 new Checksum(TYPE_WHOLE_MD5, hexStringToBytes("f6430e1b795ce2658c49e68d15316b2d"))}; 819 820 final Certificate installerCertificate = getInstallerCertificate(); 821 822 adoptShellPermissionIdentity(); 823 PackageInstaller installer = null; 824 int sessionId = -1; 825 try { 826 installer = getPackageInstaller(); 827 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 828 params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 829 830 sessionId = installer.createSession(params); 831 final Session session = installer.openSession(sessionId); 832 833 writeFileToSession(session, "hw5.apk", TEST_V4_APK); 834 session.setChecksums("hw5.apk", Arrays.asList(digestsBase), NO_SIGNATURE); 835 836 writeFileToSession(session, "hw5_split0.apk", TEST_V4_SPLIT0); 837 session.setChecksums("hw5_split0.apk", Arrays.asList(digestsSplit0), NO_SIGNATURE); 838 839 // Workaround to emulate .digests file present in installation. 840 writeChecksumsToSession(session, "hw5.digests", digestsBase); 841 writeChecksumsToSession(session, "hw5_split0.digests", digestsSplit0); 842 843 File dataApp = Environment.getDataAppDirectory(null); 844 845 { 846 LocalListener receiver = new LocalListener(); 847 848 session.requestChecksums("hw5.apk", 0, TRUST_ALL, getContext().getMainExecutor(), 849 receiver); 850 ApkChecksum[] checksums = receiver.getResult(); 851 assertNotNull(checksums); 852 assertEquals(checksums.length, 3, Arrays.toString(checksums)); 853 // base 854 assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5); 855 assertEquals(checksums[0].getSplitName(), null); 856 assertEquals(bytesToHexString(checksums[0].getValue()), 857 "dd93e23bb8cdab0382fdca0d21a4f1cb"); 858 assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME); 859 assertEquals(checksums[0].getInstallerCertificate(), installerCertificate); 860 assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256); 861 assertEquals(checksums[1].getSplitName(), null); 862 assertEquals(bytesToHexString(checksums[1].getValue()), 863 "ed8c7ae1220fe16d558e00cfc37256e6f7088ab90eb04c1bfcb39922a8a5248e"); 864 assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME); 865 assertEquals(checksums[1].getInstallerCertificate(), installerCertificate); 866 assertEquals(checksums[2].getSplitName(), null); 867 assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 868 assertNull(checksums[2].getInstallerPackageName()); 869 assertNull(checksums[2].getInstallerCertificate()); 870 } 871 { 872 LocalListener receiver = new LocalListener(); 873 874 session.requestChecksums("hw5_split0.apk", 0, TRUST_ALL, 875 getContext().getMainExecutor(), receiver); 876 ApkChecksum[] checksums = receiver.getResult(); 877 assertNotNull(checksums); 878 assertEquals(checksums.length, 3, Arrays.toString(checksums)); 879 // split0 880 assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5); 881 assertEquals(checksums[0].getSplitName(), null); 882 assertEquals(bytesToHexString(checksums[0].getValue()), 883 "f6430e1b795ce2658c49e68d15316b2d"); 884 assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME); 885 assertEquals(checksums[0].getInstallerCertificate(), installerCertificate); 886 assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256); 887 assertEquals(checksums[1].getSplitName(), null); 888 assertEquals(bytesToHexString(checksums[1].getValue()), 889 "bd9b095a49a9068498b018ce8cb7cc18d411b13a5a5f7fb417d2ff9808ae838e"); 890 assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME); 891 assertEquals(checksums[1].getInstallerCertificate(), installerCertificate); 892 assertEquals(checksums[2].getSplitName(), null); 893 assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 894 assertNull(checksums[2].getInstallerPackageName()); 895 assertNull(checksums[2].getInstallerCertificate()); 896 } 897 } finally { 898 installer.abandonSession(sessionId); 899 dropShellPermissionIdentity(); 900 } 901 } 902 903 @Test testInstallerChecksumsTrustWrongInstaller()904 public void testInstallerChecksumsTrustWrongInstaller() throws Exception { 905 uninstallPackageSilently(FIXED_PACKAGE_NAME); 906 installApkWithChecksums(TEST_FIXED_APK_DIGESTS); 907 908 // Using certificates from a security app, not the installer (us). 909 PackageManager pm = getPackageManager(); 910 PackageInfo packageInfo = pm.getPackageInfo(FIXED_PACKAGE_NAME, 911 PackageManager.PackageInfoFlags.of(GET_SIGNING_CERTIFICATES)); 912 final List<Certificate> signatures = convertSignaturesToCertificates( 913 packageInfo.signingInfo.getApkContentsSigners()); 914 915 LocalListener receiver = new LocalListener(); 916 pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, signatures, receiver); 917 ApkChecksum[] checksums = receiver.getResult(); 918 assertNotNull(checksums); 919 assertEquals(checksums.length, 1, Arrays.toString(checksums)); 920 assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 921 assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_V2_SHA256); 922 assertNull(checksums[0].getInstallerPackageName()); 923 assertNull(checksums[0].getInstallerCertificate()); 924 } 925 926 @Test testInstallerChecksumsTrustAllWrongName()927 public void testInstallerChecksumsTrustAllWrongName() throws Exception { 928 uninstallPackageSilently(FIXED_PACKAGE_NAME); 929 // NB: "Invalid checksum name(s):" is used in Play to report checksum related failures. 930 // Please consult with them before changing. 931 CommitIntentReceiver.checkFailure( 932 installApkWithChecksums(TEST_FIXED_APK, "apk", "wrong_name", 933 TEST_FIXED_APK_DIGESTS), 934 "INSTALL_FAILED_SESSION_INVALID: Invalid checksum name(s): wrong_name"); 935 } 936 937 @Test testInstallerChecksumsUpdate()938 public void testInstallerChecksumsUpdate() throws Exception { 939 uninstallPackageSilently(V4_PACKAGE_NAME); 940 941 Checksum[] digestsBase = new Checksum[]{new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes( 942 "ed8c7ae1220fe16d558e00cfc37256e6f7088ab90eb04c1bfcb39922a8a5248e")), 943 new Checksum(TYPE_WHOLE_MD5, hexStringToBytes("dd93e23bb8cdab0382fdca0d21a4f1cb"))}; 944 Checksum[] digestsSplit0 = new Checksum[]{new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes( 945 "bd9b095a49a9068498b018ce8cb7cc18d411b13a5a5f7fb417d2ff9808ae838e")), 946 new Checksum(TYPE_WHOLE_MD5, hexStringToBytes("f6430e1b795ce2658c49e68d15316b2d"))}; 947 Checksum[] digestsSplit1 = new Checksum[]{new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes( 948 "f16898f43990c14585a900eda345c3a236c6224f63920d69cfe8a7afbc0c0ccf")), 949 new Checksum(TYPE_WHOLE_MD5, hexStringToBytes("d1f4b00d034994663e84f907fe4bb664"))}; 950 951 final Certificate installerCertificate = getInstallerCertificate(); 952 953 // Original package checksums: base + split0. 954 adoptShellPermissionIdentity(); 955 try { 956 final PackageInstaller installer = getPackageInstaller(); 957 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 958 959 final int sessionId = installer.createSession(params); 960 Session session = installer.openSession(sessionId); 961 962 writeFileToSession(session, "hw5", TEST_V4_APK); 963 session.setChecksums("hw5", Arrays.asList(digestsBase), NO_SIGNATURE); 964 965 writeFileToSession(session, "hw5_split0", TEST_V4_SPLIT0); 966 session.setChecksums("hw5_split0", Arrays.asList(digestsSplit0), NO_SIGNATURE); 967 968 CommitIntentReceiver receiver = new CommitIntentReceiver(); 969 session.commit(receiver.getIntentSender()); 970 CommitIntentReceiver.checkSuccess(receiver.getResult()); 971 } finally { 972 dropShellPermissionIdentity(); 973 } 974 975 { 976 LocalListener receiver = new LocalListener(); 977 PackageManager pm = getPackageManager(); 978 pm.requestChecksums(V4_PACKAGE_NAME, true, 0, TRUST_ALL, receiver); 979 ApkChecksum[] checksums = receiver.getResult(); 980 assertNotNull(checksums); 981 assertEquals(checksums.length, 6, Arrays.toString(checksums)); 982 // base 983 assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5); 984 assertEquals(checksums[0].getSplitName(), null); 985 assertEquals(bytesToHexString(checksums[0].getValue()), 986 "dd93e23bb8cdab0382fdca0d21a4f1cb"); 987 assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME); 988 assertEquals(checksums[0].getInstallerCertificate(), installerCertificate); 989 assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256); 990 assertEquals(checksums[1].getSplitName(), null); 991 assertEquals(bytesToHexString(checksums[1].getValue()), 992 "ed8c7ae1220fe16d558e00cfc37256e6f7088ab90eb04c1bfcb39922a8a5248e"); 993 assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME); 994 assertEquals(checksums[1].getInstallerCertificate(), installerCertificate); 995 assertEquals(checksums[2].getSplitName(), null); 996 assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 997 assertNull(checksums[2].getInstallerPackageName()); 998 assertNull(checksums[2].getInstallerCertificate()); 999 // split0 1000 assertEquals(checksums[3].getType(), TYPE_WHOLE_MD5); 1001 assertEquals(checksums[3].getSplitName(), "config.hdpi"); 1002 assertEquals(bytesToHexString(checksums[3].getValue()), 1003 "f6430e1b795ce2658c49e68d15316b2d"); 1004 assertEquals(checksums[3].getInstallerPackageName(), CTS_PACKAGE_NAME); 1005 assertEquals(checksums[3].getInstallerCertificate(), installerCertificate); 1006 assertEquals(checksums[4].getType(), TYPE_WHOLE_SHA256); 1007 assertEquals(checksums[4].getSplitName(), "config.hdpi"); 1008 assertEquals(bytesToHexString(checksums[4].getValue()), 1009 "bd9b095a49a9068498b018ce8cb7cc18d411b13a5a5f7fb417d2ff9808ae838e"); 1010 assertEquals(checksums[4].getInstallerPackageName(), CTS_PACKAGE_NAME); 1011 assertEquals(checksums[4].getInstallerCertificate(), installerCertificate); 1012 assertEquals(checksums[5].getSplitName(), "config.hdpi"); 1013 assertEquals(checksums[5].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 1014 assertNull(checksums[5].getInstallerPackageName()); 1015 assertNull(checksums[5].getInstallerCertificate()); 1016 } 1017 1018 // Update the package with one split+checksums and another split without checksums. 1019 adoptShellPermissionIdentity(); 1020 try { 1021 final PackageInstaller installer = getPackageInstaller(); 1022 final SessionParams params = new SessionParams(SessionParams.MODE_INHERIT_EXISTING); 1023 params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 1024 params.setAppPackageName(V4_PACKAGE_NAME); 1025 1026 final int sessionId = installer.createSession(params); 1027 Session session = installer.openSession(sessionId); 1028 1029 writeFileToSession(session, "hw5_split1", TEST_V4_SPLIT1); 1030 session.setChecksums("hw5_split1", Arrays.asList(digestsSplit1), NO_SIGNATURE); 1031 1032 writeFileToSession(session, "hw5_split2", TEST_V4_SPLIT2); 1033 1034 CommitIntentReceiver receiver = new CommitIntentReceiver(); 1035 session.commit(receiver.getIntentSender()); 1036 CommitIntentReceiver.checkSuccess(receiver.getResult()); 1037 } finally { 1038 dropShellPermissionIdentity(); 1039 } 1040 1041 { 1042 LocalListener receiver = new LocalListener(); 1043 PackageManager pm = getPackageManager(); 1044 pm.requestChecksums(V4_PACKAGE_NAME, true, 0, TRUST_ALL, receiver); 1045 ApkChecksum[] checksums = receiver.getResult(); 1046 assertNotNull(checksums); 1047 assertEquals(checksums.length, 10, Arrays.toString(checksums)); 1048 // base 1049 assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5); 1050 assertEquals(checksums[0].getSplitName(), null); 1051 assertEquals(bytesToHexString(checksums[0].getValue()), 1052 "dd93e23bb8cdab0382fdca0d21a4f1cb"); 1053 assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME); 1054 assertEquals(checksums[0].getInstallerCertificate(), installerCertificate); 1055 assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256); 1056 assertEquals(checksums[1].getSplitName(), null); 1057 assertEquals(bytesToHexString(checksums[1].getValue()), 1058 "ed8c7ae1220fe16d558e00cfc37256e6f7088ab90eb04c1bfcb39922a8a5248e"); 1059 assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME); 1060 assertEquals(checksums[1].getInstallerCertificate(), installerCertificate); 1061 assertEquals(checksums[2].getSplitName(), null); 1062 assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 1063 assertNull(checksums[2].getInstallerPackageName()); 1064 assertNull(checksums[2].getInstallerCertificate()); 1065 // split0 1066 assertEquals(checksums[3].getType(), TYPE_WHOLE_MD5); 1067 assertEquals(checksums[3].getSplitName(), "config.hdpi"); 1068 assertEquals(bytesToHexString(checksums[3].getValue()), 1069 "f6430e1b795ce2658c49e68d15316b2d"); 1070 assertEquals(checksums[3].getInstallerPackageName(), CTS_PACKAGE_NAME); 1071 assertEquals(checksums[3].getInstallerCertificate(), installerCertificate); 1072 assertEquals(checksums[4].getType(), TYPE_WHOLE_SHA256); 1073 assertEquals(checksums[4].getSplitName(), "config.hdpi"); 1074 assertEquals(bytesToHexString(checksums[4].getValue()), 1075 "bd9b095a49a9068498b018ce8cb7cc18d411b13a5a5f7fb417d2ff9808ae838e"); 1076 assertEquals(checksums[4].getInstallerPackageName(), CTS_PACKAGE_NAME); 1077 assertEquals(checksums[4].getInstallerCertificate(), installerCertificate); 1078 assertEquals(checksums[5].getSplitName(), "config.hdpi"); 1079 assertEquals(checksums[5].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 1080 assertNull(checksums[5].getInstallerPackageName()); 1081 assertNull(checksums[5].getInstallerCertificate()); 1082 // split1 1083 assertEquals(checksums[6].getType(), TYPE_WHOLE_MD5); 1084 assertEquals(checksums[6].getSplitName(), "config.mdpi"); 1085 assertEquals(bytesToHexString(checksums[6].getValue()), 1086 "d1f4b00d034994663e84f907fe4bb664"); 1087 assertEquals(checksums[6].getInstallerPackageName(), CTS_PACKAGE_NAME); 1088 assertEquals(checksums[6].getInstallerCertificate(), installerCertificate); 1089 assertEquals(checksums[7].getType(), TYPE_WHOLE_SHA256); 1090 assertEquals(checksums[7].getSplitName(), "config.mdpi"); 1091 assertEquals(bytesToHexString(checksums[7].getValue()), 1092 "f16898f43990c14585a900eda345c3a236c6224f63920d69cfe8a7afbc0c0ccf"); 1093 assertEquals(checksums[7].getInstallerPackageName(), CTS_PACKAGE_NAME); 1094 assertEquals(checksums[7].getInstallerCertificate(), installerCertificate); 1095 assertEquals(checksums[8].getSplitName(), "config.mdpi"); 1096 assertEquals(checksums[8].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 1097 assertNull(checksums[8].getInstallerPackageName()); 1098 assertNull(checksums[8].getInstallerCertificate()); 1099 // split2 1100 assertEquals(checksums[9].getSplitName(), "config.xhdpi"); 1101 assertEquals(checksums[9].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 1102 assertNull(checksums[9].getInstallerPackageName()); 1103 assertNull(checksums[9].getInstallerCertificate()); 1104 } 1105 } 1106 1107 @Test testInstallerSignedChecksumsUpdate()1108 public void testInstallerSignedChecksumsUpdate() throws Exception { 1109 uninstallPackageSilently(V4_PACKAGE_NAME); 1110 Checksum[] digestsBase = new Checksum[]{new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes( 1111 "ed8c7ae1220fe16d558e00cfc37256e6f7088ab90eb04c1bfcb39922a8a5248e")), 1112 new Checksum(TYPE_WHOLE_MD5, hexStringToBytes("dd93e23bb8cdab0382fdca0d21a4f1cb"))}; 1113 Checksum[] digestsSplit0 = new Checksum[]{new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes( 1114 "bd9b095a49a9068498b018ce8cb7cc18d411b13a5a5f7fb417d2ff9808ae838e")), 1115 new Checksum(TYPE_WHOLE_MD5, hexStringToBytes("f6430e1b795ce2658c49e68d15316b2d"))}; 1116 Checksum[] digestsSplit1 = new Checksum[]{new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes( 1117 "f16898f43990c14585a900eda345c3a236c6224f63920d69cfe8a7afbc0c0ccf")), 1118 new Checksum(TYPE_WHOLE_MD5, hexStringToBytes("d1f4b00d034994663e84f907fe4bb664"))}; 1119 1120 String digestBaseFile = ApkChecksums.buildDigestsPathForApk(TEST_V4_APK); 1121 String digestSplit0File = ApkChecksums.buildDigestsPathForApk(TEST_V4_SPLIT0); 1122 String digestSplit1File = ApkChecksums.buildDigestsPathForApk(TEST_V4_SPLIT1); 1123 1124 checkStoredChecksums(digestsBase, digestBaseFile); 1125 checkStoredChecksums(digestsSplit0, digestSplit0File); 1126 checkStoredChecksums(digestsSplit1, digestSplit1File); 1127 1128 byte[] digestBaseSignature = readSignature( 1129 ApkChecksums.buildSignaturePathForDigests(digestBaseFile)); 1130 byte[] digestSplit0Signature = readSignature( 1131 ApkChecksums.buildSignaturePathForDigests(digestSplit0File)); 1132 byte[] digestSplit1Signature = readSignature( 1133 ApkChecksums.buildSignaturePathForDigests(digestSplit1File)); 1134 1135 final Certificate certificate = readCertificate(); 1136 1137 // Original package checksums: base + split0. 1138 adoptShellPermissionIdentity(); 1139 try { 1140 final PackageInstaller installer = getPackageInstaller(); 1141 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 1142 1143 final int sessionId = installer.createSession(params); 1144 Session session = installer.openSession(sessionId); 1145 1146 writeFileToSession(session, "hw5", TEST_V4_APK); 1147 session.setChecksums("hw5", Arrays.asList(digestsBase), digestBaseSignature); 1148 1149 writeFileToSession(session, "hw5_split0", TEST_V4_SPLIT0); 1150 session.setChecksums("hw5_split0", Arrays.asList(digestsSplit0), digestSplit0Signature); 1151 1152 CommitIntentReceiver receiver = new CommitIntentReceiver(); 1153 session.commit(receiver.getIntentSender()); 1154 CommitIntentReceiver.checkSuccess(receiver.getResult()); 1155 } finally { 1156 dropShellPermissionIdentity(); 1157 } 1158 1159 { 1160 LocalListener receiver = new LocalListener(); 1161 PackageManager pm = getPackageManager(); 1162 pm.requestChecksums(V4_PACKAGE_NAME, true, 0, TRUST_ALL, receiver); 1163 ApkChecksum[] checksums = receiver.getResult(); 1164 assertNotNull(checksums); 1165 assertEquals(checksums.length, 6, Arrays.toString(checksums)); 1166 // base 1167 assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5); 1168 assertEquals(checksums[0].getSplitName(), null); 1169 assertEquals(bytesToHexString(checksums[0].getValue()), 1170 "dd93e23bb8cdab0382fdca0d21a4f1cb"); 1171 assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME); 1172 assertEquals(checksums[0].getInstallerCertificate(), certificate); 1173 assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256); 1174 assertEquals(checksums[1].getSplitName(), null); 1175 assertEquals(bytesToHexString(checksums[1].getValue()), 1176 "ed8c7ae1220fe16d558e00cfc37256e6f7088ab90eb04c1bfcb39922a8a5248e"); 1177 assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME); 1178 assertEquals(checksums[1].getInstallerCertificate(), certificate); 1179 assertEquals(checksums[2].getSplitName(), null); 1180 assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 1181 assertNull(checksums[2].getInstallerPackageName()); 1182 assertNull(checksums[2].getInstallerCertificate()); 1183 // split0 1184 assertEquals(checksums[3].getType(), TYPE_WHOLE_MD5); 1185 assertEquals(checksums[3].getSplitName(), "config.hdpi"); 1186 assertEquals(bytesToHexString(checksums[3].getValue()), 1187 "f6430e1b795ce2658c49e68d15316b2d"); 1188 assertEquals(checksums[3].getInstallerPackageName(), CTS_PACKAGE_NAME); 1189 assertEquals(checksums[3].getInstallerCertificate(), certificate); 1190 assertEquals(checksums[4].getType(), TYPE_WHOLE_SHA256); 1191 assertEquals(checksums[4].getSplitName(), "config.hdpi"); 1192 assertEquals(bytesToHexString(checksums[4].getValue()), 1193 "bd9b095a49a9068498b018ce8cb7cc18d411b13a5a5f7fb417d2ff9808ae838e"); 1194 assertEquals(checksums[4].getInstallerPackageName(), CTS_PACKAGE_NAME); 1195 assertEquals(checksums[4].getInstallerCertificate(), certificate); 1196 assertEquals(checksums[5].getSplitName(), "config.hdpi"); 1197 assertEquals(checksums[5].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 1198 assertNull(checksums[5].getInstallerPackageName()); 1199 assertNull(checksums[5].getInstallerCertificate()); 1200 } 1201 1202 // Update the package with one split+checksums and another split without checksums. 1203 adoptShellPermissionIdentity(); 1204 try { 1205 final PackageInstaller installer = getPackageInstaller(); 1206 final SessionParams params = new SessionParams(SessionParams.MODE_INHERIT_EXISTING); 1207 params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 1208 params.setAppPackageName(V4_PACKAGE_NAME); 1209 1210 final int sessionId = installer.createSession(params); 1211 Session session = installer.openSession(sessionId); 1212 1213 writeFileToSession(session, "hw5_split1", TEST_V4_SPLIT1); 1214 session.setChecksums("hw5_split1", Arrays.asList(digestsSplit1), digestSplit1Signature); 1215 1216 writeFileToSession(session, "hw5_split2", TEST_V4_SPLIT2); 1217 1218 CommitIntentReceiver receiver = new CommitIntentReceiver(); 1219 session.commit(receiver.getIntentSender()); 1220 CommitIntentReceiver.checkSuccess(receiver.getResult()); 1221 } finally { 1222 dropShellPermissionIdentity(); 1223 } 1224 1225 { 1226 LocalListener receiver = new LocalListener(); 1227 PackageManager pm = getPackageManager(); 1228 pm.requestChecksums(V4_PACKAGE_NAME, true, 0, TRUST_ALL, receiver); 1229 ApkChecksum[] checksums = receiver.getResult(); 1230 assertNotNull(checksums); 1231 assertEquals(checksums.length, 10, Arrays.toString(checksums)); 1232 // base 1233 assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5); 1234 assertEquals(checksums[0].getSplitName(), null); 1235 assertEquals(bytesToHexString(checksums[0].getValue()), 1236 "dd93e23bb8cdab0382fdca0d21a4f1cb"); 1237 assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME); 1238 assertEquals(checksums[0].getInstallerCertificate(), certificate); 1239 assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256); 1240 assertEquals(checksums[1].getSplitName(), null); 1241 assertEquals(bytesToHexString(checksums[1].getValue()), 1242 "ed8c7ae1220fe16d558e00cfc37256e6f7088ab90eb04c1bfcb39922a8a5248e"); 1243 assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME); 1244 assertEquals(checksums[1].getInstallerCertificate(), certificate); 1245 assertEquals(checksums[2].getSplitName(), null); 1246 assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 1247 assertNull(checksums[2].getInstallerPackageName()); 1248 assertNull(checksums[2].getInstallerCertificate()); 1249 // split0 1250 assertEquals(checksums[3].getType(), TYPE_WHOLE_MD5); 1251 assertEquals(checksums[3].getSplitName(), "config.hdpi"); 1252 assertEquals(bytesToHexString(checksums[3].getValue()), 1253 "f6430e1b795ce2658c49e68d15316b2d"); 1254 assertEquals(checksums[3].getInstallerPackageName(), CTS_PACKAGE_NAME); 1255 assertEquals(checksums[3].getInstallerCertificate(), certificate); 1256 assertEquals(checksums[4].getType(), TYPE_WHOLE_SHA256); 1257 assertEquals(checksums[4].getSplitName(), "config.hdpi"); 1258 assertEquals(bytesToHexString(checksums[4].getValue()), 1259 "bd9b095a49a9068498b018ce8cb7cc18d411b13a5a5f7fb417d2ff9808ae838e"); 1260 assertEquals(checksums[4].getInstallerPackageName(), CTS_PACKAGE_NAME); 1261 assertEquals(checksums[4].getInstallerCertificate(), certificate); 1262 assertEquals(checksums[5].getSplitName(), "config.hdpi"); 1263 assertEquals(checksums[5].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 1264 assertNull(checksums[5].getInstallerPackageName()); 1265 assertNull(checksums[5].getInstallerCertificate()); 1266 // split1 1267 assertEquals(checksums[6].getType(), TYPE_WHOLE_MD5); 1268 assertEquals(checksums[6].getSplitName(), "config.mdpi"); 1269 assertEquals(bytesToHexString(checksums[6].getValue()), 1270 "d1f4b00d034994663e84f907fe4bb664"); 1271 assertEquals(checksums[6].getInstallerPackageName(), CTS_PACKAGE_NAME); 1272 assertEquals(checksums[6].getInstallerCertificate(), certificate); 1273 assertEquals(checksums[7].getType(), TYPE_WHOLE_SHA256); 1274 assertEquals(checksums[7].getSplitName(), "config.mdpi"); 1275 assertEquals(bytesToHexString(checksums[7].getValue()), 1276 "f16898f43990c14585a900eda345c3a236c6224f63920d69cfe8a7afbc0c0ccf"); 1277 assertEquals(checksums[7].getInstallerPackageName(), CTS_PACKAGE_NAME); 1278 assertEquals(checksums[7].getInstallerCertificate(), certificate); 1279 assertEquals(checksums[8].getSplitName(), "config.mdpi"); 1280 assertEquals(checksums[8].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 1281 assertNull(checksums[8].getInstallerPackageName()); 1282 assertNull(checksums[8].getInstallerCertificate()); 1283 // split2 1284 assertEquals(checksums[9].getSplitName(), "config.xhdpi"); 1285 assertEquals(checksums[9].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 1286 assertNull(checksums[9].getInstallerPackageName()); 1287 assertNull(checksums[9].getInstallerCertificate()); 1288 } 1289 } 1290 1291 @Test testInstallerChecksumsIncremental()1292 public void testInstallerChecksumsIncremental() throws Exception { 1293 assumeTrue(checkIncrementalDeliveryFeature()); 1294 1295 final Certificate installerCertificate = getInstallerCertificate(); 1296 1297 uninstallPackageSilently(FIXED_PACKAGE_NAME); 1298 installPackageIncrementally(TEST_FIXED_APK); 1299 1300 PackageManager pm = getPackageManager(); 1301 PackageInfo packageInfo = pm.getPackageInfo(FIXED_PACKAGE_NAME, 1302 PackageManager.PackageInfoFlags.of(0)); 1303 final String inPath = packageInfo.applicationInfo.getBaseCodePath(); 1304 1305 installApkWithChecksumsIncrementally(inPath); 1306 assertTrue(isAppInstalled(FIXED_PACKAGE_NAME)); 1307 1308 LocalListener receiver = new LocalListener(); 1309 pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_ALL, 1310 receiver); 1311 ApkChecksum[] checksums = receiver.getResult(); 1312 assertNotNull(checksums); 1313 assertEquals(checksums.length, 3, Arrays.toString(checksums)); 1314 assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5); 1315 assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_MD5); 1316 assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME); 1317 assertEquals(checksums[0].getInstallerCertificate(), installerCertificate); 1318 assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256); 1319 assertEquals(bytesToHexString(checksums[1].getValue()), TEST_FIXED_APK_SHA256); 1320 assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME); 1321 assertEquals(checksums[1].getInstallerCertificate(), installerCertificate); 1322 assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 1323 assertEquals(bytesToHexString(checksums[2].getValue()), TEST_FIXED_APK_V2_SHA256); 1324 assertNull(checksums[2].getInstallerPackageName()); 1325 assertNull(checksums[2].getInstallerCertificate()); 1326 } 1327 1328 @Test testInstallerSignedChecksumsIncremental()1329 public void testInstallerSignedChecksumsIncremental() throws Exception { 1330 assumeTrue(checkIncrementalDeliveryFeature()); 1331 1332 uninstallPackageSilently(FIXED_PACKAGE_NAME); 1333 installPackageIncrementally(TEST_FIXED_APK); 1334 1335 PackageInfo packageInfo = getPackageManager().getPackageInfo(FIXED_PACKAGE_NAME, 1336 PackageManager.PackageInfoFlags.of(0)); 1337 final String inPath = packageInfo.applicationInfo.getBaseCodePath(); 1338 1339 final byte[] signature = readSignature(); 1340 final Certificate certificate = readCertificate(); 1341 1342 installApkWithChecksumsIncrementally(inPath, TEST_FIXED_APK, TEST_FIXED_APK_DIGESTS, 1343 signature); 1344 assertTrue(isAppInstalled(FIXED_PACKAGE_NAME)); 1345 1346 LocalListener receiver = new LocalListener(); 1347 PackageManager pm = getPackageManager(); 1348 pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_ALL, 1349 receiver); 1350 ApkChecksum[] checksums = receiver.getResult(); 1351 assertNotNull(checksums); 1352 assertEquals(checksums.length, 3, Arrays.toString(checksums)); 1353 assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5); 1354 assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_MD5); 1355 assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME); 1356 assertEquals(checksums[0].getInstallerCertificate(), certificate); 1357 assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256); 1358 assertEquals(bytesToHexString(checksums[1].getValue()), TEST_FIXED_APK_SHA256); 1359 assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME); 1360 assertEquals(checksums[1].getInstallerCertificate(), certificate); 1361 assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 1362 assertEquals(bytesToHexString(checksums[2].getValue()), TEST_FIXED_APK_V2_SHA256); 1363 assertNull(checksums[2].getInstallerPackageName()); 1364 assertNull(checksums[2].getInstallerCertificate()); 1365 } 1366 1367 @Test testInstallerChecksumsIncrementalTrustNone()1368 public void testInstallerChecksumsIncrementalTrustNone() throws Exception { 1369 assumeTrue(checkIncrementalDeliveryFeature()); 1370 1371 uninstallPackageSilently(FIXED_PACKAGE_NAME); 1372 installPackageIncrementally(TEST_FIXED_APK); 1373 1374 PackageInfo packageInfo = getPackageManager().getPackageInfo(FIXED_PACKAGE_NAME, 1375 PackageManager.PackageInfoFlags.of(0)); 1376 final String inPath = packageInfo.applicationInfo.getBaseCodePath(); 1377 1378 installApkWithChecksumsIncrementally(inPath); 1379 assertTrue(isAppInstalled(FIXED_PACKAGE_NAME)); 1380 1381 LocalListener receiver = new LocalListener(); 1382 PackageManager pm = getPackageManager(); 1383 pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_NONE, 1384 receiver); 1385 ApkChecksum[] checksums = receiver.getResult(); 1386 assertNotNull(checksums); 1387 assertEquals(checksums.length, 1, Arrays.toString(checksums)); 1388 assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256); 1389 assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_V2_SHA256); 1390 assertNull(checksums[0].getInstallerPackageName()); 1391 assertNull(checksums[0].getInstallerCertificate()); 1392 } 1393 1394 @Test testInstallerChecksumsDuplicate()1395 public void testInstallerChecksumsDuplicate() throws Exception { 1396 uninstallPackageSilently(FIXED_PACKAGE_NAME); 1397 adoptShellPermissionIdentity(); 1398 try { 1399 final PackageInstaller installer = getPackageInstaller(); 1400 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 1401 1402 final int sessionId = installer.createSession(params); 1403 Session session = installer.openSession(sessionId); 1404 writeFileToSession(session, "file", TEST_FIXED_APK); 1405 session.setChecksums("file", Arrays.asList(TEST_FIXED_APK_DIGESTS), NO_SIGNATURE); 1406 try { 1407 session.setChecksums("file", Arrays.asList(TEST_FIXED_APK_DIGESTS), NO_SIGNATURE); 1408 Assert.fail("setChecksums should throw exception."); 1409 } catch (IllegalStateException e) { 1410 // expected 1411 } 1412 } finally { 1413 dropShellPermissionIdentity(); 1414 } 1415 } 1416 convertSignaturesToCertificates(Signature[] signatures)1417 private List<Certificate> convertSignaturesToCertificates(Signature[] signatures) { 1418 try { 1419 final CertificateFactory cf = CertificateFactory.getInstance("X.509"); 1420 ArrayList<Certificate> certs = new ArrayList<>(signatures.length); 1421 for (Signature signature : signatures) { 1422 final InputStream is = new ByteArrayInputStream(signature.toByteArray()); 1423 final X509Certificate cert = (X509Certificate) cf.generateCertificate(is); 1424 certs.add(cert); 1425 } 1426 return certs; 1427 } catch (CertificateException e) { 1428 throw ExceptionUtils.propagate(e); 1429 } 1430 } 1431 installApkWithChecksums(Checksum[] checksums)1432 private void installApkWithChecksums(Checksum[] checksums) throws Exception { 1433 installApkWithChecksums("file", "file", checksums); 1434 } 1435 installApkWithChecksums(String apkName, String checksumsName, Checksum[] checksums)1436 private void installApkWithChecksums(String apkName, String checksumsName, Checksum[] checksums) 1437 throws Exception { 1438 CommitIntentReceiver.checkSuccess( 1439 installApkWithChecksums(TEST_FIXED_APK, apkName, checksumsName, checksums)); 1440 } 1441 installApkWithChecksums(String apk, String apkName, String checksumsName, Checksum[] checksums)1442 private Intent installApkWithChecksums(String apk, String apkName, 1443 String checksumsName, Checksum[] checksums) throws Exception { 1444 return installApkWithChecksums(apk, apkName, checksumsName, checksums, NO_SIGNATURE); 1445 } 1446 installApkWithChecksums(String apk, String apkName, String checksumsName, Checksum[] checksums, byte[] signature)1447 private Intent installApkWithChecksums(String apk, String apkName, 1448 String checksumsName, Checksum[] checksums, byte[] signature) throws Exception { 1449 adoptShellPermissionIdentity(); 1450 try { 1451 final PackageInstaller installer = getPackageInstaller(); 1452 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 1453 params.installFlags |= PackageManager.INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK; 1454 1455 final int sessionId = installer.createSession(params); 1456 Session session = installer.openSession(sessionId); 1457 writeFileToSession(session, apkName, apk); 1458 session.setChecksums(checksumsName, Arrays.asList(checksums), signature); 1459 1460 CommitIntentReceiver receiver = new CommitIntentReceiver(); 1461 session.commit(receiver.getIntentSender()); 1462 return receiver.getResult(); 1463 } finally { 1464 dropShellPermissionIdentity(); 1465 } 1466 } 1467 installApkWithFSVerity(String apk, String fsv)1468 private void installApkWithFSVerity(String apk, String fsv) throws Exception { 1469 adoptShellPermissionIdentity(); 1470 try { 1471 final PackageInstaller installer = getPackageInstaller(); 1472 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 1473 params.installFlags |= PackageManager.INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK; 1474 1475 final int sessionId = installer.createSession(params); 1476 Session session = installer.openSession(sessionId); 1477 writeFileToSession(session, "file", apk); 1478 writeFileToSession(session, "file.fsv_sig", fsv); 1479 1480 CommitIntentReceiver receiver = new CommitIntentReceiver(); 1481 session.commit(receiver.getIntentSender()); 1482 CommitIntentReceiver.checkSuccess(receiver.getResult()); 1483 } finally { 1484 dropShellPermissionIdentity(); 1485 } 1486 } 1487 installApkWithChecksumsIncrementally(final String inPath)1488 private void installApkWithChecksumsIncrementally(final String inPath) throws Exception { 1489 installApkWithChecksumsIncrementally(inPath, TEST_FIXED_APK, TEST_FIXED_APK_DIGESTS, 1490 NO_SIGNATURE); 1491 } 1492 installApkWithChecksumsIncrementally(final String inPath, final String apk, final Checksum[] checksums, final byte[] signature)1493 private void installApkWithChecksumsIncrementally(final String inPath, final String apk, 1494 final Checksum[] checksums, final byte[] signature) throws Exception { 1495 adoptShellPermissionIdentity(); 1496 try { 1497 final PackageInstaller installer = getPackageInstaller(); 1498 final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL); 1499 params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 1500 params.installFlags |= PackageManager.INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK; 1501 params.setDataLoaderParams(DataLoaderParams.forIncremental(new ComponentName("android", 1502 PackageManagerShellCommandDataLoader.class.getName()), "")); 1503 1504 final int sessionId = installer.createSession(params); 1505 Session session = installer.openSession(sessionId); 1506 1507 final File file = new File(inPath); 1508 final String name = file.getName(); 1509 final long size = file.length(); 1510 final Metadata metadata = Metadata.forLocalFile(inPath); 1511 1512 session.addFile(LOCATION_DATA_APP, name, size, metadata.toByteArray(), null); 1513 session.setChecksums(name, Arrays.asList(checksums), signature); 1514 1515 CommitIntentReceiver receiver = new CommitIntentReceiver(); 1516 session.commit(receiver.getIntentSender()); 1517 CommitIntentReceiver.checkSuccess(receiver.getResult()); 1518 } finally { 1519 dropShellPermissionIdentity(); 1520 } 1521 } 1522 readFullStream(InputStream inputStream)1523 private static String readFullStream(InputStream inputStream) throws IOException { 1524 ByteArrayOutputStream result = new ByteArrayOutputStream(); 1525 writeFullStream(inputStream, result, -1); 1526 return result.toString("UTF-8"); 1527 } 1528 writeFullStream(InputStream inputStream, OutputStream outputStream, long expected)1529 private static void writeFullStream(InputStream inputStream, OutputStream outputStream, 1530 long expected) 1531 throws IOException { 1532 byte[] buffer = new byte[1024]; 1533 long total = 0; 1534 int length; 1535 while ((length = inputStream.read(buffer)) != -1) { 1536 outputStream.write(buffer, 0, length); 1537 total += length; 1538 } 1539 if (expected > 0) { 1540 Assert.assertEquals(expected, total); 1541 } 1542 } 1543 executeShellCommand(String command)1544 private static String executeShellCommand(String command) throws IOException { 1545 final ParcelFileDescriptor stdout = getUiAutomation().executeShellCommand(command); 1546 try (InputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(stdout)) { 1547 return readFullStream(inputStream); 1548 } 1549 } 1550 executeShellCommand(String command, byte[] input)1551 private String executeShellCommand(String command, byte[] input) throws IOException { 1552 final ParcelFileDescriptor[] pfds = 1553 getUiAutomation().executeShellCommandRw(command); 1554 ParcelFileDescriptor stdout = pfds[0]; 1555 ParcelFileDescriptor stdin = pfds[1]; 1556 try (FileOutputStream outputStream = new ParcelFileDescriptor.AutoCloseOutputStream( 1557 stdin)) { 1558 outputStream.write(input); 1559 } 1560 try (InputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(stdout)) { 1561 return new String(FileUtils.readInputStreamFully(inputStream)); 1562 } 1563 } 1564 createApkPath(String baseName)1565 private static String createApkPath(String baseName) { 1566 return TEST_APK_PATH + baseName; 1567 } 1568 installPackage(String baseName)1569 private void installPackage(String baseName) throws IOException { 1570 File file = new File(createApkPath(baseName)); 1571 Assert.assertEquals("Success\n", executeShellCommand( 1572 "pm install -t -g --bypass-low-target-sdk-block " + file.getPath())); 1573 } 1574 installPackageIncrementally(String baseName)1575 private void installPackageIncrementally(String baseName) throws IOException { 1576 File file = new File(createApkPath(baseName)); 1577 Assert.assertEquals("Success\n", executeShellCommand( 1578 "pm install-incremental -t -g --bypass-low-target-sdk-block " + file.getPath())); 1579 } 1580 installSplits(String[] baseNames)1581 private void installSplits(String[] baseNames) throws IOException { 1582 String[] splits = Arrays.stream(baseNames).map( 1583 baseName -> createApkPath(baseName)).toArray(String[]::new); 1584 Assert.assertEquals("Success\n", 1585 executeShellCommand( 1586 "pm install -t -g --bypass-low-target-sdk-block " + String.join(" ", 1587 splits))); 1588 } 1589 installFilesIncrementally(String[] baseNames)1590 private void installFilesIncrementally(String[] baseNames) throws IOException { 1591 String[] splits = Arrays.stream(baseNames).map( 1592 baseName -> createApkPath(baseName)).toArray(String[]::new); 1593 Assert.assertEquals("Success\n", 1594 executeShellCommand( 1595 "pm install-incremental -t -g --bypass-low-target-sdk-block " + String.join( 1596 " ", splits))); 1597 } 1598 writeFileToSession(PackageInstaller.Session session, String name, String apk)1599 private static void writeFileToSession(PackageInstaller.Session session, String name, 1600 String apk) throws IOException { 1601 File file = new File(createApkPath(apk)); 1602 try (OutputStream os = session.openWrite(name, 0, file.length()); 1603 InputStream is = new FileInputStream(file)) { 1604 writeFullStream(is, os, file.length()); 1605 } 1606 } 1607 writeChecksumsToSession(PackageInstaller.Session session, String name, Checksum[] checksums)1608 private static void writeChecksumsToSession(PackageInstaller.Session session, String name, 1609 Checksum[] checksums) throws IOException { 1610 try (DataOutputStream dos = new DataOutputStream(session.openWrite(name, 0, -1))) { 1611 for (Checksum checksum : checksums) { 1612 Checksum.writeToStream(dos, checksum); 1613 } 1614 } 1615 } 1616 uninstallPackageSilently(String packageName)1617 private static String uninstallPackageSilently(String packageName) throws IOException { 1618 return executeShellCommand("pm uninstall " + packageName); 1619 } 1620 isAppInstalled(String packageName)1621 private static boolean isAppInstalled(String packageName) throws IOException { 1622 return isPackagePresent(packageName, /*matchAllPackages=*/false); 1623 } 1624 isPackagePresent(String packageName)1625 private static boolean isPackagePresent(String packageName) throws IOException { 1626 return isPackagePresent(packageName, /*matchAllPackages=*/true); 1627 } 1628 isPackagePresent(String packageName, boolean matchAllPackages)1629 private static boolean isPackagePresent(String packageName, boolean matchAllPackages) 1630 throws IOException { 1631 final String commandResult = 1632 executeShellCommand("pm list packages" + (matchAllPackages ? " -a" : "")); 1633 final int prefixLength = "package:".length(); 1634 return Arrays.stream(commandResult.split("\\r?\\n")) 1635 .anyMatch(line -> line.substring(prefixLength).equals(packageName)); 1636 } 1637 getAppCodePath(String packageName)1638 private String getAppCodePath(String packageName) throws IOException { 1639 final String commandResult = executeShellCommand("pm dump " + packageName); 1640 final String prefix = " codePath="; 1641 final int prefixLength = prefix.length(); 1642 return Arrays.stream(commandResult.split("\\r?\\n")) 1643 .filter(line -> line.startsWith(prefix)) 1644 .map(line -> line.substring(prefixLength)) 1645 .findFirst().get(); 1646 } 1647 1648 @Nonnull bytesToHexString(byte[] bytes)1649 private static String bytesToHexString(byte[] bytes) { 1650 return HexDump.toHexString(bytes, 0, bytes.length, /*upperCase=*/ false); 1651 } 1652 1653 @Nonnull hexStringToBytes(String hexString)1654 private static byte[] hexStringToBytes(String hexString) { 1655 return HexDump.hexStringToByteArray(hexString); 1656 } 1657 checkIncrementalDeliveryFeature()1658 private boolean checkIncrementalDeliveryFeature() { 1659 return getPackageManager().hasSystemFeature(PackageManager.FEATURE_INCREMENTAL_DELIVERY); 1660 } 1661 1662 // From PackageManagerServiceUtils. isApkVerityEnabled()1663 private static boolean isApkVerityEnabled() { 1664 return Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.R 1665 || SystemProperties.getInt("ro.apk_verity.mode", FSVERITY_DISABLED) 1666 == FSVERITY_ENABLED; 1667 } 1668 readSignature()1669 private byte[] readSignature() throws IOException { 1670 return readSignature(TEST_FIXED_APK_DIGESTS_SIGNATURE); 1671 } 1672 readSignature(String file)1673 private byte[] readSignature(String file) throws IOException { 1674 return Files.readAllBytes(Paths.get(createApkPath(file))); 1675 } 1676 readCertificate()1677 private Certificate readCertificate() throws Exception { 1678 try (InputStream is = new FileInputStream(createApkPath(TEST_CERTIFICATE))) { 1679 CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); 1680 return certFactory.generateCertificate(is); 1681 } 1682 } 1683 getInstallerCertificate()1684 private Certificate getInstallerCertificate() throws Exception { 1685 PackageManager pm = getPackageManager(); 1686 PackageInfo installerPackageInfo = pm.getPackageInfo(CTS_PACKAGE_NAME, 1687 PackageManager.PackageInfoFlags.of(GET_SIGNING_CERTIFICATES)); 1688 final List<Certificate> signatures = convertSignaturesToCertificates( 1689 installerPackageInfo.signingInfo.getApkContentsSigners()); 1690 return signatures.get(0); 1691 } 1692 checkStoredChecksums(Checksum[] checksums, String fileName)1693 private void checkStoredChecksums(Checksum[] checksums, String fileName) throws Exception { 1694 ArrayList<Checksum> storedChecksumsList = new ArrayList<>(); 1695 try (InputStream is = new FileInputStream(createApkPath(fileName)); 1696 DataInputStream dis = new DataInputStream(is)) { 1697 for (int i = 0; i < 100; ++i) { 1698 try { 1699 storedChecksumsList.add(Checksum.readFromStream(dis)); 1700 } catch (EOFException e) { 1701 break; 1702 } 1703 } 1704 } 1705 final Checksum[] storedChecksums = storedChecksumsList.toArray( 1706 new Checksum[storedChecksumsList.size()]); 1707 1708 final String message = fileName + " needs to be updated: "; 1709 Assert.assertEquals(message, storedChecksums.length, checksums.length); 1710 for (int i = 0, size = storedChecksums.length; i < size; ++i) { 1711 Assert.assertEquals(message, storedChecksums[i].getType(), checksums[i].getType()); 1712 Assert.assertArrayEquals(message, storedChecksums[i].getValue(), 1713 checksums[i].getValue()); 1714 } 1715 } 1716 adoptShellPermissionIdentity()1717 private void adoptShellPermissionIdentity() { 1718 // For non-shell/non-root/non-system uids, USE_SYSTEM_DATA_LOADERS means 1719 // "install-related test adapted shell identity". 1720 getUiAutomation().adoptShellPermissionIdentity(INSTALL_PACKAGES, USE_SYSTEM_DATA_LOADERS, 1721 USE_INSTALLER_V2); 1722 } 1723 dropShellPermissionIdentity()1724 private void dropShellPermissionIdentity() { 1725 getUiAutomation().dropShellPermissionIdentity(); 1726 } 1727 1728 private static class LocalListener implements PackageManager.OnChecksumsReadyListener { 1729 private final LinkedBlockingQueue<ApkChecksum[]> mResult = new LinkedBlockingQueue<>(); 1730 1731 @Override onChecksumsReady(@onNull List<ApkChecksum> checksumsList)1732 public void onChecksumsReady(@NonNull List<ApkChecksum> checksumsList) { 1733 if (checksumsList == null) { 1734 mResult.offer(null); 1735 return; 1736 } 1737 ApkChecksum[] checksums = checksumsList.toArray(new ApkChecksum[checksumsList.size()]); 1738 Arrays.sort(checksums, (ApkChecksum lhs, ApkChecksum rhs) -> { 1739 final String lhsSplit = lhs.getSplitName(); 1740 final String rhsSplit = rhs.getSplitName(); 1741 if (Objects.equals(lhsSplit, rhsSplit)) { 1742 return Integer.signum(lhs.getType() - rhs.getType()); 1743 } 1744 if (lhsSplit == null) { 1745 return -1; 1746 } 1747 if (rhsSplit == null) { 1748 return +1; 1749 } 1750 return lhsSplit.compareTo(rhsSplit); 1751 }); 1752 mResult.offer(checksums); 1753 } 1754 getResult()1755 public ApkChecksum[] getResult() { 1756 try { 1757 return mResult.poll(6, TimeUnit.SECONDS); 1758 } catch (InterruptedException e) { 1759 throw new RuntimeException(e); 1760 } 1761 } 1762 } 1763 1764 private static class CommitIntentReceiver { 1765 private final LinkedBlockingQueue<Intent> mResult = new LinkedBlockingQueue<>(); 1766 1767 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() { 1768 @Override 1769 public void send(int code, Intent intent, String resolvedType, IBinder allowlistToken, 1770 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { 1771 try { 1772 mResult.offer(intent, 5, TimeUnit.SECONDS); 1773 } catch (InterruptedException e) { 1774 throw new RuntimeException(e); 1775 } 1776 } 1777 }; 1778 getIntentSender()1779 public IntentSender getIntentSender() { 1780 return new IntentSender((IIntentSender) mLocalSender); 1781 } 1782 getResult()1783 public Intent getResult() { 1784 try { 1785 return mResult.take(); 1786 } catch (InterruptedException e) { 1787 throw new RuntimeException(e); 1788 } 1789 } 1790 checkSuccess(Intent result)1791 public static void checkSuccess(Intent result) { 1792 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 1793 PackageInstaller.STATUS_FAILURE); 1794 assertEquals(status, PackageInstaller.STATUS_SUCCESS, 1795 result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + " OR " 1796 + result.getExtras().get(Intent.EXTRA_INTENT)); 1797 } 1798 checkFailure(Intent result, int expectedStatus, String expectedStatusMessage)1799 public static void checkFailure(Intent result, int expectedStatus, 1800 String expectedStatusMessage) { 1801 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 1802 PackageInstaller.STATUS_FAILURE); 1803 assertEquals(status, expectedStatus); 1804 assertEquals(result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE), 1805 expectedStatusMessage); 1806 } 1807 checkFailure(Intent result, String expectedStatusMessage)1808 public static void checkFailure(Intent result, String expectedStatusMessage) { 1809 checkFailure(result, PackageInstaller.STATUS_FAILURE, expectedStatusMessage); 1810 } 1811 } 1812 } 1813