/*
 * 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 com.android.apksig;

import com.android.apksig.apk.ApkFormatException;
import com.android.apksig.apk.ApkUtils;
import com.android.apksig.internal.apk.AndroidBinXmlParser;
import com.android.apksig.internal.apk.v1.V1SchemeVerifier;
import com.android.apksig.internal.apk.v2.ContentDigestAlgorithm;
import com.android.apksig.internal.apk.v2.SignatureAlgorithm;
import com.android.apksig.internal.apk.v2.V2SchemeVerifier;
import com.android.apksig.internal.util.AndroidSdkVersion;
import com.android.apksig.internal.zip.CentralDirectoryRecord;
import com.android.apksig.util.DataSource;
import com.android.apksig.util.DataSources;
import com.android.apksig.zip.ZipFormatException;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * APK signature verifier which mimics the behavior of the Android platform.
 *
 * <p>The verifier is designed to closely mimic the behavior of Android platforms. This is to enable
 * the verifier to be used for checking whether an APK's signatures will verify on Android.
 *
 * <p>Use {@link Builder} to obtain instances of this verifier.
 *
 * @see <a href="https://source.android.com/security/apksigning/index.html">Application Signing</a>
 */
public class ApkVerifier {

    private static final int APK_SIGNATURE_SCHEME_V2_ID = 2;
    private static final Map<Integer, String> SUPPORTED_APK_SIG_SCHEME_NAMES =
            Collections.singletonMap(APK_SIGNATURE_SCHEME_V2_ID, "APK Signature Scheme v2");

    private final File mApkFile;
    private final DataSource mApkDataSource;

    private final Integer mMinSdkVersion;
    private final int mMaxSdkVersion;

    private ApkVerifier(
            File apkFile,
            DataSource apkDataSource,
            Integer minSdkVersion,
            int maxSdkVersion) {
        mApkFile = apkFile;
        mApkDataSource = apkDataSource;
        mMinSdkVersion = minSdkVersion;
        mMaxSdkVersion = maxSdkVersion;
    }

    /**
     * Verifies the APK's signatures and returns the result of verification. The APK can be
     * considered verified iff the result's {@link Result#isVerified()} returns {@code true}.
     * The verification result also includes errors, warnings, and information about signers.
     *
     * @throws IOException if an I/O error is encountered while reading the APK
     * @throws ApkFormatException if the APK is malformed
     * @throws NoSuchAlgorithmException if the APK's signatures cannot be verified because a
     *         required cryptographic algorithm implementation is missing
     * @throws IllegalStateException if this verifier's configuration is missing required
     *         information.
     */
    public Result verify() throws IOException, ApkFormatException, NoSuchAlgorithmException,
            IllegalStateException {
        Closeable in = null;
        try {
            DataSource apk;
            if (mApkDataSource != null) {
                apk = mApkDataSource;
            } else if (mApkFile != null) {
                RandomAccessFile f = new RandomAccessFile(mApkFile, "r");
                in = f;
                apk = DataSources.asDataSource(f, 0, f.length());
            } else {
                throw new IllegalStateException("APK not provided");
            }
            return verify(apk);
        } finally {
            if (in != null) {
                in.close();
            }
        }
    }

