summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Michael Groover <mpgroover@google.com> 2020-01-24 19:00:01 -0800
committer Michael Groover <mpgroover@google.com> 2020-01-28 14:31:29 -0800
commit33df7c415a42ef495771228c8895b0ba7961382c (patch)
tree961e75b2c424fbfdc249cc52957cd4f11a42fbb7
parent0f681fb3fb2e85a39ac434e4728d0255e14f1d50 (diff)
Require signature scheme V2+ for target SDK R+
With the recent sha-1 news, and since minSdk less than 18 for RSA and minSdk less than 21 for DSA require sha-1, APK signature verification will now require a minimum of a V2 signature for apps targeting R+. Bug: 148313868 Test: atest PkgInstallSignatureVerificationTest Change-Id: I8f518102a0b7cef190cbca59d140d380ae41c326
-rw-r--r--core/java/android/content/pm/PackageParser.java3
-rw-r--r--core/java/android/content/pm/parsing/ApkLiteParseUtils.java6
-rw-r--r--core/java/android/content/pm/parsing/ApkParseUtils.java12
-rw-r--r--core/java/android/util/apk/ApkSignatureVerifier.java12
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java15
-rw-r--r--services/core/java/com/android/server/pm/StagingManager.java4
6 files changed, 42 insertions, 10 deletions
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index fd4c26569873..45f5ab69ff93 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1582,7 +1582,8 @@ public class PackageParser {
throws PackageParserException {
final String apkPath = apkFile.getAbsolutePath();
- int minSignatureScheme = SigningDetails.SignatureSchemeVersion.JAR;
+ int minSignatureScheme = ApkSignatureVerifier.getMinimumSignatureSchemeVersionForTargetSdk(
+ pkg.applicationInfo.targetSdkVersion);
if (pkg.applicationInfo.isStaticSharedLibrary()) {
// must use v2 signing scheme
minSignatureScheme = SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2;
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 6639b3d5c0b5..90a332ccb430 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -231,9 +231,9 @@ public class ApkLiteParseUtils {
final boolean skipVerify = (flags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0;
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
try {
- signingDetails =
- ApkParseUtils.collectCertificates(apkFile.getAbsolutePath(), skipVerify,
- false, PackageParser.SigningDetails.UNKNOWN);
+ signingDetails = ApkParseUtils.collectCertificates(apkFile.getAbsolutePath(),
+ skipVerify, false, PackageParser.SigningDetails.UNKNOWN,
+ DEFAULT_TARGET_SDK_VERSION);
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
diff --git a/core/java/android/content/pm/parsing/ApkParseUtils.java b/core/java/android/content/pm/parsing/ApkParseUtils.java
index 3018230fac27..7506412f72cc 100644
--- a/core/java/android/content/pm/parsing/ApkParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkParseUtils.java
@@ -3176,7 +3176,8 @@ public class ApkParseUtils {
pkg.getBaseCodePath(),
skipVerify,
pkg.isStaticSharedLibrary(),
- pkg.getSigningDetails()
+ pkg.getSigningDetails(),
+ pkg.getTargetSdkVersion()
));
String[] splitCodePaths = pkg.getSplitCodePaths();
@@ -3186,7 +3187,8 @@ public class ApkParseUtils {
splitCodePaths[i],
skipVerify,
pkg.isStaticSharedLibrary(),
- pkg.getSigningDetails()
+ pkg.getSigningDetails(),
+ pkg.getTargetSdkVersion()
));
}
}
@@ -3199,9 +3201,11 @@ public class ApkParseUtils {
String baseCodePath,
boolean skipVerify,
boolean isStaticSharedLibrary,
- @NonNull SigningDetails existingSigningDetails
+ @NonNull SigningDetails existingSigningDetails,
+ int targetSdk
) throws PackageParserException {
- int minSignatureScheme = SigningDetails.SignatureSchemeVersion.JAR;
+ int minSignatureScheme = ApkSignatureVerifier.getMinimumSignatureSchemeVersionForTargetSdk(
+ targetSdk);
if (isStaticSharedLibrary) {
// must use v2 signing scheme
minSignatureScheme = SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2;
diff --git a/core/java/android/util/apk/ApkSignatureVerifier.java b/core/java/android/util/apk/ApkSignatureVerifier.java
index 71c8e98a0faa..64635098f7f4 100644
--- a/core/java/android/util/apk/ApkSignatureVerifier.java
+++ b/core/java/android/util/apk/ApkSignatureVerifier.java
@@ -27,6 +27,7 @@ import android.content.pm.PackageParser;
import android.content.pm.PackageParser.PackageParserException;
import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
import android.content.pm.Signature;
+import android.os.Build;
import android.os.Trace;
import android.util.jar.StrictJarFile;
@@ -447,6 +448,17 @@ public class ApkSignatureVerifier {
}
/**
+ * Returns the minimum signature scheme version required for an app targeting the specified
+ * {@code targetSdk}.
+ */
+ public static int getMinimumSignatureSchemeVersionForTargetSdk(int targetSdk) {
+ if (targetSdk >= Build.VERSION_CODES.R) {
+ return SignatureSchemeVersion.SIGNING_BLOCK_V2;
+ }
+ return SignatureSchemeVersion.JAR;
+ }
+
+ /**
* Result of a successful APK verification operation.
*/
public static class Result {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ca4ae0277aaf..b899fcd53ee5 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -60,6 +60,7 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIB
import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
import static android.content.pm.PackageManager.INSTALL_INTERNAL;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
+import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
@@ -124,8 +125,8 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
-import android.app.ApplicationPackageManager;
import android.app.AppOpsManager;
+import android.app.ApplicationPackageManager;
import android.app.BroadcastOptions;
import android.app.IActivityManager;
import android.app.ResourcesManager;
@@ -289,6 +290,7 @@ import android.util.SparseIntArray;
import android.util.StatsLog;
import android.util.TimingsTraceLog;
import android.util.Xml;
+import android.util.apk.ApkSignatureVerifier;
import android.util.jar.StrictJarFile;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
@@ -11561,6 +11563,17 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
}
+
+ // Ensure the package is signed with at least the minimum signature scheme version
+ // required for its target SDK.
+ int minSignatureSchemeVersion =
+ ApkSignatureVerifier.getMinimumSignatureSchemeVersionForTargetSdk(
+ pkg.getTargetSdkVersion());
+ if (pkg.getSigningDetails().signatureSchemeVersion < minSignatureSchemeVersion) {
+ throw new PackageManagerException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
+ "No signature found in package of version " + minSignatureSchemeVersion
+ + " or newer for package " + pkg.getPackageName());
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 74c98f9ef444..ae28019a5dea 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -141,10 +141,12 @@ public class StagingManager {
// Get signing details of the new package
final String apexPath = newApexPkg.applicationInfo.sourceDir;
final String packageName = newApexPkg.packageName;
+ int minSignatureScheme = ApkSignatureVerifier.getMinimumSignatureSchemeVersionForTargetSdk(
+ newApexPkg.applicationInfo.targetSdkVersion);
final SigningDetails newSigningDetails;
try {
- newSigningDetails = ApkSignatureVerifier.verify(apexPath, SignatureSchemeVersion.JAR);
+ newSigningDetails = ApkSignatureVerifier.verify(apexPath, minSignatureScheme);
} catch (PackageParserException e) {
throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
"Failed to parse APEX package " + apexPath, e);