blob: 93992c21f328523b780bc2e531a43c66a3d7696b [file] [log] [blame]
Geremy Condraf1bcca82013-01-07 22:35:24 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm;
18
19import android.content.pm.KeySet;
20import android.content.pm.PackageParser;
21import android.os.Binder;
22import android.util.Base64;
23import android.util.Log;
24import android.util.LongSparseArray;
25
26import java.io.IOException;
27import java.io.PrintWriter;
28import java.security.PublicKey;
29import java.util.HashMap;
30import java.util.HashSet;
31import java.util.Map;
32import java.util.Set;
33
34import org.xmlpull.v1.XmlPullParser;
35import org.xmlpull.v1.XmlPullParserException;
36import org.xmlpull.v1.XmlSerializer;
37
38/*
39 * Manages system-wide KeySet state.
40 */
41public class KeySetManager {
42
43 static final String TAG = "KeySetManager";
44
Kenny Root9a995f52013-07-08 09:33:22 -070045 /** Sentinel value returned when a {@code KeySet} is not found. */
46 public static final long KEYSET_NOT_FOUND = -1;
47
48 /** Sentinel value returned when public key is not found. */
Geremy Condraf1bcca82013-01-07 22:35:24 -080049 private static final long PUBLIC_KEY_NOT_FOUND = -1;
50
51 private final Object mLockObject = new Object();
52
53 private final LongSparseArray<KeySet> mKeySets;
54
55 private final LongSparseArray<PublicKey> mPublicKeys;
56
57 private final LongSparseArray<Set<Long>> mKeySetMapping;
58
59 private final Map<String, PackageSetting> mPackages;
60
61 private static long lastIssuedKeySetId = 0;
62
63 private static long lastIssuedKeyId = 0;
64
65 public KeySetManager(Map<String, PackageSetting> packages) {
66 mKeySets = new LongSparseArray<KeySet>();
67 mPublicKeys = new LongSparseArray<PublicKey>();
68 mKeySetMapping = new LongSparseArray<Set<Long>>();
69 mPackages = packages;
70 }
71
Kenny Root2042e9d2013-07-08 09:31:31 -070072 /**
Geremy Condraf1bcca82013-01-07 22:35:24 -080073 * Determine if a package is signed by the given KeySet.
74 *
75 * Returns false if the package was not signed by all the
76 * keys in the KeySet.
77 *
78 * Returns true if the package was signed by at least the
79 * keys in the given KeySet.
80 *
81 * Note that this can return true for multiple KeySets.
82 */
83 public boolean packageIsSignedBy(String packageName, KeySet ks) {
84 synchronized (mLockObject) {
85 PackageSetting pkg = mPackages.get(packageName);
86 if (pkg == null) {
87 throw new NullPointerException("Invalid package name");
88 }
89 if (pkg.keySetData == null) {
90 throw new NullPointerException("Package has no KeySet data");
91 }
92 long id = getIdByKeySetLocked(ks);
93 return pkg.keySetData.packageIsSignedBy(id);
94 }
95 }
96
Kenny Root2042e9d2013-07-08 09:31:31 -070097 /**
Geremy Condraf1bcca82013-01-07 22:35:24 -080098 * This informs the system that the given package has defined a KeySet
99 * in its manifest that a) contains the given keys and b) is named
100 * alias by that package.
101 */
102 public void addDefinedKeySetToPackage(String packageName,
103 Set<PublicKey> keys, String alias) {
104 if ((packageName == null) || (keys == null) || (alias == null)) {
Geremy Condrabf7b1f42013-06-18 10:38:27 -0700105 Log.d(TAG, "Got null argument for a defined keyset, ignoring!");
Geremy Condraf1bcca82013-01-07 22:35:24 -0800106 return;
107 }
108 synchronized (mLockObject) {
109 KeySet ks = addKeySetLocked(keys);
110 PackageSetting pkg = mPackages.get(packageName);
111 if (pkg == null) {
112 throw new NullPointerException("Unknown package");
113 }
114 long id = getIdByKeySetLocked(ks);
115 pkg.keySetData.addDefinedKeySet(id, alias);
116 }
117 }
118
Kenny Root2042e9d2013-07-08 09:31:31 -0700119 /**
Geremy Condraf1bcca82013-01-07 22:35:24 -0800120 * Similar to the above, this informs the system that the given package
121 * was signed by the provided KeySet.
122 */
123 public void addSigningKeySetToPackage(String packageName,
124 Set<PublicKey> signingKeys) {
125 if ((packageName == null) || (signingKeys == null)) {
Geremy Condrabf7b1f42013-06-18 10:38:27 -0700126 Log.d(TAG, "Got null argument for a signing keyset, ignoring!");
Geremy Condraf1bcca82013-01-07 22:35:24 -0800127 return;
128 }
129 synchronized (mLockObject) {
130 // add the signing KeySet
131 KeySet ks = addKeySetLocked(signingKeys);
132 long id = getIdByKeySetLocked(ks);
133 Set<Long> publicKeyIds = mKeySetMapping.get(id);
134 if (publicKeyIds == null) {
135 throw new NullPointerException("Got invalid KeySet id");
136 }
137
138 // attach it to the package
139 PackageSetting pkg = mPackages.get(packageName);
140 if (pkg == null) {
141 throw new NullPointerException("No such package!");
142 }
143 pkg.keySetData.addSigningKeySet(id);
144
145 // for each KeySet the package defines which is a subset of
146 // the one above, add the KeySet id to the package's signing KeySets
147 for (Long keySetID : pkg.keySetData.getDefinedKeySets()) {
148 Set<Long> definedKeys = mKeySetMapping.get(keySetID);
149 if (publicKeyIds.contains(definedKeys)) {
150 pkg.keySetData.addSigningKeySet(keySetID);
151 }
152 }
153 }
154 }
155
Kenny Root2042e9d2013-07-08 09:31:31 -0700156 /**
157 * Fetches the stable identifier associated with the given KeySet. Returns
158 * {@link #KEYSET_NOT_FOUND} if the KeySet... wasn't found.
Geremy Condraf1bcca82013-01-07 22:35:24 -0800159 */
160 public long getIdByKeySet(KeySet ks) {
161 synchronized (mLockObject) {
162 return getIdByKeySetLocked(ks);
163 }
164 }
165
166 private long getIdByKeySetLocked(KeySet ks) {
167 for (int keySetIndex = 0; keySetIndex < mKeySets.size(); keySetIndex++) {
168 KeySet value = mKeySets.valueAt(keySetIndex);
169 if (ks.equals(value)) {
170 return mKeySets.keyAt(keySetIndex);
171 }
172 }
173 return KEYSET_NOT_FOUND;
174 }
175
Kenny Root2042e9d2013-07-08 09:31:31 -0700176 /**
Geremy Condraf1bcca82013-01-07 22:35:24 -0800177 * Fetches the KeySet corresponding to the given stable identifier.
178 *
Kenny Root2042e9d2013-07-08 09:31:31 -0700179 * Returns {@link #KEYSET_NOT_FOUND} if the identifier doesn't
180 * identify a {@link KeySet}.
Geremy Condraf1bcca82013-01-07 22:35:24 -0800181 */
182 public KeySet getKeySetById(long id) {
183 synchronized (mLockObject) {
184 return mKeySets.get(id);
185 }
186 }
187
Kenny Root2042e9d2013-07-08 09:31:31 -0700188 /**
Geremy Condraf1bcca82013-01-07 22:35:24 -0800189 * Fetches the KeySet that a given package refers to by the provided alias.
190 *
191 * If the package isn't known to us, throws an IllegalArgumentException.
192 * Returns null if the alias isn't known to us.
193 */
194 public KeySet getKeySetByAliasAndPackageName(String packageName, String alias) {
195 synchronized (mLockObject) {
196 PackageSetting p = mPackages.get(packageName);
197 if (p == null) {
198 throw new NullPointerException("Unknown package");
199 }
200 if (p.keySetData == null) {
201 throw new IllegalArgumentException("Package has no keySet data");
202 }
203 long keySetId = p.keySetData.getAliases().get(alias);
204 return mKeySets.get(keySetId);
205 }
206 }
207
Kenny Root2042e9d2013-07-08 09:31:31 -0700208 /**
209 * Fetches all the known {@link KeySet KeySets} that signed the given
210 * package. Returns {@code null} if package is unknown.
Geremy Condraf1bcca82013-01-07 22:35:24 -0800211 */
212 public Set<KeySet> getSigningKeySetsByPackageName(String packageName) {
213 synchronized (mLockObject) {
214 Set<KeySet> signingKeySets = new HashSet<KeySet>();
215 PackageSetting p = mPackages.get(packageName);
216 if (p == null) {
217 throw new NullPointerException("Unknown package");
218 }
219 if (p.keySetData == null) {
220 throw new IllegalArgumentException("Package has no keySet data");
221 }
222 for (long l : p.keySetData.getSigningKeySets()) {
223 signingKeySets.add(mKeySets.get(l));
224 }
225 return signingKeySets;
226 }
227 }
228
Kenny Root2042e9d2013-07-08 09:31:31 -0700229 /**
Geremy Condraf1bcca82013-01-07 22:35:24 -0800230 * Creates a new KeySet corresponding to the given keys.
231 *
Kenny Root2042e9d2013-07-08 09:31:31 -0700232 * If the {@link PublicKey PublicKeys} aren't known to the system, this
233 * adds them. Otherwise, they're deduped.
Geremy Condraf1bcca82013-01-07 22:35:24 -0800234 *
235 * If the KeySet isn't known to the system, this adds that and creates the
236 * mapping to the PublicKeys. If it is known, then it's deduped.
237 *
Kenny Root2042e9d2013-07-08 09:31:31 -0700238 * Throws if the provided set is {@code null}.
Geremy Condraf1bcca82013-01-07 22:35:24 -0800239 */
240 private KeySet addKeySetLocked(Set<PublicKey> keys) {
241 if (keys == null) {
242 throw new NullPointerException("Provided keys cannot be null");
243 }
244 // add each of the keys in the provided set
245 Set<Long> addedKeyIds = new HashSet<Long>(keys.size());
246 for (PublicKey k : keys) {
247 long id = addPublicKeyLocked(k);
248 addedKeyIds.add(id);
249 }
250
251 // check to see if the resulting keyset is new
252 long existingKeySetId = getIdFromKeyIdsLocked(addedKeyIds);
253 if (existingKeySetId != KEYSET_NOT_FOUND) {
254 return mKeySets.get(existingKeySetId);
255 }
256
257 // create the KeySet object
258 KeySet ks = new KeySet(new Binder());
259 // get the first unoccupied slot in mKeySets
260 long id = getFreeKeySetIDLocked();
261 // add the KeySet object to it
262 mKeySets.put(id, ks);
263 // add the stable key ids to the mapping
264 mKeySetMapping.put(id, addedKeyIds);
265 // go home
266 return ks;
267 }
268
Kenny Root2042e9d2013-07-08 09:31:31 -0700269 /**
Geremy Condraf1bcca82013-01-07 22:35:24 -0800270 * Adds the given PublicKey to the system, deduping as it goes.
271 */
272 private long addPublicKeyLocked(PublicKey key) {
273 // check if the public key is new
274 long existingKeyId = getIdForPublicKeyLocked(key);
275 if (existingKeyId != PUBLIC_KEY_NOT_FOUND) {
276 return existingKeyId;
277 }
278 // if it's new find the first unoccupied slot in the public keys
279 long id = getFreePublicKeyIdLocked();
280 // add the public key to it
281 mPublicKeys.put(id, key);
282 // return the stable identifier
283 return id;
284 }
285
Kenny Root2042e9d2013-07-08 09:31:31 -0700286 /**
Geremy Condraf1bcca82013-01-07 22:35:24 -0800287 * Finds the stable identifier for a KeySet based on a set of PublicKey stable IDs.
288 *
289 * Returns KEYSET_NOT_FOUND if there isn't one.
290 */
291 private long getIdFromKeyIdsLocked(Set<Long> publicKeyIds) {
292 for (int keyMapIndex = 0; keyMapIndex < mKeySetMapping.size(); keyMapIndex++) {
293 Set<Long> value = mKeySetMapping.valueAt(keyMapIndex);
294 if (value.equals(publicKeyIds)) {
295 return mKeySetMapping.keyAt(keyMapIndex);
296 }
297 }
298 return KEYSET_NOT_FOUND;
299 }
300
Kenny Root2042e9d2013-07-08 09:31:31 -0700301 /**
Geremy Condraf1bcca82013-01-07 22:35:24 -0800302 * Finds the stable identifier for a PublicKey or PUBLIC_KEY_NOT_FOUND.
303 */
304 private long getIdForPublicKeyLocked(PublicKey k) {
305 String encodedPublicKey = new String(k.getEncoded());
306 for (int publicKeyIndex = 0; publicKeyIndex < mPublicKeys.size(); publicKeyIndex++) {
307 PublicKey value = mPublicKeys.valueAt(publicKeyIndex);
308 String encodedExistingKey = new String(value.getEncoded());
309 if (encodedPublicKey.equals(encodedExistingKey)) {
310 return mPublicKeys.keyAt(publicKeyIndex);
311 }
312 }
313 return PUBLIC_KEY_NOT_FOUND;
314 }
315
Kenny Root2042e9d2013-07-08 09:31:31 -0700316 /**
Geremy Condraf1bcca82013-01-07 22:35:24 -0800317 * Gets an unused stable identifier for a KeySet.
318 */
319 private long getFreeKeySetIDLocked() {
320 lastIssuedKeySetId += 1;
321 return lastIssuedKeySetId;
322 }
323
Kenny Root2042e9d2013-07-08 09:31:31 -0700324 /**
Geremy Condraf1bcca82013-01-07 22:35:24 -0800325 * Same as above, but for public keys.
326 */
327 private long getFreePublicKeyIdLocked() {
328 lastIssuedKeyId += 1;
329 return lastIssuedKeyId;
330 }
331
332 public void removeAppKeySetData(String packageName) {
Geremy Condraf1bcca82013-01-07 22:35:24 -0800333 synchronized (mLockObject) {
334 // Get the package's known keys and KeySets
Geremy Condracdb57892013-03-26 16:22:36 -0700335 Set<Long> deletableKeySets = getKnownKeySetsByPackageNameLocked(packageName);
Geremy Condraf1bcca82013-01-07 22:35:24 -0800336 Set<Long> deletableKeys = new HashSet<Long>();
Geremy Condracdb57892013-03-26 16:22:36 -0700337 Set<Long> knownKeys = null;
Geremy Condraf1bcca82013-01-07 22:35:24 -0800338 for (Long ks : deletableKeySets) {
Geremy Condracdb57892013-03-26 16:22:36 -0700339 knownKeys = mKeySetMapping.get(ks);
340 if (knownKeys != null) {
341 deletableKeys.addAll(knownKeys);
342 }
Geremy Condraf1bcca82013-01-07 22:35:24 -0800343 }
344
345 // Now remove the keys and KeySets known to any other package
346 for (String pkgName : mPackages.keySet()) {
347 if (pkgName.equals(packageName)) {
348 continue;
349 }
Geremy Condracdb57892013-03-26 16:22:36 -0700350 Set<Long> knownKeySets = getKnownKeySetsByPackageNameLocked(pkgName);
Geremy Condraf1bcca82013-01-07 22:35:24 -0800351 deletableKeySets.removeAll(knownKeySets);
Geremy Condracdb57892013-03-26 16:22:36 -0700352 knownKeys = new HashSet<Long>();
Geremy Condraf1bcca82013-01-07 22:35:24 -0800353 for (Long ks : knownKeySets) {
Geremy Condracdb57892013-03-26 16:22:36 -0700354 knownKeys = mKeySetMapping.get(ks);
355 if (knownKeys != null) {
356 deletableKeys.removeAll(knownKeys);
357 }
Geremy Condraf1bcca82013-01-07 22:35:24 -0800358 }
359 }
360
361 // The remaining keys and KeySets are not known to any other
362 // application and so can be safely deleted.
363 for (Long ks : deletableKeySets) {
364 mKeySets.delete(ks);
365 mKeySetMapping.delete(ks);
366 }
367 for (Long keyId : deletableKeys) {
368 mPublicKeys.delete(keyId);
369 }
Geremy Condracdb57892013-03-26 16:22:36 -0700370
371 // Now remove them from the KeySets known to each package
372 for (String pkgName : mPackages.keySet()) {
Kenny Root92179bc2013-07-02 11:55:27 -0700373 PackageSetting p = mPackages.get(pkgName);
Geremy Condracdb57892013-03-26 16:22:36 -0700374 for (Long ks : deletableKeySets) {
375 p.keySetData.removeSigningKeySet(ks);
376 p.keySetData.removeDefinedKeySet(ks);
377 }
378 }
Geremy Condraf1bcca82013-01-07 22:35:24 -0800379 }
380 }
381
Geremy Condracdb57892013-03-26 16:22:36 -0700382 private Set<Long> getKnownKeySetsByPackageNameLocked(String packageName) {
Geremy Condraf1bcca82013-01-07 22:35:24 -0800383 PackageSetting p = mPackages.get(packageName);
384 if (p == null) {
385 throw new NullPointerException("Unknown package");
386 }
387 if (p.keySetData == null) {
388 throw new IllegalArgumentException("Package has no keySet data");
389 }
390 Set<Long> knownKeySets = new HashSet<Long>();
Geremy Condracdb57892013-03-26 16:22:36 -0700391 for (long ks : p.keySetData.getSigningKeySets()) {
Geremy Condraf1bcca82013-01-07 22:35:24 -0800392 knownKeySets.add(ks);
393 }
Geremy Condracdb57892013-03-26 16:22:36 -0700394 for (long ks : p.keySetData.getDefinedKeySets()) {
Geremy Condraf1bcca82013-01-07 22:35:24 -0800395 knownKeySets.add(ks);
396 }
397 return knownKeySets;
398 }
399
400 public String encodePublicKey(PublicKey k) throws IOException {
401 return new String(Base64.encode(k.getEncoded(), 0));
402 }
403
Dianne Hackborncbfd23e2013-06-11 14:26:53 -0700404 public void dump(PrintWriter pw, String packageName,
405 PackageManagerService.DumpState dumpState) {
Geremy Condraf1bcca82013-01-07 22:35:24 -0800406 synchronized (mLockObject) {
Dianne Hackborncbfd23e2013-06-11 14:26:53 -0700407 boolean printedHeader = false;
Geremy Condraf1bcca82013-01-07 22:35:24 -0800408 for (Map.Entry<String, PackageSetting> e : mPackages.entrySet()) {
Dianne Hackborncbfd23e2013-06-11 14:26:53 -0700409 String keySetPackage = e.getKey();
410 if (packageName != null && !packageName.equals(keySetPackage)) {
411 continue;
412 }
413 if (!printedHeader) {
414 if (dumpState.onTitlePrinted())
415 pw.println();
416 pw.println("Key Set Manager:");
417 printedHeader = true;
418 }
Geremy Condraf1bcca82013-01-07 22:35:24 -0800419 PackageSetting pkg = e.getValue();
Dianne Hackborncbfd23e2013-06-11 14:26:53 -0700420 pw.print(" ["); pw.print(keySetPackage); pw.println("]");
Geremy Condraf1bcca82013-01-07 22:35:24 -0800421 if (pkg.keySetData != null) {
Dianne Hackborncbfd23e2013-06-11 14:26:53 -0700422 boolean printedLabel = false;
Ying Wangfb236b52013-07-08 10:53:58 -0700423 for (Map.Entry<String, Long> entry : pkg.keySetData.getAliases().entrySet()) {
Kenny Rootdf0e6ab2013-07-03 13:38:31 -0700424 if (!printedLabel) {
425 pw.print(" KeySets Aliases: ");
426 printedLabel = true;
427 } else {
428 pw.print(", ");
429 }
430 pw.print(entry.getKey());
431 pw.print('=');
432 pw.print(Long.toString(entry.getValue()));
433 }
434 if (printedLabel) {
435 pw.println("");
436 }
437 printedLabel = false;
Geremy Condraf1bcca82013-01-07 22:35:24 -0800438 for (long keySetId : pkg.keySetData.getDefinedKeySets()) {
Dianne Hackborncbfd23e2013-06-11 14:26:53 -0700439 if (!printedLabel) {
440 pw.print(" Defined KeySets: ");
441 printedLabel = true;
442 } else {
443 pw.print(", ");
444 }
445 pw.print(Long.toString(keySetId));
Geremy Condraf1bcca82013-01-07 22:35:24 -0800446 }
Dianne Hackborncbfd23e2013-06-11 14:26:53 -0700447 if (printedLabel) {
448 pw.println("");
449 }
450 printedLabel = false;
Geremy Condraf1bcca82013-01-07 22:35:24 -0800451 for (long keySetId : pkg.keySetData.getSigningKeySets()) {
Dianne Hackborncbfd23e2013-06-11 14:26:53 -0700452 if (!printedLabel) {
Kenny Rootdf0e6ab2013-07-03 13:38:31 -0700453 pw.print(" Signing KeySets: ");
Dianne Hackborncbfd23e2013-06-11 14:26:53 -0700454 printedLabel = true;
455 } else {
456 pw.print(", ");
457 }
Kenny Rootdf0e6ab2013-07-03 13:38:31 -0700458 pw.print(Long.toString(keySetId));
Geremy Condraf1bcca82013-01-07 22:35:24 -0800459 }
Dianne Hackborncbfd23e2013-06-11 14:26:53 -0700460 if (printedLabel) {
461 pw.println("");
462 }
Geremy Condraf1bcca82013-01-07 22:35:24 -0800463 }
464 }
465 }
466 }
467
468 void writeKeySetManagerLPr(XmlSerializer serializer) throws IOException {
469 serializer.startTag(null, "keyset-settings");
470 writePublicKeysLPr(serializer);
471 writeKeySetsLPr(serializer);
472 serializer.startTag(null, "lastIssuedKeyId");
473 serializer.attribute(null, "value", Long.toString(lastIssuedKeyId));
474 serializer.endTag(null, "lastIssuedKeyId");
475 serializer.startTag(null, "lastIssuedKeySetId");
476 serializer.attribute(null, "value", Long.toString(lastIssuedKeySetId));
477 serializer.endTag(null, "lastIssuedKeySetId");
478 serializer.endTag(null, "keyset-settings");
479 }
480
481 void writePublicKeysLPr(XmlSerializer serializer) throws IOException {
482 serializer.startTag(null, "keys");
483 for (int pKeyIndex = 0; pKeyIndex < mPublicKeys.size(); pKeyIndex++) {
484 long id = mPublicKeys.keyAt(pKeyIndex);
485 PublicKey key = mPublicKeys.valueAt(pKeyIndex);
486 String encodedKey = encodePublicKey(key);
487 serializer.startTag(null, "public-key");
488 serializer.attribute(null, "identifier", Long.toString(id));
489 serializer.attribute(null, "value", encodedKey);
490 serializer.endTag(null, "public-key");
491 }
492 serializer.endTag(null, "keys");
493 }
494
495 void writeKeySetsLPr(XmlSerializer serializer) throws IOException {
496 serializer.startTag(null, "keysets");
497 for (int keySetIndex = 0; keySetIndex < mKeySetMapping.size(); keySetIndex++) {
498 long id = mKeySetMapping.keyAt(keySetIndex);
499 Set<Long> keys = mKeySetMapping.valueAt(keySetIndex);
500 serializer.startTag(null, "keyset");
501 serializer.attribute(null, "identifier", Long.toString(id));
502 for (long keyId : keys) {
503 serializer.startTag(null, "key-id");
504 serializer.attribute(null, "identifier", Long.toString(keyId));
505 serializer.endTag(null, "key-id");
506 }
507 serializer.endTag(null, "keyset");
508 }
509 serializer.endTag(null, "keysets");
510 }
511
512 void readKeySetsLPw(XmlPullParser parser)
513 throws XmlPullParserException, IOException {
514 int type;
515 long currentKeySetId = 0;
516 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
517 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
518 continue;
519 }
520 final String tagName = parser.getName();
521 if (tagName.equals("keys")) {
522 readKeysLPw(parser);
523 } else if (tagName.equals("keysets")) {
524 readKeySetListLPw(parser);
Geremy Condraf1bcca82013-01-07 22:35:24 -0800525 }
526 }
527 }
528
529 void readKeysLPw(XmlPullParser parser)
530 throws XmlPullParserException, IOException {
531 int outerDepth = parser.getDepth();
532 int type;
533 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
534 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
535 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
536 continue;
537 }
538 final String tagName = parser.getName();
539 if (tagName.equals("public-key")) {
540 readPublicKeyLPw(parser);
541 } else if (tagName.equals("lastIssuedKeyId")) {
542 lastIssuedKeyId = Long.parseLong(parser.getAttributeValue(null, "value"));
543 } else if (tagName.equals("lastIssuedKeySetId")) {
544 lastIssuedKeySetId = Long.parseLong(parser.getAttributeValue(null, "value"));
Geremy Condraf1bcca82013-01-07 22:35:24 -0800545 }
546 }
547 }
548
549 void readKeySetListLPw(XmlPullParser parser)
550 throws XmlPullParserException, IOException {
551 int outerDepth = parser.getDepth();
552 int type;
553 long currentKeySetId = 0;
554 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
555 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
556 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
557 continue;
558 }
559 final String tagName = parser.getName();
560 if (tagName.equals("keyset")) {
561 currentKeySetId = readIdentifierLPw(parser);
562 mKeySets.put(currentKeySetId, new KeySet(new Binder()));
563 mKeySetMapping.put(currentKeySetId, new HashSet<Long>());
564 } else if (tagName.equals("key-id")) {
565 long id = readIdentifierLPw(parser);
566 mKeySetMapping.get(currentKeySetId).add(id);
Geremy Condraf1bcca82013-01-07 22:35:24 -0800567 }
568 }
569 }
570
571 long readIdentifierLPw(XmlPullParser parser)
572 throws XmlPullParserException {
573 return Long.parseLong(parser.getAttributeValue(null, "identifier"));
574 }
575
576 void readPublicKeyLPw(XmlPullParser parser)
577 throws XmlPullParserException {
578 String encodedID = parser.getAttributeValue(null, "identifier");
579 long identifier = Long.parseLong(encodedID);
580 String encodedPublicKey = parser.getAttributeValue(null, "value");
581 PublicKey pub = PackageParser.parsePublicKey(encodedPublicKey);
Geremy Condraa2d8eae2013-06-21 16:59:42 -0700582 if (pub != null) {
Geremy Condraf1bcca82013-01-07 22:35:24 -0800583 mPublicKeys.put(identifier, pub);
584 }
585 }
Ying Wangfb236b52013-07-08 10:53:58 -0700586}