    /**
     * Verifies the APK's signatures and returns the result of verification. The APK can be
     * considered verified iff the result's {@link Result#isVerified()} returns {@code true}.
     * The verification result also includes errors, warnings, and information about signers.
     *
     * @param apk APK file contents
     *
     * @throws IOException if an I/O error is encountered while reading the APK
     * @throws ApkFormatException if the APK is malformed
     * @throws NoSuchAlgorithmException if the APK's signatures cannot be verified because a
     *         required cryptographic algorithm implementation is missing
     */
    private Result verify(DataSource apk)
            throws IOException, ApkFormatException, NoSuchAlgorithmException {
        if (mMinSdkVersion != null) {
            if (mMinSdkVersion < 0) {
                throw new IllegalArgumentException(
                        "minSdkVersion must not be negative: " + mMinSdkVersion);
            }
            if ((mMinSdkVersion != null) && (mMinSdkVersion > mMaxSdkVersion)) {
                throw new IllegalArgumentException(
                        "minSdkVersion (" + mMinSdkVersion + ") > maxSdkVersion (" + mMaxSdkVersion
                                + ")");
            }
        }
        int maxSdkVersion = mMaxSdkVersion;

        ApkUtils.ZipSections zipSections;
        try {
            zipSections = ApkUtils.findZipSections(apk);
        } catch (ZipFormatException e) {
            throw new ApkFormatException("Malformed APK: not a ZIP archive", e);
        }

        Result result = new Result();

        // Android N and newer attempts to verify APK Signature Scheme v2 signature of the APK.
        // If the signature is not found, it falls back to JAR signature verification. If the
        // signature is found but does not verify, the APK is rejected.
        Set<Integer> foundApkSigSchemeIds;
        if (maxSdkVersion >= AndroidSdkVersion.N) {
            foundApkSigSchemeIds = new HashSet<>(1);
            try {
                V2SchemeVerifier.Result v2Result = V2SchemeVerifier.verify(apk, zipSections);
                foundApkSigSchemeIds.add(APK_SIGNATURE_SCHEME_V2_ID);
                result.mergeFrom(v2Result);
            } catch (V2SchemeVerifier.SignatureNotFoundException ignored) {}
            if (result.containsErrors()) {
                return result;
            }
        } else {
            foundApkSigSchemeIds = Collections.emptySet();
        }

        ByteBuffer androidManifest = null;

        int minSdkVersion;
        if (mMinSdkVersion != null) {
            // No need to obtain minSdkVersion from the APK's AndroidManifest.xml
            minSdkVersion = mMinSdkVersion;
        } else {
            // Need to obtain minSdkVersion from the APK's AndroidManifest.xml
            if (androidManifest == null) {
                androidManifest = getAndroidManifestFromApk(apk, zipSections);
            }
            minSdkVersion =
                    ApkUtils.getMinSdkVersionFromBinaryAndroidManifest(androidManifest.slice());
            if (minSdkVersion > mMaxSdkVersion) {
                throw new IllegalArgumentException(
                        "minSdkVersion from APK (" + minSdkVersion + ") > maxSdkVersion ("
                                + mMaxSdkVersion + ")");
            }
        }

        // Android O and newer requires that APKs targeting security sandbox version 2 and higher
        // are signed using APK Signature Scheme v2 or newer.
        if (maxSdkVersion >= AndroidSdkVersion.O) {
            if (androidManifest == null) {
                androidManifest = getAndroidManifestFromApk(apk, zipSections);
            }
            int targetSandboxVersion =
                    getTargetSandboxVersionFromBinaryAndroidManifest(androidManifest.slice());
            if (targetSandboxVersion > 1) {
                if (foundApkSigSchemeIds.isEmpty()) {
                    result.addError(
                            Issue.NO_SIG_FOR_TARGET_SANDBOX_VERSION,
                            targetSandboxVersion);
                }
            }
        }

        // Attempt to verify the APK using JAR signing if necessary. Platforms prior to Android N
        // ignore APK Signature Scheme v2 signatures and always attempt to verify JAR signatures.
        // Android N onwards verifies JAR signatures only if no APK Signature Scheme v2 (or newer
        // scheme) signatures were found.
        if ((minSdkVersion < AndroidSdkVersion.N) || (foundApkSigSchemeIds.isEmpty())) {
            V1SchemeVerifier.Result v1Result =
                    V1SchemeVerifier.verify(
                            apk,
                            zipSections,
                            SUPPORTED_APK_SIG_SCHEME_NAMES,
                            foundApkSigSchemeIds,
                            minSdkVersion,
                            maxSdkVersion);
            result.mergeFrom(v1Result);
        }
        if (result.containsErrors()) {
            return result;
        }

        // Check whether v1 and v2 scheme signer identifies match, provided both v1 and v2
        // signatures verified.
        if ((result.isVerifiedUsingV1Scheme()) && (result.isVerifiedUsingV2Scheme())) {
            ArrayList<Result.V1SchemeSignerInfo> v1Signers =
                    new ArrayList<>(result.getV1SchemeSigners());
            ArrayList<Result.V2SchemeSignerInfo> v2Signers =
                    new ArrayList<>(result.getV2SchemeSigners());
            ArrayList<ByteArray> v1SignerCerts = new ArrayList<>();
            ArrayList<ByteArray> v2SignerCerts = new ArrayList<>();
            for (Result.V1SchemeSignerInfo signer : v1Signers) {
                try {
                    v1SignerCerts.add(new ByteArray(signer.getCertificate().getEncoded()));
                } catch (CertificateEncodingException e) {
                    throw new RuntimeException(
                            "Failed to encode JAR signer " + signer.getName() + " certs", e);
                }
            }
            for (Result.V2SchemeSignerInfo signer : v2Signers) {
                try {
                    v2SignerCerts.add(new ByteArray(signer.getCertificate().getEncoded()));
                } catch (CertificateEncodingException e) {
                    throw new RuntimeException(
                            "Failed to encode APK Signature Scheme v2 signer (index: "
                                    + signer.getIndex() + ") certs",
                            e);
                }
            }

            for (int i = 0; i < v1SignerCerts.size(); i++) {
                ByteArray v1Cert = v1SignerCerts.get(i);
                if (!v2SignerCerts.contains(v1Cert)) {
                    Result.V1SchemeSignerInfo v1Signer = v1Signers.get(i);
                    v1Signer.addError(Issue.V2_SIG_MISSING);
                    break;
                }
            }
            for (int i = 0; i < v2SignerCerts.size(); i++) {
                ByteArray v2Cert = v2SignerCerts.get(i);
                if (!v1SignerCerts.contains(v2Cert)) {
                    Result.V2SchemeSignerInfo v2Signer = v2Signers.get(i);
                    v2Signer.addError(Issue.JAR_SIG_MISSING);
                    break;
                }
            }
        }
        if (result.containsErrors()) {
            return result;
        }

        // Verified
        result.setVerified();
        if (result.isVerifiedUsingV2Scheme()) {
            for (Result.V2SchemeSignerInfo signerInfo : result.getV2SchemeSigners()) {
                result.addSignerCertificate(signerInfo.getCertificate());
            }
        } else if (result.isVerifiedUsingV1Scheme()) {
            for (Result.V1SchemeSignerInfo signerInfo : result.getV1SchemeSigners()) {
                result.addSignerCertificate(signerInfo.getCertificate());
            }
        } else {
            throw new RuntimeException(
                    "APK considered verified, but has not verified using either v1 or v2 schemes");
        }

        return result;
    }

    private static ByteBuffer getAndroidManifestFromApk(
            DataSource apk, ApkUtils.ZipSections zipSections)
                    throws IOException, ApkFormatException {
        List<CentralDirectoryRecord> cdRecords =
                V1SchemeVerifier.parseZipCentralDirectory(apk, zipSections);
        try {
            return ApkSigner.getAndroidManifestFromApk(
                    cdRecords,
                    apk.slice(0, zipSections.getZipCentralDirectoryOffset()));
        } catch (ZipFormatException e) {
            throw new ApkFormatException("Failed to read AndroidManifest.xml", e);
        }
    }

    /**
     * Android resource ID of the {@code android:targetSandboxVersion} attribute in
     * AndroidManifest.xml.
     */
    private static final int TARGET_SANDBOX_VERSION_ATTR_ID = 0x0101054c;

