修复 DSA 签名游戏无法正常更新的问题

This commit is contained in:
juntao
2021-11-19 16:26:02 +08:00
parent 844c028b7b
commit 9df38387f2
7 changed files with 124 additions and 17 deletions

View File

@ -154,6 +154,37 @@ public class ApkVerifier {
}
}
/**
* Simply retrieve result that contains V1Signature only by ignoring all the verification process.
*
* @throws IOException if an I/O error is encountered while reading the APK
* @throws ApkFormatException if the APK is malformed
* @throws NoSuchAlgorithmException if the APK's signatures cannot be verified because a
* required cryptographic algorithm implementation is missing
* @throws IllegalStateException if this verifier's configuration is missing required
* information.
*/
public Result retrieveV1Signature() throws IOException, ApkFormatException, NoSuchAlgorithmException {
Closeable in = null;
try {
DataSource apk;
if (mApkDataSource != null) {
apk = mApkDataSource;
} else if (mApkFile != null) {
RandomAccessFile f = new RandomAccessFile(mApkFile, "r");
in = f;
apk = DataSources.asDataSource(f, 0, f.length());
} else {
throw new IllegalStateException("APK not provided");
}
return retrieveV1Signature(apk);
} finally {
if (in != null) {
in.close();
}
}
}
/**
* Simply retrieve result that contains V2Signature only by ignoring all the verification process.
*
@ -257,6 +288,60 @@ public class ApkVerifier {
return result;
}
/**
* Simply retrieve result that contains V1Signature only by ignoring all the verification process.
*
* @param apk APK file contents
* @throws IOException if an I/O error is encountered while reading the APK
* @throws ApkFormatException if the APK is malformed
* @throws NoSuchAlgorithmException if the APK's signatures cannot be verified because a
* required cryptographic algorithm implementation is missing
*/
private Result retrieveV1Signature(DataSource apk) throws IOException, ApkFormatException, NoSuchAlgorithmException {
int maxSdkVersion = mMaxSdkVersion;
ApkUtils.ZipSections zipSections;
try {
zipSections = ApkUtils.findZipSections(apk);
} catch (ZipFormatException e) {
throw new ApkFormatException("Malformed APK: not a ZIP archive", e);
}
Result result = new Result();
Map<Integer, Map<ContentDigestAlgorithm, byte[]>> signatureSchemeApkContentDigests =
new HashMap<>();
// The SUPPORTED_APK_SIG_SCHEME_NAMES contains the mapping from version number to scheme
// name, but the verifiers use this parameter as the schemes supported by the target SDK
// range. Since the code below skips signature verification based on max SDK the mapping of
// supported schemes needs to be modified to ensure the verifiers do not report a stripped
// signature for an SDK range that does not support that signature version. For instance an
// APK with V1, V2, and V3 signatures and a max SDK of O would skip the V3 signature
// verification, but the SUPPORTED_APK_SIG_SCHEME_NAMES contains version 3, so when the V2
// verification is performed it would see the stripping protection attribute, see that V3
// is in the list of supported signatures, and report a stripped signature.
Map<Integer, String> supportedSchemeNames = getSupportedSchemeNames(maxSdkVersion);
// Android N and newer attempts to verify APKs using the APK Signing Block, which can
// include v2 and/or v3 signatures. If none is found, it falls back to JAR signature
// verification. If the signature is found but does not verify, the APK is rejected.
Set<Integer> foundApkSigSchemeIds = new HashSet<>(2);
int minSdkVersion = verifyAndGetMinSdkVersion(apk, zipSections);
V1SchemeVerifier.Result v1Result =
V1SchemeVerifier.verify(
apk,
zipSections,
supportedSchemeNames,
foundApkSigSchemeIds,
minSdkVersion,
maxSdkVersion);
result.mergeFrom(v1Result);
return result;
}
/**
* Verifies the APK's signatures and returns the result of verification. The APK can be
* considered verified iff the result's {@link Result#isVerified()} returns {@code true}.