Merge "Update PM#checkSignatures by uid to support pre-key rotation behavior" into rvc-dev

This commit is contained in:
Michael Groover
2020-05-07 21:36:41 +00:00
committed by Android (Google) Code Review
2 changed files with 50 additions and 29 deletions

View File

@@ -2548,9 +2548,18 @@ public class PackageManagerTests extends AndroidTestCase {
} else {
installFromRawResource(apk2Name, apk2, 0, false, false, -1,
PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
int match = mContext.getPackageManager().checkSignatures(pkg1.getPackageName(),
pkg2.getPackageName());
assertEquals(expMatchResult, match);
// TODO: All checkSignatures tests should return the same result regardless of
// querying by package name or uid; however if there are any edge cases where
// individual packages within a shareduid are compared with signatures that do not
// match the full lineage of the shareduid this method should be overloaded to
// accept the expected response for the uid query.
PackageManager pm = getPm();
int matchByName = pm.checkSignatures(pkg1.getPackageName(), pkg2.getPackageName());
int pkg1Uid = pm.getApplicationInfo(pkg1.getPackageName(), 0).uid;
int pkg2Uid = pm.getApplicationInfo(pkg2.getPackageName(), 0).uid;
int matchByUid = pm.checkSignatures(pkg1Uid, pkg2Uid);
assertEquals(expMatchResult, matchByName);
assertEquals(expMatchResult, matchByUid);
}
} finally {
if (cleanUp) {

View File

@@ -5966,25 +5966,7 @@ public class PackageManagerService extends IPackageManager.Stub
|| shouldFilterApplicationLocked(ps2, callingUid, callingUserId)) {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
SigningDetails p1SigningDetails = p1.getSigningDetails();
SigningDetails p2SigningDetails = p2.getSigningDetails();
int result = compareSignatures(p1SigningDetails.signatures,
p2SigningDetails.signatures);
// To support backwards compatibility with clients of this API expecting pre-key
// rotation results if either of the packages has a signing lineage the oldest signer
// in the lineage is used for signature verification.
if (result != PackageManager.SIGNATURE_MATCH && (
p1SigningDetails.hasPastSigningCertificates()
|| p2SigningDetails.hasPastSigningCertificates())) {
Signature[] p1Signatures = p1SigningDetails.hasPastSigningCertificates()
? new Signature[]{p1SigningDetails.pastSigningCertificates[0]}
: p1SigningDetails.signatures;
Signature[] p2Signatures = p2SigningDetails.hasPastSigningCertificates()
? new Signature[]{p2SigningDetails.pastSigningCertificates[0]}
: p2SigningDetails.signatures;
result = compareSignatures(p1Signatures, p2Signatures);
}
return result;
return checkSignaturesInternal(p1.getSigningDetails(), p2.getSigningDetails());
}
}
@@ -5998,21 +5980,21 @@ public class PackageManagerService extends IPackageManager.Stub
final int appId2 = UserHandle.getAppId(uid2);
// reader
synchronized (mLock) {
Signature[] s1;
Signature[] s2;
SigningDetails p1SigningDetails;
SigningDetails p2SigningDetails;
Object obj = mSettings.getSettingLPr(appId1);
if (obj != null) {
if (obj instanceof SharedUserSetting) {
if (isCallerInstantApp) {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
s1 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
p1SigningDetails = ((SharedUserSetting) obj).signatures.mSigningDetails;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
s1 = ps.signatures.mSigningDetails.signatures;
p1SigningDetails = ps.signatures.mSigningDetails;
} else {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
@@ -6025,23 +6007,53 @@ public class PackageManagerService extends IPackageManager.Stub
if (isCallerInstantApp) {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
s2 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
p2SigningDetails = ((SharedUserSetting) obj).signatures.mSigningDetails;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
s2 = ps.signatures.mSigningDetails.signatures;
p2SigningDetails = ps.signatures.mSigningDetails;
} else {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
} else {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
return compareSignatures(s1, s2);
return checkSignaturesInternal(p1SigningDetails, p2SigningDetails);
}
}
private int checkSignaturesInternal(SigningDetails p1SigningDetails,
SigningDetails p2SigningDetails) {
if (p1SigningDetails == null) {
return p2SigningDetails == null
? PackageManager.SIGNATURE_NEITHER_SIGNED
: PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
}
if (p2SigningDetails == null) {
return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
}
int result = compareSignatures(p1SigningDetails.signatures, p2SigningDetails.signatures);
if (result == PackageManager.SIGNATURE_MATCH) {
return result;
}
// To support backwards compatibility with clients of this API expecting pre-key
// rotation results if either of the packages has a signing lineage the oldest signer
// in the lineage is used for signature verification.
if (p1SigningDetails.hasPastSigningCertificates()
|| p2SigningDetails.hasPastSigningCertificates()) {
Signature[] p1Signatures = p1SigningDetails.hasPastSigningCertificates()
? new Signature[]{p1SigningDetails.pastSigningCertificates[0]}
: p1SigningDetails.signatures;
Signature[] p2Signatures = p2SigningDetails.hasPastSigningCertificates()
? new Signature[]{p2SigningDetails.pastSigningCertificates[0]}
: p2SigningDetails.signatures;
result = compareSignatures(p1Signatures, p2Signatures);
}
return result;
}
@Override
public boolean hasSigningCertificate(
String packageName, byte[] certificate, @PackageManager.CertificateInputType int type) {