Merge "Provide secret to vold to remove credential"

This commit is contained in:
Paul Crowley
2020-01-19 21:58:01 +00:00
committed by Android (Google) Code Review
5 changed files with 53 additions and 5 deletions

View File

@@ -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;
}

View File

@@ -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
*/

View File

@@ -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);

View File

@@ -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

View File

@@ -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);