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

Commit fc06773c authored by Rubin Xu's avatar Rubin Xu
Browse files

Force LSKF in ConfirmCredential UI when pending escrow token exists

Escrow tokens can only be activated by user confirming their LSKF,
while ConfirmCredential allows both LSKF and biometrics by default.
By requiring LSKF, it simplifies the DPC's flow of requesting the user
to activate a pending escrow token.

This change introduces an internal API to query the existence of
pending escrow tokens.

Bug: 127377026
Bug: 76084679
Bug: 79547502
Test: atest frameworks/base/services/tests/servicestests/src/com/android/server/locksettings/
Change-Id: Ie1ae58d2639394a9e6e1bf13d8bde44dfea240e8
parent bbe19695
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ interface ILockSettings {
    void systemReady();
    void userPresent(int userId);
    int getStrongAuthForUser(int userId);
    boolean hasPendingEscrowToken(int userId);

    // Keystore RecoveryController methods.
    // {@code ServiceSpecificException} may be thrown to signal an error, which caller can
+13 −1
Original line number Diff line number Diff line
@@ -1638,7 +1638,7 @@ public class LockPatternUtils {
    }

    /**
     * @see StrongAuthTracker#isFingerprintAllowedForUser
     * @see StrongAuthTracker#isBiometricAllowedForUser(int)
     */
    public boolean isBiometricAllowedForUser(int userId) {
        return (getStrongAuthForUser(userId) & ~StrongAuthTracker.ALLOWING_BIOMETRIC) == 0;
@@ -1979,6 +1979,18 @@ public class LockPatternUtils {
        return getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM) != 0;
    }

    /**
     * Returns whether the given user has pending escrow tokens
     */
    public boolean hasPendingEscrowToken(int userId) {
        try {
            return getLockSettings().hasPendingEscrowToken(userId);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
        return false;
    }

    /**
     * Return true if the device supports the lock screen feature, false otherwise.
     */
+8 −0
Original line number Diff line number Diff line
@@ -2699,6 +2699,14 @@ public class LockSettingsService extends ILockSettings.Stub {
        }
    }

    @Override
    public boolean hasPendingEscrowToken(int userId) {
        checkPasswordReadPermission(userId);
        synchronized (mSpManager) {
            return !mSpManager.getPendingTokensForUser(userId).isEmpty();
        }
    }

    private boolean removeEscrowToken(long handle, int userId) {
        synchronized (mSpManager) {
            if (handle == getSyntheticPasswordHandleLocked(userId)) {
+1 −1
Original line number Diff line number Diff line
@@ -751,7 +751,7 @@ public class SyntheticPasswordManager {

    /**
     * Create a token based Synthetic password for the given user.
     * @return
     * @return the handle of the token
     */
    public long createTokenBasedSyntheticPassword(byte[] token, int userId,
            @Nullable EscrowTokenStateChangeCallback changeCallback) {
+3 −0
Original line number Diff line number Diff line
@@ -338,12 +338,15 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
        initializeCredentialUnderSP(password, PRIMARY_USER_ID);
        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);

        assertFalse(mService.hasPendingEscrowToken(PRIMARY_USER_ID));
        long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
        assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
        assertTrue(mService.hasPendingEscrowToken(PRIMARY_USER_ID));

        mService.verifyCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
                PRIMARY_USER_ID).getResponseCode();
        assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
        assertFalse(mService.hasPendingEscrowToken(PRIMARY_USER_ID));

        mLocalService.setLockCredentialWithToken(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
                handle, token, PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);