APK signature verification: use FileChannel#size

RandomAccessFile#length returns 0 for block devices while
FileChannel#size returns the correct size.

APK signature verification utils should work with block-device zip files
when Android is running as a guest OS and APK/APEX files are passed via
block devices.

This is a follow-up of 1257f1505c.

Bug: 193592496
Bug: 192366904
Test: FrameworksServicesTests
Merged-In: I3015fc30574c36c18c0d0c9ae7453d33a1349927
Change-Id: I3015fc30574c36c18c0d0c9ae7453d33a1349927
(cherry picked from commit 310edbe3c7)
This commit is contained in:
Jooyung Han
2021-07-30 13:49:14 +09:00
parent 67f0eebdfa
commit c65e303681
4 changed files with 7 additions and 7 deletions

View File

@@ -210,7 +210,7 @@ public class ApkSignatureSchemeV2Verifier {
if (contentDigests.containsKey(CONTENT_DIGEST_VERITY_CHUNKED_SHA256)) {
byte[] verityDigest = contentDigests.get(CONTENT_DIGEST_VERITY_CHUNKED_SHA256);
verityRootHash = ApkSigningBlockUtils.parseVerityDigestAndVerifySourceLength(
verityDigest, apk.length(), signatureInfo);
verityDigest, apk.getChannel().size(), signatureInfo);
}
byte[] digest = pickBestDigestForV4(contentDigests);

View File

@@ -209,7 +209,7 @@ public class ApkSignatureSchemeV3Verifier {
if (contentDigests.containsKey(CONTENT_DIGEST_VERITY_CHUNKED_SHA256)) {
byte[] verityDigest = contentDigests.get(CONTENT_DIGEST_VERITY_CHUNKED_SHA256);
result.verityRootHash = ApkSigningBlockUtils.parseVerityDigestAndVerifySourceLength(
verityDigest, apk.length(), signatureInfo);
verityDigest, apk.getChannel().size(), signatureInfo);
}
result.digest = pickBestDigestForV4(contentDigests);

View File

@@ -349,7 +349,7 @@ final class ApkSigningBlockUtils {
SignatureInfo signatureInfo) throws SecurityException {
try {
byte[] expectedRootHash = parseVerityDigestAndVerifySourceLength(expectedDigest,
apk.length(), signatureInfo);
apk.getChannel().size(), signatureInfo);
VerityBuilder.VerityResult verity = VerityBuilder.generateApkVerityTree(apk,
signatureInfo, new ByteBufferFactory() {
@Override

View File

@@ -90,7 +90,7 @@ public abstract class VerityBuilder {
throws IOException, SecurityException, NoSuchAlgorithmException, DigestException {
long signingBlockSize =
signatureInfo.centralDirOffset - signatureInfo.apkSigningBlockOffset;
long dataSize = apk.length() - signingBlockSize;
long dataSize = apk.getChannel().size() - signingBlockSize;
int[] levelOffset = calculateVerityLevelOffset(dataSize);
int merkleTreeSize = levelOffset[levelOffset.length - 1];
@@ -108,7 +108,7 @@ public abstract class VerityBuilder {
@NonNull SignatureInfo signatureInfo, @NonNull ByteBuffer footerOutput)
throws IOException {
footerOutput.order(ByteOrder.LITTLE_ENDIAN);
generateApkVerityHeader(footerOutput, apk.length(), DEFAULT_SALT);
generateApkVerityHeader(footerOutput, apk.getChannel().size(), DEFAULT_SALT);
long signingBlockSize =
signatureInfo.centralDirOffset - signatureInfo.apkSigningBlockOffset;
generateApkVerityExtensions(footerOutput, signatureInfo.apkSigningBlockOffset,
@@ -310,11 +310,11 @@ public abstract class VerityBuilder {
eocdCdOffsetFieldPosition + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_SIZE;
consumeByChunk(digester,
new MemoryMappedFileDataSource(apk.getFD(), offsetAfterEocdCdOffsetField,
apk.length() - offsetAfterEocdCdOffsetField),
apk.getChannel().size() - offsetAfterEocdCdOffsetField),
MMAP_REGION_SIZE_BYTES);
// 5. Pad 0s up to the nearest 4096-byte block before hashing.
int lastIncompleteChunkSize = (int) (apk.length() % CHUNK_SIZE_BYTES);
int lastIncompleteChunkSize = (int) (apk.getChannel().size() % CHUNK_SIZE_BYTES);
if (lastIncompleteChunkSize != 0) {
digester.consume(ByteBuffer.allocate(CHUNK_SIZE_BYTES - lastIncompleteChunkSize));
}