Merge "Do not check user escrow state if synthetic password is not enabled yet" into oc-dev

This commit is contained in:
TreeHugger Robot
2017-04-20 14:56:20 +00:00
committed by Android (Google) Code Review
3 changed files with 44 additions and 8 deletions

View File

@@ -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));

View File

@@ -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));
}

View File

@@ -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