Home | History | Annotate | Download | only in pm
      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, 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