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);
     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