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

Commit 7b1d7b37 authored by Robert Shih's avatar Robert Shih Committed by Automerger Merge Worker
Browse files

Merge "Report app signing cert digest in license requests" into sc-dev am: ce0d6a33

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13577929

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Ibaf957aa82a9720c8fdf293172ae0a8a63253033
parents 306022ae ce0d6a33
Loading
Loading
Loading
Loading
+78 −3
Original line number Diff line number Diff line
@@ -23,7 +23,11 @@ import android.annotation.Nullable;
import android.annotation.StringDef;
import android.annotation.TestApi;
import android.app.ActivityThread;
import android.app.Application;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.media.metrics.PlaybackComponent;
import android.os.Handler;
import android.os.HandlerExecutor;
@@ -39,7 +43,10 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
import java.time.Instant;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
@@ -144,6 +151,7 @@ public final class MediaDrm implements AutoCloseable {
    private static final String PERMISSION = android.Manifest.permission.ACCESS_DRM_CERTIFICATES;

    private long mNativeContext;
    private final String mAppPackageName;

    /**
     * Specify no certificate type
@@ -281,8 +289,9 @@ public final class MediaDrm implements AutoCloseable {
        /* Native setup requires a weak reference to our object.
         * It's easier to create it here than in C++.
         */
        mAppPackageName = ActivityThread.currentOpPackageName();
        native_setup(new WeakReference<MediaDrm>(this),
                getByteArrayFromUUID(uuid),  ActivityThread.currentOpPackageName());
                getByteArrayFromUUID(uuid), mAppPackageName);

        mCloseGuard.open("release");
    }
@@ -1144,12 +1153,78 @@ public final class MediaDrm implements AutoCloseable {
     * problem with the certifcate
     */
    @NonNull
    public native KeyRequest getKeyRequest(
    public KeyRequest getKeyRequest(
            @NonNull byte[] scope, @Nullable byte[] init,
            @Nullable String mimeType, @KeyType int keyType,
            @Nullable HashMap<String, String> optionalParameters)
            throws NotProvisionedException;
            throws NotProvisionedException {
        HashMap<String, String> internalParams;
        if (optionalParameters == null) {
            internalParams = new HashMap<>();
        } else {
            internalParams = new HashMap<>(optionalParameters);
        }
        byte[] rawBytes = getNewestAvailablePackageCertificateRawBytes();
        byte[] hashBytes = null;
        if (rawBytes != null) {
            hashBytes = getDigestBytes(rawBytes, "SHA-256");
        }
        if (hashBytes != null) {
            Base64.Encoder encoderB64 = Base64.getEncoder();
            String hashBytesB64 = encoderB64.encodeToString(hashBytes);
            internalParams.put("package_certificate_hash_bytes", hashBytesB64);
        }
        return getKeyRequestNative(scope, init, mimeType, keyType, internalParams);
    }

    @Nullable
    private byte[] getNewestAvailablePackageCertificateRawBytes() {
        Application application = ActivityThread.currentApplication();
        if (application == null) {
            Log.w(TAG, "pkg cert: Application is null");
            return null;
        }
        PackageManager pm = application.getPackageManager();
        if (pm == null) {
            Log.w(TAG, "pkg cert: PackageManager is null");
            return null;
        }
        PackageInfo packageInfo = null;
        try {
            packageInfo = pm.getPackageInfo(mAppPackageName,
                    PackageManager.GET_SIGNING_CERTIFICATES);
        } catch (PackageManager.NameNotFoundException e) {
            Log.w(TAG, mAppPackageName, e);
        }
        if (packageInfo == null || packageInfo.signingInfo == null) {
            Log.w(TAG, "pkg cert: PackageInfo or SigningInfo is null");
            return null;
        }
        Signature[] signers = packageInfo.signingInfo.getApkContentsSigners();
        if (signers != null && signers.length == 1) {
            return signers[0].toByteArray();
        }
        Log.w(TAG, "pkg cert: " + signers.length + " signers");
        return null;
    }

    @Nullable
    private static byte[] getDigestBytes(@NonNull byte[] rawBytes, @NonNull String algorithm) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
            return messageDigest.digest(rawBytes);
        } catch (NoSuchAlgorithmException e) {
            Log.w(TAG, algorithm, e);
        }
        return null;
    }

    @NonNull
    private native KeyRequest getKeyRequestNative(
            @NonNull byte[] scope, @Nullable byte[] init,
            @Nullable String mimeType, @KeyType int keyType,
            @Nullable HashMap<String, String> optionalParameters)
            throws NotProvisionedException;

    /**
     * A key response is received from the license server by the app, then it is
+1 −1
Original line number Diff line number Diff line
@@ -2056,7 +2056,7 @@ static const JNINativeMethod gMethods[] = {
    { "closeSessionNative", "([B)V",
      (void *)android_media_MediaDrm_closeSession },

    { "getKeyRequest", "([B[BLjava/lang/String;ILjava/util/HashMap;)"
    { "getKeyRequestNative", "([B[BLjava/lang/String;ILjava/util/HashMap;)"
      "Landroid/media/MediaDrm$KeyRequest;",
      (void *)android_media_MediaDrm_getKeyRequest },