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

Commit 36470ad5 authored by Eric Biggers's avatar Eric Biggers
Browse files

Add and use additional VerifyCredentialResponse helper methods

Add additional methods to VerifyCredentialResponse that allow
constructing responses with various response codes and checking whether
a response has that response code.  Use these methods wherever
appropriate.  This is in preparation for removing direct checks of the
response code, which are difficult to keep track of.

Since RESPONSE_CRED_INCORRECT is a bit subtle (the credential may be
incorrect without that being the response code), don't provide a method
that checks for it specifically but rather provide a method
isCredCertainlyIncorrect() that checks for the credential being
certainly incorrect for any reason.

RESPONSE_CRED_INCORRECT was being checked for in only one place in
non-test code, and changing it to use isCredCertainlyIncorrect() makes
no difference there.  (Also, that code is flagged anyway.)  Other than
that and similar adjustments to tests that checked for
RESPONSE_CRED_INCORRECT, this CL is purely a refactor.

Bug: 423038471
Test: atest FrameworksServicesTests:com.android.server.locksettings
Flag: EXEMPT refactor
Change-Id: I9c45eb0009648497536f13922fc4bb4df7e1b5c2
parent c6cbdd23
Loading
Loading
Loading
Loading
+4 −5
Original line number Original line Diff line number Diff line
package com.android.internal.widget;
package com.android.internal.widget;


import static com.android.internal.widget.flags.Flags.runCheckCredentialWithHigherPriority;

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

import android.util.Log;
import android.util.Log;


import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
import com.android.internal.widget.LockPatternUtils.RequestThrottledException;


import static com.android.internal.widget.flags.Flags.runCheckCredentialWithHigherPriority;

/**
/**
 * Helper class to check/verify PIN/Password/Pattern asynchronously.
 * Helper class to check/verify PIN/Password/Pattern asynchronously.
 */
 */
