/*
 * 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 android.platform.test.annotations.AsbSecurityTest;

import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.testtype.DeviceTestCase;
import com.android.tradefed.testtype.IBuildReceiver;
import com.android.tradefed.util.FileUtil;

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;

/**
 * Tests for APK signature verification during installation.
 */
public class PkgInstallSignatureVerificationTest extends DeviceTestCase implements IBuildReceiver {

    private static final String TEST_PKG = "android.appsecurity.cts.tinyapp";
    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 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 IBuildInfo mCtsBuild;

    @Override
    public void setBuild(IBuildInfo buildInfo) {
        mCtsBuild = buildInfo;
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        Utils.prepareSingleUser(getDevice());
        assertNotNull(mCtsBuild);
        uninstallPackage();
        uninstallCompanionPackages();
        installDeviceTestPkg();
    }

    @Override
    protected void tearDown() throws Exception {
        try {
            uninstallPackages();
        } catch (DeviceNotAvailableException ignored) {
        } finally {
            super.tearDown();
        }
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    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.
//    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);
//    }
//
//    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);
//    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    public void testInstallMaxSizedZipEocdComment() throws Exception {
        // Obtained by modifying apksigner to produce a max-sized (0xffff bytes long) ZIP End of
        // Central Directory comment, and signing the original.apk using the modified apksigner.
        assertInstallSucceeds("v1-only-max-sized-eocd-comment.apk");
        assertInstallSucceeds("v2-only-max-sized-eocd-comment.apk");
    }

    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
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

    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 the
        // installation of this updated app 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");
        assertInstallFromBuildFails("v3-ec-p256-with-por_1_2-no-shUid-cap-sharedUid.apk");
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    public void testInstallV4WithV2Signer() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

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

    public void testInstallV4WithV3Signer() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

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

    public void testInstallV4WithV2V3Signer() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

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

    public void testInstallV4WithV2NoVeritySigner() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // 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");
    }

    public void testInstallV4WithV2VeritySigner() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // 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");
    }

    public void testInstallV4WithV3NoVeritySigner() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // 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");
    }

    public void testInstallV4WithV3VeritySigner() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // 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");
    }

    public void testInstallV4WithV2SignerDoesNotVerify() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // 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");
    }

    public void testInstallV4WithV3SignerDoesNotVerify() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // 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");

    }

    public void testInstallV4WithV2V3SignerDoesNotVerify() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // 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");
    }

    public void testInstallV4With128BytesAdditionalDataSucceeds() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

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

    public void testInstallV4With256BytesAdditionalDataFails() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // Editing apksigner to fill additional data of size 256 bytes.
        assertInstallV4FailsWithError("v4-digest-v3-256bytes-additional-data.apk",
                "additionalData has to be at most 128 bytes");
    }

    public void testInstallV4With10MBytesAdditionalDataFails() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // Editing apksigner to fill additional data of size 10 * 1024 * 1024 bytes.
        assertInstallV4FailsWithError("v4-digest-v3-10mbytes-additional-data.apk",
                "Failure");
    }

    public void testInstallV4WithWrongBlockSize() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

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

    public void testInstallV4WithDifferentBlockSize() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

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

    public void testInstallV4WithWrongRawRootHash() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

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

    public void testInstallV4WithWrongSignatureBytes() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

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

    public void testInstallV4WithWrongSignatureBytesSize() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

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

    public void testInstallV4WithNoMerkleTree() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

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

    public void testInstallV4WithWithTrailingDataInMerkleTree() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // Editing apksigner to add trailing data after the Merkle tree
        assertInstallV4FailsWithError("v4-digest-v3-merkle-tree-1mb-trailing-data.apk",
                "Failure");
    }

    public void testInstallV4WithMerkleTreeBitsFlipped() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // Editing apksigner to flip few bits in the only node of the Merkle tree of a small app.
        assertInstallV4FailsWithError("v4-digest-v3-merkle-tree-bit-flipped.apk",
                "Failed to parse");
    }

    public void testV4IncToV3NonIncSameKeyUpgradeSucceeds() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // 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");
    }

    public void testV4IncToV3NonIncMismatchingKeyUpgradeFails() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // 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 previously installed version");
    }

    public void testV4IncToV3NonIncRotatedKeyUpgradeSucceeds() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // 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");
    }

    public void testV4IncToV3NonIncMismatchedRotatedKeyUpgradeFails() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // 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 previously installed version");
    }

    public void testV4IncToV2NonIncSameKeyUpgradeSucceeds() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // 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");
    }

    public void testV4IncToV2NonIncMismatchingKeyUpgradeFails() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // 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 previously installed version");
    }

    public void testInstallV4UpdateAfterRotation() throws Exception {
        // V4 is only enabled on devices with Incremental feature
        if (!hasIncrementalFeature()) {
            return;
        }

        // 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 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\n")) {
            fail("Failed to install " + apkFilenameInResources + ": " + installResult);
        }
    }

    private void assertInstallV4FromBuildSucceeds(String apkName) throws Exception {
        String installResult = installV4PackageFromBuild(apkName);
        if (!installResult.equals("Success\n")) {
            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\n")) {
            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(mCtsBuild);
        File apk = buildHelper.getTestFile(apkName);
        return getDevice().installPackage(apk, true, INSTALL_ARG_FORCE_QUERYABLE);
    }

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

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

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

    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 {
        String command = "pm install-incremental --force-queryable -t -g " + remoteApkPath;
        return getDevice().executeShellCommand(command);
    }

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

    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 {
        return getDevice().uninstallPackage(TEST_PKG);
    }

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

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