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

Commit 86acec81 authored by Alex Klyubin's avatar Alex Klyubin Committed by android-build-merger
Browse files

Merge "Ignore signature stripping protection for preinstalled APKs." into nyc-dev am: e60d72f4

am: c860aecc

* commit 'c860aecc':
  Ignore signature stripping protection for preinstalled APKs.
parents caff4b1e c860aecc
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -1158,10 +1158,15 @@ public class PackageParser {
        StrictJarFile jarFile = null;
        try {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "strictJarFileCtor");
            // Ignore signature stripping protections when verifying APKs from system partition.
            // For those APKs we only care about extracting signer certificates, and don't care
            // about verifying integrity.
            boolean signatureSchemeRollbackProtectionsEnforced =
                    (parseFlags & PARSE_IS_SYSTEM) == 0;
            jarFile = new StrictJarFile(
                    apkPath,
                    !verified // whether to verify JAR signature
                    );
                    !verified, // whether to verify JAR signature
                    signatureSchemeRollbackProtectionsEnforced);
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

            // Always verify manifest, regardless of source
+20 −4
Original line number Diff line number Diff line
@@ -58,10 +58,21 @@ public final class StrictJarFile {

    public StrictJarFile(String fileName)
            throws IOException, SecurityException {
        this(fileName, true);
        this(fileName, true, true);
    }

    public StrictJarFile(String fileName, boolean verify)
    /**
     *
     * @param verify whether to verify the file's JAR signatures and collect the corresponding
     *        signer certificates.
     * @param signatureSchemeRollbackProtectionsEnforced {@code true} to enforce protections against
     *        stripping newer signature schemes (e.g., APK Signature Scheme v2) from the file, or
     *        {@code false} to ignore any such protections. This parameter is ignored when
     *        {@code verify} is {@code false}.
     */
    public StrictJarFile(String fileName,
            boolean verify,
            boolean signatureSchemeRollbackProtectionsEnforced)
                    throws IOException, SecurityException {
        this.nativeHandle = nativeOpenJarFile(fileName);
        this.raf = new RandomAccessFile(fileName, "r");
@@ -73,7 +84,12 @@ public final class StrictJarFile {
            if (verify) {
                HashMap<String, byte[]> metaEntries = getMetaEntries();
                this.manifest = new StrictJarManifest(metaEntries.get(JarFile.MANIFEST_NAME), true);
                this.verifier = new StrictJarVerifier(fileName, manifest, metaEntries);
                this.verifier =
                        new StrictJarVerifier(
                                fileName,
                                manifest,
                                metaEntries,
                                signatureSchemeRollbackProtectionsEnforced);
                Set<String> files = manifest.getEntries().keySet();
                for (String file : files) {
                    if (findEntry(file) == null) {
+42 −33
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ class StrictJarVerifier {
    private final StrictJarManifest manifest;
    private final HashMap<String, byte[]> metaEntries;
    private final int mainAttributesEnd;
    private final boolean signatureSchemeRollbackProtectionsEnforced;

    private final Hashtable<String, HashMap<String, Attributes>> signatures =
            new Hashtable<String, HashMap<String, Attributes>>(5);
@@ -164,13 +165,19 @@ class StrictJarVerifier {
     *
     * @param name
     *            the name of the JAR file being verified.
     *
     * @param signatureSchemeRollbackProtectionsEnforced {@code true} to enforce protections against
     *        stripping newer signature schemes (e.g., APK Signature Scheme v2) from the file, or
     *        {@code false} to ignore any such protections.
     */
    StrictJarVerifier(String name, StrictJarManifest manifest,
        HashMap<String, byte[]> metaEntries) {
        HashMap<String, byte[]> metaEntries, boolean signatureSchemeRollbackProtectionsEnforced) {
        jarName = name;
        this.manifest = manifest;
        this.metaEntries = metaEntries;
        this.mainAttributesEnd = manifest.getMainAttributesEnd();
        this.signatureSchemeRollbackProtectionsEnforced =
                signatureSchemeRollbackProtectionsEnforced;
    }

    /**
@@ -357,15 +364,16 @@ class StrictJarVerifier {
            return;
        }

        // Check whether APK Signature Scheme v2 signature was stripped.
        // If requested, check whether APK Signature Scheme v2 signature was stripped.
        if (signatureSchemeRollbackProtectionsEnforced) {
            String apkSignatureSchemeIdList =
                    attributes.getValue(
                            ApkSignatureSchemeV2Verifier.SF_ATTRIBUTE_ANDROID_APK_SIGNED_NAME);
            if (apkSignatureSchemeIdList != null) {
            // This field contains a comma-separated list of APK signature scheme IDs which were
            // used to sign this APK. If an ID is known to us, it means signatures of that scheme
            // were stripped from the APK because otherwise we wouldn't have fallen back to
            // verifying the APK using the JAR signature scheme.
                // This field contains a comma-separated list of APK signature scheme IDs which
                // were used to sign this APK. If an ID is known to us, it means signatures of that
                // scheme were stripped from the APK because otherwise we wouldn't have fallen back
                // to verifying the APK using the JAR signature scheme.
                boolean v2SignatureGenerated = false;
                StringTokenizer tokenizer = new StringTokenizer(apkSignatureSchemeIdList, ",");
                while (tokenizer.hasMoreTokens()) {
@@ -380,17 +388,18 @@ class StrictJarVerifier {
                        continue;
                    }
                    if (id == ApkSignatureSchemeV2Verifier.SF_ATTRIBUTE_ANDROID_APK_SIGNED_ID) {
                    // This APK was supposed to be signed with APK Signature Scheme v2 but no such
                    // signature was found.
                        // This APK was supposed to be signed with APK Signature Scheme v2 but no
                        // such signature was found.
                        v2SignatureGenerated = true;
                        break;
                    }
                }

                if (v2SignatureGenerated) {
                throw new SecurityException(signatureFile + " indicates " + jarName + " is signed"
                        + " using APK Signature Scheme v2, but no such signature was found."
                        + " Signature stripped?");
                    throw new SecurityException(signatureFile + " indicates " + jarName
                            + " is signed using APK Signature Scheme v2, but no such signature was"
                            + " found. Signature stripped?");
                }
            }
        }