KeySetManagerServiceTest.java revision 788c8423d19972389b82a23dec297eb27d819c86
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm;
18
19
20import android.content.pm.PackageParser;
21import android.content.pm.Signature;
22import android.util.ArrayMap;
23import android.util.ArraySet;
24import android.util.LongSparseArray;
25import com.android.internal.util.ArrayUtils;
26
27import java.io.File;
28import java.io.IOException;
29import java.security.cert.CertificateException;
30import java.security.PublicKey;
31
32import android.test.AndroidTestCase;
33
34public class KeySetManagerServiceTest extends AndroidTestCase {
35
36    private ArrayMap<String, PackageSetting> mPackagesMap;
37    private KeySetManagerService mKsms;
38
39    public PackageSetting generateFakePackageSetting(String name) {
40        return new PackageSetting(name, name, new File(mContext.getCacheDir(), "fakeCodePath"),
41                new File(mContext.getCacheDir(), "fakeResPath"), "", "", "",
42                "", 1, 0, 0, null, null, 0 /*sharedUserId*/);
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