Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 28a541ff authored by Alex Buynytskyy's avatar Alex Buynytskyy Committed by Android (Google) Code Review
Browse files

Merge "Optimization to avoid parsing v2/v3/v31 blocks."

parents 3baf0f06 0de533f5
Loading
Loading
Loading
Loading
+12 −15
Original line number Diff line number Diff line
@@ -61,14 +61,15 @@ public class ApkSignatureSchemeV4Verifier {
     */
    public static VerifiedSigner extractCertificates(String apkFile)
            throws SignatureNotFoundException, SecurityException {
        V4Signature signature = extractSignature(apkFile);
        return verify(apkFile, signature, APK_SIGNATURE_SCHEME_DEFAULT);
        Pair<V4Signature.HashingInfo, V4Signature.SigningInfos> pair = extractSignature(apkFile);
        return verify(apkFile, pair.first, pair.second, APK_SIGNATURE_SCHEME_DEFAULT);
    }

    /**
     * Extracts APK Signature Scheme v4 signature of the provided APK.
     */
    public static V4Signature extractSignature(String apkFile) throws SignatureNotFoundException {
    public static Pair<V4Signature.HashingInfo, V4Signature.SigningInfos> extractSignature(
            String apkFile) throws SignatureNotFoundException {
        final File apk = new File(apkFile);
        final byte[] signatureBytes = IncrementalManager.unsafeGetFileSignature(
                apk.getAbsolutePath());
@@ -81,7 +82,11 @@ public class ApkSignatureSchemeV4Verifier {
                throw new SecurityException(
                        "v4 signature version " + signature.version + " is not supported");
            }
            return signature;
            final V4Signature.HashingInfo hashingInfo = V4Signature.HashingInfo.fromByteArray(
                    signature.hashingInfo);
            final V4Signature.SigningInfos signingInfos = V4Signature.SigningInfos.fromByteArray(
                    signature.signingInfos);
            return Pair.create(hashingInfo, signingInfos);
        } catch (IOException e) {
            throw new SignatureNotFoundException("Failed to read V4 signature.", e);
        }
@@ -91,17 +96,9 @@ public class ApkSignatureSchemeV4Verifier {
     * Verifies APK Signature Scheme v4 signature and returns the
     * certificates associated with each signer.
     */
    public static VerifiedSigner verify(String apkFile, final V4Signature signature,
            final int v3BlockId) throws SignatureNotFoundException, SecurityException {
        final V4Signature.HashingInfo hashingInfo;
        final V4Signature.SigningInfos signingInfos;
        try {
            hashingInfo = V4Signature.HashingInfo.fromByteArray(signature.hashingInfo);
            signingInfos = V4Signature.SigningInfos.fromByteArray(signature.signingInfos);
        } catch (IOException e) {
            throw new SignatureNotFoundException("Failed to read V4 signature.", e);
        }

    public static VerifiedSigner verify(String apkFile, final V4Signature.HashingInfo hashingInfo,
            final V4Signature.SigningInfos signingInfos, final int v3BlockId)
            throws SignatureNotFoundException, SecurityException {
        final V4Signature.SigningInfo signingInfo = findSigningInfoForBlockId(signingInfos,
                v3BlockId);

+39 −32
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.content.pm.parsing.result.ParseResult;
import android.os.Build;
import android.os.Trace;
import android.os.incremental.V4Signature;
import android.util.Pair;
import android.util.jar.StrictJarFile;

import com.android.internal.util.ArrayUtils;
@@ -191,15 +192,19 @@ public class ApkSignatureVerifier {
            boolean verifyFull) throws SignatureNotFoundException {
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, verifyFull ? "verifyV4" : "certsOnlyV4");
        try {
            final V4Signature v4Signature = ApkSignatureSchemeV4Verifier.extractSignature(apkPath);
            final Pair<V4Signature.HashingInfo, V4Signature.SigningInfos> v4Pair =
                    ApkSignatureSchemeV4Verifier.extractSignature(apkPath);
            final V4Signature.HashingInfo hashingInfo = v4Pair.first;
            final V4Signature.SigningInfos signingInfos = v4Pair.second;

            Signature[] pastSignerSigs = null;

            Map<Integer, byte[]> nonstreamingDigests;
            Certificate[][] nonstreamingCerts;
            Map<Integer, byte[]> nonstreamingDigests = null;
            Certificate[][] nonstreamingCerts = null;

            int v3BlockId = APK_SIGNATURE_SCHEME_DEFAULT;

            // If V4 contains additional signing blocks then we need to always run v2/v3 verifier
            // to figure out which block they use.
            if (verifyFull || signingInfos.signingInfoBlocks.length > 0) {
                try {
                    // v4 is an add-on and requires v2 or v3 signature to validate against its
                    // certificate and digest
@@ -229,9 +234,11 @@ public class ApkSignatureVerifier {
                                        + apkPath, ee);
                    }
                }
            }

            ApkSignatureSchemeV4Verifier.VerifiedSigner vSigner =
                    ApkSignatureSchemeV4Verifier.verify(apkPath, v4Signature, v3BlockId);
                    ApkSignatureSchemeV4Verifier.verify(apkPath, hashingInfo, signingInfos,
                            v3BlockId);
            Certificate[][] signerCerts = new Certificate[][]{vSigner.certs};
            Signature[] signerSigs = convertToSignatures(signerCerts);