Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e95f0759 authored by Rubin Xu's avatar Rubin Xu Committed by android-build-merger
Browse files

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

am: b156c3a0

Change-Id: I7453311ceb4547f18055b2856965d8f30f918f16
parents 0b3408a3 b156c3a0
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -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,10 +2072,12 @@ public class LockSettingsService extends ILockSettings.Stub {
                            pwdHandle, null, userId).authToken;
                }
            }
            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) {
                mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
@@ -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));
+15 −3
Original line number Diff line number Diff line
@@ -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));
    }

+20 −0
Original line number Diff line number Diff line
@@ -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