6.6.3 - Alpha3 - Gradle 构建脚本提升版本自适应能力 (discussion #369)

This commit is contained in:
SuperMonster003
2025-05-13 18:49:00 +08:00
parent 94122476fa
commit adf8dc9f30
22 changed files with 429 additions and 240 deletions

View File

@@ -386,9 +386,7 @@ public abstract class V1SchemeSigner {
checkEntryNameValid(entryName);
byte[] entryDigest = jarEntryDigests.get(entryName);
Attributes entryAttrs = new Attributes();
String encodedEntryDigest = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
? Base64.getEncoder().encodeToString(entryDigest)
: com.mcal.apksigner.utils.Base64.encode(entryDigest);
String encodedEntryDigest = base64EncodeCompat(entryDigest);
entryAttrs.putValue(entryDigestAttributeName, encodedEntryDigest);
ByteArrayOutputStream sectionOut = new ByteArrayOutputStream();
byte[] sectionBytes;
@@ -409,6 +407,18 @@ public abstract class V1SchemeSigner {
return result;
}
public static String base64EncodeCompat(byte[] entryDigest) {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
? Base64.getEncoder().encodeToString(entryDigest)
: com.mcal.apksigner.utils.Base64.encode(entryDigest);
}
public static byte[] base64DecodeCompat(String src) {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
? Base64.getDecoder().decode(src)
: com.mcal.apksigner.utils.Base64.decode(src);
}
private static void checkEntryNameValid(String name) throws ApkFormatException {
// JAR signing spec says CR, LF, and NUL are not permitted in entry names
// CR or LF in entry names will result in malformed MANIFEST.MF and .SF files because there
@@ -460,9 +470,7 @@ public abstract class V1SchemeSigner {
// Add main attribute containing the digest of MANIFEST.MF.
MessageDigest md = getMessageDigestInstance(manifestDigestAlgorithm);
String encodedManifestDigest = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
? Base64.getEncoder().encodeToString(md.digest(manifest.contents))
: com.mcal.apksigner.utils.Base64.encode(md.digest(manifest.contents));
String encodedManifestDigest = base64EncodeCompat(md.digest(manifest.contents));
mainAttrs.putValue(getManifestDigestAttributeName(manifestDigestAlgorithm), encodedManifestDigest);
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
@@ -477,9 +485,7 @@ public abstract class V1SchemeSigner {
byte[] sectionContents = manifestSection.getValue();
byte[] sectionDigest = md.digest(sectionContents);
Attributes attrs = new Attributes();
String encodedSectionDigest = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
? Base64.getEncoder().encodeToString(sectionDigest)
: com.mcal.apksigner.utils.Base64.encode(sectionDigest);
String encodedSectionDigest = base64EncodeCompat(sectionDigest);
attrs.putValue(entryDigestAttributeName, encodedSectionDigest);
try {

View File

@@ -17,6 +17,8 @@
package com.android.apksig.internal.apk.v1;
import static com.android.apksig.Constants.MAX_APK_SIGNERS;
import static com.android.apksig.internal.apk.v1.V1SchemeSigner.base64DecodeCompat;
import static com.android.apksig.internal.apk.v1.V1SchemeSigner.base64EncodeCompat;
import static com.android.apksig.internal.oid.OidConstants.getSigAlgSupportedApiLevels;
import static com.android.apksig.internal.pkcs7.AlgorithmIdentifier.getJcaDigestAlgorithm;
import static com.android.apksig.internal.pkcs7.AlgorithmIdentifier.getJcaSignatureAlgorithm;
@@ -69,8 +71,6 @@ import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -971,8 +971,8 @@ public abstract class V1SchemeVerifier {
V1SchemeConstants.MANIFEST_ENTRY_NAME,
jcaDigestAlgorithm,
mSignatureFileEntry.getName(),
Base64.getEncoder().encodeToString(actual),
Base64.getEncoder().encodeToString(expected));
base64EncodeCompat(actual),
base64EncodeCompat(expected));
verified = false;
}
}
@@ -1013,8 +1013,8 @@ public abstract class V1SchemeVerifier {
Issue.JAR_SIG_MANIFEST_MAIN_SECTION_DIGEST_DID_NOT_VERIFY,
jcaDigestAlgorithm,
mSignatureFileEntry.getName(),
Base64.getEncoder().encodeToString(actual),
Base64.getEncoder().encodeToString(expected));
base64EncodeCompat(actual),
base64EncodeCompat(expected));
}
}
}
@@ -1066,8 +1066,8 @@ public abstract class V1SchemeVerifier {
entryName,
jcaDigestAlgorithm,
mSignatureFileEntry.getName(),
Base64.getEncoder().encodeToString(actual),
Base64.getEncoder().encodeToString(expected));
base64EncodeCompat(actual),
base64EncodeCompat(expected));
}
}
}
@@ -1142,7 +1142,6 @@ public abstract class V1SchemeVerifier {
String digestAttrSuffix,
int minSdkVersion,
int maxSdkVersion) {
Decoder base64Decoder = Base64.getDecoder();
List<NamedDigest> result = new ArrayList<>(1);
if (minSdkVersion < AndroidSdkVersion.JELLY_BEAN_MR2) {
// Prior to JB MR2, Android platform's logic for picking a digest algorithm to verify is
@@ -1171,7 +1170,7 @@ public abstract class V1SchemeVerifier {
continue;
}
// Supported digest algorithm
result.add(new NamedDigest(alg, base64Decoder.decode(digestBase64)));
result.add(new NamedDigest(alg, base64DecodeCompat(digestBase64)));
break;
}
// No supported digests found -- this will fail to verify on pre-JB MR2 Androids.
@@ -1190,7 +1189,7 @@ public abstract class V1SchemeVerifier {
// Attribute not found
continue;
}
byte[] digest = base64Decoder.decode(digestBase64);
byte[] digest = base64DecodeCompat(digestBase64);
byte[] digestInResult = getDigest(result, alg);
if ((digestInResult == null) || (!Arrays.equals(digestInResult, digest))) {
result.add(new NamedDigest(alg, digest));
@@ -1373,8 +1372,8 @@ public abstract class V1SchemeVerifier {
entryName,
expectedDigest.jcaDigestAlgorithm,
V1SchemeConstants.MANIFEST_ENTRY_NAME,
Base64.getEncoder().encodeToString(actualDigest),
Base64.getEncoder().encodeToString(expectedDigest.digest));
base64EncodeCompat(actualDigest),
base64EncodeCompat(expectedDigest.digest));
}
}
}

