summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Andrew Scull <ascull@google.com> 2018-04-13 12:01:25 +0100
committer Andrew Scull <ascull@google.com> 2018-04-17 10:34:04 +0100
commitf49794b512745ca3b3a26221d36291440bc417e5 (patch)
tree9190b28c330aa41aae923dc1eff6f3c317e66455
parent26c25f0033c73d1185b85979c2712647699ca956 (diff)
LSS: pass secret to AuthSecret HAL when no credential
If there was once a credential, a secret will have been enrolled. When the credential is removed, that secret is still enrolled but still needs to be derived. This adds that derivation in the case that the secret is enrolled by the user doesn't have a credential. Bug: 77942316 Test: runtest frameworks-services -c com.android.server.locksettings.SyntheticPasswordTests Change-Id: I099a9537ab0739830a234b5f4f3721f4e8476571
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java33
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java32
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 4b58d537e844..fd4bd1d50cde 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();