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

Commit 8b7cc7fb authored by Victor Hsieh's avatar Victor Hsieh
Browse files

Fallback to sha256 when preferred checksum failed

Bug: 265467404
Test: Manually remove the signing block of an updated preload, run the
      job.  Saw a local debugging log of sha256 measurement.
Change-Id: I8a4de6ce01a5bfc0c021ece6dbb6efffce9eba25
parent 35b1662e
Loading
Loading
Loading
Loading
+27 −14
Original line number Diff line number Diff line
@@ -184,24 +184,15 @@ public final class PackageUtils {
    }

    /**
     * @see #computeSha256DigestForLargeFile(String, byte[], String)
     */
    public static @Nullable String computeSha256DigestForLargeFile(@NonNull String filePath,
            @NonNull byte[] fileBuffer) {
        return computeSha256DigestForLargeFile(filePath, fileBuffer, null);
    }

    /**
     * Computes the SHA256 digest of large files. This is typically useful for large APEXs.
     * Computes the SHA256 digest of a large file.
     * @param filePath The path to which the file's content is to be hashed.
     * @param fileBuffer A buffer to read file's content into memory. It is strongly recommended to
     *                   make use of the {@link #createLargeFileBuffer()} method to create this
     *                   buffer.
     * @param separator Separator between each pair of characters, such as colon, or null to omit.
     * @return The SHA256 digest or null if an error occurs.
     * @return The byte array of SHA256 digest or null if an error occurs.
     */
    public static @Nullable String computeSha256DigestForLargeFile(@NonNull String filePath,
            @NonNull byte[] fileBuffer, @Nullable String separator) {
    public static @Nullable byte[] computeSha256DigestForLargeFileAsBytes(@NonNull String filePath,
            @NonNull byte[] fileBuffer) {
        MessageDigest messageDigest;
        try {
            messageDigest = MessageDigest.getInstance("SHA256");
@@ -221,8 +212,30 @@ public final class PackageUtils {
            return null;
        }

        byte[] resultBytes = messageDigest.digest();
        return messageDigest.digest();
    }

    /**
     * @see #computeSha256DigestForLargeFile(String, byte[], String)
     */
    public static @Nullable String computeSha256DigestForLargeFile(@NonNull String filePath,
            @NonNull byte[] fileBuffer) {
        return computeSha256DigestForLargeFile(filePath, fileBuffer, null);
    }

    /**
     * Computes the SHA256 digest of a large file.
     * @param filePath The path to which the file's content is to be hashed.
     * @param fileBuffer A buffer to read file's content into memory. It is strongly recommended to
     *                   make use of the {@link #createLargeFileBuffer()} method to create this
     *                   buffer.
     * @param separator Separator between each pair of characters, such as colon, or null to omit.
     * @see #computeSha256DigestForLargeFile(String, byte[])
     * @return The encoded string of SHA256 digest or null if an error occurs.
     */
    public static @Nullable String computeSha256DigestForLargeFile(@NonNull String filePath,
            @NonNull byte[] fileBuffer, @Nullable String separator) {
        byte[] resultBytes = computeSha256DigestForLargeFileAsBytes(filePath, fileBuffer);
        if (separator == null) {
            return HexEncoding.encodeToString(resultBytes, false);
        }
+18 −18
Original line number Diff line number Diff line
@@ -263,13 +263,12 @@ public class BinaryTransparencyService extends SystemService {
            Map<Integer, byte[]> contentDigests = computeApkContentDigest(apkPath);
            if (contentDigests == null) {
                Slog.d(TAG, "Failed to compute content digest for " + apkPath);
                return new Checksum(0, new byte[] { -1 });
            }

            } else {
                // in this iteration, we'll be supporting only 2 types of digests:
                // CHUNKED_SHA256 and CHUNKED_SHA512.
                // And only one of them will be available per package.
            if (contentDigests.containsKey(ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA256)) {
                if (contentDigests.containsKey(
                            ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA256)) {
                    return new Checksum(
                            Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256,
                            contentDigests.get(ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA256));
@@ -278,12 +277,13 @@ public class BinaryTransparencyService extends SystemService {
                    return new Checksum(
                            Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512,
                            contentDigests.get(ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA512));
            } else {
                // TODO(b/259423111): considering putting the raw values for the algorithm & digest
                //  into the bundle to track potential other digest algorithms that may be in use
                return new Checksum(0, new byte[] { -1 });
                }
            }
            // When something went wrong, fall back to simple sha256.
            byte[] digest = PackageUtils.computeSha256DigestForLargeFileAsBytes(apkPath,
                    PackageUtils.createLargeFileBuffer());
            return new Checksum(Checksum.TYPE_WHOLE_SHA256, digest);
        }


        /**