Add v3 signature matching support during apex validation

Bug: 136002636
Test: atest CtsStagedInstallHostTestCases
Change-Id: I7d0edb976c4228a26dd273d1c4b3d385d5acf906
This commit is contained in:
Mohammad Samiul Islam
2019-07-29 14:38:38 +01:00
parent 5cc1472d82
commit b884124b23

View File

@@ -35,7 +35,6 @@ import android.content.pm.PackageParser.PackageParserException;
import android.content.pm.PackageParser.SigningDetails; import android.content.pm.PackageParser.SigningDetails;
import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion; import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
import android.content.pm.ParceledListSlice; import android.content.pm.ParceledListSlice;
import android.content.pm.Signature;
import android.content.rollback.IRollbackManager; import android.content.rollback.IRollbackManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
@@ -106,8 +105,19 @@ public class StagingManager {
return new ParceledListSlice<>(result); return new ParceledListSlice<>(result);
} }
private void validateApexSignature(String apexPath, String packageName) /**
* Validates the signature used to sign the container of the new apex package
*
* @param newApexPkg The new apex package that is being installed
* @param installFlags flags related to the session
* @throws PackageManagerException
*/
private void validateApexSignature(PackageInfo newApexPkg, int installFlags)
throws PackageManagerException { throws PackageManagerException {
// Get signing details of the new package
final String apexPath = newApexPkg.applicationInfo.sourceDir;
final String packageName = newApexPkg.packageName;
final SigningDetails signingDetails; final SigningDetails signingDetails;
try { try {
signingDetails = ApkSignatureVerifier.verify(apexPath, SignatureSchemeVersion.JAR); signingDetails = ApkSignatureVerifier.verify(apexPath, SignatureSchemeVersion.JAR);
@@ -116,9 +126,10 @@ public class StagingManager {
"Failed to parse APEX package " + apexPath, e); "Failed to parse APEX package " + apexPath, e);
} }
final PackageInfo packageInfo = mApexManager.getPackageInfo(packageName, // Get signing details of the existing package
final PackageInfo existingApexPkg = mApexManager.getPackageInfo(packageName,
ApexManager.MATCH_ACTIVE_PACKAGE); ApexManager.MATCH_ACTIVE_PACKAGE);
if (packageInfo == null) { if (existingApexPkg == null) {
// This should never happen, because submitSessionToApexService ensures that no new // This should never happen, because submitSessionToApexService ensures that no new
// apexes were installed. // apexes were installed.
throw new IllegalStateException("Unknown apex package " + packageName); throw new IllegalStateException("Unknown apex package " + packageName);
@@ -127,22 +138,22 @@ public class StagingManager {
final SigningDetails existingSigningDetails; final SigningDetails existingSigningDetails;
try { try {
existingSigningDetails = ApkSignatureVerifier.verify( existingSigningDetails = ApkSignatureVerifier.verify(
packageInfo.applicationInfo.sourceDir, SignatureSchemeVersion.JAR); existingApexPkg.applicationInfo.sourceDir, SignatureSchemeVersion.JAR);
} catch (PackageParserException e) { } catch (PackageParserException e) {
throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
"Failed to parse APEX package " + packageInfo.applicationInfo.sourceDir, e); "Failed to parse APEX package " + existingApexPkg.applicationInfo.sourceDir, e);
} }
// Now that we have both sets of signatures, demand that they're an exact match. // Verify signing details for upgrade
if (Signature.areExactMatch(existingSigningDetails.signatures, signingDetails.signatures)) { if (signingDetails.checkCapability(existingSigningDetails,
PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)) {
return; return;
} }
throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
"APK-container signature verification failed for package " "APK-container signature of APEX package " + packageName + " with version "
+ packageName + ". Signature of file " + newApexPkg.versionCodeMajor + " and path " + apexPath + " is not"
+ apexPath + " does not match the signature of " + " compatible with the one currently installed on device");
+ " the package already installed.");
} }
private List<PackageInfo> submitSessionToApexService( private List<PackageInfo> submitSessionToApexService(
@@ -239,8 +250,7 @@ public class StagingManager {
try { try {
final List<PackageInfo> apexPackages = submitSessionToApexService(session); final List<PackageInfo> apexPackages = submitSessionToApexService(session);
for (PackageInfo apexPackage : apexPackages) { for (PackageInfo apexPackage : apexPackages) {
validateApexSignature(apexPackage.applicationInfo.sourceDir, validateApexSignature(apexPackage, session.params.installFlags);
apexPackage.packageName);
} }
} catch (PackageManagerException e) { } catch (PackageManagerException e) {
session.setStagedSessionFailed(e.error, e.getMessage()); session.setStagedSessionFailed(e.error, e.getMessage());