diff options
Diffstat (limited to 'core')
7 files changed, 159 insertions, 106 deletions
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 6e0ca50..b5da4cd 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -1312,8 +1312,8 @@ public class PackageParser { } XmlUtils.skipCurrentTag(parser); - } else if (tagName.equals("keys")) { - if (!parseKeys(pkg, res, parser, attrs, outError)) { + } else if (tagName.equals("key-sets")) { + if (!parseKeySets(pkg, res, parser, attrs, outError)) { return null; } } else if (tagName.equals("permission-group")) { @@ -1328,17 +1328,6 @@ public class PackageParser { if (parsePermissionTree(pkg, res, parser, attrs, outError) == null) { return null; } - } else if (tagName.equals("upgrade-keyset")) { - sa = res.obtainAttributes(attrs, - com.android.internal.R.styleable.AndroidManifestUpgradeKeySet); - String name = sa.getNonResourceString( - com.android.internal.R.styleable.AndroidManifestUpgradeKeySet_name); - sa.recycle(); - if (pkg.mUpgradeKeySets == null) { - pkg.mUpgradeKeySets = new ArraySet<String>(); - } - pkg.mUpgradeKeySets.add(name); - XmlUtils.skipCurrentTag(parser); } else if (tagName.equals("uses-permission")) { if (!parseUsesPermission(pkg, res, parser, attrs, outError)) { return null; @@ -1849,84 +1838,141 @@ public class PackageParser { return buildCompoundName(pkg, procSeq, "taskAffinity", outError); } - private boolean parseKeys(Package owner, Resources res, + private boolean parseKeySets(Package owner, Resources res, XmlPullParser parser, AttributeSet attrs, String[] outError) throws XmlPullParserException, IOException { - // we've encountered the 'keys' tag + // we've encountered the 'key-sets' tag // all the keys and keysets that we want must be defined here // so we're going to iterate over the parser and pull out the things we want int outerDepth = parser.getDepth(); - + int currentKeySetDepth = -1; int type; - PublicKey currentKey = null; - int currentKeyDepth = -1; - Map<PublicKey, Set<String>> definedKeySets = new HashMap<PublicKey, Set<String>>(); + String currentKeySet = null; + ArrayMap<String, PublicKey> publicKeys = new ArrayMap<String, PublicKey>(); + ArraySet<String> upgradeKeySets = new ArraySet<String>(); + ArrayMap<String, ArraySet<String>> definedKeySets = new ArrayMap<String, ArraySet<String>>(); + ArraySet<String> improperKeySets = new ArraySet<String>(); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG) { - if (parser.getDepth() == currentKeyDepth) { - currentKey = null; - currentKeyDepth = -1; + if (parser.getDepth() == currentKeySetDepth) { + currentKeySet = null; + currentKeySetDepth = -1; } continue; } - String tagname = parser.getName(); - if (tagname.equals("publicKey")) { - final TypedArray sa = res.obtainAttributes(attrs, - com.android.internal.R.styleable.PublicKey); - final String encodedKey = sa.getNonResourceString( - com.android.internal.R.styleable.PublicKey_value); - currentKey = parsePublicKey(encodedKey); - if (currentKey == null) { - Slog.w(TAG, "No valid key in 'publicKey' tag at " + String tagName = parser.getName(); + if (tagName.equals("key-set")) { + if (currentKeySet != null) { + Slog.w(TAG, "Improperly nested 'key-set' tag at " + parser.getPositionDescription()); - sa.recycle(); - continue; + return false; } - currentKeyDepth = parser.getDepth(); - definedKeySets.put(currentKey, new HashSet<String>()); + final TypedArray sa = res.obtainAttributes(attrs, + com.android.internal.R.styleable.AndroidManifestKeySet); + final String keysetName = sa.getNonResourceString( + com.android.internal.R.styleable.AndroidManifestKeySet_name); + definedKeySets.put(keysetName, new ArraySet<String>()); + currentKeySet = keysetName; + currentKeySetDepth = parser.getDepth(); sa.recycle(); - } else if (tagname.equals("keyset")) { - if (currentKey == null) { - Slog.i(TAG, "'keyset' not in 'publicKey' tag at " + } else if (tagName.equals("public-key")) { + if (currentKeySet == null) { + Slog.w(TAG, "Improperly nested 'public-key' tag at " + parser.getPositionDescription()); - continue; + return false; } final TypedArray sa = res.obtainAttributes(attrs, - com.android.internal.R.styleable.KeySet); - final String name = sa.getNonResourceString( - com.android.internal.R.styleable.KeySet_name); - definedKeySets.get(currentKey).add(name); + com.android.internal.R.styleable.AndroidManifestPublicKey); + final String publicKeyName = sa.getNonResourceString( + com.android.internal.R.styleable.AndroidManifestPublicKey_name); + final String encodedKey = sa.getNonResourceString( + com.android.internal.R.styleable.AndroidManifestPublicKey_value); + if (encodedKey == null && publicKeys.get(publicKeyName) == null) { + Slog.w(TAG, "'public-key' " + publicKeyName + " must define a public-key value" + + " on first use at " + parser.getPositionDescription()); + sa.recycle(); + return false; + } else if (encodedKey != null) { + PublicKey currentKey = parsePublicKey(encodedKey); + if (currentKey == null) { + Slog.w(TAG, "No recognized valid key in 'public-key' tag at " + + parser.getPositionDescription() + " key-set " + currentKeySet + + " will not be added to the package's defined key-sets."); + sa.recycle(); + improperKeySets.add(currentKeySet); + XmlUtils.skipCurrentTag(parser); + continue; + } + if (publicKeys.get(publicKeyName) == null + || publicKeys.get(publicKeyName).equals(currentKey)) { + + /* public-key first definition, or matches old definition */ + publicKeys.put(publicKeyName, currentKey); + } else { + Slog.w(TAG, "Value of 'public-key' " + publicKeyName + + " conflicts with previously defined value at " + + parser.getPositionDescription()); + sa.recycle(); + return false; + } + } + definedKeySets.get(currentKeySet).add(publicKeyName); + sa.recycle(); + XmlUtils.skipCurrentTag(parser); + } else if (tagName.equals("upgrade-key-set")) { + final TypedArray sa = res.obtainAttributes(attrs, + com.android.internal.R.styleable.AndroidManifestUpgradeKeySet); + String name = sa.getNonResourceString( + com.android.internal.R.styleable.AndroidManifestUpgradeKeySet_name); + upgradeKeySets.add(name); sa.recycle(); + XmlUtils.skipCurrentTag(parser); } else if (RIGID_PARSER) { - Slog.w(TAG, "Bad element under <keys>: " + parser.getName() + Slog.w(TAG, "Bad element under <key-sets>: " + parser.getName() + " at " + mArchiveSourcePath + " " + parser.getPositionDescription()); return false; } else { - Slog.w(TAG, "Unknown element under <keys>: " + parser.getName() + Slog.w(TAG, "Unknown element under <key-sets>: " + parser.getName() + " at " + mArchiveSourcePath + " " + parser.getPositionDescription()); XmlUtils.skipCurrentTag(parser); continue; } } - - owner.mKeySetMapping = new ArrayMap<String, Set<PublicKey>>(); - for (Map.Entry<PublicKey, Set<String>> e : definedKeySets.entrySet()) { - PublicKey key = e.getKey(); - Set<String> keySetNames = e.getValue(); - for (String alias : keySetNames) { - if (owner.mKeySetMapping.containsKey(alias)) { - owner.mKeySetMapping.get(alias).add(key); - } else { - Set<PublicKey> keys = new ArraySet<PublicKey>(); - keys.add(key); - owner.mKeySetMapping.put(alias, keys); - } + Set<String> publicKeyNames = publicKeys.keySet(); + if (publicKeyNames.removeAll(definedKeySets.keySet())) { + Slog.w(TAG, "Package" + owner.packageName + " AndroidManifext.xml " + + "'key-set' and 'public-key' names must be distinct."); + return false; + } + owner.mKeySetMapping = new ArrayMap<String, ArraySet<PublicKey>>(); + for (ArrayMap.Entry<String, ArraySet<String>> e: definedKeySets.entrySet()) { + final String keySetName = e.getKey(); + if (e.getValue().size() == 0) { + Slog.w(TAG, "Package" + owner.packageName + " AndroidManifext.xml " + + "'key-set' " + keySetName + " has no valid associated 'public-key'." + + " Not including in package's defined key-sets."); + continue; + } else if (improperKeySets.contains(keySetName)) { + Slog.w(TAG, "Package" + owner.packageName + " AndroidManifext.xml " + + "'key-set' " + keySetName + " contained improper 'public-key'" + + " tags. Not including in package's defined key-sets."); + continue; + } + owner.mKeySetMapping.put(keySetName, new ArraySet<PublicKey>()); + for (String s : e.getValue()) { + owner.mKeySetMapping.get(keySetName).add(publicKeys.get(s)); } } - + if (owner.mKeySetMapping.keySet().containsAll(upgradeKeySets)) { + owner.mUpgradeKeySets = upgradeKeySets; + } else { + Slog.w(TAG, "Package" + owner.packageName + " AndroidManifext.xml " + + "does not define all 'upgrade-key-set's ."); + return false; + } return true; } @@ -3925,11 +3971,11 @@ public class PackageParser { public boolean mTrustedOverlay; /** - * Data used to feed the KeySetManager + * Data used to feed the KeySetManagerService */ - public Set<PublicKey> mSigningKeys; - public Set<String> mUpgradeKeySets; - public Map<String, Set<PublicKey>> mKeySetMapping; + public ArraySet<PublicKey> mSigningKeys; + public ArraySet<String> mUpgradeKeySets; + public ArrayMap<String, ArraySet<PublicKey>> mKeySetMapping; public Package(String packageName) { this.packageName = packageName; diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 9789eee..226e30a 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -2025,10 +2025,11 @@ <!-- Groups signing keys into a {@code KeySet} for easier reference in other APIs. However, currently no APIs use this. --> <attr name="keySet" /> - <declare-styleable name="PublicKey"> + <declare-styleable name="AndroidManifestPublicKey"> + <attr name="name" /> <attr name="value" /> </declare-styleable> - <declare-styleable name="KeySet"> + <declare-styleable name="AndroidManifestKeySet"> <attr name="name" /> </declare-styleable> diff --git a/core/tests/coretests/apks/keyset/permUse/AndroidManifest.xml b/core/tests/coretests/apks/keyset/permUse/AndroidManifest.xml index 41a2974..b7645b0 100644 --- a/core/tests/coretests/apks/keyset/permUse/AndroidManifest.xml +++ b/core/tests/coretests/apks/keyset/permUse/AndroidManifest.xml @@ -18,14 +18,16 @@ <application android:hasCode="false"> </application> <uses-permission android:name="com.android.frameworks.coretests.keysets_permdef.keyset_perm" /> - <keys> - <publicKey android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ=="> - <keyset android:name="A" /> - </publicKey> - <publicKey android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTfQsY8UuXiXmvw/y7Tpr7HoyfAC0nE/8Qdk3ZtEr9asa5qqP0F6xzCI1PGVFV+WLVRwm6FdB9StENL5EKyQFcCAwEAAQ=="> - <keyset android:name="B" /> - </publicKey> - </keys> - <upgrade-keyset android:name="A"/> - <upgrade-keyset android:name="B"/> + <key-sets> + <key-set android:name="A"> + <public-key android:name="keyA" + android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ=="/> + </key-set> + <key-set android:name="B"> + <public-key android:name="keyB" + android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTfQsY8UuXiXmvw/y7Tpr7HoyfAC0nE/8Qdk3ZtEr9asa5qqP0F6xzCI1PGVFV+WLVRwm6FdB9StENL5EKyQFcCAwEAAQ==" /> + </key-set> + <upgrade-key-set android:name="A"/> + <upgrade-key-set android:name="B"/> + </key-sets> </manifest> diff --git a/core/tests/coretests/apks/keyset/uA/AndroidManifest.xml b/core/tests/coretests/apks/keyset/uA/AndroidManifest.xml index 87c420e..f31b75f 100644 --- a/core/tests/coretests/apks/keyset/uA/AndroidManifest.xml +++ b/core/tests/coretests/apks/keyset/uA/AndroidManifest.xml @@ -17,10 +17,11 @@ package="com.android.frameworks.coretests.keysets"> <application android:hasCode="false"> </application> - <keys> - <publicKey android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ=="> - <keyset android:name="A" /> - </publicKey> - </keys> - <upgrade-keyset android:name="A"/> + <key-sets> + <key-set android:name="A" > + <public-key android:name="keyA" + android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ=="/> + </key-set> + <upgrade-key-set android:name="A"/> + </key-sets> </manifest> diff --git a/core/tests/coretests/apks/keyset/uAB/AndroidManifest.xml b/core/tests/coretests/apks/keyset/uAB/AndroidManifest.xml index a65f085..8ad3471 100644 --- a/core/tests/coretests/apks/keyset/uAB/AndroidManifest.xml +++ b/core/tests/coretests/apks/keyset/uAB/AndroidManifest.xml @@ -17,13 +17,13 @@ package="com.android.frameworks.coretests.keysets"> <application android:hasCode="false"> </application> - <keys> - <publicKey android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ=="> - <keyset android:name="AB" /> - </publicKey> - <publicKey android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTfQsY8UuXiXmvw/y7Tpr7HoyfAC0nE/8Qdk3ZtEr9asa5qqP0F6xzCI1PGVFV+WLVRwm6FdB9StENL5EKyQFcCAwEAAQ=="> - <keyset android:name="AB" /> - </publicKey> - </keys> - <upgrade-keyset android:name="AB"/> + <key-sets> + <key-set android:name="AB" > + <public-key android:name="keyA" + android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ==" /> + <public-key android:name="keyB" + android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTfQsY8UuXiXmvw/y7Tpr7HoyfAC0nE/8Qdk3ZtEr9asa5qqP0F6xzCI1PGVFV+WLVRwm6FdB9StENL5EKyQFcCAwEAAQ==" /> + </key-set> + <upgrade-key-set android:name="AB"/> + </key-sets> </manifest> diff --git a/core/tests/coretests/apks/keyset/uAuB/AndroidManifest.xml b/core/tests/coretests/apks/keyset/uAuB/AndroidManifest.xml index 5b0b864..cdbd639 100644 --- a/core/tests/coretests/apks/keyset/uAuB/AndroidManifest.xml +++ b/core/tests/coretests/apks/keyset/uAuB/AndroidManifest.xml @@ -17,14 +17,16 @@ package="com.android.frameworks.coretests.keysets"> <application android:hasCode="false"> </application> - <keys> - <publicKey android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ=="> - <keyset android:name="A" /> - </publicKey> - <publicKey android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTfQsY8UuXiXmvw/y7Tpr7HoyfAC0nE/8Qdk3ZtEr9asa5qqP0F6xzCI1PGVFV+WLVRwm6FdB9StENL5EKyQFcCAwEAAQ=="> - <keyset android:name="B" /> - </publicKey> - </keys> - <upgrade-keyset android:name="A"/> - <upgrade-keyset android:name="B"/> + <key-sets> + <key-set android:name="A" > + <public-key android:name="keyA" + android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ==" /> + </key-set> + <key-set android:name="B" > + <public-key android:name="keyB" + android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTfQsY8UuXiXmvw/y7Tpr7HoyfAC0nE/8Qdk3ZtEr9asa5qqP0F6xzCI1PGVFV+WLVRwm6FdB9StENL5EKyQFcCAwEAAQ==" /> + </key-set> + <upgrade-key-set android:name="A"/> + <upgrade-key-set android:name="B"/> + </key-sets> </manifest> diff --git a/core/tests/coretests/apks/keyset/uB/AndroidManifest.xml b/core/tests/coretests/apks/keyset/uB/AndroidManifest.xml index 9b89961..61063c3 100644 --- a/core/tests/coretests/apks/keyset/uB/AndroidManifest.xml +++ b/core/tests/coretests/apks/keyset/uB/AndroidManifest.xml @@ -17,10 +17,11 @@ package="com.android.frameworks.coretests.keysets"> <application android:hasCode="false"> </application> - <keys> - <publicKey android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTfQsY8UuXiXmvw/y7Tpr7HoyfAC0nE/8Qdk3ZtEr9asa5qqP0F6xzCI1PGVFV+WLVRwm6FdB9StENL5EKyQFcCAwEAAQ=="> - <keyset android:name="B" /> - </publicKey> - </keys> - <upgrade-keyset android:name="B"/> + <key-sets> + <key-set android:name="B" > + <public-key android:name="keyB" + android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTfQsY8UuXiXmvw/y7Tpr7HoyfAC0nE/8Qdk3ZtEr9asa5qqP0F6xzCI1PGVFV+WLVRwm6FdB9StENL5EKyQFcCAwEAAQ==" /> + </key-set> + <upgrade-key-set android:name="B"/> + </key-sets> </manifest> |
