/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.appsecurity.cts;

import static org.junit.Assert.fail;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assume.assumeTrue;

import android.platform.test.annotations.AsbSecurityTest;
import android.platform.test.annotations.Presubmit;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.host.HostFlagsValueProvider;

import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.compatibility.common.util.CddTest;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.testtype.junit4.DeviceParameterizedRunner;
import com.android.tradefed.util.FileUtil;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Locale;
import java.util.Objects;
import java.util.stream.Stream;

import junitparams.Parameters;

/**
 * Tests for APK signature verification during installation.
 */
@Presubmit
@RunWith(DeviceParameterizedRunner.class)
public class PkgInstallSignatureVerificationTest extends BaseAppSecurityTest {

    private static final String TEST_PKG = "android.appsecurity.cts.tinyapp";
    private static final String TEST_PKG2 = "android.appsecurity.cts.tinyapp2";
    private static final String COMPANION_TEST_PKG = "android.appsecurity.cts.tinyapp_companion";
    private static final String COMPANION2_TEST_PKG = "android.appsecurity.cts.tinyapp_companion2";
    private static final String COMPANION3_TEST_PKG = "android.appsecurity.cts.tinyapp_companion3";
    private static final String DEVICE_TESTS_APK = "CtsV3SigningSchemeRotationTest.apk";
    private static final String DEVICE_TESTS_PKG = "android.appsecurity.cts.v3rotationtests";
    private static final String DEVICE_TESTS_CLASS = DEVICE_TESTS_PKG + ".V3RotationTest";
    private static final String SERVICE_PKG = "android.appsecurity.cts.keyrotationtest";
    private static final String SERVICE_TEST_PKG = "android.appsecurity.cts.keyrotationtest.test";
    private static final String SERVICE_TEST_CLASS =
            SERVICE_TEST_PKG + ".SignatureQueryServiceInstrumentationTest";
    private static final String TEST_APK_RESOURCE_PREFIX = "/pkgsigverify/";
    private static final String INSTALL_ARG_FORCE_QUERYABLE = "--force-queryable";

    private static final String[] DSA_KEY_NAMES = {"1024", "2048", "3072"};
    private static final String[] EC_KEY_NAMES = {"p256", "p384", "p521"};
    private static final String[] RSA_KEY_NAMES = {"1024", "2048", "3072", "4096", "8192", "16384"};
    private static final String[] RSA_KEY_NAMES_2048_AND_LARGER =
            {"2048", "3072", "4096", "8192", "16384"};

    private static final boolean INCREMENTAL = true;
    private static final boolean NON_INCREMENTAL = false;

    private static Object[] installOnIncremental() {
        // Incremental and Non-Incremental.
        return new Boolean[][]{{INCREMENTAL}, {NON_INCREMENTAL}};
    }

    private boolean mUseIncrementalForInstallWithIdsig;

    @Rule
    public final CheckFlagsRule mCheckFlagsRule =
            HostFlagsValueProvider.createCheckFlagsRule(this::getDevice);

    @Before
    public void setUp() throws Exception {
        Utils.prepareSingleUser(getDevice());
        uninstallPackage();
        uninstallCompanionPackages();
        installDeviceTestPkg();
    }

    @After
    public void tearDown() throws Exception {
        uninstallPackages();
    }

    @Test
    public void testInstallOriginalSucceeds() throws Exception {
        // APK signed with v1 and v2 schemes. Obtained by building
        // cts/hostsidetests/appsecurity/test-apps/tinyapp.
        assertInstallSucceeds("original.apk");
    }

    @Test
    public void testInstallV1OneSignerMD5withRSA() throws Exception {
        // APK signed with v1 scheme only, one signer.
        assertInstallSucceedsForEach(
                "v1-only-with-rsa-pkcs1-md5-1.2.840.113549.1.1.1-%s.apk", RSA_KEY_NAMES);
        assertInstallSucceedsForEach(
                "v1-only-with-rsa-pkcs1-md5-1.2.840.113549.1.1.4-%s.apk", RSA_KEY_NAMES);
    }

    @Test
    public void testInstallV1OneSignerSHA1withRSA() throws Exception {
        // APK signed with v1 scheme only, one signer.
        assertInstallSucceedsForEach(
                "v1-only-with-rsa-pkcs1-sha1-1.2.840.113549.1.1.1-%s.apk", RSA_KEY_NAMES);
        assertInstallSucceedsForEach(
                "v1-only-with-rsa-pkcs1-sha1-1.2.840.113549.1.1.5-%s.apk", RSA_KEY_NAMES);
    }

    @Test
    public void testInstallV1OneSignerSHA224withRSA() throws Exception {
        // APK signed with v1 scheme only, one signer.
        assertInstallSucceedsForEach(
                "v1-only-with-rsa-pkcs1-sha224-1.2.840.113549.1.1.1-%s.apk", RSA_KEY_NAMES);
        assertInstallSucceedsForEach(
                "v1-only-with-rsa-pkcs1-sha224-1.2.840.113549.1.1.14-%s.apk", RSA_KEY_NAMES);
    }

    @Test
    public void testInstallV1OneSignerSHA256withRSA() throws Exception {
        // APK signed with v1 scheme only, one signer.
        assertInstallSucceedsForEach(
                "v1-only-with-rsa-pkcs1-sha256-1.2.840.113549.1.1.1-%s.apk", RSA_KEY_NAMES);
        assertInstallSucceedsForEach(
                "v1-only-with-rsa-pkcs1-sha256-1.2.840.113549.1.1.11-%s.apk", RSA_KEY_NAMES);
    }

    @Test
    public void testInstallV1OneSignerSHA384withRSA() throws Exception {
        // APK signed with v1 scheme only, one signer.
        assertInstallSucceedsForEach(
                "v1-only-with-rsa-pkcs1-sha384-1.2.840.113549.1.1.1-%s.apk", RSA_KEY_NAMES);
        assertInstallSucceedsForEach(
                "v1-only-with-rsa-pkcs1-sha384-1.2.840.113549.1.1.12-%s.apk", RSA_KEY_NAMES);
    }

    @Test
    public void testInstallV1OneSignerSHA512withRSA() throws Exception {
        // APK signed with v1 scheme only, one signer.
        assertInstallSucceedsForEach(
                "v1-only-with-rsa-pkcs1-sha512-1.2.840.113549.1.1.1-%s.apk", RSA_KEY_NAMES);
        assertInstallSucceedsForEach(
                "v1-only-with-rsa-pkcs1-sha512-1.2.840.113549.1.1.13-%s.apk", RSA_KEY_NAMES);
    }

    @Test
    public void testInstallV1OneSignerSHA1withECDSA() throws Exception {
        // APK signed with v1 scheme only, one signer.
        assertInstallSucceedsForEach(
                "v1-only-with-ecdsa-sha1-1.2.840.10045.2.1-%s.apk", EC_KEY_NAMES);
        assertInstallSucceedsForEach(
                "v1-only-with-ecdsa-sha1-1.2.840.10045.4.1-%s.apk", EC_KEY_NAMES);
    }

    @Test
    public void testInstallV1OneSignerSHA224withECDSA() throws Exception {
        // APK signed with v1 scheme only, one signer.
        assertInstallSucceedsForEach(
                "v1-only-with-ecdsa-sha224-1.2.840.10045.2.1-%s.apk", EC_KEY_NAMES);
        assertInstallSucceedsForEach(
                "v1-only-with-ecdsa-sha224-1.2.840.10045.4.3.1-%s.apk", EC_KEY_NAMES);
    }

    @Test
    public void testInstallV1OneSignerSHA256withECDSA() throws Exception {
        // APK signed with v1 scheme only, one signer.
        assertInstallSucceedsForEach(
                "v1-only-with-ecdsa-sha256-1.2.840.10045.2.1-%s.apk", EC_KEY_NAMES);
        assertInstallSucceedsForEach(
                "v1-only-with-ecdsa-sha256-1.2.840.10045.4.3.2-%s.apk", EC_KEY_NAMES);
    }

    @Test
    public void testInstallV1OneSignerSHA384withECDSA() throws Exception {
        // APK signed with v1 scheme only, one signer.
        assertInstallSucceedsForEach(
                "v1-only-with-ecdsa-sha384-1.2.840.10045.2.1-%s.apk", EC_KEY_NAMES);
        assertInstallSucceedsForEach(
                "v1-only-with-ecdsa-sha384-1.2.840.10045.4.3.3-%s.apk", EC_KEY_NAMES);
    }

    @Test
    public void testInstallV1OneSignerSHA512withECDSA() throws Exception {
        // APK signed with v1 scheme only, one signer.
        assertInstallSucceedsForEach(
                "v1-only-with-ecdsa-sha512-1.2.840.10045.2.1-%s.apk", EC_KEY_NAMES);
        assertInstallSucceedsForEach(
                "v1-only-with-ecdsa-sha512-1.2.840.10045.4.3.4-%s.apk", EC_KEY_NAMES);
    }

    @Test
    public void testInstallV1OneSignerSHA1withDSA() throws Exception {
        // APK signed with v1 scheme only, one signer.
        assertInstallSucceedsForEach(
                "v1-only-with-dsa-sha1-1.2.840.10040.4.1-%s.apk", DSA_KEY_NAMES);
        assertInstallSucceedsForEach(
                "v1-only-with-dsa-sha1-1.2.840.10040.4.3-%s.apk", DSA_KEY_NAMES);
    }

    @Test
    public void testInstallV1OneSignerSHA224withDSA() throws Exception {
        // APK signed with v1 scheme only, one signer.
        assertInstallSucceedsForEach(
                "v1-only-with-dsa-sha224-1.2.840.10040.4.1-%s.apk", DSA_KEY_NAMES);
        assertInstallSucceedsForEach(
                "v1-only-with-dsa-sha224-2.16.840.1.101.3.4.3.1-%s.apk", DSA_KEY_NAMES);
    }

    @Test
    public void testInstallV1OneSignerSHA256withDSA() throws Exception {
        // APK signed with v1 scheme only, one signer.
        assertInstallSucceedsForEach(
                "v1-only-with-dsa-sha256-1.2.840.10040.4.1-%s.apk", DSA_KEY_NAMES);
        assertInstallSucceedsForEach(
                "v1-only-with-dsa-sha256-2.16.840.1.101.3.4.3.2-%s.apk", DSA_KEY_NAMES);
    }

//  Android platform doesn't support DSA with SHA-384 and SHA-512.
//    @Test
//    public void testInstallV1OneSignerSHA384withDSA() throws Exception {
//        // APK signed with v1 scheme only, one signer.
//        assertInstallSucceedsForEach(
//                "v1-only-with-dsa-sha384-2.16.840.1.101.3.4.3.3-%s.apk", DSA_KEY_NAMES);
//    }
//
//    @Test
//    public void testInstallV1OneSignerSHA512withDSA() throws Exception {
//        // APK signed with v1 scheme only, one signer.
//        assertInstallSucceedsForEach(
//                "v1-only-with-dsa-sha512-2.16.840.1.101.3.4.3.3-%s.apk", DSA_KEY_NAMES);
//    }

    @Test
    public void testInstallV2StrippedFails() throws Exception {
        // APK signed with v1 and v2 schemes, but v2 signature was stripped from the file (by using
        // zipalign).
        // This should fail because the v1 signature indicates that the APK was supposed to be
        // signed with v2 scheme as well, making the platform's anti-stripping protections reject
        // the APK.
        assertInstallFailsWithError("v2-stripped.apk", "Signature stripped");

        // Similar to above, but the X-Android-APK-Signed anti-stripping header in v1 signature
        // lists unknown signature schemes in addition to APK Signature Scheme v2. Unknown schemes
        // should be ignored.
        assertInstallFailsWithError(
                "v2-stripped-with-ignorable-signing-schemes.apk", "Signature stripped");
    }

