Merge "Do not check user escrow state if synthetic password is not enabled yet" into oc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b156c3a006
@@ -1562,8 +1562,9 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
// migration to synthetic password.
|
||||
synchronized (mSpManager) {
|
||||
if (shouldMigrateToSyntheticPasswordLocked(userId)) {
|
||||
initializeSyntheticPasswordLocked(storedHash.hash, credential,
|
||||
storedHash.type, userId);
|
||||
AuthenticationToken auth = initializeSyntheticPasswordLocked(
|
||||
storedHash.hash, credential, storedHash.type, userId);
|
||||
activateEscrowTokens(auth, userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2071,9 +2072,11 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
pwdHandle, null, userId).authToken;
|
||||
}
|
||||
}
|
||||
disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
|
||||
if (!mSpManager.hasEscrowData(userId)) {
|
||||
throw new SecurityException("Escrow token is disabled on the current user");
|
||||
if (isSyntheticPasswordBasedCredentialLocked(userId)) {
|
||||
disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
|
||||
if (!mSpManager.hasEscrowData(userId)) {
|
||||
throw new SecurityException("Escrow token is disabled on the current user");
|
||||
}
|
||||
}
|
||||
long handle = mSpManager.createTokenBasedSyntheticPassword(token, userId);
|
||||
if (auth != null) {
|
||||
@@ -2085,6 +2088,7 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
|
||||
private void activateEscrowTokens(AuthenticationToken auth, int userId) throws RemoteException {
|
||||
if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId);
|
||||
disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
|
||||
synchronized (mSpManager) {
|
||||
for (long handle : mSpManager.getPendingTokensForUser(userId)) {
|
||||
Slog.i(TAG, String.format("activateEscrowTokens: %x %d ", handle, userId));
|
||||
|
||||
@@ -48,6 +48,20 @@ import java.util.Set;
|
||||
* The SP has an associated password handle, which binds to the SID for that user. The password
|
||||
* handle is persisted by SyntheticPasswordManager internally.
|
||||
* If the user credential is null, it's treated as if the credential is DEFAULT_PASSWORD
|
||||
*
|
||||
* Information persisted on disk:
|
||||
* for each user (stored under DEFAULT_HANDLE):
|
||||
* SP_HANDLE_NAME: GateKeeper password handle of synthetic password. Only available if user
|
||||
* credential exists, cleared when user clears their credential.
|
||||
* SP_E0_NAME, SP_P1_NAME: Secret to derive synthetic password when combined with escrow
|
||||
* tokens. Destroyed when escrow support is turned off for the given user.
|
||||
*
|
||||
* for each SP blob under the user (stored under the corresponding handle):
|
||||
* SP_BLOB_NAME: The encrypted synthetic password. Always exists.
|
||||
* PASSWORD_DATA_NAME: Metadata about user credential. Only exists for password based SP.
|
||||
* SECDISCARDABLE_NAME: Part of the necessary ingredient to decrypt SP_BLOB_NAME for the
|
||||
* purpose of secure deletion.
|
||||
*
|
||||
*/
|
||||
public class SyntheticPasswordManager {
|
||||
private static final String SP_BLOB_NAME = "spblob";
|
||||
@@ -221,7 +235,7 @@ public class SyntheticPasswordManager {
|
||||
* If the existing credential hash is non-null, the existing SID mill be migrated so
|
||||
* the synthetic password in the authentication token will produce the same SID
|
||||
* (the corresponding synthetic password handle is persisted by SyntheticPasswordManager
|
||||
* in a per-user data storage.
|
||||
* in a per-user data storage.)
|
||||
*
|
||||
* If the existing credential hash is null, it means the given user should have no SID so
|
||||
* SyntheticPasswordManager will nuke any SP handle previously persisted. In this case,
|
||||
@@ -578,8 +592,6 @@ public class SyntheticPasswordManager {
|
||||
|
||||
private void destroySyntheticPassword(long handle, int userId) {
|
||||
destroyState(SP_BLOB_NAME, true, handle, userId);
|
||||
destroyState(SP_E0_NAME, true, handle, userId);
|
||||
destroyState(SP_P1_NAME, true, handle, userId);
|
||||
destroySPBlobKey(getHandleName(handle));
|
||||
}
|
||||
|
||||
|
||||
@@ -320,6 +320,26 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
|
||||
assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
|
||||
}
|
||||
|
||||
public void testEscrowTokenActivatedLaterWithUserPasswordNeedsMigration() throws RemoteException {
|
||||
final String TOKEN = "some-high-entropy-secure-token";
|
||||
final String PASSWORD = "password";
|
||||
// Set up pre-SP user password
|
||||
disableSyntheticPassword(PRIMARY_USER_ID);
|
||||
mService.setLockCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
|
||||
PRIMARY_USER_ID);
|
||||
enableSyntheticPassword(PRIMARY_USER_ID);
|
||||
|
||||
long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
|
||||
// Token not activated immediately since user password exists
|
||||
assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
// Activate token (password gets migrated to SP at the same time)
|
||||
assertEquals(VerifyCredentialResponse.RESPONSE_OK,
|
||||
mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
|
||||
PRIMARY_USER_ID).getResponseCode());
|
||||
// Verify token is activated
|
||||
assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
}
|
||||
|
||||
// b/34600579
|
||||
//TODO: add non-migration work profile case, and unify/un-unify transition.
|
||||
//TODO: test token after user resets password
|
||||
|
||||
Reference in New Issue
Block a user