Search in sources :

Example 1 with DataSource

use of com.android.apksig.util.DataSource in project LSPatch by LSPosed.

the class SigningBlockUtils method extractBlock.

/**
 * Extract a block with the given id from the APK. If there is more than one block with the same
 * ID, the first block will be returned. If there are no block with the give id, {@code null} will
 * be returned.
 *
 * @param apk APK file
 * @param blockId id of the block to be extracted.
 */
@Nullable
public static ByteBuffer extractBlock(File apk, int blockId) throws IOException, ZipFormatException, ApkSigningBlockNotFoundException {
    try (RandomAccessFile file = new RandomAccessFile(apk, "r")) {
        DataSource apkDataSource = DataSources.asDataSource(file);
        ApkSigningBlock signingBlockInfo = ApkUtils.findApkSigningBlock(apkDataSource, ApkUtils.findZipSections(apkDataSource));
        DataSource wholeV2Block = signingBlockInfo.getContents();
        final int lengthAndIdByteCount = BLOCK_LENGTH_NUM_BYTES + BLOCK_ID_NUM_BYTES;
        DataSource signingBlock = wholeV2Block.slice(SIZE_OF_BLOCK_NUM_BYTES, wholeV2Block.size() - SIZE_OF_BLOCK_NUM_BYTES - MAGIC_NUM_BYTES);
        ByteBuffer lengthAndId = ByteBuffer.allocate(lengthAndIdByteCount).order(ByteOrder.LITTLE_ENDIAN);
        for (int index = 0; index <= signingBlock.size() - lengthAndIdByteCount; ) {
            signingBlock.copyTo(index, lengthAndIdByteCount, lengthAndId);
            lengthAndId.flip();
            int blockLength = (int) lengthAndId.getLong();
            int id = lengthAndId.getInt();
            lengthAndId.flip();
            if (id == blockId) {
                ByteBuffer block = ByteBuffer.allocate(blockLength - BLOCK_ID_NUM_BYTES);
                signingBlock.copyTo(index + lengthAndIdByteCount, blockLength - BLOCK_ID_NUM_BYTES, block);
                block.flip();
                return block;
            }
            index += blockLength + BLOCK_LENGTH_NUM_BYTES;
        }
        return null;
    }
}
Also used : RandomAccessFile(java.io.RandomAccessFile) ApkSigningBlock(com.android.apksig.apk.ApkUtils.ApkSigningBlock) ByteBuffer(java.nio.ByteBuffer) DataSource(com.android.apksig.util.DataSource) Nullable(javax.annotation.Nullable)

Example 2 with DataSource

use of com.android.apksig.util.DataSource in project apksig by venshine.

the class ApkSigningBlockUtils method computeOneMbChunkContentDigests.

static void computeOneMbChunkContentDigests(RunnablesExecutor executor, Set<ContentDigestAlgorithm> digestAlgorithms, DataSource[] contents, Map<ContentDigestAlgorithm, byte[]> outputContentDigests) throws NoSuchAlgorithmException, DigestException {
    long chunkCountLong = 0;
    for (DataSource input : contents) {
        chunkCountLong += getChunkCount(input.size(), CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES);
    }
    if (chunkCountLong > Integer.MAX_VALUE) {
        throw new DigestException("Input too long: " + chunkCountLong + " chunks");
    }
    int chunkCount = (int) chunkCountLong;
    List<ChunkDigests> chunkDigestsList = new ArrayList<>(digestAlgorithms.size());
    for (ContentDigestAlgorithm algorithms : digestAlgorithms) {
        chunkDigestsList.add(new ChunkDigests(algorithms, chunkCount));
    }
    ChunkSupplier chunkSupplier = new ChunkSupplier(contents);
    executor.execute(() -> new ChunkDigester(chunkSupplier, chunkDigestsList));
    // Compute and write out final digest for each algorithm.
    for (ChunkDigests chunkDigests : chunkDigestsList) {
        MessageDigest messageDigest = chunkDigests.createMessageDigest();
        outputContentDigests.put(chunkDigests.algorithm, messageDigest.digest(chunkDigests.concatOfDigestsOfChunks));
    }
}
Also used : DigestException(java.security.DigestException) ArrayList(java.util.ArrayList) MessageDigest(java.security.MessageDigest) DataSource(com.android.apksig.util.DataSource) ChainedDataSource(com.android.apksig.internal.util.ChainedDataSource) ByteBufferDataSource(com.android.apksig.internal.util.ByteBufferDataSource)

Example 3 with DataSource

use of com.android.apksig.util.DataSource in project apksig by venshine.

the class ApkUtils method getAndroidManifest.

/**
 * Returns the contents of the APK's {@code AndroidManifest.xml}.
 *
 * @throws IOException if an I/O error occurs while reading the APK
 * @throws ApkFormatException if the APK is malformed
 */
