summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java851
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/KeySetStrings.java137
2 files changed, 988 insertions, 0 deletions
diff --git a/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
new file mode 100644
index 0000000..fbdb20b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
@@ -0,0 +1,851 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+
+import android.content.pm.PackageParser;
+import android.content.pm.Signature;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.LongSparseArray;
+import com.android.internal.util.ArrayUtils;
+
+import java.lang.reflect.Field;
+import java.io.File;
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.security.PublicKey;
+
+import android.test.AndroidTestCase;
+
+public class KeySetManagerServiceTest extends AndroidTestCase {
+
+ private ArrayMap<String, PackageSetting> mPackagesMap;
+ private KeySetManagerService mKsms;
+
+ public PackageSetting generateFakePackageSetting(String name) {
+ return new PackageSetting(name, name, new File(mContext.getCacheDir(), "fakeCodePath"),
+ new File(mContext.getCacheDir(), "fakeResPath"), "", "", "",
+ "", 1, 0, 0);
+ }
+
+ public PublicKey getPubKey(long pkId) throws NoSuchFieldException, IllegalAccessException {
+ Field pkField = mKsms.getClass().getDeclaredField("mPublicKeys");
+ pkField.setAccessible(true);
+ LongSparseArray<KeySetManagerService.PublicKeyHandle> mPublicKeys =
+ (LongSparseArray<KeySetManagerService.PublicKeyHandle>) pkField.get(mKsms);
+ KeySetManagerService.PublicKeyHandle pkh = mPublicKeys.get(pkId);
+ if (pkh == null) {
+ return null;
+ } else {
+ return pkh.getKey();
+ }
+ }
+
+ public int getPubKeyRefCount(long pkId) throws NoSuchFieldException, IllegalAccessException {
+ Field pkField = mKsms.getClass().getDeclaredField("mPublicKeys");
+ pkField.setAccessible(true);
+ LongSparseArray<KeySetManagerService.PublicKeyHandle> mPublicKeys =
+ (LongSparseArray<KeySetManagerService.PublicKeyHandle>) pkField.get(mKsms);
+ KeySetManagerService.PublicKeyHandle pkh = mPublicKeys.get(pkId);
+ if (pkh == null) {
+ return 0;
+ } else {
+ return pkh.getRefCountLPr();
+ }
+ }
+
+ public int getKeySetRefCount(long keysetId) throws NoSuchFieldException, IllegalAccessException {
+ Field ksField = mKsms.getClass().getDeclaredField("mKeySets");
+ ksField.setAccessible(true);
+ LongSparseArray<KeySetHandle> mKeySets =
+ (LongSparseArray<KeySetHandle>) ksField.get(mKsms);
+ KeySetHandle ksh = mKeySets.get(keysetId);
+ if (ksh == null) {
+ return 0;
+ } else {
+ return ksh.getRefCountLPr();
+ }
+ }
+
+ public LongSparseArray<ArraySet<Long>> getKeySetMapping()
+ throws NoSuchFieldException, IllegalAccessException {
+ Field ksField = mKsms.getClass().getDeclaredField("mKeySetMapping");
+ ksField.setAccessible(true);
+ return (LongSparseArray<ArraySet<Long>>) ksField.get(mKsms);
+ }
+
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mPackagesMap = new ArrayMap<String, PackageSetting>();
+ mKsms = new KeySetManagerService(mPackagesMap);
+ }
+
+ public void testPackageKeySetDataConstructorUnassignend() {
+ PackageKeySetData pksd = new PackageKeySetData();
+ assertEquals(PackageKeySetData.KEYSET_UNASSIGNED, pksd.getProperSigningKeySet());
+ assertNull(pksd.getUpgradeKeySets());
+ ArrayMap<String, Long> aliases = pksd.getAliases();
+ assertNotNull(aliases);
+ assertEquals(0, aliases.size());
+ }
+
+ /* test equivalence of PackageManager cert encoding and PackageParser manifest keys */
+ public void testPublicKeyCertReprEquiv() throws CertificateException {
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+ PublicKey keyC = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyC);
+
+ Signature sigA = new Signature(KeySetStrings.ctsKeySetCertA);
+ Signature sigB = new Signature(KeySetStrings.ctsKeySetCertB);
+ Signature sigC = new Signature(KeySetStrings.ctsKeySetCertC);
+
+ assertNotNull(keyA);
+ assertNotNull(keyB);
+ assertNotNull(keyC);
+
+ assertEquals(keyA, sigA.getPublicKey());
+ assertEquals(keyB, sigB.getPublicKey());
+ assertEquals(keyC, sigC.getPublicKey());
+
+ byte[] bArrayPk = keyA.getEncoded();
+ byte[] bArrayCert = sigA.getPublicKey().getEncoded();
+ assertEquals(bArrayPk.length, bArrayCert.length);
+ assertEquals(true, ArrayUtils.equals(bArrayPk, bArrayCert, bArrayPk.length));
+
+ bArrayPk = keyB.getEncoded();
+ bArrayCert = sigB.getPublicKey().getEncoded();
+ assertEquals(bArrayPk.length, bArrayCert.length);
+ assertEquals(true, ArrayUtils.equals(bArrayPk, bArrayCert, bArrayPk.length));
+
+ bArrayPk = keyC.getEncoded();
+ bArrayCert = sigC.getPublicKey().getEncoded();
+ assertEquals(bArrayPk.length, bArrayCert.length);
+ assertEquals(true, ArrayUtils.equals(bArrayPk, bArrayCert, bArrayPk.length));
+ }
+
+ public void testEncodePublicKey() throws IOException {
+ ArrayMap<String, PackageSetting> packagesMap = new ArrayMap<String, PackageSetting>();
+ KeySetManagerService ksms = new KeySetManagerService(packagesMap);
+
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+ PublicKey keyC = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyC);
+
+ assertEquals(ksms.encodePublicKey(keyA), KeySetStrings.ctsKeySetPublicKeyA);
+ assertEquals(ksms.encodePublicKey(keyB), KeySetStrings.ctsKeySetPublicKeyB);
+ assertEquals(ksms.encodePublicKey(keyC), KeySetStrings.ctsKeySetPublicKeyC);
+ }
+
+ /*
+ * Add the keyset information for a package to a system w/no previous keysets
+ */
+ public void testAddSigningKSToPackageEmpty() throws ReflectiveOperationException {
+
+ /* create PackageSetting and add to Settings mPackages */
+ PackageSetting ps = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps.name, ps);
+
+ /* collect signing key and add */
+ ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ signingKeys.add(keyA);
+ mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+
+ assertEquals(1, getKeySetRefCount(1));
+ assertEquals(1, getPubKeyRefCount(1));
+ assertEquals(keyA, getPubKey(1));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, ksMapping.size());
+ ArraySet<Long> mapping = ksMapping.get(1);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(1)));
+ assertEquals(1, ps.keySetData.getProperSigningKeySet());
+ }
+
+ /*
+ * upgrade an app (same packagename) with same keyset and verify that
+ * nothing changed.
+ */
+ public void testAddSigningKSToPackageUpgradeSame() throws ReflectiveOperationException {
+
+ /* create PackageSetting and add to Settings mPackages */
+ PackageSetting ps = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps.name, ps);
+
+ /* collect signing key and add */
+ ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ signingKeys.add(keyA);
+ mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+
+ /* add again, to represent upgrade of package */
+ mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+
+ assertEquals(1, getKeySetRefCount(1));
+ assertEquals(1, getPubKeyRefCount(1));
+ assertEquals(keyA, getPubKey(1));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, ksMapping.size());
+ ArraySet<Long> mapping = ksMapping.get(1);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(1)));
+ assertEquals(1, ps.keySetData.getProperSigningKeySet());
+ }
+
+ /*
+ * upgrade an app (same packagename) with different unique keyset and verify
+ * that the old was removed.
+ */
+ public void testAddSigningKSToPackageUpgradeDiff() throws ReflectiveOperationException {
+
+ /* create PackageSetting and add to Settings mPackages */
+ PackageSetting ps = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps.name, ps);
+
+ /* collect signing key and add */
+ ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ signingKeys.add(keyA);
+ mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+
+ /* now upgrade with new key */
+ PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+ signingKeys.removeAt(0);
+ signingKeys.add(keyB);
+ mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+
+ assertEquals(0, getKeySetRefCount(1));
+ assertEquals(1, getKeySetRefCount(2));
+ assertEquals(0, getPubKeyRefCount(1));
+ assertEquals(1, getPubKeyRefCount(2));
+ assertEquals(keyB, getPubKey(2));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, ksMapping.size());
+ ArraySet<Long> mapping = ksMapping.get(2);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(2)));
+ assertEquals(2, ps.keySetData.getProperSigningKeySet());
+ }
+
+ /*
+ * upgrade an app (same packagename) with different keyset and verify
+ * that the old had its ref count reduced due to reference by other ps.
+ */
+ public void testAddSigningKSToPackageUpgradeDiff2() throws ReflectiveOperationException {
+
+ /* create PackageSetting and add to Settings mPackages */
+ PackageSetting ps1 = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps1.name, ps1);
+ PackageSetting ps2 = generateFakePackageSetting("packageB");
+ mPackagesMap.put(ps2.name, ps2);
+
+ /* collect signing key and add */
+ ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ signingKeys.add(keyA);
+ mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys);
+
+ /* now upgrade with new key */
+ PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+ signingKeys.removeAt(0);
+ signingKeys.add(keyB);
+ mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys);
+
+ assertEquals(1, getKeySetRefCount(1));
+ assertEquals(1, getKeySetRefCount(2));
+ assertEquals(1, getPubKeyRefCount(1));
+ assertEquals(1, getPubKeyRefCount(2));
+ assertEquals(keyA, getPubKey(1));
+ assertEquals(keyB, getPubKey(2));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(2, ksMapping.size());
+ ArraySet<Long> mapping = ksMapping.get(1);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(1)));
+ mapping = ksMapping.get(2);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(2)));
+ assertEquals(2, ps1.keySetData.getProperSigningKeySet());
+ assertEquals(1, ps2.keySetData.getProperSigningKeySet());
+ }
+
+ /*
+ * Add orthoganal keyset info to system and ensure previous keysets are
+ * unmodified.
+ */
+ public void testAddSigningKSToPackageNewOrtho() throws ReflectiveOperationException {
+
+ /* create PackageSettings and add to Settings mPackages */
+ PackageSetting ps1 = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps1.name, ps1);
+ PackageSetting ps2 = generateFakePackageSetting("packageB");
+ mPackagesMap.put(ps2.name, ps2);
+
+ /* collect signing key and add */
+ ArraySet<PublicKey> signingKeys1 = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ signingKeys1.add(keyA);
+ mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys1);
+
+ /* collect second signing key and add */
+ ArraySet<PublicKey> signingKeys2 = new ArraySet<PublicKey>();
+ PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+ signingKeys2.add(keyB);
+ mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys2);
+
+ /* verify first is unchanged */
+ assertEquals(1, getKeySetRefCount(1));
+ assertEquals(1, getPubKeyRefCount(1));
+ assertEquals(keyA, getPubKey(1));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(2, ksMapping.size());
+ ArraySet<Long> mapping = ksMapping.get(1);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(1)));
+ assertEquals(1, ps1.keySetData.getProperSigningKeySet());
+
+ /* verify second */
+ assertEquals(1, getKeySetRefCount(2));
+ assertEquals(1, getPubKeyRefCount(2));
+ assertEquals(keyB, getPubKey(2));
+ mapping = ksMapping.get(2);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(2)));
+ assertEquals(2, ps2.keySetData.getProperSigningKeySet());
+ }
+
+ /*
+ * Add identical keyset info to system via new package and ensure previous
+ * keysets has reference count incremented
+ */
+ public void testAddSigningKSToPackageNewSame() throws ReflectiveOperationException {
+
+ /* create PackageSettings and add to Settings mPackages */
+ PackageSetting ps1 = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps1.name, ps1);
+ PackageSetting ps2 = generateFakePackageSetting("packageB");
+ mPackagesMap.put(ps2.name, ps2);
+
+ /* collect signing key and add */
+ ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ signingKeys.add(keyA);
+ mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys);
+
+ /* add again for second package */
+ mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys);
+
+ assertEquals(2, getKeySetRefCount(1));
+ assertEquals(1, getPubKeyRefCount(1));
+ assertEquals(keyA, getPubKey(1));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, ksMapping.size());
+ ArraySet<Long> mapping = ksMapping.get(1);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(1)));
+ assertEquals(1, ps1.keySetData.getProperSigningKeySet());
+ assertEquals(1, ps2.keySetData.getProperSigningKeySet());
+ }
+
+ /*
+ * add a package which is signed by a keyset which contains a previously seen
+ * public key and make sure its refernces are incremented.
+ */
+ public void testAddSigningKSToPackageSuper() throws ReflectiveOperationException {
+
+ /* create PackageSettings and add to Settings mPackages */
+ PackageSetting ps1 = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps1.name, ps1);
+ PackageSetting ps2 = generateFakePackageSetting("packageB");
+ mPackagesMap.put(ps2.name, ps2);
+
+ /* collect signing key and add */
+ ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ signingKeys.add(keyA);
+ mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys);
+
+ /* give ps2 a superset (add keyB) */
+ PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+ signingKeys.add(keyB);
+ mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys);
+
+ assertEquals(1, getKeySetRefCount(1));
+ assertEquals(1, getKeySetRefCount(2));
+ assertEquals(2, getPubKeyRefCount(1));
+ assertEquals(1, getPubKeyRefCount(2));
+ assertEquals(keyA, getPubKey(1));
+ assertEquals(keyB, getPubKey(2));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(2, ksMapping.size());
+ ArraySet<Long> mapping = ksMapping.get(1);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(1)));
+ mapping = ksMapping.get(2);
+ assertEquals(2, mapping.size());
+ assertTrue(mapping.contains(new Long(1)));
+ assertTrue(mapping.contains(new Long(2)));
+ assertEquals(1, ps1.keySetData.getProperSigningKeySet());
+ assertEquals(2, ps2.keySetData.getProperSigningKeySet());
+ }
+
+ /*
+ * Upgrade an app (same pkgName) with different keyset which contains a public
+ * key from the previous keyset. Verify old keyset removed and pub key ref
+ * count is accurate.
+ */
+ public void testAddSigningKSToPackageUpgradeDiffSuper() throws ReflectiveOperationException {
+
+ /* create PackageSetting and add to Settings mPackages */
+ PackageSetting ps = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps.name, ps);
+
+ /* collect signing key and add */
+ ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ signingKeys.add(keyA);
+ mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+
+ /* now with additional key */
+ PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+ signingKeys.add(keyB);
+ mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+
+ assertEquals(0, getKeySetRefCount(1));
+ assertEquals(1, getKeySetRefCount(2));
+ assertEquals(0, getPubKeyRefCount(1));
+ assertEquals(1, getPubKeyRefCount(2));
+ assertEquals(1, getPubKeyRefCount(3));
+
+ /* the pub key is removed w/prev keyset and may be either 2 or 3 */
+ assertTrue(keyA.equals(getPubKey(2)) && keyB.equals(getPubKey(3))
+ || keyA.equals(getPubKey(3)) && keyB.equals(getPubKey(2)));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, ksMapping.size());
+ ArraySet<Long> mapping = ksMapping.get(2);
+ assertEquals(2, mapping.size());
+ assertTrue(mapping.contains(new Long(2)));
+ assertTrue(mapping.contains(new Long(3)));
+ assertEquals(2, ps.keySetData.getProperSigningKeySet());
+ }
+
+ /* add a defined keyset make sure it shows up */
+ public void testAddDefinedKSToPackageEmpty() throws ReflectiveOperationException {
+
+ /* create PackageSetting and add to Settings mPackages */
+ PackageSetting ps = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps.name, ps);
+
+ /* collect key and add */
+ ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+ ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ keys.add(keyA);
+ definedKS.put("aliasA", keys);
+ mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+ assertEquals(1, getKeySetRefCount(1));
+ assertEquals(1, getPubKeyRefCount(1));
+ assertEquals(keyA, getPubKey(1));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, ksMapping.size());
+ ArraySet<Long> mapping = ksMapping.get(1);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(1)));
+ assertNotNull(ps.keySetData.getAliases().get("aliasA"));
+ assertEquals(new Long(1), ps.keySetData.getAliases().get("aliasA"));
+ }
+
+ /* add 2 defined keysets which refer to same keyset and make sure ref-ct is 2 */
+ public void testAddDefinedKSToPackageDoubleAlias() throws ReflectiveOperationException {
+
+ /* create PackageSetting and add to Settings mPackages */
+ PackageSetting ps = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps.name, ps);
+
+ /* collect key and add */
+ ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+ ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ keys.add(keyA);
+ definedKS.put("aliasA", keys);
+ definedKS.put("aliasA2", keys);
+ mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+ assertEquals(2, getKeySetRefCount(1));
+ assertEquals(1, getPubKeyRefCount(1));
+ assertEquals(keyA, getPubKey(1));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, ksMapping.size());
+ ArraySet<Long> mapping = ksMapping.get(1);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(1)));
+ assertNotNull(ps.keySetData.getAliases().get("aliasA"));
+ assertEquals(new Long(1), ps.keySetData.getAliases().get("aliasA"));
+ assertNotNull(ps.keySetData.getAliases().get("aliasA2"));
+ assertEquals(new Long(1), ps.keySetData.getAliases().get("aliasA2"));
+ }
+
+ /* upgrd defined keyset ortho (make sure previous is removed for pkg) */
+ public void testAddDefinedKSToPackageOrthoUpgr() throws ReflectiveOperationException {
+
+ /* create PackageSetting and add to Settings mPackages */
+ PackageSetting ps = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps.name, ps);
+
+ /* collect key and add */
+ ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+ ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ keys.add(keyA);
+ definedKS.put("aliasA", keys);
+ mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+ /* now upgrade to different defined key-set */
+ keys = new ArraySet<PublicKey>();
+ PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+ keys.add(keyB);
+ definedKS.remove("aliasA");
+ definedKS.put("aliasB", keys);
+ mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+ assertEquals(0, getKeySetRefCount(1));
+ assertEquals(0, getPubKeyRefCount(1));
+ assertEquals(1, getKeySetRefCount(2));
+ assertEquals(1, getPubKeyRefCount(2));
+ assertEquals(keyB, getPubKey(2));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, ksMapping.size());
+ ArraySet<Long> mapping = ksMapping.get(2);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(2)));
+ assertNull(ps.keySetData.getAliases().get("aliasA"));
+ assertNotNull(ps.keySetData.getAliases().get("aliasB"));
+ assertEquals(new Long(2), ps.keySetData.getAliases().get("aliasB"));
+ }
+
+ /* upgrd defined keyset ortho but reuse alias (make sure old is removed and
+ * alias points to new keyset)
+ */
+ public void testAddDefinedKSToPackageOrthoUpgrAliasSame() throws ReflectiveOperationException {
+
+ /* create PackageSetting and add to Settings mPackages */
+ PackageSetting ps = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps.name, ps);
+
+ /* collect key and add */
+ ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+ ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ keys.add(keyA);
+ definedKS.put("aliasA", keys);
+ mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+ /* now upgrade to different set w/same alias as before */
+ keys = new ArraySet<PublicKey>();
+ PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+ keys.add(keyB);
+ definedKS.put("aliasA", keys);
+ mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+ assertEquals(0, getKeySetRefCount(1));
+ assertEquals(0, getPubKeyRefCount(1));
+ assertEquals(1, getKeySetRefCount(2));
+ assertEquals(1, getPubKeyRefCount(2));
+ assertEquals(keyB, getPubKey(2));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, ksMapping.size());
+ ArraySet<Long> mapping = ksMapping.get(2);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(2)));
+ assertNotNull(ps.keySetData.getAliases().get("aliasA"));
+ assertEquals(new Long(2), ps.keySetData.getAliases().get("aliasA"));
+ }
+
+ /* Start with defined ks of (A, B) and upgrade to (B, C). Make sure B is
+ * unchanged. */
+ public void testAddDefinedKSToPackageOverlapUpgr() throws ReflectiveOperationException {
+
+ /* create PackageSetting and add to Settings mPackages */
+ PackageSetting ps = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps.name, ps);
+
+ /* collect keys A and B and add */
+ ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+ ArraySet<PublicKey> keys1 = new ArraySet<PublicKey>();
+ ArraySet<PublicKey> keys2 = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+ keys1.add(keyA);
+ keys2.add(keyB);
+ definedKS.put("aliasA", keys1);
+ definedKS.put("aliasB", keys2);
+ mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+ /* now upgrade to different set (B, C) */
+ keys1 = new ArraySet<PublicKey>();
+ PublicKey keyC = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyC);
+ keys1.add(keyC);
+ definedKS.remove("aliasA");
+ definedKS.put("aliasC", keys1);
+ mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+ assertEquals(1, getKeySetRefCount(3));
+ assertEquals(1, getPubKeyRefCount(3));
+ assertEquals(keyC, getPubKey(3));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(2, ksMapping.size());
+ ArraySet<Long> mapping = ksMapping.get(3);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(3)));
+ assertEquals(new Long(3), ps.keySetData.getAliases().get("aliasC"));
+
+ /* either keyset w/keyA or w/keyB was added first, address both cases */
+ if (1 == getKeySetRefCount(1)) {
+
+ /* keyB was added first and should have keyset 1 and pub-key 1 */
+ assertEquals(1, getPubKeyRefCount(1));
+ assertEquals(0, getKeySetRefCount(2));
+ assertEquals(0, getPubKeyRefCount(2));
+ assertEquals(keyB, getPubKey(1));
+ mapping = ksMapping.get(1);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(1)));
+ assertEquals(new Long(1), ps.keySetData.getAliases().get("aliasB"));
+ } else {
+
+ /* keyA was added first and keyB has id 2 */
+ assertEquals(1, getKeySetRefCount(2));
+ assertEquals(1, getPubKeyRefCount(2));
+ assertEquals(0, getKeySetRefCount(1));
+ assertEquals(0, getPubKeyRefCount(1));
+ assertEquals(keyB, getPubKey(2));
+ mapping = ksMapping.get(2);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(2)));
+ assertEquals(new Long(2), ps.keySetData.getAliases().get("aliasB"));
+ }
+ assertNull(ps.keySetData.getAliases().get("aliasA"));
+ }
+
+ /* add defined keyset, remove it, add again and make sure diff id. */
+ public void testAddDefinedKSToPackageThree() throws ReflectiveOperationException {
+
+ /* create PackageSetting and add to Settings mPackages */
+ PackageSetting ps = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps.name, ps);
+
+ /* collect key and add */
+ ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+ ArraySet<PublicKey> keys1 = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ keys1.add(keyA);
+ definedKS.put("aliasA", keys1);
+ mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+ /* now upgrade to different set */
+ ArraySet<PublicKey> keys2 = new ArraySet<PublicKey>();
+ PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+ keys2.add(keyB);
+ definedKS.remove("aliasA");
+ definedKS.put("aliasB", keys2);
+ mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+ /* upgrade back to original */
+ definedKS.remove("aliasB");
+ definedKS.put("aliasA", keys1);
+ mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+ assertEquals(0, getKeySetRefCount(1));
+ assertEquals(0, getKeySetRefCount(2));
+ assertEquals(1, getKeySetRefCount(3));
+ assertEquals(0, getPubKeyRefCount(1));
+ assertEquals(0, getPubKeyRefCount(2));
+ assertEquals(1, getPubKeyRefCount(3));
+ assertEquals(keyA, getPubKey(3));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, ksMapping.size());
+ ArraySet<Long> mapping = ksMapping.get(3);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(3)));
+ assertEquals(new Long(3), ps.keySetData.getAliases().get("aliasA"));
+ }
+
+ /* add upgrade keyset for existing defined keyset and check that it is recorded */
+ public void testAddUpgradeKSToPackageEmpty() {
+
+ /* create PackageSetting and add to Settings mPackages */
+ PackageSetting ps = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps.name, ps);
+
+ /* collect key and add, and denote as an upgrade keyset */
+ ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+ ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ keys.add(keyA);
+ definedKS.put("aliasA", keys);
+ mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ ArraySet<String> upgradeKS = new ArraySet<String>();
+ upgradeKS.add("aliasA");
+ mKsms.addUpgradeKeySetsToPackageLPw(ps.name, upgradeKS);
+
+ assertEquals(1, ps.keySetData.getUpgradeKeySets().length);
+ assertEquals(1, ps.keySetData.getUpgradeKeySets()[0]);
+ }
+
+ /* add upgrade keyset for non-existing defined and check that it compains */
+ public void testAddUpgradeKSToPackageWrong() {
+
+ /* create PackageSetting and add to Settings mPackages */
+ PackageSetting ps = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps.name, ps);
+
+ /* collect key and add and try to specify bogus upgrade keyset */
+ ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+ ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ keys.add(keyA);
+ definedKS.put("aliasA", keys);
+ mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ ArraySet<String> upgradeKS = new ArraySet<String>();
+ upgradeKS.add("aliasB");
+ try {
+ mKsms.addUpgradeKeySetsToPackageLPw(ps.name, upgradeKS);
+ } catch (IllegalArgumentException e) {
+
+ /* should have been caught in packagemanager, so exception thrown */
+ return;
+ }
+ fail("Expected IllegalArgumentException when adding undefined upgrade keyset!!");
+ }
+
+ /* upgrade from defined keysets w/upgrade to different defined keysets and
+ * make sure the previously specified upgrade keyset has been removed. */
+ public void testAddUpgradeKSToPackageDisappear() {
+
+ /* create PackageSetting and add to Settings mPackages */
+ PackageSetting ps = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps.name, ps);
+
+ /* collect key and add */
+ ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+ ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ keys.add(keyA);
+ definedKS.put("aliasA", keys);
+ mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ ArraySet<String> upgradeKS = new ArraySet<String>();
+ upgradeKS.add("aliasA");
+ mKsms.addUpgradeKeySetsToPackageLPw(ps.name, upgradeKS);
+
+ keys = new ArraySet<PublicKey>();
+ PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+ keys.add(keyB);
+ definedKS.remove("aliasA");
+ definedKS.put("aliasB", keys);
+ mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ assertNull(ps.keySetData.getUpgradeKeySets());
+ }
+
+ /* remove package and validate that keyset and public keys are removed */
+ public void testRemoveAppKSDataUnique() throws ReflectiveOperationException {
+
+ /* create PackageSetting and add to Settings mPackages */
+ PackageSetting ps = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps.name, ps);
+
+ /* collect signing key and add */
+ ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ signingKeys.add(keyA);
+ mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+
+ /* remove its references */
+ mKsms.removeAppKeySetDataLPw(ps.name);
+ assertEquals(0, getKeySetRefCount(1));
+ assertEquals(0, getPubKeyRefCount(1));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(0, ksMapping.size());
+ assertEquals(PackageKeySetData.KEYSET_UNASSIGNED, ps.keySetData.getProperSigningKeySet());
+ }
+
+ /* remove package and validate that keysets remain if defined elsewhere but
+ * have refcounts decreased. */
+ public void testRemoveAppKSDataDup() throws ReflectiveOperationException {
+
+ /* create PackageSettings and add to Settings mPackages */
+ PackageSetting ps1 = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps1.name, ps1);
+ PackageSetting ps2 = generateFakePackageSetting("packageB");
+ mPackagesMap.put(ps2.name, ps2);
+
+ /* collect signing key and add for both packages */
+ ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ signingKeys.add(keyA);
+ mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys);
+ mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys);
+
+ /* remove references from first package */
+ mKsms.removeAppKeySetDataLPw(ps1.name);
+
+ assertEquals(1, getKeySetRefCount(1));
+ assertEquals(1, getPubKeyRefCount(1));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, ksMapping.size());
+ assertEquals(PackageKeySetData.KEYSET_UNASSIGNED, ps1.keySetData.getProperSigningKeySet());
+ assertEquals(1, ps2.keySetData.getProperSigningKeySet());
+ }
+
+ /* remove package which used defined and upgrade keysets and ensure removed */
+ public void testRemoveAppKSDataDefined() throws ReflectiveOperationException {
+
+ /* create PackageSetting and add to Settings mPackages */
+ PackageSetting ps = generateFakePackageSetting("packageA");
+ mPackagesMap.put(ps.name, ps);
+
+ /* collect key and add */
+ ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+ ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ keys.add(keyA);
+
+ /* removal requires signing keyset to be specified (since all apps are
+ * assumed to have it). We skipped this in the defined tests, but can't
+ * here. */
+ mKsms.addSigningKeySetToPackageLPw(ps.name, keys);
+
+ definedKS.put("aliasA", keys);
+ mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+ ArraySet<String> upgradeKS = new ArraySet<String>();
+ upgradeKS.add("aliasA");
+ mKsms.addUpgradeKeySetsToPackageLPw(ps.name, upgradeKS);
+ mKsms.removeAppKeySetDataLPw(ps.name);
+
+ assertEquals(0, getKeySetRefCount(1));
+ assertEquals(0, getPubKeyRefCount(1));
+ LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(0, ksMapping.size());
+ assertEquals(PackageKeySetData.KEYSET_UNASSIGNED, ps.keySetData.getProperSigningKeySet());
+ assertEquals(0, ps.keySetData.getAliases().size());
+ assertNull(ps.keySetData.getUpgradeKeySets());
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/KeySetStrings.java b/services/tests/servicestests/src/com/android/server/pm/KeySetStrings.java
new file mode 100644
index 0000000..89d01ae
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/KeySetStrings.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+public class KeySetStrings {
+
+ /*
+ * public keys taken from:
+ * openssl x509 -in cts-keyset-test-${N}.x509.pem -inform PEM -pubkey
+ * in /platform/cts/hostsidetests/appsecurity/certs/keysets
+ */
+ public static final String ctsKeySetPublicKeyA =
+ "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwf5zJblvYSB7Ym7or/7Ggg"
+ + "AAu7mp7RrykPJsXhod8doFhVT5s7eF3A4MCE55vvANP7HvwMw2b+T6qx7Pq0VJtb"
+ + "bSDtlBHBtIc47Pjq0CsDg590BUcgKp7PdJ9J6UVgtzDnV6cGEpXmSag3sY+lqiW0"
+ + "4ytPhCVwzYTWGdYe9+TIl47cBrveRfLOlGrcuFQe+zCTmDFqzBKCRHK9b7l5PDWv"
+ + "XXyg65Uu/MBUA/TZWO0fEqOlxZG/nn6DUKQLhPdmJRXWJ3WqMNMhJGD+nKtkmdX7"
+ + "03xRqmg4h+6g0S7M9Y3IQ2NUGyw05AYzCguHB/Mv6uVIiW659wpbyb45TgKG3UhQ"
+ + "IDAQAB";
+
+ public static final String ctsKeySetPublicKeyB =
+ "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoeFZqMqTbZiozFTXMkXtSK"
+ + "JRzn2qODZgvVXAAwKTi50xYcbPcHTfKxtif8+q7OCp/50JYDH32bg6wkUunn5+dE"
+ + "aHkxZY8d7uw46tQtl5dNGi+6cc4MezVLCS6nkqNDusAgdvgLU6Fl6SGi02KTp1vk"
+ + "t6CwLO977YJP7kt9ouDRTG7ASJiq3OyRRoOqYHhD9gpsbUq4w+1bXGfuuZujA1dX"
+ + "yovXtvrHUGOdFIEBYOVYGfCcwh3lXPmjNJMlHtKQkurq8/LH7a1B5ocoXCGsyR8Y"
+ + "HdlWfrqRAfzgOB1KCnNNmWqskU9LOci3uQn9IDeMEFmAd8FqF8SwV+4Ludk/xWGQ"
+ + "IDAQAB";
+
+ public static final String ctsKeySetPublicKeyC =
+ "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwIJ/p9zZ6pGe7h1lBJULE"
+ + "5lbYbC3mh5G43OsJ+B0CebN4KzEKyVg+wmkuGSvG2xXUp1BlbipSjnTJ5bUt2iBu"
+ + "wB81Lvumg9GOfCpTBGtfE4a4igtfo7e2U8IbRzEYbhaZlBEmC1BDUvdTFdMRGZPu"
+ + "hUcMkwit4RpHkL6rttuOfaeoJwsgEjbELyzgcm+1Z49Den/JmmXNGMw1/QMibBFG"
+ + "vGkhu2rHg/SYiKpupclU4FIeALcOSnPkrrY6LuSATHDnYvuvK3Vhu0EBKID+rAv5"
+ + "j6BNvnu25SAf3GgS7PLuyVlhiE5p3hTevXn5g/7tjJlXa0FsbMlnFf53WyP9pRWw"
+ + "IDAQAB";
+
+ /*
+ * certs taken from packagemanager packages.xml output corresponding to certs in
+ * /platform/cts/hostsidetests/appsecurity/certs/keysets
+ */
+ public static final String ctsKeySetCertA =
+ "3082030b308201f3a0030201020209009d76e8a600170813300d06092a864886f7"
+ + "0d0101050500301c311a301806035504030c116374732d6b65797365742d7465"
+ + "73742d61301e170d3134303931313030343434385a170d343230313237303034"
+ + "3434385a301c311a301806035504030c116374732d6b65797365742d74657374"
+ + "2d6130820122300d06092a864886f70d01010105000382010f003082010a0282"
+ + "010100c1fe7325b96f61207b626ee8affec6820000bbb9a9ed1af290f26c5e1a"
+ + "1df1da058554f9b3b785dc0e0c084e79bef00d3fb1efc0cc366fe4faab1ecfab"
+ + "4549b5b6d20ed9411c1b48738ecf8ead02b03839f740547202a9ecf749f49e94"
+ + "560b730e757a7061295e649a837b18fa5aa25b4e32b4f842570cd84d619d61ef"
+ + "7e4c8978edc06bbde45f2ce946adcb8541efb309398316acc12824472bd6fb97"
+ + "93c35af5d7ca0eb952efcc05403f4d958ed1f12a3a5c591bf9e7e8350a40b84f"
+ + "7662515d62775aa30d3212460fe9cab6499d5fbd37c51aa683887eea0d12eccf"
+ + "58dc84363541b2c34e406330a0b8707f32feae548896eb9f70a5bc9be394e028"
+ + "6dd4850203010001a350304e301d0603551d0e04160414debf602e08b7573bce"
+ + "4816ac32eab215fb052892301f0603551d23041830168014debf602e08b7573b"
+ + "ce4816ac32eab215fb052892300c0603551d13040530030101ff300d06092a86"
+ + "4886f70d0101050500038201010092f1b8d08252d808d3051dce80780bd27eef"
+ + "e3f6b6d935398afb448209461b6f8b352e830d4358661e1b3e9eb9ab3937bddd"
+ + "581a28f533da1ebeb6838ce4a84ca64c43507c5ef9528917857e4d1c4c5996cf"
+ + "6b3d30823db514a715eeee709d69e38b4f0ef5dce4b08ce40fd52b39ac651311"
+ + "b6d1814913d922ce84748b6999256851fb583a49e35cecf79a527108df8e062d"
+ + "f4831addbb12a661999d41849e2545150cab74c91447dd15e55cdf3f8082dcab"
+ + "667c5cee3350d0f15d3970edcf3e81882e80985b0c0bf9917adb55c634de3a92"
+ + "e8fb5d9413b1703bec116b9ee9346b658f394acfe0c60406718be80b7110df8b"
+ + "44c984f001e1d16aac3831afee18";
+
+ public static final String ctsKeySetCertB =
+ "3082030b308201f3a003020102020900e670a5b2ec1e8a12300d06092a864886f7"
+ + "0d0101050500301c311a301806035504030c116374732d6b65797365742d7465"
+ + "73742d62301e170d3134303931313030343434315a170d343230313237303034"
+ + "3434315a301c311a301806035504030c116374732d6b65797365742d74657374"
+ + "2d6230820122300d06092a864886f70d01010105000382010f003082010a0282"
+ + "010100a1e159a8ca936d98a8cc54d73245ed48a251ce7daa383660bd55c00302"
+ + "938b9d3161c6cf7074df2b1b627fcfaaece0a9ff9d096031f7d9b83ac2452e9e"
+ + "7e7e744687931658f1deeec38ead42d97974d1a2fba71ce0c7b354b092ea792a"
+ + "343bac02076f80b53a165e921a2d36293a75be4b7a0b02cef7bed824fee4b7da"
+ + "2e0d14c6ec04898aadcec914683aa607843f60a6c6d4ab8c3ed5b5c67eeb99ba"
+ + "3035757ca8bd7b6fac750639d14810160e55819f09cc21de55cf9a33493251ed"
+ + "29092eaeaf3f2c7edad41e687285c21acc91f181dd9567eba9101fce0381d4a0"
+ + "a734d996aac914f4b39c8b7b909fd20378c10598077c16a17c4b057ee0bb9d93"
+ + "fc56190203010001a350304e301d0603551d0e04160414ccd4d9d47dcc18889d"
+ + "cba32de37e6570c88f8109301f0603551d23041830168014ccd4d9d47dcc1888"
+ + "9dcba32de37e6570c88f8109300c0603551d13040530030101ff300d06092a86"
+ + "4886f70d0101050500038201010061951cf9c9a629b30b560d53d62a72796edc"
+ + "97b0b210b567859311b14574abb052ef08cabb0b18cef5517597eabee9498a07"
+ + "a04472b8e6eee8668c05d2ff28141a36351593551f0c9d27feb4367fd0d23c76"
+ + "e36035f9d06d2d24b4167120fabdcfddfbe872bd127a602de8563ad6027ee19a"
+ + "fc21065cf02d6aaf97bf78388c3c129e72d1b31f5727896aaad7fe6773fbc285"
+ + "34e89194a75e1ecf64bcc5fa228e71e3be9efc78cb39bbabf60e334b403fc3e4"
+ + "9eb59c3407883d10efb04470a7d7d12114e7c9ddc3b381ffc43e8e8a830efa59"
+ + "38e47eef0d4dd39a80186c3b4236f812f52775941fe1dd73d51f6f50ab0916e3"
+ + "149c31feabcf38860be45d113a54";
+
+ public static final String ctsKeySetCertC =
+ "3082030b308201f3a0030201020209008f2e824e4e17810d300d06092a864886f7"
+ + "0d0101050500301c311a301806035504030c116374732d6b65797365742d7465"
+ + "73742d63301e170d3134303931313030343432325a170d343230313237303034"
+ + "3432325a301c311a301806035504030c116374732d6b65797365742d74657374"
+ + "2d6330820122300d06092a864886f70d01010105000382010f003082010a0282"
+ + "010100af0209fe9f7367aa467bb8759412542c4e656d86c2de68791b8dceb09f"
+ + "81d0279b3782b310ac9583ec2692e192bc6db15d4a750656e2a528e74c9e5b52"
+ + "dda206ec01f352efba683d18e7c2a53046b5f1386b88a0b5fa3b7b653c21b473"
+ + "1186e16999411260b504352f75315d3111993ee85470c9308ade11a4790beabb"
+ + "6db8e7da7a8270b201236c42f2ce0726fb5678f437a7fc99a65cd18cc35fd032"
+ + "26c1146bc6921bb6ac783f49888aa6ea5c954e0521e00b70e4a73e4aeb63a2ee"
+ + "4804c70e762fbaf2b7561bb41012880feac0bf98fa04dbe7bb6e5201fdc6812e"
+ + "cf2eec95961884e69de14debd79f983feed8c99576b416c6cc96715fe775b23f"
+ + "da515b0203010001a350304e301d0603551d0e041604141b8137c73974a17633"
+ + "686f93798a7f7b8385bded301f0603551d230418301680141b8137c73974a176"
+ + "33686f93798a7f7b8385bded300c0603551d13040530030101ff300d06092a86"
+ + "4886f70d01010505000382010100276ce2ca7b78b12aa2e432c8287075af91e5"
+ + "2a15a8586e23cdd7524a4c5ae04156307e95275cdfd841f2d28c0583cb36779e"
+ + "25d849a8b608eb48a84a50202a7825c7847e865409b1dd01303b5b1bdfafecab"
+ + "bfe1c6ec5f30ce1cb16b93db72ef726f77a48ca4f5ac5e12c4ad08c6df6fbf7e"
+ + "1548ef7ca80cf1d98abb550c0e28b246e8c0f1a975ffb624f1a4aeec11f01ba6"
+ + "02631d56645f5ae042dbf67b444b160711ca2629c456c5cc12e2ff56fa1332b6"
+ + "92483d14d2e6fb8e026246058fb5826e3958ee8f780d0fc2b840d51c2bbf0d24"
+ + "e9e108ef1c2d9ec13797bb4e5793349628a2ddb2a79c9d9c5736e7aea93e4552"
+ + "18fd162e0a42a4fbb4aa9df82b8a";
+}