Loading api/current.txt +2 −1 Original line number Diff line number Diff line Loading @@ -620,6 +620,7 @@ package android { field public static final int keyboardLayout = 16843691; // 0x10103ab field public static final int keyboardMode = 16843341; // 0x101024d field public static final int keycode = 16842949; // 0x10100c5 field public static final int keyset = 16843727; // 0x10103cf field public static final int killAfterRestore = 16843420; // 0x101029c field public static final int label = 16842753; // 0x1010001 field public static final int labelFor = 16843718; // 0x10103c6 Loading Loading @@ -1174,7 +1175,7 @@ package android { field public static final int windowMinWidthMinor = 16843607; // 0x1010357 field public static final int windowNoDisplay = 16843294; // 0x101021e field public static final int windowNoTitle = 16842838; // 0x1010056 field public static final int windowOverscan = 16843727; // 0x10103cf field public static final int windowOverscan = 16843728; // 0x10103d0 field public static final int windowShowAnimation = 16842934; // 0x10100b6 field public static final int windowShowWallpaper = 16843410; // 0x1010292 field public static final int windowSoftInputMode = 16843307; // 0x101022b core/java/android/content/pm/KeySet.java 0 → 100644 +34 −0 Original line number Diff line number Diff line /* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.content.pm; import android.os.Binder; /** @hide */ public class KeySet { private Binder token; /** @hide */ public KeySet(Binder token) { this.token = token; } Binder getToken() { return token; } } No newline at end of file core/java/android/content/pm/PackageParser.java +100 −6 Original line number Diff line number Diff line Loading @@ -46,14 +46,20 @@ import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateFactory; import java.security.cert.CertPath; import java.security.cert.X509Certificate; import java.security.spec.EncodedKeySpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; Loading Loading @@ -689,6 +695,13 @@ public class PackageParser { mParseError = PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES; return false; } // Add the signing KeySet to the system pkg.mSigningKeys = new HashSet<PublicKey>(); for (int i=0; i < certs.length; i++) { pkg.mSigningKeys.add(certs[i].getPublicKey()); } } catch (CertificateEncodingException e) { Slog.w(TAG, "Exception reading " + mArchiveSourcePath, e); mParseError = PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING; Loading Loading @@ -1002,6 +1015,10 @@ public class PackageParser { if (!parseApplication(pkg, res, parser, attrs, flags, outError)) { return null; } } else if (tagName.equals("keys")) { if (!parseKeys(pkg, res, parser, attrs, outError)) { return null; } } else if (tagName.equals("permission-group")) { if (parsePermissionGroup(pkg, flags, res, parser, attrs, outError) == null) { return null; Loading Loading @@ -1465,6 +1482,70 @@ public class PackageParser { return buildCompoundName(pkg, procSeq, "taskAffinity", outError); } private boolean parseKeys(Package owner, Resources res, XmlPullParser parser, AttributeSet attrs, String[] outError) throws XmlPullParserException, IOException { // we've encountered the 'keys' 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 type; PublicKey currentKey = null; Map<PublicKey, Set<String>> definedKeySets = new HashMap<PublicKey, Set<String>>(); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG) { 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); definedKeySets.put(currentKey, new HashSet<String>()); sa.recycle(); } else if (tagname.equals("keyset")) { 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); sa.recycle(); } else if (RIGID_PARSER) { Slog.w(TAG, "Bad element under <keys>: " + parser.getName() + " at " + mArchiveSourcePath + " " + parser.getPositionDescription()); return false; } else { Slog.w(TAG, "Unknown element under <keys>: " + parser.getName() + " at " + mArchiveSourcePath + " " + parser.getPositionDescription()); XmlUtils.skipCurrentTag(parser); continue; } } owner.mKeySetMapping = new HashMap<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 HashSet<PublicKey>(); keys.add(key); owner.mKeySetMapping.put(alias, keys); } } } return true; } private PermissionGroup parsePermissionGroup(Package owner, int flags, Resources res, XmlPullParser parser, AttributeSet attrs, String[] outError) throws XmlPullParserException, IOException { Loading Loading @@ -2988,20 +3069,28 @@ public class PackageParser { Slog.i(TAG, "verifier " + packageName + " public key was null; skipping"); } PublicKey publicKey = parsePublicKey(encodedPublicKey); if (publicKey != null) { return new VerifierInfo(packageName, publicKey); } return null; } public static final PublicKey parsePublicKey(String encodedPublicKey) { EncodedKeySpec keySpec; try { final byte[] encoded = Base64.decode(encodedPublicKey, Base64.DEFAULT); keySpec = new X509EncodedKeySpec(encoded); } catch (IllegalArgumentException e) { Slog.i(TAG, "Could not parse verifier " + packageName + " public key; invalid Base64"); Slog.i(TAG, "Could not parse verifier public key; invalid Base64"); return null; } /* First try the key as an RSA key. */ try { final KeyFactory keyFactory = KeyFactory.getInstance("RSA"); final PublicKey publicKey = keyFactory.generatePublic(keySpec); return new VerifierInfo(packageName, publicKey); return keyFactory.generatePublic(keySpec); } catch (NoSuchAlgorithmException e) { Log.wtf(TAG, "Could not parse public key because RSA isn't included in build"); return null; Loading @@ -3012,8 +3101,7 @@ public class PackageParser { /* Now try it as a DSA key. */ try { final KeyFactory keyFactory = KeyFactory.getInstance("DSA"); final PublicKey publicKey = keyFactory.generatePublic(keySpec); return new VerifierInfo(packageName, publicKey); return keyFactory.generatePublic(keySpec); } catch (NoSuchAlgorithmException e) { Log.wtf(TAG, "Could not parse public key because DSA isn't included in build"); return null; Loading Loading @@ -3254,6 +3342,12 @@ public class PackageParser { */ public ManifestDigest manifestDigest; /** * Data used to feed the KeySetManager */ public Set<PublicKey> mSigningKeys; public Map<String, Set<PublicKey>> mKeySetMapping; public Package(String _name) { packageName = _name; applicationInfo.packageName = _name; Loading core/res/res/values/attrs_manifest.xml +8 −0 Original line number Diff line number Diff line Loading @@ -1699,4 +1699,12 @@ <!-- Concrete value to put for this named extra data. --> <attr name="value" /> </declare-styleable> <attr name="keyset" /> <declare-styleable name="PublicKey"> <attr name="value" /> </declare-styleable> <declare-styleable name="KeySet"> <attr name="name" /> </declare-styleable> </resources> core/res/res/values/public.xml +1 −0 Original line number Diff line number Diff line Loading @@ -2041,6 +2041,7 @@ =============================================================== --> <eat-comment /> <public type="attr" name="keyset" id="0x010103cf" /> <public type="attr" name="windowOverscan" /> <public type="style" name="Theme.NoTitleBar.Overscan" /> <public type="style" name="Theme.Light.NoTitleBar.Overscan" /> Loading Loading
api/current.txt +2 −1 Original line number Diff line number Diff line Loading @@ -620,6 +620,7 @@ package android { field public static final int keyboardLayout = 16843691; // 0x10103ab field public static final int keyboardMode = 16843341; // 0x101024d field public static final int keycode = 16842949; // 0x10100c5 field public static final int keyset = 16843727; // 0x10103cf field public static final int killAfterRestore = 16843420; // 0x101029c field public static final int label = 16842753; // 0x1010001 field public static final int labelFor = 16843718; // 0x10103c6 Loading Loading @@ -1174,7 +1175,7 @@ package android { field public static final int windowMinWidthMinor = 16843607; // 0x1010357 field public static final int windowNoDisplay = 16843294; // 0x101021e field public static final int windowNoTitle = 16842838; // 0x1010056 field public static final int windowOverscan = 16843727; // 0x10103cf field public static final int windowOverscan = 16843728; // 0x10103d0 field public static final int windowShowAnimation = 16842934; // 0x10100b6 field public static final int windowShowWallpaper = 16843410; // 0x1010292 field public static final int windowSoftInputMode = 16843307; // 0x101022b
core/java/android/content/pm/KeySet.java 0 → 100644 +34 −0 Original line number Diff line number Diff line /* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.content.pm; import android.os.Binder; /** @hide */ public class KeySet { private Binder token; /** @hide */ public KeySet(Binder token) { this.token = token; } Binder getToken() { return token; } } No newline at end of file
core/java/android/content/pm/PackageParser.java +100 −6 Original line number Diff line number Diff line Loading @@ -46,14 +46,20 @@ import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateFactory; import java.security.cert.CertPath; import java.security.cert.X509Certificate; import java.security.spec.EncodedKeySpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; Loading Loading @@ -689,6 +695,13 @@ public class PackageParser { mParseError = PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES; return false; } // Add the signing KeySet to the system pkg.mSigningKeys = new HashSet<PublicKey>(); for (int i=0; i < certs.length; i++) { pkg.mSigningKeys.add(certs[i].getPublicKey()); } } catch (CertificateEncodingException e) { Slog.w(TAG, "Exception reading " + mArchiveSourcePath, e); mParseError = PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING; Loading Loading @@ -1002,6 +1015,10 @@ public class PackageParser { if (!parseApplication(pkg, res, parser, attrs, flags, outError)) { return null; } } else if (tagName.equals("keys")) { if (!parseKeys(pkg, res, parser, attrs, outError)) { return null; } } else if (tagName.equals("permission-group")) { if (parsePermissionGroup(pkg, flags, res, parser, attrs, outError) == null) { return null; Loading Loading @@ -1465,6 +1482,70 @@ public class PackageParser { return buildCompoundName(pkg, procSeq, "taskAffinity", outError); } private boolean parseKeys(Package owner, Resources res, XmlPullParser parser, AttributeSet attrs, String[] outError) throws XmlPullParserException, IOException { // we've encountered the 'keys' 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 type; PublicKey currentKey = null; Map<PublicKey, Set<String>> definedKeySets = new HashMap<PublicKey, Set<String>>(); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG) { 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); definedKeySets.put(currentKey, new HashSet<String>()); sa.recycle(); } else if (tagname.equals("keyset")) { 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); sa.recycle(); } else if (RIGID_PARSER) { Slog.w(TAG, "Bad element under <keys>: " + parser.getName() + " at " + mArchiveSourcePath + " " + parser.getPositionDescription()); return false; } else { Slog.w(TAG, "Unknown element under <keys>: " + parser.getName() + " at " + mArchiveSourcePath + " " + parser.getPositionDescription()); XmlUtils.skipCurrentTag(parser); continue; } } owner.mKeySetMapping = new HashMap<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 HashSet<PublicKey>(); keys.add(key); owner.mKeySetMapping.put(alias, keys); } } } return true; } private PermissionGroup parsePermissionGroup(Package owner, int flags, Resources res, XmlPullParser parser, AttributeSet attrs, String[] outError) throws XmlPullParserException, IOException { Loading Loading @@ -2988,20 +3069,28 @@ public class PackageParser { Slog.i(TAG, "verifier " + packageName + " public key was null; skipping"); } PublicKey publicKey = parsePublicKey(encodedPublicKey); if (publicKey != null) { return new VerifierInfo(packageName, publicKey); } return null; } public static final PublicKey parsePublicKey(String encodedPublicKey) { EncodedKeySpec keySpec; try { final byte[] encoded = Base64.decode(encodedPublicKey, Base64.DEFAULT); keySpec = new X509EncodedKeySpec(encoded); } catch (IllegalArgumentException e) { Slog.i(TAG, "Could not parse verifier " + packageName + " public key; invalid Base64"); Slog.i(TAG, "Could not parse verifier public key; invalid Base64"); return null; } /* First try the key as an RSA key. */ try { final KeyFactory keyFactory = KeyFactory.getInstance("RSA"); final PublicKey publicKey = keyFactory.generatePublic(keySpec); return new VerifierInfo(packageName, publicKey); return keyFactory.generatePublic(keySpec); } catch (NoSuchAlgorithmException e) { Log.wtf(TAG, "Could not parse public key because RSA isn't included in build"); return null; Loading @@ -3012,8 +3101,7 @@ public class PackageParser { /* Now try it as a DSA key. */ try { final KeyFactory keyFactory = KeyFactory.getInstance("DSA"); final PublicKey publicKey = keyFactory.generatePublic(keySpec); return new VerifierInfo(packageName, publicKey); return keyFactory.generatePublic(keySpec); } catch (NoSuchAlgorithmException e) { Log.wtf(TAG, "Could not parse public key because DSA isn't included in build"); return null; Loading Loading @@ -3254,6 +3342,12 @@ public class PackageParser { */ public ManifestDigest manifestDigest; /** * Data used to feed the KeySetManager */ public Set<PublicKey> mSigningKeys; public Map<String, Set<PublicKey>> mKeySetMapping; public Package(String _name) { packageName = _name; applicationInfo.packageName = _name; Loading
core/res/res/values/attrs_manifest.xml +8 −0 Original line number Diff line number Diff line Loading @@ -1699,4 +1699,12 @@ <!-- Concrete value to put for this named extra data. --> <attr name="value" /> </declare-styleable> <attr name="keyset" /> <declare-styleable name="PublicKey"> <attr name="value" /> </declare-styleable> <declare-styleable name="KeySet"> <attr name="name" /> </declare-styleable> </resources>
core/res/res/values/public.xml +1 −0 Original line number Diff line number Diff line Loading @@ -2041,6 +2041,7 @@ =============================================================== --> <eat-comment /> <public type="attr" name="keyset" id="0x010103cf" /> <public type="attr" name="windowOverscan" /> <public type="style" name="Theme.NoTitleBar.Overscan" /> <public type="style" name="Theme.Light.NoTitleBar.Overscan" /> Loading