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

Commit 7f829329 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I9561cb2b,Ic9c46700 into main

* changes:
  Update auth flags and state across secure lock device progress
  LockSettings updates for secure lock device
parents e3a50cc3 80f1ddbb
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -138,6 +138,29 @@ public abstract class LockSettingsInternal {
     */
    public abstract void lockUser(@UserIdInt int userId);

    /**
     * Notifies LockSettingsService that secure lock device mode has been disabled.
     *
     * <p>When this method is called, the strong authentication flags set by secure lock device are
     * asynchronously cleared.
     *
     * <p>If {@code authenticationComplete} is {@code true}, indicating successful on-device
     * two-factor authentication, the user is unlocked. This involves unlocking the user (both
     * storage and user state) and its associated profiles that share the lock credential (e.g.
     * managed and clone profiles) synchronously.
     *
     * <p>If {@code authenticationComplete} is {@code false} (indicating a disable request by a
     * remote mechanism that has independently verified the user's identity), this indicates the
     * user has not completed the on-device two-factor authentication. As a result, any partial
     * authentication progress (e.g. if the user has authenticated with LSKF but not biometrics)
     * is reset, and the user's CE storage and keystore are relocked.
     *
     * @see LockSettingsStrongAuth#disableSecureLockDevice(int, boolean)
     * @param userId the ID of the user requesting to disable secure lock device.
     * @param authenticationComplete whether two-factor authentication was completed.
     */
    public abstract void disableSecureLockDevice(int userId, boolean authenticationComplete);

    /**
     * Returns PasswordMetrics object corresponding to the given user's lockscreen password.
     * If the user has a password but its metrics isn't known yet (for example if the device
+85 −0
Original line number Diff line number Diff line
@@ -29,14 +29,17 @@ import static android.content.Intent.ACTION_MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTO
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.UserHandle.USER_ALL;
import static android.os.UserHandle.USER_SYSTEM;
import static android.security.Flags.secureLockdown;

import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD_OR_PIN;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
import static com.android.internal.widget.LockPatternUtils.CURRENT_LSKF_BASED_PROTECTOR_ID_KEY;
import static com.android.internal.widget.LockPatternUtils.PIN_LENGTH_UNAVAILABLE;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.PRIMARY_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_BIOMETRIC_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE;
import static com.android.internal.widget.LockPatternUtils.USER_FRP;
import static com.android.internal.widget.LockPatternUtils.USER_REPAIR_MODE;
import static com.android.internal.widget.LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE;
@@ -152,6 +155,7 @@ import com.android.server.locksettings.SyntheticPasswordManager.SyntheticPasswor
import com.android.server.locksettings.SyntheticPasswordManager.TokenType;
import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager;
import com.android.server.pm.UserManagerInternal;
import com.android.server.security.authenticationpolicy.SecureLockDeviceServiceInternal;
import com.android.server.utils.Slogf;
import com.android.server.wm.WindowManagerInternal;

@@ -543,6 +547,15 @@ public class LockSettingsService extends ILockSettings.Stub {
            return (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        }

        @Nullable
        public SecureLockDeviceServiceInternal getSecureLockDeviceServiceInternal() {
            if (secureLockdown()) {
                return LocalServices.getService(SecureLockDeviceServiceInternal.class);
            } else {
                return null;
            }
        }

        public UserManager getUserManager() {
            return (UserManager) mContext.getSystemService(Context.USER_SERVICE);
        }
@@ -958,6 +971,25 @@ public class LockSettingsService extends ILockSettings.Stub {
        mStorage.prefetchUser(UserHandle.USER_SYSTEM);
        mBiometricDeferredQueue.systemReady(mInjector.getFingerprintManager(),
                mInjector.getFaceManager(), mInjector.getBiometricManager());

        // When secure lock device is enabled, require two-factor authentication for
        // device entry: primary authentication as the first factor, followed by strong
        // biometric authentication as the second factor. The flags are set on all users, because
        // secure lock device is a global state applied on the whole device. Keyguard should only
        // allow authentication requests by the user that initiated Secure Lock Device, but flags
        // are set on all users to be safe.
        SecureLockDeviceServiceInternal secureLockDeviceServiceInternal =
                mInjector.getSecureLockDeviceServiceInternal();
        if (secureLockDeviceServiceInternal != null
                && secureLockDeviceServiceInternal.isSecureLockDeviceEnabled()) {
            for (UserInfo userInfo : mUserManager.getUsers()) {
                int userId = userInfo.id;
                Slog.d(TAG, "Applying Secure Lock Device strong auth flags to user: "
                        + userId);
                requireStrongAuth(PRIMARY_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE
                        | STRONG_BIOMETRIC_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE, userId);
            }
        }
    }

    private void loadEscrowData() {
@@ -3052,6 +3084,41 @@ public class LockSettingsService extends ILockSettings.Stub {

    private void onCredentialVerified(SyntheticPassword sp, @Nullable PasswordMetrics metrics,
            int userId) {
        SecureLockDeviceServiceInternal secureLockDeviceServiceInternal =
                mInjector.getSecureLockDeviceServiceInternal();
        if (secureLockDeviceServiceInternal != null
                && secureLockDeviceServiceInternal.isSecureLockDeviceEnabled()) {
            onCredentialVerifiedInSecureLockDeviceMode(sp, metrics, userId);
        } else {
            onCredentialVerifiedInternal(sp, metrics, userId);
        }
    }

    private void onCredentialVerifiedInSecureLockDeviceMode(SyntheticPassword sp,
            @Nullable PasswordMetrics metrics, int userId) {
        // TODO: (b/433569177) Cache the synthetic password in memory and don't unlock CE storage
        //  etc. until Secure Lock mode is disabled.
        if (metrics != null) {
            synchronized (this) {
                mUserPasswordMetrics.put(userId,  metrics);
            }
        }
        unlockKeystore(userId, sp);
        unlockCeStorage(userId, sp);
        activateEscrowTokens(sp, userId);
        onSyntheticPasswordUnlocked(userId, sp);

        Slog.d(TAG, "Secure lock device is enabled: reporting successful primary auth, "
                + "but awaiting two-factor authentication completion before full strong auth "
                + "unlock.");
        mStrongAuth.reportSuccessfulPrimaryAuthInSecureLockDeviceMode(userId);
        Slog.d(TAG, "Successful primary auth in secure lock device mode: process biometric "
                + "lockout resets.");
        mBiometricDeferredQueue.processPendingLockoutResets();
    }

    private void onCredentialVerifiedInternal(SyntheticPassword sp,
            @Nullable PasswordMetrics metrics, int userId) {

        if (metrics != null) {
            synchronized (this) {
@@ -3714,6 +3781,24 @@ public class LockSettingsService extends ILockSettings.Stub {
    }

    private final class LocalService extends LockSettingsInternal {
        @Override
        public void disableSecureLockDevice(int userId, boolean authenticationComplete) {
            mStrongAuth.disableSecureLockDevice(userId, authenticationComplete);
            if (authenticationComplete) {
                // TODO: (b/433569177) Cache the synthetic password in memory and don't unlock CE
                //  storage until Secure Lock mode is disabled here upon two-factor authentication
                //  completion
                unlockUser(userId);
                if (isCredentialShareableWithParent(userId)
                        && getSeparateProfileChallengeEnabledInternal(userId)) {
                    setDeviceUnlockedForUser(userId);
                }
            } else {
                // If secure lock mode is disabled while two factor authentication is incomplete,
                // lock the user.
                lockUser(userId);
            }
        }

        @Override
        public void onThirdPartyAppsStarted() {
+148 −0
Original line number Diff line number Diff line
@@ -16,9 +16,13 @@

package com.android.server.locksettings;

import static android.security.Flags.secureLockDevice;

import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.PRIMARY_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_BIOMETRIC_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE;

import android.app.AlarmManager;
import android.app.AlarmManager.OnAlarmListener;
@@ -62,6 +66,8 @@ public class LockSettingsStrongAuth {
    private static final int MSG_STRONG_BIOMETRIC_UNLOCK = 8;
    private static final int MSG_SCHEDULE_NON_STRONG_BIOMETRIC_IDLE_TIMEOUT = 9;
    private static final int MSG_REFRESH_STRONG_AUTH_TIMEOUT = 10;
    private static final int MSG_PRIMARY_AUTH_SUCCESS_IN_SECURE_LOCK_DEVICE_MODE = 11;
    private static final int MSG_DISABLE_SECURE_LOCK_DEVICE = 12;

    @VisibleForTesting
    protected static final String STRONG_AUTH_TIMEOUT_ALARM_TAG =
@@ -199,6 +205,14 @@ public class LockSettingsStrongAuth {
    }

    private void handleRequireStrongAuthOneUser(int strongAuthReason, int userId) {
        // If requiring strong biometric auth for Secure Lock Device, disallow non-strong
        // biometrics
        if (secureLockDevice()
                && (strongAuthReason & STRONG_BIOMETRIC_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE) != 0
        ) {
            setIsNonStrongBiometricAllowed(false, userId);
        }

        int oldValue = mStrongAuthForUser.get(userId, mDefaultStrongAuthFlags);
        int newValue = strongAuthReason == STRONG_AUTH_NOT_REQUIRED
                ? STRONG_AUTH_NOT_REQUIRED
@@ -269,6 +283,56 @@ public class LockSettingsStrongAuth {
                STRONG_AUTH_TIMEOUT_ALARM_TAG, alarm, mHandler);
    }

    /**
     * Indicates if PRIMARY_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE flag is set for a given userId.
     *
     * Returns false if FLAG_SECURE_LOCK_DEVICE is disabled, or if the
     * PRIMARY_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE flag is not set.
     */
    private boolean isSecureLockDevicePrimaryAuthFlagSet(int userId) {
        if (!secureLockDevice()) {
            return false;
        }

        return (mStrongAuthForUser.get(userId, mDefaultStrongAuthFlags)
                & PRIMARY_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE) != 0;
    }

    /**
     * Indicates if STRONG_BIOMETRIC_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE flag is set for a given
     * userId.
     *
     * Returns false if FLAG_SECURE_LOCK_DEVICE is disabled, or if the
     * STRONG_BIOMETRIC_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE flag is not set.
     */
    private boolean isSecureLockDeviceStrongBiometricAuthFlagSet(int userId) {
        if (!secureLockDevice()) {
            return false;
        }

        return (mStrongAuthForUser.get(userId, mDefaultStrongAuthFlags)
                & STRONG_BIOMETRIC_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE) != 0;
    }

    /**
     * Unsets all strong auth flag changes for Secure Lock Device.
     * @param userId the user requesting to disable secure lock device
     * @param authenticationComplete indicates if secure lock device is being disabled due to
     *                               successful two-factor primary and biometric authentication
     *                               by the user on this device. If {@code false}, it indicates
     *                               a disable request by a remote mechanism that has verified the
     *                               user's identity.
     */
    public void disableSecureLockDevice(int userId, boolean authenticationComplete) {
        if (DEBUG) {
            Slog.d(TAG, "disableSecureLockDevice(userId=" + userId + ", "
                    + "authenticationComplete=" + authenticationComplete + ")");
        }
        Message msg = mHandler.obtainMessage(MSG_DISABLE_SECURE_LOCK_DEVICE,
                userId, authenticationComplete ? 1 : 0);
        mHandler.sendMessage(msg);
    }

    private void handleScheduleStrongAuthTimeout(int userId) {
        if (DEBUG) Slog.d(TAG, "handleScheduleStrongAuthTimeout for userId=" + userId);
        rescheduleStrongAuthTimeoutAlarm(mInjector.getElapsedRealtimeMs(), userId);
@@ -402,6 +466,72 @@ public class LockSettingsStrongAuth {
                NON_STRONG_BIOMETRIC_IDLE_TIMEOUT_ALARM_TAG, alarm, mHandler);
    }

    /**
     * Updates strong auth flags after primary authentication success in Secure Lock Device mode.
     *
     * Primary auth typically unlocks the device when secure lock device is disabled.
     *
     * When Secure Lock Device is enabled, the device is not unlocked after primary auth, because a
     * second factor strong-biometric-only auth step is still required. Instead, primary auth
     * success unsets all flags except for STRONG_BIOMETRIC_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE.
     * @param userId the userId of the user that successfully authenticated
     */
    private void handlePrimaryAuthSuccessInSecureLockDeviceMode(int userId) {
        if (DEBUG) Slog.d(TAG, "handlePrimaryAuthSuccessInSecureLockDeviceMode");
        if (secureLockDevice() && isSecureLockDevicePrimaryAuthFlagSet(userId)) {
            mStrongAuthForUser.put(userId, STRONG_BIOMETRIC_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE);
            notifyStrongAuthTrackers(STRONG_BIOMETRIC_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE, userId);
        }
    }

    /**
     * Updates strong auth flags after disabling Secure Lock Device.
     *
     * <p>If {@code authenticationComplete} is {@code true}, reports the successful strong auth
     * unlock and strong biometric unlock.
     *
     * <p>If {@code authenticationComplete} is {@code false}, the user has not completed two-factor
     * authentication and any partial authentication progress is reset.
     *
     * @param userId the ID of the user requesting to disable secure lock device.
     * @param authenticationComplete whether two-factor authentication was completed.
     */
    private void handleDisableSecureLockDevice(int userId, int authenticationComplete) {
        if (!secureLockDevice()) {
            return;
        }

        boolean authComplete = (authenticationComplete == 1);
        if (DEBUG) {
            Slog.d(TAG, "Disabling secure lock device for userId=" + userId + ", "
                    + "authenticationComplete=" + authComplete);
        }

        for (int i = 0; i < mStrongAuthForUser.size(); i++) {
            final int targetUserId = mStrongAuthForUser.keyAt(i);

            // Unset Secure Lock Device strong biometric auth flag if set
            if (isSecureLockDeviceStrongBiometricAuthFlagSet(targetUserId)) {
                handleNoLongerRequireStrongAuth(
                        STRONG_BIOMETRIC_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE, targetUserId);
            }

            if (!authComplete) {
                // Unset Secure Lock Device primary auth flag if set
                if (isSecureLockDevicePrimaryAuthFlagSet(targetUserId)) {
                    handleNoLongerRequireStrongAuth(PRIMARY_AUTH_REQUIRED_FOR_SECURE_LOCK_DEVICE,
                            targetUserId);
                }
                handleRequireStrongAuth(mDefaultStrongAuthFlags, targetUserId);
            }
        }

        if (authComplete) {
            handleRequireStrongAuth(STRONG_AUTH_NOT_REQUIRED, userId);
            handleScheduleStrongAuthTimeout(userId);
        }
    }

    private void notifyStrongAuthTrackers(int strongAuthReason, int userId) {
        int i = mTrackers.beginBroadcast();
        try {
@@ -479,6 +609,18 @@ public class LockSettingsStrongAuth {
        requireStrongAuth(STRONG_AUTH_NOT_REQUIRED, userId);
    }

    /**
     * Report successful authentication with primary auth as part of a two-factor authentication in
     * secure lock device. The device will remain locked until the second-factor strong biometric
     * authentication is complete.
     */
    public void reportSuccessfulPrimaryAuthInSecureLockDeviceMode(int userId) {
        final int argNotUsed = 0;
        mHandler.obtainMessage(MSG_PRIMARY_AUTH_SUCCESS_IN_SECURE_LOCK_DEVICE_MODE, userId,
                argNotUsed).sendToTarget();

    }

    /**
     * Report successful unlocking with primary auth
     */
@@ -630,6 +772,12 @@ public class LockSettingsStrongAuth {
                case MSG_SCHEDULE_NON_STRONG_BIOMETRIC_IDLE_TIMEOUT:
                    handleScheduleNonStrongBiometricIdleTimeout(msg.arg1);
                    break;
                case MSG_PRIMARY_AUTH_SUCCESS_IN_SECURE_LOCK_DEVICE_MODE:
                    handlePrimaryAuthSuccessInSecureLockDeviceMode(msg.arg1);
                    break;
                case MSG_DISABLE_SECURE_LOCK_DEVICE:
                    handleDisableSecureLockDevice(msg.arg1, msg.arg2);
                    break;
            }
        }
    };
+81 −15

File changed.

Preview size limit exceeded, changes collapsed.

+126 −12

File changed.

Preview size limit exceeded, changes collapsed.

Loading