    @Test
    public void testInstallV2OneSignerOneSignature() throws Exception {
        // APK signed with v2 scheme only, one signer, one signature.
        assertInstallSucceedsForEach("v2-only-with-dsa-sha256-%s.apk", DSA_KEY_NAMES);
        assertInstallSucceedsForEach("v2-only-with-ecdsa-sha256-%s.apk", EC_KEY_NAMES);
        assertInstallSucceedsForEach("v2-only-with-rsa-pkcs1-sha256-%s.apk", RSA_KEY_NAMES);
        assertInstallSucceedsForEach("v2-only-with-rsa-pss-sha256-%s.apk", RSA_KEY_NAMES);

        // DSA with SHA-512 is not supported by Android platform and thus APK Signature Scheme v2
        // does not support that either
        // assertInstallSucceedsForEach("v2-only-with-dsa-sha512-%s.apk", DSA_KEY_NAMES);
        assertInstallSucceedsForEach("v2-only-with-ecdsa-sha512-%s.apk", EC_KEY_NAMES);
        assertInstallSucceedsForEach("v2-only-with-rsa-pkcs1-sha512-%s.apk", RSA_KEY_NAMES);
        assertInstallSucceedsForEach(
                "v2-only-with-rsa-pss-sha512-%s.apk",
                RSA_KEY_NAMES_2048_AND_LARGER // 1024-bit key is too short for PSS with SHA-512
        );
    }

    @Test
    public void testInstallV1SignatureOnlyDoesNotVerify() throws Exception {
        // APK signed with v1 scheme only, but not all digests match those recorded in
        // META-INF/MANIFEST.MF.
        String error = "META-INF/MANIFEST.MF has invalid digest";

        // Bitflip in classes.dex of otherwise good file.
        assertInstallFailsWithError(
                "v1-only-with-tampered-classes-dex.apk", error);
    }

    @Test
    public void testInstallV2SignatureDoesNotVerify() throws Exception {
        // APK signed with v2 scheme only, but the signature over signed-data does not verify.
        String error = "signature did not verify";

        // Bitflip in certificate field inside signed-data. Based on
        // v2-only-with-dsa-sha256-1024.apk.
        assertInstallFailsWithError("v2-only-with-dsa-sha256-1024-sig-does-not-verify.apk", error);

        // Signature claims to be RSA PKCS#1 v1.5 with SHA-256, but is actually using SHA-512.
        // Based on v2-only-with-rsa-pkcs1-sha256-2048.apk.
        assertInstallFailsWithError(
                "v2-only-with-rsa-pkcs1-sha256-2048-sig-does-not-verify.apk", error);

        // Signature claims to be RSA PSS with SHA-256 and 32 bytes of salt, but is actually using 0
        // bytes of salt. Based on v2-only-with-rsa-pkcs1-sha256-2048.apk. Obtained by modifying APK
        // signer to use the wrong amount of salt.
        assertInstallFailsWithError(
                "v2-only-with-rsa-pss-sha256-2048-sig-does-not-verify.apk", error);

        // Bitflip in the ECDSA signature. Based on v2-only-with-ecdsa-sha256-p256.apk.
        assertInstallFailsWithError(
                "v2-only-with-ecdsa-sha256-p256-sig-does-not-verify.apk", error);
    }

    @Test
    public void testInstallV2ContentDigestMismatch() throws Exception {
        // APK signed with v2 scheme only, but the digest of contents does not match the digest
        // stored in signed-data.
        String error = "digest of contents did not verify";

        // Based on v2-only-with-rsa-pkcs1-sha512-4096.apk. Obtained by modifying APK signer to
        // flip the leftmost bit in content digest before signing signed-data.
        assertInstallFailsWithError(
                "v2-only-with-rsa-pkcs1-sha512-4096-digest-mismatch.apk", error);

        // Based on v2-only-with-ecdsa-sha256-p256.apk. Obtained by modifying APK signer to flip the
        // leftmost bit in content digest before signing signed-data.
        assertInstallFailsWithError(
                "v2-only-with-ecdsa-sha256-p256-digest-mismatch.apk", error);
    }

    @Test
    public void testInstallNoApkSignatureSchemeBlock() throws Exception {
        // APK signed with v2 scheme only, but the rules for verifying APK Signature Scheme v2
        // signatures say that this APK must not be verified using APK Signature Scheme v2.

        // Obtained from v2-only-with-rsa-pkcs1-sha512-4096.apk by flipping a bit in the magic
        // field in the footer of APK Signing Block. This makes the APK Signing Block disappear.
        assertInstallFails("v2-only-wrong-apk-sig-block-magic.apk");

        // Obtained by modifying APK signer to insert "GARBAGE" between ZIP Central Directory and
        // End of Central Directory. The APK is otherwise fine and is signed with APK Signature
        // Scheme v2. Based on v2-only-with-rsa-pkcs1-sha256.apk.
        assertInstallFails("v2-only-garbage-between-cd-and-eocd.apk");

        // Obtained by modifying APK signer to truncate the ZIP Central Directory by one byte. The
        // APK is otherwise fine and is signed with APK Signature Scheme v2. Based on
        // v2-only-with-rsa-pkcs1-sha256.apk
        assertInstallFails("v2-only-truncated-cd.apk");

        // Obtained by modifying the size in APK Signature Block header. Based on
        // v2-only-with-ecdsa-sha512-p521.apk.
        assertInstallFails("v2-only-apk-sig-block-size-mismatch.apk");

        // Obtained by modifying the ID under which APK Signature Scheme v2 Block is stored in
        // APK Signing Block and by modifying the APK signer to not insert anti-stripping
        // protections into JAR Signature. The APK should appear as having no APK Signature Scheme
        // v2 Block and should thus successfully verify using JAR Signature Scheme.
        assertInstallSucceeds("v1-with-apk-sig-block-but-without-apk-sig-scheme-v2-block.apk");
    }

    @Test
    public void testInstallV2UnknownPairIgnoredInApkSigningBlock() throws Exception {
        // Obtained by modifying APK signer to emit an unknown ID-value pair into APK Signing Block
        // before the ID-value pair containing the APK Signature Scheme v2 Block. The unknown
        // ID-value should be ignored.
        assertInstallSucceeds("v2-only-unknown-pair-in-apk-sig-block.apk");
    }

    @Test
    public void testInstallV2IgnoresUnknownSignatureAlgorithms() throws Exception {
        // APK is signed with a known signature algorithm and with a couple of unknown ones.
        // Obtained by modifying APK signer to use "unknown" signature algorithms in addition to
        // known ones.
        assertInstallSucceeds("v2-only-with-ignorable-unsupported-sig-algs.apk");
    }

    @Test
    public void testInstallV2RejectsMismatchBetweenSignaturesAndDigestsBlocks() throws Exception {
        // APK is signed with a single signature algorithm, but the digests block claims that it is
        // signed with two different signature algorithms. Obtained by modifying APK Signer to
        // emit an additional digest record with signature algorithm 0x12345678.
        assertInstallFailsWithError(
                "v2-only-signatures-and-digests-block-mismatch.apk",
                "Signature algorithms don't match between digests and signatures records");
    }

    @Test
    public void testInstallV2RejectsMismatchBetweenPublicKeyAndCertificate() throws Exception {
        // APK is signed with v2 only. The public key field does not match the public key in the
        // leaf certificate. Obtained by modifying APK signer to write out a modified leaf
        // certificate where the RSA modulus has a bitflip.
        assertInstallFailsWithError(
                "v2-only-cert-and-public-key-mismatch.apk",
                "Public key mismatch between certificate and signature record");
    }

    @Test
    public void testInstallV2RejectsSignerBlockWithNoCertificates() throws Exception {
        // APK is signed with v2 only. There are no certificates listed in the signer block.
        // Obtained by modifying APK signer to output no certificates.
        assertInstallFailsWithError("v2-only-no-certs-in-sig.apk", "No certificates listed");
    }

    @Test
    public void testInstallTwoSigners() throws Exception {
        // APK signed by two different signers.
        assertInstallSucceeds("two-signers.apk");
        // Because the install attempt below is an update, it also tests that the signing
        // certificates exposed by v2 signatures above are the same as the one exposed by v1
        // signatures in this APK.
        assertInstallSucceeds("v1-only-two-signers.apk");
        assertInstallSucceeds("v2-only-two-signers.apk");
    }

    @Test
    public void testInstallNegativeModulus() throws Exception {
        // APK signed with a certificate that has a negative RSA modulus.
        assertInstallSucceeds("v1-only-negative-modulus.apk");
        assertInstallSucceeds("v2-only-negative-modulus.apk");
        assertInstallSucceeds("v3-only-negative-modulus.apk");
    }

    @Test
    public void testInstallV2TwoSignersRejectsWhenOneBroken() throws Exception {
        // Bitflip in the ECDSA signature of second signer. Based on two-signers.apk.
        // This asserts that breakage in any signer leads to rejection of the APK.
        assertInstallFailsWithError(
                "two-signers-second-signer-v2-broken.apk", "signature did not verify");
    }

    @Test
    public void testInstallV2TwoSignersRejectsWhenOneWithoutSignatures() throws Exception {
        // APK v2-signed by two different signers. However, there are no signatures for the second
        // signer.
        assertInstallFailsWithError(
                "v2-only-two-signers-second-signer-no-sig.apk", "No signatures");
    }

    @Test
    public void testInstallV2TwoSignersRejectsWhenOneWithoutSupportedSignatures() throws Exception {
        // APK v2-signed by two different signers. However, there are no supported signatures for
        // the second signer.
        assertInstallFailsWithError(
                "v2-only-two-signers-second-signer-no-supported-sig.apk",
                "No supported signatures");
    }

    @Test
    public void testInstallV2RejectsWhenMissingCode() throws Exception {
        // Obtained by removing classes.dex from original.apk and then signing with v2 only.
        // Although this has nothing to do with v2 signature verification, package manager wants
        // signature verification / certificate collection to reject APKs with missing code
        // (classes.dex) unless requested otherwise.
        assertInstallFailsWithError("v2-only-missing-classes.dex.apk", "code is missing");
    }

    @Test
    public void testCorrectCertUsedFromPkcs7SignedDataCertsSet() throws Exception {
        // Obtained by prepending the rsa-1024 certificate to the PKCS#7 SignedData certificates set
        // of v1-only-with-rsa-pkcs1-sha1-1.2.840.113549.1.1.1-2048.apk META-INF/CERT.RSA. The certs
        // (in the order of appearance in the file) are thus: rsa-1024, rsa-2048. The package's
        // signing cert is rsa-2048.
        assertInstallSucceeds("v1-only-pkcs7-cert-bag-first-cert-not-used.apk");

        // Check that rsa-1024 was not used as the previously installed package's signing cert.
        assertInstallFailsWithError(
                "v1-only-with-rsa-pkcs1-sha1-1.2.840.113549.1.1.1-1024.apk",
                "signatures do not match");

        // Check that rsa-2048 was used as the previously installed package's signing cert.
        assertInstallSucceeds("v1-only-with-rsa-pkcs1-sha1-1.2.840.113549.1.1.1-2048.apk");
    }

