diff options
| author | 2018-04-17 11:04:52 +0000 | |
|---|---|---|
| committer | 2018-04-17 11:04:52 +0000 | |
| commit | d7cea28bbc43e80dd7da44b275ffe53f127af0bf (patch) | |
| tree | 20d88bb6f9d3da98fa83983d1e082a62ddb0fa12 | |
| parent | 5037beea1c118ee9aa9d9d3f314a228d5f80c727 (diff) | |
| parent | f49794b512745ca3b3a26221d36291440bc417e5 (diff) | |
Merge "LSS: pass secret to AuthSecret HAL when no credential" into pi-dev
5 files changed, 77 insertions, 3 deletions
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index fb1874c165b7..f1fd00b4ea2a 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -584,10 +584,43 @@ public class LockSettingsService extends ILockSettings.Stub { if (mUserManager.getUserInfo(userId).isManagedProfile()) { tieManagedProfileLockIfNecessary(userId, null); } + + // If the user doesn't have a credential, try and derive their secret for the + // AuthSecret HAL. The secret will have been enrolled if the user previously set a + // credential and still needs to be passed to the HAL once that credential is + // removed. + if (mUserManager.getUserInfo(userId).isPrimary() && !isUserSecure(userId)) { + tryDeriveAuthTokenForUnsecuredPrimaryUser(userId); + } } }); } + private void tryDeriveAuthTokenForUnsecuredPrimaryUser(@UserIdInt int userId) { + synchronized (mSpManager) { + // Make sure the user has a synthetic password to derive + if (!isSyntheticPasswordBasedCredentialLocked(userId)) { + return; + } + + try { + final long handle = getSyntheticPasswordHandleLocked(userId); + final String noCredential = null; + AuthenticationResult result = + mSpManager.unwrapPasswordBasedSyntheticPassword( + getGateKeeperService(), handle, noCredential, userId, null); + if (result.authToken != null) { + Slog.i(TAG, "Retrieved auth token for user " + userId); + onAuthTokenKnownForUser(userId, result.authToken); + } else { + Slog.e(TAG, "Auth token not available for user " + userId); + } + } catch (RemoteException e) { + Slog.e(TAG, "Failure retrieving auth token", e); + } + } + } + private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java index 96f81606a985..2dc3510a82e5 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java @@ -25,6 +25,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.app.IActivityManager; +import android.app.KeyguardManager; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManagerInternal; @@ -102,7 +103,8 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase { LocalServices.addService(DevicePolicyManagerInternal.class, mDevicePolicyManagerInternal); mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager, - mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class)); + mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class), + mock(KeyguardManager.class)); mStorage = new LockSettingsStorageTestable(mContext, new File(getContext().getFilesDir(), "locksettings")); File storageDir = mStorage.mStorageDir; diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java index 237091de2640..6e1f35784c7d 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java @@ -20,6 +20,7 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import android.app.KeyguardManager; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.app.trust.TrustManager; @@ -79,7 +80,7 @@ public class LockSettingsStorageTests extends AndroidTestCase { MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager, mock(NotificationManager.class), mock(DevicePolicyManager.class), - mock(StorageManager.class), mock(TrustManager.class)); + mock(StorageManager.class), mock(TrustManager.class), mock(KeyguardManager.class)); mStorage = new LockSettingsStorageTestable(context, new File(getContext().getFilesDir(), "locksettings")); mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() { diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java index 3ad30f38595b..b33253264317 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java @@ -16,6 +16,7 @@ package com.android.server.locksettings; +import android.app.KeyguardManager; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.app.trust.TrustManager; @@ -32,16 +33,19 @@ public class MockLockSettingsContext extends ContextWrapper { private DevicePolicyManager mDevicePolicyManager; private StorageManager mStorageManager; private TrustManager mTrustManager; + private KeyguardManager mKeyguardManager; public MockLockSettingsContext(Context base, UserManager userManager, NotificationManager notificationManager, DevicePolicyManager devicePolicyManager, - StorageManager storageManager, TrustManager trustManager) { + StorageManager storageManager, TrustManager trustManager, + KeyguardManager keyguardManager) { super(base); mUserManager = userManager; mNotificationManager = notificationManager; mDevicePolicyManager = devicePolicyManager; mStorageManager = storageManager; mTrustManager = trustManager; + mKeyguardManager = keyguardManager; } @Override @@ -56,6 +60,8 @@ public class MockLockSettingsContext extends ContextWrapper { return mStorageManager; } else if (TRUST_SERVICE.equals(name)) { return mTrustManager; + } else if (KEYGUARD_SERVICE.equals(name)) { + return mKeyguardManager; } else { throw new RuntimeException("System service not mocked: " + name); } diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java index e9f9800f2198..142b950c395b 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java @@ -217,6 +217,38 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { verify(mAuthSecretService, never()).primaryUserCredential(any(ArrayList.class)); } + public void testNoSyntheticPasswordOrCredentialDoesNotPassAuthSecret() throws RemoteException { + // Setting null doesn't create a synthetic password + initializeCredentialUnderSP(null, PRIMARY_USER_ID); + + reset(mAuthSecretService); + mService.onUnlockUser(PRIMARY_USER_ID); + mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler + verify(mAuthSecretService, never()).primaryUserCredential(any(ArrayList.class)); + } + + public void testSyntheticPasswordAndCredentialDoesNotPassAuthSecret() throws RemoteException { + final String PASSWORD = "passwordForASyntheticPassword"; + initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID); + + reset(mAuthSecretService); + mService.onUnlockUser(PRIMARY_USER_ID); + mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler + verify(mAuthSecretService, never()).primaryUserCredential(any(ArrayList.class)); + } + + public void testSyntheticPasswordButNoCredentialPassesAuthSecret() throws RemoteException { + final String PASSWORD = "getASyntheticPassword"; + initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID); + mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, PASSWORD, + PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID); + + reset(mAuthSecretService); + mService.onUnlockUser(PRIMARY_USER_ID); + mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler + verify(mAuthSecretService).primaryUserCredential(any(ArrayList.class)); + } + public void testManagedProfileUnifiedChallengeMigration() throws RemoteException { final String UnifiedPassword = "testManagedProfileUnifiedChallengeMigration-pwd"; disableSyntheticPassword(); |