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

Commit be2f8039 authored by Kevin Chyn's avatar Kevin Chyn
Browse files

Return handle to gatekeeper password instead of actual password

This allows 1) LockSettingsService to ensure the password isn't
valid forever. 2) Password to stay in system_server

Also, adds ILockSettings#removeGatekeeperPasswordHandle
so that callers can clean up after themselves.

Bug: 161765592

Run the following on face/fingerprint devices
Test: Remove credential
      adb shell am start -a android.app.action.SET_NEW_PASSWORD
      Set up credential + fingerprint
Test: Remove credential,
      adb shell am start -a android.settings.FINGERPRINT_SETTINGS
      This tests the ChooseLock* logic in FingerprintSettings
Test: Set up credential,
      adb shell am start -a android.settings.FINGERPRINT_SETTINGS
      This tests the ConfirmLock* logic in FingerprintSettings
Test: Remove device credential, enroll fingerprint/face. Succeeds.
      This tests the ChooseLock* returning SP path from
      BiometricEnrollIntro
Test: With credential and fingerprint/face enrolled, go to
      fingerprint/face settings and enroll. This tests the
      ConfirmLock* path in Fingerprint/FaceSettings
Test: Remove device credential, enroll credential-only, enroll
      fingerprint/face separately. Succeeds. This tests the
      ConfirmLock* returning SP path in BiometricEnrollIntro
Test: In SUW, set up credential, then biometric. This tests
      the ChooseLock* path in SUW
Test: In SUW, set up credential, go back, then set up biometric.
      This tests the ConfirmLock* path in SUW

Change-Id: I76534acc7af1e0f2e4d8af369fee31d1e19ddba9
parent 8148d943
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -49,7 +49,8 @@ interface ILockSettings {
            in ICheckCredentialProgressCallback progressCallback);
    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);
    VerifyCredentialResponse verifyGatekeeperPasswordHandle(long gatekeeperPasswordHandle, long challenge, int userId);
    void removeGatekeeperPasswordHandle(long gatekeeperPasswordHandle);
    boolean checkVoldPassword(int userId);
    int getCredentialType(int userId);
    byte[] getHashFactor(in LockscreenCredential currentCredential, int userId);
+19 −10
Original line number Diff line number Diff line
@@ -130,14 +130,15 @@ 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}.
     * Flag provided to {@link #verifyCredential(LockscreenCredential, int, int)} . If set, the
     * method will return a handle to the Gatekeeper Password in the
     * {@link VerifyCredentialResponse}.
     */
    public static final int VERIFY_FLAG_RETURN_GK_PW = 1 << 0;
    public static final int VERIFY_FLAG_REQUEST_GK_PW_HANDLE = 1 << 0;

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

@@ -409,16 +410,16 @@ public class LockPatternUtils {
    }

    /**
     * With the Gatekeeper Password returned via {@link #verifyCredential(LockscreenCredential,
     * int, int)}, request Gatekeeper to create a HardwareAuthToken wrapping the given
     * challenge.
     * With the Gatekeeper Password Handle returned via {@link #verifyCredential(
     * LockscreenCredential, int, int)}, request Gatekeeper to create a HardwareAuthToken wrapping
     * the given challenge.
     */
    @NonNull
    public VerifyCredentialResponse verifyGatekeeperPassword(@NonNull byte[] gatekeeperPassword,
    public VerifyCredentialResponse verifyGatekeeperPasswordHandle(long gatekeeperPasswordHandle,
            long challenge, int userId) {
        try {
            final VerifyCredentialResponse response = getLockSettings().verifyGatekeeperPassword(
                    gatekeeperPassword, challenge, userId);
            final VerifyCredentialResponse response = getLockSettings()
                    .verifyGatekeeperPasswordHandle(gatekeeperPasswordHandle, challenge, userId);
            if (response == null) {
                return VerifyCredentialResponse.ERROR;
            }
@@ -429,6 +430,14 @@ public class LockPatternUtils {
        }
    }

    public void removeGatekeeperPasswordHandle(long gatekeeperPasswordHandle) {
        try {
            getLockSettings().removeGatekeeperPasswordHandle(gatekeeperPasswordHandle);
        } catch (RemoteException e) {
            Log.e(TAG, "failed to remove gatekeeper password handle", e);
        }
    }

    /**
     * Check to see if a credential matches the saved one.
     *
+20 −17
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ public final class VerifyCredentialResponse implements Parcelable {
    private final @ResponseCode int mResponseCode;
    private final int mTimeout;
    @Nullable private final byte[] mGatekeeperHAT;
    @Nullable private final byte[] mGatekeeperPw;
    private final long mGatekeeperPasswordHandle;

    public static final Parcelable.Creator<VerifyCredentialResponse> CREATOR
            = new Parcelable.Creator<VerifyCredentialResponse>() {
@@ -58,10 +58,10 @@ public final class VerifyCredentialResponse implements Parcelable {
            final @ResponseCode int responseCode = source.readInt();
            final int timeout = source.readInt();
            final byte[] gatekeeperHAT = source.createByteArray();
            final byte[] gatekeeperPassword = source.createByteArray();
            long gatekeeperPasswordHandle = source.readLong();

            return new VerifyCredentialResponse(responseCode, timeout, gatekeeperHAT,
                    gatekeeperPassword);
                    gatekeeperPasswordHandle);
        }

        @Override
@@ -72,7 +72,7 @@ public final class VerifyCredentialResponse implements Parcelable {

    public static class Builder {
        @Nullable private byte[] mGatekeeperHAT;
        @Nullable private byte[] mGatekeeperPassword;
        private long mGatekeeperPasswordHandle;

        /**
         * @param gatekeeperHAT Gatekeeper HardwareAuthToken, minted upon successful authentication.
@@ -82,8 +82,8 @@ public final class VerifyCredentialResponse implements Parcelable {
            return this;
        }

        public Builder setGatekeeperPassword(byte[] gatekeeperPassword) {
            mGatekeeperPassword = gatekeeperPassword;
        public Builder setGatekeeperPasswordHandle(long gatekeeperPasswordHandle) {
            mGatekeeperPasswordHandle = gatekeeperPasswordHandle;
            return this;
        }

@@ -96,7 +96,7 @@ public final class VerifyCredentialResponse implements Parcelable {
            return new VerifyCredentialResponse(RESPONSE_OK,
                    0 /* timeout */,
                    mGatekeeperHAT,
                    mGatekeeperPassword);
                    mGatekeeperPasswordHandle);
        }
    }

