Add SigningInfo class to expose package signing details.
Attempt to simplify the exposure of package signing information via
PackageInfo by creating a new class and corresponding methods for
querying a package's signing information.
Bug: 74831530
Test: PkgInstallSignatureVerificationTest
Change-Id: Idbc008b41a921f89cefb224b26f910da4d238dea
diff --git a/api/current.txt b/api/current.txt
index 423e0ae..f8d3b1d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11021,7 +11021,7 @@
field public java.lang.String sharedUserId;
field public int sharedUserLabel;
field public deprecated android.content.pm.Signature[] signatures;
- field public android.content.pm.Signature[][] signingCertificateHistory;
+ field public android.content.pm.SigningInfo signingInfo;
field public java.lang.String[] splitNames;
field public int[] splitRevisionCodes;
field public deprecated int versionCode;
@@ -11649,6 +11649,18 @@
field public static final android.os.Parcelable.Creator<android.content.pm.Signature> CREATOR;
}
+ public final class SigningInfo implements android.os.Parcelable {
+ ctor public SigningInfo();
+ ctor public SigningInfo(android.content.pm.SigningInfo);
+ method public int describeContents();
+ method public android.content.pm.Signature[] getApkContentsSigners();
+ method public android.content.pm.Signature[] getSigningCertificateHistory();
+ method public boolean hasMultipleSigners();
+ method public boolean hasPastSigningCertificates();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.content.pm.SigningInfo> CREATOR;
+ }
+
public final class VersionedPackage implements android.os.Parcelable {
ctor public VersionedPackage(java.lang.String, int);
ctor public VersionedPackage(java.lang.String, long);
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 627ceb7..5f9f8f1 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -244,7 +244,7 @@
* the first position to be the same across updates.
*
* <strong>Deprecated</strong> This has been replaced by the
- * {@link PackageInfo#signingCertificateHistory} field, which takes into
+ * {@link PackageInfo#signingInfo} field, which takes into
* account signing certificate rotation. For backwards compatibility in
* the event of signing certificate rotation, this will return the oldest
* reported signing certificate, so that an application will appear to
@@ -256,29 +256,15 @@
public Signature[] signatures;
/**
- * Array of all signatures arrays read from the package file, potentially
+ * Signing information read from the package file, potentially
* including past signing certificates no longer used after signing
- * certificate rotation. Though signing certificate rotation is only
- * available for apps with a single signing certificate, this provides an
- * array of arrays so that packages signed with multiple signing
- * certificates can still return all signers. This is only filled in if
+ * certificate rotation. This is only filled in if
* the flag {@link PackageManager#GET_SIGNING_CERTIFICATES} was set.
*
- * A package must be singed with at least one certificate, which is at
- * position zero in the array. An application may be signed by multiple
- * certificates, which would be in the array at position zero in an
- * indeterminate order. A package may also have a history of certificates
- * due to signing certificate rotation. In this case, the array will be
- * populated by a series of single-entry arrays corresponding to a signing
- * certificate of the package.
- *
- * <strong>Note:</strong> Signature ordering is not guaranteed to be
- * stable which means that a package signed with certificates A and B is
- * equivalent to being signed with certificates B and A. This means that
- * in case multiple signatures are reported you cannot assume the one at
- * the first position will be the same across updates.
+ * Use this field instead of the deprecated {@code signatures} field.
+ * See {@link SigningInfo} for more information on its contents.
*/
- public Signature[][] signingCertificateHistory;
+ public SigningInfo signingInfo;
/**
* Application specified preferred configuration
@@ -476,17 +462,11 @@
dest.writeBoolean(mOverlayIsStatic);
dest.writeInt(compileSdkVersion);
dest.writeString(compileSdkVersionCodename);
- writeSigningCertificateHistoryToParcel(dest, parcelableFlags);
- }
-
- private void writeSigningCertificateHistoryToParcel(Parcel dest, int parcelableFlags) {
- if (signingCertificateHistory != null) {
- dest.writeInt(signingCertificateHistory.length);
- for (int i = 0; i < signingCertificateHistory.length; i++) {
- dest.writeTypedArray(signingCertificateHistory[i], parcelableFlags);
- }
+ if (signingInfo != null) {
+ dest.writeInt(1);
+ signingInfo.writeToParcel(dest, parcelableFlags);
} else {
- dest.writeInt(-1);
+ dest.writeInt(0);
}
}
@@ -544,7 +524,10 @@
mOverlayIsStatic = source.readBoolean();
compileSdkVersion = source.readInt();
compileSdkVersionCodename = source.readString();
- readSigningCertificateHistoryFromParcel(source);
+ int hasSigningInfo = source.readInt();
+ if (hasSigningInfo != 0) {
+ signingInfo = SigningInfo.CREATOR.createFromParcel(source);
+ }
// The component lists were flattened with the redundant ApplicationInfo
// instances omitted. Distribute the canonical one here as appropriate.
@@ -556,16 +539,6 @@
}
}
- private void readSigningCertificateHistoryFromParcel(Parcel source) {
- int len = source.readInt();
- if (len != -1) {
- signingCertificateHistory = new Signature[len][];
- for (int i = 0; i < len; i++) {
- signingCertificateHistory[i] = source.createTypedArray(Signature.CREATOR);
- }
- }
- }
-
private void propagateApplicationInfo(ApplicationInfo appInfo, ComponentInfo[] components) {
if (components != null) {
for (ComponentInfo ci : components) {
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 3e0db60..7159f77 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -810,21 +810,11 @@
// replacement for GET_SIGNATURES
if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) {
- if (p.mSigningDetails.hasPastSigningCertificates()) {
- // Package has included signing certificate rotation information. Convert each
- // entry to an array
- int numberOfSigs = p.mSigningDetails.pastSigningCertificates.length;
- pi.signingCertificateHistory = new Signature[numberOfSigs][];
- for (int i = 0; i < numberOfSigs; i++) {
- pi.signingCertificateHistory[i] =
- new Signature[] { p.mSigningDetails.pastSigningCertificates[i] };
- }
- } else if (p.mSigningDetails.hasSignatures()) {
- // otherwise keep old behavior
- int numberOfSigs = p.mSigningDetails.signatures.length;
- pi.signingCertificateHistory = new Signature[1][numberOfSigs];
- System.arraycopy(p.mSigningDetails.signatures, 0,
- pi.signingCertificateHistory[0], 0, numberOfSigs);
+ if (p.mSigningDetails != SigningDetails.UNKNOWN) {
+ // only return a valid SigningInfo if there is signing information to report
+ pi.signingInfo = new SigningInfo(p.mSigningDetails);
+ } else {
+ pi.signingInfo = null;
}
}
return pi;
diff --git a/core/java/android/content/pm/SigningInfo.java b/core/java/android/content/pm/SigningInfo.java
new file mode 100644
index 0000000..ef87403
--- /dev/null
+++ b/core/java/android/content/pm/SigningInfo.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Information pertaining to the signing certificates used to sign a package.
+ */
+public final class SigningInfo implements Parcelable {
+
+ @NonNull
+ private final PackageParser.SigningDetails mSigningDetails;
+
+ public SigningInfo() {
+ mSigningDetails = PackageParser.SigningDetails.UNKNOWN;
+ }
+
+ /**
+ * @hide only packagemanager should be populating this
+ */
+ public SigningInfo(PackageParser.SigningDetails signingDetails) {
+ mSigningDetails = new PackageParser.SigningDetails(signingDetails);
+ }
+
+ public SigningInfo(SigningInfo orig) {
+ mSigningDetails = new PackageParser.SigningDetails(orig.mSigningDetails);
+ }
+
+ private SigningInfo(Parcel source) {
+ mSigningDetails = PackageParser.SigningDetails.CREATOR.createFromParcel(source);
+ }
+
+ /**
+ * Although relatively uncommon, packages may be signed by more than one signer, in which case
+ * their identity is viewed as being the set of all signers, not just any one.
+ */
+ public boolean hasMultipleSigners() {
+ return mSigningDetails.signatures != null && mSigningDetails.signatures.length > 1;
+ }
+
+ /**
+ * APK Signature Scheme v3 enables packages to provide a proof-of-rotation record that the
+ * platform verifies, and uses, to allow the use of new signing certificates. This is only
+ * available to packages that are not signed by multiple signers. In the event of a change to a
+ * new signing certificate, the package's past signing certificates are presented as well. Any
+ * check of a package's signing certificate should also include a search through its entire
+ * signing history, since it could change to a new signing certificate at any time.
+ */
+ public boolean hasPastSigningCertificates() {
+ return mSigningDetails.signatures != null
+ && mSigningDetails.pastSigningCertificates != null;
+ }
+
+ /**
+ * Returns the signing certificates this package has proven it is authorized to use. This
+ * includes both the signing certificate associated with the signer of the package and the past
+ * signing certificates it included as its proof of signing certificate rotation. This method
+ * is the preferred replacement for the {@code GET_SIGNATURES} flag used with {@link
+ * PackageManager#getPackageInfo(String, int)}. When determining if a package is signed by a
+ * desired certificate, the returned array should be checked to determine if it is one of the
+ * entries.
+ *
+ * <note>
+ * This method returns null if the package is signed by multiple signing certificates, as
+ * opposed to being signed by one current signer and also providing the history of past
+ * signing certificates. {@link #hasMultipleSigners()} may be used to determine if this
+ * package is signed by multiple signers. Packages which are signed by multiple signers
+ * cannot change their signing certificates and their {@code Signature} array should be
+ * checked to make sure that every entry matches the looked-for signing certificates.
+ * </note>
+ */
+ public Signature[] getSigningCertificateHistory() {
+ if (hasMultipleSigners()) {
+ return null;
+ } else if (!hasPastSigningCertificates()) {
+
+ // this package is only signed by one signer with no history, return it
+ return mSigningDetails.signatures;
+ } else {
+
+ // this package has provided proof of past signing certificates, include them
+ return mSigningDetails.pastSigningCertificates;
+ }
+ }
+
+ /**
+ * Returns the signing certificates used to sign the APK contents of this application. Not
+ * including any past signing certificates the package proved it is authorized to use.
+ * <note>
+ * This method should not be used unless {@link #hasMultipleSigners()} returns true,
+ * indicating that {@link #getSigningCertificateHistory()} cannot be used, otherwise {@link
+ * #getSigningCertificateHistory()} should be preferred.
+ * </note>
+ */
+ public Signature[] getApkContentsSigners() {
+ return mSigningDetails.signatures;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int parcelableFlags) {
+ mSigningDetails.writeToParcel(dest, parcelableFlags);
+ }
+
+ public static final Parcelable.Creator<SigningInfo> CREATOR =
+ new Parcelable.Creator<SigningInfo>() {
+ @Override
+ public SigningInfo createFromParcel(Parcel source) {
+ return new SigningInfo(source);
+ }
+
+ @Override
+ public SigningInfo[] newArray(int size) {
+ return new SigningInfo[size];
+ }
+ };
+}
diff --git a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
index dc28cd1..e4ce62d 100644
--- a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
+++ b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
@@ -27,6 +27,7 @@
import android.content.pm.ResolveInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
+import android.content.pm.SigningInfo;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.util.Slog;
@@ -240,12 +241,13 @@
PackageManager.GET_SIGNING_CERTIFICATES);
homeInstaller = mPackageManager.getInstallerPackageName(home.getPackageName());
homeVersion = homeInfo.getLongVersionCode();
- Signature[][] signingHistory = homeInfo.signingCertificateHistory;
- if (signingHistory == null || signingHistory.length == 0) {
- Slog.e(TAG, "Home app has no signing history");
+ SigningInfo signingInfo = homeInfo.signingInfo;
+ if (signingInfo == null) {
+ Slog.e(TAG, "Home app has no signing information");
} else {
// retrieve the newest sigs to back up
- Signature[] homeInfoSignatures = signingHistory[signingHistory.length - 1];
+ // TODO (b/73988180) use entire signing history in case of rollbacks
+ Signature[] homeInfoSignatures = signingInfo.getApkContentsSigners();
homeSigHashes = BackupUtils.hashSignatureArray(homeInfoSignatures);
}
} catch (NameNotFoundException e) {
@@ -334,8 +336,8 @@
}
}
- Signature[][] signingHistory = info.signingCertificateHistory;
- if (signingHistory == null || signingHistory.length == 0) {
+ SigningInfo signingInfo = info.signingInfo;
+ if (signingInfo == null) {
Slog.w(TAG, "Not backing up package " + packName
+ " since it appears to have no signatures.");
continue;
@@ -358,7 +360,7 @@
outputBufferStream.writeInt(info.versionCode);
}
// retrieve the newest sigs to back up
- Signature[] infoSignatures = signingHistory[signingHistory.length - 1];
+ Signature[] infoSignatures = signingInfo.getApkContentsSigners();
writeSignatureHashArray(outputBufferStream,
BackupUtils.hashSignatureArray(infoSignatures));
diff --git a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
index 5518374..c39cceb 100644
--- a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
@@ -27,6 +27,7 @@
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.Signature;
+import android.content.pm.SigningInfo;
import android.os.Process;
import android.util.Slog;
@@ -203,15 +204,16 @@
return false;
}
- Signature[][] deviceHistorySigs = target.signingCertificateHistory;
- if (ArrayUtils.isEmpty(deviceHistorySigs)) {
- Slog.w(TAG, "signingCertificateHistory is empty, app was either unsigned or the flag" +
+ SigningInfo signingInfo = target.signingInfo;
+ if (signingInfo == null) {
+ Slog.w(TAG, "signingInfo is empty, app was either unsigned or the flag" +
" PackageManager#GET_SIGNING_CERTIFICATES was not specified");
return false;
}
if (DEBUG) {
- Slog.v(TAG, "signaturesMatch(): stored=" + storedSigs + " device=" + deviceHistorySigs);
+ Slog.v(TAG, "signaturesMatch(): stored=" + storedSigs + " device="
+ + signingInfo.getApkContentsSigners());
}
final int nStored = storedSigs.length;
@@ -225,8 +227,8 @@
} else {
// the app couldn't have rotated keys, since it was signed with multiple sigs - do
// a check to see if we find a match for all stored sigs
- // since app hasn't rotated key, we only need to check with deviceHistorySigs[0]
- Signature[] deviceSigs = deviceHistorySigs[0];
+ // since app hasn't rotated key, we only need to check with its current signers
+ Signature[] deviceSigs = signingInfo.getApkContentsSigners();
int nDevice = deviceSigs.length;
// ensure that each stored sig matches an on-device sig
diff --git a/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java b/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
index 994d5a9..a3d5601 100644
--- a/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
@@ -22,6 +22,7 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
+import android.content.pm.SigningInfo;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.util.Slog;
@@ -106,12 +107,13 @@
printer.println(withApk ? "1" : "0");
// write the signature block
- Signature[][] signingHistory = pkg.signingCertificateHistory;
- if (signingHistory == null) {
+ SigningInfo signingInfo = pkg.signingInfo;
+ if (signingInfo == null) {
printer.println("0");
} else {
// retrieve the newest sigs to write
- Signature[] signatures = signingHistory[signingHistory.length - 1];
+ // TODO (b/73988180) use entire signing history in case of rollbacks
+ Signature[] signatures = signingInfo.getApkContentsSigners();
printer.println(Integer.toString(signatures.length));
for (Signature sig : signatures) {
printer.println(sig.toCharsString());
diff --git a/services/core/java/com/android/server/backup/BackupUtils.java b/services/core/java/com/android/server/backup/BackupUtils.java
index d817534..96c5621 100644
--- a/services/core/java/com/android/server/backup/BackupUtils.java
+++ b/services/core/java/com/android/server/backup/BackupUtils.java
@@ -20,6 +20,7 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManagerInternal;
import android.content.pm.Signature;
+import android.content.pm.SigningInfo;
import android.util.Slog;
import com.android.internal.util.ArrayUtils;
@@ -55,16 +56,16 @@
return false;
}
- Signature[][] deviceHistorySigs = target.signingCertificateHistory;
- if (ArrayUtils.isEmpty(deviceHistorySigs)) {
- Slog.w(TAG, "signingCertificateHistory is empty, app was either unsigned or the flag" +
+ SigningInfo signingInfo = target.signingInfo;
+ if (signingInfo == null) {
+ Slog.w(TAG, "signingInfo is empty, app was either unsigned or the flag" +
" PackageManager#GET_SIGNING_CERTIFICATES was not specified");
return false;
}
if (DEBUG) {
Slog.v(TAG, "signaturesMatch(): stored=" + storedSigHashes
- + " device=" + deviceHistorySigs);
+ + " device=" + signingInfo.getApkContentsSigners());
}
final int nStored = storedSigHashes.size();
@@ -78,8 +79,9 @@
} else {
// the app couldn't have rotated keys, since it was signed with multiple sigs - do
// a check to see if we find a match for all stored sigs
- // since app hasn't rotated key, we only need to check with deviceHistorySigs[0]
- ArrayList<byte[]> deviceHashes = hashSignatureArray(deviceHistorySigs[0]);
+ // since app hasn't rotated key, we only need to check with current signers
+ ArrayList<byte[]> deviceHashes =
+ hashSignatureArray(signingInfo.getApkContentsSigners());
int nDevice = deviceHashes.size();
// ensure that each stored sig matches an on-device sig
for (int i = 0; i < nStored; i++) {
diff --git a/services/core/java/com/android/server/pm/ShortcutPackageInfo.java b/services/core/java/com/android/server/pm/ShortcutPackageInfo.java
index eeaa333..8c7871f 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackageInfo.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackageInfo.java
@@ -21,6 +21,7 @@
import android.content.pm.PackageManagerInternal;
import android.content.pm.ShortcutInfo;
import android.content.pm.Signature;
+import android.content.pm.SigningInfo;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -164,12 +165,13 @@
ShortcutService s, String packageName, @UserIdInt int packageUserId) {
final PackageInfo pi = s.getPackageInfoWithSignatures(packageName, packageUserId);
// retrieve the newest sigs
- Signature[][] signingHistory = pi.signingCertificateHistory;
- if (signingHistory == null || signingHistory.length == 0) {
+ SigningInfo signingInfo = pi.signingInfo;
+ if (signingInfo == null) {
Slog.e(TAG, "Can't get signatures: package=" + packageName);
return null;
}
- Signature[] signatures = signingHistory[signingHistory.length - 1];
+ // TODO (b/73988180) use entire signing history in case of rollbacks
+ Signature[] signatures = signingInfo.getApkContentsSigners();
final ShortcutPackageInfo ret = new ShortcutPackageInfo(pi.getLongVersionCode(),
pi.lastUpdateTime, BackupUtils.hashSignatureArray(signatures), /* shadow=*/ false);
@@ -192,13 +194,14 @@
return;
}
// retrieve the newest sigs
- Signature[][] signingHistory = pi.signingCertificateHistory;
- if (signingHistory == null || signingHistory.length == 0) {
+ SigningInfo signingInfo = pi.signingInfo;
+ if (signingInfo == null) {
Slog.w(TAG, "Not refreshing signature for " + pkg.getPackageName()
- + " since it appears to have no signature history.");
+ + " since it appears to have no signing info.");
return;
}
- Signature[] signatures = signingHistory[signingHistory.length - 1];
+ // TODO (b/73988180) use entire signing history in case of rollbacks
+ Signature[] signatures = signingInfo.getApkContentsSigners();
mSigHashes = BackupUtils.hashSignatureArray(signatures);
}
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
index d37db20..4f18be7 100644
--- a/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
@@ -26,7 +26,9 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
+import android.content.pm.PackageParser;
import android.content.pm.Signature;
+import android.content.pm.SigningInfo;
import android.os.Process;
import android.platform.test.annotations.Presubmit;
import android.support.test.filters.SmallTest;
@@ -395,7 +397,13 @@
throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_1},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.applicationInfo = new ApplicationInfo();
boolean result = AppBackupUtils.signaturesMatch(null, packageInfo,
@@ -409,7 +417,13 @@
throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_1},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.applicationInfo = new ApplicationInfo();
boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo,
@@ -425,7 +439,7 @@
throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[0][0];
+ packageInfo.signingInfo = null;
packageInfo.applicationInfo = new ApplicationInfo();
boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, packageInfo,
@@ -440,7 +454,7 @@
throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = null;
+ packageInfo.signingInfo = null;
packageInfo.applicationInfo = new ApplicationInfo();
boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, packageInfo,
@@ -453,7 +467,7 @@
public void signaturesMatch_disallowsUnsignedApps_bothSignaturesNull_returnsFalse()
throws Exception {
PackageInfo packageInfo = new PackageInfo();
- packageInfo.signingCertificateHistory = null;
+ packageInfo.signingInfo = null;
packageInfo.applicationInfo = new ApplicationInfo();
boolean result = AppBackupUtils.signaturesMatch(null, packageInfo,
@@ -467,7 +481,7 @@
throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[0][0];
+ packageInfo.signingInfo = null;
packageInfo.applicationInfo = new ApplicationInfo();
boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo,
@@ -484,9 +498,13 @@
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {
- {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}
- };
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.applicationInfo = new ApplicationInfo();
boolean result = AppBackupUtils.signaturesMatch(
@@ -503,9 +521,13 @@
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {
- {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}
- };
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.applicationInfo = new ApplicationInfo();
boolean result = AppBackupUtils.signaturesMatch(
@@ -522,9 +544,13 @@
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {
- {signature1Copy, signature2Copy}
- };
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {signature1Copy, signature2Copy},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.applicationInfo = new ApplicationInfo();
boolean result = AppBackupUtils.signaturesMatch(
@@ -541,9 +567,13 @@
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {
- {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}
- };
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.applicationInfo = new ApplicationInfo();
boolean result = AppBackupUtils.signaturesMatch(
@@ -560,7 +590,13 @@
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_1},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.applicationInfo = new ApplicationInfo();
doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(signature1Copy,
@@ -579,7 +615,13 @@
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}, {SIGNATURE_2}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_2},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ new Signature[] {SIGNATURE_1, SIGNATURE_2},
+ new int[] {0, 0}));
packageInfo.applicationInfo = new ApplicationInfo();
// we know signature1Copy is in history, and we want to assume it has
@@ -601,7 +643,13 @@
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}, {SIGNATURE_2}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_2},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ new Signature[] {SIGNATURE_1, SIGNATURE_2},
+ new int[] {0, 0}));
packageInfo.applicationInfo = new ApplicationInfo();
// we know signature1Copy is in history, but we want to assume it does not have
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
index 5f052ce..2830a74 100644
--- a/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
@@ -41,7 +41,9 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManagerInternal;
+import android.content.pm.PackageParser;
import android.content.pm.Signature;
+import android.content.pm.SigningInfo;
import android.os.Bundle;
import android.os.Process;
import android.platform.test.annotations.Presubmit;
@@ -371,7 +373,13 @@
packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
packageInfo.applicationInfo.backupAgentName = null;
- packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_2}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {FAKE_SIGNATURE_2},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
PackageManagerStub.sPackageInfo = packageInfo;
RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
@@ -402,7 +410,13 @@
ApplicationInfo.FLAG_ALLOW_BACKUP | ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
packageInfo.applicationInfo.uid = Process.SYSTEM_UID;
packageInfo.applicationInfo.backupAgentName = "backup.agent";
- packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_1}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {FAKE_SIGNATURE_1},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
PackageManagerStub.sPackageInfo = packageInfo;
doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
@@ -434,7 +448,13 @@
ApplicationInfo.FLAG_ALLOW_BACKUP | ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
packageInfo.applicationInfo.backupAgentName = null;
- packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_1}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {FAKE_SIGNATURE_1},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
PackageManagerStub.sPackageInfo = packageInfo;
doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
@@ -469,7 +489,13 @@
packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
packageInfo.applicationInfo.backupAgentName = null;
- packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_1}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {FAKE_SIGNATURE_1},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.versionCode = 2;
PackageManagerStub.sPackageInfo = packageInfo;
@@ -507,7 +533,13 @@
packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
packageInfo.applicationInfo.backupAgentName = null;
- packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_1}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {FAKE_SIGNATURE_1},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.versionCode = 1;
PackageManagerStub.sPackageInfo = packageInfo;
@@ -541,7 +573,13 @@
packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
packageInfo.applicationInfo.backupAgentName = null;
- packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_1}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {FAKE_SIGNATURE_1},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.versionCode = 1;
PackageManagerStub.sPackageInfo = packageInfo;
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index ee83b62..998ffa0 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -58,11 +58,13 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
+import android.content.pm.PackageParser;
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.content.pm.ShortcutServiceInternal;
import android.content.pm.Signature;
+import android.content.pm.SigningInfo;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
@@ -102,6 +104,8 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -1039,8 +1043,13 @@
pi.versionCode = version;
pi.applicationInfo.setVersionCode(version);
pi.signatures = null;
- pi.signingCertificateHistory = new Signature[][] {genSignatures(signatures)};
-
+ pi.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ genSignatures(signatures),
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
return pi;
}
@@ -1128,7 +1137,7 @@
if (getSignatures) {
ret.signatures = null;
- ret.signingCertificateHistory = pi.signingCertificateHistory;
+ ret.signingInfo = pi.signingInfo;
}
return ret;
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest5.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest5.java
index cd7feea..203b2ca 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest5.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest5.java
@@ -76,13 +76,13 @@
mMyPackage, mMyUserId, /*signature*/ false);
assertEquals(mMyPackage, pi.packageName);
assertNull(pi.signatures);
- assertNull(pi.signingCertificateHistory);
+ assertNull(pi.signingInfo);
pi = mShortcutService.getPackageInfo(
mMyPackage, mMyUserId, /*signature*/ true);
assertEquals(mMyPackage, pi.packageName);
assertNull(pi.signatures);
- assertNotNull(pi.signingCertificateHistory);
+ assertNotNull(pi.signingInfo);
pi = mShortcutService.getPackageInfo(
"no.such.package", mMyUserId, /*signature*/ true);
diff --git a/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java
index 1ac7cb8..caa1d02 100644
--- a/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java
@@ -27,8 +27,10 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManagerInternal;
+import android.content.pm.PackageParser;
import android.content.pm.PackageParser.Package;
import android.content.pm.Signature;
+import android.content.pm.SigningInfo;
import android.test.MoreAsserts;
import android.platform.test.annotations.Presubmit;
import android.support.test.filters.SmallTest;
@@ -94,7 +96,13 @@
throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_1},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.applicationInfo = new ApplicationInfo();
boolean result = BackupUtils.signaturesMatch(null, packageInfo,
@@ -108,7 +116,13 @@
throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_1},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.applicationInfo = new ApplicationInfo();
ArrayList<byte[]> storedSigHashes = new ArrayList<>();
@@ -125,7 +139,7 @@
throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[0][0];
+ packageInfo.signingInfo = null;
packageInfo.applicationInfo = new ApplicationInfo();
ArrayList<byte[]> storedSigHashes = new ArrayList<>();
@@ -142,7 +156,7 @@
throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = null;
+ packageInfo.signingInfo = null;
packageInfo.applicationInfo = new ApplicationInfo();
ArrayList<byte[]> storedSigHashes = new ArrayList<>();
@@ -158,7 +172,7 @@
throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = null;
+ packageInfo.signingInfo = null;
packageInfo.applicationInfo = new ApplicationInfo();
boolean result = BackupUtils.signaturesMatch(null, packageInfo,
@@ -172,7 +186,7 @@
throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[0][0];
+ packageInfo.signingInfo = null;
packageInfo.applicationInfo = new ApplicationInfo();
ArrayList<byte[]> storedSigHashes = new ArrayList<>();
@@ -186,9 +200,13 @@
public void signaturesMatch_equalSignatures_returnsTrue() throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {
- {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}
- };
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.applicationInfo = new ApplicationInfo();
ArrayList<byte[]> storedSigHashes = new ArrayList<>();
@@ -205,9 +223,13 @@
public void signaturesMatch_extraSignatureInTarget_returnsTrue() throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {
- {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}
- };
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.applicationInfo = new ApplicationInfo();
ArrayList<byte[]> storedSigHashes = new ArrayList<>();
@@ -223,7 +245,13 @@
public void signaturesMatch_extraSignatureInStored_returnsFalse() throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1, SIGNATURE_2}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_1, SIGNATURE_2},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.applicationInfo = new ApplicationInfo();
ArrayList<byte[]> storedSigHashes = new ArrayList<>();
@@ -240,9 +268,13 @@
public void signaturesMatch_oneNonMatchingSignature_returnsFalse() throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {
- {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}
- };
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.applicationInfo = new ApplicationInfo();
ArrayList<byte[]> storedSigHashes = new ArrayList<>();
@@ -260,7 +292,13 @@
throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_1},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.applicationInfo = new ApplicationInfo();
doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(SIGNATURE_HASH_1,
@@ -279,7 +317,13 @@
throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}, {SIGNATURE_2}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_1, SIGNATURE_2},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.applicationInfo = new ApplicationInfo();
// we know SIGNATURE_1 is in history, and we want to assume it has
@@ -301,7 +345,13 @@
throws Exception {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test";
- packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}, {SIGNATURE_2}};
+ packageInfo.signingInfo = new SigningInfo(
+ new PackageParser.SigningDetails(
+ new Signature[] {SIGNATURE_1, SIGNATURE_2},
+ PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
+ null,
+ null,
+ null));
packageInfo.applicationInfo = new ApplicationInfo();
// we know SIGNATURE_1 is in history, but we want to assume it does not have