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

Commit 02e09b98 authored by Paul Crowley's avatar Paul Crowley Committed by Gerrit Code Review
Browse files

Merge changes from topic "remove_ce_caching"

* changes:
  Provide secret to vold to remove credential
  Force all devices to migrate to synthetic password
parents 5b8737d5 add57fcc
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -193,4 +193,5 @@ interface IStorageManager {
    void startCheckpoint(int numTries) = 85;
    void startCheckpoint(int numTries) = 85;
    boolean needsCheckpoint() = 86;
    boolean needsCheckpoint() = 86;
    void abortChanges(in String message, boolean retry) = 87;
    void abortChanges(in String message, boolean retry) = 87;
    void clearUserKeyAuth(int userId, int serialNumber, in byte[] token, in byte[] secret) = 88;
}
}
+18 −0
Original line number Original line Diff line number Diff line
@@ -2787,6 +2787,24 @@ class StorageManagerService extends IStorageManager.Stub
        }
        }
    }
    }


    /*
     * Clear disk encryption key bound to the associated token / secret pair. Removing the user
     * binding of the Disk encryption key is done in two phases: first, this call will retrieve
     * the disk encryption key using the provided token / secret pair and store it by
     * encrypting it with a keymaster key not bound to the user, then fixateNewestUserKeyAuth
     * is called to delete all other bindings of the disk encryption key.
     */
    @Override
    public void clearUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret) {
        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);

        try {
            mVold.clearUserKeyAuth(userId, serialNumber, encodeBytes(token), encodeBytes(secret));
        } catch (Exception e) {
            Slog.wtf(TAG, e);
        }
    }

    /*
    /*
     * Delete all disk encryption token/secret pairs except the most recently added one
     * Delete all disk encryption token/secret pairs except the most recently added one
     */
     */
+15 −20
Original line number Original line Diff line number Diff line
@@ -25,7 +25,6 @@ import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
import static com.android.internal.widget.LockPatternUtils.USER_FRP;
import static com.android.internal.widget.LockPatternUtils.USER_FRP;
@@ -1511,7 +1510,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            if (credential != null) {
            if (credential != null) {
                Slog.wtf(TAG, "CredentialType is none, but credential is non-null.");
                Slog.wtf(TAG, "CredentialType is none, but credential is non-null.");
            }
            }
            clearUserKeyProtection(userId);
            clearUserKeyProtection(userId, null);
            getGateKeeperService().clearSecureUserId(userId);
            getGateKeeperService().clearSecureUserId(userId);
            mStorage.writeCredentialHash(CredentialHash.createEmptyHash(), userId);
            mStorage.writeCredentialHash(CredentialHash.createEmptyHash(), userId);
            setKeystorePassword(null, userId);
            setKeystorePassword(null, userId);