    /**
     * Returns the security sandbox version targeted by an APK with the provided
     * {@code AndroidManifest.xml}.
     *
     * @param androidManifestContents contents of {@code AndroidManifest.xml} in binary Android
     *        resource format
     *
     * @throws ApkFormatException if an error occurred while determining the version
     */
    private static int getTargetSandboxVersionFromBinaryAndroidManifest(
            ByteBuffer androidManifestContents) throws ApkFormatException {
        // Return the value of the android:targetSandboxVersion attribute of the top-level manifest
        // element
        try {
            AndroidBinXmlParser parser = new AndroidBinXmlParser(androidManifestContents);
            int eventType = parser.getEventType();
            while (eventType != AndroidBinXmlParser.EVENT_END_DOCUMENT) {
                if ((eventType == AndroidBinXmlParser.EVENT_START_ELEMENT)
                        && (parser.getDepth() == 1)
                        && ("manifest".equals(parser.getName()))
                        && (parser.getNamespace().isEmpty())) {
                    // In each manifest element, targetSandboxVersion defaults to 1
                    int result = 1;
                    for (int i = 0; i < parser.getAttributeCount(); i++) {
                        if (parser.getAttributeNameResourceId(i)
                                == TARGET_SANDBOX_VERSION_ATTR_ID) {
                            int valueType = parser.getAttributeValueType(i);
                            switch (valueType) {
                                case AndroidBinXmlParser.VALUE_TYPE_INT:
                                    result = parser.getAttributeIntValue(i);
                                    break;
                                default:
                                    throw new ApkFormatException(
                                            "Failed to determine APK's target sandbox version"
                                                    + ": unsupported value type of"
                                                    + " AndroidManifest.xml"
                                                    + " android:targetSandboxVersion"
                                                    + ". Only integer values supported.");
                            }
                            break;
                        }
                    }
                    return result;
                }
                eventType = parser.next();
            }
            throw new ApkFormatException(
                    "Failed to determine APK's target sandbox version"
                            + " : no manifest element in AndroidManifest.xml");
        } catch (AndroidBinXmlParser.XmlParserException e) {
            throw new ApkFormatException(
                    "Failed to determine APK's target sandbox version"
                            + ": malformed AndroidManifest.xml",
                    e);
        }
    }

    /**
     * Result of verifying an APKs signatures. The APK can be considered verified iff
     * {@link #isVerified()} returns {@code true}.
     */
    public static class Result {
        private final List<IssueWithParams> mErrors = new ArrayList<>();
        private final List<IssueWithParams> mWarnings = new ArrayList<>();
        private final List<X509Certificate> mSignerCerts = new ArrayList<>();
        private final List<V1SchemeSignerInfo> mV1SchemeSigners = new ArrayList<>();
        private final List<V1SchemeSignerInfo> mV1SchemeIgnoredSigners = new ArrayList<>();
        private final List<V2SchemeSignerInfo> mV2SchemeSigners = new ArrayList<>();

        private boolean mVerified;
        private boolean mVerifiedUsingV1Scheme;
        private boolean mVerifiedUsingV2Scheme;

        /**
         * Returns {@code true} if the APK's signatures verified.
         */
        public boolean isVerified() {
            return mVerified;
        }

        private void setVerified() {
            mVerified = true;
        }

        /**
         * Returns {@code true} if the APK's JAR signatures verified.
         */
        public boolean isVerifiedUsingV1Scheme() {
            return mVerifiedUsingV1Scheme;
        }

        /**
         * Returns {@code true} if the APK's APK Signature Scheme v2 signatures verified.
         */
        public boolean isVerifiedUsingV2Scheme() {
            return mVerifiedUsingV2Scheme;
        }

        /**
         * Returns the verified signers' certificates, one per signer.
         */
        public List<X509Certificate> getSignerCertificates() {
            return mSignerCerts;
        }

        private void addSignerCertificate(X509Certificate cert) {
            mSignerCerts.add(cert);
        }

        /**
         * Returns information about JAR signers associated with the APK's signature. These are the
         * signers used by Android.
         *
         * @see #getV1SchemeIgnoredSigners()
         */
        public List<V1SchemeSignerInfo> getV1SchemeSigners() {
            return mV1SchemeSigners;
        }

        /**
         * Returns information about JAR signers ignored by the APK's signature verification
         * process. These signers are ignored by Android. However, each signer's errors or warnings
         * will contain information about why they are ignored.
         *
         * @see #getV1SchemeSigners()
         */
        public List<V1SchemeSignerInfo> getV1SchemeIgnoredSigners() {
            return mV1SchemeIgnoredSigners;
        }

        /**
         * Returns information about APK Signature Scheme v2 signers associated with the APK's
         * signature.
         */
        public List<V2SchemeSignerInfo> getV2SchemeSigners() {
            return mV2SchemeSigners;
        }

        void addError(Issue msg, Object... parameters) {
            mErrors.add(new IssueWithParams(msg, parameters));
        }

        /**
         * Returns errors encountered while verifying the APK's signatures.
         */
        public List<IssueWithParams> getErrors() {
            return mErrors;
        }

        /**
         * Returns warnings encountered while verifying the APK's signatures.
         */
        public List<IssueWithParams> getWarnings() {
            return mWarnings;
        }

        private void mergeFrom(V1SchemeVerifier.Result source) {
            mVerifiedUsingV1Scheme = source.verified;
            mErrors.addAll(source.getErrors());
            mWarnings.addAll(source.getWarnings());
            for (V1SchemeVerifier.Result.SignerInfo signer : source.signers) {
                mV1SchemeSigners.add(new V1SchemeSignerInfo(signer));
            }
            for (V1SchemeVerifier.Result.SignerInfo signer : source.ignoredSigners) {
                mV1SchemeIgnoredSigners.add(new V1SchemeSignerInfo(signer));
            }
        }

        private void mergeFrom(V2SchemeVerifier.Result source) {
            mVerifiedUsingV2Scheme = source.verified;
            mErrors.addAll(source.getErrors());
            mWarnings.addAll(source.getWarnings());
            for (V2SchemeVerifier.Result.SignerInfo signer : source.signers) {
                mV2SchemeSigners.add(new V2SchemeSignerInfo(signer));
            }
        }

