diff --git a/tools/apksigner/core/src/com/android/apksigner/core/ApkVerifier.java b/tools/apksigner/core/src/com/android/apksigner/core/ApkVerifier.java
new file mode 100644
index 0000000..931c7b2
--- /dev/null
+++ b/tools/apksigner/core/src/com/android/apksigner/core/ApkVerifier.java
@@ -0,0 +1,458 @@
+/*
+ * 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.apksigner.core;
+
+import com.android.apksigner.core.apk.ApkUtils;
+import com.android.apksigner.core.internal.apk.v2.ContentDigestAlgorithm;
+import com.android.apksigner.core.internal.apk.v2.SignatureAlgorithm;
+import com.android.apksigner.core.internal.apk.v2.V2SchemeVerifier;
+import com.android.apksigner.core.util.DataSource;
+import com.android.apksigner.core.zip.ZipFormatException;
+
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 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.
+ */
+public class ApkVerifier {
+
+    /**
+     * 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
+     * @param minSdkVersion API Level of the oldest Android platform on which the APK's signatures
+     *        may need to be verified
+     *
+     * @throws IOException if an I/O error is encountered while reading the APK
+     * @throws ZipFormatException if the APK is malformed at ZIP format level
+     */
+    public Result verify(DataSource apk, int minSdkVersion) throws IOException, ZipFormatException {
+        ApkUtils.ZipSections zipSections = ApkUtils.findZipSections(apk);
+
+        // Attempt to verify the APK using APK Signature Scheme v2
+        Result result = new Result();
+        try {
+            V2SchemeVerifier.Result v2Result = V2SchemeVerifier.verify(apk, zipSections);
+            result.mergeFrom(v2Result);
+        } catch (V2SchemeVerifier.SignatureNotFoundException ignored) {}
+        if (result.containsErrors()) {
+            return result;
+        }
+
+        // TODO: Verify JAR signature if necessary
+        if (!result.isVerifiedUsingV2Scheme()) {
+            return result;
+        }
+
+        // Verified
+        result.setVerified();
+        for (Result.V2SchemeSignerInfo signerInfo : result.getV2SchemeSigners()) {
+            result.addSignerCertificate(signerInfo.getCertificate());
+        }
+
+        return result;
+    }
+
+    /**
+     * 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<V2SchemeSignerInfo> mV2SchemeSigners = new ArrayList<>();
+
+        private boolean mVerified;
+        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 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 APK Signature Scheme v2 signers associated with the APK's
+         * signature.
+         */
+        public List<V2SchemeSignerInfo> getV2SchemeSigners() {
+            return mV2SchemeSigners;
+        }
+
+        /**
+         * 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(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 (!mV2SchemeSigners.isEmpty()) {
+                for (V2SchemeSignerInfo signer : mV2SchemeSigners) {
+                    if (signer.containsErrors()) {
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        }
+
+        /**
+         * 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;
+            }
+
+            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 {
+
+        /**
+         * 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);
+        }
+    }
+}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/DefaultApkSignerEngine.java b/tools/apksigner/core/src/com/android/apksigner/core/DefaultApkSignerEngine.java
index dae3c5e..612f4fd 100644
--- a/tools/apksigner/core/src/com/android/apksigner/core/DefaultApkSignerEngine.java
+++ b/tools/apksigner/core/src/com/android/apksigner/core/DefaultApkSignerEngine.java
@@ -18,9 +18,9 @@
 
 import com.android.apksigner.core.internal.apk.v1.DigestAlgorithm;
 import com.android.apksigner.core.internal.apk.v1.V1SchemeSigner;
-import com.android.apksigner.core.internal.apk.v2.MessageDigestSink;
 import com.android.apksigner.core.internal.apk.v2.V2SchemeSigner;
 import com.android.apksigner.core.internal.util.ByteArrayOutputStreamSink;
+import com.android.apksigner.core.internal.util.MessageDigestSink;
 import com.android.apksigner.core.internal.util.Pair;
 import com.android.apksigner.core.util.DataSink;
 import com.android.apksigner.core.util.DataSource;
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/ContentDigestAlgorithm.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/ContentDigestAlgorithm.java
index cb0f84a..7c136be 100644
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/ContentDigestAlgorithm.java
+++ b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/ContentDigestAlgorithm.java
@@ -19,7 +19,7 @@
 /**
  * APK Signature Scheme v2 content digest algorithm.
  */
-enum ContentDigestAlgorithm {
+public enum ContentDigestAlgorithm {
     /** SHA2-256 over 1 MB chunks. */
     CHUNKED_SHA256("SHA-256", 256 / 8),
 
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/SignatureAlgorithm.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/SignatureAlgorithm.java
index 3c7b5f0..20f890d 100644
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/SignatureAlgorithm.java
+++ b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/SignatureAlgorithm.java
@@ -23,7 +23,7 @@
 import java.security.spec.PSSParameterSpec;
 
 /**
- * APK Signature Scheme v2 content digest algorithm.
+ * APK Signature Scheme v2 signature algorithm.
  */
 public enum SignatureAlgorithm {
     /**
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/V2SchemeSigner.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/V2SchemeSigner.java
index 103a0ec..aba390b 100644
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/V2SchemeSigner.java
+++ b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/V2SchemeSigner.java
@@ -16,6 +16,7 @@
 
 package com.android.apksigner.core.internal.apk.v2;
 
+import com.android.apksigner.core.internal.util.MessageDigestSink;
 import com.android.apksigner.core.internal.util.Pair;
 import com.android.apksigner.core.internal.zip.ZipUtils;
 import com.android.apksigner.core.util.DataSource;
@@ -216,7 +217,7 @@
         return generateApkSigningBlock(signerConfigs, contentDigests);
     }
 
-    private static Map<ContentDigestAlgorithm, byte[]> computeContentDigests(
+    static Map<ContentDigestAlgorithm, byte[]> computeContentDigests(
             Set<ContentDigestAlgorithm> digestAlgorithms,
             DataSource[] contents) throws IOException, DigestException {
         // For each digest algorithm the result is computed as follows:
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/V2SchemeVerifier.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/V2SchemeVerifier.java
new file mode 100644
index 0000000..efefb00
--- /dev/null
+++ b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/V2SchemeVerifier.java
@@ -0,0 +1,939 @@
+/*
+ * 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.apksigner.core.internal.apk.v2;
+
+import com.android.apksigner.core.ApkVerifier.Issue;
+import com.android.apksigner.core.ApkVerifier.IssueWithParams;
+import com.android.apksigner.core.apk.ApkUtils;
+import com.android.apksigner.core.internal.util.ByteBufferDataSource;
+import com.android.apksigner.core.internal.util.DelegatingX509Certificate;
+import com.android.apksigner.core.internal.util.Pair;
+import com.android.apksigner.core.internal.zip.ZipUtils;
+import com.android.apksigner.core.util.DataSource;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.security.DigestException;
+import java.security.KeyFactory;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * APK Signature Scheme v2 verifier.
+ *
+ * <p>APK Signature Scheme v2 is a whole-file signature scheme which aims to protect every single
+ * bit of the APK, as opposed to the JAR Signature Scheme which protects only the names and
+ * uncompressed contents of ZIP entries.
+ *
+ * <p>TODO: Link to APK Signature Scheme v2 documentation once it's available.
+ */
+public abstract class V2SchemeVerifier {
+
+    private static final long APK_SIG_BLOCK_MAGIC_HI = 0x3234206b636f6c42L;
+    private static final long APK_SIG_BLOCK_MAGIC_LO = 0x20676953204b5041L;
+    private static final int APK_SIG_BLOCK_MIN_SIZE = 32;
+
+    private static final int APK_SIGNATURE_SCHEME_V2_BLOCK_ID = 0x7109871a;
+
+    /** Hidden constructor to prevent instantiation. */
+    private V2SchemeVerifier() {}
+
+    /**
+     * Verifies the provided APK's APK Signature Scheme v2 signatures and returns the result of
+     * verification. APK is considered verified only if {@link Result#verified} is {@code true}. If
+     * verification fails, the result will contain errors -- see {@link Result#getErrors()}.
+     *
+     * @throws SignatureNotFoundException if no APK Signature Scheme v2 signatures are found
+     * @throws IOException if an I/O error occurs when reading the APK
+     */
+    public static Result verify(DataSource apk, ApkUtils.ZipSections zipSections)
+            throws IOException, SignatureNotFoundException {
+        Result result = new Result();
+        SignatureInfo signatureInfo = findSignature(apk, zipSections, result);
+
+        DataSource beforeApkSigningBlock = apk.slice(0, signatureInfo.apkSigningBlockOffset);
+        DataSource centralDir =
+                apk.slice(
+                        signatureInfo.centralDirOffset,
+                        signatureInfo.eocdOffset - signatureInfo.centralDirOffset);
+        ByteBuffer eocd = signatureInfo.eocd;
+
+        verify(beforeApkSigningBlock,
+                signatureInfo.signatureBlock,
+                centralDir,
+                eocd,
+                result);
+        return result;
+    }
+
+    /**
+     * Verifies the provided APK's v2 signatures and outputs the results into the provided
+     * {@code result}. APK is considered verified only if there are no errors reported in the
+     * {@code result}.
+     */
+    private static void verify(
+            DataSource beforeApkSigningBlock,
+            ByteBuffer apkSignatureSchemeV2Block,
+            DataSource centralDir,
+            ByteBuffer eocd,
+            Result result) throws IOException {
+        Set<ContentDigestAlgorithm> contentDigestsToVerify = new HashSet<>(1);
+        parseSigners(apkSignatureSchemeV2Block, contentDigestsToVerify, result);
+        if (result.containsErrors()) {
+            return;
+        }
+        verifyIntegrity(
+                beforeApkSigningBlock, centralDir, eocd, contentDigestsToVerify, result);
+        if (!result.containsErrors()) {
+            result.verified = true;
+        }
+    }
+
+    /**
+     * Parses each signer in the provided APK Signature Scheme v2 block and populates
+     * {@code signerInfos} of the provided {@code result}.
+     *
+     * <p>This verifies signatures over {@code signed-data} block contained in each signer block.
+     * However, this does not verify the integrity of the rest of the APK but rather simply reports
+     * the expected digests of the rest of the APK (see {@code contentDigestsToVerify}).
+     */
+    private static void parseSigners(
+            ByteBuffer apkSignatureSchemeV2Block,
+            Set<ContentDigestAlgorithm> contentDigestsToVerify,
+            Result result) {
+        ByteBuffer signers;
+        try {
+            signers = getLengthPrefixedSlice(apkSignatureSchemeV2Block);
+        } catch (IOException e) {
+            result.addError(Issue.V2_SIG_MALFORMED_SIGNERS);
+            return;
+        }
+        if (!signers.hasRemaining()) {
+            result.addError(Issue.V2_SIG_NO_SIGNERS);
+            return;
+        }
+
+        CertificateFactory certFactory;
+        try {
+            certFactory = CertificateFactory.getInstance("X.509");
+        } catch (CertificateException e) {
+            throw new RuntimeException("Failed to obtain X.509 CertificateFactory", e);
+        }
+        int signerCount = 0;
+        while (signers.hasRemaining()) {
+            int signerIndex = signerCount;
+            signerCount++;
+            Result.SignerInfo signerInfo = new Result.SignerInfo();
+            signerInfo.index = signerIndex;
+            result.signers.add(signerInfo);
+            try {
+                ByteBuffer signer = getLengthPrefixedSlice(signers);
+                parseSigner(signer, certFactory, signerInfo, contentDigestsToVerify);
+            } catch (IOException | BufferUnderflowException e) {
+                signerInfo.addError(Issue.V2_SIG_MALFORMED_SIGNER);
+                return;
+            }
+        }
+    }
+
+    /**
+     * Parses the provided signer block and populates the {@code result}.
+     *
+     * <p>This verifies signatures over {@code signed-data} contained in this block but does not
+     * verify the integrity of the rest of the APK. Rather, this method adds to the
+     * {@code contentDigestsToVerify}.
+     */
+    private static void parseSigner(
+            ByteBuffer signerBlock,
+            CertificateFactory certFactory,
+            Result.SignerInfo result,
+            Set<ContentDigestAlgorithm> contentDigestsToVerify) throws IOException {
+        ByteBuffer signedData = getLengthPrefixedSlice(signerBlock);
+        byte[] signedDataBytes = new byte[signedData.remaining()];
+        signedData.get(signedDataBytes);
+        signedData.flip();
+        result.signedData = signedDataBytes;
+
+        ByteBuffer signatures = getLengthPrefixedSlice(signerBlock);
+        byte[] publicKeyBytes = readLengthPrefixedByteArray(signerBlock);
+
+        // Parse the signatures block and identify supported signatures
+        int signatureCount = 0;
+        List<SupportedSignature> supportedSignatures = new ArrayList<>(1);
+        while (signatures.hasRemaining()) {
+            signatureCount++;
+            try {
+                ByteBuffer signature = getLengthPrefixedSlice(signatures);
+                int sigAlgorithmId = signature.getInt();
+                byte[] sigBytes = readLengthPrefixedByteArray(signature);
+                result.signatures.add(
+                        new Result.SignerInfo.Signature(sigAlgorithmId, sigBytes));
+                SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.findById(sigAlgorithmId);
+                if (signatureAlgorithm == null) {
+                    result.addWarning(Issue.V2_SIG_UNKNOWN_SIG_ALGORITHM, sigAlgorithmId);
+                    continue;
+                }
+                supportedSignatures.add(new SupportedSignature(signatureAlgorithm, sigBytes));
+            } catch (IOException | BufferUnderflowException e) {
+                result.addError(Issue.V2_SIG_MALFORMED_SIGNATURE, signatureCount);
+                return;
+            }
+        }
+        if (result.signatures.isEmpty()) {
+            result.addError(Issue.V2_SIG_NO_SIGNATURES);
+            return;
+        }
+
+        // Verify signatures over signed-data block using the public key
+        List<SupportedSignature> signaturesToVerify = getSignaturesToVerify(supportedSignatures);
+        if (signaturesToVerify.isEmpty()) {
+            result.addError(Issue.V2_SIG_NO_SUPPORTED_SIGNATURES);
+            return;
+        }
+        for (SupportedSignature signature : signaturesToVerify) {
+            SignatureAlgorithm signatureAlgorithm = signature.algorithm;
+            String jcaSignatureAlgorithm =
+                    signatureAlgorithm.getJcaSignatureAlgorithmAndParams().getFirst();
+            AlgorithmParameterSpec jcaSignatureAlgorithmParams =
+                    signatureAlgorithm.getJcaSignatureAlgorithmAndParams().getSecond();
+            String keyAlgorithm = signatureAlgorithm.getJcaKeyAlgorithm();
+            PublicKey publicKey;
+            try {
+                publicKey =
+                        KeyFactory.getInstance(keyAlgorithm).generatePublic(
+                                new X509EncodedKeySpec(publicKeyBytes));
+            } catch (Exception e) {
+                result.addError(Issue.V2_SIG_MALFORMED_PUBLIC_KEY, e);
+                return;
+            }
+            try {
+                Signature sig = Signature.getInstance(jcaSignatureAlgorithm);
+                sig.initVerify(publicKey);
+                if (jcaSignatureAlgorithmParams != null) {
+                    sig.setParameter(jcaSignatureAlgorithmParams);
+                }
+                signedData.position(0);
+                sig.update(signedData);
+                byte[] sigBytes = signature.signature;
+                if (!sig.verify(sigBytes)) {
+                    result.addError(Issue.V2_SIG_DID_NOT_VERIFY, signatureAlgorithm);
+                    return;
+                }
+                result.verifiedSignatures.put(signatureAlgorithm, sigBytes);
+                contentDigestsToVerify.add(signatureAlgorithm.getContentDigestAlgorithm());
+            } catch (Exception e) {
+                result.addError(Issue.V2_SIG_VERIFY_EXCEPTION, signatureAlgorithm, e);
+                return;
+            }
+        }
+
+        // At least one signature over signedData has verified. We can now parse signed-data.
+        signedData.position(0);
+        ByteBuffer digests = getLengthPrefixedSlice(signedData);
+        ByteBuffer certificates = getLengthPrefixedSlice(signedData);
+        ByteBuffer additionalAttributes = getLengthPrefixedSlice(signedData);
+
+        // Parse the certificates block
+        int certificateIndex = -1;
+        while (certificates.hasRemaining()) {
+            certificateIndex++;
+            byte[] encodedCert = readLengthPrefixedByteArray(certificates);
+            X509Certificate certificate;
+            try {
+                certificate =
+                        (X509Certificate)
+                                certFactory.generateCertificate(
+                                        new ByteArrayInputStream(encodedCert));
+            } catch (CertificateException e) {
+                result.addError(
+                        Issue.V2_SIG_MALFORMED_CERTIFICATE,
+                        certificateIndex,
+                        certificateIndex + 1,
+                        e);
+                return;
+            }
+            // Wrap the cert so that the result's getEncoded returns exactly the original encoded
+            // form. Without this, getEncoded may return a different form from what was stored in
+            // the signature. This is becase some X509Certificate(Factory) implementations re-encode
+            // certificates.
+            certificate = new GuaranteedEncodedFormX509Certificate(certificate, encodedCert);
+            result.certs.add(certificate);
+        }
+
+        if (result.certs.isEmpty()) {
+            result.addError(Issue.V2_SIG_NO_CERTIFICATES);
+            return;
+        }
+        X509Certificate mainCertificate = result.certs.get(0);
+        byte[] certificatePublicKeyBytes = mainCertificate.getPublicKey().getEncoded();
+        if (!Arrays.equals(publicKeyBytes, certificatePublicKeyBytes)) {
+            result.addError(
+                    Issue.V2_SIG_PUBLIC_KEY_MISMATCH_BETWEEN_CERTIFICATE_AND_SIGNATURES_RECORD,
+                    toHex(certificatePublicKeyBytes),
+                    toHex(publicKeyBytes));
+            return;
+        }
+
+        // Parse the digests block
+        int digestCount = 0;
+        while (digests.hasRemaining()) {
+            digestCount++;
+            try {
+                ByteBuffer digest = getLengthPrefixedSlice(digests);
+                int sigAlgorithmId = digest.getInt();
+                byte[] digestBytes = readLengthPrefixedByteArray(digest);
+                result.contentDigests.add(
+                        new Result.SignerInfo.ContentDigest(sigAlgorithmId, digestBytes));
+            } catch (IOException | BufferUnderflowException e) {
+                result.addError(Issue.V2_SIG_MALFORMED_DIGEST, digestCount);
+                return;
+            }
+        }
+
+        List<Integer> sigAlgsFromSignaturesRecord = new ArrayList<>(result.signatures.size());
+        for (Result.SignerInfo.Signature signature : result.signatures) {
+            sigAlgsFromSignaturesRecord.add(signature.getAlgorithmId());
+        }
+        List<Integer> sigAlgsFromDigestsRecord = new ArrayList<>(result.contentDigests.size());
+        for (Result.SignerInfo.ContentDigest digest : result.contentDigests) {
+            sigAlgsFromDigestsRecord.add(digest.getSignatureAlgorithmId());
+        }
+
+        if (!sigAlgsFromSignaturesRecord.equals(sigAlgsFromDigestsRecord)) {
+            result.addError(
+                    Issue.V2_SIG_SIG_ALG_MISMATCH_BETWEEN_SIGNATURES_AND_DIGESTS_RECORDS,
+                    sigAlgsFromSignaturesRecord,
+                    sigAlgsFromDigestsRecord);
+            return;
+        }
+
+        // Parse the additional attributes block.
+        int additionalAttributeCount = 0;
+        while (additionalAttributes.hasRemaining()) {
+            additionalAttributeCount++;
+            try {
+                ByteBuffer attribute = getLengthPrefixedSlice(additionalAttributes);
+                int id = attribute.getInt();
+                byte[] value = readLengthPrefixedByteArray(attribute);
+                result.additionalAttributes.add(
+                        new Result.SignerInfo.AdditionalAttribute(id, value));
+                result.addWarning(Issue.V2_SIG_UNKNOWN_ADDITIONAL_ATTRIBUTE, id);
+            } catch (IOException | BufferUnderflowException e) {
+                result.addError(
+                        Issue.V2_SIG_MALFORMED_ADDITIONAL_ATTRIBUTE, additionalAttributeCount);
+                return;
+            }
+        }
+    }
+
+    private static List<SupportedSignature> getSignaturesToVerify(
+            List<SupportedSignature> signatures) {
+        // Pick the signature with the strongest algorithm, to mimic Android's behavior.
+        SignatureAlgorithm bestSigAlgorithm = null;
+        byte[] bestSigAlgorithmSignatureBytes = null;
+        for (SupportedSignature sig : signatures) {
+            SignatureAlgorithm sigAlgorithm = sig.algorithm;
+            if ((bestSigAlgorithm == null)
+                    || (compareSignatureAlgorithm(sigAlgorithm, bestSigAlgorithm) > 0)) {
+                bestSigAlgorithm = sigAlgorithm;
+                bestSigAlgorithmSignatureBytes = sig.signature;
+            }
+        }
+
+        if (bestSigAlgorithm == null) {
+            return Collections.emptyList();
+        } else {
+            return Collections.singletonList(
+                    new SupportedSignature(bestSigAlgorithm, bestSigAlgorithmSignatureBytes));
+        }
+    }
+
+    private static class SupportedSignature {
+        private final SignatureAlgorithm algorithm;
+        private final byte[] signature;
+
+        private SupportedSignature(SignatureAlgorithm algorithm, byte[] signature) {
+            this.algorithm = algorithm;
+            this.signature = signature;
+        }
+    }
+
+    /**
+     * Returns positive number if {@code alg1} is preferred over {@code alg2}, {@code -1} if
+     * {@code alg2} is preferred over {@code alg1}, and {@code 0} if there is no preference.
+     */
+    private static int compareSignatureAlgorithm(SignatureAlgorithm alg1, SignatureAlgorithm alg2) {
+        ContentDigestAlgorithm digestAlg1 = alg1.getContentDigestAlgorithm();
+        ContentDigestAlgorithm digestAlg2 = alg2.getContentDigestAlgorithm();
+        return compareContentDigestAlgorithm(digestAlg1, digestAlg2);
+    }
+
+    /**
+     * Returns positive number if {@code alg1} is preferred over {@code alg2}, {@code -1} if
+     * {@code alg2} is preferred over {@code alg1}, and {@code 0} if there is no preference.
+     */
+    private static int compareContentDigestAlgorithm(
+            ContentDigestAlgorithm alg1,
+            ContentDigestAlgorithm alg2) {
+        switch (alg1) {
+            case CHUNKED_SHA256:
+                switch (alg2) {
+                    case CHUNKED_SHA256:
+                        return 0;
+                    case CHUNKED_SHA512:
+                        return -1;
+                    default:
+                        throw new IllegalArgumentException("Unknown alg2: " + alg2);
+                }
+            case CHUNKED_SHA512:
+                switch (alg2) {
+                    case CHUNKED_SHA256:
+                        return 1;
+                    case CHUNKED_SHA512:
+                        return 0;
+                    default:
+                        throw new IllegalArgumentException("Unknown alg2: " + alg2);
+                }
+            default:
+                throw new IllegalArgumentException("Unknown alg1: " + alg1);
+        }
+    }
+
+    /**
+     * Verifies integrity of the APK outside of the APK Signing Block by computing digests of the
+     * APK and comparing them against the digests listed in APK Signing Block. The expected digests
+     * taken from {@code v2SchemeSignerInfos} of the provided {@code result}.
+     */
+    private static void verifyIntegrity(
+            DataSource beforeApkSigningBlock,
+            DataSource centralDir,
+            ByteBuffer eocd,
+            Set<ContentDigestAlgorithm> contentDigestAlgorithms,
+            Result result) throws IOException {
+        if (contentDigestAlgorithms.isEmpty()) {
+            // This should never occur because this method is invoked once at least one signature
+            // is verified, meaning at least one content digest is known.
+            throw new RuntimeException("No content digests found");
+        }
+
+        // For the purposes of verifying integrity, ZIP End of Central Directory (EoCD) must be
+        // treated as though its Central Directory offset points to the start of APK Signing Block.
+        // We thus modify the EoCD accordingly.
+        ByteBuffer modifiedEocd = ByteBuffer.allocate(eocd.remaining());
+        modifiedEocd.order(ByteOrder.LITTLE_ENDIAN);
+        modifiedEocd.put(eocd);
+        modifiedEocd.flip();
+        ZipUtils.setZipEocdCentralDirectoryOffset(modifiedEocd, beforeApkSigningBlock.size());
+        Map<ContentDigestAlgorithm, byte[]> actualContentDigests;
+        try {
+            actualContentDigests =
+                    V2SchemeSigner.computeContentDigests(
+                            contentDigestAlgorithms,
+                            new DataSource[] {
+                                    beforeApkSigningBlock,
+                                    centralDir,
+                                    new ByteBufferDataSource(modifiedEocd)
+                            });
+        } catch (DigestException e) {
+            throw new RuntimeException("Failed to compute content digests", e);
+        }
+        if (!contentDigestAlgorithms.equals(actualContentDigests.keySet())) {
+            throw new RuntimeException(
+                    "Mismatch between sets of requested and computed content digests"
+                            + " . Requested: " + contentDigestAlgorithms
+                            + ", computed: " + actualContentDigests.keySet());
+        }
+
+        // Compare digests computed over the rest of APK against the corresponding expected digests
+        // in signer blocks.
+        for (Result.SignerInfo signerInfo : result.signers) {
+            for (Result.SignerInfo.ContentDigest expected : signerInfo.contentDigests) {
+                SignatureAlgorithm signatureAlgorithm =
+                        SignatureAlgorithm.findById(expected.getSignatureAlgorithmId());
+                if (signatureAlgorithm == null) {
+                    continue;
+                }
+                ContentDigestAlgorithm contentDigestAlgorithm =
+                        signatureAlgorithm.getContentDigestAlgorithm();
+                byte[] expectedDigest = expected.getValue();
+                byte[] actualDigest = actualContentDigests.get(contentDigestAlgorithm);
+                if (!Arrays.equals(expectedDigest, actualDigest)) {
+                    signerInfo.addError(
+                            Issue.V2_SIG_APK_DIGEST_DID_NOT_VERIFY,
+                            contentDigestAlgorithm,
+                            toHex(expectedDigest),
+                            toHex(actualDigest));
+                    continue;
+                }
+                signerInfo.verifiedContentDigests.put(contentDigestAlgorithm, actualDigest);
+            }
+        }
+    }
+
+    /**
+     * APK Signature Scheme v2 block and additional information relevant to verifying the signatures
+     * contained in the block against the file.
+     */
+    private static class SignatureInfo {
+        /** Contents of APK Signature Scheme v2 block. */
+        private final ByteBuffer signatureBlock;
+
+        /** Position of the APK Signing Block in the file. */
+        private final long apkSigningBlockOffset;
+
+        /** Position of the ZIP Central Directory in the file. */
+        private final long centralDirOffset;
+
+        /** Position of the ZIP End of Central Directory (EoCD) in the file. */
+        private final long eocdOffset;
+
+        /** Contents of ZIP End of Central Directory (EoCD) of the file. */
+        private final ByteBuffer eocd;
+
+        private SignatureInfo(
+                ByteBuffer signatureBlock,
+                long apkSigningBlockOffset,
+                long centralDirOffset,
+                long eocdOffset,
+                ByteBuffer eocd) {
+            this.signatureBlock = signatureBlock;
+            this.apkSigningBlockOffset = apkSigningBlockOffset;
+            this.centralDirOffset = centralDirOffset;
+            this.eocdOffset = eocdOffset;
+            this.eocd = eocd;
+        }
+    }
+
+    /**
+     * Returns the APK Signature Scheme v2 block contained in the provided APK file and the
+     * additional information relevant for verifying the block against the file.
+     *
+     * @throws SignatureNotFoundException if the APK is not signed using APK Signature Scheme v2
+     * @throws IOException if an I/O error occurs while reading the APK
+     */
+    private static SignatureInfo findSignature(
+            DataSource apk, ApkUtils.ZipSections zipSections, Result result)
+                    throws IOException, SignatureNotFoundException {
+        long centralDirStartOffset = zipSections.getZipCentralDirectoryOffset();
+        long centralDirEndOffset =
+                centralDirStartOffset + zipSections.getZipCentralDirectorySizeBytes();
+        long eocdStartOffset = zipSections.getZipEndOfCentralDirectoryOffset();
+        if (centralDirEndOffset != eocdStartOffset) {
+            throw new SignatureNotFoundException(
+                    "ZIP Central Directory is not immediately followed by End of Central Directory"
+                            + ". CD end: " + centralDirEndOffset
+                            + ", EoCD start: " + eocdStartOffset);
+        }
+
+        // Find the APK Signing Block. The block immediately precedes the Central Directory.
+        ByteBuffer eocd = zipSections.getZipEndOfCentralDirectory();
+        Pair<ByteBuffer, Long> apkSigningBlockAndOffset =
+                findApkSigningBlock(apk, centralDirStartOffset);
+        ByteBuffer apkSigningBlock = apkSigningBlockAndOffset.getFirst();
+        long apkSigningBlockOffset = apkSigningBlockAndOffset.getSecond();
+
+        // Find the APK Signature Scheme v2 Block inside the APK Signing Block.
+        ByteBuffer apkSignatureSchemeV2Block =
+                findApkSignatureSchemeV2Block(apkSigningBlock, result);
+
+        return new SignatureInfo(
+                apkSignatureSchemeV2Block,
+                apkSigningBlockOffset,
+                centralDirStartOffset,
+                eocdStartOffset,
+                eocd);
+    }
+
+    private static Pair<ByteBuffer, Long> findApkSigningBlock(
+            DataSource apk, long centralDirOffset) throws IOException, SignatureNotFoundException {
+        // FORMAT:
+        // OFFSET       DATA TYPE  DESCRIPTION
+        // * @+0  bytes uint64:    size in bytes (excluding this field)
+        // * @+8  bytes payload
+        // * @-24 bytes uint64:    size in bytes (same as the one above)
+        // * @-16 bytes uint128:   magic
+
+        if (centralDirOffset < APK_SIG_BLOCK_MIN_SIZE) {
+            throw new SignatureNotFoundException(
+                    "APK too small for APK Signing Block. ZIP Central Directory offset: "
+                            + centralDirOffset);
+        }
+        // Read the magic and offset in file from the footer section of the block:
+        // * uint64:   size of block
+        // * 16 bytes: magic
+        ByteBuffer footer = apk.getByteBuffer(centralDirOffset - 24, 24);
+        footer.order(ByteOrder.LITTLE_ENDIAN);
+        if ((footer.getLong(8) != APK_SIG_BLOCK_MAGIC_LO)
+                || (footer.getLong(16) != APK_SIG_BLOCK_MAGIC_HI)) {
+            throw new SignatureNotFoundException(
+                    "No APK Signing Block before ZIP Central Directory");
+        }
+        // Read and compare size fields
+        long apkSigBlockSizeInFooter = footer.getLong(0);
+        if ((apkSigBlockSizeInFooter < footer.capacity())
+                || (apkSigBlockSizeInFooter > Integer.MAX_VALUE - 8)) {
+            throw new SignatureNotFoundException(
+                    "APK Signing Block size out of range: " + apkSigBlockSizeInFooter);
+        }
+        int totalSize = (int) (apkSigBlockSizeInFooter + 8);
+        long apkSigBlockOffset = centralDirOffset - totalSize;
+        if (apkSigBlockOffset < 0) {
+            throw new SignatureNotFoundException(
+                    "APK Signing Block offset out of range: " + apkSigBlockOffset);
+        }
+        ByteBuffer apkSigBlock = apk.getByteBuffer(apkSigBlockOffset, totalSize);
+        apkSigBlock.order(ByteOrder.LITTLE_ENDIAN);
+        long apkSigBlockSizeInHeader = apkSigBlock.getLong(0);
+        if (apkSigBlockSizeInHeader != apkSigBlockSizeInFooter) {
+            throw new SignatureNotFoundException(
+                    "APK Signing Block sizes in header and footer do not match: "
+                            + apkSigBlockSizeInHeader + " vs " + apkSigBlockSizeInFooter);
+        }
+        return Pair.of(apkSigBlock, apkSigBlockOffset);
+    }
+
+    private static ByteBuffer findApkSignatureSchemeV2Block(
+            ByteBuffer apkSigningBlock,
+            Result result) throws SignatureNotFoundException {
+        checkByteOrderLittleEndian(apkSigningBlock);
+        // FORMAT:
+        // OFFSET       DATA TYPE  DESCRIPTION
+        // * @+0  bytes uint64:    size in bytes (excluding this field)
+        // * @+8  bytes pairs
+        // * @-24 bytes uint64:    size in bytes (same as the one above)
+        // * @-16 bytes uint128:   magic
+        ByteBuffer pairs = sliceFromTo(apkSigningBlock, 8, apkSigningBlock.capacity() - 24);
+
+        int entryCount = 0;
+        while (pairs.hasRemaining()) {
+            entryCount++;
+            if (pairs.remaining() < 8) {
+                throw new SignatureNotFoundException(
+                        "Insufficient data to read size of APK Signing Block entry #" + entryCount);
+            }
+            long lenLong = pairs.getLong();
+            if ((lenLong < 4) || (lenLong > Integer.MAX_VALUE)) {
+                throw new SignatureNotFoundException(
+                        "APK Signing Block entry #" + entryCount
+                                + " size out of range: " + lenLong);
+            }
+            int len = (int) lenLong;
+            int nextEntryPos = pairs.position() + len;
+            if (len > pairs.remaining()) {
+                throw new SignatureNotFoundException(
+                        "APK Signing Block entry #" + entryCount + " size out of range: " + len
+                                + ", available: " + pairs.remaining());
+            }
+            int id = pairs.getInt();
+            if (id == APK_SIGNATURE_SCHEME_V2_BLOCK_ID) {
+                return getByteBuffer(pairs, len - 4);
+            }
+            result.addWarning(Issue.APK_SIG_BLOCK_UNKNOWN_ENTRY_ID, id);
+            pairs.position(nextEntryPos);
+        }
+
+        throw new SignatureNotFoundException(
+                "No APK Signature Scheme v2 block in APK Signing Block");
+    }
+
+    private static void checkByteOrderLittleEndian(ByteBuffer buffer) {
+        if (buffer.order() != ByteOrder.LITTLE_ENDIAN) {
+            throw new IllegalArgumentException("ByteBuffer byte order must be little endian");
+        }
+    }
+
+    public static class SignatureNotFoundException extends Exception {
+        private static final long serialVersionUID = 1L;
+
+        public SignatureNotFoundException(String message) {
+            super(message);
+        }
+
+        public SignatureNotFoundException(String message, Throwable cause) {
+            super(message, cause);
+        }
+    }
+
+    /**
+     * Returns new byte buffer whose content is a shared subsequence of this buffer's content
+     * between the specified start (inclusive) and end (exclusive) positions. As opposed to
+     * {@link ByteBuffer#slice()}, the returned buffer's byte order is the same as the source
+     * buffer's byte order.
+     */
+    private static ByteBuffer sliceFromTo(ByteBuffer source, int start, int end) {
+        if (start < 0) {
+            throw new IllegalArgumentException("start: " + start);
+        }
+        if (end < start) {
+            throw new IllegalArgumentException("end < start: " + end + " < " + start);
+        }
+        int capacity = source.capacity();
+        if (end > source.capacity()) {
+            throw new IllegalArgumentException("end > capacity: " + end + " > " + capacity);
+        }
+        int originalLimit = source.limit();
+        int originalPosition = source.position();
+        try {
+            source.position(0);
+            source.limit(end);
+            source.position(start);
+            ByteBuffer result = source.slice();
+            result.order(source.order());
+            return result;
+        } finally {
+            source.position(0);
+            source.limit(originalLimit);
+            source.position(originalPosition);
+        }
+    }
+
+    /**
+     * Relative <em>get</em> method for reading {@code size} number of bytes from the current
+     * position of this buffer.
+     *
+     * <p>This method reads the next {@code size} bytes at this buffer's current position,
+     * returning them as a {@code ByteBuffer} with start set to 0, limit and capacity set to
+     * {@code size}, byte order set to this buffer's byte order; and then increments the position by
+     * {@code size}.
+     */
+    private static ByteBuffer getByteBuffer(ByteBuffer source, int size)
+            throws BufferUnderflowException {
+        if (size < 0) {
+            throw new IllegalArgumentException("size: " + size);
+        }
+        int originalLimit = source.limit();
+        int position = source.position();
+        int limit = position + size;
+        if ((limit < position) || (limit > originalLimit)) {
+            throw new BufferUnderflowException();
+        }
+        source.limit(limit);
+        try {
+            ByteBuffer result = source.slice();
+            result.order(source.order());
+            source.position(limit);
+            return result;
+        } finally {
+            source.limit(originalLimit);
+        }
+    }
+
+    private static ByteBuffer getLengthPrefixedSlice(ByteBuffer source) throws IOException {
+        if (source.remaining() < 4) {
+            throw new IOException(
+                    "Remaining buffer too short to contain length of length-prefixed field."
+                            + " Remaining: " + source.remaining());
+        }
+        int len = source.getInt();
+        if (len < 0) {
+            throw new IllegalArgumentException("Negative length");
+        } else if (len > source.remaining()) {
+            throw new IOException("Length-prefixed field longer than remaining buffer."
+                    + " Field length: " + len + ", remaining: " + source.remaining());
+        }
+        return getByteBuffer(source, len);
+    }
+
+    private static byte[] readLengthPrefixedByteArray(ByteBuffer buf) throws IOException {
+        int len = buf.getInt();
+        if (len < 0) {
+            throw new IOException("Negative length");
+        } else if (len > buf.remaining()) {
+            throw new IOException("Underflow while reading length-prefixed value. Length: " + len
+                    + ", available: " + buf.remaining());
+        }
+        byte[] result = new byte[len];
+        buf.get(result);
+        return result;
+    }
+
+    /**
+     * {@link X509Certificate} whose {@link #getEncoded()} returns the data provided at construction
+     * time.
+     */
+    private static class GuaranteedEncodedFormX509Certificate extends DelegatingX509Certificate {
+        private byte[] mEncodedForm;
+
+        public GuaranteedEncodedFormX509Certificate(X509Certificate wrapped, byte[] encodedForm) {
+            super(wrapped);
+            this.mEncodedForm = (encodedForm != null) ? encodedForm.clone() : null;
+        }
+
+        @Override
+        public byte[] getEncoded() throws CertificateEncodingException {
+            return (mEncodedForm != null) ? mEncodedForm.clone() : null;
+        }
+    }
+
+    private static final char[] HEX_DIGITS = "01234567890abcdef".toCharArray();
+
+    private static String toHex(byte[] value) {
+        StringBuilder sb = new StringBuilder(value.length * 2);
+        int len = value.length;
+        for (int i = 0; i < len; i++) {
+            int hi = (value[i] & 0xff) >>> 4;
+            int lo = value[i] & 0x0f;
+            sb.append(HEX_DIGITS[hi]).append(HEX_DIGITS[lo]);
+        }
+        return sb.toString();
+    }
+
+    public static class Result {
+
+        /** Whether the APK's APK Signature Scheme v2 signature verifies. */
+        public boolean verified;
+
+        public final List<SignerInfo> signers = new ArrayList<>();
+        private final List<IssueWithParams> mWarnings = new ArrayList<>();
+        private final List<IssueWithParams> mErrors = new ArrayList<>();
+
+        public boolean containsErrors() {
+            if (!mErrors.isEmpty()) {
+                return true;
+            }
+            if (!signers.isEmpty()) {
+                for (SignerInfo signer : signers) {
+                    if (signer.containsErrors()) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+        public void addError(Issue msg, Object... parameters) {
+            mErrors.add(new IssueWithParams(msg, parameters));
+        }
+
+        public void addWarning(Issue msg, Object... parameters) {
+            mWarnings.add(new IssueWithParams(msg, parameters));
+        }
+
+        public List<IssueWithParams> getErrors() {
+            return mErrors;
+        }
+
+        public List<IssueWithParams> getWarnings() {
+            return mWarnings;
+        }
+
+        public static class SignerInfo {
+            public int index;
+            public List<X509Certificate> certs = new ArrayList<>();
+            public List<ContentDigest> contentDigests = new ArrayList<>();
+            public Map<ContentDigestAlgorithm, byte[]> verifiedContentDigests = new HashMap<>();
+            public List<Signature> signatures = new ArrayList<>();
+            public Map<SignatureAlgorithm, byte[]> verifiedSignatures = new HashMap<>();
+            public List<AdditionalAttribute> additionalAttributes = new ArrayList<>();
+            public byte[] signedData;
+
+            private final List<IssueWithParams> mWarnings = new ArrayList<>();
+            private final List<IssueWithParams> mErrors = new ArrayList<>();
+
+            public void addError(Issue msg, Object... parameters) {
+                mErrors.add(new IssueWithParams(msg, parameters));
+            }
+
+            public void addWarning(Issue msg, Object... parameters) {
+                mWarnings.add(new IssueWithParams(msg, parameters));
+            }
+
+            public boolean containsErrors() {
+                return !mErrors.isEmpty();
+            }
+
+            public List<IssueWithParams> getErrors() {
+                return mErrors;
+            }
+
+            public List<IssueWithParams> getWarnings() {
+                return mWarnings;
+            }
+
+            public static class ContentDigest {
+                private final int mSignatureAlgorithmId;
+                private final byte[] mValue;
+
+                public ContentDigest(int signatureAlgorithmId, byte[] value) {
+                    mSignatureAlgorithmId  = signatureAlgorithmId;
+                    mValue = value;
+                }
+
+                public int getSignatureAlgorithmId() {
+                    return mSignatureAlgorithmId;
+                }
+
+                public byte[] getValue() {
+                    return mValue;
+                }
+            }
+
+            public static class Signature {
+                private final int mAlgorithmId;
+                private final byte[] mValue;
+
+                public Signature(int algorithmId, byte[] value) {
+                    mAlgorithmId  = algorithmId;
+                    mValue = value;
+                }
+
+                public int getAlgorithmId() {
+                    return mAlgorithmId;
+                }
+
+                public byte[] getValue() {
+                    return mValue;
+                }
+            }
+
+            public static class AdditionalAttribute {
+                private final int mId;
+                private final byte[] mValue;
+
+                public AdditionalAttribute(int id, byte[] value) {
+                    mId  = id;
+                    mValue = value.clone();
+                }
+
+                public int getId() {
+                    return mId;
+                }
+
+                public byte[] getValue() {
+                    return mValue.clone();
+                }
+            }
+        }
+    }
+}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/DelegatingX509Certificate.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/DelegatingX509Certificate.java
new file mode 100644
index 0000000..936cfa9
--- /dev/null
+++ b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/DelegatingX509Certificate.java
@@ -0,0 +1,179 @@
+/*
+ * 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.apksigner.core.internal.util;
+
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Set;
+
+/**
+ * {@link X509Certificate} which delegates all method invocations to the provided delegate
+ * {@code X509Certificate}.
+ */
+public class DelegatingX509Certificate extends X509Certificate {
+    private final X509Certificate mDelegate;
+
+    public DelegatingX509Certificate(X509Certificate delegate) {
+        this.mDelegate = delegate;
+    }
+
+    @Override
+    public Set<String> getCriticalExtensionOIDs() {
+        return mDelegate.getCriticalExtensionOIDs();
+    }
+
+    @Override
+    public byte[] getExtensionValue(String oid) {
+        return mDelegate.getExtensionValue(oid);
+    }
+
+    @Override
+    public Set<String> getNonCriticalExtensionOIDs() {
+        return mDelegate.getNonCriticalExtensionOIDs();
+    }
+
+    @Override
+    public boolean hasUnsupportedCriticalExtension() {
+        return mDelegate.hasUnsupportedCriticalExtension();
+    }
+
+    @Override
+    public void checkValidity()
+            throws CertificateExpiredException, CertificateNotYetValidException {
+        mDelegate.checkValidity();
+    }
+
+    @Override
+    public void checkValidity(Date date)
+            throws CertificateExpiredException, CertificateNotYetValidException {
+        mDelegate.checkValidity(date);
+    }
+
+    @Override
+    public int getVersion() {
+        return mDelegate.getVersion();
+    }
+
+    @Override
+    public BigInteger getSerialNumber() {
+        return mDelegate.getSerialNumber();
+    }
+
+    @Override
+    public Principal getIssuerDN() {
+        return mDelegate.getIssuerDN();
+    }
+
+    @Override
+    public Principal getSubjectDN() {
+        return mDelegate.getSubjectDN();
+    }
+
+    @Override
+    public Date getNotBefore() {
+        return mDelegate.getNotBefore();
+    }
+
+    @Override
+    public Date getNotAfter() {
+        return mDelegate.getNotAfter();
+    }
+
+    @Override
+    public byte[] getTBSCertificate() throws CertificateEncodingException {
+        return mDelegate.getTBSCertificate();
+    }
+
+    @Override
+    public byte[] getSignature() {
+        return mDelegate.getSignature();
+    }
+
+    @Override
+    public String getSigAlgName() {
+        return mDelegate.getSigAlgName();
+    }
+
+    @Override
+    public String getSigAlgOID() {
+        return mDelegate.getSigAlgOID();
+    }
+
+    @Override
+    public byte[] getSigAlgParams() {
+        return mDelegate.getSigAlgParams();
+    }
+
+    @Override
+    public boolean[] getIssuerUniqueID() {
+        return mDelegate.getIssuerUniqueID();
+    }
+
+    @Override
+    public boolean[] getSubjectUniqueID() {
+        return mDelegate.getSubjectUniqueID();
+    }
+
+    @Override
+    public boolean[] getKeyUsage() {
+        return mDelegate.getKeyUsage();
+    }
+
+    @Override
+    public int getBasicConstraints() {
+        return mDelegate.getBasicConstraints();
+    }
+
+    @Override
+    public byte[] getEncoded() throws CertificateEncodingException {
+        return mDelegate.getEncoded();
+    }
+
+    @Override
+    public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException,
+            InvalidKeyException, NoSuchProviderException, SignatureException {
+        mDelegate.verify(key);
+    }
+
+    @Override
+    public void verify(PublicKey key, String sigProvider)
+            throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
+            NoSuchProviderException, SignatureException {
+        mDelegate.verify(key, sigProvider);
+    }
+
+    @Override
+    public String toString() {
+        return mDelegate.toString();
+    }
+
+    @Override
+    public PublicKey getPublicKey() {
+        return mDelegate.getPublicKey();
+    }
+}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/MessageDigestSink.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/MessageDigestSink.java
similarity index 96%
rename from tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/MessageDigestSink.java
rename to tools/apksigner/core/src/com/android/apksigner/core/internal/util/MessageDigestSink.java
index 9ef04bf..45bb30e 100644
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/MessageDigestSink.java
+++ b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/MessageDigestSink.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.apksigner.core.internal.apk.v2;
+package com.android.apksigner.core.internal.util;
 
 import com.android.apksigner.core.util.DataSink;
 
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/ZipUtils.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/ZipUtils.java
index 51110b6..5e724a2 100644
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/ZipUtils.java
+++ b/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/ZipUtils.java
@@ -20,7 +20,6 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
-import com.android.apksigner.core.internal.util.ByteBufferSink;
 import com.android.apksigner.core.internal.util.Pair;
 import com.android.apksigner.core.util.DataSource;
 
@@ -175,11 +174,10 @@
         // Lower maxCommentSize if the file is too small.
         maxCommentSize = (int) Math.min(maxCommentSize, fileSize - ZIP_EOCD_REC_MIN_SIZE);
 
-        ByteBuffer buf = ByteBuffer.allocate(ZIP_EOCD_REC_MIN_SIZE + maxCommentSize);
+        int maxEocdSize = ZIP_EOCD_REC_MIN_SIZE + maxCommentSize;
+        long bufOffsetInFile = fileSize - maxEocdSize;
+        ByteBuffer buf = zip.getByteBuffer(bufOffsetInFile, maxEocdSize);
         buf.order(ByteOrder.LITTLE_ENDIAN);
-        long bufOffsetInFile = fileSize - buf.capacity();
-        zip.feed(bufOffsetInFile, buf.remaining(), new ByteBufferSink(buf));
-        buf.flip();
         int eocdOffsetInBuf = findZipEndOfCentralDirectoryRecord(buf);
         if (eocdOffsetInBuf == -1) {
             // No EoCD record found in the buffer
@@ -252,10 +250,8 @@
             return false;
         }
 
-        ByteBuffer sig = ByteBuffer.allocate(4);
+        ByteBuffer sig = zip.getByteBuffer(locatorPosition, 4);
         sig.order(ByteOrder.LITTLE_ENDIAN);
-        zip.feed(locatorPosition, sig.remaining(), new ByteBufferSink(sig));
-        sig.flip();
         return sig.getInt(0) == ZIP64_EOCD_LOCATOR_SIG;
     }
 
