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