summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorPatrick Baumann <patb@google.com>2017-12-19 10:17:21 -0800
committerPatrick Baumann <patb@google.com>2018-01-09 15:12:48 -0800
commit420d58a9d867a3ce96fb4ea98bd30ee4d44eab4d (patch)
treee21ad7562e2241e004be32ac971aeca8b1ce77f5 /core/java
parentdf86ddb3f9612444e1f08d751845f835958beb9c (diff)
Move signing data into SigningDetails container
This change replaces fields from Package that relate to signing with a single SigningDetails container. It does the same with InstallArgs and InstallParams. This simplifies much of the code that would have otherwise relied on synchronizing many fields and will enable PackageManagerService to make install-time descisions based on package data instead of forcing it to be part of package parsing. This is a retake of ag/3382280 Test: android.appsecurity.cts.PkgInstallSignatureVerificationTest passes. Test: atest google/perf/boottime/boottime-test to ensure no startup regression. Bug: 68860689 Change-Id: I0df45ce537df5552a7e60e4d727a4dcef23c2252
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/content/pm/PackageParser.java257
-rw-r--r--core/java/android/util/apk/ApkSignatureVerifier.java63
2 files changed, 178 insertions, 142 deletions
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 77eb57f25613..367c39dfd8ff 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -85,7 +85,6 @@ import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TypedValue;
-import android.util.apk.ApkSignatureSchemeV2Verifier;
import android.util.apk.ApkSignatureVerifier;
import android.view.Gravity;
@@ -112,8 +111,7 @@ import java.lang.reflect.Constructor;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
@@ -158,10 +156,6 @@ public class PackageParser {
private static final boolean MULTI_PACKAGE_APK_ENABLED = Build.IS_DEBUGGABLE &&
SystemProperties.getBoolean(PROPERTY_CHILD_PACKAGES_ENABLED, false);
- public static final int APK_SIGNING_UNKNOWN = 0;
- public static final int APK_SIGNING_V1 = 1;
- public static final int APK_SIGNING_V2 = 2;
-
private static final float DEFAULT_PRE_O_MAX_ASPECT_RATIO = 1.86f;
// TODO: switch outError users to PackageParserException
@@ -477,8 +471,7 @@ public class PackageParser {
public final int revisionCode;
public final int installLocation;
public final VerifierInfo[] verifiers;
- public final Signature[] signatures;
- public final Certificate[][] certificates;
+ public final SigningDetails signingDetails;
public final boolean coreApp;
public final boolean debuggable;
public final boolean multiArch;
@@ -486,10 +479,11 @@ public class PackageParser {
public final boolean extractNativeLibs;
public final boolean isolatedSplits;
- public ApkLite(String codePath, String packageName, String splitName, boolean isFeatureSplit,
+ public ApkLite(String codePath, String packageName, String splitName,
+ boolean isFeatureSplit,
String configForSplit, String usesSplitName, int versionCode, int versionCodeMajor,
int revisionCode, int installLocation, List<VerifierInfo> verifiers,
- Signature[] signatures, Certificate[][] certificates, boolean coreApp,
+ SigningDetails signingDetails, boolean coreApp,
boolean debuggable, boolean multiArch, boolean use32bitAbi,
boolean extractNativeLibs, boolean isolatedSplits) {
this.codePath = codePath;
@@ -502,9 +496,8 @@ public class PackageParser {
this.versionCodeMajor = versionCodeMajor;
this.revisionCode = revisionCode;
this.installLocation = installLocation;
+ this.signingDetails = signingDetails;
this.verifiers = verifiers.toArray(new VerifierInfo[verifiers.size()]);
- this.signatures = signatures;
- this.certificates = certificates;
this.coreApp = coreApp;
this.debuggable = debuggable;
this.multiArch = multiArch;
@@ -807,10 +800,10 @@ public class PackageParser {
}
}
if ((flags&PackageManager.GET_SIGNATURES) != 0) {
- int N = (p.mSignatures != null) ? p.mSignatures.length : 0;
- if (N > 0) {
- pi.signatures = new Signature[N];
- System.arraycopy(p.mSignatures, 0, pi.signatures, 0, N);
+ if (p.mSigningDetails.hasSignatures()) {
+ int numberOfSigs = p.mSigningDetails.signatures.length;
+ pi.signatures = new Signature[numberOfSigs];
+ System.arraycopy(p.mSigningDetails.signatures, 0, pi.signatures, 0, numberOfSigs);
}
}
return pi;
@@ -1349,7 +1342,7 @@ public class PackageParser {
pkg.setVolumeUuid(volumeUuid);
pkg.setApplicationVolumeUuid(volumeUuid);
pkg.setBaseCodePath(apkPath);
- pkg.setSignatures(null);
+ pkg.setSigningDetails(SigningDetails.UNKNOWN);
return pkg;
@@ -1469,57 +1462,19 @@ public class PackageParser {
return pkg;
}
- public static int getApkSigningVersion(Package pkg) {
- try {
- if (ApkSignatureSchemeV2Verifier.hasSignature(pkg.baseCodePath)) {
- return APK_SIGNING_V2;
- }
- return APK_SIGNING_V1;
- } catch (IOException e) {
- }
- return APK_SIGNING_UNKNOWN;
- }
-
- /**
- * Populates the correct packages fields with the given certificates.
- * <p>
- * This is useful when we've already processed the certificates [such as during package
- * installation through an installer session]. We don't re-process the archive and
- * simply populate the correct fields.
- */
- public static void populateCertificates(Package pkg, Certificate[][] certificates)
- throws PackageParserException {
- pkg.mCertificates = null;
- pkg.mSignatures = null;
- pkg.mSigningKeys = null;
-
- pkg.mCertificates = certificates;
- try {
- pkg.mSignatures = ApkSignatureVerifier.convertToSignatures(certificates);
- } catch (CertificateEncodingException e) {
- // certificates weren't encoded properly; something went wrong
- throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
- "Failed to collect certificates from " + pkg.baseCodePath, e);
- }
- pkg.mSigningKeys = new ArraySet<>(certificates.length);
- for (int i = 0; i < certificates.length; i++) {
- Certificate[] signerCerts = certificates[i];
- Certificate signerCert = signerCerts[0];
- pkg.mSigningKeys.add(signerCert.getPublicKey());
- }
- // add signatures to child packages
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- Package childPkg = pkg.childPackages.get(i);
- childPkg.mCertificates = pkg.mCertificates;
- childPkg.mSignatures = pkg.mSignatures;
- childPkg.mSigningKeys = pkg.mSigningKeys;
+ /** Parses the public keys from the set of signatures. */
+ public static ArraySet<PublicKey> toSigningKeys(Signature[] signatures)
+ throws CertificateException {
+ ArraySet<PublicKey> keys = new ArraySet<>(signatures.length);
+ for (int i = 0; i < signatures.length; i++) {
+ keys.add(signatures[i].getPublicKey());
}
+ return keys;
}
/**
* Collect certificates from all the APKs described in the given package,
- * populating {@link Package#mSignatures}. Also asserts that all APK
+ * populating {@link Package#mSigningDetails}. Also asserts that all APK
* contents are signed correctly and consistently.
*/
public static void collectCertificates(Package pkg, @ParseFlags int parseFlags)
@@ -1528,17 +1483,13 @@ public class PackageParser {
final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
Package childPkg = pkg.childPackages.get(i);
- childPkg.mCertificates = pkg.mCertificates;
- childPkg.mSignatures = pkg.mSignatures;
- childPkg.mSigningKeys = pkg.mSigningKeys;
+ childPkg.mSigningDetails = pkg.mSigningDetails;
}
}
private static void collectCertificatesInternal(Package pkg, @ParseFlags int parseFlags)
throws PackageParserException {
- pkg.mCertificates = null;
- pkg.mSignatures = null;
- pkg.mSigningKeys = null;
+ pkg.mSigningDetails = SigningDetails.UNKNOWN;
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
try {
@@ -1558,12 +1509,12 @@ public class PackageParser {
throws PackageParserException {
final String apkPath = apkFile.getAbsolutePath();
- int minSignatureScheme = ApkSignatureVerifier.VERSION_JAR_SIGNATURE_SCHEME;
+ int minSignatureScheme = SigningDetails.SignatureSchemeVersion.JAR;
if (pkg.applicationInfo.isStaticSharedLibrary()) {
// must use v2 signing scheme
- minSignatureScheme = ApkSignatureVerifier.VERSION_APK_SIGNATURE_SCHEME_V2;
+ minSignatureScheme = SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2;
}
- ApkSignatureVerifier.Result verified;
+ SigningDetails verified;
if ((parseFlags & PARSE_IS_SYSTEM_DIR) != 0) {
// systemDir APKs are already trusted, save time by not verifying
verified = ApkSignatureVerifier.plsCertsNoVerifyOnlyCerts(
@@ -1572,7 +1523,7 @@ public class PackageParser {
verified = ApkSignatureVerifier.verify(apkPath, minSignatureScheme);
}
if (verified.signatureSchemeVersion
- < ApkSignatureVerifier.VERSION_APK_SIGNATURE_SCHEME_V2) {
+ < SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2) {
// TODO (b/68860689): move this logic to packagemanagerserivce
if ((parseFlags & PARSE_IS_EPHEMERAL) != 0) {
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
@@ -1583,17 +1534,10 @@ public class PackageParser {
// Verify that entries are signed consistently with the first pkg
// we encountered. Note that for splits, certificates may have
// already been populated during an earlier parse of a base APK.
- if (pkg.mCertificates == null) {
- pkg.mCertificates = verified.certs;
- pkg.mSignatures = verified.sigs;
- pkg.mSigningKeys = new ArraySet<>(verified.certs.length);
- for (int i = 0; i < verified.certs.length; i++) {
- Certificate[] signerCerts = verified.certs[i];
- Certificate signerCert = signerCerts[0];
- pkg.mSigningKeys.add(signerCert.getPublicKey());
- }
+ if (pkg.mSigningDetails == SigningDetails.UNKNOWN) {
+ pkg.mSigningDetails = verified;
} else {
- if (!Signature.areExactMatch(pkg.mSignatures, verified.sigs)) {
+ if (!Signature.areExactMatch(pkg.mSigningDetails.signatures, verified.signatures)) {
throw new PackageParserException(
INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
apkPath + " has mismatched certificates");
@@ -1655,8 +1599,7 @@ public class PackageParser {
parser = assets.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
- final Signature[] signatures;
- final Certificate[][] certificates;
+ final SigningDetails signingDetails;
if ((flags & PARSE_COLLECT_CERTIFICATES) != 0) {
// TODO: factor signature related items out of Package object
final Package tempPkg = new Package((String) null);
@@ -1666,15 +1609,13 @@ public class PackageParser {
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
- signatures = tempPkg.mSignatures;
- certificates = tempPkg.mCertificates;
+ signingDetails = tempPkg.mSigningDetails;
} else {
- signatures = null;
- certificates = null;
+ signingDetails = SigningDetails.UNKNOWN;
}
final AttributeSet attrs = parser;
- return parseApkLite(apkPath, parser, attrs, signatures, certificates);
+ return parseApkLite(apkPath, parser, attrs, signingDetails);
} catch (XmlPullParserException | IOException | RuntimeException e) {
Slog.w(TAG, "Failed to parse " + apkPath, e);
@@ -1761,7 +1702,7 @@ public class PackageParser {
}
private static ApkLite parseApkLite(String codePath, XmlPullParser parser, AttributeSet attrs,
- Signature[] signatures, Certificate[][] certificates)
+ SigningDetails signingDetails)
throws IOException, XmlPullParserException, PackageParserException {
final Pair<String, String> packageSplit = parsePackageSplitNames(parser, attrs);
@@ -1854,7 +1795,7 @@ public class PackageParser {
return new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit,
configForSplit, usesSplitName, versionCode, versionCodeMajor, revisionCode,
- installLocation, verifiers, signatures, certificates, coreApp, debuggable,
+ installLocation, verifiers, signingDetails, coreApp, debuggable,
multiArch, use32bitAbi, extractNativeLibs, isolatedSplits);
}
@@ -5734,6 +5675,117 @@ public class PackageParser {
return true;
}
+ /** A container for signing-related data of an application package. */
+ public static final class SigningDetails implements Parcelable {
+
+ @IntDef({SigningDetails.SignatureSchemeVersion.UNKNOWN,
+ SigningDetails.SignatureSchemeVersion.JAR,
+ SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2,
+ SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3})
+ public @interface SignatureSchemeVersion {
+ int UNKNOWN = 0;
+ int JAR = 1;
+ int SIGNING_BLOCK_V2 = 2;
+ int SIGNING_BLOCK_V3 = 3;
+ }
+
+ @Nullable
+ public final Signature[] signatures;
+ @SignatureSchemeVersion
+ public final int signatureSchemeVersion;
+ @Nullable
+ public final ArraySet<PublicKey> publicKeys;
+
+ /** A representation of unknown signing details. Use instead of null. */
+ public static final SigningDetails UNKNOWN =
+ new SigningDetails(null, SignatureSchemeVersion.UNKNOWN, null);
+
+ @VisibleForTesting
+ public SigningDetails(Signature[] signatures,
+ @SignatureSchemeVersion int signatureSchemeVersion,
+ ArraySet<PublicKey> keys) {
+ this.signatures = signatures;
+ this.signatureSchemeVersion = signatureSchemeVersion;
+ this.publicKeys = keys;
+ }
+
+ public SigningDetails(Signature[] signatures,
+ @SignatureSchemeVersion int signatureSchemeVersion)
+ throws CertificateException {
+ this(signatures, signatureSchemeVersion, toSigningKeys(signatures));
+ }
+
+ /** Returns true if the signing details have one or more signatures. */
+ public boolean hasSignatures() {
+ return signatures != null && signatures.length > 0;
+ }
+
+ /** Returns true if the signatures in this and other match exactly. */
+ public boolean signaturesMatchExactly(SigningDetails other) {
+ return Signature.areExactMatch(this.signatures, other.signatures);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ boolean isUnknown = UNKNOWN == this;
+ dest.writeBoolean(isUnknown);
+ if (isUnknown) {
+ return;
+ }
+ dest.writeTypedArray(this.signatures, flags);
+ dest.writeInt(this.signatureSchemeVersion);
+ dest.writeArraySet(this.publicKeys);
+ }
+
+ protected SigningDetails(Parcel in) {
+ final ClassLoader boot = Object.class.getClassLoader();
+ this.signatures = in.createTypedArray(Signature.CREATOR);
+ this.signatureSchemeVersion = in.readInt();
+ this.publicKeys = (ArraySet<PublicKey>) in.readArraySet(boot);
+ }
+
+ public static final Creator<SigningDetails> CREATOR = new Creator<SigningDetails>() {
+ @Override
+ public SigningDetails createFromParcel(Parcel source) {
+ if (source.readBoolean()) {
+ return UNKNOWN;
+ }
+ return new SigningDetails(source);
+ }
+
+ @Override
+ public SigningDetails[] newArray(int size) {
+ return new SigningDetails[size];
+ }
+ };
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SigningDetails)) return false;
+
+ SigningDetails that = (SigningDetails) o;
+
+ if (signatureSchemeVersion != that.signatureSchemeVersion) return false;
+ if (!Signature.areExactMatch(signatures, that.signatures)) return false;
+ return publicKeys != null ? publicKeys.equals(that.publicKeys)
+ : that.publicKeys == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = +Arrays.hashCode(signatures);
+ result = 31 * result + signatureSchemeVersion;
+ result = 31 * result + (publicKeys != null ? publicKeys.hashCode() : 0);
+ return result;
+ }
+ }
+
/**
* Representation of a full package parsed from APK files on disk. A package
* consists of a single base APK, and zero or more split APKs.
@@ -5840,8 +5892,7 @@ public class PackageParser {
public int mSharedUserLabel;
// Signatures that were read from the package.
- public Signature[] mSignatures;
- public Certificate[][] mCertificates;
+ @NonNull public SigningDetails mSigningDetails = SigningDetails.UNKNOWN;
// For use by package manager service for quick lookup of
// preferred up order.
@@ -5893,7 +5944,6 @@ public class PackageParser {
/**
* Data used to feed the KeySetManagerService
*/
- public ArraySet<PublicKey> mSigningKeys;
public ArraySet<String> mUpgradeKeySets;
public ArrayMap<String, ArraySet<PublicKey>> mKeySetMapping;
@@ -6037,12 +6087,13 @@ public class PackageParser {
}
}
- public void setSignatures(Signature[] signatures) {
- this.mSignatures = signatures;
+ /** Sets signing details on the package and any of its children. */
+ public void setSigningDetails(@NonNull SigningDetails signingDetails) {
+ mSigningDetails = signingDetails;
if (childPackages != null) {
final int packageCount = childPackages.size();
for (int i = 0; i < packageCount; i++) {
- childPackages.get(i).mSignatures = signatures;
+ childPackages.get(i).mSigningDetails = signingDetails;
}
}
}
@@ -6348,8 +6399,7 @@ public class PackageParser {
}
mSharedUserLabel = dest.readInt();
- mSignatures = (Signature[]) dest.readParcelableArray(boot, Signature.class);
- mCertificates = (Certificate[][]) dest.readSerializable();
+ mSigningDetails = dest.readParcelable(boot);
mPreferredOrder = dest.readInt();
@@ -6389,7 +6439,6 @@ public class PackageParser {
mTrustedOverlay = (dest.readInt() == 1);
mCompileSdkVersion = dest.readInt();
mCompileSdkVersionCodename = dest.readString();
- mSigningKeys = (ArraySet<PublicKey>) dest.readArraySet(boot);
mUpgradeKeySets = (ArraySet<String>) dest.readArraySet(boot);
mKeySetMapping = readKeySetMapping(dest);
@@ -6489,8 +6538,7 @@ public class PackageParser {
dest.writeString(mSharedUserId);
dest.writeInt(mSharedUserLabel);
- dest.writeParcelableArray(mSignatures, flags);
- dest.writeSerializable(mCertificates);
+ dest.writeParcelable(mSigningDetails, flags);
dest.writeInt(mPreferredOrder);
@@ -6515,7 +6563,6 @@ public class PackageParser {
dest.writeInt(mTrustedOverlay ? 1 : 0);
dest.writeInt(mCompileSdkVersion);
dest.writeString(mCompileSdkVersionCodename);
- dest.writeArraySet(mSigningKeys);
dest.writeArraySet(mUpgradeKeySets);
writeKeySetMapping(dest, mKeySetMapping);
dest.writeString(cpuAbiOverride);
diff --git a/core/java/android/util/apk/ApkSignatureVerifier.java b/core/java/android/util/apk/ApkSignatureVerifier.java
index 81467292d491..555c4740389a 100644
--- a/core/java/android/util/apk/ApkSignatureVerifier.java
+++ b/core/java/android/util/apk/ApkSignatureVerifier.java
@@ -25,6 +25,7 @@ import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.PackageParserException;
+import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
import android.content.pm.Signature;
import android.os.Trace;
import android.util.jar.StrictJarFile;
@@ -52,10 +53,6 @@ import java.util.zip.ZipEntry;
*/
public class ApkSignatureVerifier {
- public static final int VERSION_JAR_SIGNATURE_SCHEME = 1;
- public static final int VERSION_APK_SIGNATURE_SCHEME_V2 = 2;
- public static final int VERSION_APK_SIGNATURE_SCHEME_V3 = 3;
-
private static final AtomicReference<byte[]> sBuffer = new AtomicReference<>();
/**
@@ -63,10 +60,11 @@ public class ApkSignatureVerifier {
*
* @throws PackageParserException if the APK's signature failed to verify.
*/
- public static Result verify(String apkPath, int minSignatureSchemeVersion)
+ public static PackageParser.SigningDetails verify(String apkPath,
+ @SignatureSchemeVersion int minSignatureSchemeVersion)
throws PackageParserException {
- if (minSignatureSchemeVersion > VERSION_APK_SIGNATURE_SCHEME_V3) {
+ if (minSignatureSchemeVersion > SignatureSchemeVersion.SIGNING_BLOCK_V3) {
// V3 and before are older than the requested minimum signing version
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
"No signature found in package of version " + minSignatureSchemeVersion
@@ -80,10 +78,11 @@ public class ApkSignatureVerifier {
ApkSignatureSchemeV3Verifier.verify(apkPath);
Certificate[][] signerCerts = new Certificate[][] { vSigner.certs };
Signature[] signerSigs = convertToSignatures(signerCerts);
- return new Result(signerCerts, signerSigs, VERSION_APK_SIGNATURE_SCHEME_V3);
+ return new PackageParser.SigningDetails(signerSigs,
+ SignatureSchemeVersion.SIGNING_BLOCK_V3);
} catch (SignatureNotFoundException e) {
// not signed with v2, try older if allowed
- if (minSignatureSchemeVersion >= VERSION_APK_SIGNATURE_SCHEME_V3) {
+ if (minSignatureSchemeVersion >= SignatureSchemeVersion.SIGNING_BLOCK_V3) {
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
"No APK Signature Scheme v3 signature in package " + apkPath, e);
}
@@ -97,7 +96,7 @@ public class ApkSignatureVerifier {
}
// redundant, protective version check
- if (minSignatureSchemeVersion > VERSION_APK_SIGNATURE_SCHEME_V2) {
+ if (minSignatureSchemeVersion > SignatureSchemeVersion.SIGNING_BLOCK_V2) {
// V2 and before are older than the requested minimum signing version
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
"No signature found in package of version " + minSignatureSchemeVersion
@@ -110,10 +109,11 @@ public class ApkSignatureVerifier {
Certificate[][] signerCerts = ApkSignatureSchemeV2Verifier.verify(apkPath);
Signature[] signerSigs = convertToSignatures(signerCerts);
- return new Result(signerCerts, signerSigs, VERSION_APK_SIGNATURE_SCHEME_V2);
+ return new PackageParser.SigningDetails(
+ signerSigs, SignatureSchemeVersion.SIGNING_BLOCK_V2);
} catch (SignatureNotFoundException e) {
// not signed with v2, try older if allowed
- if (minSignatureSchemeVersion >= VERSION_APK_SIGNATURE_SCHEME_V2) {
+ if (minSignatureSchemeVersion >= SignatureSchemeVersion.SIGNING_BLOCK_V2) {
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
"No APK Signature Scheme v2 signature in package " + apkPath, e);
}
@@ -127,7 +127,7 @@ public class ApkSignatureVerifier {
}
// redundant, protective version check
- if (minSignatureSchemeVersion > VERSION_JAR_SIGNATURE_SCHEME) {
+ if (minSignatureSchemeVersion > SignatureSchemeVersion.JAR) {
// V1 and is older than the requested minimum signing version
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
"No signature found in package of version " + minSignatureSchemeVersion
@@ -145,7 +145,8 @@ public class ApkSignatureVerifier {
*
* @throws PackageParserException if there was a problem collecting certificates
*/
- private static Result verifyV1Signature(String apkPath, boolean verifyFull)
+ private static PackageParser.SigningDetails verifyV1Signature(
+ String apkPath, boolean verifyFull)
throws PackageParserException {
StrictJarFile jarFile = null;
@@ -211,7 +212,7 @@ public class ApkSignatureVerifier {
}
}
}
- return new Result(lastCerts, lastSigs, VERSION_JAR_SIGNATURE_SCHEME);
+ return new PackageParser.SigningDetails(lastSigs, SignatureSchemeVersion.JAR);
} catch (GeneralSecurityException e) {
throw new PackageParserException(INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING,
"Failed to collect certificates from " + apkPath, e);
@@ -289,10 +290,11 @@ public class ApkSignatureVerifier {
* @throws PackageParserException if the APK's signature failed to verify.
* or greater is not found, except in the case of no JAR signature.
*/
- public static Result plsCertsNoVerifyOnlyCerts(String apkPath, int minSignatureSchemeVersion)
+ public static PackageParser.SigningDetails plsCertsNoVerifyOnlyCerts(
+ String apkPath, int minSignatureSchemeVersion)
throws PackageParserException {
- if (minSignatureSchemeVersion > VERSION_APK_SIGNATURE_SCHEME_V3) {
+ if (minSignatureSchemeVersion > SignatureSchemeVersion.SIGNING_BLOCK_V3) {
// V3 and before are older than the requested minimum signing version
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
"No signature found in package of version " + minSignatureSchemeVersion
@@ -306,10 +308,11 @@ public class ApkSignatureVerifier {
ApkSignatureSchemeV3Verifier.plsCertsNoVerifyOnlyCerts(apkPath);
Certificate[][] signerCerts = new Certificate[][] { vSigner.certs };
Signature[] signerSigs = convertToSignatures(signerCerts);
- return new Result(signerCerts, signerSigs, VERSION_APK_SIGNATURE_SCHEME_V3);
+ return new PackageParser.SigningDetails(signerSigs,
+ SignatureSchemeVersion.SIGNING_BLOCK_V3);
} catch (SignatureNotFoundException e) {
// not signed with v2, try older if allowed
- if (minSignatureSchemeVersion >= VERSION_APK_SIGNATURE_SCHEME_V3) {
+ if (minSignatureSchemeVersion >= SignatureSchemeVersion.SIGNING_BLOCK_V3) {
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
"No APK Signature Scheme v3 signature in package " + apkPath, e);
}
@@ -323,7 +326,7 @@ public class ApkSignatureVerifier {
}
// redundant, protective version check
- if (minSignatureSchemeVersion > VERSION_APK_SIGNATURE_SCHEME_V2) {
+ if (minSignatureSchemeVersion > SignatureSchemeVersion.SIGNING_BLOCK_V2) {
// V2 and before are older than the requested minimum signing version
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
"No signature found in package of version " + minSignatureSchemeVersion
@@ -336,10 +339,11 @@ public class ApkSignatureVerifier {
Certificate[][] signerCerts =
ApkSignatureSchemeV2Verifier.plsCertsNoVerifyOnlyCerts(apkPath);
Signature[] signerSigs = convertToSignatures(signerCerts);
- return new Result(signerCerts, signerSigs, VERSION_APK_SIGNATURE_SCHEME_V2);
+ return new PackageParser.SigningDetails(signerSigs,
+ SignatureSchemeVersion.SIGNING_BLOCK_V2);
} catch (SignatureNotFoundException e) {
// not signed with v2, try older if allowed
- if (minSignatureSchemeVersion >= VERSION_APK_SIGNATURE_SCHEME_V2) {
+ if (minSignatureSchemeVersion >= SignatureSchemeVersion.SIGNING_BLOCK_V2) {
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
"No APK Signature Scheme v2 signature in package " + apkPath, e);
}
@@ -353,7 +357,7 @@ public class ApkSignatureVerifier {
}
// redundant, protective version check
- if (minSignatureSchemeVersion > VERSION_JAR_SIGNATURE_SCHEME) {
+ if (minSignatureSchemeVersion > SignatureSchemeVersion.JAR) {
// V1 and is older than the requested minimum signing version
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
"No signature found in package of version " + minSignatureSchemeVersion
@@ -363,19 +367,4 @@ public class ApkSignatureVerifier {
// v2 didn't work, try jarsigner
return verifyV1Signature(apkPath, false);
}
-
- /**
- * Result of a successful APK verification operation.
- */
- public static class Result {
- public final Certificate[][] certs;
- public final Signature[] sigs;
- public final int signatureSchemeVersion;
-
- public Result(Certificate[][] certs, Signature[] sigs, int signingVersion) {
- this.certs = certs;
- this.sigs = sigs;
- this.signatureSchemeVersion = signingVersion;
- }
- }
}