diff options
author | Kenny Root <kroot@google.com> | 2013-04-03 14:04:14 -0700 |
---|---|---|
committer | Kenny Root <kroot@google.com> | 2013-04-03 14:04:14 -0700 |
commit | de1175db67da94dc3bb2c1bf2cf20b961f67ccc0 (patch) | |
tree | 89716c999daff835a7745cf76f67021613f6c9be | |
parent | 0147afa7422331b4fff91d20580e013d293f12ab (diff) | |
parent | 0afa8b36942951e89e9cd4572148416d48cfc09f (diff) | |
download | frameworks_base-de1175db67da94dc3bb2c1bf2cf20b961f67ccc0.zip frameworks_base-de1175db67da94dc3bb2c1bf2cf20b961f67ccc0.tar.gz frameworks_base-de1175db67da94dc3bb2c1bf2cf20b961f67ccc0.tar.bz2 |
resolved conflicts for merge of 0afa8b36 to master
Change-Id: I09a453ab5dbad58e3dc0858972e222a34d53b282
3 files changed, 85 insertions, 66 deletions
diff --git a/core/java/android/content/pm/ManifestDigest.java b/core/java/android/content/pm/ManifestDigest.java index 75505bc..409b5ae 100644 --- a/core/java/android/content/pm/ManifestDigest.java +++ b/core/java/android/content/pm/ManifestDigest.java @@ -18,10 +18,17 @@ package android.content.pm; import android.os.Parcel; import android.os.Parcelable; -import android.util.Base64; - +import android.util.Slog; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.DigestInputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.Arrays; -import java.util.jar.Attributes; + +import libcore.io.IoUtils; /** * Represents the manifest digest for a package. This is suitable for comparison @@ -30,17 +37,17 @@ import java.util.jar.Attributes; * @hide */ public class ManifestDigest implements Parcelable { + private static final String TAG = "ManifestDigest"; + /** The digest of the manifest in our preferred order. */ private final byte[] mDigest; - /** Digest field names to look for in preferred order. */ - private static final String[] DIGEST_TYPES = { - "SHA1-Digest", "SHA-Digest", "MD5-Digest", - }; - /** What we print out first when toString() is called. */ private static final String TO_STRING_PREFIX = "ManifestDigest {mDigest="; + /** Digest algorithm to use. */ + private static final String DIGEST_ALGORITHM = "SHA-256"; + ManifestDigest(byte[] digest) { mDigest = digest; } @@ -49,26 +56,32 @@ public class ManifestDigest implements Parcelable { mDigest = source.createByteArray(); } - static ManifestDigest fromAttributes(Attributes attributes) { - if (attributes == null) { + static ManifestDigest fromInputStream(InputStream fileIs) { + if (fileIs == null) { return null; } - String encodedDigest = null; - - for (int i = 0; i < DIGEST_TYPES.length; i++) { - final String value = attributes.getValue(DIGEST_TYPES[i]); - if (value != null) { - encodedDigest = value; - break; - } + final MessageDigest md; + try { + md = MessageDigest.getInstance(DIGEST_ALGORITHM); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(DIGEST_ALGORITHM + " must be available", e); } - if (encodedDigest == null) { + final DigestInputStream dis = new DigestInputStream(new BufferedInputStream(fileIs), md); + try { + byte[] readBuffer = new byte[8192]; + while (dis.read(readBuffer, 0, readBuffer.length) != -1) { + // not using + } + } catch (IOException e) { + Slog.w(TAG, "Could not read manifest"); return null; + } finally { + IoUtils.closeQuietly(dis); } - final byte[] digest = Base64.decode(encodedDigest, Base64.DEFAULT); + final byte[] digest = md.digest(); return new ManifestDigest(digest); } diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index ae9df67..aab830a 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -24,7 +24,6 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; -import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.PatternMatcher; @@ -60,10 +59,9 @@ 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; -import java.util.jar.Manifest; +import java.util.zip.ZipEntry; import com.android.internal.util.XmlUtils; @@ -573,6 +571,28 @@ public class PackageParser { return pkg; } + /** + * Gathers the {@link ManifestDigest} for {@code pkg} if it exists in the + * APK. If it successfully scanned the package and found the + * {@code AndroidManifest.xml}, {@code true} is returned. + */ + public boolean collectManifestDigest(Package pkg) { + try { + final JarFile jarFile = new JarFile(mArchiveSourcePath); + try { + final ZipEntry je = jarFile.getEntry(ANDROID_MANIFEST_FILENAME); + if (je != null) { + pkg.manifestDigest = ManifestDigest.fromInputStream(jarFile.getInputStream(je)); + } + } finally { + jarFile.close(); + } + return true; + } catch (IOException e) { + return false; + } + } + public boolean collectCertificates(Package pkg, int flags) { pkg.mSignatures = null; @@ -624,7 +644,6 @@ public class PackageParser { } } else { Enumeration<JarEntry> entries = jarFile.entries(); - final Manifest manifest = jarFile.getManifest(); while (entries.hasMoreElements()) { final JarEntry je = entries.nextElement(); if (je.isDirectory()) continue; @@ -635,8 +654,8 @@ public class PackageParser { continue; if (ANDROID_MANIFEST_FILENAME.equals(name)) { - final Attributes attributes = manifest.getAttributes(name); - pkg.manifestDigest = ManifestDigest.fromAttributes(attributes); + pkg.manifestDigest = + ManifestDigest.fromInputStream(jarFile.getInputStream(je)); } final Certificate[] localCerts = loadCertificates(jarFile, je, readBuffer); diff --git a/core/tests/coretests/src/android/content/pm/ManifestDigestTest.java b/core/tests/coretests/src/android/content/pm/ManifestDigestTest.java index cc8c4a6..37495e1 100644 --- a/core/tests/coretests/src/android/content/pm/ManifestDigestTest.java +++ b/core/tests/coretests/src/android/content/pm/ManifestDigestTest.java @@ -18,64 +18,51 @@ package android.content.pm; import android.os.Parcel; import android.test.AndroidTestCase; -import android.util.Base64; -import java.util.jar.Attributes; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.MessageDigest; public class ManifestDigestTest extends AndroidTestCase { - private static final byte[] DIGEST_1 = { + private static final byte[] MESSAGE_1 = { (byte) 0x00, (byte) 0xAA, (byte) 0x55, (byte) 0xFF }; - private static final String DIGEST_1_STR = Base64.encodeToString(DIGEST_1, Base64.DEFAULT); - - private static final byte[] DIGEST_2 = { - (byte) 0x0A, (byte) 0xA5, (byte) 0xF0, (byte) 0x5A - }; - - private static final String DIGEST_2_STR = Base64.encodeToString(DIGEST_2, Base64.DEFAULT); - - private static final Attributes.Name SHA1_DIGEST = new Attributes.Name("SHA1-Digest"); - - private static final Attributes.Name MD5_DIGEST = new Attributes.Name("MD5-Digest"); - - public void testManifestDigest_FromAttributes_Null() { + public void testManifestDigest_FromInputStream_Null() { assertNull("Attributes were null, so ManifestDigest.fromAttributes should return null", - ManifestDigest.fromAttributes(null)); + ManifestDigest.fromInputStream(null)); } - public void testManifestDigest_FromAttributes_NoAttributes() { - Attributes a = new Attributes(); + public void testManifestDigest_FromInputStream_ThrowsIoException() { + InputStream is = new InputStream() { + @Override + public int read() throws IOException { + throw new IOException(); + } + }; - assertNull("There were no attributes to extract, so ManifestDigest should be null", - ManifestDigest.fromAttributes(a)); + assertNull("InputStream threw exception, so ManifestDigest should be null", + ManifestDigest.fromInputStream(is)); } - public void testManifestDigest_FromAttributes_SHA1PreferredOverMD5() { - Attributes a = new Attributes(); - a.put(SHA1_DIGEST, DIGEST_1_STR); - - a.put(MD5_DIGEST, DIGEST_2_STR); - - ManifestDigest fromAttributes = ManifestDigest.fromAttributes(a); - - assertNotNull("A valid ManifestDigest should be returned", fromAttributes); + public void testManifestDigest_Equals() throws Exception { + InputStream is = new ByteArrayInputStream(MESSAGE_1); - ManifestDigest created = new ManifestDigest(DIGEST_1); + ManifestDigest expected = + new ManifestDigest(MessageDigest.getInstance("SHA-256").digest(MESSAGE_1)); - assertEquals("SHA-1 should be preferred over MD5: " + created.toString() + " vs. " - + fromAttributes.toString(), created, fromAttributes); + ManifestDigest actual = ManifestDigest.fromInputStream(is); + assertEquals(expected, actual); - assertEquals("Hash codes should be the same: " + created.toString() + " vs. " - + fromAttributes.toString(), created.hashCode(), fromAttributes - .hashCode()); + ManifestDigest unexpected = new ManifestDigest(new byte[0]); + assertFalse(unexpected.equals(actual)); } - public void testManifestDigest_Parcel() { - Attributes a = new Attributes(); - a.put(SHA1_DIGEST, DIGEST_1_STR); + public void testManifestDigest_Parcel() throws Exception { + InputStream is = new ByteArrayInputStream(MESSAGE_1); - ManifestDigest digest = ManifestDigest.fromAttributes(a); + ManifestDigest digest = ManifestDigest.fromInputStream(is); Parcel p = Parcel.obtain(); digest.writeToParcel(p, 0); |