View File

@@ -16,6 +16,8 @@
package com.android.apksig.internal.util;
import static com.android.apksig.internal.apk.v1.V1SchemeSigner.base64DecodeCompat;
import com.android.apksig.internal.asn1.Asn1BerParser;
import com.android.apksig.internal.asn1.Asn1DecodingException;
import com.android.apksig.internal.asn1.Asn1DerEncoder;
@@ -30,7 +32,6 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collection;
/**
@@ -265,7 +266,7 @@ public class X509CertificateUtils {
+ "valid certificate footer");
}
}
byte[] derEncoding = Base64.getDecoder().decode(pemEncoding.toString());
byte[] derEncoding = base64DecodeCompat(pemEncoding.toString());
// consume any trailing whitespace in the byte buffer
int nextEncodedChar = certificateBuffer.position();
while (certificateBuffer.hasRemaining()) {

View File

@@ -16,6 +16,8 @@
package com.android.apksigner;
import android.annotation.SuppressLint;
import java.io.ByteArrayOutputStream;
import java.io.Console;
import java.io.File;
@@ -86,7 +88,7 @@ public class PasswordRetriever implements AutoCloseable {
return encoded;
}
private static char[] decodePassword(byte[] pwdBytes, Charset encoding) throws IOException {
private static char[] decodePassword(byte[] pwdBytes, Charset encoding) throws IOException {
CharBuffer pwdChars =
encoding.newDecoder()
.onMalformedInput(CodingErrorAction.REPLACE)
@@ -140,6 +142,7 @@ public class PasswordRetriever implements AutoCloseable {
}
String consoleCharsetName = null;
try {
@SuppressLint("SoonBlockedPrivateApi")
Method encodingMethod = Console.class.getDeclaredMethod("encoding");
encodingMethod.setAccessible(true);
consoleCharsetName = (String) encodingMethod.invoke(null);
@@ -314,7 +317,7 @@ public class PasswordRetriever implements AutoCloseable {
if (value == null) {
throw new IOException(
"Failed to read " + description + ": environment variable " + value
+ " not specified");
+ " not specified");
}
return getPasswords(value.toCharArray(), additionalPwdEncodings);
} else {