        /**
         * Returns {@code true} if an error was encountered while verifying the APK. Any error
         * prevents the APK from being considered verified.
         */
        public boolean containsErrors() {
            if (!mErrors.isEmpty()) {
                return true;
            }
            if (!mV1SchemeSigners.isEmpty()) {
                for (V1SchemeSignerInfo signer : mV1SchemeSigners) {
                    if (signer.containsErrors()) {
                        return true;
                    }
                }
            }
            if (!mV2SchemeSigners.isEmpty()) {
                for (V2SchemeSignerInfo signer : mV2SchemeSigners) {
                    if (signer.containsErrors()) {
                        return true;
                    }
                }
            }

            return false;
        }

        /**
         * Information about a JAR signer associated with the APK's signature.
         */
        public static class V1SchemeSignerInfo {
            private final String mName;
            private final List<X509Certificate> mCertChain;
            private final String mSignatureBlockFileName;
            private final String mSignatureFileName;

            private final List<IssueWithParams> mErrors;
            private final List<IssueWithParams> mWarnings;

            private V1SchemeSignerInfo(V1SchemeVerifier.Result.SignerInfo result) {
                mName = result.name;
                mCertChain = result.certChain;
                mSignatureBlockFileName = result.signatureBlockFileName;
                mSignatureFileName = result.signatureFileName;
                mErrors = result.getErrors();
                mWarnings = result.getWarnings();
            }

            /**
             * Returns a user-friendly name of the signer.
             */
            public String getName() {
                return mName;
            }

            /**
             * Returns the name of the JAR entry containing this signer's JAR signature block file.
             */
            public String getSignatureBlockFileName() {
                return mSignatureBlockFileName;
            }

            /**
             * Returns the name of the JAR entry containing this signer's JAR signature file.
             */
            public String getSignatureFileName() {
                return mSignatureFileName;
            }

            /**
             * Returns this signer's signing certificate or {@code null} if not available. The
             * certificate is guaranteed to be available if no errors were encountered during
             * verification (see {@link #containsErrors()}.
             *
             * <p>This certificate contains the signer's public key.
             */
            public X509Certificate getCertificate() {
                return mCertChain.isEmpty() ? null : mCertChain.get(0);
            }

            /**
             * Returns the certificate chain for the signer's public key. The certificate containing
             * the public key is first, followed by the certificate (if any) which issued the
             * signing certificate, and so forth. An empty list may be returned if an error was
             * encountered during verification (see {@link #containsErrors()}).
             */
            public List<X509Certificate> getCertificateChain() {
                return mCertChain;
            }

            /**
             * Returns {@code true} if an error was encountered while verifying this signer's JAR
             * signature. Any error prevents the signer's signature from being considered verified.
             */
            public boolean containsErrors() {
                return !mErrors.isEmpty();
            }

            /**
             * Returns errors encountered while verifying this signer's JAR signature. Any error
             * prevents the signer's signature from being considered verified.
             */
            public List<IssueWithParams> getErrors() {
                return mErrors;
            }

            /**
             * Returns warnings encountered while verifying this signer's JAR signature. Warnings
             * do not prevent the signer's signature from being considered verified.
             */
            public List<IssueWithParams> getWarnings() {
                return mWarnings;
            }

            private void addError(Issue msg, Object... parameters) {
                mErrors.add(new IssueWithParams(msg, parameters));
            }
        }

        /**
         * Information about an APK Signature Scheme v2 signer associated with the APK's signature.
         */
        public static class V2SchemeSignerInfo {
            private final int mIndex;
            private final List<X509Certificate> mCerts;

            private final List<IssueWithParams> mErrors;
            private final List<IssueWithParams> mWarnings;

            private V2SchemeSignerInfo(V2SchemeVerifier.Result.SignerInfo result) {
                mIndex = result.index;
                mCerts = result.certs;
                mErrors = result.getErrors();
                mWarnings = result.getWarnings();
            }

            /**
             * Returns this signer's {@code 0}-based index in the list of signers contained in the
             * APK's APK Signature Scheme v2 signature.
             */
            public int getIndex() {
                return mIndex;
            }

            /**
             * Returns this signer's signing certificate or {@code null} if not available. The
             * certificate is guaranteed to be available if no errors were encountered during
             * verification (see {@link #containsErrors()}.
             *
             * <p>This certificate contains the signer's public key.
             */
            public X509Certificate getCertificate() {
                return mCerts.isEmpty() ? null : mCerts.get(0);
            }

            /**
             * Returns this signer's certificates. The first certificate is for the signer's public
             * key. An empty list may be returned if an error was encountered during verification
             * (see {@link #containsErrors()}).
             */
            public List<X509Certificate> getCertificates() {
                return mCerts;
            }

            private void addError(Issue msg, Object... parameters) {
                mErrors.add(new IssueWithParams(msg, parameters));
            }

            public boolean containsErrors() {
                return !mErrors.isEmpty();
            }

            public List<IssueWithParams> getErrors() {
                return mErrors;
            }

            public List<IssueWithParams> getWarnings() {
                return mWarnings;
            }
        }
    }

    /**
     * Error or warning encountered while verifying an APK's signatures.
     */
    public static enum Issue {

        /**
         * APK is not JAR-signed.
         */
        JAR_SIG_NO_SIGNATURES("No JAR signatures"),

        /**
         * APK does not contain any entries covered by JAR signatures.
         */
        JAR_SIG_NO_SIGNED_ZIP_ENTRIES("No JAR entries covered by JAR signatures"),

        /**
         * APK contains multiple entries with the same name.
         *
         * <ul>
         * <li>Parameter 1: name ({@code String})</li>
         * </ul>
         */
        JAR_SIG_DUPLICATE_ZIP_ENTRY("Duplicate entry: %1$s"),

        /**
         * JAR manifest contains a section with a duplicate name.
         *
         * <ul>
         * <li>Parameter 1: section name ({@code String})</li>
         * </ul>
         */
        JAR_SIG_DUPLICATE_MANIFEST_SECTION("Duplicate section in META-INF/MANIFEST.MF: %1$s"),