public static ByteBuffer getAndroidManifest(DataSource apk) throws IOException, ApkFormatException {
    ZipSections zipSections;
    try {
        zipSections = findZipSections(apk);
    } catch (ZipFormatException e) {
        throw new ApkFormatException("Not a valid ZIP archive", e);
    }
    List<CentralDirectoryRecord> cdRecords = V1SchemeVerifier.parseZipCentralDirectory(apk, zipSections);
    CentralDirectoryRecord androidManifestCdRecord = null;
    for (CentralDirectoryRecord cdRecord : cdRecords) {
        if (ANDROID_MANIFEST_ZIP_ENTRY_NAME.equals(cdRecord.getName())) {
            androidManifestCdRecord = cdRecord;
            break;
        }
    }
    if (androidManifestCdRecord == null) {
        throw new ApkFormatException("Missing " + ANDROID_MANIFEST_ZIP_ENTRY_NAME);
    }
    DataSource lfhSection = apk.slice(0, zipSections.getZipCentralDirectoryOffset());
    try {
        return ByteBuffer.wrap(LocalFileRecord.getUncompressedData(lfhSection, androidManifestCdRecord, lfhSection.size()));
    } catch (ZipFormatException e) {
        throw new ApkFormatException("Failed to read " + ANDROID_MANIFEST_ZIP_ENTRY_NAME, e);
    }
}
Also used : CentralDirectoryRecord(com.android.apksig.internal.zip.CentralDirectoryRecord) ZipFormatException(com.android.apksig.zip.ZipFormatException) DataSource(com.android.apksig.util.DataSource)

Example 4 with DataSource

use of com.android.apksig.util.DataSource in project apksig by venshine.

the class SigningCertificateLineageTest method testLineageFromAPKContainsExpectedSigners.

@Test
public void testLineageFromAPKContainsExpectedSigners() throws Exception {
    SignerConfig firstSigner = getSignerConfigFromResources(FIRST_RSA_2048_SIGNER_RESOURCE_NAME);
    SignerConfig secondSigner = getSignerConfigFromResources(SECOND_RSA_2048_SIGNER_RESOURCE_NAME);
    SignerConfig thirdSigner = getSignerConfigFromResources(THIRD_RSA_2048_SIGNER_RESOURCE_NAME);
    List<SignerConfig> expectedSigners = Arrays.asList(firstSigner, secondSigner, thirdSigner);
    DataSource apkDataSource = Resources.toDataSource(getClass(), "v1v2v3-with-rsa-2048-lineage-3-signers.apk");
    SigningCertificateLineage lineageFromApk = SigningCertificateLineage.readFromApkDataSource(apkDataSource);
    assertLineageContainsExpectedSigners(lineageFromApk, expectedSigners);
}
Also used : SignerConfig(com.android.apksig.SigningCertificateLineage.SignerConfig) DataSource(com.android.apksig.util.DataSource) Test(org.junit.Test)

Example 5 with DataSource

use of com.android.apksig.util.DataSource in project apksig by venshine.

the class SigningCertificateLineageTest method testLineageFromAPKWithInvalidZipCDSizeFails.

@Test(expected = ApkFormatException.class)
public void testLineageFromAPKWithInvalidZipCDSizeFails() throws Exception {
    // This test verifies that attempting to read the lineage from an APK where the zip
    // sections cannot be parsed fails. This APK is based off the
    // v1v2v3-with-rsa-2048-lineage-3-signers.apk with a modified CD size in the EoCD.
    DataSource apkDataSource = Resources.toDataSource(getClass(), "v1v2v3-with-rsa-2048-lineage-3-signers-invalid-zip.apk");
    SigningCertificateLineage.readFromApkDataSource(apkDataSource);
}
Also used : DataSource(com.android.apksig.util.DataSource) Test(org.junit.Test)

Aggregations

DataSource (com.android.apksig.util.DataSource)29 RandomAccessFile (java.io.RandomAccessFile)11 Test (org.junit.Test)10 ByteBuffer (java.nio.ByteBuffer)7 ArrayList (java.util.ArrayList)6 ApkFormatException (com.android.apksig.apk.ApkFormatException)5 ApkSigningBlockUtils (com.android.apksig.internal.apk.ApkSigningBlockUtils)5 IOException (java.io.IOException)5 ApkUtils (com.android.apksig.apk.ApkUtils)4 ByteBufferDataSource (com.android.apksig.internal.util.ByteBufferDataSource)4 SignerConfig (com.android.apksig.SigningCertificateLineage.SignerConfig)3 CentralDirectoryRecord (com.android.apksig.internal.zip.CentralDirectoryRecord)3 DataSink (com.android.apksig.util.DataSink)3 File (java.io.File)3 MessageDigest (java.security.MessageDigest)3 ApkSigningBlockNotFoundException (com.android.apksig.apk.ApkSigningBlockNotFoundException)2 SignatureInfo (com.android.apksig.internal.apk.SignatureInfo)2 ChainedDataSource (com.android.apksig.internal.util.ChainedDataSource)2 Pair (com.android.apksig.internal.util.Pair)2 ZipFormatException (com.android.apksig.zip.ZipFormatException)2