    @Test
    public void testV1SchemeSignatureCertNotReencoded() throws Exception {
        // Regression test for b/30148997 and b/18228011. When PackageManager does not preserve the
        // original encoded form of signing certificates, bad things happen, such as rejection of
        // completely valid updates to apps. The issue in b/30148997 and b/18228011 was that
        // PackageManager started re-encoding signing certs into DER. This normally produces exactly
        // the original form because X.509 certificates are supposed to be DER-encoded. However, a
        // small fraction of Android apps uses X.509 certificates which are not DER-encoded. For
        // such apps, re-encoding into DER changes the serialized form of the certificate, creating
        // a mismatch with the serialized form stored in the PackageManager database, leading to the
        // rejection of updates for the app.
        //
        // The signing certs of the two APKs differ only in how the cert's signature is encoded.
        // From Android's perspective, these two APKs are signed by different entities and thus
        // cannot be used to update one another. If signature verification code re-encodes certs
        // into DER, both certs will be exactly the same and Android will accept these APKs as
        // updates of each other. This test is thus asserting that the two APKs are not accepted as
        // updates of each other.
        //
        // * v1-only-with-rsa-1024.apk cert's signature is DER-encoded
        // * v1-only-with-rsa-1024-cert-not-der.apk cert's signature is not DER-encoded. It is
        //   BER-encoded, with length encoded as two bytes instead of just one.
        //   v1-only-with-rsa-1024-cert-not-der.apk META-INF/CERT.RSA was obtained from
        //   v1-only-with-rsa-1024.apk META-INF/CERT.RSA by manually modifying the ASN.1 structure.
        assertInstallSucceeds("v1-only-with-rsa-1024.apk");
        assertInstallFailsWithError(
                "v1-only-with-rsa-1024-cert-not-der.apk", "signatures do not match");

        uninstallPackage();
        assertInstallSucceeds("v1-only-with-rsa-1024-cert-not-der.apk");
        assertInstallFailsWithError("v1-only-with-rsa-1024.apk", "signatures do not match");
    }

    @Test
    public void testV2SchemeSignatureCertNotReencoded() throws Exception {
        // This test is here to catch something like b/30148997 and b/18228011 happening to the
        // handling of APK Signature Scheme v2 signatures by PackageManager. When PackageManager
        // does not preserve the original encoded form of signing certificates, bad things happen,
        // such as rejection of completely valid updates to apps. The issue in b/30148997 and
        // b/18228011 was that PackageManager started re-encoding signing certs into DER. This
        // normally produces exactly the original form because X.509 certificates are supposed to be
        // DER-encoded. However, a small fraction of Android apps uses X.509 certificates which are
        // not DER-encoded. For such apps, re-encoding into DER changes the serialized form of the
        // certificate, creating a mismatch with the serialized form stored in the PackageManager
        // database, leading to the rejection of updates for the app.
        //
        // The signing certs of the two APKs differ only in how the cert's signature is encoded.
        // From Android's perspective, these two APKs are signed by different entities and thus
        // cannot be used to update one another. If signature verification code re-encodes certs
        // into DER, both certs will be exactly the same and Android will accept these APKs as
        // updates of each other. This test is thus asserting that the two APKs are not accepted as
        // updates of each other.
        //
        // * v2-only-with-rsa-pkcs1-sha256-1024.apk cert's signature is DER-encoded
        // * v2-only-with-rsa-pkcs1-sha256-1024-cert-not-der.apk cert's signature is not DER-encoded
        //   It is BER-encoded, with length encoded as two bytes instead of just one.
        assertInstallSucceeds("v2-only-with-rsa-pkcs1-sha256-1024.apk");
        assertInstallFailsWithError(
                "v2-only-with-rsa-pkcs1-sha256-1024-cert-not-der.apk", "signatures do not match");

        uninstallPackage();
        assertInstallSucceeds("v2-only-with-rsa-pkcs1-sha256-1024-cert-not-der.apk");
        assertInstallFailsWithError(
                "v2-only-with-rsa-pkcs1-sha256-1024.apk", "signatures do not match");
    }

    @Test
    public void testInstallMaxSizedZipEocdComment() throws Exception {
        // Obtained by modifying apksigner to produce a 0xffff-byte long ZIP End of
        // Central Directory comment which exceeds the maximum size of comment,
        // and signing the original.apk using the modified apksigner.
        assertInstallFailsWithError("v1-only-max-sized-eocd-comment.apk", "Unknown failure");
        assertInstallFailsWithError("v2-only-max-sized-eocd-comment.apk", "Unknown failure");
    }

    @Test
    public void testInstallEphemeralRequiresV2Signature() throws Exception {
        assertInstallEphemeralFailsWithError("unsigned-ephemeral.apk",
                "Failed to collect certificates");
        assertInstallEphemeralFailsWithError("v1-only-ephemeral.apk",
                "must be signed with APK Signature Scheme v2 or greater");
        assertInstallEphemeralSucceeds("v2-only-ephemeral.apk");
        assertInstallEphemeralSucceeds("v1-v2-ephemeral.apk"); // signed with both schemes
    }

    @Test
    public void testInstallEmpty() throws Exception {
        assertInstallFailsWithError("empty-unsigned.apk", "Unknown failure");
        assertInstallFailsWithError("v1-only-empty.apk", "Unknown failure");
        assertInstallFailsWithError("v2-only-empty.apk", "Unknown failure");
    }

    @AsbSecurityTest(cveBugId = 64211847)
    @Test
    public void testInstallApkWhichDoesNotStartWithZipLocalFileHeaderMagic() throws Exception {
        // The APKs below are competely fine except they don't start with ZIP Local File Header
        // magic. Thus, these APKs will install just fine unless Package Manager requires that APKs
        // start with ZIP Local File Header magic.
        String error = "Unknown failure";

        // Obtained by modifying apksigner to output four unused 0x00 bytes at the start of the APK
        assertInstallFailsWithError("v1-only-starts-with-00000000-magic.apk", error);
        assertInstallFailsWithError("v2-only-starts-with-00000000-magic.apk", error);

        // Obtained by modifying apksigner to output 8 unused bytes (DEX magic and version) at the
        // start of the APK
        assertInstallFailsWithError("v1-only-starts-with-dex-magic.apk", error);
        assertInstallFailsWithError("v2-only-starts-with-dex-magic.apk", error);
    }

    @Test
    public void testInstallV3KeyRotation() throws Exception {
        // tests that a v3 signed APK with RSA key can rotate to a new key
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-1.apk");
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-caps.apk");
    }

    @Test
    public void testInstallV3KeyRotationToAncestor() throws Exception {
        // tests that a v3 signed APK with RSA key cannot be upgraded by one of its past certs
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-caps.apk");
        assertInstallFails("v3-rsa-pkcs1-sha256-2048-1.apk");
    }

    @Test
    public void testInstallV3KeyRotationToAncestorWithRollback() throws Exception {
        // tests that a v3 signed APK with RSA key can be upgraded by one of its past certs if it
        // has granted that cert the rollback capability
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-and-roll-caps.apk");
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-1.apk");
    }

    @Test
    public void testInstallV3KeyRotationMultipleHops() throws Exception {
        // tests that a v3 signed APK with RSA key can rotate to a new key which is the result of
        // multiple rotations from the original: APK signed with key 1 can be updated by key 3, when
        // keys were: 1 -> 2 -> 3
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-1.apk");
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-3-with-por_1_2_3-full-caps.apk");
    }

    @Test
    public void testInstallV3PorSignerMismatch() throws Exception {
        // tests that an APK with a proof-of-rotation struct that doesn't include the current
        // signing certificate fails to install
        assertInstallFails("v3-rsa-pkcs1-sha256-2048-3-with-por_1_2-full-caps.apk");
    }

    @Test
    public void testInstallV3KeyRotationWrongPor() throws Exception {
        // tests that a valid APK with a proof-of-rotation record can't upgrade an APK with a
        // signing certificate that isn't in the proof-of-rotation record
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-1.apk");
        assertInstallFails("v3-rsa-pkcs1-sha256-2048-3-with-por_2_3-full-caps.apk");
    }

    @Test
    public void testInstallV3KeyRotationSharedUid() throws Exception {
        // tests that a v3 signed sharedUid APK can still be sharedUid with apps with its older
        // signing certificate, if it so desires
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-1-sharedUid.apk");
        assertInstallSucceeds(
                "v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-caps-sharedUid-companion.apk");
    }

    @Test
    public void testInstallV3KeyRotationOlderSharedUid() throws Exception {
        // tests that a sharedUid APK can still install with another app that is signed by a newer
        // signing certificate, but which allows sharedUid with the older one
        assertInstallSucceeds(
                "v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-caps-sharedUid-companion.apk");
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-1-sharedUid.apk");
    }

    @Test
    public void testInstallV3KeyRotationSharedUidNoCap() throws Exception {
        // tests that a v3 signed sharedUid APK cannot be sharedUid with apps with its older
        // signing certificate, when it has not granted that certificate the sharedUid capability
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-1-sharedUid.apk");
        assertInstallFails(
                "v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-no-shUid-cap-sharedUid-companion.apk");
    }

    @Test
    public void testInstallV3KeyRotationOlderSharedUidNoCap() throws Exception {
        // tests that a sharedUid APK signed with an old certificate cannot install with
        // an app having a proof-of-rotation structure that hasn't granted the older
        // certificate the sharedUid capability
        assertInstallSucceeds(
                "v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-no-shUid-cap-sharedUid-companion.apk");
        assertInstallFails("v3-rsa-pkcs1-sha256-2048-1-sharedUid.apk");
    }

    @Test
    public void testInstallV3NoRotationSharedUid() throws Exception {
        // tests that a sharedUid APK signed with a new certificate installs with
        // an app having a proof-of-rotation structure that hasn't granted an older
        // certificate the sharedUid capability
        assertInstallSucceeds(
                "v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-no-shUid-cap-sharedUid-companion.apk");
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-sharedUid.apk");
    }

    @Test
    public void testInstallV3MultipleAppsOneDeniesOldKeySharedUid() throws Exception {
        // If two apps are installed as part of a sharedUid, one granting access to the sharedUid
        // to the previous key and the other revoking access to the sharedUid, then when an app
        // signed with the old key attempts to join the sharedUid the installation should be blocked
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-no-shUid-cap-sharedUid.apk");
        assertInstallFromBuildSucceeds(
                "v3-ec-p256-with-por_1_2-default-caps-sharedUid-companion.apk");
        assertInstallFromBuildFails("v3-ec-p256-1-sharedUid-companion2.apk");
    }

    @Test
    public void testInstallV3MultipleAppsOneUpdatedToDenyOldKeySharedUid() throws Exception {
        // Similar to the test above if two apps are installed as part of a sharedUid with both
        // granting access to the sharedUid to the previous key then an app signed with the previous
        // key should be allowed to install and join the sharedUid. If one of the first two apps
        // is then updated with a lineage that denies access to the sharedUid for the old key, all
        // subsequent installs / updates with that old key should be blocked.
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-default-caps-sharedUid.apk");
        assertInstallFromBuildSucceeds(
                "v3-ec-p256-with-por_1_2-default-caps-sharedUid-companion.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256-1-sharedUid-companion2.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-no-shUid-cap-sharedUid.apk");
        assertInstallFromBuildFails("v3-ec-p256-1-sharedUid-companion2.apk");
    }

    @Test
    public void testInstallV3SharedUidDeniedOnlyRotatedUpdateAllowed() throws Exception {
        // To allow rotation after a signing key compromise, an APK that is already part of a
        // shareddUserId can rotate to a new key with the old key being denied the SHARED_USER_ID
        // capability and still be updated in the sharedUserId. Another app signed with this same
        // lineage and capabilities that is not currently part of the sharedUserId will not be
        // allowed to join as long as any apps signed with the untrusted key are still part of
        // the sharedUserId.
        assertInstallFromBuildSucceeds("v3-ec-p256-1-sharedUid.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256-1-sharedUid-companion2.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-no-shUid-cap-sharedUid.apk");
        // An app signed with the untrusted key is still part of the sharedUserId, so a new app
        // that does not trust this key is not allowed to join the sharedUserId.
        assertInstallFromBuildFails("v3-ec-p256-with-por_1_2-no-shUid-cap-sharedUid-companion.apk");
        assertInstallFromBuildSucceeds(
                "v3-ec-p256-with-por_1_2-no-shUid-cap-sharedUid-companion2.apk");
        // Once all apps have rotated away from the untrusted key, a new app that also does not
        // trust the previous key can now join the sharedUserId.
        assertInstallFromBuildSucceeds(
                "v3-ec-p256-with-por_1_2-no-shUid-cap-sharedUid-companion.apk");
    }