        /**
         * JAR manifest contains a section without a name.
         *
         * <ul>
         * <li>Parameter 1: section index (1-based) ({@code Integer})</li>
         * </ul>
         */
        JAR_SIG_UNNNAMED_MANIFEST_SECTION(
                "Malformed META-INF/MANIFEST.MF: invidual section #%1$d does not have a name"),

        /**
         * JAR signature file contains a section without a name.
         *
         * <ul>
         * <li>Parameter 1: signature file name ({@code String})</li>
         * <li>Parameter 2: section index (1-based) ({@code Integer})</li>
         * </ul>
         */
        JAR_SIG_UNNNAMED_SIG_FILE_SECTION(
                "Malformed %1$s: invidual section #%2$d does not have a name"),

        /** APK is missing the JAR manifest entry (META-INF/MANIFEST.MF). */
        JAR_SIG_NO_MANIFEST("Missing META-INF/MANIFEST.MF"),

        /**
         * JAR manifest references an entry which is not there in the APK.
         *
         * <ul>
         * <li>Parameter 1: entry name ({@code String})</li>
         * </ul>
         */
        JAR_SIG_MISSING_ZIP_ENTRY_REFERENCED_IN_MANIFEST(
                "%1$s entry referenced by META-INF/MANIFEST.MF not found in the APK"),

        /**
         * JAR manifest does not list a digest for the specified entry.
         *
         * <ul>
         * <li>Parameter 1: entry name ({@code String})</li>
         * </ul>
         */
        JAR_SIG_NO_ZIP_ENTRY_DIGEST_IN_MANIFEST("No digest for %1$s in META-INF/MANIFEST.MF"),

        /**
         * JAR signature does not list a digest for the specified entry.
         *
         * <ul>
         * <li>Parameter 1: entry name ({@code String})</li>
         * <li>Parameter 2: signature file name ({@code String})</li>
         * </ul>
         */
        JAR_SIG_NO_ZIP_ENTRY_DIGEST_IN_SIG_FILE("No digest for %1$s in %2$s"),

        /**
         * The specified JAR entry is not covered by JAR signature.
         *
         * <ul>
         * <li>Parameter 1: entry name ({@code String})</li>
         * </ul>
         */
        JAR_SIG_ZIP_ENTRY_NOT_SIGNED("%1$s entry not signed"),

        /**
         * JAR signature uses different set of signers to protect the two specified ZIP entries.
         *
         * <ul>
         * <li>Parameter 1: first entry name ({@code String})</li>
         * <li>Parameter 2: first entry signer names ({@code List<String>})</li>
         * <li>Parameter 3: second entry name ({@code String})</li>
         * <li>Parameter 4: second entry signer names ({@code List<String>})</li>
         * </ul>
         */
        JAR_SIG_ZIP_ENTRY_SIGNERS_MISMATCH(
                "Entries %1$s and %3$s are signed with different sets of signers"
                        + " : <%2$s> vs <%4$s>"),

        /**
         * Digest of the specified ZIP entry's data does not match the digest expected by the JAR
         * signature.
         *
         * <ul>
         * <li>Parameter 1: entry name ({@code String})</li>
         * <li>Parameter 2: digest algorithm (e.g., SHA-256) ({@code String})</li>
         * <li>Parameter 3: name of the entry in which the expected digest is specified
         *     ({@code String})</li>
         * <li>Parameter 4: base64-encoded actual digest ({@code String})</li>
         * <li>Parameter 5: base64-encoded expected digest ({@code String})</li>
         * </ul>
         */
        JAR_SIG_ZIP_ENTRY_DIGEST_DID_NOT_VERIFY(
                "%2$s digest of %1$s does not match the digest specified in %3$s"
                        + ". Expected: <%5$s>, actual: <%4$s>"),

        /**
         * Digest of the JAR manifest main section did not verify.
         *
         * <ul>
         * <li>Parameter 1: digest algorithm (e.g., SHA-256) ({@code String})</li>
         * <li>Parameter 2: name of the entry in which the expected digest is specified
         *     ({@code String})</li>
         * <li>Parameter 3: base64-encoded actual digest ({@code String})</li>
         * <li>Parameter 4: base64-encoded expected digest ({@code String})</li>
         * </ul>
         */
        JAR_SIG_MANIFEST_MAIN_SECTION_DIGEST_DID_NOT_VERIFY(
                "%1$s digest of META-INF/MANIFEST.MF main section does not match the digest"
                        + " specified in %2$s. Expected: <%4$s>, actual: <%3$s>"),

        /**
         * Digest of the specified JAR manifest section does not match the digest expected by the
         * JAR signature.
         *
         * <ul>
         * <li>Parameter 1: section name ({@code String})</li>
         * <li>Parameter 2: digest algorithm (e.g., SHA-256) ({@code String})</li>
         * <li>Parameter 3: name of the signature file in which the expected digest is specified
         *     ({@code String})</li>
         * <li>Parameter 4: base64-encoded actual digest ({@code String})</li>
         * <li>Parameter 5: base64-encoded expected digest ({@code String})</li>
         * </ul>
         */
        JAR_SIG_MANIFEST_SECTION_DIGEST_DID_NOT_VERIFY(
                "%2$s digest of META-INF/MANIFEST.MF section for %1$s does not match the digest"
                        + " specified in %3$s. Expected: <%5$s>, actual: <%4$s>"),

        /**
         * JAR signature file does not contain the whole-file digest of the JAR manifest file. The
         * digest speeds up verification of JAR signature.
         *
         * <ul>
         * <li>Parameter 1: name of the signature file ({@code String})</li>
         * </ul>
         */
        JAR_SIG_NO_MANIFEST_DIGEST_IN_SIG_FILE(
                "%1$s does not specify digest of META-INF/MANIFEST.MF"
                        + ". This slows down verification."),

