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

Commit 9ff55740 authored by Patrick Baumann's avatar Patrick Baumann
Browse files

Returns signing version from ApkSignatureVerifier

This is a first step at a larger goal of moving instant app
verifications from parsing logic into install logic.

Test: manual - install v1 and v2 instant app and static lib
Test: android.appsecurity.cts.PkgInstallSignatureVerificationTest passes.
Change-Id: Iab50b91a6fb8ef014b573bb9f733d30c1aa6022f
Bug: 68860689
parent 1beb2684
Loading
Loading
Loading
Loading
+22 −29
Original line number Diff line number Diff line
@@ -87,7 +87,6 @@ import android.util.SparseArray;
import android.util.TypedValue;
import android.util.apk.ApkSignatureSchemeV2Verifier;
import android.util.apk.ApkSignatureVerifier;
import android.util.apk.SignatureNotFoundException;
import android.view.Gravity;

import com.android.internal.R;
@@ -1561,13 +1560,20 @@ public class PackageParser {

        boolean systemDir = (parseFlags & PARSE_IS_SYSTEM_DIR) != 0;
        int minSignatureScheme = ApkSignatureVerifier.VERSION_JAR_SIGNATURE_SCHEME;
        if ((parseFlags & PARSE_IS_EPHEMERAL) != 0 || pkg.applicationInfo.isStaticSharedLibrary()) {
        if (pkg.applicationInfo.isStaticSharedLibrary()) {
            // must use v2 signing scheme
            minSignatureScheme = ApkSignatureVerifier.VERSION_APK_SIGNATURE_SCHEME_V2;
        }
        try {
        ApkSignatureVerifier.Result verified =
                ApkSignatureVerifier.verify(apkPath, minSignatureScheme, systemDir);
        if (verified.signatureSchemeVersion
                < ApkSignatureVerifier.VERSION_APK_SIGNATURE_SCHEME_V2) {
            // TODO (b/68860689): move this logic to packagemanagerserivce
            if ((parseFlags & PARSE_IS_EPHEMERAL) != 0) {
                throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
                        "No APK Signature Scheme v2 signature in ephemeral package " + apkPath);
            }
        }
        if (pkg.mCertificates == null) {
            pkg.mCertificates = verified.certs;
            pkg.mSignatures = verified.sigs;
@@ -1584,19 +1590,6 @@ public class PackageParser {
                        apkPath + " has mismatched certificates");
            }
        }
        } catch (SignatureNotFoundException e) {
            if ((parseFlags & PARSE_IS_EPHEMERAL) != 0) {
                throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
                        "No APK Signature Scheme v2 signature in ephemeral package " + apkPath,
                        e);
            }
            if (pkg.applicationInfo.isStaticSharedLibrary()) {
                throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
                        "Static shared libs must use v2 signature scheme " + apkPath);
            }
            throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
                    "No APK Signature Scheme v2 signature in package " + apkPath, e);
        }
    }

    private static AssetManager newConfiguredAssetManager() {
+9 −11
Original line number Diff line number Diff line
@@ -65,18 +65,14 @@ public class ApkSignatureVerifier {
     *                  v2 stripping rollback protection, or verify integrity of the APK.
     *
     * @throws PackageParserException if the APK's signature failed to verify.
     * @throws SignatureNotFoundException if a signature corresponding to minLevel or greater
     * is not found, except in the case of no JAR signature.
     */
    public static Result verify(String apkPath, int minSignatureSchemeVersion, boolean systemDir)
            throws PackageParserException, SignatureNotFoundException {
        boolean verified = false;
        Certificate[][] signerCerts;
        int level = VERSION_APK_SIGNATURE_SCHEME_V2;
            throws PackageParserException {

        // first try v2
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "verifyV2");
        try {
            Certificate[][] signerCerts;
            signerCerts = ApkSignatureSchemeV2Verifier.verify(apkPath);
            Signature[] signerSigs = convertToSignatures(signerCerts);

@@ -93,12 +89,12 @@ public class ApkSignatureVerifier {
            } finally {
                closeQuietly(jarFile);
            }
            return new Result(signerCerts, signerSigs);
            return new Result(signerCerts, signerSigs, VERSION_APK_SIGNATURE_SCHEME_V2);
        } catch (SignatureNotFoundException e) {
            // not signed with v2, try older if allowed
            if (minSignatureSchemeVersion >= VERSION_APK_SIGNATURE_SCHEME_V2) {
                throw new SignatureNotFoundException(
                        "No APK Signature Scheme v2 signature found for " + apkPath, e);
                throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
                        "No APK Signature Scheme v2 signature in package " + apkPath, e);
            }
        } catch (PackageParserException e) {
            // preserve any new exceptions explicitly thrown here
@@ -178,7 +174,7 @@ public class ApkSignatureVerifier {
                    }
                }
            }
            return new Result(lastCerts, lastSigs);
            return new Result(lastCerts, lastSigs, VERSION_JAR_SIGNATURE_SCHEME);
        } catch (GeneralSecurityException e) {
            throw new PackageParserException(INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING,
                    "Failed to collect certificates from " + apkPath, e);
@@ -254,10 +250,12 @@ public class ApkSignatureVerifier {
    public static class Result {
        public final Certificate[][] certs;
        public final Signature[] sigs;
        public final int signatureSchemeVersion;

        public Result(Certificate[][] certs, Signature[] sigs) {
        public Result(Certificate[][] certs, Signature[] sigs, int signingVersion) {
            this.certs = certs;
            this.sigs = sigs;
            this.signatureSchemeVersion = signingVersion;
        }
    }
}