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

Commit 4ed98986 authored by Rubin Xu's avatar Rubin Xu
Browse files

Handle managed profile with unified challenge in getHashFactor()

Settings passes null into getHashFactor() when a profile user has
unified challenge. In this case getHashFactor() needs to derive the real
profile password before it can calculate the hash factor.

Bug: 80077655
Test: runtest frameworks-services -c com.android.server.locksettings.SyntheticPasswordTests
Change-Id: Ifa1d88818b58f914fd3560bb6ef44012facde87b
parent 1a315869
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -2537,6 +2537,7 @@ public class LockSettingsService extends ILockSettings.Stub {
     * Returns a fixed pseudorandom byte string derived from the user's synthetic password.
     * This is used to salt the password history hash to protect the hash against offline
     * bruteforcing, since rederiving this value requires a successful authentication.
     * If user is a managed profile with unified challenge, currentCredential is ignored.
     */
    @Override
    public byte[] getHashFactor(String currentCredential, int userId) throws RemoteException {
@@ -2544,6 +2545,14 @@ public class LockSettingsService extends ILockSettings.Stub {
        if (TextUtils.isEmpty(currentCredential)) {
            currentCredential = null;
        }
        if (isManagedProfileWithUnifiedLock(userId)) {
            try {
                currentCredential = getDecryptedPasswordForTiedProfile(userId);
            } catch (Exception e) {
                Slog.e(TAG, "Failed to get work profile credential", e);
                return null;
            }
        }
        synchronized (mSpManager) {
            if (!isSyntheticPasswordBasedCredentialLocked(userId)) {
                Slog.w(TAG, "Synthetic password not enabled");
+33 −0
Original line number Diff line number Diff line
@@ -448,6 +448,39 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
        assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
    }

    public void testgetHashFactorPrimaryUser() throws RemoteException {
        final String password = "password";
        mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
        final byte[] hashFactor = mService.getHashFactor(password, PRIMARY_USER_ID);
        assertNotNull(hashFactor);

        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, password,
                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
        final byte[] newHashFactor = mService.getHashFactor(null, PRIMARY_USER_ID);
        assertNotNull(newHashFactor);
        // Hash factor should never change after password change/removal
        assertArrayEquals(hashFactor, newHashFactor);
    }

    public void testgetHashFactorManagedProfileUnifiedChallenge() throws RemoteException {
        final String pattern = "1236";
        mService.setLockCredential(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, null,
                PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
        mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
        assertNotNull(mService.getHashFactor(null, MANAGED_PROFILE_USER_ID));
    }

    public void testgetHashFactorManagedProfileSeparateChallenge() throws RemoteException {
        final String primaryPassword = "primary";
        final String profilePassword = "profile";
        mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
        mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
                PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID);
        assertNotNull(mService.getHashFactor(profilePassword, MANAGED_PROFILE_USER_ID));
    }

    public void testPasswordData_serializeDeserialize() {
        PasswordData data = new PasswordData();
        data.scryptN = 11;