        /**
         * APK is signed using APK Signature Scheme v2 or newer, but JAR signature file does not
         * contain protections against stripping of these newer scheme signatures.
         *
         * <ul>
         * <li>Parameter 1: name of the signature file ({@code String})</li>
         * </ul>
         */
        JAR_SIG_NO_APK_SIG_STRIP_PROTECTION(
                "APK is signed using APK Signature Scheme v2 but these signatures may be stripped"
                        + " without being detected because %1$s does not contain anti-stripping"
                        + " protections."),

        /**
         * JAR signature of the signer is missing a file/entry.
         *
         * <ul>
         * <li>Parameter 1: name of the encountered file ({@code String})</li>
         * <li>Parameter 2: name of the missing file ({@code String})</li>
         * </ul>
         */
        JAR_SIG_MISSING_FILE("Partial JAR signature. Found: %1$s, missing: %2$s"),

        /**
         * An exception was encountered while verifying JAR signature contained in a signature block
         * against the signature file.
         *
         * <ul>
         * <li>Parameter 1: name of the signature block file ({@code String})</li>
         * <li>Parameter 2: name of the signature file ({@code String})</li>
         * <li>Parameter 3: exception ({@code Throwable})</li>
         * </ul>
         */
        JAR_SIG_VERIFY_EXCEPTION("Failed to verify JAR signature %1$s against %2$s: %3$s"),

        /**
         * JAR signature contains unsupported digest algorithm.
         *
         * <ul>
         * <li>Parameter 1: name of the signature block file ({@code String})</li>
         * <li>Parameter 2: digest algorithm OID ({@code String})</li>
         * <li>Parameter 2: signature algorithm OID ({@code String})</li>
         * <li>Parameter 3: API Levels on which this combination of algorithms is not supported
         *     ({@code String})</li>
         * </ul>
         */
        JAR_SIG_UNSUPPORTED_SIG_ALG(
                "JAR signature %1$s uses digest algorithm %2$s and signature algorithm %3$s which"
                        + " is not supported on API Levels %4$s"),

        /**
         * An exception was encountered while parsing JAR signature contained in a signature block.
         *
         * <ul>
         * <li>Parameter 1: name of the signature block file ({@code String})</li>
         * <li>Parameter 2: exception ({@code Throwable})</li>
         * </ul>
         */
        JAR_SIG_PARSE_EXCEPTION("Failed to parse JAR signature %1$s: %2$s"),

        /**
         * An exception was encountered while parsing a certificate contained in the JAR signature
         * block.
         *
         * <ul>
         * <li>Parameter 1: name of the signature block file ({@code String})</li>
         * <li>Parameter 2: exception ({@code Throwable})</li>
         * </ul>
         */
        JAR_SIG_MALFORMED_CERTIFICATE("Malformed certificate in JAR signature %1$s: %2$s"),

        /**
         * JAR signature contained in a signature block file did not verify against the signature
         * file.
         *
         * <ul>
         * <li>Parameter 1: name of the signature block file ({@code String})</li>
         * <li>Parameter 2: name of the signature file ({@code String})</li>
         * </ul>
         */
        JAR_SIG_DID_NOT_VERIFY("JAR signature %1$s did not verify against %2$s"),

        /**
         * JAR signature contains no verified signers.
         *
         * <ul>
         * <li>Parameter 1: name of the signature block file ({@code String})</li>
         * </ul>
         */
        JAR_SIG_NO_SIGNERS("JAR signature %1$s contains no signers"),

        /**
         * JAR signature file contains a section with a duplicate name.
         *
         * <ul>
         * <li>Parameter 1: signature file name ({@code String})</li>
         * <li>Parameter 1: section name ({@code String})</li>
         * </ul>
         */
        JAR_SIG_DUPLICATE_SIG_FILE_SECTION("Duplicate section in %1$s: %2$s"),

        /**
         * JAR signature file's main section doesn't contain the mandatory Signature-Version
         * attribute.
         *
         * <ul>
         * <li>Parameter 1: signature file name ({@code String})</li>
         * </ul>
         */
        JAR_SIG_MISSING_VERSION_ATTR_IN_SIG_FILE(
                "Malformed %1$s: missing Signature-Version attribute"),

        /**
         * JAR signature file references an unknown APK signature scheme ID.
         *
         * <ul>
         * <li>Parameter 1: name of the signature file ({@code String})</li>
         * <li>Parameter 2: unknown APK signature scheme ID ({@code} Integer)</li>
         * </ul>
         */
        JAR_SIG_UNKNOWN_APK_SIG_SCHEME_ID(
                "JAR signature %1$s references unknown APK signature scheme ID: %2$d"),

        /**
         * JAR signature file indicates that the APK is supposed to be signed with a supported APK
         * signature scheme (in addition to the JAR signature) but no such signature was found in
         * the APK.
         *
         * <ul>
         * <li>Parameter 1: name of the signature file ({@code String})</li>
         * <li>Parameter 2: APK signature scheme ID ({@code} Integer)</li>
         * <li>Parameter 3: APK signature scheme English name ({@code} String)</li>
         * </ul>
         */
        JAR_SIG_MISSING_APK_SIG_REFERENCED(
                "JAR signature %1$s indicates the APK is signed using %3$s but no such signature"
                        + " was found. Signature stripped?"),

        /**
         * JAR entry is not covered by signature and thus unauthorized modifications to its contents
         * will not be detected.
         *
         * <ul>
         * <li>Parameter 1: entry name ({@code String})</li>
         * </ul>
         */
        JAR_SIG_UNPROTECTED_ZIP_ENTRY(
                "%1$s not protected by signature. Unauthorized modifications to this JAR entry"
                        + " will not be detected. Delete or move the entry outside of META-INF/."),

        /**
         * APK which is both JAR-signed and signed using APK Signature Scheme v2 contains an APK
         * Signature Scheme v2 signature from this signer, but does not contain a JAR signature
         * from this signer.
         */
        JAR_SIG_MISSING("No JAR signature from this signer"),

