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