From ef4bf730f52a050d0902eb2a927aa65a7fd4537d Mon Sep 17 00:00:00 2001 From: Mohammad Samiul Islam Date: Mon, 29 Jul 2019 14:38:38 +0100 Subject: [PATCH] Add v3 signature matching support during apex validation Bug: 136002636 Test: atest CtsStagedInstallHostTestCases Change-Id: I7d0edb976c4228a26dd273d1c4b3d385d5acf906 Merged-In: I7d0edb976c4228a26dd273d1c4b3d385d5acf906 --- .../com/android/server/pm/StagingManager.java | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 6d3424cf39429..dd1eb8355de12 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -35,7 +35,6 @@ import android.content.pm.PackageParser.PackageParserException; import android.content.pm.PackageParser.SigningDetails; import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion; import android.content.pm.ParceledListSlice; -import android.content.pm.Signature; import android.content.rollback.IRollbackManager; import android.os.Bundle; import android.os.Handler; @@ -106,8 +105,19 @@ public class StagingManager { 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 { + // Get signing details of the new package + final String apexPath = newApexPkg.applicationInfo.sourceDir; + final String packageName = newApexPkg.packageName; + final SigningDetails signingDetails; try { signingDetails = ApkSignatureVerifier.verify(apexPath, SignatureSchemeVersion.JAR); @@ -116,9 +126,10 @@ public class StagingManager { "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); - if (packageInfo == null) { + if (existingApexPkg == null) { // This should never happen, because submitSessionToApexService ensures that no new // apexes were installed. throw new IllegalStateException("Unknown apex package " + packageName); @@ -127,22 +138,22 @@ public class StagingManager { final SigningDetails existingSigningDetails; try { existingSigningDetails = ApkSignatureVerifier.verify( - packageInfo.applicationInfo.sourceDir, SignatureSchemeVersion.JAR); + existingApexPkg.applicationInfo.sourceDir, SignatureSchemeVersion.JAR); } catch (PackageParserException e) { 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. - if (Signature.areExactMatch(existingSigningDetails.signatures, signingDetails.signatures)) { + // Verify signing details for upgrade + if (signingDetails.checkCapability(existingSigningDetails, + PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)) { return; } throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, - "APK-container signature verification failed for package " - + packageName + ". Signature of file " - + apexPath + " does not match the signature of " - + " the package already installed."); + "APK-container signature of APEX package " + packageName + " with version " + + newApexPkg.versionCodeMajor + " and path " + apexPath + " is not" + + " compatible with the one currently installed on device"); } private List submitSessionToApexService( @@ -239,8 +250,7 @@ public class StagingManager { try { final List apexPackages = submitSessionToApexService(session); for (PackageInfo apexPackage : apexPackages) { - validateApexSignature(apexPackage.applicationInfo.sourceDir, - apexPackage.packageName); + validateApexSignature(apexPackage, session.params.installFlags); } } catch (PackageManagerException e) { session.setStagedSessionFailed(e.error, e.getMessage());