Loading core/java/android/content/pm/ContainerEncryptionParams.java +15 −13 Original line number Diff line number Diff line Loading @@ -70,16 +70,16 @@ public class ContainerEncryptionParams implements Parcelable { private final byte[] mMacTag; /** Offset into file where authenticated (e.g., MAC protected) data begins. */ private final int mAuthenticatedDataStart; private final long mAuthenticatedDataStart; /** Offset into file where encrypted data begins. */ private final int mEncryptedDataStart; private final long mEncryptedDataStart; /** * Offset into file for the end of encrypted data (and, by extension, * authenticated data) in file. */ private final int mDataEnd; private final long mDataEnd; public ContainerEncryptionParams(String encryptionAlgorithm, AlgorithmParameterSpec encryptionSpec, SecretKey encryptionKey) Loading @@ -99,6 +99,8 @@ public class ContainerEncryptionParams implements Parcelable { * @param macAlgorithm MAC algorithm to use; format matches JCE * @param macSpec algorithm parameters specification, may be {@code null} * @param macKey key used for authentication (i.e., for the MAC tag) * @param macTag message authentication code (MAC) tag for the authenticated * data * @param authenticatedDataStart offset of start of authenticated data in * stream * @param encryptedDataStart offset of start of encrypted data in stream Loading @@ -109,7 +111,7 @@ public class ContainerEncryptionParams implements Parcelable { public ContainerEncryptionParams(String encryptionAlgorithm, AlgorithmParameterSpec encryptionSpec, SecretKey encryptionKey, String macAlgorithm, AlgorithmParameterSpec macSpec, SecretKey macKey, byte[] macTag, int authenticatedDataStart, int encryptedDataStart, int dataEnd) long authenticatedDataStart, long encryptedDataStart, long dataEnd) throws InvalidAlgorithmParameterException { if (TextUtils.isEmpty(encryptionAlgorithm)) { throw new NullPointerException("algorithm == null"); Loading Loading @@ -172,15 +174,15 @@ public class ContainerEncryptionParams implements Parcelable { return mMacTag; } public int getAuthenticatedDataStart() { public long getAuthenticatedDataStart() { return mAuthenticatedDataStart; } public int getEncryptedDataStart() { public long getEncryptedDataStart() { return mEncryptedDataStart; } public int getDataEnd() { public long getDataEnd() { return mDataEnd; } Loading Loading @@ -315,9 +317,9 @@ public class ContainerEncryptionParams implements Parcelable { dest.writeByteArray(mMacTag); dest.writeInt(mAuthenticatedDataStart); dest.writeInt(mEncryptedDataStart); dest.writeInt(mDataEnd); dest.writeLong(mAuthenticatedDataStart); dest.writeLong(mEncryptedDataStart); dest.writeLong(mDataEnd); } private ContainerEncryptionParams(Parcel source) throws InvalidAlgorithmParameterException { Loading @@ -333,9 +335,9 @@ public class ContainerEncryptionParams implements Parcelable { mMacTag = source.createByteArray(); mAuthenticatedDataStart = source.readInt(); mEncryptedDataStart = source.readInt(); mDataEnd = source.readInt(); mAuthenticatedDataStart = source.readLong(); mEncryptedDataStart = source.readLong(); mDataEnd = source.readLong(); switch (encParamType) { case ENC_PARAMS_IV_PARAMETERS: Loading core/java/android/content/pm/LimitedLengthInputStream.java +19 −7 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ package android.content.pm; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; /** * A class that limits the amount of data that is read from an InputStream. When Loading @@ -15,20 +16,20 @@ public class LimitedLengthInputStream extends FilterInputStream { /** * The end of the stream where we don't want to allow more data to be read. */ private final int mEnd; private final long mEnd; /** * Current offset in the stream. */ private int mOffset; private long mOffset; /** * @param in underlying stream to wrap * @param offset offset into stream where data starts * @param length length of data at offset * @throws IOException if an error occured with the underlying stream * @throws IOException if an error occurred with the underlying stream */ public LimitedLengthInputStream(InputStream in, int offset, int length) throws IOException { public LimitedLengthInputStream(InputStream in, long offset, long length) throws IOException { super(in); if (in == null) { Loading @@ -36,11 +37,15 @@ public class LimitedLengthInputStream extends FilterInputStream { } if (offset < 0) { throw new IOException("offset == " + offset); throw new IOException("offset < 0"); } if (length < 0) { throw new IOException("length must be non-negative; is " + length); throw new IOException("length < 0"); } if (length > Long.MAX_VALUE - offset) { throw new IOException("offset + length > Long.MAX_VALUE"); } mEnd = offset + length; Loading @@ -65,8 +70,15 @@ public class LimitedLengthInputStream extends FilterInputStream { return -1; } final int arrayLength = buffer.length; Arrays.checkOffsetAndCount(arrayLength, offset, byteCount); if (mOffset > Long.MAX_VALUE - byteCount) { throw new IOException("offset out of bounds: " + mOffset + " + " + byteCount); } if (mOffset + byteCount > mEnd) { byteCount = mEnd - mOffset; byteCount = (int) (mEnd - mOffset); } final int numRead = super.read(buffer, offset, byteCount); Loading core/tests/coretests/src/android/content/pm/LimitedLengthInputStreamTest.java +11 −1 Original line number Diff line number Diff line Loading @@ -66,6 +66,17 @@ public class LimitedLengthInputStreamTest extends AndroidTestCase { } } @MediumTest public void testConstructor_OffsetLengthOverflow_Fail() throws Exception { try { InputStream is = new LimitedLengthInputStream(mTestStream1, Long.MAX_VALUE - 1, Long.MAX_VALUE - 1); fail("Should fail when offset + length is > Long.MAX_VALUE"); } catch (IOException e) { // success } } private void checkReadBytesWithOffsetAndLength_WithString1(int offset, int length) throws Exception { byte[] temp = new byte[TEST_STRING1.length]; Loading Loading @@ -182,5 +193,4 @@ public class LimitedLengthInputStreamTest extends AndroidTestCase { public void testSingleByteRead_NonZeroOffset_FullLength_Success() throws Exception { checkSingleByteRead_WithString1(3, TEST_STRING1.length - 3); } } packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +18 −7 Original line number Diff line number Diff line Loading @@ -473,6 +473,8 @@ public class DefaultContainerService extends IntentService { } private static class ApkContainer { private static final int MAX_AUTHENTICATED_DATA_SIZE = 16384; private final InputStream mInStream; private MacAuthenticatedInputStream mAuthenticatedStream; Loading Loading @@ -540,26 +542,35 @@ public class DefaultContainerService extends IntentService { throw new IOException(e); } final int encStart = encryptionParams.getEncryptedDataStart(); final int end = encryptionParams.getDataEnd(); final long encStart = encryptionParams.getEncryptedDataStart(); final long end = encryptionParams.getDataEnd(); if (end < encStart) { throw new IOException("end <= encStart"); } final Mac mac = getMacInstance(encryptionParams); if (mac != null) { final int macStart = encryptionParams.getAuthenticatedDataStart(); final long macStart = encryptionParams.getAuthenticatedDataStart(); if (macStart >= Integer.MAX_VALUE) { throw new IOException("macStart >= Integer.MAX_VALUE"); } final int furtherOffset; final long furtherOffset; if (macStart >= 0 && encStart >= 0 && macStart < encStart) { /* * If there is authenticated data at the beginning, read * that into our MAC first. */ final int authenticatedLength = encStart - macStart; final byte[] authenticatedData = new byte[authenticatedLength]; final long authenticatedLengthLong = encStart - macStart; if (authenticatedLengthLong > MAX_AUTHENTICATED_DATA_SIZE) { throw new IOException("authenticated data is too long"); } final int authenticatedLength = (int) authenticatedLengthLong; final byte[] authenticatedData = new byte[(int) authenticatedLength]; Streams.readFully(inStream, authenticatedData, macStart, authenticatedLength); Streams.readFully(inStream, authenticatedData, (int) macStart, authenticatedLength); mac.update(authenticatedData, 0, authenticatedLength); furtherOffset = 0; Loading Loading
core/java/android/content/pm/ContainerEncryptionParams.java +15 −13 Original line number Diff line number Diff line Loading @@ -70,16 +70,16 @@ public class ContainerEncryptionParams implements Parcelable { private final byte[] mMacTag; /** Offset into file where authenticated (e.g., MAC protected) data begins. */ private final int mAuthenticatedDataStart; private final long mAuthenticatedDataStart; /** Offset into file where encrypted data begins. */ private final int mEncryptedDataStart; private final long mEncryptedDataStart; /** * Offset into file for the end of encrypted data (and, by extension, * authenticated data) in file. */ private final int mDataEnd; private final long mDataEnd; public ContainerEncryptionParams(String encryptionAlgorithm, AlgorithmParameterSpec encryptionSpec, SecretKey encryptionKey) Loading @@ -99,6 +99,8 @@ public class ContainerEncryptionParams implements Parcelable { * @param macAlgorithm MAC algorithm to use; format matches JCE * @param macSpec algorithm parameters specification, may be {@code null} * @param macKey key used for authentication (i.e., for the MAC tag) * @param macTag message authentication code (MAC) tag for the authenticated * data * @param authenticatedDataStart offset of start of authenticated data in * stream * @param encryptedDataStart offset of start of encrypted data in stream Loading @@ -109,7 +111,7 @@ public class ContainerEncryptionParams implements Parcelable { public ContainerEncryptionParams(String encryptionAlgorithm, AlgorithmParameterSpec encryptionSpec, SecretKey encryptionKey, String macAlgorithm, AlgorithmParameterSpec macSpec, SecretKey macKey, byte[] macTag, int authenticatedDataStart, int encryptedDataStart, int dataEnd) long authenticatedDataStart, long encryptedDataStart, long dataEnd) throws InvalidAlgorithmParameterException { if (TextUtils.isEmpty(encryptionAlgorithm)) { throw new NullPointerException("algorithm == null"); Loading Loading @@ -172,15 +174,15 @@ public class ContainerEncryptionParams implements Parcelable { return mMacTag; } public int getAuthenticatedDataStart() { public long getAuthenticatedDataStart() { return mAuthenticatedDataStart; } public int getEncryptedDataStart() { public long getEncryptedDataStart() { return mEncryptedDataStart; } public int getDataEnd() { public long getDataEnd() { return mDataEnd; } Loading Loading @@ -315,9 +317,9 @@ public class ContainerEncryptionParams implements Parcelable { dest.writeByteArray(mMacTag); dest.writeInt(mAuthenticatedDataStart); dest.writeInt(mEncryptedDataStart); dest.writeInt(mDataEnd); dest.writeLong(mAuthenticatedDataStart); dest.writeLong(mEncryptedDataStart); dest.writeLong(mDataEnd); } private ContainerEncryptionParams(Parcel source) throws InvalidAlgorithmParameterException { Loading @@ -333,9 +335,9 @@ public class ContainerEncryptionParams implements Parcelable { mMacTag = source.createByteArray(); mAuthenticatedDataStart = source.readInt(); mEncryptedDataStart = source.readInt(); mDataEnd = source.readInt(); mAuthenticatedDataStart = source.readLong(); mEncryptedDataStart = source.readLong(); mDataEnd = source.readLong(); switch (encParamType) { case ENC_PARAMS_IV_PARAMETERS: Loading
core/java/android/content/pm/LimitedLengthInputStream.java +19 −7 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ package android.content.pm; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; /** * A class that limits the amount of data that is read from an InputStream. When Loading @@ -15,20 +16,20 @@ public class LimitedLengthInputStream extends FilterInputStream { /** * The end of the stream where we don't want to allow more data to be read. */ private final int mEnd; private final long mEnd; /** * Current offset in the stream. */ private int mOffset; private long mOffset; /** * @param in underlying stream to wrap * @param offset offset into stream where data starts * @param length length of data at offset * @throws IOException if an error occured with the underlying stream * @throws IOException if an error occurred with the underlying stream */ public LimitedLengthInputStream(InputStream in, int offset, int length) throws IOException { public LimitedLengthInputStream(InputStream in, long offset, long length) throws IOException { super(in); if (in == null) { Loading @@ -36,11 +37,15 @@ public class LimitedLengthInputStream extends FilterInputStream { } if (offset < 0) { throw new IOException("offset == " + offset); throw new IOException("offset < 0"); } if (length < 0) { throw new IOException("length must be non-negative; is " + length); throw new IOException("length < 0"); } if (length > Long.MAX_VALUE - offset) { throw new IOException("offset + length > Long.MAX_VALUE"); } mEnd = offset + length; Loading @@ -65,8 +70,15 @@ public class LimitedLengthInputStream extends FilterInputStream { return -1; } final int arrayLength = buffer.length; Arrays.checkOffsetAndCount(arrayLength, offset, byteCount); if (mOffset > Long.MAX_VALUE - byteCount) { throw new IOException("offset out of bounds: " + mOffset + " + " + byteCount); } if (mOffset + byteCount > mEnd) { byteCount = mEnd - mOffset; byteCount = (int) (mEnd - mOffset); } final int numRead = super.read(buffer, offset, byteCount); Loading
core/tests/coretests/src/android/content/pm/LimitedLengthInputStreamTest.java +11 −1 Original line number Diff line number Diff line Loading @@ -66,6 +66,17 @@ public class LimitedLengthInputStreamTest extends AndroidTestCase { } } @MediumTest public void testConstructor_OffsetLengthOverflow_Fail() throws Exception { try { InputStream is = new LimitedLengthInputStream(mTestStream1, Long.MAX_VALUE - 1, Long.MAX_VALUE - 1); fail("Should fail when offset + length is > Long.MAX_VALUE"); } catch (IOException e) { // success } } private void checkReadBytesWithOffsetAndLength_WithString1(int offset, int length) throws Exception { byte[] temp = new byte[TEST_STRING1.length]; Loading Loading @@ -182,5 +193,4 @@ public class LimitedLengthInputStreamTest extends AndroidTestCase { public void testSingleByteRead_NonZeroOffset_FullLength_Success() throws Exception { checkSingleByteRead_WithString1(3, TEST_STRING1.length - 3); } }
packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +18 −7 Original line number Diff line number Diff line Loading @@ -473,6 +473,8 @@ public class DefaultContainerService extends IntentService { } private static class ApkContainer { private static final int MAX_AUTHENTICATED_DATA_SIZE = 16384; private final InputStream mInStream; private MacAuthenticatedInputStream mAuthenticatedStream; Loading Loading @@ -540,26 +542,35 @@ public class DefaultContainerService extends IntentService { throw new IOException(e); } final int encStart = encryptionParams.getEncryptedDataStart(); final int end = encryptionParams.getDataEnd(); final long encStart = encryptionParams.getEncryptedDataStart(); final long end = encryptionParams.getDataEnd(); if (end < encStart) { throw new IOException("end <= encStart"); } final Mac mac = getMacInstance(encryptionParams); if (mac != null) { final int macStart = encryptionParams.getAuthenticatedDataStart(); final long macStart = encryptionParams.getAuthenticatedDataStart(); if (macStart >= Integer.MAX_VALUE) { throw new IOException("macStart >= Integer.MAX_VALUE"); } final int furtherOffset; final long furtherOffset; if (macStart >= 0 && encStart >= 0 && macStart < encStart) { /* * If there is authenticated data at the beginning, read * that into our MAC first. */ final int authenticatedLength = encStart - macStart; final byte[] authenticatedData = new byte[authenticatedLength]; final long authenticatedLengthLong = encStart - macStart; if (authenticatedLengthLong > MAX_AUTHENTICATED_DATA_SIZE) { throw new IOException("authenticated data is too long"); } final int authenticatedLength = (int) authenticatedLengthLong; final byte[] authenticatedData = new byte[(int) authenticatedLength]; Streams.readFully(inStream, authenticatedData, macStart, authenticatedLength); Streams.readFully(inStream, authenticatedData, (int) macStart, authenticatedLength); mac.update(authenticatedData, 0, authenticatedLength); furtherOffset = 0; Loading