1/* 2 * Copyright (C) 2015 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 17package com.android.server.pm; 18 19 20import android.content.pm.PackageParser; 21import android.content.pm.Signature; 22import android.util.ArrayMap; 23import android.util.ArraySet; 24import android.util.LongSparseArray; 25import com.android.internal.util.ArrayUtils; 26 27import java.io.File; 28import java.io.IOException; 29import java.security.cert.CertificateException; 30import java.security.PublicKey; 31 32import android.test.AndroidTestCase; 33 34public class KeySetManagerServiceTest extends AndroidTestCase { 35 36 private ArrayMap<String, PackageSetting> mPackagesMap; 37 private KeySetManagerService mKsms; 38 39 public PackageSetting generateFakePackageSetting(String name) { 40 return new PackageSetting(name, name, new File(mContext.getCacheDir(), "fakeCodePath"), 41 new File(mContext.getCacheDir(), "fakeResPath"), "", "", "", 42 "", 1, 0, 0, null, null, 0 /*sharedUserId*/, null /*usesStaticLibraries*/, 43 null /*usesStaticLibrariesVersions*/); 44 } 45 46 @Override 47 public void setUp() throws Exception { 48 super.setUp(); 49 mPackagesMap = new ArrayMap<String, PackageSetting>(); 50 mKsms = new KeySetManagerService(mPackagesMap); 51 } 52 53 public void testPackageKeySetDataConstructorUnassignend() { 54 PackageKeySetData pksd = new PackageKeySetData(); 55 assertEquals(PackageKeySetData.KEYSET_UNASSIGNED, pksd.getProperSigningKeySet()); 56 assertNull(pksd.getUpgradeKeySets()); 57 ArrayMap<String, Long> aliases = pksd.getAliases(); 58 assertNotNull(aliases); 59 assertEquals(0, aliases.size()); 60 } 61 62 /* test equivalence of PackageManager cert encoding and PackageParser manifest keys */ 63 public void testPublicKeyCertReprEquiv() throws CertificateException { 64 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 65 PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB); 66 PublicKey keyC = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyC); 67 68 Signature sigA = new Signature(KeySetStrings.ctsKeySetCertA); 69 Signature sigB = new Signature(KeySetStrings.ctsKeySetCertB); 70 Signature sigC = new Signature(KeySetStrings.ctsKeySetCertC); 71 72 assertNotNull(keyA); 73 assertNotNull(keyB); 74 assertNotNull(keyC); 75 76 assertEquals(keyA, sigA.getPublicKey()); 77 assertEquals(keyB, sigB.getPublicKey()); 78 assertEquals(keyC, sigC.getPublicKey()); 79 80 byte[] bArrayPk = keyA.getEncoded(); 81 byte[] bArrayCert = sigA.getPublicKey().getEncoded(); 82 assertEquals(bArrayPk.length, bArrayCert.length); 83 assertEquals(true, ArrayUtils.equals(bArrayPk, bArrayCert, bArrayPk.length)); 84 85 bArrayPk = keyB.getEncoded(); 86 bArrayCert = sigB.getPublicKey().getEncoded(); 87 assertEquals(bArrayPk.length, bArrayCert.length); 88 assertEquals(true, ArrayUtils.equals(bArrayPk, bArrayCert, bArrayPk.length)); 89 90 bArrayPk = keyC.getEncoded(); 91 bArrayCert = sigC.getPublicKey().getEncoded(); 92 assertEquals(bArrayPk.length, bArrayCert.length); 93 assertEquals(true, ArrayUtils.equals(bArrayPk, bArrayCert, bArrayPk.length)); 94 } 95 96 public void testEncodePublicKey() throws IOException { 97 ArrayMap<String, PackageSetting> packagesMap = new ArrayMap<String, PackageSetting>(); 98 KeySetManagerService ksms = new KeySetManagerService(packagesMap); 99 100 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 101 PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB); 102 PublicKey keyC = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyC); 103 104 assertEquals(ksms.encodePublicKey(keyA), KeySetStrings.ctsKeySetPublicKeyA); 105 assertEquals(ksms.encodePublicKey(keyB), KeySetStrings.ctsKeySetPublicKeyB); 106 assertEquals(ksms.encodePublicKey(keyC), KeySetStrings.ctsKeySetPublicKeyC); 107 } 108 109 /* 110 * Add the keyset information for a package to a system w/no previous keysets 111 */ 112 public void testAddSigningKSToPackageEmpty() throws ReflectiveOperationException { 113 114 /* create PackageSetting and add to Settings mPackages */ 115 PackageSetting ps = generateFakePackageSetting("packageA"); 116 mPackagesMap.put(ps.name, ps); 117 118 /* collect signing key and add */ 119 ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>(); 120 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 121 signingKeys.add(keyA); 122 mKsms.addSigningKeySetToPackageLPw(ps, signingKeys); 123 124 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1)); 125 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 126 assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1)); 127 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 128 assertEquals(1, ksMapping.size()); 129 ArraySet<Long> mapping = ksMapping.get(1); 130 assertEquals(1, mapping.size()); 131 assertTrue(mapping.contains(new Long(1))); 132 assertEquals(1, ps.keySetData.getProperSigningKeySet()); 133 } 134 135 /* 136 * upgrade an app (same packagename) with same keyset and verify that 137 * nothing changed. 138 */ 139 public void testAddSigningKSToPackageUpgradeSame() throws ReflectiveOperationException { 140 141 /* create PackageSetting and add to Settings mPackages */ 142 PackageSetting ps = generateFakePackageSetting("packageA"); 143 mPackagesMap.put(ps.name, ps); 144 145 /* collect signing key and add */ 146 ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>(); 147 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 148 signingKeys.add(keyA); 149 mKsms.addSigningKeySetToPackageLPw(ps, signingKeys); 150 151 /* add again, to represent upgrade of package */ 152 mKsms.addSigningKeySetToPackageLPw(ps, signingKeys); 153 154 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1)); 155 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 156 assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1)); 157 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 158 assertEquals(1, ksMapping.size()); 159 ArraySet<Long> mapping = ksMapping.get(1); 160 assertEquals(1, mapping.size()); 161 assertTrue(mapping.contains(new Long(1))); 162 assertEquals(1, ps.keySetData.getProperSigningKeySet()); 163 } 164 165 /* 166 * upgrade an app (same packagename) with different unique keyset and verify 167 * that the old was removed. 168 */ 169 public void testAddSigningKSToPackageUpgradeDiff() throws ReflectiveOperationException { 170 171 /* create PackageSetting and add to Settings mPackages */ 172 PackageSetting ps = generateFakePackageSetting("packageA"); 173 mPackagesMap.put(ps.name, ps); 174 175 /* collect signing key and add */ 176 ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>(); 177 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 178 signingKeys.add(keyA); 179 mKsms.addSigningKeySetToPackageLPw(ps, signingKeys); 180 181 /* now upgrade with new key */ 182 PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB); 183 signingKeys.removeAt(0); 184 signingKeys.add(keyB); 185 mKsms.addSigningKeySetToPackageLPw(ps, signingKeys); 186 187 assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1)); 188 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2)); 189 assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 190 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2)); 191 assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2)); 192 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 193 assertEquals(1, ksMapping.size()); 194 ArraySet<Long> mapping = ksMapping.get(2); 195 assertEquals(1, mapping.size()); 196 assertTrue(mapping.contains(new Long(2))); 197 assertEquals(2, ps.keySetData.getProperSigningKeySet()); 198 } 199 200 /* 201 * upgrade an app (same packagename) with different keyset and verify 202 * that the old had its ref count reduced due to reference by other ps. 203 */ 204 public void testAddSigningKSToPackageUpgradeDiff2() throws ReflectiveOperationException { 205 206 /* create PackageSetting and add to Settings mPackages */ 207 PackageSetting ps1 = generateFakePackageSetting("packageA"); 208 mPackagesMap.put(ps1.name, ps1); 209 PackageSetting ps2 = generateFakePackageSetting("packageB"); 210 mPackagesMap.put(ps2.name, ps2); 211 212 /* collect signing key and add */ 213 ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>(); 214 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 215 signingKeys.add(keyA); 216 mKsms.addSigningKeySetToPackageLPw(ps1, signingKeys); 217 mKsms.addSigningKeySetToPackageLPw(ps2, signingKeys); 218 219 /* now upgrade with new key */ 220 PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB); 221 signingKeys.removeAt(0); 222 signingKeys.add(keyB); 223 mKsms.addSigningKeySetToPackageLPw(ps1, signingKeys); 224 225 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1)); 226 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2)); 227 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 228 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2)); 229 assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1)); 230 assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2)); 231 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 232 assertEquals(2, ksMapping.size()); 233 ArraySet<Long> mapping = ksMapping.get(1); 234 assertEquals(1, mapping.size()); 235 assertTrue(mapping.contains(new Long(1))); 236 mapping = ksMapping.get(2); 237 assertEquals(1, mapping.size()); 238 assertTrue(mapping.contains(new Long(2))); 239 assertEquals(2, ps1.keySetData.getProperSigningKeySet()); 240 assertEquals(1, ps2.keySetData.getProperSigningKeySet()); 241 } 242 243 /* 244 * Add orthoganal keyset info to system and ensure previous keysets are 245 * unmodified. 246 */ 247 public void testAddSigningKSToPackageNewOrtho() throws ReflectiveOperationException { 248 249 /* create PackageSettings and add to Settings mPackages */ 250 PackageSetting ps1 = generateFakePackageSetting("packageA"); 251 mPackagesMap.put(ps1.name, ps1); 252 PackageSetting ps2 = generateFakePackageSetting("packageB"); 253 mPackagesMap.put(ps2.name, ps2); 254 255 /* collect signing key and add */ 256 ArraySet<PublicKey> signingKeys1 = new ArraySet<PublicKey>(); 257 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 258 signingKeys1.add(keyA); 259 mKsms.addSigningKeySetToPackageLPw(ps1, signingKeys1); 260 261 /* collect second signing key and add */ 262 ArraySet<PublicKey> signingKeys2 = new ArraySet<PublicKey>(); 263 PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB); 264 signingKeys2.add(keyB); 265 mKsms.addSigningKeySetToPackageLPw(ps2, signingKeys2); 266 267 /* verify first is unchanged */ 268 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1)); 269 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 270 assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1)); 271 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 272 assertEquals(2, ksMapping.size()); 273 ArraySet<Long> mapping = ksMapping.get(1); 274 assertEquals(1, mapping.size()); 275 assertTrue(mapping.contains(new Long(1))); 276 assertEquals(1, ps1.keySetData.getProperSigningKeySet()); 277 278 /* verify second */ 279 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2)); 280 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2)); 281 assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2)); 282 mapping = ksMapping.get(2); 283 assertEquals(1, mapping.size()); 284 assertTrue(mapping.contains(new Long(2))); 285 assertEquals(2, ps2.keySetData.getProperSigningKeySet()); 286 } 287 288 /* 289 * Add identical keyset info to system via new package and ensure previous 290 * keysets has reference count incremented 291 */ 292 public void testAddSigningKSToPackageNewSame() throws ReflectiveOperationException { 293 294 /* create PackageSettings and add to Settings mPackages */ 295 PackageSetting ps1 = generateFakePackageSetting("packageA"); 296 mPackagesMap.put(ps1.name, ps1); 297 PackageSetting ps2 = generateFakePackageSetting("packageB"); 298 mPackagesMap.put(ps2.name, ps2); 299 300 /* collect signing key and add */ 301 ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>(); 302 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 303 signingKeys.add(keyA); 304 mKsms.addSigningKeySetToPackageLPw(ps1, signingKeys); 305 306 /* add again for second package */ 307 mKsms.addSigningKeySetToPackageLPw(ps2, signingKeys); 308 309 assertEquals(2, KeySetUtils.getKeySetRefCount(mKsms, 1)); 310 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 311 assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1)); 312 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 313 assertEquals(1, ksMapping.size()); 314 ArraySet<Long> mapping = ksMapping.get(1); 315 assertEquals(1, mapping.size()); 316 assertTrue(mapping.contains(new Long(1))); 317 assertEquals(1, ps1.keySetData.getProperSigningKeySet()); 318 assertEquals(1, ps2.keySetData.getProperSigningKeySet()); 319 } 320 321 /* 322 * add a package which is signed by a keyset which contains a previously seen 323 * public key and make sure its refernces are incremented. 324 */ 325 public void testAddSigningKSToPackageSuper() throws ReflectiveOperationException { 326 327 /* create PackageSettings and add to Settings mPackages */ 328 PackageSetting ps1 = generateFakePackageSetting("packageA"); 329 mPackagesMap.put(ps1.name, ps1); 330 PackageSetting ps2 = generateFakePackageSetting("packageB"); 331 mPackagesMap.put(ps2.name, ps2); 332 333 /* collect signing key and add */ 334 ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>(); 335 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 336 signingKeys.add(keyA); 337 mKsms.addSigningKeySetToPackageLPw(ps1, signingKeys); 338 339 /* give ps2 a superset (add keyB) */ 340 PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB); 341 signingKeys.add(keyB); 342 mKsms.addSigningKeySetToPackageLPw(ps2, signingKeys); 343 344 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1)); 345 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2)); 346 assertEquals(2, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 347 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2)); 348 assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1)); 349 assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2)); 350 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 351 assertEquals(2, ksMapping.size()); 352 ArraySet<Long> mapping = ksMapping.get(1); 353 assertEquals(1, mapping.size()); 354 assertTrue(mapping.contains(new Long(1))); 355 mapping = ksMapping.get(2); 356 assertEquals(2, mapping.size()); 357 assertTrue(mapping.contains(new Long(1))); 358 assertTrue(mapping.contains(new Long(2))); 359 assertEquals(1, ps1.keySetData.getProperSigningKeySet()); 360 assertEquals(2, ps2.keySetData.getProperSigningKeySet()); 361 } 362 363 /* 364 * Upgrade an app (same pkgName) with different keyset which contains a public 365 * key from the previous keyset. Verify old keyset removed and pub key ref 366 * count is accurate. 367 */ 368 public void testAddSigningKSToPackageUpgradeDiffSuper() throws ReflectiveOperationException { 369 370 /* create PackageSetting and add to Settings mPackages */ 371 PackageSetting ps = generateFakePackageSetting("packageA"); 372 mPackagesMap.put(ps.name, ps); 373 374 /* collect signing key and add */ 375 ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>(); 376 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 377 signingKeys.add(keyA); 378 mKsms.addSigningKeySetToPackageLPw(ps, signingKeys); 379 380 /* now with additional key */ 381 PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB); 382 signingKeys.add(keyB); 383 mKsms.addSigningKeySetToPackageLPw(ps, signingKeys); 384 385 assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1)); 386 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2)); 387 assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 388 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2)); 389 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 3)); 390 391 /* the pub key is removed w/prev keyset and may be either 2 or 3 */ 392 assertTrue(keyA.equals(KeySetUtils.getPubKey(mKsms, 2)) || keyA.equals(KeySetUtils.getPubKey(mKsms, 3))); 393 assertTrue(keyB.equals(KeySetUtils.getPubKey(mKsms, 2)) || keyB.equals(KeySetUtils.getPubKey(mKsms, 3))); 394 assertFalse(KeySetUtils.getPubKey(mKsms, 2).equals(KeySetUtils.getPubKey(mKsms, 3))); 395 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 396 assertEquals(1, ksMapping.size()); 397 ArraySet<Long> mapping = ksMapping.get(2); 398 assertEquals(2, mapping.size()); 399 assertTrue(mapping.contains(new Long(2))); 400 assertTrue(mapping.contains(new Long(3))); 401 assertEquals(2, ps.keySetData.getProperSigningKeySet()); 402 } 403 404 /* add a defined keyset make sure it shows up */ 405 public void testAddDefinedKSToPackageEmpty() throws ReflectiveOperationException { 406 407 /* create PackageSetting and add to Settings mPackages */ 408 PackageSetting ps = generateFakePackageSetting("packageA"); 409 mPackagesMap.put(ps.name, ps); 410 411 /* collect key and add */ 412 ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>(); 413 ArraySet<PublicKey> keys = new ArraySet<PublicKey>(); 414 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 415 keys.add(keyA); 416 definedKS.put("aliasA", keys); 417 mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS); 418 419 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1)); 420 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 421 assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1)); 422 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 423 assertEquals(1, ksMapping.size()); 424 ArraySet<Long> mapping = ksMapping.get(1); 425 assertEquals(1, mapping.size()); 426 assertTrue(mapping.contains(new Long(1))); 427 assertNotNull(ps.keySetData.getAliases().get("aliasA")); 428 assertEquals(new Long(1), ps.keySetData.getAliases().get("aliasA")); 429 } 430 431 /* add 2 defined keysets which refer to same keyset and make sure ref-ct is 2 */ 432 public void testAddDefinedKSToPackageDoubleAlias() throws ReflectiveOperationException { 433 434 /* create PackageSetting and add to Settings mPackages */ 435 PackageSetting ps = generateFakePackageSetting("packageA"); 436 mPackagesMap.put(ps.name, ps); 437 438 /* collect key and add */ 439 ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>(); 440 ArraySet<PublicKey> keys = new ArraySet<PublicKey>(); 441 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 442 keys.add(keyA); 443 definedKS.put("aliasA", keys); 444 definedKS.put("aliasA2", keys); 445 mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS); 446 447 assertEquals(2, KeySetUtils.getKeySetRefCount(mKsms, 1)); 448 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 449 assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1)); 450 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 451 assertEquals(1, ksMapping.size()); 452 ArraySet<Long> mapping = ksMapping.get(1); 453 assertEquals(1, mapping.size()); 454 assertTrue(mapping.contains(new Long(1))); 455 assertNotNull(ps.keySetData.getAliases().get("aliasA")); 456 assertEquals(new Long(1), ps.keySetData.getAliases().get("aliasA")); 457 assertNotNull(ps.keySetData.getAliases().get("aliasA2")); 458 assertEquals(new Long(1), ps.keySetData.getAliases().get("aliasA2")); 459 } 460 461 /* upgrd defined keyset ortho (make sure previous is removed for pkg) */ 462 public void testAddDefinedKSToPackageOrthoUpgr() throws ReflectiveOperationException { 463 464 /* create PackageSetting and add to Settings mPackages */ 465 PackageSetting ps = generateFakePackageSetting("packageA"); 466 mPackagesMap.put(ps.name, ps); 467 468 /* collect key and add */ 469 ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>(); 470 ArraySet<PublicKey> keys = new ArraySet<PublicKey>(); 471 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 472 keys.add(keyA); 473 definedKS.put("aliasA", keys); 474 mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS); 475 476 /* now upgrade to different defined key-set */ 477 keys = new ArraySet<PublicKey>(); 478 PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB); 479 keys.add(keyB); 480 definedKS.remove("aliasA"); 481 definedKS.put("aliasB", keys); 482 mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS); 483 484 assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1)); 485 assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 486 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2)); 487 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2)); 488 assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2)); 489 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 490 assertEquals(1, ksMapping.size()); 491 ArraySet<Long> mapping = ksMapping.get(2); 492 assertEquals(1, mapping.size()); 493 assertTrue(mapping.contains(new Long(2))); 494 assertNull(ps.keySetData.getAliases().get("aliasA")); 495 assertNotNull(ps.keySetData.getAliases().get("aliasB")); 496 assertEquals(new Long(2), ps.keySetData.getAliases().get("aliasB")); 497 } 498 499 /* upgrd defined keyset ortho but reuse alias (make sure old is removed and 500 * alias points to new keyset) 501 */ 502 public void testAddDefinedKSToPackageOrthoUpgrAliasSame() throws ReflectiveOperationException { 503 504 /* create PackageSetting and add to Settings mPackages */ 505 PackageSetting ps = generateFakePackageSetting("packageA"); 506 mPackagesMap.put(ps.name, ps); 507 508 /* collect key and add */ 509 ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>(); 510 ArraySet<PublicKey> keys = new ArraySet<PublicKey>(); 511 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 512 keys.add(keyA); 513 definedKS.put("aliasA", keys); 514 mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS); 515 516 /* now upgrade to different set w/same alias as before */ 517 keys = new ArraySet<PublicKey>(); 518 PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB); 519 keys.add(keyB); 520 definedKS.put("aliasA", keys); 521 mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS); 522 523 assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1)); 524 assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 525 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2)); 526 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2)); 527 assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2)); 528 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 529 assertEquals(1, ksMapping.size()); 530 ArraySet<Long> mapping = ksMapping.get(2); 531 assertEquals(1, mapping.size()); 532 assertTrue(mapping.contains(new Long(2))); 533 assertNotNull(ps.keySetData.getAliases().get("aliasA")); 534 assertEquals(new Long(2), ps.keySetData.getAliases().get("aliasA")); 535 } 536 537 /* Start with defined ks of (A, B) and upgrade to (B, C). Make sure B is 538 * unchanged. */ 539 public void testAddDefinedKSToPackageOverlapUpgr() throws ReflectiveOperationException { 540 541 /* create PackageSetting and add to Settings mPackages */ 542 PackageSetting ps = generateFakePackageSetting("packageA"); 543 mPackagesMap.put(ps.name, ps); 544 545 /* collect keys A and B and add */ 546 ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>(); 547 ArraySet<PublicKey> keys1 = new ArraySet<PublicKey>(); 548 ArraySet<PublicKey> keys2 = new ArraySet<PublicKey>(); 549 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 550 PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB); 551 keys1.add(keyA); 552 keys2.add(keyB); 553 definedKS.put("aliasA", keys1); 554 definedKS.put("aliasB", keys2); 555 mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS); 556 557 /* now upgrade to different set (B, C) */ 558 keys1 = new ArraySet<PublicKey>(); 559 PublicKey keyC = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyC); 560 keys1.add(keyC); 561 definedKS.remove("aliasA"); 562 definedKS.put("aliasC", keys1); 563 mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS); 564 565 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 3)); 566 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 3)); 567 assertEquals(keyC, KeySetUtils.getPubKey(mKsms, 3)); 568 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 569 assertEquals(2, ksMapping.size()); 570 ArraySet<Long> mapping = ksMapping.get(3); 571 assertEquals(1, mapping.size()); 572 assertTrue(mapping.contains(new Long(3))); 573 assertEquals(new Long(3), ps.keySetData.getAliases().get("aliasC")); 574 575 /* either keyset w/keyA or w/keyB was added first, address both cases */ 576 if (1 == KeySetUtils.getKeySetRefCount(mKsms, 1)) { 577 578 /* keyB was added first and should have keyset 1 and pub-key 1 */ 579 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 580 assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 2)); 581 assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 2)); 582 assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 1)); 583 mapping = ksMapping.get(1); 584 assertEquals(1, mapping.size()); 585 assertTrue(mapping.contains(new Long(1))); 586 assertEquals(new Long(1), ps.keySetData.getAliases().get("aliasB")); 587 } else { 588 589 /* keyA was added first and keyB has id 2 */ 590 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2)); 591 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2)); 592 assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1)); 593 assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 594 assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2)); 595 mapping = ksMapping.get(2); 596 assertEquals(1, mapping.size()); 597 assertTrue(mapping.contains(new Long(2))); 598 assertEquals(new Long(2), ps.keySetData.getAliases().get("aliasB")); 599 } 600 assertNull(ps.keySetData.getAliases().get("aliasA")); 601 } 602 603 /* add defined keyset, remove it, add again and make sure diff id. */ 604 public void testAddDefinedKSToPackageThree() throws ReflectiveOperationException { 605 606 /* create PackageSetting and add to Settings mPackages */ 607 PackageSetting ps = generateFakePackageSetting("packageA"); 608 mPackagesMap.put(ps.name, ps); 609 610 /* collect key and add */ 611 ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>(); 612 ArraySet<PublicKey> keys1 = new ArraySet<PublicKey>(); 613 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 614 keys1.add(keyA); 615 definedKS.put("aliasA", keys1); 616 mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS); 617 618 /* now upgrade to different set */ 619 ArraySet<PublicKey> keys2 = new ArraySet<PublicKey>(); 620 PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB); 621 keys2.add(keyB); 622 definedKS.remove("aliasA"); 623 definedKS.put("aliasB", keys2); 624 mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS); 625 626 /* upgrade back to original */ 627 definedKS.remove("aliasB"); 628 definedKS.put("aliasA", keys1); 629 mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS); 630 631 assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1)); 632 assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 2)); 633 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 3)); 634 assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 635 assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 2)); 636 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 3)); 637 assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 3)); 638 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 639 assertEquals(1, ksMapping.size()); 640 ArraySet<Long> mapping = ksMapping.get(3); 641 assertEquals(1, mapping.size()); 642 assertTrue(mapping.contains(new Long(3))); 643 assertEquals(new Long(3), ps.keySetData.getAliases().get("aliasA")); 644 } 645 646 /* add upgrade keyset for existing defined keyset and check that it is recorded */ 647 public void testAddUpgradeKSToPackageEmpty() { 648 649 /* create PackageSetting and add to Settings mPackages */ 650 PackageSetting ps = generateFakePackageSetting("packageA"); 651 mPackagesMap.put(ps.name, ps); 652 653 /* collect key and add, and denote as an upgrade keyset */ 654 ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>(); 655 ArraySet<PublicKey> keys = new ArraySet<PublicKey>(); 656 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 657 keys.add(keyA); 658 definedKS.put("aliasA", keys); 659 mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS); 660 ArraySet<String> upgradeKS = new ArraySet<String>(); 661 upgradeKS.add("aliasA"); 662 mKsms.addUpgradeKeySetsToPackageLPw(ps, upgradeKS); 663 664 assertEquals(1, ps.keySetData.getUpgradeKeySets().length); 665 assertEquals(1, ps.keySetData.getUpgradeKeySets()[0]); 666 } 667 668 /* add upgrade keyset for non-existing defined and check that it compains */ 669 public void testAddUpgradeKSToPackageWrong() { 670 671 /* create PackageSetting and add to Settings mPackages */ 672 PackageSetting ps = generateFakePackageSetting("packageA"); 673 mPackagesMap.put(ps.name, ps); 674 675 /* collect key and add and try to specify bogus upgrade keyset */ 676 ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>(); 677 ArraySet<PublicKey> keys = new ArraySet<PublicKey>(); 678 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 679 keys.add(keyA); 680 definedKS.put("aliasA", keys); 681 mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS); 682 ArraySet<String> upgradeKS = new ArraySet<String>(); 683 upgradeKS.add("aliasB"); 684 try { 685 mKsms.addUpgradeKeySetsToPackageLPw(ps, upgradeKS); 686 } catch (IllegalArgumentException e) { 687 688 /* should have been caught in packagemanager, so exception thrown */ 689 return; 690 } 691 fail("Expected IllegalArgumentException when adding undefined upgrade keyset!!"); 692 } 693 694 /* upgrade from defined keysets w/upgrade to different defined keysets and 695 * make sure the previously specified upgrade keyset has been removed. */ 696 public void testAddUpgradeKSToPackageDisappear() { 697 698 /* create PackageSetting and add to Settings mPackages */ 699 PackageSetting ps = generateFakePackageSetting("packageA"); 700 mPackagesMap.put(ps.name, ps); 701 702 /* collect key and add */ 703 ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>(); 704 ArraySet<PublicKey> keys = new ArraySet<PublicKey>(); 705 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 706 keys.add(keyA); 707 definedKS.put("aliasA", keys); 708 mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS); 709 ArraySet<String> upgradeKS = new ArraySet<String>(); 710 upgradeKS.add("aliasA"); 711 mKsms.addUpgradeKeySetsToPackageLPw(ps, upgradeKS); 712 713 keys = new ArraySet<PublicKey>(); 714 PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB); 715 keys.add(keyB); 716 definedKS.remove("aliasA"); 717 definedKS.put("aliasB", keys); 718 mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS); 719 assertNull(ps.keySetData.getUpgradeKeySets()); 720 } 721 722 /* remove package and validate that keyset and public keys are removed */ 723 public void testRemoveAppKSDataUnique() throws ReflectiveOperationException { 724 725 /* create PackageSetting and add to Settings mPackages */ 726 PackageSetting ps = generateFakePackageSetting("packageA"); 727 mPackagesMap.put(ps.name, ps); 728 729 /* collect signing key and add */ 730 ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>(); 731 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 732 signingKeys.add(keyA); 733 mKsms.addSigningKeySetToPackageLPw(ps, signingKeys); 734 735 /* remove its references */ 736 mKsms.removeAppKeySetDataLPw(ps.name); 737 assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1)); 738 assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 739 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 740 assertEquals(0, ksMapping.size()); 741 assertEquals(PackageKeySetData.KEYSET_UNASSIGNED, ps.keySetData.getProperSigningKeySet()); 742 } 743 744 /* remove package and validate that keysets remain if defined elsewhere but 745 * have refcounts decreased. */ 746 public void testRemoveAppKSDataDup() throws ReflectiveOperationException { 747 748 /* create PackageSettings and add to Settings mPackages */ 749 PackageSetting ps1 = generateFakePackageSetting("packageA"); 750 mPackagesMap.put(ps1.name, ps1); 751 PackageSetting ps2 = generateFakePackageSetting("packageB"); 752 mPackagesMap.put(ps2.name, ps2); 753 754 /* collect signing key and add for both packages */ 755 ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>(); 756 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 757 signingKeys.add(keyA); 758 mKsms.addSigningKeySetToPackageLPw(ps1, signingKeys); 759 mKsms.addSigningKeySetToPackageLPw(ps2, signingKeys); 760 761 /* remove references from first package */ 762 mKsms.removeAppKeySetDataLPw(ps1.name); 763 764 assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1)); 765 assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 766 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 767 assertEquals(1, ksMapping.size()); 768 assertEquals(PackageKeySetData.KEYSET_UNASSIGNED, ps1.keySetData.getProperSigningKeySet()); 769 assertEquals(1, ps2.keySetData.getProperSigningKeySet()); 770 } 771 772 /* remove package which used defined and upgrade keysets and ensure removed */ 773 public void testRemoveAppKSDataDefined() throws ReflectiveOperationException { 774 775 /* create PackageSetting and add to Settings mPackages */ 776 PackageSetting ps = generateFakePackageSetting("packageA"); 777 mPackagesMap.put(ps.name, ps); 778 779 /* collect key and add */ 780 ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>(); 781 ArraySet<PublicKey> keys = new ArraySet<PublicKey>(); 782 PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA); 783 keys.add(keyA); 784 785 /* removal requires signing keyset to be specified (since all apps are 786 * assumed to have it). We skipped this in the defined tests, but can't 787 * here. */ 788 mKsms.addSigningKeySetToPackageLPw(ps, keys); 789 790 definedKS.put("aliasA", keys); 791 mKsms.addDefinedKeySetsToPackageLPw(ps, definedKS); 792 ArraySet<String> upgradeKS = new ArraySet<String>(); 793 upgradeKS.add("aliasA"); 794 mKsms.addUpgradeKeySetsToPackageLPw(ps, upgradeKS); 795 mKsms.removeAppKeySetDataLPw(ps.name); 796 797 assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1)); 798 assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1)); 799 LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms); 800 assertEquals(0, ksMapping.size()); 801 assertEquals(PackageKeySetData.KEYSET_UNASSIGNED, ps.keySetData.getProperSigningKeySet()); 802 assertEquals(0, ps.keySetData.getAliases().size()); 803 assertNull(ps.keySetData.getUpgradeKeySets()); 804 } 805} 806