Loading core/java/android/content/pm/PackageInfoLite.java +17 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ public class PackageInfoLite implements Parcelable { public int recommendedInstallLocation; public int installLocation; public VerifierInfo[] verifiers; public PackageInfoLite() { } Loading @@ -58,6 +60,13 @@ public class PackageInfoLite implements Parcelable { dest.writeString(packageName); dest.writeInt(recommendedInstallLocation); dest.writeInt(installLocation); if (verifiers == null || verifiers.length == 0) { dest.writeInt(0); } else { dest.writeInt(verifiers.length); dest.writeTypedArray(verifiers, parcelableFlags); } } public static final Parcelable.Creator<PackageInfoLite> CREATOR Loading @@ -75,5 +84,13 @@ public class PackageInfoLite implements Parcelable { packageName = source.readString(); recommendedInstallLocation = source.readInt(); installLocation = source.readInt(); final int verifiersLength = source.readInt(); if (verifiersLength == 0) { verifiers = new VerifierInfo[0]; } else { verifiers = new VerifierInfo[verifiersLength]; source.readTypedArray(verifiers, VerifierInfo.CREATOR); } } } core/java/android/content/pm/PackageManager.java +10 −0 Original line number Diff line number Diff line Loading @@ -724,6 +724,16 @@ public abstract class PackageManager { */ public static final int MOVE_EXTERNAL_MEDIA = 0x00000002; /** * Usable by the required verifier as the {@code verificationCode} argument * for {@link PackageManager#verifyPendingInstall} to indicate that it will * allow the installation to proceed without any of the optional verifiers * needing to vote. * * @hide */ public static final int VERIFICATION_ALLOW_WITHOUT_SUFFICIENT = 2; /** * Used as the {@code verificationCode} argument for * {@link PackageManager#verifyPendingInstall} to indicate that the calling Loading core/java/android/content/pm/PackageParser.java +104 −12 Original line number Diff line number Diff line Loading @@ -28,7 +28,9 @@ import android.os.Build; import android.os.Bundle; import android.os.PatternMatcher; import android.util.AttributeSet; import android.util.Base64; import android.util.DisplayMetrics; import android.util.Log; import android.util.Slog; import android.util.TypedValue; import com.android.internal.util.XmlUtils; Loading @@ -40,11 +42,18 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.lang.ref.WeakReference; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; 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.Iterator; import java.util.List; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; Loading Loading @@ -150,12 +159,14 @@ public class PackageParser { * @hide */ public static class PackageLite { public String packageName; public int installLocation; public String mScanPath; public PackageLite(String packageName, int installLocation) { public final String packageName; public final int installLocation; public final VerifierInfo[] verifiers; public PackageLite(String packageName, int installLocation, List<VerifierInfo> verifiers) { this.packageName = packageName; this.installLocation = installLocation; this.verifiers = verifiers.toArray(new VerifierInfo[verifiers.size()]); } } Loading Loading @@ -619,8 +630,9 @@ public class PackageParser { * @return PackageLite object with package information or null on failure. */ public static PackageLite parsePackageLite(String packageFilePath, int flags) { XmlResourceParser parser = null; AssetManager assmgr = null; final XmlResourceParser parser; final Resources res; try { assmgr = new AssetManager(); assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Loading @@ -631,6 +643,9 @@ public class PackageParser { return null; } final DisplayMetrics metrics = new DisplayMetrics(); metrics.setToDefaults(); res = new Resources(assmgr, metrics, null); parser = assmgr.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME); } catch (Exception e) { if (assmgr != null) assmgr.close(); Loading @@ -638,11 +653,12 @@ public class PackageParser { + packageFilePath, e); return null; } AttributeSet attrs = parser; String errors[] = new String[1]; final AttributeSet attrs = parser; final String errors[] = new String[1]; PackageLite packageLite = null; try { packageLite = parsePackageLite(parser, attrs, flags, errors); packageLite = parsePackageLite(res, parser, attrs, flags, errors); } catch (IOException e) { Slog.w(TAG, packageFilePath, e); } catch (XmlPullParserException e) { Loading Loading @@ -719,9 +735,9 @@ public class PackageParser { return pkgName.intern(); } private static PackageLite parsePackageLite(XmlPullParser parser, AttributeSet attrs, int flags, String[] outError) throws IOException, XmlPullParserException { private static PackageLite parsePackageLite(Resources res, XmlPullParser parser, AttributeSet attrs, int flags, String[] outError) throws IOException, XmlPullParserException { int type; while ((type = parser.next()) != XmlPullParser.START_TAG Loading Loading @@ -759,7 +775,26 @@ public class PackageParser { break; } } return new PackageLite(pkgName.intern(), installLocation); // Only search the tree when the tag is directly below <manifest> final int searchDepth = parser.getDepth() + 1; final List<VerifierInfo> verifiers = new ArrayList<VerifierInfo>(); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() >= searchDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } if (parser.getDepth() == searchDepth && "package-verifier".equals(parser.getName())) { final VerifierInfo verifier = parseVerifier(res, parser, attrs, flags, outError); if (verifier != null) { verifiers.add(verifier); } } } return new PackageLite(pkgName.intern(), installLocation, verifiers); } /** Loading Loading @@ -2691,6 +2726,63 @@ public class PackageParser { return data; } private static VerifierInfo parseVerifier(Resources res, XmlPullParser parser, AttributeSet attrs, int flags, String[] outError) throws XmlPullParserException, IOException { final TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestPackageVerifier); final String packageName = sa.getNonResourceString( com.android.internal.R.styleable.AndroidManifestPackageVerifier_name); final String encodedPublicKey = sa.getNonResourceString( com.android.internal.R.styleable.AndroidManifestPackageVerifier_publicKey); sa.recycle(); if (packageName == null || packageName.length() == 0) { Slog.i(TAG, "verifier package name was null; skipping"); return null; } else if (encodedPublicKey == null) { Slog.i(TAG, "verifier " + packageName + " public key was null; skipping"); } 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"); 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); } catch (NoSuchAlgorithmException e) { Log.wtf(TAG, "Could not parse public key because RSA isn't included in build"); return null; } catch (InvalidKeySpecException e) { // Not a RSA public key. } /* 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); } catch (NoSuchAlgorithmException e) { Log.wtf(TAG, "Could not parse public key because DSA isn't included in build"); return null; } catch (InvalidKeySpecException e) { // Not a DSA public key. } return null; } private static final String ANDROID_RESOURCES = "http://schemas.android.com/apk/res/android"; Loading core/java/android/content/pm/Signature.java +19 −0 Original line number Diff line number Diff line Loading @@ -19,7 +19,12 @@ package android.content.pm; import android.os.Parcel; import android.os.Parcelable; import java.io.ByteArrayInputStream; import java.lang.ref.SoftReference; import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.util.Arrays; /** Loading Loading @@ -135,6 +140,20 @@ public class Signature implements Parcelable { return bytes; } /** * Returns the public key for this signature. * * @throws CertificateException when Signature isn't a valid X.509 * certificate; shouldn't happen. * @hide */ public PublicKey getPublicKey() throws CertificateException { final CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); final ByteArrayInputStream bais = new ByteArrayInputStream(mSignature); final Certificate cert = certFactory.generateCertificate(bais); return cert.getPublicKey(); } @Override public boolean equals(Object obj) { try { Loading core/java/android/content/pm/VerifierInfo.aidl 0 → 100644 +19 −0 Original line number Diff line number Diff line /* * Copyright 2011, 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; parcelable VerifierInfo; Loading
core/java/android/content/pm/PackageInfoLite.java +17 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ public class PackageInfoLite implements Parcelable { public int recommendedInstallLocation; public int installLocation; public VerifierInfo[] verifiers; public PackageInfoLite() { } Loading @@ -58,6 +60,13 @@ public class PackageInfoLite implements Parcelable { dest.writeString(packageName); dest.writeInt(recommendedInstallLocation); dest.writeInt(installLocation); if (verifiers == null || verifiers.length == 0) { dest.writeInt(0); } else { dest.writeInt(verifiers.length); dest.writeTypedArray(verifiers, parcelableFlags); } } public static final Parcelable.Creator<PackageInfoLite> CREATOR Loading @@ -75,5 +84,13 @@ public class PackageInfoLite implements Parcelable { packageName = source.readString(); recommendedInstallLocation = source.readInt(); installLocation = source.readInt(); final int verifiersLength = source.readInt(); if (verifiersLength == 0) { verifiers = new VerifierInfo[0]; } else { verifiers = new VerifierInfo[verifiersLength]; source.readTypedArray(verifiers, VerifierInfo.CREATOR); } } }
core/java/android/content/pm/PackageManager.java +10 −0 Original line number Diff line number Diff line Loading @@ -724,6 +724,16 @@ public abstract class PackageManager { */ public static final int MOVE_EXTERNAL_MEDIA = 0x00000002; /** * Usable by the required verifier as the {@code verificationCode} argument * for {@link PackageManager#verifyPendingInstall} to indicate that it will * allow the installation to proceed without any of the optional verifiers * needing to vote. * * @hide */ public static final int VERIFICATION_ALLOW_WITHOUT_SUFFICIENT = 2; /** * Used as the {@code verificationCode} argument for * {@link PackageManager#verifyPendingInstall} to indicate that the calling Loading
core/java/android/content/pm/PackageParser.java +104 −12 Original line number Diff line number Diff line Loading @@ -28,7 +28,9 @@ import android.os.Build; import android.os.Bundle; import android.os.PatternMatcher; import android.util.AttributeSet; import android.util.Base64; import android.util.DisplayMetrics; import android.util.Log; import android.util.Slog; import android.util.TypedValue; import com.android.internal.util.XmlUtils; Loading @@ -40,11 +42,18 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.lang.ref.WeakReference; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; 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.Iterator; import java.util.List; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; Loading Loading @@ -150,12 +159,14 @@ public class PackageParser { * @hide */ public static class PackageLite { public String packageName; public int installLocation; public String mScanPath; public PackageLite(String packageName, int installLocation) { public final String packageName; public final int installLocation; public final VerifierInfo[] verifiers; public PackageLite(String packageName, int installLocation, List<VerifierInfo> verifiers) { this.packageName = packageName; this.installLocation = installLocation; this.verifiers = verifiers.toArray(new VerifierInfo[verifiers.size()]); } } Loading Loading @@ -619,8 +630,9 @@ public class PackageParser { * @return PackageLite object with package information or null on failure. */ public static PackageLite parsePackageLite(String packageFilePath, int flags) { XmlResourceParser parser = null; AssetManager assmgr = null; final XmlResourceParser parser; final Resources res; try { assmgr = new AssetManager(); assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Loading @@ -631,6 +643,9 @@ public class PackageParser { return null; } final DisplayMetrics metrics = new DisplayMetrics(); metrics.setToDefaults(); res = new Resources(assmgr, metrics, null); parser = assmgr.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME); } catch (Exception e) { if (assmgr != null) assmgr.close(); Loading @@ -638,11 +653,12 @@ public class PackageParser { + packageFilePath, e); return null; } AttributeSet attrs = parser; String errors[] = new String[1]; final AttributeSet attrs = parser; final String errors[] = new String[1]; PackageLite packageLite = null; try { packageLite = parsePackageLite(parser, attrs, flags, errors); packageLite = parsePackageLite(res, parser, attrs, flags, errors); } catch (IOException e) { Slog.w(TAG, packageFilePath, e); } catch (XmlPullParserException e) { Loading Loading @@ -719,9 +735,9 @@ public class PackageParser { return pkgName.intern(); } private static PackageLite parsePackageLite(XmlPullParser parser, AttributeSet attrs, int flags, String[] outError) throws IOException, XmlPullParserException { private static PackageLite parsePackageLite(Resources res, XmlPullParser parser, AttributeSet attrs, int flags, String[] outError) throws IOException, XmlPullParserException { int type; while ((type = parser.next()) != XmlPullParser.START_TAG Loading Loading @@ -759,7 +775,26 @@ public class PackageParser { break; } } return new PackageLite(pkgName.intern(), installLocation); // Only search the tree when the tag is directly below <manifest> final int searchDepth = parser.getDepth() + 1; final List<VerifierInfo> verifiers = new ArrayList<VerifierInfo>(); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() >= searchDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } if (parser.getDepth() == searchDepth && "package-verifier".equals(parser.getName())) { final VerifierInfo verifier = parseVerifier(res, parser, attrs, flags, outError); if (verifier != null) { verifiers.add(verifier); } } } return new PackageLite(pkgName.intern(), installLocation, verifiers); } /** Loading Loading @@ -2691,6 +2726,63 @@ public class PackageParser { return data; } private static VerifierInfo parseVerifier(Resources res, XmlPullParser parser, AttributeSet attrs, int flags, String[] outError) throws XmlPullParserException, IOException { final TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestPackageVerifier); final String packageName = sa.getNonResourceString( com.android.internal.R.styleable.AndroidManifestPackageVerifier_name); final String encodedPublicKey = sa.getNonResourceString( com.android.internal.R.styleable.AndroidManifestPackageVerifier_publicKey); sa.recycle(); if (packageName == null || packageName.length() == 0) { Slog.i(TAG, "verifier package name was null; skipping"); return null; } else if (encodedPublicKey == null) { Slog.i(TAG, "verifier " + packageName + " public key was null; skipping"); } 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"); 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); } catch (NoSuchAlgorithmException e) { Log.wtf(TAG, "Could not parse public key because RSA isn't included in build"); return null; } catch (InvalidKeySpecException e) { // Not a RSA public key. } /* 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); } catch (NoSuchAlgorithmException e) { Log.wtf(TAG, "Could not parse public key because DSA isn't included in build"); return null; } catch (InvalidKeySpecException e) { // Not a DSA public key. } return null; } private static final String ANDROID_RESOURCES = "http://schemas.android.com/apk/res/android"; Loading
core/java/android/content/pm/Signature.java +19 −0 Original line number Diff line number Diff line Loading @@ -19,7 +19,12 @@ package android.content.pm; import android.os.Parcel; import android.os.Parcelable; import java.io.ByteArrayInputStream; import java.lang.ref.SoftReference; import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.util.Arrays; /** Loading Loading @@ -135,6 +140,20 @@ public class Signature implements Parcelable { return bytes; } /** * Returns the public key for this signature. * * @throws CertificateException when Signature isn't a valid X.509 * certificate; shouldn't happen. * @hide */ public PublicKey getPublicKey() throws CertificateException { final CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); final ByteArrayInputStream bais = new ByteArrayInputStream(mSignature); final Certificate cert = certFactory.generateCertificate(bais); return cert.getPublicKey(); } @Override public boolean equals(Object obj) { try { Loading
core/java/android/content/pm/VerifierInfo.aidl 0 → 100644 +19 −0 Original line number Diff line number Diff line /* * Copyright 2011, 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; parcelable VerifierInfo;