        /**
         * APK is targeting a sandbox version which requires APK Signature Scheme v2 signature but
         * no such signature was found.
         *
         * <ul>
         * <li>Parameter 1: target sandbox version ({@code Integer})</li>
         * </ul>
         */
        NO_SIG_FOR_TARGET_SANDBOX_VERSION(
                "Missing APK Signature Scheme v2 signature required for target sandbox version"
                        + " %1$d"),

        /**
         * APK which is both JAR-signed and signed using APK Signature Scheme v2 contains a JAR
         * signature from this signer, but does not contain an APK Signature Scheme v2 signature
         * from this signer.
         */
        V2_SIG_MISSING("No APK Signature Scheme v2 signature from this signer"),

        /**
         * Failed to parse the list of signers contained in the APK Signature Scheme v2 signature.
         */
        V2_SIG_MALFORMED_SIGNERS("Malformed list of signers"),

        /**
         * Failed to parse this signer's signer block contained in the APK Signature Scheme v2
         * signature.
         */
        V2_SIG_MALFORMED_SIGNER("Malformed signer block"),

        /**
         * Public key embedded in the APK Signature Scheme v2 signature of this signer could not be
         * parsed.
         *
         * <ul>
         * <li>Parameter 1: error details ({@code Throwable})</li>
         * </ul>
         */
        V2_SIG_MALFORMED_PUBLIC_KEY("Malformed public key: %1$s"),

        /**
         * This APK Signature Scheme v2 signer's certificate could not be parsed.
         *
         * <ul>
         * <li>Parameter 1: index ({@code 0}-based) of the certificate in the signer's list of
         *     certificates ({@code Integer})</li>
         * <li>Parameter 2: sequence number ({@code 1}-based) of the certificate in the signer's
         *     list of certificates ({@code Integer})</li>
         * <li>Parameter 3: error details ({@code Throwable})</li>
         * </ul>
         */
        V2_SIG_MALFORMED_CERTIFICATE("Malformed certificate #%2$d: %3$s"),

        /**
         * Failed to parse this signer's signature record contained in the APK Signature Scheme v2
         * signature.
         *
         * <ul>
         * <li>Parameter 1: record number (first record is {@code 1}) ({@code Integer})</li>
         * </ul>
         */
        V2_SIG_MALFORMED_SIGNATURE("Malformed APK Signature Scheme v2 signature record #%1$d"),

        /**
         * Failed to parse this signer's digest record contained in the APK Signature Scheme v2
         * signature.
         *
         * <ul>
         * <li>Parameter 1: record number (first record is {@code 1}) ({@code Integer})</li>
         * </ul>
         */
        V2_SIG_MALFORMED_DIGEST("Malformed APK Signature Scheme v2 digest record #%1$d"),

        /**
         * This APK Signature Scheme v2 signer contains a malformed additional attribute.
         *
         * <ul>
         * <li>Parameter 1: attribute number (first attribute is {@code 1}) {@code Integer})</li>
         * </ul>
         */
        V2_SIG_MALFORMED_ADDITIONAL_ATTRIBUTE("Malformed additional attribute #%1$d"),

        /**
         * APK Signature Scheme v2 signature contains no signers.
         */
        V2_SIG_NO_SIGNERS("No signers in APK Signature Scheme v2 signature"),

        /**
         * This APK Signature Scheme v2 signer contains a signature produced using an unknown
         * algorithm.
         *
         * <ul>
         * <li>Parameter 1: algorithm ID ({@code Integer})</li>
         * </ul>
         */
        V2_SIG_UNKNOWN_SIG_ALGORITHM("Unknown signature algorithm: %1$#x"),

        /**
         * This APK Signature Scheme v2 signer contains an unknown additional attribute.
         *
         * <ul>
         * <li>Parameter 1: attribute ID ({@code Integer})</li>
         * </ul>
         */
        V2_SIG_UNKNOWN_ADDITIONAL_ATTRIBUTE("Unknown additional attribute: ID %1$#x"),

        /**
         * An exception was encountered while verifying APK Signature Scheme v2 signature of this
         * signer.
         *
         * <ul>
         * <li>Parameter 1: signature algorithm ({@link SignatureAlgorithm})</li>
         * <li>Parameter 2: exception ({@code Throwable})</li>
         * </ul>
         */
        V2_SIG_VERIFY_EXCEPTION("Failed to verify %1$s signature: %2$s"),

        /**
         * APK Signature Scheme v2 signature over this signer's signed-data block did not verify.
         *
         * <ul>
         * <li>Parameter 1: signature algorithm ({@link SignatureAlgorithm})</li>
         * </ul>
         */
        V2_SIG_DID_NOT_VERIFY("%1$s signature over signed-data did not verify"),

        /**
         * This APK Signature Scheme v2 signer offers no signatures.
         */
        V2_SIG_NO_SIGNATURES("No signatures"),

        /**
         * This APK Signature Scheme v2 signer offers signatures but none of them are supported.
         */
        V2_SIG_NO_SUPPORTED_SIGNATURES("No supported signatures"),

        /**
         * This APK Signature Scheme v2 signer offers no certificates.
         */
        V2_SIG_NO_CERTIFICATES("No certificates"),

        /**
         * This APK Signature Scheme v2 signer's public key listed in the signer's certificate does
         * not match the public key listed in the signatures record.
         *
         * <ul>
         * <li>Parameter 1: hex-encoded public key from certificate ({@code String})</li>
         * <li>Parameter 2: hex-encoded public key from signatures record ({@code String})</li>
         * </ul>
         */
        V2_SIG_PUBLIC_KEY_MISMATCH_BETWEEN_CERTIFICATE_AND_SIGNATURES_RECORD(
                "Public key mismatch between certificate and signature record: <%1$s> vs <%2$s>"),