    @Test
    public void testInstallV3FirstAppOnlySignedByNewKeyLastAppOldKey() throws Exception {
        // This test verifies the following scenario:
        // - First installed app in sharedUid only signed with new key without lineage.
        // - Second installed app in sharedUid signed with new key and includes lineage granting
        //   access to the old key to join the sharedUid.
        // - Last installed app in sharedUid signed with old key.
        // The lineage should be updated when the second app is installed to allow the installation
        // of the app signed with the old key.
        assertInstallFromBuildSucceeds("v3-ec-p256-2-sharedUid-companion.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-default-caps-sharedUid.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256-1-sharedUid-companion2.apk");
    }

    @Test
    public void testInstallV3AppSignedWithOldKeyUpdatedLineageDeniesShUidCap() throws Exception {
        // If an app is installed as part of a sharedUid, and then that app is signed with a new key
        // that rejects the previous key in the lineage the update should be allowed to proceed
        // as the app is being updated to the newly rotated key.
        assertInstallFromBuildSucceeds("v3-ec-p256-1-sharedUid.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-no-shUid-cap-sharedUid.apk");
    }

    @Test
    public void testInstallV3TwoSharedUidAppsWithDivergedLineages() throws Exception {
        // Apps that are installed as part of the sharedUserId with a lineage must have common
        // ancestors; the platform will allow the installation if the lineage of an app being
        // installed as part of the sharedUserId is the same, a subset, or a superset of the
        // existing lineage, but if the lineage diverges then the installation should be blocked.
        assertInstallFromBuildSucceeds("v3-por_Y_1_2-default-caps-sharedUid.apk");
        assertInstallFromBuildFails("v3-por_Z_1_2-default-caps-sharedUid-companion.apk");
    }

    @Test
    public void testInstallV3WithRestoredCapabilityInSharedUserId() throws Exception {
        // A sharedUserId contains the shared signing lineage for all packages in the UID; this
        // shared lineage contain the full signing history for all packages along with the merged
        // capabilities for each signer shared between the packages. This test verifies if one
        // package revokes a capability from a previous signer, but subsequently restores that
        // capability, then since all packages have granted the capability, it is restored to the
        // previous signer in the shared lineage.

        // Install a package with the SHARED_USER_ID capability revoked for the original signer
        // in the lineage; verify that a package signed with only the original signer cannot join
        // the sharedUserId.
        assertInstallFromBuildSucceeds(
                "v3-ec-p256-with-por_1_2-default-caps-sharedUid-companion.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-no-shUid-cap-sharedUid.apk");
        assertInstallFromBuildFails("v3-ec-p256-1-sharedUid-companion2.apk");

        // Update the package that revoked the SHARED_USER_ID with an updated lineage that restores
        // this capability to the original signer; verify the package signed with the original
        // signing key can now join the sharedUserId since all existing packages in the UID grant
        // this capability to the original signer.
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-default-caps-sharedUid.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256-1-sharedUid-companion2.apk");
    }

    @Test
    public void testInstallV3WithRevokedCapabilityInSharedUserId() throws Exception {
        // While a capability can be restored to a common signer in the shared signing lineage, if
        // one package has revoked a capability from a common signer and another package is
        // installed / updated which restores the capability to that signer, the revocation of
        // the capability by the existing package should take precedence. A capability can only
        // be restored to a common signer if all packages in the sharedUserId have granted this
        // capability to the signer.

        // Install a package with the SHARED_USER_ID capability revoked from the original signer,
        // then install another package in the sharedUserId that grants this capability to the
        // original signer. Since a package exists in the sharedUserId that has revoked this
        // capability, another package signed with this capability shouldn't be able to join the
        // sharedUserId.
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-no-shUid-cap-sharedUid.apk");
        assertInstallFromBuildSucceeds(
                "v3-ec-p256-with-por_1_2-default-caps-sharedUid-companion.apk");
        assertInstallFromBuildFails("v3-ec-p256-1-sharedUid-companion2.apk");

        // Install the same package that grants the SHARED_USER_ID capability to the original
        // signer; when iterating over the existing packages in the packages in the sharedUserId,
        // the original version of this package should be skipped since the lineage from the
        // updated package is used when merging with the shared lineage.
        assertInstallFromBuildSucceeds(
                "v3-ec-p256-with-por_1_2-default-caps-sharedUid-companion.apk");
        assertInstallFromBuildFails("v3-ec-p256-1-sharedUid-companion2.apk");

        // Install another package that has granted the SHARED_USER_ID to the original signer; this
        // should trigger another merge with all packages in the sharedUserId. Since one still
        // remains that revokes the capability, the capability should be revoked in the shared
        // lineage.
        assertInstallFromBuildSucceeds(
                "v3-ec-p256-with-por_1_2-default-caps-sharedUid-companion3.apk");
        assertInstallFromBuildFails("v3-ec-p256-1-sharedUid-companion2.apk");
    }

    @Test
    public void testInstallV3UpdateAfterRotation() throws Exception {
        // This test performs an end to end verification of the update of an app with a rotated
        // key. The app under test exports a bound service that performs its own PackageManager key
        // rotation API verification, and the instrumentation test binds to the service and invokes
        // the verifySignatures method to verify that the key rotation APIs return the expected
        // results. The instrumentation test app is signed with the same key and lineage as the
        // app under test to also provide a second app that can be used for the checkSignatures
        // verification.

        // Install the initial versions of the apps; the test method verifies the app under test is
        // signed with the original signing key.
        assertInstallFromBuildSucceeds("CtsSignatureQueryService.apk");
        assertInstallFromBuildSucceeds("CtsSignatureQueryServiceTest.apk");
        Utils.runDeviceTests(getDevice(), SERVICE_TEST_PKG, SERVICE_TEST_CLASS,
                "verifySignatures_noRotation_succeeds");

        // Install the second version of the app signed with the rotated key. This test verifies the
        // app still functions as expected after the update with the rotated key. The
        // instrumentation test app is not updated here to allow verification of the pre-key
        // rotation behavior for the checkSignatures APIs. These APIs should behave similar to the
        // GET_SIGNATURES flag in that if one or both apps have a signing lineage if the oldest
        // signers in the lineage match then the methods should return that the signatures match
        // even if one is signed with a newer key in the lineage.
        assertInstallFromBuildSucceeds("CtsSignatureQueryService_v2.apk");
        Utils.runDeviceTests(getDevice(), SERVICE_TEST_PKG, SERVICE_TEST_CLASS,
                "verifySignatures_withRotation_succeeds");

        // Installs the third version of the app under test and the instrumentation test, both
        // signed with the same rotated key and lineage. This test is intended to verify that the
        // app can still be updated and function as expected after an update with a rotated key.
        assertInstallFromBuildSucceeds("CtsSignatureQueryService_v3.apk");
        assertInstallFromBuildSucceeds("CtsSignatureQueryServiceTest_v2.apk");
        Utils.runDeviceTests(getDevice(), SERVICE_TEST_PKG, SERVICE_TEST_CLASS,
                "verifySignatures_withRotation_succeeds");
    }

    @CddTest(requirement="4/C-0-2")
    @Test
    public void testInstallV31UpdateAfterRotation() throws Exception {
        // This test is the same as above, but using the v3.1 signature scheme for rotation.
        assertInstallFromBuildSucceeds("CtsSignatureQueryService.apk");
        assertInstallFromBuildSucceeds("CtsSignatureQueryServiceTest.apk");
        Utils.runDeviceTests(getDevice(), SERVICE_TEST_PKG, SERVICE_TEST_CLASS,
                "verifySignatures_noRotation_succeeds");

        assertInstallFromBuildSucceeds("CtsSignatureQueryService_v2-tgt-33.apk");
        Utils.runDeviceTests(getDevice(), SERVICE_TEST_PKG, SERVICE_TEST_CLASS,
                "verifySignatures_withRotation_succeeds");

        assertInstallFromBuildSucceeds("CtsSignatureQueryService_v3-tgt-33.apk");
        assertInstallFromBuildSucceeds("CtsSignatureQueryServiceTest_v2-tgt-33.apk");
        Utils.runDeviceTests(getDevice(), SERVICE_TEST_PKG, SERVICE_TEST_CLASS,
                "verifySignatures_withRotation_succeeds");
    }

    @CddTest(requirement="4/C-0-9")
    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV41UpdateAfterRotation(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // This test is the same as above, but using the v4.1 signature scheme for rotation.
        assertInstallV4FromBuildSucceeds("CtsSignatureQueryService.apk");
        assertInstallV4FromBuildSucceeds("CtsSignatureQueryServiceTest.apk");
        Utils.runDeviceTests(getDevice(), SERVICE_TEST_PKG, SERVICE_TEST_CLASS,
                "verifySignatures_noRotation_succeeds");

        assertInstallV4FromBuildSucceeds("CtsSignatureQueryService_v2-tgt-33.apk");
        Utils.runDeviceTests(getDevice(), SERVICE_TEST_PKG, SERVICE_TEST_CLASS,
                "verifySignatures_withRotation_succeeds");

        assertInstallV4FromBuildSucceeds("CtsSignatureQueryService_v3-tgt-33.apk");
        assertInstallV4FromBuildSucceeds("CtsSignatureQueryServiceTest_v2-tgt-33.apk");
        Utils.runDeviceTests(getDevice(), SERVICE_TEST_PKG, SERVICE_TEST_CLASS,
                "verifySignatures_withRotation_succeeds");
    }

    @CddTest(requirement="4/C-0-9")
    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV41WrongBlockId(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // This test is the same as above, but using the v4.1 signature scheme for rotation.
        assertInstallV4FromBuildSucceeds("CtsSignatureQueryService.apk");
        assertInstallV4FromBuildSucceeds("CtsSignatureQueryServiceTest.apk");
        Utils.runDeviceTests(getDevice(), SERVICE_TEST_PKG, SERVICE_TEST_CLASS,
                "verifySignatures_noRotation_succeeds");

        assertInstallV4FailsWithError("CtsSignatureQueryService_v2-tgt-33-wrongV41Block.apk",
                "Failed to find V4 signature block corresponding to V3 blockId: 462663009");
    }

    @CddTest(requirement="4/C-0-9")
    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV41LegacyV4(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // This test is the same as above, but using the v4.1 signature scheme for rotation.
        assertInstallV4FromBuildSucceeds("CtsSignatureQueryService.apk");
        assertInstallV4FromBuildSucceeds("CtsSignatureQueryServiceTest.apk");
        Utils.runDeviceTests(getDevice(), SERVICE_TEST_PKG, SERVICE_TEST_CLASS,
                "verifySignatures_noRotation_succeeds");

        assertInstallV4FailsWithError("CtsSignatureQueryService_v2-tgt-33-legacyV4.apk",
                "Failed to find V4 signature block corresponding to V3 blockId: 462663009");
    }

    @CddTest(requirement="4/C-0-9")
    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV41WrongDigest(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // This test is the same as above, but using the v4.1 signature scheme for rotation.
        assertInstallV4FromBuildSucceeds("CtsSignatureQueryService.apk");
        assertInstallV4FromBuildSucceeds("CtsSignatureQueryServiceTest.apk");
        Utils.runDeviceTests(getDevice(), SERVICE_TEST_PKG, SERVICE_TEST_CLASS,
                "verifySignatures_noRotation_succeeds");

        assertInstallV4FailsWithError("CtsSignatureQueryService_v2-tgt-33-wrongDigest.apk",
                "APK digest in V4 signature does not match V2/V3");
    }

