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 of1257f1505c. Bug: 193592496 Bug: 192366904 Test: FrameworksServicesTests Change-Id: I3015fc30574c36c18c0d0c9ae7453d33a1349927 (cherry picked from commit310edbe3c7)
This commit is contained in:
@@ -209,7 +209,7 @@ public class ApkSignatureSchemeV2Verifier {
|
|||||||
if (contentDigests.containsKey(CONTENT_DIGEST_VERITY_CHUNKED_SHA256)) {
|
if (contentDigests.containsKey(CONTENT_DIGEST_VERITY_CHUNKED_SHA256)) {
|
||||||
byte[] verityDigest = contentDigests.get(CONTENT_DIGEST_VERITY_CHUNKED_SHA256);
|
byte[] verityDigest = contentDigests.get(CONTENT_DIGEST_VERITY_CHUNKED_SHA256);
|
||||||
verityRootHash = ApkSigningBlockUtils.parseVerityDigestAndVerifySourceLength(
|
verityRootHash = ApkSigningBlockUtils.parseVerityDigestAndVerifySourceLength(
|
||||||
verityDigest, apk.length(), signatureInfo);
|
verityDigest, apk.getChannel().size(), signatureInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new VerifiedSigner(
|
return new VerifiedSigner(
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ public class ApkSignatureSchemeV3Verifier {
|
|||||||
if (contentDigests.containsKey(CONTENT_DIGEST_VERITY_CHUNKED_SHA256)) {
|
if (contentDigests.containsKey(CONTENT_DIGEST_VERITY_CHUNKED_SHA256)) {
|
||||||
byte[] verityDigest = contentDigests.get(CONTENT_DIGEST_VERITY_CHUNKED_SHA256);
|
byte[] verityDigest = contentDigests.get(CONTENT_DIGEST_VERITY_CHUNKED_SHA256);
|
||||||
verityRootHash = ApkSigningBlockUtils.parseVerityDigestAndVerifySourceLength(
|
verityRootHash = ApkSigningBlockUtils.parseVerityDigestAndVerifySourceLength(
|
||||||
verityDigest, apk.length(), signatureInfo);
|
verityDigest, apk.getChannel().size(), signatureInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new VerifiedSigner(result.first, result.second, verityRootHash, contentDigests);
|
return new VerifiedSigner(result.first, result.second, verityRootHash, contentDigests);
|
||||||
|
|||||||
@@ -368,7 +368,7 @@ public final class ApkSigningBlockUtils {
|
|||||||
SignatureInfo signatureInfo) throws SecurityException {
|
SignatureInfo signatureInfo) throws SecurityException {
|
||||||
try {
|
try {
|
||||||
byte[] expectedRootHash = parseVerityDigestAndVerifySourceLength(expectedDigest,
|
byte[] expectedRootHash = parseVerityDigestAndVerifySourceLength(expectedDigest,
|
||||||
apk.length(), signatureInfo);
|
apk.getChannel().size(), signatureInfo);
|
||||||
VerityBuilder.VerityResult verity = VerityBuilder.generateApkVerityTree(apk,
|
VerityBuilder.VerityResult verity = VerityBuilder.generateApkVerityTree(apk,
|
||||||
signatureInfo, new ByteBufferFactory() {
|
signatureInfo, new ByteBufferFactory() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ public abstract class VerityBuilder {
|
|||||||
throws IOException, SecurityException, NoSuchAlgorithmException, DigestException {
|
throws IOException, SecurityException, NoSuchAlgorithmException, DigestException {
|
||||||
long signingBlockSize =
|
long signingBlockSize =
|
||||||
signatureInfo.centralDirOffset - signatureInfo.apkSigningBlockOffset;
|
signatureInfo.centralDirOffset - signatureInfo.apkSigningBlockOffset;
|
||||||
long dataSize = apk.length() - signingBlockSize;
|
long dataSize = apk.getChannel().size() - signingBlockSize;
|
||||||
int[] levelOffset = calculateVerityLevelOffset(dataSize);
|
int[] levelOffset = calculateVerityLevelOffset(dataSize);
|
||||||
int merkleTreeSize = levelOffset[levelOffset.length - 1];
|
int merkleTreeSize = levelOffset[levelOffset.length - 1];
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ public abstract class VerityBuilder {
|
|||||||
@NonNull SignatureInfo signatureInfo, @NonNull ByteBuffer footerOutput)
|
@NonNull SignatureInfo signatureInfo, @NonNull ByteBuffer footerOutput)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
footerOutput.order(ByteOrder.LITTLE_ENDIAN);
|
footerOutput.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
generateApkVerityHeader(footerOutput, apk.length(), DEFAULT_SALT);
|
generateApkVerityHeader(footerOutput, apk.getChannel().size(), DEFAULT_SALT);
|
||||||
long signingBlockSize =
|
long signingBlockSize =
|
||||||
signatureInfo.centralDirOffset - signatureInfo.apkSigningBlockOffset;
|
signatureInfo.centralDirOffset - signatureInfo.apkSigningBlockOffset;
|
||||||
generateApkVerityExtensions(footerOutput, signatureInfo.apkSigningBlockOffset,
|
generateApkVerityExtensions(footerOutput, signatureInfo.apkSigningBlockOffset,
|
||||||
@@ -339,11 +339,11 @@ public abstract class VerityBuilder {
|
|||||||
eocdCdOffsetFieldPosition + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_SIZE;
|
eocdCdOffsetFieldPosition + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_SIZE;
|
||||||
consumeByChunk(digester,
|
consumeByChunk(digester,
|
||||||
DataSource.create(apk.getFD(), offsetAfterEocdCdOffsetField,
|
DataSource.create(apk.getFD(), offsetAfterEocdCdOffsetField,
|
||||||
apk.length() - offsetAfterEocdCdOffsetField),
|
apk.getChannel().size() - offsetAfterEocdCdOffsetField),
|
||||||
MMAP_REGION_SIZE_BYTES);
|
MMAP_REGION_SIZE_BYTES);
|
||||||
|
|
||||||
// 5. Pad 0s up to the nearest 4096-byte block before hashing.
|
// 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) {
|
if (lastIncompleteChunkSize != 0) {
|
||||||
digester.consume(ByteBuffer.allocate(CHUNK_SIZE_BYTES - lastIncompleteChunkSize));
|
digester.consume(ByteBuffer.allocate(CHUNK_SIZE_BYTES - lastIncompleteChunkSize));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user