@@ -1688,9 +1687,17 @@ public class LockSettingsService extends ILockSettings.Stub {
        addUserKeyAuth(userId, token, secretFromCredential(credential));
        addUserKeyAuth(userId, token, secretFromCredential(credential));
    }
    }


    private void clearUserKeyProtection(int userId) throws RemoteException {
    private void clearUserKeyProtection(int userId, byte[] secret) {
        if (DEBUG) Slog.d(TAG, "clearUserKeyProtection user=" + userId);
        if (DEBUG) Slog.d(TAG, "clearUserKeyProtection user=" + userId);
        addUserKeyAuth(userId, null, null);
        final UserInfo userInfo = mUserManager.getUserInfo(userId);
        final long callingId = Binder.clearCallingIdentity();
        try {
            mStorageManager.clearUserKeyAuth(userId, userInfo.serialNumber, null, secret);
        } catch (RemoteException e) {
            throw new IllegalStateException("clearUserKeyAuth failed user=" + userId);
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
    }
    }


    private static byte[] secretFromCredential(byte[] credential) throws RemoteException {
    private static byte[] secretFromCredential(byte[] credential) throws RemoteException {
@@ -2512,7 +2519,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            setAuthlessUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
            setAuthlessUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
            setKeystorePassword(auth.deriveKeyStorePassword(), userId);
            setKeystorePassword(auth.deriveKeyStorePassword(), userId);
        } else {
        } else {
            clearUserKeyProtection(userId);
            clearUserKeyProtection(userId, null);
            setKeystorePassword(null, userId);
            setKeystorePassword(null, userId);
            getGateKeeperService().clearSecureUserId(userId);
            getGateKeeperService().clearSecureUserId(userId);
        }
        }
@@ -2532,23 +2539,12 @@ public class LockSettingsService extends ILockSettings.Stub {
            return type == PersistentData.TYPE_SP || type == PersistentData.TYPE_SP_WEAVER;
            return type == PersistentData.TYPE_SP || type == PersistentData.TYPE_SP_WEAVER;
        }
        }
        long handle = getSyntheticPasswordHandleLocked(userId);
        long handle = getSyntheticPasswordHandleLocked(userId);
        // This is a global setting
        return handle != SyntheticPasswordManager.DEFAULT_HANDLE;
        long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY,
                SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT, UserHandle.USER_SYSTEM);
      return enabled != 0 && handle != SyntheticPasswordManager.DEFAULT_HANDLE;
    }
    }


    @VisibleForTesting
    @VisibleForTesting
    protected boolean shouldMigrateToSyntheticPasswordLocked(int userId) {
    protected boolean shouldMigrateToSyntheticPasswordLocked(int userId) {
        long handle = getSyntheticPasswordHandleLocked(userId);
        return true;
        // This is a global setting
        long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY,
                SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT, UserHandle.USER_SYSTEM);
        return enabled != 0 && handle == SyntheticPasswordManager.DEFAULT_HANDLE;
    }

    private void enableSyntheticPasswordLocked() {
        setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
    }
    }


    private VerifyCredentialResponse spBasedDoVerifyCredential(byte[] userCredential,
    private VerifyCredentialResponse spBasedDoVerifyCredential(byte[] userCredential,
@@ -2698,7 +2694,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            // during boot. Vold storage needs to be unlocked before manipulation of the keys can
            // during boot. Vold storage needs to be unlocked before manipulation of the keys can
            // succeed.
            // succeed.
            unlockUserKey(userId, null, auth.deriveDiskEncryptionKey());
            unlockUserKey(userId, null, auth.deriveDiskEncryptionKey());
            clearUserKeyProtection(userId);
            clearUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
            fixateNewestUserKeyAuth(userId);
            fixateNewestUserKeyAuth(userId);
            unlockKeystore(auth.deriveKeyStorePassword(), userId);
            unlockKeystore(auth.deriveKeyStorePassword(), userId);
            setKeystorePassword(null, userId);
            setKeystorePassword(null, userId);
@@ -2829,7 +2825,6 @@ public class LockSettingsService extends ILockSettings.Stub {
            throws RemoteException {
            throws RemoteException {
        if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId);
        if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId);
        synchronized (mSpManager) {
        synchronized (mSpManager) {
            enableSyntheticPasswordLocked();
            // Migrate to synthetic password based credentials if the user has no password,
            // Migrate to synthetic password based credentials if the user has no password,
            // the token can then be activated immediately.
            // the token can then be activated immediately.
            AuthenticationToken auth = null;
            AuthenticationToken auth = null;
+12 −0
Original line number Original line Diff line number Diff line
@@ -215,6 +215,18 @@ public abstract class BaseLockSettingsServiceTests {
            }
            }
        }).when(sm).addUserKeyAuth(anyInt(), anyInt(), any(), any());
        }).when(sm).addUserKeyAuth(anyInt(), anyInt(), any(), any());


        doAnswer(new Answer<Void>() {
            @Override
            public Void answer(InvocationOnMock invocation) throws Throwable {
                Object[] args = invocation.getArguments();
                mStorageManager.clearUserKeyAuth((int) args[0] /* userId */,
                        (int) args[1] /* serialNumber */,
                        (byte[]) args[2] /* token */,
                        (byte[]) args[3] /* secret */);
                return null;
            }
        }).when(sm).clearUserKeyAuth(anyInt(), anyInt(), any(), any());

        doAnswer(
        doAnswer(
                new Answer<Void>() {
                new Answer<Void>() {
            @Override
            @Override
+9 −0
Original line number Original line Diff line number Diff line
@@ -36,6 +36,15 @@ public class FakeStorageManager {
        getUserAuth(userId).add(new Pair<>(token, secret));
        getUserAuth(userId).add(new Pair<>(token, secret));
    }
    }


    public void clearUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret) {
        ArrayList<Pair<byte[], byte[]>> auths = getUserAuth(userId);
        if (token == null && secret == null) {
            return;
        }
        auths.remove(new Pair<>(token, secret));
        auths.add(new Pair<>(null, null));
    }

    public void fixateNewestUserKeyAuth(int userId) {
    public void fixateNewestUserKeyAuth(int userId) {
        ArrayList<Pair<byte[], byte[]>> auths = mAuth.get(userId);
        ArrayList<Pair<byte[], byte[]>> auths = mAuth.get(userId);
        Pair<byte[], byte[]> latest = auths.get(auths.size() - 1);
        Pair<byte[], byte[]> latest = auths.get(auths.size() - 1);
Loading