1f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra/* 2f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Copyright (C) 2013 The Android Open Source Project 3f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * 4f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Licensed under the Apache License, Version 2.0 (the "License"); 5f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * you may not use this file except in compliance with the License. 6f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * You may obtain a copy of the License at 7f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * 8f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * http://www.apache.org/licenses/LICENSE-2.0 9f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * 10f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Unless required by applicable law or agreed to in writing, software 11f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * distributed under the License is distributed on an "AS IS" BASIS, 12f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * See the License for the specific language governing permissions and 14f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * limitations under the License. 15f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra */ 16f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 17f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condrapackage com.android.server.pm; 18f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 19f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condraimport android.content.pm.KeySet; 20f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condraimport android.content.pm.PackageParser; 21f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condraimport android.os.Binder; 22f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condraimport android.util.Base64; 23f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condraimport android.util.Log; 24f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condraimport android.util.LongSparseArray; 25f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 26f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condraimport java.io.IOException; 27f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condraimport java.io.PrintWriter; 28f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condraimport java.security.PublicKey; 29f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condraimport java.util.HashMap; 30f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condraimport java.util.HashSet; 31f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condraimport java.util.Map; 32f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condraimport java.util.Set; 33f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 34f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condraimport org.xmlpull.v1.XmlPullParser; 35f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condraimport org.xmlpull.v1.XmlPullParserException; 36f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condraimport org.xmlpull.v1.XmlSerializer; 37f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 38f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra/* 39f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Manages system-wide KeySet state. 40f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra */ 41f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condrapublic class KeySetManager { 42f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 43f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra static final String TAG = "KeySetManager"; 44f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 459a995f57a3cbfefc248498bbd51e7a09f584ff4fKenny Root /** Sentinel value returned when a {@code KeySet} is not found. */ 469a995f57a3cbfefc248498bbd51e7a09f584ff4fKenny Root public static final long KEYSET_NOT_FOUND = -1; 479a995f57a3cbfefc248498bbd51e7a09f584ff4fKenny Root 489a995f57a3cbfefc248498bbd51e7a09f584ff4fKenny Root /** Sentinel value returned when public key is not found. */ 49f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra private static final long PUBLIC_KEY_NOT_FOUND = -1; 50f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 51f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra private final Object mLockObject = new Object(); 52f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 53f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra private final LongSparseArray<KeySet> mKeySets; 54f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 55f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra private final LongSparseArray<PublicKey> mPublicKeys; 56f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 57f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra private final LongSparseArray<Set<Long>> mKeySetMapping; 58f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 59f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra private final Map<String, PackageSetting> mPackages; 60f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 61f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra private static long lastIssuedKeySetId = 0; 62f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 63f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra private static long lastIssuedKeyId = 0; 64f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 65f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra public KeySetManager(Map<String, PackageSetting> packages) { 66f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra mKeySets = new LongSparseArray<KeySet>(); 67f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra mPublicKeys = new LongSparseArray<PublicKey>(); 68f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra mKeySetMapping = new LongSparseArray<Set<Long>>(); 69f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra mPackages = packages; 70f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 71f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 722042e9df4855ef59e3329b548b208279a88d7adbKenny Root /** 73f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Determine if a package is signed by the given KeySet. 74f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * 75f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Returns false if the package was not signed by all the 76f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * keys in the KeySet. 77f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * 78f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Returns true if the package was signed by at least the 79f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * keys in the given KeySet. 80f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * 81f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Note that this can return true for multiple KeySets. 82f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra */ 83f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra public boolean packageIsSignedBy(String packageName, KeySet ks) { 84f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra synchronized (mLockObject) { 85f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra PackageSetting pkg = mPackages.get(packageName); 86f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (pkg == null) { 87f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throw new NullPointerException("Invalid package name"); 88f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 89f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (pkg.keySetData == null) { 90f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throw new NullPointerException("Package has no KeySet data"); 91f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 92f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra long id = getIdByKeySetLocked(ks); 93f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return pkg.keySetData.packageIsSignedBy(id); 94f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 95f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 96f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 972042e9df4855ef59e3329b548b208279a88d7adbKenny Root /** 98f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * This informs the system that the given package has defined a KeySet 99f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * in its manifest that a) contains the given keys and b) is named 100f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * alias by that package. 101f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra */ 102f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra public void addDefinedKeySetToPackage(String packageName, 103f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra Set<PublicKey> keys, String alias) { 104f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if ((packageName == null) || (keys == null) || (alias == null)) { 105c30d92e2241ad329ceb67e216e1e5adfbfc84d99Dianne Hackborn //Log.d(TAG, "Got null argument for a defined keyset, ignoring!"); 106f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return; 107f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 108f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra synchronized (mLockObject) { 109f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra KeySet ks = addKeySetLocked(keys); 110f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra PackageSetting pkg = mPackages.get(packageName); 111f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (pkg == null) { 112f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throw new NullPointerException("Unknown package"); 113f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 114f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra long id = getIdByKeySetLocked(ks); 115f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra pkg.keySetData.addDefinedKeySet(id, alias); 116f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 117f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 118f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 1192042e9df4855ef59e3329b548b208279a88d7adbKenny Root /** 120f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Similar to the above, this informs the system that the given package 121f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * was signed by the provided KeySet. 122f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra */ 123f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra public void addSigningKeySetToPackage(String packageName, 124f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra Set<PublicKey> signingKeys) { 125f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if ((packageName == null) || (signingKeys == null)) { 126c30d92e2241ad329ceb67e216e1e5adfbfc84d99Dianne Hackborn //Log.d(TAG, "Got null argument for a signing keyset, ignoring!"); 127f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return; 128f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 129f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra synchronized (mLockObject) { 130f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // add the signing KeySet 131f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra KeySet ks = addKeySetLocked(signingKeys); 132f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra long id = getIdByKeySetLocked(ks); 133f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra Set<Long> publicKeyIds = mKeySetMapping.get(id); 134f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (publicKeyIds == null) { 135f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throw new NullPointerException("Got invalid KeySet id"); 136f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 137f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 138f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // attach it to the package 139f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra PackageSetting pkg = mPackages.get(packageName); 140f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (pkg == null) { 141f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throw new NullPointerException("No such package!"); 142f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 143f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra pkg.keySetData.addSigningKeySet(id); 144f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 145f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // for each KeySet the package defines which is a subset of 146f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // the one above, add the KeySet id to the package's signing KeySets 147f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (Long keySetID : pkg.keySetData.getDefinedKeySets()) { 148f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra Set<Long> definedKeys = mKeySetMapping.get(keySetID); 149f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (publicKeyIds.contains(definedKeys)) { 150f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra pkg.keySetData.addSigningKeySet(keySetID); 151f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 152f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 153f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 154f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 155f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 1562042e9df4855ef59e3329b548b208279a88d7adbKenny Root /** 1572042e9df4855ef59e3329b548b208279a88d7adbKenny Root * Fetches the stable identifier associated with the given KeySet. Returns 1582042e9df4855ef59e3329b548b208279a88d7adbKenny Root * {@link #KEYSET_NOT_FOUND} if the KeySet... wasn't found. 159f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra */ 160f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra public long getIdByKeySet(KeySet ks) { 161f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra synchronized (mLockObject) { 162f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return getIdByKeySetLocked(ks); 163f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 164f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 165f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 166f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra private long getIdByKeySetLocked(KeySet ks) { 167f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (int keySetIndex = 0; keySetIndex < mKeySets.size(); keySetIndex++) { 168f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra KeySet value = mKeySets.valueAt(keySetIndex); 169f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (ks.equals(value)) { 170f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return mKeySets.keyAt(keySetIndex); 171f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 172f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 173f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return KEYSET_NOT_FOUND; 174f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 175f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 1762042e9df4855ef59e3329b548b208279a88d7adbKenny Root /** 177f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Fetches the KeySet corresponding to the given stable identifier. 178f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * 1792042e9df4855ef59e3329b548b208279a88d7adbKenny Root * Returns {@link #KEYSET_NOT_FOUND} if the identifier doesn't 1802042e9df4855ef59e3329b548b208279a88d7adbKenny Root * identify a {@link KeySet}. 181f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra */ 182f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra public KeySet getKeySetById(long id) { 183f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra synchronized (mLockObject) { 184f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return mKeySets.get(id); 185f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 186f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 187f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 1882042e9df4855ef59e3329b548b208279a88d7adbKenny Root /** 189f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Fetches the KeySet that a given package refers to by the provided alias. 190f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * 191f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * If the package isn't known to us, throws an IllegalArgumentException. 192f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Returns null if the alias isn't known to us. 193f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra */ 194f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra public KeySet getKeySetByAliasAndPackageName(String packageName, String alias) { 195f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra synchronized (mLockObject) { 196f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra PackageSetting p = mPackages.get(packageName); 197f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (p == null) { 198f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throw new NullPointerException("Unknown package"); 199f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 200f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (p.keySetData == null) { 201f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throw new IllegalArgumentException("Package has no keySet data"); 202f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 203f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra long keySetId = p.keySetData.getAliases().get(alias); 204f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return mKeySets.get(keySetId); 205f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 206f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 207f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 2082042e9df4855ef59e3329b548b208279a88d7adbKenny Root /** 2092042e9df4855ef59e3329b548b208279a88d7adbKenny Root * Fetches all the known {@link KeySet KeySets} that signed the given 2102042e9df4855ef59e3329b548b208279a88d7adbKenny Root * package. Returns {@code null} if package is unknown. 211f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra */ 212f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra public Set<KeySet> getSigningKeySetsByPackageName(String packageName) { 213f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra synchronized (mLockObject) { 214f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra Set<KeySet> signingKeySets = new HashSet<KeySet>(); 215f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra PackageSetting p = mPackages.get(packageName); 216f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (p == null) { 217f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throw new NullPointerException("Unknown package"); 218f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 219f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (p.keySetData == null) { 220f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throw new IllegalArgumentException("Package has no keySet data"); 221f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 222f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (long l : p.keySetData.getSigningKeySets()) { 223f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra signingKeySets.add(mKeySets.get(l)); 224f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 225f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return signingKeySets; 226f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 227f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 228f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 2292042e9df4855ef59e3329b548b208279a88d7adbKenny Root /** 230f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Creates a new KeySet corresponding to the given keys. 231f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * 2322042e9df4855ef59e3329b548b208279a88d7adbKenny Root * If the {@link PublicKey PublicKeys} aren't known to the system, this 2332042e9df4855ef59e3329b548b208279a88d7adbKenny Root * adds them. Otherwise, they're deduped. 234f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * 235f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * If the KeySet isn't known to the system, this adds that and creates the 236f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * mapping to the PublicKeys. If it is known, then it's deduped. 237f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * 2382042e9df4855ef59e3329b548b208279a88d7adbKenny Root * Throws if the provided set is {@code null}. 239f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra */ 240f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra private KeySet addKeySetLocked(Set<PublicKey> keys) { 241f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (keys == null) { 242f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throw new NullPointerException("Provided keys cannot be null"); 243f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 244f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // add each of the keys in the provided set 245f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra Set<Long> addedKeyIds = new HashSet<Long>(keys.size()); 246f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (PublicKey k : keys) { 247f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra long id = addPublicKeyLocked(k); 248f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra addedKeyIds.add(id); 249f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 250f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 251f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // check to see if the resulting keyset is new 252f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra long existingKeySetId = getIdFromKeyIdsLocked(addedKeyIds); 253f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (existingKeySetId != KEYSET_NOT_FOUND) { 254f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return mKeySets.get(existingKeySetId); 255f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 256f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 257f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // create the KeySet object 258f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra KeySet ks = new KeySet(new Binder()); 259f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // get the first unoccupied slot in mKeySets 260f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra long id = getFreeKeySetIDLocked(); 261f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // add the KeySet object to it 262f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra mKeySets.put(id, ks); 263f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // add the stable key ids to the mapping 264f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra mKeySetMapping.put(id, addedKeyIds); 265f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // go home 266f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return ks; 267f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 268f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 2692042e9df4855ef59e3329b548b208279a88d7adbKenny Root /** 270f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Adds the given PublicKey to the system, deduping as it goes. 271f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra */ 272f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra private long addPublicKeyLocked(PublicKey key) { 273f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // check if the public key is new 274f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra long existingKeyId = getIdForPublicKeyLocked(key); 275f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (existingKeyId != PUBLIC_KEY_NOT_FOUND) { 276f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return existingKeyId; 277f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 278f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // if it's new find the first unoccupied slot in the public keys 279f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra long id = getFreePublicKeyIdLocked(); 280f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // add the public key to it 281f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra mPublicKeys.put(id, key); 282f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // return the stable identifier 283f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return id; 284f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 285f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 2862042e9df4855ef59e3329b548b208279a88d7adbKenny Root /** 287f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Finds the stable identifier for a KeySet based on a set of PublicKey stable IDs. 288f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * 289f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Returns KEYSET_NOT_FOUND if there isn't one. 290f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra */ 291f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra private long getIdFromKeyIdsLocked(Set<Long> publicKeyIds) { 292f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (int keyMapIndex = 0; keyMapIndex < mKeySetMapping.size(); keyMapIndex++) { 293f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra Set<Long> value = mKeySetMapping.valueAt(keyMapIndex); 294f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (value.equals(publicKeyIds)) { 295f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return mKeySetMapping.keyAt(keyMapIndex); 296f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 297f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 298f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return KEYSET_NOT_FOUND; 299f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 300f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 3012042e9df4855ef59e3329b548b208279a88d7adbKenny Root /** 302f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Finds the stable identifier for a PublicKey or PUBLIC_KEY_NOT_FOUND. 303f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra */ 304f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra private long getIdForPublicKeyLocked(PublicKey k) { 305f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra String encodedPublicKey = new String(k.getEncoded()); 306f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (int publicKeyIndex = 0; publicKeyIndex < mPublicKeys.size(); publicKeyIndex++) { 307f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra PublicKey value = mPublicKeys.valueAt(publicKeyIndex); 308f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra String encodedExistingKey = new String(value.getEncoded()); 309f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (encodedPublicKey.equals(encodedExistingKey)) { 310f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return mPublicKeys.keyAt(publicKeyIndex); 311f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 312f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 313f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return PUBLIC_KEY_NOT_FOUND; 314f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 315f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 3162042e9df4855ef59e3329b548b208279a88d7adbKenny Root /** 317f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Gets an unused stable identifier for a KeySet. 318f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra */ 319f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra private long getFreeKeySetIDLocked() { 320f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra lastIssuedKeySetId += 1; 321f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return lastIssuedKeySetId; 322f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 323f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 3242042e9df4855ef59e3329b548b208279a88d7adbKenny Root /** 325f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra * Same as above, but for public keys. 326f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra */ 327f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra private long getFreePublicKeyIdLocked() { 328f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra lastIssuedKeyId += 1; 329f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return lastIssuedKeyId; 330f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 331f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 332f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra public void removeAppKeySetData(String packageName) { 333f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra synchronized (mLockObject) { 334f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // Get the package's known keys and KeySets 335cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra Set<Long> deletableKeySets = getKnownKeySetsByPackageNameLocked(packageName); 336f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra Set<Long> deletableKeys = new HashSet<Long>(); 337cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra Set<Long> knownKeys = null; 338f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (Long ks : deletableKeySets) { 339cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra knownKeys = mKeySetMapping.get(ks); 340cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra if (knownKeys != null) { 341cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra deletableKeys.addAll(knownKeys); 342cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra } 343f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 344f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 345f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // Now remove the keys and KeySets known to any other package 346f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (String pkgName : mPackages.keySet()) { 347f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (pkgName.equals(packageName)) { 348f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra continue; 349f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 350cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra Set<Long> knownKeySets = getKnownKeySetsByPackageNameLocked(pkgName); 351f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra deletableKeySets.removeAll(knownKeySets); 352cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra knownKeys = new HashSet<Long>(); 353f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (Long ks : knownKeySets) { 354cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra knownKeys = mKeySetMapping.get(ks); 355cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra if (knownKeys != null) { 356cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra deletableKeys.removeAll(knownKeys); 357cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra } 358f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 359f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 360f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 361f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // The remaining keys and KeySets are not known to any other 362f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra // application and so can be safely deleted. 363f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (Long ks : deletableKeySets) { 364f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra mKeySets.delete(ks); 365f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra mKeySetMapping.delete(ks); 366f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 367f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (Long keyId : deletableKeys) { 368f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra mPublicKeys.delete(keyId); 369f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 370cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra 371cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra // Now remove them from the KeySets known to each package 372cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra for (String pkgName : mPackages.keySet()) { 37392179bc261cf9ff216f10a9adf64088ed76675cbKenny Root PackageSetting p = mPackages.get(pkgName); 374cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra for (Long ks : deletableKeySets) { 375cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra p.keySetData.removeSigningKeySet(ks); 376cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra p.keySetData.removeDefinedKeySet(ks); 377cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra } 378cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra } 379f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 380f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 381f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 382cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra private Set<Long> getKnownKeySetsByPackageNameLocked(String packageName) { 383f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra PackageSetting p = mPackages.get(packageName); 384f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (p == null) { 385f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throw new NullPointerException("Unknown package"); 386f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 387f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (p.keySetData == null) { 388f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throw new IllegalArgumentException("Package has no keySet data"); 389f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 390f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra Set<Long> knownKeySets = new HashSet<Long>(); 391cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra for (long ks : p.keySetData.getSigningKeySets()) { 392f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra knownKeySets.add(ks); 393f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 394cdb5789022791f5557e4915f9be4dc5e6dd8b46eGeremy Condra for (long ks : p.keySetData.getDefinedKeySets()) { 395f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra knownKeySets.add(ks); 396f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 397f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return knownKeySets; 398f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 399f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 400f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra public String encodePublicKey(PublicKey k) throws IOException { 401f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return new String(Base64.encode(k.getEncoded(), 0)); 402f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 403f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 404cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn public void dump(PrintWriter pw, String packageName, 405cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn PackageManagerService.DumpState dumpState) { 406f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra synchronized (mLockObject) { 407cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn boolean printedHeader = false; 408f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (Map.Entry<String, PackageSetting> e : mPackages.entrySet()) { 409cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn String keySetPackage = e.getKey(); 410cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn if (packageName != null && !packageName.equals(keySetPackage)) { 411cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn continue; 412cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn } 413cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn if (!printedHeader) { 414cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn if (dumpState.onTitlePrinted()) 415cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn pw.println(); 416cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn pw.println("Key Set Manager:"); 417cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn printedHeader = true; 418cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn } 419f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra PackageSetting pkg = e.getValue(); 420cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn pw.print(" ["); pw.print(keySetPackage); pw.println("]"); 421f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (pkg.keySetData != null) { 422cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn boolean printedLabel = false; 423fb236b56d23fa563880f98ec3fc484723235296cYing Wang for (Map.Entry<String, Long> entry : pkg.keySetData.getAliases().entrySet()) { 424df0e6abd9f5863740942a1da12685f261016a8e1Kenny Root if (!printedLabel) { 425df0e6abd9f5863740942a1da12685f261016a8e1Kenny Root pw.print(" KeySets Aliases: "); 426df0e6abd9f5863740942a1da12685f261016a8e1Kenny Root printedLabel = true; 427df0e6abd9f5863740942a1da12685f261016a8e1Kenny Root } else { 428df0e6abd9f5863740942a1da12685f261016a8e1Kenny Root pw.print(", "); 429df0e6abd9f5863740942a1da12685f261016a8e1Kenny Root } 430df0e6abd9f5863740942a1da12685f261016a8e1Kenny Root pw.print(entry.getKey()); 431df0e6abd9f5863740942a1da12685f261016a8e1Kenny Root pw.print('='); 432df0e6abd9f5863740942a1da12685f261016a8e1Kenny Root pw.print(Long.toString(entry.getValue())); 433df0e6abd9f5863740942a1da12685f261016a8e1Kenny Root } 434df0e6abd9f5863740942a1da12685f261016a8e1Kenny Root if (printedLabel) { 435df0e6abd9f5863740942a1da12685f261016a8e1Kenny Root pw.println(""); 436df0e6abd9f5863740942a1da12685f261016a8e1Kenny Root } 437df0e6abd9f5863740942a1da12685f261016a8e1Kenny Root printedLabel = false; 438f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (long keySetId : pkg.keySetData.getDefinedKeySets()) { 439cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn if (!printedLabel) { 440cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn pw.print(" Defined KeySets: "); 441cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn printedLabel = true; 442cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn } else { 443cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn pw.print(", "); 444cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn } 445cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn pw.print(Long.toString(keySetId)); 446cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn } 447cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn if (printedLabel) { 448cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn pw.println(""); 449f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 450cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn printedLabel = false; 451f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (long keySetId : pkg.keySetData.getSigningKeySets()) { 452cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn if (!printedLabel) { 453df0e6abd9f5863740942a1da12685f261016a8e1Kenny Root pw.print(" Signing KeySets: "); 454cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn printedLabel = true; 455cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn } else { 456cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn pw.print(", "); 457cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn } 458df0e6abd9f5863740942a1da12685f261016a8e1Kenny Root pw.print(Long.toString(keySetId)); 459f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 460cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn if (printedLabel) { 461cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn pw.println(""); 462cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn } 463f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 464f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 465f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 466f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 467f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 468f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra void writeKeySetManagerLPr(XmlSerializer serializer) throws IOException { 469f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.startTag(null, "keyset-settings"); 470f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra writePublicKeysLPr(serializer); 471f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra writeKeySetsLPr(serializer); 472f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.startTag(null, "lastIssuedKeyId"); 473f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.attribute(null, "value", Long.toString(lastIssuedKeyId)); 474f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.endTag(null, "lastIssuedKeyId"); 475f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.startTag(null, "lastIssuedKeySetId"); 476f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.attribute(null, "value", Long.toString(lastIssuedKeySetId)); 477f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.endTag(null, "lastIssuedKeySetId"); 478f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.endTag(null, "keyset-settings"); 479f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 480f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 481f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra void writePublicKeysLPr(XmlSerializer serializer) throws IOException { 482f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.startTag(null, "keys"); 483f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (int pKeyIndex = 0; pKeyIndex < mPublicKeys.size(); pKeyIndex++) { 484f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra long id = mPublicKeys.keyAt(pKeyIndex); 485f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra PublicKey key = mPublicKeys.valueAt(pKeyIndex); 486f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra String encodedKey = encodePublicKey(key); 487f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.startTag(null, "public-key"); 488f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.attribute(null, "identifier", Long.toString(id)); 489f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.attribute(null, "value", encodedKey); 490f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.endTag(null, "public-key"); 491f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 492f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.endTag(null, "keys"); 493f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 494f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 495f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra void writeKeySetsLPr(XmlSerializer serializer) throws IOException { 496f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.startTag(null, "keysets"); 497f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (int keySetIndex = 0; keySetIndex < mKeySetMapping.size(); keySetIndex++) { 498f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra long id = mKeySetMapping.keyAt(keySetIndex); 499f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra Set<Long> keys = mKeySetMapping.valueAt(keySetIndex); 500f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.startTag(null, "keyset"); 501f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.attribute(null, "identifier", Long.toString(id)); 502f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra for (long keyId : keys) { 503f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.startTag(null, "key-id"); 504f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.attribute(null, "identifier", Long.toString(keyId)); 505f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.endTag(null, "key-id"); 506f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 507f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.endTag(null, "keyset"); 508f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 509f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra serializer.endTag(null, "keysets"); 510f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 511f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 512f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra void readKeySetsLPw(XmlPullParser parser) 513f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throws XmlPullParserException, IOException { 514f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra int type; 515f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra long currentKeySetId = 0; 516f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { 517f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 518f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra continue; 519f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 520f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra final String tagName = parser.getName(); 521f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (tagName.equals("keys")) { 522f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra readKeysLPw(parser); 523f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } else if (tagName.equals("keysets")) { 524f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra readKeySetListLPw(parser); 525f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 526f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 527f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 528f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 529f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra void readKeysLPw(XmlPullParser parser) 530f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throws XmlPullParserException, IOException { 531f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra int outerDepth = parser.getDepth(); 532f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra int type; 533f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 534f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 535f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 536f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra continue; 537f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 538f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra final String tagName = parser.getName(); 539f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (tagName.equals("public-key")) { 540f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra readPublicKeyLPw(parser); 541f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } else if (tagName.equals("lastIssuedKeyId")) { 542f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra lastIssuedKeyId = Long.parseLong(parser.getAttributeValue(null, "value")); 543f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } else if (tagName.equals("lastIssuedKeySetId")) { 544f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra lastIssuedKeySetId = Long.parseLong(parser.getAttributeValue(null, "value")); 545f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 546f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 547f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 548f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 549f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra void readKeySetListLPw(XmlPullParser parser) 550f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throws XmlPullParserException, IOException { 551f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra int outerDepth = parser.getDepth(); 552f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra int type; 553f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra long currentKeySetId = 0; 554f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 555f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 556f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 557f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra continue; 558f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 559f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra final String tagName = parser.getName(); 560f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra if (tagName.equals("keyset")) { 561f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra currentKeySetId = readIdentifierLPw(parser); 562f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra mKeySets.put(currentKeySetId, new KeySet(new Binder())); 563f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra mKeySetMapping.put(currentKeySetId, new HashSet<Long>()); 564f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } else if (tagName.equals("key-id")) { 565f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra long id = readIdentifierLPw(parser); 566f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra mKeySetMapping.get(currentKeySetId).add(id); 567f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 568f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 569f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 570f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 571f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra long readIdentifierLPw(XmlPullParser parser) 572f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throws XmlPullParserException { 573f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra return Long.parseLong(parser.getAttributeValue(null, "identifier")); 574f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 575f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra 576f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra void readPublicKeyLPw(XmlPullParser parser) 577f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra throws XmlPullParserException { 578f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra String encodedID = parser.getAttributeValue(null, "identifier"); 579f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra long identifier = Long.parseLong(encodedID); 580f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra String encodedPublicKey = parser.getAttributeValue(null, "value"); 581f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra PublicKey pub = PackageParser.parsePublicKey(encodedPublicKey); 582a2d8eae2892e215a63ec5a1261e53a8a6a57d397Geremy Condra if (pub != null) { 583f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra mPublicKeys.put(identifier, pub); 584f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 585f1bcca82158c39da3c3696f9af954be2c0be1809Geremy Condra } 586fb236b56d23fa563880f98ec3fc484723235296cYing Wang} 587