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

Commit 19d5180b authored by Eric Biggers's avatar Eric Biggers Committed by Automerger Merge Worker
Browse files

Merge "Split Keystore's onLockScreenEvent into onDevice{Unlocked,Locked}" into main am: 20821529

parents b342db5d 20821529
Loading
Loading
Loading
Loading
+25 −15
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import android.os.ServiceManager;
import android.os.ServiceSpecificException;
import android.os.StrictMode;
import android.security.authorization.IKeystoreAuthorization;
import android.security.authorization.LockScreenEvent;
import android.system.keystore2.ResponseCode;
import android.util.Log;

@@ -76,26 +75,37 @@ public class Authorization {
    }

    /**
     * Informs keystore2 about lock screen event.
     *
     * @param locked            - whether it is a lock (true) or unlock (false) event
     * @param syntheticPassword - if it is an unlock event with the password, pass the synthetic
     *                            password provided by the LockSettingService
     * @param unlockingSids     - KeyMint secure user IDs that should be permitted to unlock
     *                            UNLOCKED_DEVICE_REQUIRED keys.
     * Tells Keystore that the device is now unlocked for a user.
     *
     * @param userId - the user's Android user ID
     * @param password - a secret derived from the user's synthetic password, if the unlock method
     *                   is LSKF (or equivalent) and thus has made the synthetic password available
     * @return 0 if successful or a {@code ResponseCode}.
     */
    public static int onLockScreenEvent(@NonNull boolean locked, @NonNull int userId,
            @Nullable byte[] syntheticPassword, @Nullable long[] unlockingSids) {
    public static int onDeviceUnlocked(int userId, @Nullable byte[] password) {
        StrictMode.noteDiskWrite();
        try {
            if (locked) {
                getService().onLockScreenEvent(LockScreenEvent.LOCK, userId, null, unlockingSids);
            } else {
                getService().onLockScreenEvent(
                        LockScreenEvent.UNLOCK, userId, syntheticPassword, unlockingSids);
            getService().onDeviceUnlocked(userId, password);
            return 0;
        } catch (RemoteException | NullPointerException e) {
            Log.w(TAG, "Can not connect to keystore", e);
            return SYSTEM_ERROR;
        } catch (ServiceSpecificException e) {
            return e.errorCode;
        }
    }

    /**
     * Tells Keystore that the device is now locked for a user.
     *
     * @param userId - the user's Android user ID
     * @param unlockingSids - list of biometric SIDs with which the device may be unlocked again
     * @return 0 if successful or a {@code ResponseCode}.
     */
    public static int onDeviceLocked(int userId, @NonNull long[] unlockingSids) {
        StrictMode.noteDiskWrite();
        try {
            getService().onDeviceLocked(userId, unlockingSids);
            return 0;
        } catch (RemoteException | NullPointerException e) {
            Log.w(TAG, "Can not connect to keystore", e);
+1 −1
Original line number Diff line number Diff line
@@ -1429,7 +1429,7 @@ public class LockSettingsService extends ILockSettings.Stub {
    }

    private void unlockKeystore(int userId, SyntheticPassword sp) {
        Authorization.onLockScreenEvent(false, userId, sp.deriveKeyStorePassword(), null);
        Authorization.onDeviceUnlocked(userId, sp.deriveKeyStorePassword());
    }

    @VisibleForTesting /** Note: this method is overridden in unit tests */
+18 −10
Original line number Diff line number Diff line
@@ -867,21 +867,19 @@ public class TrustManagerService extends SystemService {
            mDeviceLockedForUser.put(userId, locked);
        }
        if (changed) {
            dispatchDeviceLocked(userId, locked);
            Authorization.onLockScreenEvent(locked, userId, null,
                    getBiometricSids(userId));
            notifyTrustAgentsOfDeviceLockState(userId, locked);
            notifyKeystoreOfDeviceLockState(userId, locked);
            // Also update the user's profiles who have unified challenge, since they
            // share the same unlocked state (see {@link #isDeviceLocked(int)})
            for (int profileHandle : mUserManager.getEnabledProfileIds(userId)) {
                if (mLockPatternUtils.isManagedProfileWithUnifiedChallenge(profileHandle)) {
                    Authorization.onLockScreenEvent(locked, profileHandle, null,
                            getBiometricSids(profileHandle));
                    notifyKeystoreOfDeviceLockState(profileHandle, locked);
                }
            }
        }
    }

    private void dispatchDeviceLocked(int userId, boolean isLocked) {
    private void notifyTrustAgentsOfDeviceLockState(int userId, boolean isLocked) {
        for (int i = 0; i < mActiveAgents.size(); i++) {
            AgentInfo agent = mActiveAgents.valueAt(i);
            if (agent.userId == userId) {
@@ -894,6 +892,17 @@ public class TrustManagerService extends SystemService {
        }
    }

    private void notifyKeystoreOfDeviceLockState(int userId, boolean isLocked) {
        if (isLocked) {
            Authorization.onDeviceLocked(userId, getBiometricSids(userId));
        } else {
            // Notify Keystore that the device is now unlocked for the user.  Note that for unlocks
            // with LSKF, this is redundant with the call from LockSettingsService which provides
            // the password.  However, for unlocks with biometric or trust agent, this is required.
            Authorization.onDeviceUnlocked(userId, /* password= */ null);
        }
    }

    private void dispatchEscrowTokenActivatedLocked(long handle, int userId) {
        for (int i = 0; i < mActiveAgents.size(); i++) {
            AgentInfo agent = mActiveAgents.valueAt(i);
@@ -1427,10 +1436,10 @@ public class TrustManagerService extends SystemService {
        }
    }

    private long[] getBiometricSids(int userId) {
    private @NonNull long[] getBiometricSids(int userId) {
        BiometricManager biometricManager = mContext.getSystemService(BiometricManager.class);
        if (biometricManager == null) {
            return null;
            return new long[0];
        }
        return biometricManager.getAuthenticatorIds(userId);
    }
@@ -1729,8 +1738,7 @@ public class TrustManagerService extends SystemService {
                        mDeviceLockedForUser.put(userId, locked);
                    }

                    Authorization.onLockScreenEvent(locked, userId, null,
                            getBiometricSids(userId));
                    notifyKeystoreOfDeviceLockState(userId, locked);

                    if (locked) {
                        try {