@@ -52,8 +51,8 @@ public final class LockPatternChecker {
         * Invoked when a security verification is finished.
         * Invoked when a security verification is finished.
         *
         *
         * @param response The response, optionally containing Gatekeeper HAT or Gatekeeper Password
         * @param response The response, optionally containing Gatekeeper HAT or Gatekeeper Password
         * @param throttleTimeoutMs The amount of time in ms to wait before reattempting
         * @param throttleTimeoutMs The amount of time in ms to wait before reattempting the call.
         * the call. Only non-0 if the response is {@link VerifyCredentialResponse#RESPONSE_RETRY}.
         *     Only non-0 if {@link VerifyCredentialResponse#hasTimeout()}.
         */
         */
        void onVerified(@NonNull VerifyCredentialResponse response, int throttleTimeoutMs);
        void onVerified(@NonNull VerifyCredentialResponse response, int throttleTimeoutMs);
    }
    }
+1 −1
Original line number Original line Diff line number Diff line
@@ -520,7 +520,7 @@ public class LockPatternUtils {
                return false;
                return false;
            } else if (response.isMatched()) {
            } else if (response.isMatched()) {
                return true;
                return true;
            } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
            } else if (response.hasTimeout()) {
                throw new RequestThrottledException(response.getTimeout());
                throw new RequestThrottledException(response.getTimeout());
            } else {
            } else {
                return false;
                return false;
+61 −1
Original line number Original line Diff line number Diff line
@@ -176,11 +176,26 @@ public final class VerifyCredentialResponse implements Parcelable {
        return fromError(RESPONSE_OTHER_ERROR);
        return fromError(RESPONSE_OTHER_ERROR);
    }
    }


    /** Builds a {@link VerifyCredentialResponse} with {@link #RESPONSE_CRED_TOO_SHORT}. */
    public static VerifyCredentialResponse credTooShort() {
        return fromError(RESPONSE_CRED_TOO_SHORT);
    }

    /** Builds a {@link VerifyCredentialResponse} with {@link #RESPONSE_CRED_ALREADY_TRIED}. */
    public static VerifyCredentialResponse credAlreadyTried() {
        return fromError(RESPONSE_CRED_ALREADY_TRIED);
    }

    /** Builds a {@link VerifyCredentialResponse} with {@link #RESPONSE_CRED_INCORRECT}. */
    public static VerifyCredentialResponse credIncorrect() {
        return fromError(RESPONSE_CRED_INCORRECT);
    }

    /**
    /**
     * Builds a {@link VerifyCredentialResponse} for an error response that does not use any of the
     * Builds a {@link VerifyCredentialResponse} for an error response that does not use any of the
     * additional fields.
     * additional fields.
     */
     */
    public static VerifyCredentialResponse fromError(@ResponseCode int responseCode) {
    private static VerifyCredentialResponse fromError(@ResponseCode int responseCode) {
        Preconditions.checkArgument(
        Preconditions.checkArgument(
                responseCode == RESPONSE_OTHER_ERROR
                responseCode == RESPONSE_OTHER_ERROR
                        || responseCode == RESPONSE_CRED_TOO_SHORT
                        || responseCode == RESPONSE_CRED_TOO_SHORT
@@ -239,10 +254,55 @@ public final class VerifyCredentialResponse implements Parcelable {
        return mResponseCode;
        return mResponseCode;
    }
    }


    /** Returns true if credential verification succeeded. */
    public boolean isMatched() {
    public boolean isMatched() {
        return mResponseCode == RESPONSE_OK;
        return mResponseCode == RESPONSE_OK;
    }
    }


    /**
     * Returns true if credential verification failed and there is a timeout before the next request
     * will be allowed.
     */
    public boolean hasTimeout() {
        return mResponseCode == RESPONSE_RETRY;
    }

    /**
     * Returns true if credential verification failed because the credential was shorter than the
     * minimum length.
     */
    public boolean isCredTooShort() {
        return mResponseCode == RESPONSE_CRED_TOO_SHORT;
    }

    /**
     * Returns true if credential verification failed because the credential was incorrect and was
     * already tried recently.
     */
    public boolean isCredAlreadyTried() {
        return mResponseCode == RESPONSE_CRED_ALREADY_TRIED;
    }

    /**
     * Returns true if the credential is known for certain to be incorrect. Returns false in all
     * other cases: credential verification succeeded, or credential verification failed but it is
     * not known for certain that the credential is incorrect. (A credential that failed to verify
     * could still be correct if there is an active timeout or if there was a transient error.)
     */
    public boolean isCredCertainlyIncorrect() {
        return mResponseCode == RESPONSE_CRED_TOO_SHORT
                || mResponseCode == RESPONSE_CRED_ALREADY_TRIED
                || mResponseCode == RESPONSE_CRED_INCORRECT;
    }

    /**
     * Returns true if credential verification failed for a reason that isn't covered by {@link
     * #hasTimeout()} or {@link #isCredCertainlyIncorrect()}.
     */
    public boolean isOtherError() {
        return mResponseCode == RESPONSE_OTHER_ERROR;
    }

    @Override
    @Override
    public String toString() {
    public String toString() {
        return "Response: " + mResponseCode
        return "Response: " + mResponseCode
+7 −16
Original line number Original line Diff line number Diff line
@@ -1990,9 +1990,7 @@ public class LockSettingsService extends ILockSettings.Stub {
                SyntheticPassword sp = authResult.syntheticPassword;
                SyntheticPassword sp = authResult.syntheticPassword;


                if (sp == null) {
                if (sp == null) {
                    if (response != null
                    if (response != null && response.hasTimeout()) {
                            && response.getResponseCode()
                                    == VerifyCredentialResponse.RESPONSE_RETRY) {
                        Slog.w(TAG, "Failed to enroll: rate limit exceeded.");
                        Slog.w(TAG, "Failed to enroll: rate limit exceeded.");
                    } else {
                    } else {
                        Slog.w(TAG, "Failed to enroll: incorrect credential.");
                        Slog.w(TAG, "Failed to enroll: incorrect credential.");
@@ -2479,14 +2477,11 @@ public class LockSettingsService extends ILockSettings.Stub {
                    case SoftwareRateLimiterResult.RATE_LIMITED:
                    case SoftwareRateLimiterResult.RATE_LIMITED:
                        return VerifyCredentialResponse.fromTimeout(res.remainingDelay);
                        return VerifyCredentialResponse.fromTimeout(res.remainingDelay);
                    case SoftwareRateLimiterResult.CREDENTIAL_TOO_SHORT:
                    case SoftwareRateLimiterResult.CREDENTIAL_TOO_SHORT:
                        return VerifyCredentialResponse.fromError(
                        return VerifyCredentialResponse.credTooShort();
                                VerifyCredentialResponse.RESPONSE_CRED_TOO_SHORT);
                    case SoftwareRateLimiterResult.DUPLICATE_WRONG_GUESS:
                    case SoftwareRateLimiterResult.DUPLICATE_WRONG_GUESS:
                        return VerifyCredentialResponse.fromError(
                        return VerifyCredentialResponse.credAlreadyTried();
                                VerifyCredentialResponse.RESPONSE_CRED_ALREADY_TRIED);
                    default:
                    default:
                        return VerifyCredentialResponse.fromError(
                        return VerifyCredentialResponse.fromError();
                                VerifyCredentialResponse.RESPONSE_OTHER_ERROR);
                }
                }
            }
            }
            if (isSpecialUserId(userId)) {
            if (isSpecialUserId(userId)) {
@@ -2526,11 +2521,9 @@ public class LockSettingsService extends ILockSettings.Stub {
                        .build();
                        .build();
            }
            }
            sendCredentialsOnUnlockIfRequired(credential, userId);
            sendCredentialsOnUnlockIfRequired(credential, userId);
        } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
        } else if (response.hasTimeout() && response.getTimeout() > 0) {
            if (response.getTimeout() > 0) {
            requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
            requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
        }
        }
        }
        notifyLockSettingsStateListeners(response.isMatched(), userId);
        notifyLockSettingsStateListeners(response.isMatched(), userId);
        return response;
        return response;
    }
    }
@@ -2548,9 +2541,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            if (response.isMatched()) {
            if (response.isMatched()) {
                mSoftwareRateLimiter.reportSuccess(lskfId);
                mSoftwareRateLimiter.reportSuccess(lskfId);
            } else {
            } else {
                boolean isCertainlyWrongGuess =
                boolean isCertainlyWrongGuess = response.isCredCertainlyIncorrect();
                        response.getResponseCode()
                                == VerifyCredentialResponse.RESPONSE_CRED_INCORRECT;
                Duration swTimeout =
                Duration swTimeout =
                        mSoftwareRateLimiter.reportFailure(
                        mSoftwareRateLimiter.reportFailure(
                                lskfId, credential, isCertainlyWrongGuess);
                                lskfId, credential, isCertainlyWrongGuess);
+1 −2
Original line number Original line Diff line number Diff line
@@ -730,8 +730,7 @@ class SyntheticPasswordManager {
                            Duration.ofMillis(weaverResponse.timeout));
                            Duration.ofMillis(weaverResponse.timeout));
                }
                }
                if (android.security.Flags.softwareRatelimiter()) {
                if (android.security.Flags.softwareRatelimiter()) {
                    yield VerifyCredentialResponse.fromError(
                    yield VerifyCredentialResponse.credIncorrect();
                            VerifyCredentialResponse.RESPONSE_CRED_INCORRECT);
                }
                }
                yield VerifyCredentialResponse.OTHER_ERROR;
                yield VerifyCredentialResponse.OTHER_ERROR;
            }
            }
Loading