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

Commit 658b4ca4 authored by Paul Crowley's avatar Paul Crowley Committed by Android (Google) Code Review
Browse files

Merge "Provide secret to vold to remove credential"

parents 0231ac86 9ba99ed3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -193,4 +193,5 @@ interface IStorageManager {
    void startCheckpoint(int numTries) = 85;
    boolean needsCheckpoint() = 86;
    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 Diff line number Diff line
@@ -2988,6 +2988,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
     */
+13 −5
Original line number Diff line number Diff line
@@ -1622,7 +1622,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        }

        if (credential.isNone()) {
            clearUserKeyProtection(userId);
            clearUserKeyProtection(userId, null);
            gateKeeperClearSecureUserId(userId);
            mStorage.writeCredentialHash(CredentialHash.createEmptyHash(), userId);
            // Still update PASSWORD_TYPE_KEY if we are running in pre-synthetic password code path,
@@ -1813,9 +1813,17 @@ public class LockSettingsService extends ILockSettings.Stub {
        addUserKeyAuth(userId, token, secretFromCredential(credential));
    }

    private void clearUserKeyProtection(int userId) {
    private void clearUserKeyProtection(int userId, byte[] secret) {
        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(LockscreenCredential credential) {
@@ -2571,7 +2579,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            setAuthlessUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
            setKeystorePassword(auth.deriveKeyStorePassword(), userId);
        } else {
            clearUserKeyProtection(userId);
            clearUserKeyProtection(userId, null);
            setKeystorePassword(null, userId);
            gateKeeperClearSecureUserId(userId);
        }
@@ -2765,7 +2773,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            // during boot. Vold storage needs to be unlocked before manipulation of the keys can
            // succeed.
            unlockUserKey(userId, null, auth.deriveDiskEncryptionKey());
            clearUserKeyProtection(userId);
            clearUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
            fixateNewestUserKeyAuth(userId);
            unlockKeystore(auth.deriveKeyStorePassword(), userId);
            setKeystorePassword(null, userId);
+12 −0
Original line number Diff line number Diff line
@@ -230,6 +230,18 @@ public abstract class BaseLockSettingsServiceTests {
            }
        }).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(
                new Answer<Void>() {
            @Override
+9 −0
Original line number Diff line number Diff line
@@ -36,6 +36,15 @@ public class FakeStorageManager {
        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) {
        ArrayList<Pair<byte[], byte[]>> auths = mAuth.get(userId);
        Pair<byte[], byte[]> latest = auths.get(auths.size() - 1);