@@ -110,7 +110,7 @@ public final class VerifyCredentialResponse implements Parcelable {
        return new VerifyCredentialResponse(RESPONSE_RETRY,
                timeout,
                null /* gatekeeperHAT */,
                null /* gatekeeperPassword */);
                0L /* gatekeeperPasswordHandle */);
    }

    /**
@@ -121,20 +121,20 @@ public final class VerifyCredentialResponse implements Parcelable {
        return new VerifyCredentialResponse(RESPONSE_ERROR,
                0 /* timeout */,
                null /* gatekeeperHAT */,
                null /* gatekeeperPassword */);
                0L /* gatekeeperPasswordHandle */);
    }

    private VerifyCredentialResponse(@ResponseCode int responseCode, int timeout,
            @Nullable byte[] gatekeeperHAT, @Nullable byte[] gatekeeperPassword) {
            @Nullable byte[] gatekeeperHAT, long gatekeeperPasswordHandle) {
        mResponseCode = responseCode;
        mTimeout = timeout;
        mGatekeeperHAT = gatekeeperHAT;
        mGatekeeperPw = gatekeeperPassword;
        mGatekeeperPasswordHandle = gatekeeperPasswordHandle;
    }

    public VerifyCredentialResponse stripPayload() {
        return new VerifyCredentialResponse(mResponseCode, mTimeout,
                null /* gatekeeperHAT */, null /* gatekeeperPassword */);
                null /* gatekeeperHAT */, 0L /* gatekeeperPasswordHandle */);
    }

    @Override
@@ -142,7 +142,7 @@ public final class VerifyCredentialResponse implements Parcelable {
        dest.writeInt(mResponseCode);
        dest.writeInt(mTimeout);
        dest.writeByteArray(mGatekeeperHAT);
        dest.writeByteArray(mGatekeeperPw);
        dest.writeLong(mGatekeeperPasswordHandle);
    }

    @Override
@@ -155,9 +155,12 @@ public final class VerifyCredentialResponse implements Parcelable {
        return mGatekeeperHAT;
    }

    @Nullable
    public byte[] getGatekeeperPw() {
        return mGatekeeperPw;
    public long getGatekeeperPasswordHandle() {
        return mGatekeeperPasswordHandle;
    }

    public boolean containsGatekeeperPasswordHandle() {
        return mGatekeeperPasswordHandle != 0L;
    }

    public int getTimeout() {
@@ -176,7 +179,7 @@ public final class VerifyCredentialResponse implements Parcelable {
    public String toString() {
        return "Response: " + mResponseCode
                + ", GK HAT: " + (mGatekeeperHAT != null)
                + ", GK PW: " + (mGatekeeperPw != null);
                + ", GK PW: " + (mGatekeeperPasswordHandle != 0L);
    }

    public static VerifyCredentialResponse fromGateKeeperResponse(
+1 −1
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ public class AuthCredentialPasswordView extends AuthCredentialView
            // VerifyCredentialResponse so that we can request a Gatekeeper HAT with the
            // Gatekeeper Password and operationId.
            mPendingLockCheck = LockPatternChecker.verifyCredential(mLockPatternUtils,
                    password, mEffectiveUserId, LockPatternUtils.VERIFY_FLAG_RETURN_GK_PW,
                    password, mEffectiveUserId, LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE,
                    this::onCredentialVerified);
        }
    }
+1 −1
Original line number Diff line number Diff line
@@ -75,7 +75,7 @@ public class AuthCredentialPatternView extends AuthCredentialView {
                        mLockPatternUtils,
                        credential,
                        mEffectiveUserId,
                        LockPatternUtils.VERIFY_FLAG_RETURN_GK_PW,
                        LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE,
                        this::onPatternVerified);
            }
        }
Loading