Merge "Add SigningInfo class to expose package signing details." into pi-dev

am: 960a0c6c57

Change-Id: I512db4ad4f81da5cdd61bb2de5f3ed0e719379c1
This commit is contained in:
Daniel Cashman
2018-04-11 12:40:33 -07:00
committed by android-build-merger
14 changed files with 407 additions and 137 deletions

View File

@@ -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<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);

View File

@@ -244,7 +244,7 @@ public class PackageInfo implements Parcelable {
* 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 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.
*
* <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 @@ 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) {

View File

@@ -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;

View File

@@ -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];
}
};
}

View File

@@ -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));

View File

@@ -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

View File

@@ -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());

View File

@@ -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<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++) {

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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<byte[]> 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<byte[]> 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<byte[]> 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<byte[]> 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<byte[]> 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<byte[]> 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<byte[]> 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<byte[]> 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