Loading keystore/java/android/security/Authorization.java +25 −15 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading services/core/java/com/android/server/locksettings/LockSettingsService.java +1 −1 Original line number Diff line number Diff line Loading @@ -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 */ Loading services/core/java/com/android/server/trust/TrustManagerService.java +18 −10 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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); Loading Loading @@ -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); } Loading Loading @@ -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 { Loading Loading
keystore/java/android/security/Authorization.java +25 −15 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading
services/core/java/com/android/server/locksettings/LockSettingsService.java +1 −1 Original line number Diff line number Diff line Loading @@ -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 */ Loading
services/core/java/com/android/server/trust/TrustManagerService.java +18 −10 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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); Loading Loading @@ -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); } Loading Loading @@ -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 { Loading