Snap for 8541063 from 6ad4c757abe3744a2cb9e3e2b66d13e945ae1dec to mainline-appsearch-release
Change-Id: I440e277683165aa91c1f9d3e672abf4c8345d73c
diff --git a/src/main/java/com/android/apksig/internal/apk/v3/V3SchemeConstants.java b/src/main/java/com/android/apksig/internal/apk/v3/V3SchemeConstants.java
index 834e3cc..319b57f 100644
--- a/src/main/java/com/android/apksig/internal/apk/v3/V3SchemeConstants.java
+++ b/src/main/java/com/android/apksig/internal/apk/v3/V3SchemeConstants.java
@@ -28,9 +28,13 @@
public static final int MIN_SDK_WITH_V3_SUPPORT = AndroidSdkVersion.P;
public static final int MIN_SDK_WITH_V31_SUPPORT = AndroidSdkVersion.T;
- // TODO(b/192301300): Once the signing config has been updated to support specifying a
- // minSdkVersion for rotation this should be updated to T.
- public static final int DEFAULT_ROTATION_MIN_SDK_VERSION = AndroidSdkVersion.P;
+ /**
+ * By default, APK signing key rotation will target T, but packages that have previously
+ * rotated can continue rotating on pre-T by specifying an SDK version <= 32 as the
+ * --rotation-min-sdk-version parameter when using apksigner or when invoking
+ * {@link com.android.apksig.ApkSigner.Builder#setMinSdkVersionForRotation(int)}.
+ */
+ public static final int DEFAULT_ROTATION_MIN_SDK_VERSION = AndroidSdkVersion.T;
/**
* The v3.1 signature scheme is initially intended for the T development release, but until
* the T SDK is finalized it is using the SDK version of the latest platform release. To support
diff --git a/src/test/java/com/android/apksig/ApkSignerTest.java b/src/test/java/com/android/apksig/ApkSignerTest.java
index adc3a38..9004d80 100644
--- a/src/test/java/com/android/apksig/ApkSignerTest.java
+++ b/src/test/java/com/android/apksig/ApkSignerTest.java
@@ -228,7 +228,9 @@
.setV1SigningEnabled(false)
.setV2SigningEnabled(false)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
+
signGolden(
"golden-legacy-aligned-in.apk",
new File(outDir, "golden-legacy-aligned-v3-lineage-out.apk"),
@@ -236,6 +238,7 @@
.setV1SigningEnabled(false)
.setV2SigningEnabled(false)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
signGolden(
"golden-aligned-in.apk",
@@ -244,6 +247,7 @@
.setV1SigningEnabled(false)
.setV2SigningEnabled(false)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
signGolden(
@@ -296,6 +300,7 @@
.setV1SigningEnabled(false)
.setV2SigningEnabled(true)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
signGolden(
"golden-legacy-aligned-in.apk",
@@ -304,6 +309,7 @@
.setV1SigningEnabled(false)
.setV2SigningEnabled(true)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
signGolden(
"golden-aligned-in.apk",
@@ -312,6 +318,7 @@
.setV1SigningEnabled(false)
.setV2SigningEnabled(true)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
signGolden(
@@ -342,6 +349,7 @@
.setV1SigningEnabled(true)
.setV2SigningEnabled(true)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
signGolden(
"golden-legacy-aligned-in.apk",
@@ -350,6 +358,7 @@
.setV1SigningEnabled(true)
.setV2SigningEnabled(true)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
signGolden(
"golden-aligned-in.apk",
@@ -358,6 +367,7 @@
.setV1SigningEnabled(true)
.setV2SigningEnabled(true)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
signGolden(
@@ -462,6 +472,7 @@
.setV1SigningEnabled(false)
.setV2SigningEnabled(false)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
assertGolden(
"golden-unaligned-in.apk",
@@ -484,6 +495,7 @@
.setV1SigningEnabled(false)
.setV2SigningEnabled(true)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
assertGolden(
"golden-unaligned-in.apk",
@@ -499,6 +511,7 @@
.setV1SigningEnabled(true)
.setV2SigningEnabled(true)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
// Uncompressed entries in this input file are aligned by zero-padding the "extra" field, as
@@ -538,6 +551,7 @@
.setV1SigningEnabled(false)
.setV2SigningEnabled(false)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
assertGolden(
"golden-legacy-aligned-in.apk",
@@ -560,6 +574,7 @@
.setV1SigningEnabled(false)
.setV2SigningEnabled(true)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
assertGolden(
"golden-legacy-aligned-in.apk",
@@ -575,6 +590,7 @@
.setV1SigningEnabled(true)
.setV2SigningEnabled(true)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
// Uncompressed entries in this input file are aligned by padding the "extra" field, as
@@ -613,6 +629,7 @@
.setV1SigningEnabled(false)
.setV2SigningEnabled(false)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
assertGolden(
"golden-aligned-in.apk",
@@ -635,6 +652,7 @@
.setV1SigningEnabled(false)
.setV2SigningEnabled(true)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
assertGolden(
"golden-aligned-in.apk",
@@ -650,6 +668,7 @@
.setV1SigningEnabled(true)
.setV2SigningEnabled(true)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
}
@@ -952,6 +971,7 @@
.setV1SigningEnabled(false)
.setV2SigningEnabled(false)
.setV3SigningEnabled(true)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
.setSigningCertificateLineage(lineage));
// Verifies that an intermediate signer in the lineage is not sufficient to satisfy the
@@ -1860,6 +1880,66 @@
}
@Test
+ public void testV31_rotationMinSdkVersionDefault_rotationTargetsT() throws Exception {
+ // The v3.1 signature scheme was introduced in T to allow developers to target T+ for
+ // rotation due to known issues with rotation on previous platform releases. This test
+ // verifies an APK signed with a rotated signing key defaults to the original signing
+ // key used in the v3 signing block for pre-T devices, and the rotated signing key used
+ // in the v3.1 signing block for T+ devices.
+ List<ApkSigner.SignerConfig> rsa2048SignerConfigWithLineage =
+ Arrays.asList(
+ getDefaultSignerConfigFromResources(FIRST_RSA_2048_SIGNER_RESOURCE_NAME),
+ getDefaultSignerConfigFromResources(SECOND_RSA_2048_SIGNER_RESOURCE_NAME));
+ SigningCertificateLineage lineage =
+ Resources.toSigningCertificateLineage(
+ ApkSignerTest.class, LINEAGE_RSA_2048_2_SIGNERS_RESOURCE_NAME);
+
+ File signedApk = sign("original.apk",
+ new ApkSigner.Builder(rsa2048SignerConfigWithLineage)
+ .setV1SigningEnabled(true)
+ .setV2SigningEnabled(true)
+ .setV3SigningEnabled(true)
+ .setV4SigningEnabled(false)
+ .setSigningCertificateLineage(lineage));
+ ApkVerifier.Result result = verify(signedApk, null);
+
+ assertVerified(result);
+ assertTrue(result.isVerifiedUsingV3Scheme());
+ assertTrue(result.isVerifiedUsingV31Scheme());
+ assertEquals(AndroidSdkVersion.Sv2, result.getV3SchemeSigners().get(0).getMaxSdkVersion());
+ assertV31SignerTargetsMinApiLevel(result, SECOND_RSA_2048_SIGNER_RESOURCE_NAME,
+ V3SchemeConstants.DEV_RELEASE_ROTATION_MIN_SDK_VERSION);
+ }
+
+ @Test
+ public void testV31_rotationMinSdkVersionP_rotationTargetsP() throws Exception {
+ // While the V3.1 signature scheme will target T by default, a package that has
+ // previously rotated can provide a rotation-min-sdk-version less than T to continue
+ // using the rotated signing key in the v3.0 block.
+ List<ApkSigner.SignerConfig> rsa2048SignerConfigWithLineage =
+ Arrays.asList(
+ getDefaultSignerConfigFromResources(FIRST_RSA_2048_SIGNER_RESOURCE_NAME),
+ getDefaultSignerConfigFromResources(SECOND_RSA_2048_SIGNER_RESOURCE_NAME));
+ SigningCertificateLineage lineage =
+ Resources.toSigningCertificateLineage(
+ ApkSignerTest.class, LINEAGE_RSA_2048_2_SIGNERS_RESOURCE_NAME);
+
+ File signedApk = sign("original.apk",
+ new ApkSigner.Builder(rsa2048SignerConfigWithLineage)
+ .setV1SigningEnabled(true)
+ .setV2SigningEnabled(true)
+ .setV3SigningEnabled(true)
+ .setV4SigningEnabled(false)
+ .setMinSdkVersionForRotation(AndroidSdkVersion.P)
+ .setSigningCertificateLineage(lineage));
+ ApkVerifier.Result result = verify(signedApk, null);
+
+ assertVerified(result);
+ assertTrue(result.isVerifiedUsingV3Scheme());
+ assertFalse(result.isVerifiedUsingV31Scheme());
+ }
+
+ @Test
public void testV4_rotationMinSdkVersionLessThanT_signatureOnlyHasRotatedSigner()
throws Exception {
// To support SDK version targeting in the v3.1 signature scheme, apksig added a