        /**
         * This APK Signature Scheme v2 signer's signature algorithms listed in the signatures
         * record do not match the signature algorithms listed in the signatures record.
         *
         * <ul>
         * <li>Parameter 1: signature algorithms from signatures record ({@code List<Integer>})</li>
         * <li>Parameter 2: signature algorithms from digests record ({@code List<Integer>})</li>
         * </ul>
         */
        V2_SIG_SIG_ALG_MISMATCH_BETWEEN_SIGNATURES_AND_DIGESTS_RECORDS(
                "Signature algorithms mismatch between signatures and digests records"
                        + ": %1$s vs %2$s"),

        /**
         * The APK's digest does not match the digest contained in the APK Signature Scheme v2
         * signature.
         *
         * <ul>
         * <li>Parameter 1: content digest algorithm ({@link ContentDigestAlgorithm})</li>
         * <li>Parameter 2: hex-encoded expected digest of the APK ({@code String})</li>
         * <li>Parameter 3: hex-encoded actual digest of the APK ({@code String})</li>
         * </ul>
         */
        V2_SIG_APK_DIGEST_DID_NOT_VERIFY(
                "APK integrity check failed. %1$s digest mismatch."
                        + " Expected: <%2$s>, actual: <%3$s>"),

        /**
         * APK Signing Block contains an unknown entry.
         *
         * <ul>
         * <li>Parameter 1: entry ID ({@code Integer})</li>
         * </ul>
         */
        APK_SIG_BLOCK_UNKNOWN_ENTRY_ID("APK Signing Block contains unknown entry: ID %1$#x");

        private final String mFormat;

        private Issue(String format) {
            mFormat = format;
        }

        /**
         * Returns the format string suitable for combining the parameters of this issue into a
         * readable string. See {@link java.util.Formatter} for format.
         */
        private String getFormat() {
            return mFormat;
        }
    }

    /**
     * {@link Issue} with associated parameters. {@link #toString()} produces a readable formatted
     * form.
     */
    public static class IssueWithParams {
        private final Issue mIssue;
        private final Object[] mParams;

        /**
         * Constructs a new {@code IssueWithParams} of the specified type and with provided
         * parameters.
         */
        public IssueWithParams(Issue issue, Object[] params) {
            mIssue = issue;
            mParams = params;
        }

        /**
         * Returns the type of this issue.
         */
        public Issue getIssue() {
            return mIssue;
        }

        /**
         * Returns the parameters of this issue.
         */
        public Object[] getParams() {
            return mParams.clone();
        }

        /**
         * Returns a readable form of this issue.
         */
        @Override
        public String toString() {
            return String.format(mIssue.getFormat(), mParams);
        }
    }

    /**
     * Wrapped around {@code byte[]} which ensures that {@code equals} and {@code hashCode} operate
     * on the contents of the arrays rather than on references.
     */
    private static class ByteArray {
        private final byte[] mArray;
        private final int mHashCode;

        private ByteArray(byte[] arr) {
            mArray = arr;
            mHashCode = Arrays.hashCode(mArray);
        }

        @Override
        public int hashCode() {
            return mHashCode;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            ByteArray other = (ByteArray) obj;
            if (hashCode() != other.hashCode()) {
                return false;
            }
            if (!Arrays.equals(mArray, other.mArray)) {
                return false;
            }
            return true;
        }
    }

    /**
     * Builder of {@link ApkVerifier} instances.
     *
     * <p>The resulting verifier by default checks whether the APK will verify on all platform
     * versions supported by the APK, as specified by {@code android:minSdkVersion} attributes in
     * the APK's {@code AndroidManifest.xml}. The range of platform versions can be customized using
     * {@link #setMinCheckedPlatformVersion(int)} and {@link #setMaxCheckedPlatformVersion(int)}.
     */
    public static class Builder {
        private final File mApkFile;
        private final DataSource mApkDataSource;

        private Integer mMinSdkVersion;
        private int mMaxSdkVersion = Integer.MAX_VALUE;

        /**
         * Constructs a new {@code Builder} for verifying the provided APK file.
         */
        public Builder(File apk) {
            if (apk == null) {
                throw new NullPointerException("apk == null");
            }
            mApkFile = apk;
            mApkDataSource = null;
        }

        /**
         * Constructs a new {@code Builder} for verifying the provided APK.
         */
        public Builder(DataSource apk) {
            if (apk == null) {
                throw new NullPointerException("apk == null");
            }
            mApkDataSource = apk;
            mApkFile = null;
        }

        /**
         * Sets the oldest Android platform version for which the APK is verified. APK verification
         * will confirm that the APK is expected to install successfully on all known Android
         * platforms starting from the platform version with the provided API Level. The upper end
         * of the platform versions range can be modified via
         * {@link #setMaxCheckedPlatformVersion(int)}.
         *
         * <p>This method is useful for overriding the default behavior which checks that the APK
         * will verify on all platform versions supported by the APK, as specified by
         * {@code android:minSdkVersion} attributes in the APK's {@code AndroidManifest.xml}.
         *
         * @param minSdkVersion API Level of the oldest platform for which to verify the APK
         *
         * @see #setMinCheckedPlatformVersion(int)
         */
        public Builder setMinCheckedPlatformVersion(int minSdkVersion) {
            mMinSdkVersion = minSdkVersion;
            return this;
        }

        /**
         * Sets the newest Android platform version for which the APK is verified. APK verification
         * will confirm that the APK is expected to install successfully on all platform versions
         * supported by the APK up until and including the provided version. The lower end
         * of the platform versions range can be modified via
         * {@link #setMinCheckedPlatformVersion(int)}.
         *
         * @param maxSdkVersion API Level of the newest platform for which to verify the APK
         *
         * @see #setMinCheckedPlatformVersion(int)
         */
        public Builder setMaxCheckedPlatformVersion(int maxSdkVersion) {
            mMaxSdkVersion = maxSdkVersion;
            return this;
        }

        /**
         * Returns an {@link ApkVerifier} initialized according to the configuration of this
         * builder.
         */
        public ApkVerifier build() {
            return new ApkVerifier(
                    mApkFile,
                    mApkDataSource,
                    mMinSdkVersion,
                    mMaxSdkVersion);
        }
    }
}