    @Test
    public void testInstallV3KeyRotationSigPerm() throws Exception {
        // tests that a v3 signed APK can still get a signature permission from an app with its
        // older signing certificate.
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-1-permdef.apk");
        assertInstallSucceeds(
                "v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-caps-permcli-companion.apk");
        Utils.runDeviceTests(getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS, "testHasPerm");
    }

    @Test
    public void testInstallV3KeyRotationOlderSigPerm() throws Exception {
        // tests that an apk with an older signing certificate than the one which defines a
        // signature permission it wants gets the permission if the defining APK grants the
        // capability
        assertInstallSucceeds(
                "v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-caps-permdef.apk");
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-1-permcli-companion.apk");
        Utils.runDeviceTests(getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS, "testHasPerm");
    }

    @Test
    public void testInstallV3KeyRotationSigPermNoCap() throws Exception {
        // tests that an APK signed by an older signing certificate is unable to get a requested
        // signature permission when the defining APK has rotated to a newer signing certificiate
        // and does not grant the permission capability to the older cert
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-no-perm-cap-permdef.apk");
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-1-permcli-companion.apk");
        Utils.runDeviceTests(getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS, "testHasNoPerm");
    }

    @Test
    public void testInstallV3KeyRotationOlderSigPermNoCap() throws Exception {
        // tests that an APK signed by a newer signing certificate than the APK which defines a
        // signature permission is able to get that permission, even if the newer APK does not
        // grant the permission capability to the older signing certificate.
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-1-permdef.apk");
        assertInstallSucceeds(
                "v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-no-perm-cap-permcli-companion.apk");
        Utils.runDeviceTests(getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS, "testHasPerm");
    }

    @Test
    public void testInstallV3NoRotationSigPerm() throws Exception {
        // make sure that an APK, which wants to use a signature permission defined by an APK, which
        // has not granted that capability to older signing certificates, can still install
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-no-perm-cap-permdef.apk");
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-permcli-companion.apk");
        Utils.runDeviceTests(getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS, "testHasPerm");
    }

    @Test
    public void testInstallV3CommonSignerInLineageWithPermCap() throws Exception {
        // If an APK requesting a signature permission has a common signer in the lineage with the
        // APK declaring the permission, and that signer is granted the permission capability in
        // the declaring APK, then the permission should be granted to the requesting app even
        // if their signers have diverged.
        assertInstallFromBuildSucceeds(
                "v3-ec-p256-with-por_1_2_3-1-no-caps-2-default-declperm.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2_4-companion-usesperm.apk");
        Utils.runDeviceTests(getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS, "testHasPerm");
    }

    @Test
    public void testInstallV3CommonSignerInLineageNoCaps() throws Exception {
        // If an APK requesting a signature permission has a common signer in the lineage with the
        // APK declaring the permission, but the signer in the lineage has not been granted the
        // permission capability the permission should not be granted to the requesting app.
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2_3-no-caps-declperm.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2_4-companion-usesperm.apk");
        Utils.runDeviceTests(getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS, "testHasNoPerm");
    }

    @Test
    public void testKnownSignerPermGrantedWhenCurrentSignerInResource() throws Exception {
        // The knownSigner protection flag allows an app to declare other trusted signing
        // certificates in an array resource; if a requesting app's current signer is in this array
        // of trusted certificates then the permission should be granted.
        assertInstallFromBuildSucceeds("v3-rsa-2048-decl-knownSigner-ec-p256-1-3.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256_3-companion-uses-knownSigner.apk");
        Utils.runDeviceTests(getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS, "testHasPerm");

        // If the declaring app changes the trusted certificates on an update any requesting app
        // that no longer meets the requirements based on its signing identity should have the
        // permission revoked. This app update only trusts ec-p256_1 but the app that was previously
        // granted the permission based on its signing identity is signed by ec-p256_3.
        assertInstallFromBuildSucceeds("v3-rsa-2048-decl-knownSigner-str-res-ec-p256-1.apk");
        Utils.runDeviceTests(getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS, "testHasNoPerm");
    }

    @Test
    public void testKnownSignerPermCurrentSignerNotInResource() throws Exception {
        // If an app requesting a knownSigner permission does not meet the requirements for a
        // signature permission and is not signed by any of the trusted certificates then the
        // permission should not be granted.
        assertInstallFromBuildSucceeds("v3-rsa-2048-decl-knownSigner-ec-p256-1-3.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256_2-companion-uses-knownSigner.apk");
        Utils.runDeviceTests(getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS, "testHasNoPerm");
    }

    @Test
    public void testKnownSignerPermGrantedWhenSignerInLineageInResource() throws Exception {
        // If an app requesting a knownSigner permission was previously signed by a certificate
        // that is trusted by the declaring app then the permission should be granted.
        assertInstallFromBuildSucceeds("v3-rsa-2048-decl-knownSigner-ec-p256-1-3.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-companion-uses-knownSigner.apk");
        Utils.runDeviceTests(getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS, "testHasPerm");

        // If the declaring app changes the permission to no longer use the knownSigner flag then
        // any app granted the permission based on a signing identity from the set of trusted
        // certificates should have the permission revoked.
        assertInstallFromBuildSucceeds("v3-rsa-2048-declperm.apk");
        Utils.runDeviceTests(getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS, "testHasNoPerm");
    }

    @Test
    public void testKnownSignerPermSignerInLineageMatchesStringResource() throws Exception {
        // The knownSigner protection flag allows an app to declare a single known trusted
        // certificate digest using a string resource instead of a string-array resource. This test
        // verifies the knownSigner permission is granted to a requesting app if the single trusted
        // cert is in the requesting app's lineage.
        assertInstallFromBuildSucceeds("v3-rsa-2048-decl-knownSigner-str-res-ec-p256-1.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-companion-uses-knownSigner.apk");
        Utils.runDeviceTests(getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS, "testHasPerm");
    }

    @Test
    public void testKnownSignerPermSignerInLineageMatchesStringConst() throws Exception {
        // The knownSigner protection flag allows an app to declare a single known trusted
        // certificate digest using a string constant as the knownCerts attribute value instead of a
        // resource. This test verifies the knownSigner permission is granted to a requesting app if
        // the single trusted cert is in the requesting app's lineage.
        assertInstallFromBuildSucceeds("v3-rsa-2048-decl-knownSigner-str-const-ec-p256-1.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-companion-uses-knownSigner.apk");
        Utils.runDeviceTests(getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS, "testHasPerm");
    }

    @Test
    public void testInstallV3SigPermDoubleDefNewerSucceeds() throws Exception {
        // make sure that if an app defines a signature permission already defined by another app,
        // it successfully installs if the other app's signing cert is in its past signing certs and
        // the signature permission capability is granted
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-1-permdef.apk");
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-with_por_1_2-permdef-companion.apk");
    }

    @Test
    public void testInstallV3SigPermDoubleDefOlderSucceeds() throws Exception {
        // make sure that if an app defines a signature permission already defined by another app,
        // it successfully installs if it is in the other app's past signing certs and the signature
        // permission capability is granted
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-with_por_1_2-permdef-companion.apk");
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-1-permdef.apk");
    }

    @Test
    public void testInstallV3SigPermDoubleDefNewerNoCapFails() throws Exception {
        // make sure that if an app defines a signature permission already defined by another app,
        // it fails to install if the other app's signing cert is in its past signing certs but the
        // signature permission capability is not granted
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-1-permdef.apk");
        assertInstallFails(
                "v3-rsa-pkcs1-sha256-2048-2-with_por_1_2-no-perm-cap-permdef-companion.apk");
    }

    @Test
    public void testInstallV3SigPermDoubleDefOlderNoCapFails() throws Exception {
        // make sure that if an app defines a signature permission already defined by another app,
        // it fails to install if it is in the other app's past signing certs but the signature
        // permission capability is not granted
        assertInstallSucceeds(
                "v3-rsa-pkcs1-sha256-2048-2-with_por_1_2-no-perm-cap-permdef-companion.apk");
        assertInstallFails("v3-rsa-pkcs1-sha256-2048-1-permdef.apk");
    }

    @Test
    public void testInstallV3SigPermDoubleDefSameNoCapSucceeds() throws Exception {
        // make sure that if an app defines a signature permission already defined by another app,
        // it installs successfully when signed by the same certificate, even if the original app
        // does not grant signature capabilities to its past certs
        assertInstallSucceeds(
                "v3-rsa-pkcs1-sha256-2048-2-with_por_1_2-no-perm-cap-permdef-companion.apk");
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-permdef.apk");
    }

    @Test
    public void testInstallV3KeyRotationGetSignatures() throws Exception {
        // tests that a PackageInfo w/GET_SIGNATURES flag returns the older cert
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-caps.apk");
        Utils.runDeviceTests(
                getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS, "testGetSignaturesShowsOld");
    }

    @Test
    public void testInstallV3KeyRotationGetSigningCertificates() throws Exception {
        // tests that a PackageInfo w/GET_SIGNING_CERTIFICATES flag returns the old and new certs
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-caps.apk");
        Utils.runDeviceTests(
                getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS,
                "testGetSigningCertificatesShowsAll");
    }

    @Test
    public void testInstallV3KeyRotationGetApkContentsSigners() throws Exception {
        // The GET_SIGNING_CERTIFICATES flag results in a PackageInfo object returned with a
        // SigningInfo instance that can be used to query all certificates in the lineage or only
        // the current signer(s) via getApkContentsSigners. This test verifies when a V3 signed
        // package with a rotated key is queried getApkContentsSigners only returns the current
        // signer.
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-default-caps.apk");
        Utils.runDeviceTests(
                getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS,
                "testGetApkContentsSignersShowsCurrent");
    }

    @Test
    public void testInstallV2MultipleSignersGetApkContentsSigners() throws Exception {
        // Similar to the above test, but verifies when an APK is signed with two V2 signers
        // getApkContentsSigners returns both of the V2 signers.
        assertInstallFromBuildSucceeds("v1v2-ec-p256-two-signers-targetSdk-30.apk");
        Utils.runDeviceTests(
                getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS,
                "testGetApkContentsSignersShowsMultipleSigners");
    }

    @Test
    public void testInstallV3MultipleSignersInLineageGetSigningCertificateHistory()
            throws Exception {
        // The APK used for this test is signed with a lineage containing 5 keys in the signing
        // history; this test verifies SigningInfo#getSigningCertificateHistory returns all of an
        // APKs signers in their order of rotation.
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por-1_2_3_4_5-default-caps.apk");
        Utils.runDeviceTests(
                getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS,
                "testGetSigningCertificateHistoryReturnsSignersInOrder");
    }

    @Test
    public void testInstallV3KeyRotationHasSigningCertificate() throws Exception {
        // tests that hasSigningCertificate() recognizes past and current signing certs
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-caps.apk");
        Utils.runDeviceTests(
                getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS,
                "testHasSigningCertificate");
    }

    @Test
    public void testInstallV3KeyRotationHasSigningCertificateSha256() throws Exception {
        // tests that hasSigningCertificate() recognizes past and current signing certs by sha256
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-caps.apk");
        Utils.runDeviceTests(
                getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS,
                "testHasSigningCertificateSha256");
    }

    @Test
    public void testInstallV3KeyRotationHasSigningCertificateByUid() throws Exception {
        // tests that hasSigningCertificate() recognizes past and current signing certs by uid
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-caps.apk");
        Utils.runDeviceTests(
                getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS,
                "testHasSigningCertificateByUid");
    }

