Search in sources :

Example 1 with ByteBufferDataSource

use of com.android.apksigner.core.internal.util.ByteBufferDataSource in project walle by Meituan-Dianping.

the class V2SchemeVerifier method verifyIntegrity.

/**
     * Verifies integrity of the APK outside of the APK Signing Block by computing digests of the
     * APK and comparing them against the digests listed in APK Signing Block. The expected digests
     * taken from {@code v2SchemeSignerInfos} of the provided {@code result}.
     */
private static void verifyIntegrity(DataSource beforeApkSigningBlock, DataSource centralDir, ByteBuffer eocd, Set<ContentDigestAlgorithm> contentDigestAlgorithms, Result result) throws IOException {
    if (contentDigestAlgorithms.isEmpty()) {
        // is verified, meaning at least one content digest is known.
        throw new RuntimeException("No content digests found");
    }
    // For the purposes of verifying integrity, ZIP End of Central Directory (EoCD) must be
    // treated as though its Central Directory offset points to the start of APK Signing Block.
    // We thus modify the EoCD accordingly.
    ByteBuffer modifiedEocd = ByteBuffer.allocate(eocd.remaining());
    modifiedEocd.order(ByteOrder.LITTLE_ENDIAN);
    modifiedEocd.put(eocd);
    modifiedEocd.flip();
    ZipUtils.setZipEocdCentralDirectoryOffset(modifiedEocd, beforeApkSigningBlock.size());
    Map<ContentDigestAlgorithm, byte[]> actualContentDigests;
    try {
        actualContentDigests = V2SchemeSigner.computeContentDigests(contentDigestAlgorithms, new DataSource[] { beforeApkSigningBlock, centralDir, new ByteBufferDataSource(modifiedEocd) });
    } catch (DigestException e) {
        throw new RuntimeException("Failed to compute content digests", e);
    }
    if (!contentDigestAlgorithms.equals(actualContentDigests.keySet())) {
        throw new RuntimeException("Mismatch between sets of requested and computed content digests" + " . Requested: " + contentDigestAlgorithms + ", computed: " + actualContentDigests.keySet());
    }
    // in signer blocks.
    for (Result.SignerInfo signerInfo : result.signers) {
        for (Result.SignerInfo.ContentDigest expected : signerInfo.contentDigests) {
            SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.findById(expected.getSignatureAlgorithmId());
            if (signatureAlgorithm == null) {
                continue;
            }
            ContentDigestAlgorithm contentDigestAlgorithm = signatureAlgorithm.getContentDigestAlgorithm();
            byte[] expectedDigest = expected.getValue();
            byte[] actualDigest = actualContentDigests.get(contentDigestAlgorithm);
            if (!Arrays.equals(expectedDigest, actualDigest)) {
                signerInfo.addError(Issue.V2_SIG_APK_DIGEST_DID_NOT_VERIFY, contentDigestAlgorithm, toHex(expectedDigest), toHex(actualDigest));
                continue;
            }
            signerInfo.verifiedContentDigests.put(contentDigestAlgorithm, actualDigest);
        }
    }
}
Also used : ByteBufferDataSource(com.android.apksigner.core.internal.util.ByteBufferDataSource) ByteBuffer(java.nio.ByteBuffer) DataSource(com.android.apksigner.core.util.DataSource) ByteBufferDataSource(com.android.apksigner.core.internal.util.ByteBufferDataSource) DigestException(java.security.DigestException)

Aggregations

ByteBufferDataSource (com.android.apksigner.core.internal.util.ByteBufferDataSource)1 DataSource (com.android.apksigner.core.util.DataSource)1 ByteBuffer (java.nio.ByteBuffer)1 DigestException (java.security.DigestException)1