diff --git a/api/current.txt b/api/current.txt index dd71724bdeacb..601a861083eb6 100644 --- a/api/current.txt +++ b/api/current.txt @@ -11020,7 +11020,7 @@ package android.content.pm { 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; @@ -11648,6 +11648,18 @@ package android.content.pm { field public static final android.os.Parcelable.Creator 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 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 627ceb7871f2b..5f9f8f1f8bf1e 100644 --- a/core/java/android/content/pm/PackageInfo.java +++ b/core/java/android/content/pm/PackageInfo.java @@ -244,7 +244,7 @@ public class PackageInfo implements Parcelable { * the first position to be the same across updates. * * Deprecated 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 class PackageInfo implements Parcelable { 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. - * - * Note: 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 @@ public class PackageInfo implements Parcelable { 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 @@ public class PackageInfo implements Parcelable { 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 @@ public class PackageInfo implements Parcelable { } } - 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 3e0db609c47ee..7159f773a4d84 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -810,21 +810,11 @@ public class PackageParser { // 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 0000000000000..ef87403596279 --- /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. + * + * + * 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. + * + */ + 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. + * + * This method should not be used unless {@link #hasMultipleSigners()} returns true, + * indicating that {@link #getSigningCertificateHistory()} cannot be used, otherwise {@link + * #getSigningCertificateHistory()} should be preferred. + * + */ + 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 CREATOR = + new Parcelable.Creator() { + @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 dc28cd179bcba..e4ce62d0a5b54 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.PackageManagerInternal; 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 @@ public class PackageManagerBackupAgent extends BackupAgent { 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 @@ public class PackageManagerBackupAgent extends BackupAgent { } } - 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 @@ public class PackageManagerBackupAgent extends BackupAgent { 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 5518374ebdbca..c39cceb538c87 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.PackageInfo; 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 @@ public class AppBackupUtils { 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 @@ public class AppBackupUtils { } 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 994d5a967298b..a3d56011272f5 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 static com.android.server.backup.BackupManagerService.TAG; 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 @@ public class FullBackupUtils { 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 d817534551f7b..96c562100a7a5 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.ApplicationInfo; 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 @@ public class BackupUtils { 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 @@ public class BackupUtils { } 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 deviceHashes = hashSignatureArray(deviceHistorySigs[0]); + // since app hasn't rotated key, we only need to check with current signers + ArrayList 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 eeaa3330dee48..8c7871ffaf962 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.PackageInfo; 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 @@ class ShortcutPackageInfo { 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 @@ class ShortcutPackageInfo { 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 d37db20f05b74..4f18be728d859 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.ApplicationInfo; 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 @@ public class AppBackupUtilsTest { 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 @@ public class AppBackupUtilsTest { 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 @@ public class AppBackupUtilsTest { 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 @@ public class AppBackupUtilsTest { 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 class AppBackupUtilsTest { 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 @@ public class AppBackupUtilsTest { 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 @@ public class AppBackupUtilsTest { 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 @@ public class AppBackupUtilsTest { 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 @@ public class AppBackupUtilsTest { 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 @@ public class AppBackupUtilsTest { 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 @@ public class AppBackupUtilsTest { 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 @@ public class AppBackupUtilsTest { 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 @@ public class AppBackupUtilsTest { 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 5f052ceb2e26b..2830a7459dc8c 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.Context; 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 @@ public class TarBackupReaderTest { 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 @@ public class TarBackupReaderTest { 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 @@ public class TarBackupReaderTest { 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 @@ public class TarBackupReaderTest { 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 @@ public class TarBackupReaderTest { 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 @@ public class TarBackupReaderTest { 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 ee83b62698509..998ffa09d2b31 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.LauncherApps.ShortcutQuery; 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.FileReader; 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 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { 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 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { 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 cd7feea08caa4..203b2caff22c7 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 @@ public class ShortcutManagerTest5 extends BaseShortcutManagerTest { 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 1ac7cb86f867a..caa1d02b47f02 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 static org.mockito.Mockito.when; 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 @@ public class BackupUtilsTest { 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 @@ public class BackupUtilsTest { 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 storedSigHashes = new ArrayList<>(); @@ -125,7 +139,7 @@ public class BackupUtilsTest { throws Exception { PackageInfo packageInfo = new PackageInfo(); packageInfo.packageName = "test"; - packageInfo.signingCertificateHistory = new Signature[0][0]; + packageInfo.signingInfo = null; packageInfo.applicationInfo = new ApplicationInfo(); ArrayList storedSigHashes = new ArrayList<>(); @@ -142,7 +156,7 @@ public class BackupUtilsTest { throws Exception { PackageInfo packageInfo = new PackageInfo(); packageInfo.packageName = "test"; - packageInfo.signingCertificateHistory = null; + packageInfo.signingInfo = null; packageInfo.applicationInfo = new ApplicationInfo(); ArrayList storedSigHashes = new ArrayList<>(); @@ -158,7 +172,7 @@ public class BackupUtilsTest { 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 @@ public class BackupUtilsTest { throws Exception { PackageInfo packageInfo = new PackageInfo(); packageInfo.packageName = "test"; - packageInfo.signingCertificateHistory = new Signature[0][0]; + packageInfo.signingInfo = null; packageInfo.applicationInfo = new ApplicationInfo(); ArrayList storedSigHashes = new ArrayList<>(); @@ -186,9 +200,13 @@ public class BackupUtilsTest { 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 storedSigHashes = new ArrayList<>(); @@ -205,9 +223,13 @@ public class BackupUtilsTest { 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 storedSigHashes = new ArrayList<>(); @@ -223,7 +245,13 @@ public class BackupUtilsTest { 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 storedSigHashes = new ArrayList<>(); @@ -240,9 +268,13 @@ public class BackupUtilsTest { 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 storedSigHashes = new ArrayList<>(); @@ -260,7 +292,13 @@ public class BackupUtilsTest { 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 @@ public class BackupUtilsTest { 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 @@ public class BackupUtilsTest { 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