From 5daccec818ffc26fafb795b17d5b1f76fbce3a60 Mon Sep 17 00:00:00 2001 From: Robert Berry Date: Sat, 6 Jan 2018 19:16:25 +0000 Subject: [PATCH] Add API to remove recoverable keys Test: adb shell am instrument -w -e package com.android.server.locksettings.recoverablekeystore com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner Change-Id: Ib69e730467974d34ffe4a700bd6aaf4543a524ae --- .../android/internal/widget/ILockSettings.aidl | 1 + .../server/locksettings/LockSettingsService.java | 5 +++++ .../RecoverableKeyStoreManager.java | 5 ++++- .../storage/RecoverableKeyStoreDb.java | 13 +++++++++++++ .../RecoverableKeyStoreManagerTest.java | 10 ++++++++++ .../storage/RecoverableKeyStoreDbTest.java | 16 ++++++++++++++++ 6 files changed, 49 insertions(+), 1 deletion(-) diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl index 862288bdd63ba..4e7df2858cb23 100644 --- a/core/java/com/android/internal/widget/ILockSettings.aidl +++ b/core/java/com/android/internal/widget/ILockSettings.aidl @@ -66,6 +66,7 @@ interface ILockSettings { void initRecoveryService(in String rootCertificateAlias, in byte[] signedPublicKeyList); KeyStoreRecoveryData getRecoveryData(in byte[] account); byte[] generateAndStoreKey(String alias); + void removeKey(String alias); void setSnapshotCreatedPendingIntent(in PendingIntent intent); Map getRecoverySnapshotVersions(); void setServerParameters(long serverParameters); diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 1fa8da7347d52..1e852327914c2 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -2030,6 +2030,11 @@ public class LockSettingsService extends ILockSettings.Stub { sessionId, recoveryKeyBlob, applicationKeys); } + @Override + public void removeKey(@NonNull String alias) throws RemoteException { + mRecoverableKeyStoreManager.removeKey(alias); + } + @Override public byte[] generateAndStoreKey(@NonNull String alias) throws RemoteException { return mRecoverableKeyStoreManager.generateAndStoreKey(alias); diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java index 9865079a79fac..54acb871fdd67 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java @@ -411,7 +411,6 @@ public class RecoverableKeyStoreManager { int uid = Binder.getCallingUid(); int userId = UserHandle.getCallingUserId(); - PlatformEncryptionKey encryptionKey; try { encryptionKey = mPlatformKeyManager.getEncryptKey(userId); @@ -433,6 +432,10 @@ public class RecoverableKeyStoreManager { } } + public void removeKey(@NonNull String alias) throws RemoteException { + mDatabase.removeKey(Binder.getCallingUid(), alias); + } + private byte[] decryptRecoveryKey( RecoverySessionStorage.Entry sessionEntry, byte[] encryptedClaimResponse) throws RemoteException, ServiceSpecificException { diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java index 5ca5da4ead566..33249e9de8d36 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java @@ -146,6 +146,19 @@ public class RecoverableKeyStoreDb { } } + /** + * Removes key with {@code alias} for app with {@code uid}. + * + * @return {@code true} if deleted a row. + */ + public boolean removeKey(int uid, String alias) { + SQLiteDatabase db = mKeyStoreDbHelper.getWritableDatabase(); + String selection = KeysEntry.COLUMN_NAME_UID + " = ? AND " + + KeysEntry.COLUMN_NAME_ALIAS + " = ?"; + String[] selectionArgs = { Integer.toString(uid), alias }; + return db.delete(KeysEntry.TABLE_NAME, selection, selectionArgs) > 0; + } + /** * Returns all statuses for keys {@code uid} and {@code platformKeyGenerationId}. * diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java index c0efb20b1a7ef..967c3b89f2cf5 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java @@ -192,6 +192,16 @@ public class RecoverableKeyStoreManagerTest { .hasLength(RECOVERABLE_KEY_SIZE_BYTES); } + @Test + public void removeKey_removesAKey() throws Exception { + int uid = Binder.getCallingUid(); + mRecoverableKeyStoreManager.generateAndStoreKey(TEST_ALIAS); + + mRecoverableKeyStoreManager.removeKey(TEST_ALIAS); + + assertThat(mRecoverableKeyStoreDb.getKey(uid, TEST_ALIAS)).isNull(); + } + @Test public void startRecoverySession_checksPermissionFirst() throws Exception { mRecoverableKeyStoreManager.startRecoverySession( diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java index a8c7d5e5adba4..c7b338c6fa49a 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java @@ -112,6 +112,22 @@ public class RecoverableKeyStoreDbTest { mRecoverableKeyStoreDb.getKey(2, alias).getNonce()); } + @Test + public void removeKey_removesAKey() { + int userId = 6; + int uid = 60001; + String alias = "rupertbates"; + WrappedKey key = new WrappedKey( + getUtf8Bytes("nonce1"), + getUtf8Bytes("key1"), + /*platformKeyGenerationId=*/ 1); + mRecoverableKeyStoreDb.insertKey(userId, uid, alias, key); + + assertTrue(mRecoverableKeyStoreDb.removeKey(uid, alias)); + + assertNull(mRecoverableKeyStoreDb.getKey(uid, alias)); + } + @Test public void getKey_returnsNullIfNoKey() { WrappedKey key = mRecoverableKeyStoreDb.getKey(