Merge "Require signature scheme V2+ for target SDK R+"

This commit is contained in:
TreeHugger Robot
2020-01-29 20:47:00 +00:00
committed by Android (Google) Code Review
6 changed files with 41 additions and 9 deletions

View File

@@ -1584,7 +1584,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;

View File

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

View File

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

View File

@@ -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;
@@ -446,6 +447,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.
*/

View File

@@ -61,6 +61,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;
@@ -290,6 +291,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;
@@ -11591,6 +11593,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());
}
}
}

View File

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