KeySetManagerService.java revision 0888276a1c6cd4077770844615848674de21dab3
1/* 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.PackageParser; 20import android.os.Binder; 21import android.util.ArraySet; 22import android.util.Base64; 23import android.util.Slog; 24import android.util.LongSparseArray; 25 26import java.io.IOException; 27import java.io.PrintWriter; 28import java.security.PublicKey; 29import java.util.Map; 30import java.util.Set; 31 32import org.xmlpull.v1.XmlPullParser; 33import org.xmlpull.v1.XmlPullParserException; 34import org.xmlpull.v1.XmlSerializer; 35 36/* 37 * Manages system-wide KeySet state. 38 */ 39public class KeySetManagerService { 40 41 static final String TAG = "KeySetManagerService"; 42 43 /* original keysets implementation had no versioning info, so this is the first */ 44 public static final int FIRST_VERSION = 1; 45 46 public static final int CURRENT_VERSION = FIRST_VERSION; 47 48 /** Sentinel value returned when a {@code KeySet} is not found. */ 49 public static final long KEYSET_NOT_FOUND = -1; 50 51 /** Sentinel value returned when public key is not found. */ 52 protected static final long PUBLIC_KEY_NOT_FOUND = -1; 53 54 private final LongSparseArray<KeySetHandle> mKeySets; 55 56 private final LongSparseArray<PublicKey> mPublicKeys; 57 58 protected final LongSparseArray<ArraySet<Long>> mKeySetMapping; 59 60 private final Map<String, PackageSetting> mPackages; 61 62 private static long lastIssuedKeySetId = 0; 63 64 private static long lastIssuedKeyId = 0; 65 66 public KeySetManagerService(Map<String, PackageSetting> packages) { 67 mKeySets = new LongSparseArray<KeySetHandle>(); 68 mPublicKeys = new LongSparseArray<PublicKey>(); 69 mKeySetMapping = new LongSparseArray<ArraySet<Long>>(); 70 mPackages = packages; 71 } 72 73 /** 74 * Determine if a package is signed by the given KeySet. 75 * 76 * Returns false if the package was not signed by all the 77 * keys in the KeySet. 78 * 79 * Returns true if the package was signed by at least the 80 * keys in the given KeySet. 81 * 82 * Note that this can return true for multiple KeySets. 83 */ 84 public boolean packageIsSignedByLPr(String packageName, KeySetHandle ks) { 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 = getIdByKeySetLPr(ks); 93 if (id == KEYSET_NOT_FOUND) { 94 return false; 95 } 96 return pkg.keySetData.packageIsSignedBy(id); 97 } 98 99 /** 100 * Determine if a package is signed by the given KeySet. 101 * 102 * Returns false if the package was not signed by all the 103 * keys in the KeySet, or if the package was signed by keys 104 * not in the KeySet. 105 * 106 * Note that this can return only for one KeySet. 107 */ 108 public boolean packageIsSignedByExactlyLPr(String packageName, KeySetHandle ks) { 109 PackageSetting pkg = mPackages.get(packageName); 110 if (pkg == null) { 111 throw new NullPointerException("Invalid package name"); 112 } 113 if (pkg.keySetData == null 114 || pkg.keySetData.getProperSigningKeySet() 115 == PackageKeySetData.KEYSET_UNASSIGNED) { 116 throw new NullPointerException("Package has no KeySet data"); 117 } 118 long id = getIdByKeySetLPr(ks); 119 return pkg.keySetData.getProperSigningKeySet() == id; 120 } 121 122 /** 123 * This informs the system that the given package has defined a KeySet 124 * in its manifest that a) contains the given keys and b) is named 125 * alias by that package. 126 */ 127 public void addDefinedKeySetToPackageLPw(String packageName, 128 ArraySet<PublicKey> keys, String alias) { 129 if ((packageName == null) || (keys == null) || (alias == null)) { 130 Slog.w(TAG, "Got null argument for a defined keyset, ignoring!"); 131 return; 132 } 133 PackageSetting pkg = mPackages.get(packageName); 134 if (pkg == null) { 135 throw new NullPointerException("Unknown package"); 136 } 137 // Add to KeySets, then to package 138 KeySetHandle ks = addKeySetLPw(keys); 139 long id = getIdByKeySetLPr(ks); 140 pkg.keySetData.addDefinedKeySet(id, alias); 141 } 142 143 /** 144 * This informs the system that the given package has defined a KeySet 145 * alias in its manifest to be an upgradeKeySet. This must be called 146 * after all of the defined KeySets have been added. 147 */ 148 public void addUpgradeKeySetToPackageLPw(String packageName, String alias) { 149 if ((packageName == null) || (alias == null)) { 150 Slog.w(TAG, "Got null argument for a defined keyset, ignoring!"); 151 return; 152 } 153 PackageSetting pkg = mPackages.get(packageName); 154 if (pkg == null) { 155 throw new NullPointerException("Unknown package"); 156 } 157 pkg.keySetData.addUpgradeKeySet(alias); 158 } 159 160 /** 161 * Similar to the above, this informs the system that the given package 162 * was signed by the provided KeySet. 163 */ 164 public void addSigningKeySetToPackageLPw(String packageName, 165 ArraySet<PublicKey> signingKeys) { 166 if ((packageName == null) || (signingKeys == null)) { 167 Slog.w(TAG, "Got null argument for a signing keyset, ignoring!"); 168 return; 169 } 170 // add the signing KeySet 171 KeySetHandle ks = addKeySetLPw(signingKeys); 172 long id = getIdByKeySetLPr(ks); 173 ArraySet<Long> publicKeyIds = mKeySetMapping.get(id); 174 if (publicKeyIds == null) { 175 throw new NullPointerException("Got invalid KeySet id"); 176 } 177 // attach it to the package 178 PackageSetting pkg = mPackages.get(packageName); 179 if (pkg == null) { 180 throw new NullPointerException("No such package!"); 181 } 182 pkg.keySetData.setProperSigningKeySet(id); 183 // for each KeySet which is a subset of the one above, add the 184 // KeySet id to the package's signing KeySets 185 for (int keySetIndex = 0; keySetIndex < mKeySets.size(); keySetIndex++) { 186 long keySetID = mKeySets.keyAt(keySetIndex); 187 ArraySet<Long> definedKeys = mKeySetMapping.get(keySetID); 188 if (publicKeyIds.containsAll(definedKeys)) { 189 pkg.keySetData.addSigningKeySet(keySetID); 190 } 191 } 192 } 193 194 /** 195 * Fetches the stable identifier associated with the given KeySet. Returns 196 * {@link #KEYSET_NOT_FOUND} if the KeySet... wasn't found. 197 */ 198 private long getIdByKeySetLPr(KeySetHandle ks) { 199 for (int keySetIndex = 0; keySetIndex < mKeySets.size(); keySetIndex++) { 200 KeySetHandle value = mKeySets.valueAt(keySetIndex); 201 if (ks.equals(value)) { 202 return mKeySets.keyAt(keySetIndex); 203 } 204 } 205 return KEYSET_NOT_FOUND; 206 } 207 208 /** 209 * Fetches the KeySet corresponding to the given stable identifier. 210 * 211 * Returns {@link #KEYSET_NOT_FOUND} if the identifier doesn't 212 * identify a {@link KeySet}. 213 */ 214 public KeySetHandle getKeySetByIdLPr(long id) { 215 return mKeySets.get(id); 216 } 217 218 /** 219 * Fetches the {@link KeySetHandle} that a given package refers to by the 220 * provided alias. Returns null if the package is unknown or does not have a 221 * KeySet corresponding to that alias. 222 */ 223 public KeySetHandle getKeySetByAliasAndPackageNameLPr(String packageName, String alias) { 224 PackageSetting p = mPackages.get(packageName); 225 if (p == null || p.keySetData == null) { 226 return null; 227 } 228 Long keySetId = p.keySetData.getAliases().get(alias); 229 if (keySetId == null) { 230 throw new IllegalArgumentException("Unknown KeySet alias: " + alias); 231 } 232 return mKeySets.get(keySetId); 233 } 234 235 /** 236 * Fetches the {@link PublicKey public keys} which belong to the specified 237 * KeySet id. 238 * 239 * Returns {@code null} if the identifier doesn't 240 * identify a {@link KeySetHandle}. 241 */ 242 public ArraySet<PublicKey> getPublicKeysFromKeySetLPr(long id) { 243 if(mKeySetMapping.get(id) == null) { 244 return null; 245 } 246 ArraySet<PublicKey> mPubKeys = new ArraySet<PublicKey>(); 247 for (long pkId : mKeySetMapping.get(id)) { 248 mPubKeys.add(mPublicKeys.get(pkId)); 249 } 250 return mPubKeys; 251 } 252 253 /** 254 * Fetches the proper {@link KeySetHandle KeySet} that signed the given 255 * package. 256 * 257 * @throws IllegalArgumentException if the package has no keyset data. 258 * @throws NullPointerException if the package is unknown. 259 */ 260 public KeySetHandle getSigningKeySetByPackageNameLPr(String packageName) { 261 PackageSetting p = mPackages.get(packageName); 262 if (p == null 263 || p.keySetData == null 264 || p.keySetData.getProperSigningKeySet() 265 == PackageKeySetData.KEYSET_UNASSIGNED) { 266 return null; 267 } 268 return mKeySets.get(p.keySetData.getProperSigningKeySet()); 269 } 270 271 /** 272 * Fetches all the known {@link KeySetHandle KeySets} that may upgrade the given 273 * package. 274 * 275 * @throws IllegalArgumentException if the package has no keyset data. 276 * @throws NullPointerException if the package is unknown. 277 */ 278 public ArraySet<KeySetHandle> getUpgradeKeySetsByPackageNameLPr(String packageName) { 279 ArraySet<KeySetHandle> upgradeKeySets = new ArraySet<KeySetHandle>(); 280 PackageSetting p = mPackages.get(packageName); 281 if (p == null) { 282 throw new NullPointerException("Unknown package"); 283 } 284 if (p.keySetData == null) { 285 throw new IllegalArgumentException("Package has no keySet data"); 286 } 287 if (p.keySetData.isUsingUpgradeKeySets()) { 288 for (long l : p.keySetData.getUpgradeKeySets()) { 289 upgradeKeySets.add(mKeySets.get(l)); 290 } 291 } 292 return upgradeKeySets; 293 } 294 295 /** 296 * Creates a new KeySet corresponding to the given keys. 297 * 298 * If the {@link PublicKey PublicKeys} aren't known to the system, this 299 * adds them. Otherwise, they're deduped. 300 * 301 * If the KeySet isn't known to the system, this adds that and creates the 302 * mapping to the PublicKeys. If it is known, then it's deduped. 303 * 304 * If the KeySet isn't known to the system, this adds it to all appropriate 305 * signingKeySets 306 * 307 * Throws if the provided set is {@code null}. 308 */ 309 private KeySetHandle addKeySetLPw(ArraySet<PublicKey> keys) { 310 if (keys == null) { 311 throw new NullPointerException("Provided keys cannot be null"); 312 } 313 // add each of the keys in the provided set 314 ArraySet<Long> addedKeyIds = new ArraySet<Long>(keys.size()); 315 for (PublicKey k : keys) { 316 long id = addPublicKeyLPw(k); 317 addedKeyIds.add(id); 318 } 319 320 // check to see if the resulting keyset is new 321 long existingKeySetId = getIdFromKeyIdsLPr(addedKeyIds); 322 if (existingKeySetId != KEYSET_NOT_FOUND) { 323 return mKeySets.get(existingKeySetId); 324 } 325 326 // create the KeySet object 327 KeySetHandle ks = new KeySetHandle(); 328 // get the first unoccupied slot in mKeySets 329 long id = getFreeKeySetIDLPw(); 330 // add the KeySet object to it 331 mKeySets.put(id, ks); 332 // add the stable key ids to the mapping 333 mKeySetMapping.put(id, addedKeyIds); 334 // add this KeySet id to all packages which are signed by it 335 for (String pkgName : mPackages.keySet()) { 336 PackageSetting p = mPackages.get(pkgName); 337 if (p.keySetData != null) { 338 long pProperSigning = p.keySetData.getProperSigningKeySet(); 339 if (pProperSigning != PackageKeySetData.KEYSET_UNASSIGNED) { 340 ArraySet<Long> pSigningKeys = mKeySetMapping.get(pProperSigning); 341 if (pSigningKeys.containsAll(addedKeyIds)) { 342 p.keySetData.addSigningKeySet(id); 343 } 344 } 345 } 346 } 347 // go home 348 return ks; 349 } 350 351 /** 352 * Adds the given PublicKey to the system, deduping as it goes. 353 */ 354 private long addPublicKeyLPw(PublicKey key) { 355 // check if the public key is new 356 long existingKeyId = getIdForPublicKeyLPr(key); 357 if (existingKeyId != PUBLIC_KEY_NOT_FOUND) { 358 return existingKeyId; 359 } 360 // if it's new find the first unoccupied slot in the public keys 361 long id = getFreePublicKeyIdLPw(); 362 // add the public key to it 363 mPublicKeys.put(id, key); 364 // return the stable identifier 365 return id; 366 } 367 368 /** 369 * Finds the stable identifier for a KeySet based on a set of PublicKey stable IDs. 370 * 371 * Returns KEYSET_NOT_FOUND if there isn't one. 372 */ 373 private long getIdFromKeyIdsLPr(Set<Long> publicKeyIds) { 374 for (int keyMapIndex = 0; keyMapIndex < mKeySetMapping.size(); keyMapIndex++) { 375 ArraySet<Long> value = mKeySetMapping.valueAt(keyMapIndex); 376 if (value.equals(publicKeyIds)) { 377 return mKeySetMapping.keyAt(keyMapIndex); 378 } 379 } 380 return KEYSET_NOT_FOUND; 381 } 382 383 /** 384 * Finds the stable identifier for a PublicKey or PUBLIC_KEY_NOT_FOUND. 385 */ 386 private long getIdForPublicKeyLPr(PublicKey k) { 387 String encodedPublicKey = new String(k.getEncoded()); 388 for (int publicKeyIndex = 0; publicKeyIndex < mPublicKeys.size(); publicKeyIndex++) { 389 PublicKey value = mPublicKeys.valueAt(publicKeyIndex); 390 String encodedExistingKey = new String(value.getEncoded()); 391 if (encodedPublicKey.equals(encodedExistingKey)) { 392 return mPublicKeys.keyAt(publicKeyIndex); 393 } 394 } 395 return PUBLIC_KEY_NOT_FOUND; 396 } 397 398 /** 399 * Gets an unused stable identifier for a KeySet. 400 */ 401 private long getFreeKeySetIDLPw() { 402 lastIssuedKeySetId += 1; 403 return lastIssuedKeySetId; 404 } 405 406 /** 407 * Same as above, but for public keys. 408 */ 409 private long getFreePublicKeyIdLPw() { 410 lastIssuedKeyId += 1; 411 return lastIssuedKeyId; 412 } 413 414 public void removeAppKeySetDataLPw(String packageName) { 415 // Get the package's known keys and KeySets 416 ArraySet<Long> deletableKeySets = getOriginalKeySetsByPackageNameLPr(packageName); 417 ArraySet<Long> deletableKeys = new ArraySet<Long>(); 418 final int origDksSize = deletableKeySets.size(); 419 for (int i = 0; i < origDksSize; i++) { 420 ArraySet<Long> knownKeys = mKeySetMapping.get(deletableKeySets.valueAt(i)); 421 if (knownKeys != null) { 422 deletableKeys.addAll(knownKeys); 423 } 424 } 425 426 // Now remove the keys and KeySets on which any other package relies 427 for (String pkgName : mPackages.keySet()) { 428 if (pkgName.equals(packageName)) { 429 continue; 430 } 431 ArraySet<Long> knownKeySets = getOriginalKeySetsByPackageNameLPr(pkgName); 432 deletableKeySets.removeAll(knownKeySets); 433 final int kksSize = knownKeySets.size(); 434 for (int i = 0; i < kksSize; i++) { 435 ArraySet<Long> knownKeys = mKeySetMapping.get(knownKeySets.valueAt(i)); 436 if (knownKeys != null) { 437 deletableKeys.removeAll(knownKeys); 438 } 439 } 440 } 441 442 // The remaining keys and KeySets are not relied on by any other 443 // application and so can be safely deleted. 444 final int dksSize = deletableKeySets.size(); 445 for (int i = 0; i < dksSize; i++) { 446 Long ks = deletableKeySets.valueAt(i); 447 mKeySets.delete(ks); 448 mKeySetMapping.delete(ks); 449 } 450 final int dkSize = deletableKeys.size(); 451 for (int i = 0; i < dkSize; i++) { 452 mPublicKeys.delete(deletableKeys.valueAt(i)); 453 } 454 455 // Now remove the deleted KeySets from each package's signingKeySets 456 for (String pkgName : mPackages.keySet()) { 457 PackageSetting p = mPackages.get(pkgName); 458 for (int i = 0; i < dksSize; i++) { 459 Long ks = deletableKeySets.valueAt(i); 460 p.keySetData.removeSigningKeySet(ks); 461 } 462 } 463 // Finally, remove all KeySets from the original package 464 PackageSetting p = mPackages.get(packageName); 465 clearPackageKeySetDataLPw(p); 466 } 467 468 private void clearPackageKeySetDataLPw(PackageSetting p) { 469 p.keySetData.removeAllSigningKeySets(); 470 p.keySetData.removeAllUpgradeKeySets(); 471 p.keySetData.removeAllDefinedKeySets(); 472 return; 473 } 474 475 private ArraySet<Long> getOriginalKeySetsByPackageNameLPr(String packageName) { 476 PackageSetting p = mPackages.get(packageName); 477 if (p == null) { 478 throw new NullPointerException("Unknown package"); 479 } 480 if (p.keySetData == null) { 481 throw new IllegalArgumentException("Package has no keySet data"); 482 } 483 ArraySet<Long> knownKeySets = new ArraySet<Long>(); 484 knownKeySets.add(p.keySetData.getProperSigningKeySet()); 485 if (p.keySetData.isUsingDefinedKeySets()) { 486 for (long ks : p.keySetData.getDefinedKeySets()) { 487 knownKeySets.add(ks); 488 } 489 } 490 return knownKeySets; 491 } 492 493 public String encodePublicKey(PublicKey k) throws IOException { 494 return new String(Base64.encode(k.getEncoded(), 0)); 495 } 496 497 public void dumpLPr(PrintWriter pw, String packageName, 498 PackageManagerService.DumpState dumpState) { 499 boolean printedHeader = false; 500 for (Map.Entry<String, PackageSetting> e : mPackages.entrySet()) { 501 String keySetPackage = e.getKey(); 502 if (packageName != null && !packageName.equals(keySetPackage)) { 503 continue; 504 } 505 if (!printedHeader) { 506 if (dumpState.onTitlePrinted()) 507 pw.println(); 508 pw.println("Key Set Manager:"); 509 printedHeader = true; 510 } 511 PackageSetting pkg = e.getValue(); 512 pw.print(" ["); pw.print(keySetPackage); pw.println("]"); 513 if (pkg.keySetData != null) { 514 boolean printedLabel = false; 515 for (Map.Entry<String, Long> entry : pkg.keySetData.getAliases().entrySet()) { 516 if (!printedLabel) { 517 pw.print(" KeySets Aliases: "); 518 printedLabel = true; 519 } else { 520 pw.print(", "); 521 } 522 pw.print(entry.getKey()); 523 pw.print('='); 524 pw.print(Long.toString(entry.getValue())); 525 } 526 if (printedLabel) { 527 pw.println(""); 528 } 529 printedLabel = false; 530 if (pkg.keySetData.isUsingDefinedKeySets()) { 531 for (long keySetId : pkg.keySetData.getDefinedKeySets()) { 532 if (!printedLabel) { 533 pw.print(" Defined KeySets: "); 534 printedLabel = true; 535 } else { 536 pw.print(", "); 537 } 538 pw.print(Long.toString(keySetId)); 539 } 540 } 541 if (printedLabel) { 542 pw.println(""); 543 } 544 printedLabel = false; 545 final long[] signingKeySets = pkg.keySetData.getSigningKeySets(); 546 if (signingKeySets != null) { 547 for (long keySetId : signingKeySets) { 548 if (!printedLabel) { 549 pw.print(" Signing KeySets: "); 550 printedLabel = true; 551 } else { 552 pw.print(", "); 553 } 554 pw.print(Long.toString(keySetId)); 555 } 556 } 557 if (printedLabel) { 558 pw.println(""); 559 } 560 printedLabel = false; 561 if (pkg.keySetData.isUsingUpgradeKeySets()) { 562 for (long keySetId : pkg.keySetData.getUpgradeKeySets()) { 563 if (!printedLabel) { 564 pw.print(" Upgrade KeySets: "); 565 printedLabel = true; 566 } else { 567 pw.print(", "); 568 } 569 pw.print(Long.toString(keySetId)); 570 } 571 } 572 if (printedLabel) { 573 pw.println(""); 574 } 575 } 576 } 577 } 578 579 void writeKeySetManagerServiceLPr(XmlSerializer serializer) throws IOException { 580 serializer.startTag(null, "keyset-settings"); 581 serializer.attribute(null, "version", Integer.toString(CURRENT_VERSION)); 582 writePublicKeysLPr(serializer); 583 writeKeySetsLPr(serializer); 584 serializer.startTag(null, "lastIssuedKeyId"); 585 serializer.attribute(null, "value", Long.toString(lastIssuedKeyId)); 586 serializer.endTag(null, "lastIssuedKeyId"); 587 serializer.startTag(null, "lastIssuedKeySetId"); 588 serializer.attribute(null, "value", Long.toString(lastIssuedKeySetId)); 589 serializer.endTag(null, "lastIssuedKeySetId"); 590 serializer.endTag(null, "keyset-settings"); 591 } 592 593 void writePublicKeysLPr(XmlSerializer serializer) throws IOException { 594 serializer.startTag(null, "keys"); 595 for (int pKeyIndex = 0; pKeyIndex < mPublicKeys.size(); pKeyIndex++) { 596 long id = mPublicKeys.keyAt(pKeyIndex); 597 PublicKey key = mPublicKeys.valueAt(pKeyIndex); 598 String encodedKey = encodePublicKey(key); 599 serializer.startTag(null, "public-key"); 600 serializer.attribute(null, "identifier", Long.toString(id)); 601 serializer.attribute(null, "value", encodedKey); 602 serializer.endTag(null, "public-key"); 603 } 604 serializer.endTag(null, "keys"); 605 } 606 607 void writeKeySetsLPr(XmlSerializer serializer) throws IOException { 608 serializer.startTag(null, "keysets"); 609 for (int keySetIndex = 0; keySetIndex < mKeySetMapping.size(); keySetIndex++) { 610 long id = mKeySetMapping.keyAt(keySetIndex); 611 ArraySet<Long> keys = mKeySetMapping.valueAt(keySetIndex); 612 serializer.startTag(null, "keyset"); 613 serializer.attribute(null, "identifier", Long.toString(id)); 614 for (long keyId : keys) { 615 serializer.startTag(null, "key-id"); 616 serializer.attribute(null, "identifier", Long.toString(keyId)); 617 serializer.endTag(null, "key-id"); 618 } 619 serializer.endTag(null, "keyset"); 620 } 621 serializer.endTag(null, "keysets"); 622 } 623 624 void readKeySetsLPw(XmlPullParser parser) 625 throws XmlPullParserException, IOException { 626 int type; 627 long currentKeySetId = 0; 628 int outerDepth = parser.getDepth(); 629 String recordedVersion = parser.getAttributeValue(null, "version"); 630 if (recordedVersion == null || Integer.parseInt(recordedVersion) != CURRENT_VERSION) { 631 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 632 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 633 // Our version is different than the one which generated the old keyset data. 634 // We don't want any of the old data, but we must advance the parser 635 continue; 636 } 637 // The KeySet information read previously from packages.xml is invalid. 638 // Destroy it all. 639 for (PackageSetting p : mPackages.values()) { 640 clearPackageKeySetDataLPw(p); 641 } 642 return; 643 } 644 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 645 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 646 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 647 continue; 648 } 649 final String tagName = parser.getName(); 650 if (tagName.equals("keys")) { 651 readKeysLPw(parser); 652 } else if (tagName.equals("keysets")) { 653 readKeySetListLPw(parser); 654 } else if (tagName.equals("lastIssuedKeyId")) { 655 lastIssuedKeyId = Long.parseLong(parser.getAttributeValue(null, "value")); 656 } else if (tagName.equals("lastIssuedKeySetId")) { 657 lastIssuedKeySetId = Long.parseLong(parser.getAttributeValue(null, "value")); 658 } 659 } 660 } 661 662 void readKeysLPw(XmlPullParser parser) 663 throws XmlPullParserException, IOException { 664 int outerDepth = parser.getDepth(); 665 int type; 666 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 667 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 668 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 669 continue; 670 } 671 final String tagName = parser.getName(); 672 if (tagName.equals("public-key")) { 673 readPublicKeyLPw(parser); 674 } 675 } 676 } 677 678 void readKeySetListLPw(XmlPullParser parser) 679 throws XmlPullParserException, IOException { 680 int outerDepth = parser.getDepth(); 681 int type; 682 long currentKeySetId = 0; 683 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 684 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 685 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 686 continue; 687 } 688 final String tagName = parser.getName(); 689 if (tagName.equals("keyset")) { 690 currentKeySetId = readIdentifierLPw(parser); 691 mKeySets.put(currentKeySetId, new KeySetHandle()); 692 mKeySetMapping.put(currentKeySetId, new ArraySet<Long>()); 693 } else if (tagName.equals("key-id")) { 694 long id = readIdentifierLPw(parser); 695 mKeySetMapping.get(currentKeySetId).add(id); 696 } 697 } 698 } 699 700 long readIdentifierLPw(XmlPullParser parser) 701 throws XmlPullParserException { 702 return Long.parseLong(parser.getAttributeValue(null, "identifier")); 703 } 704 705 void readPublicKeyLPw(XmlPullParser parser) 706 throws XmlPullParserException { 707 String encodedID = parser.getAttributeValue(null, "identifier"); 708 long identifier = Long.parseLong(encodedID); 709 String encodedPublicKey = parser.getAttributeValue(null, "value"); 710 PublicKey pub = PackageParser.parsePublicKey(encodedPublicKey); 711 if (pub != null) { 712 mPublicKeys.put(identifier, pub); 713 } 714 } 715} 716