    @Test
    public void testInstallV3KeyRotationHasSigningCertificateByUidSha256() throws Exception {
        // tests that hasSigningCertificate() recognizes past and current signing certs by uid
        // and sha256
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-caps.apk");
        Utils.runDeviceTests(
                getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS,
                "testHasSigningCertificateByUidSha256");
    }

    @Test
    public void testInstallV3KeyRotationHasDuplicateSigningCertificateHistory() throws Exception {
        // tests that an app's proof-of-rotation signing history cannot contain the same certificate
        // more than once.
        assertInstallFails("v3-rsa-pkcs1-sha256-2048-2-with-por_1_2_2-full-caps.apk");
    }

    @Test
    public void testInstallV3HasMultipleSigners() throws Exception {
        // tests that an app can't be signed by multiple signers when using v3 signature scheme
        assertInstallFails("v3-rsa-pkcs1-sha256-2048-1_and_2.apk");
    }

    @Test
    public void testInstallV3HasMultiplePlatformSigners() throws Exception {
        // tests that an app can be signed by multiple v3 signers if they target different platform
        // versions
        assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-1_P_and_2_Qplus.apk");
    }

    @Test
    public void testSharedKeyInSeparateLineageRetainsDeclaredCapabilities() throws Exception {
        // This test verifies when a key is used in the signing lineage of multiple apps each
        // instance of the key retains its declared capabilities.

        // This app has granted the PERMISSION capability to the previous signer in the lineage
        // but has revoked the SHARED_USER_ID capability.
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-no-shUid-cap-declperm2.apk");
        // This app has granted the SHARED_USER_ID capability to the previous signer in the lineage
        // but has revoked the PERMISSION capability.
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-no-perm-cap-sharedUid.apk");

        // Reboot the device to ensure that the capabilities written to packages.xml are properly
        // assigned to the packages installed above; it's possible immediately after a package
        // install the capabilities are as declared, but then during the reboot shared signing
        // keys also share the initial declared capabilities.
        getDevice().reboot();

        // This app is signed with the original shared signing key in the lineage and is part of the
        // sharedUserId; since the other app in this sharedUserId has granted the required
        // capability in the lineage the install should succeed.
        assertInstallFromBuildSucceeds("v3-ec-p256-1-sharedUid-companion2.apk");
        // This app is signed with the original shared signing key in the lineage and requests the
        // signature permission declared by the test app above. Since that app granted the
        // PERMISSION capability to the previous signer in the lineage this app should have the
        // permission granted.
        assertInstallFromBuildSucceeds("v3-ec-p256-1-companion-usesperm.apk");
        Utils.runDeviceTests(getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS, "testHasPerm");
    }

    @CddTest(requirement="4/C-0-2")
    @Test
    public void testV31TargetTPlatformUsesRotatedKey() throws Exception {
        // The v3.1 signature block is intended to allow applications to target T+ for APK signing
        // key rotation without needing multi-targeting APKs. This test verifies a standard APK
        // install with the rotated key in the v3.1 signing block targeting T is recognized by the
        // platform, and this rotated key is used as the signing identity.
        assertInstallSucceeds("v31-ec-p256_2-tgt-33.apk");
        Utils.runDeviceTests(
                getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS,
                "testUsingRotatedSigner");
    }

    @CddTest(requirement="4/C-0-2")
    @Test
    public void testV31TargetLaterThanDevicePlatformUsesOriginalKey() throws Exception {
        // The v3.1 signature block allows targeting SDK versions later than T for rotation; for
        // this test a target of 100001 is used assuming it will be beyond the platform's version.
        // Since the target version for rotation is beyond the platform's version the original
        // signer from the v3.0 block should be used.
        assertInstallSucceeds("v31-ec-p256_2-tgt-100001.apk");
        Utils.runDeviceTests(
                getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS,
                "testUsingOriginalSigner");
    }

    @CddTest(requirement="4/C-0-2")
    @Test
    public void testV31SignersTargetPAnd100001PlatformUsesTargetPSigner() throws Exception {
        // The v3.1 signature scheme allows signer configs to target SDK versions; if a rotated
        // signer config is targeting P, the v3.0 block will include a signature with that rotated
        // config. This test verifies when the v3.1 signer is targeting an SDK version beyond that
        // of the platform's, the rotated signing config from the v3.0 block is used by the
        // platform.
        assertInstallSucceeds("v31-ec-p256_2-tgt-28-ec-p256_3-tgt-100001.apk");
        Utils.runDeviceTests(
                getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS,
                "testUsingRotatedSigner");
    }

    @CddTest(requirement="4/C-0-2")
    @Test
    public void testV31BlockStrippedWithV3StrippingProtectionAttrSet() throws Exception {
        // With the introduction of the v3.1 signature scheme, a new stripping protection attribute
        // has been added to the v3.0 signer to protect against stripping and modification of the
        // v3.1 signing block. This test verifies a stripped v3.1 block is detected when the v3.0
        // stripping protection attribute is set.
        assertInstallFails("v31-block-stripped-v3-attr-value-33.apk");
    }

    @CddTest(requirement="4/C-0-2")
    @Test
    public void testV31BlockWithMultipleSignersUsesCorrectSigner() throws Exception {
        // All of the APKs for this test use multiple v3.1 signers; those targeting SDK versions
        // expected to be outside the version of a device under test use the original signer, and
        // those targeting an expected range for a device use the rotated key. This test is
        // intended to ensure the signer with the min / max SDK version that matches the device
        // SDK version is used.

        // The APK used for this test contains two signers in the v3.1 signing block. The first
        // has a range from 100001 to Integer.MAX_VALUE and is using the original signing key;
        // the second targets 33 to 100000 using the rotated key.
        assertInstallSucceeds("v31-ec-p256_2-tgt-33-ec-p256-tgt-100001.apk");
        Utils.runDeviceTests(
                getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS,
                "testUsingRotatedSigner");
        uninstallPackage();

        // The APK for this test contains two signers in the v3.1 block, one targeting SDK versions
        // 1 to 27 using the original signer, and the other targeting 33+ using the rotated signer.
        assertInstallSucceeds("v31-ec-p256_2-tgt-33-ec-p256-tgt-1-27.apk");
        Utils.runDeviceTests(
                getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS,
                "testUsingRotatedSigner");
        uninstallPackage();

        // This APK combines the extra signers from the APKs above, one targeting 1 to 27 with the
        // original signing key, another targeting 100001+ with the original signing key, and the
        // last targeting 33 to 100000 with the rotated key.
        assertInstallSucceeds("v31-ec-p256_2-tgt-33-ec-p256-tgt-1-27-and-100001.apk");
        Utils.runDeviceTests(
                getDevice(), DEVICE_TESTS_PKG, DEVICE_TESTS_CLASS,
                "testUsingRotatedSigner");
    }

    @CddTest(requirement="4/C-0-2")
    @Test
    public void testV31UpdateV3ToFromV31Succeeds() throws Exception {
        // Since the v3.1 block is just intended to allow targeting SDK versions T and later for
        // rotation, an APK signed with the rotated key in a v3.0 signing block should support
        // updates to an APK signed with the same signing key in a v3.1 signing block.
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-default-caps.apk");
        assertInstallSucceeds("v31-ec-p256_2-tgt-33.apk");
        uninstallPackage();

        // Similarly an APK signed with the rotated key in a v3.1 signing block should support
        // updates to an APK signed with the same signing key in a v3.0 signing block.
        assertInstallSucceeds("v31-ec-p256_2-tgt-33.apk");
        assertInstallFromBuildSucceeds("v3-ec-p256-with-por_1_2-default-caps.apk");
        uninstallPackage();
    }

    @CddTest(requirement="4/C-0-2")
    @Test
    public void testV31RotationTargetModifiedReportedByV3() throws Exception {
        // When determining if a signer in the v3.1 signing block should be applied, the min / max
        // SDK versions from the signer are compared against the device's SDK version; if the device
        // is not within the signer's range then the block is skipped, other v3.1 blocks are
        // checked, and finally the v3.0 block is used. The v3.0 signer block contains an additional
        // attribute with the rotation-min-sdk-version that was expected in the v3.1 signing
        // block; if this attribute's value does not match what was found in the v3.1 block the
        // APK should fail to install.
        assertInstallFails("v31-ec-p256_2-tgt-33-modified.apk");
    }

    @CddTest(requirement="4/C-0-2")
    @Test
    public void testV31RotationTargetsDevRelease() throws Exception {
        // The v3.1 signature scheme allows targeting a platform release under development through
        // the use of a rotation-targets-dev-release additional attribute. Since a platform under
        // development shares the same SDK version as the most recently released platform, the
        // attribute is used by the platform to determine if a signer block should be applied. If
        // the signer's minSdkVersion is the same as the device's SDK version and this attribute
        // is set, then the platform will check the value of ro.build.version.codename; a value of
        // "REL" indicates the platform is a release platform, so the current signer block will not
        // be used. During T's development, the SDK version is 31 and the codename is not "REL", so
        // this test APK will install on T during development as well as after its release since
        // the SDK version will be bumped at that point.
        assertInstallSucceeds("v31-ec-p256_2-tgt-31-dev-release.apk");
    }

    @Test
    public void testInstallTargetSdk30WithV1Signers() throws Exception {
        // An app targeting SDK version >= 30 must have at least a V2 signature; this test verifies
        // an app targeting SDK version 30 with only a V1 signature fails to install.
        assertInstallFails("v1-ec-p256-two-signers-targetSdk-30.apk");
    }

