Verify best signature algorithms of all signers
The previous implementation does not verify signature algorithms of all signers. It's possible that the attacker can take an old apk (with digest and signature of old algorithm) and add their own signer block with new/P digest and signature. In this case, the old implementation only verifies the attacker's signature, thus the attacker can change apk content easily. The solution here is to verify digests of all best signature algorithms by all signers. It is expected to increase verification time, if the apk does have multiple signers with different type of digests. Test: apks still install Bug: 78359754 Change-Id: I607edf219c25a2a7adfa27a21a94e9bfefbb6cec
This commit is contained in:
@@ -92,6 +92,8 @@ final class ApkSigningBlockUtils {
|
||||
throw new SecurityException("No digests provided");
|
||||
}
|
||||
|
||||
boolean neverVerified = true;
|
||||
|
||||
Map<Integer, byte[]> expected1MbChunkDigests = new ArrayMap<>();
|
||||
if (expectedDigests.containsKey(CONTENT_DIGEST_CHUNKED_SHA256)) {
|
||||
expected1MbChunkDigests.put(CONTENT_DIGEST_CHUNKED_SHA256,
|
||||
@@ -101,18 +103,23 @@ final class ApkSigningBlockUtils {
|
||||
expected1MbChunkDigests.put(CONTENT_DIGEST_CHUNKED_SHA512,
|
||||
expectedDigests.get(CONTENT_DIGEST_CHUNKED_SHA512));
|
||||
}
|
||||
if (!expected1MbChunkDigests.isEmpty()) {
|
||||
try {
|
||||
verifyIntegrityFor1MbChunkBasedAlgorithm(expected1MbChunkDigests, apk.getFD(),
|
||||
signatureInfo);
|
||||
neverVerified = false;
|
||||
} catch (IOException e) {
|
||||
throw new SecurityException("Cannot get FD", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (expectedDigests.containsKey(CONTENT_DIGEST_VERITY_CHUNKED_SHA256)) {
|
||||
verifyIntegrityForVerityBasedAlgorithm(
|
||||
expectedDigests.get(CONTENT_DIGEST_VERITY_CHUNKED_SHA256), apk, signatureInfo);
|
||||
} else if (!expected1MbChunkDigests.isEmpty()) {
|
||||
try {
|
||||
verifyIntegrityFor1MbChunkBasedAlgorithm(expected1MbChunkDigests, apk.getFD(),
|
||||
signatureInfo);
|
||||
} catch (IOException e) {
|
||||
throw new SecurityException("Cannot get FD", e);
|
||||
}
|
||||
} else {
|
||||
neverVerified = false;
|
||||
}
|
||||
|
||||
if (neverVerified) {
|
||||
throw new SecurityException("No known digest exists for integrity check");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user