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

Commit 19293693 authored by Kevin Chyn's avatar Kevin Chyn Committed by Android (Google) Code Review
Browse files

Merge changes from topics "async-challenge", "lss-sp"

* changes:
  Remove GenerateChallengeBlocking from FingerprintManager
  Change GenerateChallengeCallback from abstract class to interface
  3/n: Remove challenge from verifyCredential
  2/n: Remove unnecessary RequestThrottledException for verify paths
  1/n: Allow LockSettingsService to return Gatekeeper Password
parents ed4b9396 0bca835e
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -1073,12 +1073,12 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
    /**
     * @hide
     */
    public abstract static class GenerateChallengeCallback {
        public abstract void onGenerateChallengeResult(long challenge);
    public interface GenerateChallengeCallback {
        void onGenerateChallengeResult(long challenge);
    }

    private abstract static class InternalGenerateChallengeCallback
            extends GenerateChallengeCallback {}
            implements GenerateChallengeCallback {}

    private class OnEnrollCancelListener implements OnCancelListener {
        @Override
+3 −34
Original line number Diff line number Diff line
@@ -377,12 +377,12 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
    /**
     * @hide
     */
    public abstract static class GenerateChallengeCallback {
        public abstract void onChallengeGenerated(long challenge);
    public interface GenerateChallengeCallback {
        void onChallengeGenerated(long challenge);
    }

    private abstract static class InternalGenerateChallengeCallback
            extends GenerateChallengeCallback {}
            implements GenerateChallengeCallback {}

    /**
     * Request authentication of a crypto object. This call warms up the fingerprint hardware
@@ -580,37 +580,6 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
        }
    }

    /**
     * Same as {@link #generateChallenge(GenerateChallengeCallback)}, except blocks until the
     * TEE/hardware operation is complete.
     * @return challenge generated in the TEE/hardware
     * @hide
     */
    @RequiresPermission(MANAGE_FINGERPRINT)
    public long generateChallengeBlocking() {
        final AtomicReference<Long> result = new AtomicReference<>();
        final CountDownLatch latch = new CountDownLatch(1);
        final GenerateChallengeCallback callback = new InternalGenerateChallengeCallback() {
            @Override
            public void onChallengeGenerated(long challenge) {
                result.set(challenge);
                latch.countDown();
            }
        };

        generateChallenge(callback);

        try {
            latch.await(1, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Slog.e(TAG, "Interrupted while generatingChallenge", e);
            e.printStackTrace();
        }

        return result.get();
    }


    /**
     * Generates a unique random challenge in the TEE. A typical use case is to have it wrapped in a
     * HardwareAuthenticationToken, minted by Gatekeeper upon PIN/Pattern/Password verification.
+3 −2
Original line number Diff line number Diff line
@@ -47,8 +47,9 @@ interface ILockSettings {
    void resetKeyStore(int userId);
    VerifyCredentialResponse checkCredential(in LockscreenCredential credential, int userId,
            in ICheckCredentialProgressCallback progressCallback);
    VerifyCredentialResponse verifyCredential(in LockscreenCredential credential, long challenge, int userId);
    VerifyCredentialResponse verifyTiedProfileChallenge(in LockscreenCredential credential, long challenge, int userId);
    VerifyCredentialResponse verifyCredential(in LockscreenCredential credential, int userId, int flags);
    VerifyCredentialResponse verifyTiedProfileChallenge(in LockscreenCredential credential, int userId, int flags);
    VerifyCredentialResponse verifyGatekeeperPassword(in byte[] gatekeeperPassword, long challenge, int userId);
    boolean checkVoldPassword(int userId);
    int getCredentialType(int userId);
    byte[] getHashFactor(in LockscreenCredential currentCredential, int userId);
+21 −32
Original line number Diff line number Diff line
package com.android.internal.widget;

import android.annotation.NonNull;
import android.os.AsyncTask;

import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
@@ -41,11 +42,11 @@ public final class LockPatternChecker {
        /**
         * Invoked when a security verification is finished.
         *
         * @param attestation The attestation that the challenge was verified, or null.
         * @param response The response, optionally containing Gatekeeper HAT or Gatekeeper Password
         * @param throttleTimeoutMs The amount of time in ms to wait before reattempting
         * the call. Only non-0 if attestation is null.
         * the call. Only non-0 if the response is {@link VerifyCredentialResponse#RESPONSE_RETRY}.
         */
        void onVerified(byte[] attestation, int throttleTimeoutMs);
        void onVerified(@NonNull VerifyCredentialResponse response, int throttleTimeoutMs);
    }

    /**
@@ -53,33 +54,27 @@ public final class LockPatternChecker {
     *
     * @param utils The LockPatternUtils instance to use.
     * @param credential The credential to check.
     * @param challenge The challenge to verify against the credential.
     * @param userId The user to check against the credential.
     * @param flags See {@link LockPatternUtils.VerifyFlag}
     * @param callback The callback to be invoked with the verification result.
     */
    public static AsyncTask<?, ?, ?> verifyCredential(final LockPatternUtils utils,
            final LockscreenCredential credential,
            final long challenge,
            final int userId,
            final @LockPatternUtils.VerifyFlag int flags,
            final OnVerifyCallback callback) {
        // Create a copy of the credential since checking credential is asynchrounous.
        final LockscreenCredential credentialCopy = credential.duplicate();
        AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() {
            private int mThrottleTimeout;

        AsyncTask<Void, Void, VerifyCredentialResponse> task =
                new AsyncTask<Void, Void, VerifyCredentialResponse>() {
            @Override
            protected byte[] doInBackground(Void... args) {
                try {
                    return utils.verifyCredential(credentialCopy, challenge, userId);
                } catch (RequestThrottledException ex) {
                    mThrottleTimeout = ex.getTimeoutMs();
                    return null;
                }
            protected VerifyCredentialResponse doInBackground(Void... args) {
                return utils.verifyCredential(credentialCopy, userId, flags);
            }

            @Override
            protected void onPostExecute(byte[] result) {
                callback.onVerified(result, mThrottleTimeout);
            protected void onPostExecute(@NonNull VerifyCredentialResponse result) {
                callback.onVerified(result, result.getTimeout());
                credentialCopy.zeroize();
            }

@@ -141,33 +136,27 @@ public final class LockPatternChecker {
     *
     * @param utils The LockPatternUtils instance to use.
     * @param credential The credential to check.
     * @param challenge The challenge to verify against the credential.
     * @param userId The user to check against the credential.
     * @param flags See {@link LockPatternUtils.VerifyFlag}
     * @param callback The callback to be invoked with the verification result.
     */
    public static AsyncTask<?, ?, ?> verifyTiedProfileChallenge(final LockPatternUtils utils,
            final LockscreenCredential credential,
            final long challenge,
            final int userId,
            final @LockPatternUtils.VerifyFlag int flags,
            final OnVerifyCallback callback) {
        // Create a copy of the credential since checking credential is asynchrounous.
        // Create a copy of the credential since checking credential is asynchronous.
        final LockscreenCredential credentialCopy = credential.duplicate();
        AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() {
            private int mThrottleTimeout;

        AsyncTask<Void, Void, VerifyCredentialResponse> task =
                new AsyncTask<Void, Void, VerifyCredentialResponse>() {
            @Override
            protected byte[] doInBackground(Void... args) {
                try {
                    return utils.verifyTiedProfileChallenge(credentialCopy, challenge, userId);
                } catch (RequestThrottledException ex) {
                    mThrottleTimeout = ex.getTimeoutMs();
                    return null;
                }
            protected VerifyCredentialResponse doInBackground(Void... args) {
                return utils.verifyTiedProfileChallenge(credentialCopy, userId, flags);
            }

            @Override
            protected void onPostExecute(byte[] result) {
                callback.onVerified(result, mThrottleTimeout);
            protected void onPostExecute(@NonNull VerifyCredentialResponse response) {
                callback.onVerified(response, response.getTimeout());
                credentialCopy.zeroize();
            }

+56 −30
Original line number Diff line number Diff line
@@ -129,6 +129,18 @@ public class LockPatternUtils {
    })
    public @interface CredentialType {}

    /**
     * Flag provided to {@link #verifyCredential(LockscreenCredential, long, int, int)} . If set,
     * the method will return the Gatekeeper Password in the {@link VerifyCredentialResponse}.
     */
    public static final int VERIFY_FLAG_RETURN_GK_PW = 1 << 0;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(flag = true, value = {
            VERIFY_FLAG_RETURN_GK_PW
    })
    public @interface VerifyFlag {}

    /**
     * Special user id for triggering the FRP verification flow.
     */
@@ -374,29 +386,46 @@ public class LockPatternUtils {
     * If credential matches, return an opaque attestation that the challenge was verified.
     *
     * @param credential The credential to check.
     * @param challenge The challenge to verify against the credential
     * @param userId The user whose credential is being verified
     * @return the attestation that the challenge was verified, or null
     * @throws RequestThrottledException if credential verification is being throttled due to
     *         to many incorrect attempts.
     * @param flags See {@link VerifyFlag}
     * @throws IllegalStateException if called on the main thread.
     */
    public byte[] verifyCredential(@NonNull LockscreenCredential credential, long challenge,
            int userId) throws RequestThrottledException {
    @NonNull
    public VerifyCredentialResponse verifyCredential(@NonNull LockscreenCredential credential,
            int userId, @VerifyFlag int flags) {
        throwIfCalledOnMainThread();
        try {
            VerifyCredentialResponse response = getLockSettings().verifyCredential(
                    credential, challenge, userId);
            if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
                return response.getPayload();
            } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
                throw new RequestThrottledException(response.getTimeout());
            final VerifyCredentialResponse response = getLockSettings().verifyCredential(
                    credential, userId, flags);
            if (response == null) {
                return VerifyCredentialResponse.ERROR;
            } else {
                return null;
                return response;
            }
        } catch (RemoteException re) {
            Log.e(TAG, "failed to verify credential", re);
            return null;
            return VerifyCredentialResponse.ERROR;
        }
    }

    /**
     * With the Gatekeeper Password returned via {@link #verifyCredential(LockscreenCredential,
     * int, int)}, request Gatekeeper to create a HardwareAuthToken wrapping the given
     * challenge.
     */
    @NonNull
    public VerifyCredentialResponse verifyGatekeeperPassword(@NonNull byte[] gatekeeperPassword,
            long challenge, int userId) {
        try {
            final VerifyCredentialResponse response = getLockSettings().verifyGatekeeperPassword(
                    gatekeeperPassword, challenge, userId);
            if (response == null) {
                return VerifyCredentialResponse.ERROR;
            }
            return response;
        } catch (RemoteException e) {
            Log.e(TAG, "failed to verify gatekeeper password", e);
            return VerifyCredentialResponse.ERROR;
        }
    }

@@ -418,8 +447,9 @@ public class LockPatternUtils {
        try {
            VerifyCredentialResponse response = getLockSettings().checkCredential(
                    credential, userId, wrapCallback(progressCallback));

            if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
            if (response == null) {
                return false;
            } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
                return true;
            } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
                throw new RequestThrottledException(response.getTimeout());
@@ -439,30 +469,26 @@ public class LockPatternUtils {
     * verified.
     *
     * @param credential The parent user's credential to check.
     * @param challenge The challenge to verify against the credential
     * @return the attestation that the challenge was verified, or null
     * @param userId The managed profile user id
     * @throws RequestThrottledException if credential verification is being throttled due to
     *         to many incorrect attempts.
     * @param flags See {@link VerifyFlag}
     * @throws IllegalStateException if called on the main thread.
     */
    public byte[] verifyTiedProfileChallenge(@NonNull LockscreenCredential credential,
            long challenge, int userId) throws RequestThrottledException {
    @NonNull
    public VerifyCredentialResponse verifyTiedProfileChallenge(
            @NonNull LockscreenCredential credential, int userId, @VerifyFlag int flags) {
        throwIfCalledOnMainThread();
        try {
            VerifyCredentialResponse response =
                    getLockSettings().verifyTiedProfileChallenge(credential, challenge, userId);

            if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
                return response.getPayload();
            } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
                throw new RequestThrottledException(response.getTimeout());
            final VerifyCredentialResponse response = getLockSettings()
                    .verifyTiedProfileChallenge(credential, userId, flags);
            if (response == null) {
                return VerifyCredentialResponse.ERROR;
            } else {
                return null;
                return response;
            }
        } catch (RemoteException re) {
            Log.e(TAG, "failed to verify tied profile credential", re);
            return null;
            return VerifyCredentialResponse.ERROR;
        }
    }

Loading