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

Commit 703df7f0 authored by Todd Kennedy's avatar Todd Kennedy Committed by android-build-merger
Browse files

Merge "dump apk signing version" into nyc-dev am: 40a6e6a1

am: 8b25c1ba

* commit '8b25c1ba':
  dump apk signing version
parents 90bbe397 8b25c1ba
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -121,6 +121,10 @@ public class PackageParser {

    private static final int MAX_PACKAGES_PER_APK = 5;

    public static final int APK_SIGNING_UNKNOWN = 0;
    public static final int APK_SIGNING_V1 = 1;
    public static final int APK_SIGNING_V2 = 2;

    // TODO: switch outError users to PackageParserException
    // TODO: refactor "codePath" to "apkPath"

@@ -1058,12 +1062,24 @@ public class PackageParser {
        return pkg;
    }

    public static int getApkSigningVersion(Package pkg) {
        try {
            if (ApkSignatureSchemeV2Verifier.hasSignature(pkg.baseCodePath)) {
                return APK_SIGNING_V2;
            }
            return APK_SIGNING_V1;
        } catch (IOException e) {
        }
        return APK_SIGNING_UNKNOWN;
    }

    /**
     * Collect certificates from all the APKs described in the given package,
     * populating {@link Package#mSignatures}. Also asserts that all APK
     * contents are signed correctly and consistently.
     */
    public static void collectCertificates(Package pkg, int parseFlags) throws PackageParserException {
    public static void collectCertificates(Package pkg, int parseFlags)
            throws PackageParserException {
        collectCertificatesInternal(pkg, parseFlags);
        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
        for (int i = 0; i < childCount; i++) {
@@ -1074,7 +1090,8 @@ public class PackageParser {
        }
    }

    private static void collectCertificatesInternal(Package pkg, int parseFlags) throws PackageParserException {
    private static void collectCertificatesInternal(Package pkg, int parseFlags)
            throws PackageParserException {
        pkg.mCertificates = null;
        pkg.mSignatures = null;
        pkg.mSigningKeys = null;
+69 −25
Original line number Diff line number Diff line
@@ -74,6 +74,36 @@ public class ApkSignatureSchemeV2Verifier {
    public static final String SF_ATTRIBUTE_ANDROID_APK_SIGNED_NAME = "X-Android-APK-Signed";
    public static final int SF_ATTRIBUTE_ANDROID_APK_SIGNED_ID = 2;

    /**
     * Returns {@code true} if the provided APK contains an APK Signature Scheme V2
     * signature. The signature will not be verified.
     */
    public static boolean hasSignature(String apkFile) throws IOException {
        try (RandomAccessFile apk = new RandomAccessFile(apkFile, "r")) {
            long fileSize = apk.length();
            if (fileSize > Integer.MAX_VALUE) {
                return false;
            }
            MappedByteBuffer apkContents =
                    apk.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, fileSize);
            // ZipUtils and APK Signature Scheme v2 verifier expect little-endian byte order.
            apkContents.order(ByteOrder.LITTLE_ENDIAN);

            final int centralDirOffset =
                    (int) getCentralDirOffset(apkContents, getEocdOffset(apkContents));
            // Find the APK Signing Block.
            int apkSigningBlockOffset = findApkSigningBlock(apkContents, centralDirOffset);
            ByteBuffer apkSigningBlock =
                    sliceFromTo(apkContents, apkSigningBlockOffset, centralDirOffset);

            // Find the APK Signature Scheme v2 Block inside the APK Signing Block.
            findApkSignatureSchemeV2Block(apkSigningBlock);
            return true;
        } catch (SignatureNotFoundException e) {
        }
        return false;
    }

    /**
     * Verifies APK Signature Scheme v2 signatures of the provided APK and returns the certificates
     * associated with each signer.
@@ -130,31 +160,8 @@ public class ApkSignatureSchemeV2Verifier {
        // ZipUtils and APK Signature Scheme v2 verifier expect little-endian byte order.
        apkContents.order(ByteOrder.LITTLE_ENDIAN);

        // Find the offset of ZIP End of Central Directory (EoCD)
        int eocdOffset = ZipUtils.findZipEndOfCentralDirectoryRecord(apkContents);
        if (eocdOffset == -1) {
            throw new SignatureNotFoundException(
                    "Not an APK file: ZIP End of Central Directory record not found");
        }
        if (ZipUtils.isZip64EndOfCentralDirectoryLocatorPresent(apkContents, eocdOffset)) {
            throw new SignatureNotFoundException("ZIP64 APK not supported");
        }
        ByteBuffer eocd = sliceFromTo(apkContents, eocdOffset, apkContents.capacity());

        // Look up the offset of ZIP Central Directory.
        long centralDirOffsetLong = ZipUtils.getZipEocdCentralDirectoryOffset(eocd);
        if (centralDirOffsetLong >= eocdOffset) {
            throw new SignatureNotFoundException(
                    "ZIP Central Directory offset out of range: " + centralDirOffsetLong
                    + ". ZIP End of Central Directory offset: " + eocdOffset);
        }
        long centralDirSizeLong = ZipUtils.getZipEocdCentralDirectorySizeBytes(eocd);
        if (centralDirOffsetLong + centralDirSizeLong != eocdOffset) {
            throw new SignatureNotFoundException(
                    "ZIP Central Directory is not immediately followed by End of Central"
                    + " Directory");
        }
        int centralDirOffset = (int) centralDirOffsetLong;
        final int eocdOffset = getEocdOffset(apkContents);
        final int centralDirOffset = (int) getCentralDirOffset(apkContents, eocdOffset);

        // Find the APK Signing Block.
        int apkSigningBlockOffset = findApkSigningBlock(apkContents, centralDirOffset);
@@ -499,6 +506,43 @@ public class ApkSignatureSchemeV2Verifier {
        return result;
    }

    /**
     * Finds the offset of ZIP End of Central Directory (EoCD).
     *
     * @throws SignatureNotFoundException If the EoCD could not be found
     */
    private static int getEocdOffset(ByteBuffer apkContents) throws SignatureNotFoundException {
        int eocdOffset = ZipUtils.findZipEndOfCentralDirectoryRecord(apkContents);
        if (eocdOffset == -1) {
            throw new SignatureNotFoundException(
                    "Not an APK file: ZIP End of Central Directory record not found");
        }
        return eocdOffset;
    }

    private static long getCentralDirOffset(ByteBuffer apkContents, int eocdOffset)
            throws SignatureNotFoundException {
        if (ZipUtils.isZip64EndOfCentralDirectoryLocatorPresent(apkContents, eocdOffset)) {
            throw new SignatureNotFoundException("ZIP64 APK not supported");
        }
        ByteBuffer eocd = sliceFromTo(apkContents, eocdOffset, apkContents.capacity());

        // Look up the offset of ZIP Central Directory.
        long centralDirOffsetLong = ZipUtils.getZipEocdCentralDirectoryOffset(eocd);
        if (centralDirOffsetLong >= eocdOffset) {
            throw new SignatureNotFoundException(
                    "ZIP Central Directory offset out of range: " + centralDirOffsetLong
                    + ". ZIP End of Central Directory offset: " + eocdOffset);
        }
        long centralDirSizeLong = ZipUtils.getZipEocdCentralDirectorySizeBytes(eocd);
        if (centralDirOffsetLong + centralDirSizeLong != eocdOffset) {
            throw new SignatureNotFoundException(
                    "ZIP Central Directory is not immediately followed by End of Central"
                    + " Directory");
        }
        return centralDirOffsetLong;
    }

    private static final int getChunkCount(int inputSizeBytes) {
        return (inputSizeBytes + CHUNK_SIZE_BYTES - 1) / CHUNK_SIZE_BYTES;
    }
+4 −1
Original line number Diff line number Diff line
@@ -2604,7 +2604,6 @@ final class Settings {
        if (pkg.volumeUuid != null) {
            serializer.attribute(null, "volumeUuid", pkg.volumeUuid);
        }

        if (pkg.parentPackageName != null) {
            serializer.attribute(null, "parentPackageName", pkg.parentPackageName);
        }
@@ -4316,6 +4315,10 @@ final class Settings {
            }
            pw.print(prefix); pw.print("  versionName="); pw.println(ps.pkg.mVersionName);
            pw.print(prefix); pw.print("  splits="); dumpSplitNames(pw, ps.pkg); pw.println();
            final int apkSigningVersion = PackageParser.getApkSigningVersion(ps.pkg);
            if (apkSigningVersion != PackageParser.APK_SIGNING_UNKNOWN) {
                pw.print(prefix); pw.print("  apkSigningVersion="); pw.println(apkSigningVersion);
            }
            pw.print(prefix); pw.print("  applicationInfo=");
                pw.println(ps.pkg.applicationInfo.toString());
            pw.print(prefix); pw.print("  flags="); printFlags(pw, ps.pkg.applicationInfo.flags,