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

Commit 97d0a5b5 authored by Kevin Chyn's avatar Kevin Chyn
Browse files

Unlocking children profile must pass on existing challenge

The challenge must be passed on, otherwise LSS will generate, invalidate,
and revoke the challenge that's passed from places like FaceSettings.

Bug: 134834442

Test: duplicate generate/revoke challenge not seen anymore
Test: with work profile enrolled and owner profile non-enrolled,
      trying to enroll for owner profile works now

Change-Id: I0d38390bd5e0ee38a615d17f44d18ffa410904aa
parent 28623b6d
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -584,7 +584,8 @@ public class LockSettingsService extends ILockSettings.Stub {
                // If boot took too long and the password in vold got expired, parent keystore will
                // be still locked, we ignore this case since the user will be prompted to unlock
                // the device after boot.
                unlockChildProfile(userId, true /* ignoreUserNotAuthenticated */);
                unlockChildProfile(userId, true /* ignoreUserNotAuthenticated */,
                        false /* hasChallenge */, 0 /* challenge */);
            } catch (RemoteException e) {
                Slog.e(TAG, "Failed to unlock child profile");
            }
@@ -1160,12 +1161,13 @@ public class LockSettingsService extends ILockSettings.Stub {
        return decryptionResult;
    }

    private void unlockChildProfile(int profileHandle, boolean ignoreUserNotAuthenticated)
    private void unlockChildProfile(int profileHandle, boolean ignoreUserNotAuthenticated,
            boolean hasChallenge, long challenge)
            throws RemoteException {
        try {
            doVerifyCredential(getDecryptedPasswordForTiedProfile(profileHandle),
                    CREDENTIAL_TYPE_PASSWORD,
                    false, 0 /* no challenge */, profileHandle, null /* progressCallback */);
                    hasChallenge, challenge, profileHandle, null /* progressCallback */);
        } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
                | NoSuchAlgorithmException | NoSuchPaddingException
                | InvalidAlgorithmParameterException | IllegalBlockSizeException
@@ -1180,6 +1182,10 @@ public class LockSettingsService extends ILockSettings.Stub {
        }
    }

    private void unlockUser(int userId, byte[] token, byte[] secret) {
        unlockUser(userId, token, secret, false /* hasChallenge */, 0 /* challenge */);
    }

    /**
     * Unlock the user (both storage and user state) and its associated managed profiles
     * synchronously.
@@ -1188,7 +1194,8 @@ public class LockSettingsService extends ILockSettings.Stub {
     * can end up calling into other system services to process user unlock request (via
     * {@link com.android.server.SystemServiceManager#unlockUser} </em>
     */
    private void unlockUser(int userId, byte[] token, byte[] secret) {
    private void unlockUser(int userId, byte[] token, byte[] secret,
            boolean hasChallenge, long challenge) {
        // TODO: make this method fully async so we can update UI with progress strings
        final boolean alreadyUnlocked = mUserManager.isUserUnlockingOrUnlocked(userId);
        final CountDownLatch latch = new CountDownLatch(1);
@@ -1230,7 +1237,10 @@ public class LockSettingsService extends ILockSettings.Stub {
            // Unlock managed profile with unified lock
            if (tiedManagedProfileReadyToUnlock(profile)) {
                try {
                    unlockChildProfile(profile.id, false /* ignoreUserNotAuthenticated */);
                    // Must pass the challenge on for resetLockout, so it's not over-written, which
                    // causes LockSettingsService to revokeChallenge inappropriately.
                    unlockChildProfile(profile.id, false /* ignoreUserNotAuthenticated */,
                            hasChallenge, challenge);
                } catch (RemoteException e) {
                    Log.d(TAG, "Failed to unlock child profile", e);
                }
@@ -2561,7 +2571,7 @@ public class LockSettingsService extends ILockSettings.Stub {

            final byte[] secret = authResult.authToken.deriveDiskEncryptionKey();
            Slog.i(TAG, "Unlocking user " + userId + " with secret only, length " + secret.length);
            unlockUser(userId, null, secret);
            unlockUser(userId, null, secret, hasChallenge, challenge);

            activateEscrowTokens(authResult.authToken, userId);