    @Test
    public void testInstallTargetSdk30WithV1V2Signers() throws Exception {
        // An app targeting SDK version >= 30 must have at least a V2 signature; this test verifies
        // that an app targeting SDK version 30 with both a V1 and V2 signature installs
        // successfully.
        installApkFromBuild("v1v2-ec-p256-two-signers-targetSdk-30.apk");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithV2Signer(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // APK generated with:
        // apksigner sign --v2-signing-enabled true --v3-signing-enabled false --v4-signing-enabled
        assertInstallV4Succeeds("v4-digest-v2.apk");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithV3Signer(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // APK generated with:
        // apksigner sign --v2-signing-enabled false --v3-signing-enabled true --v4-signing-enabled
        assertInstallV4Succeeds("v4-digest-v3.apk");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithV2V3Signer(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // APK generated with:
        // apksigner sign --v2-signing-enabled true --v3-signing-enabled true --v4-signing-enabled
        assertInstallV4Succeeds("v4-digest-v2v3.apk");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithV2NoVeritySigner(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // APK generated with:
        // --v2-signing-enabled true --v3-signing-enabled false --v4-signing-enabled
        // Full commands in generate-apks.sh
        assertInstallV4SucceedsAndUninstall("v4-digest-v2-Sha256withDSA.apk");
        assertInstallV4SucceedsAndUninstall("v4-digest-v2-Sha256withEC.apk");
        assertInstallV4SucceedsAndUninstall("v4-digest-v2-Sha256withRSA.apk");
        assertInstallV4SucceedsAndUninstall("v4-digest-v2-Sha512withEC.apk");
        assertInstallV4SucceedsAndUninstall("v4-digest-v2-Sha512withRSA.apk");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithV2VeritySigner(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // APK generated with:
        // --v2-signing-enabled true --v3-signing-enabled false
        // --v4-signing-enabled --verity-enabled
        // Full commands in generate-apks.sh
        assertInstallV4SucceedsAndUninstall("v4-digest-v2-Sha256withDSA-Verity.apk");
        assertInstallV4SucceedsAndUninstall("v4-digest-v2-Sha256withEC-Verity.apk");
        assertInstallV4SucceedsAndUninstall("v4-digest-v2-Sha256withRSA-Verity.apk");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithV3NoVeritySigner(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // APK generated with:
        // --v2-signing-enabled false --v3-signing-enabled true --v4-signing-enabled
        // Full commands in generate-apks.sh
        assertInstallV4SucceedsAndUninstall("v4-digest-v3-Sha256withDSA.apk");
        assertInstallV4SucceedsAndUninstall("v4-digest-v3-Sha256withEC.apk");
        assertInstallV4SucceedsAndUninstall("v4-digest-v3-Sha256withRSA.apk");
        assertInstallV4SucceedsAndUninstall("v4-digest-v3-Sha512withEC.apk");
        assertInstallV4SucceedsAndUninstall("v4-digest-v3-Sha512withRSA.apk");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithV3VeritySigner(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // APK generated with:
        // --v2-signing-enabled false --v3-signing-enabled true
        // --v4-signing-enabled --verity-enabled
        // Full commands in generate-apks.sh
        assertInstallV4SucceedsAndUninstall("v4-digest-v3-Sha256withDSA-Verity.apk");
        assertInstallV4SucceedsAndUninstall("v4-digest-v3-Sha256withEC-Verity.apk");
        assertInstallV4SucceedsAndUninstall("v4-digest-v3-Sha256withRSA-Verity.apk");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithV2SignerDoesNotVerify(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // APKs generated with:
        // apksigner sign -v2-signing-enabled true --v3-signing-enabled false --v4-signing-enabled

        // Malformed v4 signature - first byte of v4 signing_info.signature is flipped
        assertInstallV4FailsWithError("v4-digest-v2-badv4signature.apk", "did not verify");
        // Malformed digest - first byte of v4 signing_info.apk_digest is flipped
        assertInstallV4FailsWithError("v4-digest-v2-badv2digest.apk", "did not verify");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithV3SignerDoesNotVerify(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // APKs generated with:
        // apksigner sign -v2-signing-enabled false --v3-signing-enabled true --v4-signing-enabled

        // Malformed v4 signature - first byte of v4 signing_info.signature is flipped
        assertInstallV4FailsWithError("v4-digest-v3-badv4signature.apk", "did not verify");

        // Malformed digest - first byte of v4 signing_info.apk_digest is flipped
        assertInstallV4FailsWithError("v4-digest-v3-badv3digest.apk", "did not verify");

    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithV2V3SignerDoesNotVerify(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // APKs generated with:
        // apksigner sign -v2-signing-enabled true --v3-signing-enabled true --v4-signing-enabled

        // Malformed v4 signature - first byte of v4 signing_info.signature is flipped
        assertInstallV4FailsWithError("v4-digest-v2v3-badv4signature.apk", "did not verify");

        // Malformed digest - first byte of v4 signing_info.apk_digest is flipped
        assertInstallV4FailsWithError("v4-digest-v2v3-badv2v3digest.apk", "did not verify");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4With128BytesAdditionalDataSucceeds(boolean onIncremental)
            throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // Editing apksigner to fill additional data of size 128 bytes.
        assertInstallV4Succeeds("v4-digest-v3-128bytes-additional-data.apk");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4With256BytesAdditionalDataFails(boolean onIncremental)
            throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // Editing apksigner to fill additional data of size 256 bytes.
        if (onIncremental) {
            // For incremental, a bad Merkle tree will fail.
            assertInstallV4FailsWithError("v4-digest-v3-256bytes-additional-data.apk",
                    "additionalData has to be at most 128 bytes");
        } else {
            // For non-incremental, Merkle tree in idsig is not used.
            assertInstallV4Succeeds("v4-digest-v3-256bytes-additional-data.apk");
        }
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4With10MBytesAdditionalDataFails(boolean onIncremental)
            throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // Editing apksigner to fill additional data of size 10 * 1024 * 1024 bytes.
        if (onIncremental) {
            // For incremental, a bad Merkle tree will fail.
            assertInstallV4FailsWithError("v4-digest-v3-10mbytes-additional-data.apk",
                    "Failure");
        } else {
            // For non-incremental, Merkle tree in idsig is not used.
            assertInstallV4Succeeds("v4-digest-v3-10mbytes-additional-data.apk");
        }
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithWrongBlockSize(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // Editing apksigner with the wrong block size in the v4 signature.
        assertInstallV4FailsWithError("v4-digest-v3-wrong-block-size.apk",
                "did not verify");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithDifferentBlockSize(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // Editing apksigner with the different block size (2048 instead of 4096).
        assertInstallV4FailsWithError("v4-digest-v3-merkle-tree-different-block-size.apk",
                "Unsupported log2BlockSize: 11");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithWrongRawRootHash(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // Editing apksigner with the wrong raw root hash in the v4 signature.
        assertInstallV4FailsWithError("v4-digest-v3-wrong-raw-root-hash.apk", "Failure");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithWrongSignatureBytes(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // Editing apksigner with the wrong signature bytes in the v4 signature.
        assertInstallV4FailsWithError("v4-digest-v3-wrong-sig-bytes.apk",
                "did not verify");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithWrongSignatureBytesSize(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // Editing apksigner with the wrong signature byte size in the v4 signature.
        assertInstallV4FailsWithError("v4-digest-v3-wrong-sig-bytes-size.apk",
                "Failure");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithNoMerkleTree(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        if (onIncremental) {
            // Editing apksigner to not include the Merkle tree.
            assertInstallV4FailsWithError("v4-digest-v3-no-merkle-tree.apk",
                    "Failure");
        } else {
            assertInstallV4Succeeds("v4-digest-v3-no-merkle-tree.apk");
        }
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithWithTrailingDataInMerkleTree(boolean onIncremental)
            throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // Editing apksigner to add trailing data after the Merkle tree.
        if (onIncremental) {
            // For incremental, a bad Merkle tree will fail.
            assertInstallV4FailsWithError("v4-digest-v3-merkle-tree-1mb-trailing-data.apk",
                    "Failure");
        } else {
            // For non-incremental, Merkle tree in idsig is not used.
            assertInstallV4Succeeds("v4-digest-v3-merkle-tree-1mb-trailing-data.apk");
        }
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4WithMerkleTreeBitsFlipped(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // Editing apksigner to flip few bits in the only node of the Merkle tree of a small app.
        if (onIncremental) {
            // For incremental, a bad Merkle tree will fail.
            assertInstallV4FailsWithError("v4-digest-v3-merkle-tree-bit-flipped.apk",
                    "Failed to parse");
        } else {
            // For non-incremental, Merkle tree in idsig is not used.
            assertInstallV4Succeeds("v4-digest-v3-merkle-tree-bit-flipped.apk");
        }
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testV4IncToV3NonIncSameKeyUpgradeSucceeds(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // See cts/hostsidetests/appsecurity/res/pkgsigverify/generate-apks.sh for the command
        // to generate the apks
        assertInstallV4Succeeds("v4-inc-to-v3-noninc-ec-p256-appv1.apk");

        // non-incremental upgrade with the same key.
        assertInstallSucceeds("v4-inc-to-v3-noninc-ec-p256-appv2.apk");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testV4IncToV3NonIncMismatchingKeyUpgradeFails(boolean onIncremental)
            throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // See cts/hostsidetests/appsecurity/res/pkgsigverify/generate-apks.sh for the command
        // to generate the apks
        assertInstallV4Succeeds("v4-inc-to-v3-noninc-ec-p256-appv1.apk");

        // non-incremental upgrade with a mismatching key.
        assertInstallFailsWithError("v4-inc-to-v3-noninc-ec-p384-appv2.apk",
                "signatures do not match newer version");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testV4IncToV3NonIncRotatedKeyUpgradeSucceeds(boolean onIncremental)
            throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // See cts/hostsidetests/appsecurity/res/pkgsigverify/generate-apks.sh for the command
        // to generate the apks
        assertInstallV4Succeeds("v4-inc-to-v3-noninc-ec-p256-appv1.apk");

        // non-incremental upgrade with key rotation.
        assertInstallSucceeds("v4-inc-to-v3-noninc-ec-p384-rotated-ec-p256-appv2.apk");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testV4IncToV3NonIncMismatchedRotatedKeyUpgradeFails(boolean onIncremental)
            throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // See cts/hostsidetests/appsecurity/res/pkgsigverify/generate-apks.sh for the command
        // to generate the apks
        assertInstallV4Succeeds("v4-inc-to-v3-noninc-dsa-3072-appv1.apk");

        // non-incremental upgrade with key rotation mismatch with key used in app v1.
        assertInstallFailsWithError("v4-inc-to-v3-noninc-ec-p384-rotated-ec-p256-appv2.apk",
                "signatures do not match newer version");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testV4IncToV2NonIncSameKeyUpgradeSucceeds(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // See cts/hostsidetests/appsecurity/res/pkgsigverify/generate-apks.sh for the command
        // to generate the apks
        assertInstallV4Succeeds("v4-inc-to-v2-noninc-ec-p256-appv1.apk");

        // non-incremental upgrade with the same key.
        assertInstallSucceeds("v4-inc-to-v2-noninc-ec-p256-appv2.apk");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testV4IncToV2NonIncMismatchingKeyUpgradeFails(boolean onIncremental)
            throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // See cts/hostsidetests/appsecurity/res/pkgsigverify/generate-apks.sh for the command
        // to generate the apks
        assertInstallV4Succeeds("v4-inc-to-v2-noninc-ec-p256-appv1.apk");

        // non-incremental upgrade with a mismatching key.
        assertInstallFailsWithError("v4-inc-to-v2-noninc-ec-p384-appv2.apk",
                "signatures do not match newer version");
    }

    @Test
    @Parameters(method = "installOnIncremental")
    public void testInstallV4UpdateAfterRotation(boolean onIncremental) throws Exception {
        checkAssumptionAndSetIdsigInstallMode(onIncremental);

        // This test performs an end to end verification of the update of an app with a rotated
        // key. The app under test exports a bound service that performs its own PackageManager key
        // rotation API verification, and the instrumentation test binds to the service and invokes
        // the verifySignatures method to verify that the key rotation APIs return the expected
        // results. The instrumentation test app is signed with the same key and lineage as the
        // app under test to also provide a second app that can be used for the checkSignatures
        // verification.

        // Install the initial versions of the apps; the test method verifies the app under test is
        // signed with the original signing key.
        assertInstallV4FromBuildSucceeds("CtsSignatureQueryService.apk");
        assertInstallV4FromBuildSucceeds("CtsSignatureQueryServiceTest.apk");
        Utils.runDeviceTests(getDevice(), SERVICE_TEST_PKG, SERVICE_TEST_CLASS,
                "verifySignatures_noRotation_succeeds");

        // Install the second version of the app signed with the rotated key. This test verifies the
        // app still functions as expected after the update with the rotated key. The
        // instrumentation test app is not updated here to allow verification of the pre-key
        // rotation behavior for the checkSignatures APIs. These APIs should behave similar to the
        // GET_SIGNATURES flag in that if one or both apps have a signing lineage if the oldest
        // signers in the lineage match then the methods should return that the signatures match
        // even if one is signed with a newer key in the lineage.
        assertInstallV4FromBuildSucceeds("CtsSignatureQueryService_v2.apk");
        Utils.runDeviceTests(getDevice(), SERVICE_TEST_PKG, SERVICE_TEST_CLASS,
                "verifySignatures_withRotation_succeeds");

        // Installs the third version of the app under test and the instrumentation test, both
        // signed with the same rotated key and lineage. This test is intended to verify that the
        // app can still be updated and function as expected after an update with a rotated key.
        assertInstallV4FromBuildSucceeds("CtsSignatureQueryService_v3.apk");
        assertInstallV4FromBuildSucceeds("CtsSignatureQueryServiceTest_v2.apk");
        Utils.runDeviceTests(getDevice(), SERVICE_TEST_PKG, SERVICE_TEST_CLASS,
                "verifySignatures_withRotation_succeeds");
    }

    private boolean hasIncrementalFeature() throws Exception {
        return "true\n".equals(getDevice().executeShellCommand(
                "pm has-feature android.software.incremental_delivery"));
    }

    private void checkAssumptionAndSetIdsigInstallMode(boolean onIncremental) throws Exception {
        // Due to the limitation of existing test runners (i.e. DeviceParameterizedRunner and
        // DeviceJUnit4Parameterized), there's no easy way to parameterize only some of the test
        // methods while avoid recording the parameter manually.
        mUseIncrementalForInstallWithIdsig = onIncremental;

        if (onIncremental) {
            // V4 is only enabled on devices with Incremental feature
            assumeTrue(hasIncrementalFeature());
        } else {
            // Install V4 in classic install session
            assumeTrue(android.security.Flags.extendVbChainToUpdatedApk());
        }
    }

    private void assertInstallSucceeds(String apkFilenameInResources) throws Exception {
        String installResult = installPackageFromResource(apkFilenameInResources);
        if (installResult != null) {
            fail("Failed to install " + apkFilenameInResources + ": " + installResult);
        }
    }

    private void assertInstallEphemeralSucceeds(String apkFilenameInResources) throws Exception {
        String installResult = installEphemeralPackageFromResource(apkFilenameInResources);
        if (installResult != null) {
            fail("Failed to install " + apkFilenameInResources + ": " + installResult);
        }
    }

    private void assertInstallSucceedsForEach(
            String apkFilenamePatternInResources, String[] args) throws Exception {
        for (String arg : args) {
            String apkFilenameInResources =
                    String.format(Locale.US, apkFilenamePatternInResources, arg);
            String installResult = installPackageFromResource(apkFilenameInResources);
            if (installResult != null) {
                fail("Failed to install " + apkFilenameInResources + ": " + installResult);
            }
            try {
                uninstallPackage();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Failed to uninstall after installing " + apkFilenameInResources, e);
            }
        }
    }

    private void assertInstallV4Succeeds(String apkFilenameInResources) throws Exception {
        String installResult = installV4PackageFromResource(apkFilenameInResources);
        if (!installResult.equals("Success")) {
            fail("Failed to install " + apkFilenameInResources + ": " + installResult);
        }
    }

    private void assertInstallV4FromBuildSucceeds(String apkName) throws Exception {
        String installResult = installV4PackageFromBuild(apkName);
        if (!installResult.equals("Success")) {
            fail("Failed to install " + apkName + ": " + installResult);
        }
    }

    private void assertInstallV4SucceedsAndUninstall(String apkFilenameInResources)
            throws Exception {
        assertInstallV4Succeeds(apkFilenameInResources);
        try {
            uninstallPackage();
        } catch (Exception e) {
            throw new RuntimeException(
                    "Failed to uninstall after installing " + apkFilenameInResources, e);
        }
    }

    private void assertInstallV4FailsWithError(String apkFilenameInResources, String errorSubstring)
            throws Exception {
        String installResult = installV4PackageFromResource(apkFilenameInResources);
        if (installResult.equals("Success")) {
            fail("Install of " + apkFilenameInResources + " succeeded but was expected to fail"
                    + " with \"" + errorSubstring + "\"");
        }
        assertContains(
                "Install failure message of " + apkFilenameInResources,
                errorSubstring,
                installResult);
    }

    private void assertInstallFailsWithError(
            String apkFilenameInResources, String errorSubstring) throws Exception {
        String installResult = installPackageFromResource(apkFilenameInResources);
        if (installResult == null) {
            fail("Install of " + apkFilenameInResources + " succeeded but was expected to fail"
                    + " with \"" + errorSubstring + "\"");
        }
        assertContains(
                "Install failure message of " + apkFilenameInResources,
                errorSubstring,
                installResult);
    }

    private void assertInstallEphemeralFailsWithError(
            String apkFilenameInResources, String errorSubstring) throws Exception {
        String installResult = installEphemeralPackageFromResource(apkFilenameInResources);
        if (installResult == null) {
            fail("Install of " + apkFilenameInResources + " succeeded but was expected to fail"
                    + " with \"" + errorSubstring + "\"");
        }
        assertContains(
                "Install failure message of " + apkFilenameInResources,
                errorSubstring,
                installResult);
    }

    private void assertInstallFails(String apkFilenameInResources) throws Exception {
        String installResult = installPackageFromResource(apkFilenameInResources);
        if (installResult == null) {
            fail("Install of " + apkFilenameInResources + " succeeded but was expected to fail");
        }
    }

    private static void assertContains(String message, String expectedSubstring, String actual) {
        String errorPrefix = ((message != null) && (message.length() > 0)) ? (message + ": ") : "";
        if (actual == null) {
            fail(errorPrefix + "Expected to contain \"" + expectedSubstring + "\", but was null");
        }
        if (!actual.contains(expectedSubstring)) {
            fail(errorPrefix + "Expected to contain \"" + expectedSubstring + "\", but was \""
                    + actual + "\"");
        }
    }

    private void installDeviceTestPkg() throws Exception {
        assertInstallFromBuildSucceeds(DEVICE_TESTS_APK);
    }

    private void assertInstallFromBuildSucceeds(String apkName) throws Exception {
        String result = installApkFromBuild(apkName);
        assertNull("failed to install " + apkName + ", Reason: " + result, result);
    }

    private void assertInstallFromBuildFails(String apkName) throws Exception {
        String result = installApkFromBuild(apkName);
        assertNotNull("Successfully installed " + apkName + " when failure was expected", result);
    }

    private String installApkFromBuild(String apkName) throws Exception {
        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
        File apk = buildHelper.getTestFile(apkName);
        try {
            return getDevice().installPackage(apk, true, INSTALL_ARG_FORCE_QUERYABLE);
        } finally {
            getDevice().deleteFile("/data/local/tmp/" + apk.getName());
        }
    }

    private String installPackageFromResource(String apkFilenameInResources, boolean ephemeral)
            throws IOException, DeviceNotAvailableException {
        // ITestDevice.installPackage API requires the APK to be install to be a File. We thus
        // copy the requested resource into a temporary file, attempt to install it, and delete the
        // file during cleanup.
        File apkFile = null;
        try {
            apkFile = getFileFromResource(apkFilenameInResources);
            if (ephemeral) {
                return getDevice().installPackage(apkFile, true, "--ephemeral",
                        INSTALL_ARG_FORCE_QUERYABLE);
            } else {
                return getDevice().installPackage(apkFile, true, INSTALL_ARG_FORCE_QUERYABLE);
            }
        } finally {
            cleanUpFile(apkFile);
            getDevice().deleteFile("/data/local/tmp/" + apkFile.getName());
        }
    }

    private String installV4PackageFromResource(String apkFilenameInResources)
            throws IOException, DeviceNotAvailableException {
        File apkFile = null;
        File v4SignatureFile = null;
        String remoteApkFilePath = null, remoteV4SignaturePath = null;
        try {
            apkFile = getFileFromResource(apkFilenameInResources);
            v4SignatureFile = getFileFromResource(apkFilenameInResources + ".idsig");
            remoteApkFilePath = pushFileToRemote(apkFile);
            remoteV4SignaturePath = pushFileToRemote(v4SignatureFile);
            return installV4Package(remoteApkFilePath);
        } finally {
            cleanUpFile(apkFile);
            cleanUpFile(v4SignatureFile);
            getDevice().deleteFile(remoteApkFilePath);
            getDevice().deleteFile(remoteV4SignaturePath);
        }
    }

    private String installV4PackageFromBuild(String apkName)
            throws IOException, DeviceNotAvailableException {
        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
        File apkFile = buildHelper.getTestFile(apkName);
        File v4SignatureFile = buildHelper.getTestFile(apkName + ".idsig");
        String remoteApkFilePath = pushFileToRemote(apkFile);
        String remoteV4SignaturePath = pushFileToRemote(v4SignatureFile);
        try {
            return installV4Package(remoteApkFilePath);
        } finally {
            getDevice().deleteFile(remoteApkFilePath);
            getDevice().deleteFile(remoteV4SignaturePath);
        }
    }

    private String pushFileToRemote(File localFile) throws DeviceNotAvailableException {
        String remotePath = "/data/local/tmp/pkginstalltest-" + localFile.getName();
        getDevice().pushFile(localFile, remotePath);
        return remotePath;
    }

    private String installV4Package(String remoteApkPath)
            throws DeviceNotAvailableException {
        var installer = new InstallMultiple();
        if (mUseIncrementalForInstallWithIdsig) {
            installer.useIncremental();
        } else {
            // Add to the install session
            installer.addRemoteFile(remoteApkPath + ".idsig");
        }
        return installer
            .forceQueryable()
            .addRemoteFile(remoteApkPath)
            .runForResult();
    }

    private File getFileFromResource(String filenameInResources)
            throws IOException, IllegalArgumentException {
        String fullResourceName = TEST_APK_RESOURCE_PREFIX + filenameInResources;
        File tempDir = FileUtil.createTempDir("pkginstalltest");
        File file = new File(tempDir, filenameInResources);
        InputStream in = getClass().getResourceAsStream(fullResourceName);
        if (in == null) {
            throw new IllegalArgumentException("Resource not found: " + fullResourceName);
        }
        OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
        byte[] buf = new byte[65536];
        int chunkSize;
        while ((chunkSize = in.read(buf)) != -1) {
            out.write(buf, 0, chunkSize);
        }
        out.close();
        return file;
    }

    private void cleanUpFile(File file) {
        if (file != null && file.exists()) {
            file.delete();
            // Delete the parent dir as well which is a temp dir
            File parent = file.getParentFile();
            if (parent.exists()) {
                parent.delete();
            }
        }
    }

    private String installPackageFromResource(String apkFilenameInResources)
            throws IOException, DeviceNotAvailableException {
        return installPackageFromResource(apkFilenameInResources, false);
    }

    private String installEphemeralPackageFromResource(String apkFilenameInResources)
            throws IOException, DeviceNotAvailableException {
        return installPackageFromResource(apkFilenameInResources, true);
    }

    private String uninstallPackage() throws DeviceNotAvailableException {
        String result1 = getDevice().uninstallPackage(TEST_PKG);
        String result2 = getDevice().uninstallPackage(TEST_PKG2);
        return result1 != null ? result1 : result2;
    }

    private String uninstallCompanionPackages() throws DeviceNotAvailableException {
        String result1 = getDevice().uninstallPackage(COMPANION_TEST_PKG);
        String result2 = getDevice().uninstallPackage(COMPANION2_TEST_PKG);
        String result3 = getDevice().uninstallPackage(COMPANION3_TEST_PKG);
        return Stream.of(result1, result2, result3)
                .filter(Objects::nonNull)
                .findFirst()
                .orElse(null);
    }

    private String uninstallDeviceTestPackage() throws DeviceNotAvailableException {
        return getDevice().uninstallPackage(DEVICE_TESTS_PKG);
    }

    private void uninstallServicePackages() throws DeviceNotAvailableException {
        getDevice().uninstallPackage(SERVICE_PKG);
        getDevice().uninstallPackage(SERVICE_TEST_PKG);
    }

    private void uninstallPackages() throws DeviceNotAvailableException {
        uninstallPackage();
        uninstallCompanionPackages();
        uninstallDeviceTestPackage();
        uninstallServicePackages();
    }

    private class InstallMultiple extends BaseInstallMultiple<InstallMultiple> {
        InstallMultiple() {
            super(getDevice(), getBuild(), getAbi(), /* grantPermissions */ true);
        }

        @Override
        protected String deriveRemoteName(String originalName, int index) {
            return originalName;
        }
    }
}
