Merge "Revert "Move signing data into SigningDetails container""
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 367c39d..77eb57f2 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -85,6 +85,7 @@
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;
@@ -111,7 +112,8 @@
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
-import java.security.cert.CertificateException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
@@ -156,6 +158,10 @@
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
@@ -471,7 +477,8 @@
public final int revisionCode;
public final int installLocation;
public final VerifierInfo[] verifiers;
- public final SigningDetails signingDetails;
+ public final Signature[] signatures;
+ public final Certificate[][] certificates;
public final boolean coreApp;
public final boolean debuggable;
public final boolean multiArch;
@@ -479,11 +486,10 @@
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,
- SigningDetails signingDetails, boolean coreApp,
+ Signature[] signatures, Certificate[][] certificates, boolean coreApp,
boolean debuggable, boolean multiArch, boolean use32bitAbi,
boolean extractNativeLibs, boolean isolatedSplits) {
this.codePath = codePath;
@@ -496,8 +502,9 @@
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;
@@ -800,10 +807,10 @@
}
}
if ((flags&PackageManager.GET_SIGNATURES) != 0) {
- 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);
+ 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);
}
}
return pi;
@@ -1342,7 +1349,7 @@
pkg.setVolumeUuid(volumeUuid);
pkg.setApplicationVolumeUuid(volumeUuid);
pkg.setBaseCodePath(apkPath);
- pkg.setSigningDetails(SigningDetails.UNKNOWN);
+ pkg.setSignatures(null);
return pkg;
@@ -1462,19 +1469,57 @@
return pkg;
}
- /** 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());
+ public static int getApkSigningVersion(Package pkg) {
+ try {
+ if (ApkSignatureSchemeV2Verifier.hasSignature(pkg.baseCodePath)) {
+ return APK_SIGNING_V2;
+ }
+ return APK_SIGNING_V1;
+ } catch (IOException e) {
}
- return keys;
+ 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;
+ }
}
/**
* Collect certificates from all the APKs described in the given package,
- * populating {@link Package#mSigningDetails}. Also asserts that all APK
+ * populating {@link Package#mSignatures}. Also asserts that all APK
* contents are signed correctly and consistently.
*/
public static void collectCertificates(Package pkg, @ParseFlags int parseFlags)
@@ -1483,13 +1528,17 @@
final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
Package childPkg = pkg.childPackages.get(i);
- childPkg.mSigningDetails = pkg.mSigningDetails;
+ childPkg.mCertificates = pkg.mCertificates;
+ childPkg.mSignatures = pkg.mSignatures;
+ childPkg.mSigningKeys = pkg.mSigningKeys;
}
}
private static void collectCertificatesInternal(Package pkg, @ParseFlags int parseFlags)
throws PackageParserException {
- pkg.mSigningDetails = SigningDetails.UNKNOWN;
+ pkg.mCertificates = null;
+ pkg.mSignatures = null;
+ pkg.mSigningKeys = null;
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
try {
@@ -1509,12 +1558,12 @@
throws PackageParserException {
final String apkPath = apkFile.getAbsolutePath();
- int minSignatureScheme = SigningDetails.SignatureSchemeVersion.JAR;
+ int minSignatureScheme = ApkSignatureVerifier.VERSION_JAR_SIGNATURE_SCHEME;
if (pkg.applicationInfo.isStaticSharedLibrary()) {
// must use v2 signing scheme
- minSignatureScheme = SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2;
+ minSignatureScheme = ApkSignatureVerifier.VERSION_APK_SIGNATURE_SCHEME_V2;
}
- SigningDetails verified;
+ ApkSignatureVerifier.Result verified;
if ((parseFlags & PARSE_IS_SYSTEM_DIR) != 0) {
// systemDir APKs are already trusted, save time by not verifying
verified = ApkSignatureVerifier.plsCertsNoVerifyOnlyCerts(
@@ -1523,7 +1572,7 @@
verified = ApkSignatureVerifier.verify(apkPath, minSignatureScheme);
}
if (verified.signatureSchemeVersion
- < SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2) {
+ < ApkSignatureVerifier.VERSION_APK_SIGNATURE_SCHEME_V2) {
// TODO (b/68860689): move this logic to packagemanagerserivce
if ((parseFlags & PARSE_IS_EPHEMERAL) != 0) {
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
@@ -1534,10 +1583,17 @@
// 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.mSigningDetails == SigningDetails.UNKNOWN) {
- pkg.mSigningDetails = verified;
+ 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());
+ }
} else {
- if (!Signature.areExactMatch(pkg.mSigningDetails.signatures, verified.signatures)) {
+ if (!Signature.areExactMatch(pkg.mSignatures, verified.sigs)) {
throw new PackageParserException(
INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
apkPath + " has mismatched certificates");
@@ -1599,7 +1655,8 @@
parser = assets.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
- final SigningDetails signingDetails;
+ final Signature[] signatures;
+ final Certificate[][] certificates;
if ((flags & PARSE_COLLECT_CERTIFICATES) != 0) {
// TODO: factor signature related items out of Package object
final Package tempPkg = new Package((String) null);
@@ -1609,13 +1666,15 @@
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
- signingDetails = tempPkg.mSigningDetails;
+ signatures = tempPkg.mSignatures;
+ certificates = tempPkg.mCertificates;
} else {
- signingDetails = SigningDetails.UNKNOWN;
+ signatures = null;
+ certificates = null;
}
final AttributeSet attrs = parser;
- return parseApkLite(apkPath, parser, attrs, signingDetails);
+ return parseApkLite(apkPath, parser, attrs, signatures, certificates);
} catch (XmlPullParserException | IOException | RuntimeException e) {
Slog.w(TAG, "Failed to parse " + apkPath, e);
@@ -1702,7 +1761,7 @@
}
private static ApkLite parseApkLite(String codePath, XmlPullParser parser, AttributeSet attrs,
- SigningDetails signingDetails)
+ Signature[] signatures, Certificate[][] certificates)
throws IOException, XmlPullParserException, PackageParserException {
final Pair<String, String> packageSplit = parsePackageSplitNames(parser, attrs);
@@ -1795,7 +1854,7 @@
return new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit,
configForSplit, usesSplitName, versionCode, versionCodeMajor, revisionCode,
- installLocation, verifiers, signingDetails, coreApp, debuggable,
+ installLocation, verifiers, signatures, certificates, coreApp, debuggable,
multiArch, use32bitAbi, extractNativeLibs, isolatedSplits);
}
@@ -5675,117 +5734,6 @@
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.
@@ -5892,7 +5840,8 @@
public int mSharedUserLabel;
// Signatures that were read from the package.
- @NonNull public SigningDetails mSigningDetails = SigningDetails.UNKNOWN;
+ public Signature[] mSignatures;
+ public Certificate[][] mCertificates;
// For use by package manager service for quick lookup of
// preferred up order.
@@ -5944,6 +5893,7 @@
/**
* Data used to feed the KeySetManagerService
*/
+ public ArraySet<PublicKey> mSigningKeys;
public ArraySet<String> mUpgradeKeySets;
public ArrayMap<String, ArraySet<PublicKey>> mKeySetMapping;
@@ -6087,13 +6037,12 @@
}
}
- /** Sets signing details on the package and any of its children. */
- public void setSigningDetails(@NonNull SigningDetails signingDetails) {
- mSigningDetails = signingDetails;
+ public void setSignatures(Signature[] signatures) {
+ this.mSignatures = signatures;
if (childPackages != null) {
final int packageCount = childPackages.size();
for (int i = 0; i < packageCount; i++) {
- childPackages.get(i).mSigningDetails = signingDetails;
+ childPackages.get(i).mSignatures = signatures;
}
}
}
@@ -6399,7 +6348,8 @@
}
mSharedUserLabel = dest.readInt();
- mSigningDetails = dest.readParcelable(boot);
+ mSignatures = (Signature[]) dest.readParcelableArray(boot, Signature.class);
+ mCertificates = (Certificate[][]) dest.readSerializable();
mPreferredOrder = dest.readInt();
@@ -6439,6 +6389,7 @@
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);
@@ -6538,7 +6489,8 @@
dest.writeString(mSharedUserId);
dest.writeInt(mSharedUserLabel);
- dest.writeParcelable(mSigningDetails, flags);
+ dest.writeParcelableArray(mSignatures, flags);
+ dest.writeSerializable(mCertificates);
dest.writeInt(mPreferredOrder);
@@ -6563,6 +6515,7 @@
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 555c474..8146729 100644
--- a/core/java/android/util/apk/ApkSignatureVerifier.java
+++ b/core/java/android/util/apk/ApkSignatureVerifier.java
@@ -25,7 +25,6 @@
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;
@@ -53,6 +52,10 @@
*/
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<>();
/**
@@ -60,11 +63,10 @@
*
* @throws PackageParserException if the APK's signature failed to verify.
*/
- public static PackageParser.SigningDetails verify(String apkPath,
- @SignatureSchemeVersion int minSignatureSchemeVersion)
+ public static Result verify(String apkPath, int minSignatureSchemeVersion)
throws PackageParserException {
- if (minSignatureSchemeVersion > SignatureSchemeVersion.SIGNING_BLOCK_V3) {
+ if (minSignatureSchemeVersion > VERSION_APK_SIGNATURE_SCHEME_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
@@ -78,11 +80,10 @@
ApkSignatureSchemeV3Verifier.verify(apkPath);
Certificate[][] signerCerts = new Certificate[][] { vSigner.certs };
Signature[] signerSigs = convertToSignatures(signerCerts);
- return new PackageParser.SigningDetails(signerSigs,
- SignatureSchemeVersion.SIGNING_BLOCK_V3);
+ return new Result(signerCerts, signerSigs, VERSION_APK_SIGNATURE_SCHEME_V3);
} catch (SignatureNotFoundException e) {
// not signed with v2, try older if allowed
- if (minSignatureSchemeVersion >= SignatureSchemeVersion.SIGNING_BLOCK_V3) {
+ if (minSignatureSchemeVersion >= VERSION_APK_SIGNATURE_SCHEME_V3) {
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
"No APK Signature Scheme v3 signature in package " + apkPath, e);
}
@@ -96,7 +97,7 @@
}
// redundant, protective version check
- if (minSignatureSchemeVersion > SignatureSchemeVersion.SIGNING_BLOCK_V2) {
+ if (minSignatureSchemeVersion > VERSION_APK_SIGNATURE_SCHEME_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
@@ -109,11 +110,10 @@
Certificate[][] signerCerts = ApkSignatureSchemeV2Verifier.verify(apkPath);
Signature[] signerSigs = convertToSignatures(signerCerts);
- return new PackageParser.SigningDetails(
- signerSigs, SignatureSchemeVersion.SIGNING_BLOCK_V2);
+ return new Result(signerCerts, signerSigs, VERSION_APK_SIGNATURE_SCHEME_V2);
} catch (SignatureNotFoundException e) {
// not signed with v2, try older if allowed
- if (minSignatureSchemeVersion >= SignatureSchemeVersion.SIGNING_BLOCK_V2) {
+ if (minSignatureSchemeVersion >= VERSION_APK_SIGNATURE_SCHEME_V2) {
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
"No APK Signature Scheme v2 signature in package " + apkPath, e);
}
@@ -127,7 +127,7 @@
}
// redundant, protective version check
- if (minSignatureSchemeVersion > SignatureSchemeVersion.JAR) {
+ if (minSignatureSchemeVersion > VERSION_JAR_SIGNATURE_SCHEME) {
// 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,8 +145,7 @@
*
* @throws PackageParserException if there was a problem collecting certificates
*/
- private static PackageParser.SigningDetails verifyV1Signature(
- String apkPath, boolean verifyFull)
+ private static Result verifyV1Signature(String apkPath, boolean verifyFull)
throws PackageParserException {
StrictJarFile jarFile = null;
@@ -212,7 +211,7 @@
}
}
}
- return new PackageParser.SigningDetails(lastSigs, SignatureSchemeVersion.JAR);
+ return new Result(lastCerts, lastSigs, VERSION_JAR_SIGNATURE_SCHEME);
} catch (GeneralSecurityException e) {
throw new PackageParserException(INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING,
"Failed to collect certificates from " + apkPath, e);
@@ -290,11 +289,10 @@
* @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 PackageParser.SigningDetails plsCertsNoVerifyOnlyCerts(
- String apkPath, int minSignatureSchemeVersion)
+ public static Result plsCertsNoVerifyOnlyCerts(String apkPath, int minSignatureSchemeVersion)
throws PackageParserException {
- if (minSignatureSchemeVersion > SignatureSchemeVersion.SIGNING_BLOCK_V3) {
+ if (minSignatureSchemeVersion > VERSION_APK_SIGNATURE_SCHEME_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
@@ -308,11 +306,10 @@
ApkSignatureSchemeV3Verifier.plsCertsNoVerifyOnlyCerts(apkPath);
Certificate[][] signerCerts = new Certificate[][] { vSigner.certs };
Signature[] signerSigs = convertToSignatures(signerCerts);
- return new PackageParser.SigningDetails(signerSigs,
- SignatureSchemeVersion.SIGNING_BLOCK_V3);
+ return new Result(signerCerts, signerSigs, VERSION_APK_SIGNATURE_SCHEME_V3);
} catch (SignatureNotFoundException e) {
// not signed with v2, try older if allowed
- if (minSignatureSchemeVersion >= SignatureSchemeVersion.SIGNING_BLOCK_V3) {
+ if (minSignatureSchemeVersion >= VERSION_APK_SIGNATURE_SCHEME_V3) {
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
"No APK Signature Scheme v3 signature in package " + apkPath, e);
}
@@ -326,7 +323,7 @@
}
// redundant, protective version check
- if (minSignatureSchemeVersion > SignatureSchemeVersion.SIGNING_BLOCK_V2) {
+ if (minSignatureSchemeVersion > VERSION_APK_SIGNATURE_SCHEME_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
@@ -339,11 +336,10 @@
Certificate[][] signerCerts =
ApkSignatureSchemeV2Verifier.plsCertsNoVerifyOnlyCerts(apkPath);
Signature[] signerSigs = convertToSignatures(signerCerts);
- return new PackageParser.SigningDetails(signerSigs,
- SignatureSchemeVersion.SIGNING_BLOCK_V2);
+ return new Result(signerCerts, signerSigs, VERSION_APK_SIGNATURE_SCHEME_V2);
} catch (SignatureNotFoundException e) {
// not signed with v2, try older if allowed
- if (minSignatureSchemeVersion >= SignatureSchemeVersion.SIGNING_BLOCK_V2) {
+ if (minSignatureSchemeVersion >= VERSION_APK_SIGNATURE_SCHEME_V2) {
throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
"No APK Signature Scheme v2 signature in package " + apkPath, e);
}
@@ -357,7 +353,7 @@
}
// redundant, protective version check
- if (minSignatureSchemeVersion > SignatureSchemeVersion.JAR) {
+ if (minSignatureSchemeVersion > VERSION_JAR_SIGNATURE_SCHEME) {
// 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
@@ -367,4 +363,19 @@
// 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;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/pm/InstantAppRegistry.java b/services/core/java/com/android/server/pm/InstantAppRegistry.java
index af20cd7..c964f91 100644
--- a/services/core/java/com/android/server/pm/InstantAppRegistry.java
+++ b/services/core/java/com/android/server/pm/InstantAppRegistry.java
@@ -49,6 +49,7 @@
import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.XmlUtils;
+import com.android.server.pm.permission.BasePermission;
import libcore.io.IoUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -301,7 +302,7 @@
// into account but also allow the value from the old computation to avoid
// data loss.
final String[] signaturesSha256Digests = PackageUtils.computeSignaturesSha256Digests(
- pkg.mSigningDetails.signatures);
+ pkg.mSignatures);
final String signaturesSha256Digest = PackageUtils.computeSignaturesSha256Digest(
signaturesSha256Digests);
@@ -312,7 +313,7 @@
}
// For backwards compatibility we accept match based on first signature
- if (pkg.mSigningDetails.signatures.length > 1 && currentCookieFile.equals(computeInstantCookieFile(
+ if (pkg.mSignatures.length > 1 && currentCookieFile.equals(computeInstantCookieFile(
pkg.packageName, signaturesSha256Digests[0], userId))) {
return;
}
@@ -1175,13 +1176,12 @@
// We prefer the modern computation procedure where all certs are taken
// into account and delete the file derived via the legacy hash computation.
File newCookieFile = computeInstantCookieFile(pkg.packageName,
- PackageUtils.computeSignaturesSha256Digest(pkg.mSigningDetails.signatures), userId);
- if (!pkg.mSigningDetails.hasSignatures()) {
- Slog.wtf(LOG_TAG, "Parsed Instant App contains no valid signatures!");
- }
- File oldCookieFile = peekInstantCookieFile(pkg.packageName, userId);
- if (oldCookieFile != null && !newCookieFile.equals(oldCookieFile)) {
- oldCookieFile.delete();
+ PackageUtils.computeSignaturesSha256Digest(pkg.mSignatures), userId);
+ if (pkg.mSignatures.length > 0) {
+ File oldCookieFile = peekInstantCookieFile(pkg.packageName, userId);
+ if (oldCookieFile != null && !newCookieFile.equals(oldCookieFile)) {
+ oldCookieFile.delete();
+ }
}
cancelPendingPersistLPw(pkg, userId);
addPendingPersistCookieLPw(userId, pkg, cookie, newCookieFile);
diff --git a/services/core/java/com/android/server/pm/KeySetManagerService.java b/services/core/java/com/android/server/pm/KeySetManagerService.java
index 93d3b77..fca9585 100644
--- a/services/core/java/com/android/server/pm/KeySetManagerService.java
+++ b/services/core/java/com/android/server/pm/KeySetManagerService.java
@@ -188,7 +188,7 @@
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
"Passed invalid package to keyset validation.");
}
- ArraySet<PublicKey> signingKeys = pkg.mSigningDetails.publicKeys;
+ ArraySet<PublicKey> signingKeys = pkg.mSigningKeys;
if (signingKeys == null || !(signingKeys.size() > 0) || signingKeys.contains(null)) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
"Package has invalid signing-key-set.");
@@ -223,7 +223,7 @@
PackageSetting ps = mPackages.get(pkg.packageName);
Preconditions.checkNotNull(ps, "pkg: " + pkg.packageName
+ "does not have a corresponding entry in mPackages.");
- addSigningKeySetToPackageLPw(ps, pkg.mSigningDetails.publicKeys);
+ addSigningKeySetToPackageLPw(ps, pkg.mSigningKeys);
if (pkg.mKeySetMapping != null) {
addDefinedKeySetsToPackageLPw(ps, pkg.mKeySetMapping);
if (pkg.mUpgradeKeySets != null) {
@@ -371,7 +371,7 @@
long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
for (int i = 0; i < upgradeKeySets.length; i++) {
Set<PublicKey> upgradeSet = getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
- if (upgradeSet != null && newPkg.mSigningDetails.publicKeys.containsAll(upgradeSet)) {
+ if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
return true;
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 4e91898..5577de8 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -58,6 +58,7 @@
import android.content.pm.PackageParser.ApkLite;
import android.content.pm.PackageParser.PackageLite;
import android.content.pm.PackageParser.PackageParserException;
+import android.content.pm.Signature;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Binder;
@@ -83,7 +84,6 @@
import android.util.ExceptionUtils;
import android.util.MathUtils;
import android.util.Slog;
-import android.util.apk.ApkSignatureVerifier;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.NativeLibraryHelper;
@@ -107,7 +107,7 @@
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.security.cert.CertificateException;
+import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -227,7 +227,9 @@
@GuardedBy("mLock")
private long mVersionCode;
@GuardedBy("mLock")
- private PackageParser.SigningDetails mSigningDetails;
+ private Signature[] mSignatures;
+ @GuardedBy("mLock")
+ private Certificate[][] mCertificates;
/**
* Path to the validated base APK for this session, which may point at an
@@ -855,7 +857,7 @@
}
Preconditions.checkNotNull(mPackageName);
- Preconditions.checkNotNull(mSigningDetails);
+ Preconditions.checkNotNull(mSignatures);
Preconditions.checkNotNull(mResolvedBaseFile);
if (needToAskForPermissionsLocked()) {
@@ -936,7 +938,7 @@
mRelinquished = true;
mPm.installStage(mPackageName, stageDir, localObserver, params,
- mInstallerPackageName, mInstallerUid, user, mSigningDetails);
+ mInstallerPackageName, mInstallerUid, user, mCertificates);
}
/**
@@ -955,7 +957,7 @@
throws PackageManagerException {
mPackageName = null;
mVersionCode = -1;
- mSigningDetails = PackageParser.SigningDetails.UNKNOWN;
+ mSignatures = null;
mResolvedBaseFile = null;
mResolvedStagedFiles.clear();
@@ -1007,8 +1009,9 @@
mPackageName = apk.packageName;
mVersionCode = apk.getLongVersionCode();
}
- if (mSigningDetails == PackageParser.SigningDetails.UNKNOWN) {
- mSigningDetails = apk.signingDetails;
+ if (mSignatures == null) {
+ mSignatures = apk.signatures;
+ mCertificates = apk.certificates;
}
assertApkConsistentLocked(String.valueOf(addedFile), apk);
@@ -1057,15 +1060,8 @@
mPackageName = pkgInfo.packageName;
mVersionCode = pkgInfo.getLongVersionCode();
}
- if (mSigningDetails == PackageParser.SigningDetails.UNKNOWN) {
- try {
- mSigningDetails = ApkSignatureVerifier.plsCertsNoVerifyOnlyCerts(
- pkgInfo.applicationInfo.sourceDir,
- PackageParser.SigningDetails.SignatureSchemeVersion.JAR);
- } catch (PackageParserException e) {
- throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
- "Couldn't obtain signatures from base APK");
- }
+ if (mSignatures == null) {
+ mSignatures = pkgInfo.signatures;
}
}
@@ -1159,7 +1155,7 @@
+ " version code " + apk.versionCode + " inconsistent with "
+ mVersionCode);
}
- if (!mSigningDetails.signaturesMatchExactly(apk.signingDetails)) {
+ if (!Signature.areExactMatch(mSignatures, apk.signatures)) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
tag + " signatures are inconsistent");
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 3df7c47..44aad44 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -337,6 +337,7 @@
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.SecureRandom;
+import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -5359,7 +5360,7 @@
|| filterAppAccessLPr(ps2, callingUid, callingUserId)) {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
- return compareSignatures(p1.mSigningDetails.signatures, p2.mSigningDetails.signatures);
+ return compareSignatures(p1.mSignatures, p2.mSignatures);
}
}
@@ -8193,11 +8194,19 @@
&& ps.timeStamp == lastModifiedTime
&& !isCompatSignatureUpdateNeeded(pkg)
&& !isRecoverSignatureUpdateNeeded(pkg)) {
- if ((ps.pkg != null) &&
- PackageParser.SigningDetails.UNKNOWN != ps.pkg.mSigningDetails) {
- // Optimization: reuse the existing cached signing data
+ long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
+ final KeySetManagerService ksms = mSettings.mKeySetManagerService;
+ ArraySet<PublicKey> signingKs;
+ synchronized (mPackages) {
+ signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
+ }
+ if (ps.signatures.mSignatures != null
+ && ps.signatures.mSignatures.length != 0
+ && signingKs != null) {
+ // Optimization: reuse the existing cached certificates
// if the package appears to be unchanged.
- pkg.mSigningDetails = ps.pkg.mSigningDetails;
+ pkg.mSignatures = ps.signatures.mSignatures;
+ pkg.mSigningKeys = signingKs;
return;
}
@@ -8537,7 +8546,7 @@
* Check to make sure the signatures match first. If they don't,
* wipe the installed application and its data.
*/
- if (compareSignatures(ps.signatures.mSignatures, pkg.mSigningDetails.signatures)
+ if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
!= PackageManager.SIGNATURE_MATCH) {
logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
+ " signatures don't match existing userdata copy; removing");
@@ -9509,10 +9518,9 @@
final String[] expectedCertDigests = requiredCertDigests[i];
// For apps targeting O MR1 we require explicit enumeration of all certs.
final String[] libCertDigests = (targetSdk > Build.VERSION_CODES.O)
- ? PackageUtils.computeSignaturesSha256Digests(
- libPkg.mSigningDetails.signatures)
+ ? PackageUtils.computeSignaturesSha256Digests(libPkg.mSignatures)
: PackageUtils.computeSignaturesSha256Digests(
- new Signature[]{libPkg.mSigningDetails.signatures[0]});
+ new Signature[]{libPkg.mSignatures[0]});
// Take a shortcut if sizes don't match. Note that if an app doesn't
// target O we don't parse the "additional-certificate" tags similarly
@@ -9848,14 +9856,14 @@
if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
// We just determined the app is signed correctly, so bring
// over the latest parsed certs.
- pkgSetting.signatures.mSignatures = pkg.mSigningDetails.signatures;
+ pkgSetting.signatures.mSignatures = pkg.mSignatures;
} else {
if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
"Package " + pkg.packageName + " upgrade keys do not match the "
+ "previously installed version");
} else {
- pkgSetting.signatures.mSignatures = pkg.mSigningDetails.signatures;
+ pkgSetting.signatures.mSignatures = pkg.mSignatures;
String msg = "System package " + pkg.packageName
+ " signature changed; retaining data.";
reportSettingsProblem(Log.WARN, msg);
@@ -9865,8 +9873,7 @@
try {
final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
- final boolean compatMatch = verifySignatures(signatureCheckPs,
- pkg.mSigningDetails.signatures,
+ final boolean compatMatch = verifySignatures(signatureCheckPs, pkg.mSignatures,
compareCompat, compareRecover);
// The new KeySets will be re-added later in the scanning process.
if (compatMatch) {
@@ -9876,14 +9883,14 @@
}
// We just determined the app is signed correctly, so bring
// over the latest parsed certs.
- pkgSetting.signatures.mSignatures = pkg.mSigningDetails.signatures;
+ pkgSetting.signatures.mSignatures = pkg.mSignatures;
} catch (PackageManagerException e) {
if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
throw e;
}
// The signature has changed, but this package is in the system
// image... let's recover!
- pkgSetting.signatures.mSignatures = pkg.mSigningDetails.signatures;
+ pkgSetting.signatures.mSignatures = pkg.mSignatures;
// However... if this package is part of a shared user, but it
// doesn't match the signature of the shared user, let's fail.
// What this means is that you can't change the signatures
@@ -9891,7 +9898,7 @@
// that unreasonable.
if (signatureCheckPs.sharedUser != null) {
if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
- pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH) {
+ pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
throw new PackageManagerException(
INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
"Signature mismatch for shared user: "
@@ -13197,7 +13204,7 @@
void installStage(String packageName, File stagedDir,
IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
String installerPackageName, int installerUid, UserHandle user,
- PackageParser.SigningDetails signingDetails) {
+ Certificate[][] certificates) {
if (DEBUG_EPHEMERAL) {
if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
Slog.d(TAG, "Ephemeral install of " + packageName);
@@ -13215,7 +13222,7 @@
final InstallParams params = new InstallParams(origin, null, observer,
sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
verificationInfo, user, sessionParams.abiOverride,
- sessionParams.grantedRuntimePermissions, signingDetails, installReason);
+ sessionParams.grantedRuntimePermissions, certificates, installReason);
params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
msg.obj = params;
@@ -13819,7 +13826,7 @@
final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
if (pkg == null) {
return -1;
- } else if (pkg.mSigningDetails.signatures.length != 1) {
+ } else if (pkg.mSignatures.length != 1) {
Slog.i(TAG, "Verifier package " + verifierInfo.packageName
+ " has more than one signature; ignoring");
return -1;
@@ -13833,7 +13840,7 @@
final byte[] expectedPublicKey;
try {
- final Signature verifierSig = pkg.mSigningDetails.signatures[0];
+ final Signature verifierSig = pkg.mSignatures[0];
final PublicKey publicKey = verifierSig.getPublicKey();
expectedPublicKey = publicKey.getEncoded();
} catch (CertificateException e) {
@@ -14525,13 +14532,13 @@
final String packageAbiOverride;
final String[] grantedRuntimePermissions;
final VerificationInfo verificationInfo;
- final PackageParser.SigningDetails signingDetails;
+ final Certificate[][] certificates;
final int installReason;
InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
int installFlags, String installerPackageName, String volumeUuid,
VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
- String[] grantedPermissions, PackageParser.SigningDetails signingDetails, int installReason) {
+ String[] grantedPermissions, Certificate[][] certificates, int installReason) {
super(user);
this.origin = origin;
this.move = move;
@@ -14542,7 +14549,7 @@
this.verificationInfo = verificationInfo;
this.packageAbiOverride = packageAbiOverride;
this.grantedRuntimePermissions = grantedPermissions;
- this.signingDetails = signingDetails;
+ this.certificates = certificates;
this.installReason = installReason;
}
@@ -14973,7 +14980,7 @@
/** If non-null, drop an async trace when the install completes */
final String traceMethod;
final int traceCookie;
- final PackageParser.SigningDetails signingDetails;
+ final Certificate[][] certificates;
final int installReason;
// The list of instruction sets supported by this app. This is currently
@@ -14985,7 +14992,7 @@
int installFlags, String installerPackageName, String volumeUuid,
UserHandle user, String[] instructionSets,
String abiOverride, String[] installGrantPermissions,
- String traceMethod, int traceCookie, PackageParser.SigningDetails signingDetails,
+ String traceMethod, int traceCookie, Certificate[][] certificates,
int installReason) {
this.origin = origin;
this.move = move;
@@ -14999,7 +15006,7 @@
this.installGrantPermissions = installGrantPermissions;
this.traceMethod = traceMethod;
this.traceCookie = traceCookie;
- this.signingDetails = signingDetails;
+ this.certificates = certificates;
this.installReason = installReason;
}
@@ -15095,7 +15102,7 @@
params.installerPackageName, params.volumeUuid,
params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
params.grantedRuntimePermissions,
- params.traceMethod, params.traceCookie, params.signingDetails,
+ params.traceMethod, params.traceCookie, params.certificates,
params.installReason);
if (isFwdLocked()) {
throw new IllegalArgumentException("Forward locking only supported in ASEC");
@@ -15105,7 +15112,7 @@
/** Existing install */
FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
- null, null, null, 0, PackageParser.SigningDetails.UNKNOWN,
+ null, null, null, 0, null /*certificates*/,
PackageManager.INSTALL_REASON_UNKNOWN);
this.codeFile = (codePath != null) ? new File(codePath) : null;
this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
@@ -15326,7 +15333,7 @@
params.installerPackageName, params.volumeUuid,
params.getUser(), null /* instruction sets */, params.packageAbiOverride,
params.grantedRuntimePermissions,
- params.traceMethod, params.traceCookie, params.signingDetails,
+ params.traceMethod, params.traceCookie, params.certificates,
params.installReason);
}
@@ -15665,8 +15672,7 @@
}
} else {
// default to original signature matching
- if (compareSignatures(oldPackage.mSigningDetails.signatures,
- pkg.mSigningDetails.signatures)
+ if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
!= PackageManager.SIGNATURE_MATCH) {
res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
"New package has a different signature: " + pkgName);
@@ -16478,8 +16484,14 @@
try {
// either use what we've been given or parse directly from the APK
- if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
- pkg.setSigningDetails(args.signingDetails);
+ if (args.certificates != null) {
+ try {
+ PackageParser.populateCertificates(pkg, args.certificates);
+ } catch (PackageParserException e) {
+ // there was something wrong with the certificates we were given;
+ // try to pull them from the APK
+ PackageParser.collectCertificates(pkg, parseFlags);
+ }
} else {
PackageParser.collectCertificates(pkg, parseFlags);
}
@@ -16598,8 +16610,7 @@
final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
final boolean compatMatch = verifySignatures(
- signatureCheckPs, pkg.mSigningDetails.signatures, compareCompat,
- compareRecover);
+ signatureCheckPs, pkg.mSignatures, compareCompat, compareRecover);
// The new KeySets will be re-added later in the scanning process.
if (compatMatch) {
synchronized (mPackages) {
@@ -16650,7 +16661,7 @@
sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, pkg);
} else {
sigsOk = compareSignatures(sourcePackageSetting.signatures.mSignatures,
- pkg.mSigningDetails.signatures) == PackageManager.SIGNATURE_MATCH;
+ pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
}
if (!sigsOk) {
// If the owning package is the system itself, we log but allow
@@ -16926,8 +16937,7 @@
for (ActivityIntentInfo filter : a.intents) {
if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
if (DEBUG_DOMAIN_VERIFICATION) {
- Slog.d(TAG,
- "Intent filter needs verification, so processing all filters");
+ Slog.d(TAG, "Intent filter needs verification, so processing all filters");
}
needToVerify = true;
break;
@@ -22235,8 +22245,8 @@
final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
installerPackageName, volumeUuid, null /*verificationInfo*/, user,
- packageAbiOverride, null /*grantedPermissions*/,
- PackageParser.SigningDetails.UNKNOWN, PackageManager.INSTALL_REASON_UNKNOWN);
+ packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
+ PackageManager.INSTALL_REASON_UNKNOWN);
params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
msg.obj = params;
diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java
index 37f9a74..fbf3d82 100644
--- a/services/core/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java
@@ -17,6 +17,8 @@
package com.android.server.pm;
import android.content.pm.PackageParser;
+import android.content.pm.PackageUserState;
+import android.content.pm.SELinuxUtil;
import android.content.pm.Signature;
import android.os.Environment;
import android.util.Slog;
@@ -451,7 +453,7 @@
public String getMatchedSeInfo(PackageParser.Package pkg) {
// Check for exact signature matches across all certs.
Signature[] certs = mCerts.toArray(new Signature[0]);
- if (!Signature.areExactMatch(certs, pkg.mSigningDetails.signatures)) {
+ if (!Signature.areExactMatch(certs, pkg.mSignatures)) {
return null;
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index b5d3af1..4cf1814 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -955,7 +955,7 @@
}
// Update signatures if needed.
if (p.signatures.mSignatures == null) {
- p.signatures.assignSignatures(pkg.mSigningDetails.signatures);
+ p.signatures.assignSignatures(pkg.mSignatures);
}
// Update flags if needed.
if (pkg.applicationInfo.flags != p.pkgFlags) {
@@ -964,7 +964,7 @@
// If this app defines a shared user id initialize
// the shared user signatures as well.
if (p.sharedUser != null && p.sharedUser.signatures.mSignatures == null) {
- p.sharedUser.signatures.assignSignatures(pkg.mSigningDetails.signatures);
+ p.sharedUser.signatures.assignSignatures(pkg.mSignatures);
}
// Update static shared library dependencies if needed
if (pkg.usesStaticLibraries != null && pkg.usesStaticLibrariesVersions != null
@@ -4565,8 +4565,10 @@
}
pw.print(prefix); pw.print(" versionName="); pw.println(ps.pkg.mVersionName);
pw.print(prefix); pw.print(" splits="); dumpSplitNames(pw, ps.pkg); pw.println();
- final int apkSigningVersion = ps.pkg.mSigningDetails.signatureSchemeVersion;
- pw.print(prefix); pw.print(" apkSigningVersion="); pw.println(apkSigningVersion);
+ final int apkSigningVersion = PackageParser.getApkSigningVersion(ps.pkg);
+ if (apkSigningVersion != PackageParser.APK_SIGNING_UNKNOWN) {
+ pw.print(prefix); pw.print(" apkSigningVersion="); pw.println(apkSigningVersion);
+ }
pw.print(prefix); pw.print(" applicationInfo=");
pw.println(ps.pkg.applicationInfo.toString());
pw.print(prefix); pw.print(" flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 6e07eaa..34c3ce3 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -27,6 +27,7 @@
import android.companion.CompanionDeviceManager;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageList;
@@ -61,6 +62,8 @@
import android.util.Xml;
import com.android.internal.util.XmlUtils;
import com.android.server.LocalServices;
+import com.android.server.pm.PackageManagerService;
+import com.android.server.pm.PackageSetting;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -1166,8 +1169,7 @@
final String systemPackageName = mServiceInternal.getKnownPackageName(
PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
final PackageParser.Package systemPackage = getPackage(systemPackageName);
- return compareSignatures(systemPackage.mSigningDetails.signatures,
- pkg.mSigningDetails.signatures)
+ return compareSignatures(systemPackage.mSignatures, pkg.mSignatures)
== PackageManager.SIGNATURE_MATCH;
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 786b998..90ac4ab 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -29,6 +29,7 @@
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
@@ -55,17 +56,21 @@
import android.util.Slog;
import android.util.SparseArray;
+import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.RoSystemProperties;
import com.android.internal.util.ArrayUtils;
+import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemConfig;
import com.android.server.Watchdog;
+import com.android.server.pm.PackageManagerService;
import com.android.server.pm.PackageManagerServiceUtils;
import com.android.server.pm.PackageSetting;
+import com.android.server.pm.ProcessLoggingHandler;
import com.android.server.pm.SharedUserSetting;
import com.android.server.pm.UserManagerService;
import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
@@ -1010,10 +1015,10 @@
final PackageParser.Package systemPackage =
mPackageManagerInt.getPackage(systemPackageName);
boolean allowed = (PackageManagerServiceUtils.compareSignatures(
- bp.getSourceSignatures(), pkg.mSigningDetails.signatures)
+ bp.getSourceSignatures(), pkg.mSignatures)
== PackageManager.SIGNATURE_MATCH)
|| (PackageManagerServiceUtils.compareSignatures(
- systemPackage.mSigningDetails.signatures, pkg.mSigningDetails.signatures)
+ systemPackage.mSignatures, pkg.mSignatures)
== PackageManager.SIGNATURE_MATCH);
if (!allowed && (privilegedPermission || oemPermission)) {
if (pkg.isSystem()) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index 49601c3..32b0b26 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -34,6 +34,7 @@
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
+import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
@@ -261,13 +262,14 @@
assertBundleApproximateEquals(a.mAppMetaData, b.mAppMetaData);
assertEquals(a.mVersionName, b.mVersionName);
assertEquals(a.mSharedUserId, b.mSharedUserId);
- assertTrue(Arrays.equals(a.mSigningDetails.signatures, b.mSigningDetails.signatures));
+ assertTrue(Arrays.equals(a.mSignatures, b.mSignatures));
+ assertTrue(Arrays.equals(a.mCertificates, b.mCertificates));
assertTrue(Arrays.equals(a.mLastPackageUsageTimeInMills, b.mLastPackageUsageTimeInMills));
assertEquals(a.mExtras, b.mExtras);
assertEquals(a.mRestrictedAccountType, b.mRestrictedAccountType);
assertEquals(a.mRequiredAccountType, b.mRequiredAccountType);
assertEquals(a.mOverlayTarget, b.mOverlayTarget);
- assertEquals(a.mSigningDetails.publicKeys, b.mSigningDetails.publicKeys);
+ assertEquals(a.mSigningKeys, b.mSigningKeys);
assertEquals(a.mUpgradeKeySets, b.mUpgradeKeySets);
assertEquals(a.mKeySetMapping, b.mKeySetMapping);
assertEquals(a.cpuAbiOverride, b.cpuAbiOverride);
@@ -493,16 +495,14 @@
pkg.mAppMetaData = new Bundle();
pkg.mVersionName = "foo17";
pkg.mSharedUserId = "foo18";
- pkg.mSigningDetails =
- new PackageParser.SigningDetails(
- new Signature[] { new Signature(new byte[16]) },
- 2,
- new ArraySet<>());
+ pkg.mSignatures = new Signature[] { new Signature(new byte[16]) };
+ pkg.mCertificates = new Certificate[][] { new Certificate[] { null }};
pkg.mExtras = new Bundle();
pkg.mRestrictedAccountType = "foo19";
pkg.mRequiredAccountType = "foo20";
pkg.mOverlayTarget = "foo21";
pkg.mOverlayPriority = 100;
+ pkg.mSigningKeys = new ArraySet<>();
pkg.mUpgradeKeySets = new ArraySet<>();
pkg.mKeySetMapping = new ArrayMap<>();
pkg.cpuAbiOverride = "foo22";