diff options
| -rw-r--r-- | core/java/android/security/keystore/RecoveryController.java (renamed from core/java/android/security/keystore/RecoveryManager.java) | 32 | ||||
| -rw-r--r-- | core/java/android/security/keystore/RecoveryControllerException.java | 2 | ||||
| -rw-r--r-- | core/java/android/security/keystore/RecoverySession.java | 12 | ||||
| -rw-r--r-- | core/java/com/android/internal/widget/ILockSettings.aidl | 2 | ||||
| -rw-r--r-- | services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java | 16 | ||||
| -rw-r--r-- | services/core/java/com/android/server/locksettings/recoverablekeystore/WrappedKey.java | 8 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java | 5 |
7 files changed, 44 insertions, 33 deletions
diff --git a/core/java/android/security/keystore/RecoveryManager.java b/core/java/android/security/keystore/RecoveryController.java index a381a2cea4b7..87283cbd75ab 100644 --- a/core/java/android/security/keystore/RecoveryManager.java +++ b/core/java/android/security/keystore/RecoveryController.java @@ -31,12 +31,25 @@ import java.util.List; import java.util.Map; /** - * A wrapper around KeyStore which lets key be exported to trusted hardware on server side and - * recovered later. + * An assistant for generating {@link javax.crypto.SecretKey} instances that can be recovered by + * other Android devices belonging to the user. The exported keychain is protected by the user's + * lock screen. + * + * <p>The RecoveryController must be paired with a recovery agent. The recovery agent is responsible + * for transporting the keychain to remote trusted hardware. This hardware must prevent brute force + * attempts against the user's lock screen by limiting the number of allowed guesses (to, e.g., 10). + * After that number of incorrect guesses, the trusted hardware no longer allows access to the + * key chain. + * + * <p>For now only the recovery agent itself is able to create keys, so it is expected that the + * recovery agent is itself the system app. + * + * <p>A recovery agent requires the privileged permission + * {@code android.Manifest.permission#RECOVER_KEYSTORE}. * * @hide */ -public class RecoveryManager { +public class RecoveryController { private static final String TAG = "RecoveryController"; /** Key has been successfully synced. */ @@ -96,28 +109,28 @@ public class RecoveryManager { private final ILockSettings mBinder; - private RecoveryManager(ILockSettings binder) { + private RecoveryController(ILockSettings binder) { mBinder = binder; } /** * Gets a new instance of the class. */ - public static RecoveryManager getInstance() { + public static RecoveryController getInstance() { ILockSettings lockSettings = ILockSettings.Stub.asInterface(ServiceManager.getService("lock_settings")); - return new RecoveryManager(lockSettings); + return new RecoveryController(lockSettings); } /** - * Initializes key recovery service for the calling application. RecoveryManager + * Initializes key recovery service for the calling application. RecoveryController * randomly chooses one of the keys from the list and keeps it to use for future key export * operations. Collection of all keys in the list must be signed by the provided {@code * rootCertificateAlias}, which must also be present in the list of root certificates - * preinstalled on the device. The random selection allows RecoveryManager to select + * preinstalled on the device. The random selection allows RecoveryController to select * which of a set of remote recovery service devices will be used. * - * <p>In addition, RecoveryManager enforces a delay of three months between + * <p>In addition, RecoveryController enforces a delay of three months between * consecutive initialization attempts, to limit the ability of an attacker to often switch * remote recovery devices and significantly increase number of recovery attempts. * @@ -373,7 +386,6 @@ public class RecoveryManager { * The method generates symmetric key for a session, which trusted remote device can use to * return recovery key. * - * @param sessionId ID for recovery session. * @param verifierPublicKey Encoded {@code java.security.cert.X509Certificate} with Public key * used to create the recovery blob on the source device. * Keystore will verify the certificate using root of trust. diff --git a/core/java/android/security/keystore/RecoveryControllerException.java b/core/java/android/security/keystore/RecoveryControllerException.java index 31fd4af9a7d1..5b806b75ebab 100644 --- a/core/java/android/security/keystore/RecoveryControllerException.java +++ b/core/java/android/security/keystore/RecoveryControllerException.java @@ -19,7 +19,7 @@ package android.security.keystore; import java.security.GeneralSecurityException; /** - * Base exception for errors thrown by {@link RecoveryManager}. + * Base exception for errors thrown by {@link RecoveryController}. * * @hide */ diff --git a/core/java/android/security/keystore/RecoverySession.java b/core/java/android/security/keystore/RecoverySession.java index f78551fdf194..ae8d91af3230 100644 --- a/core/java/android/security/keystore/RecoverySession.java +++ b/core/java/android/security/keystore/RecoverySession.java @@ -29,18 +29,18 @@ public class RecoverySession implements AutoCloseable { private static final int SESSION_ID_LENGTH_BYTES = 16; private final String mSessionId; - private final RecoveryManager mRecoveryManager; + private final RecoveryController mRecoveryController; - private RecoverySession(RecoveryManager recoveryManager, String sessionId) { - mRecoveryManager = recoveryManager; + private RecoverySession(RecoveryController recoveryController, String sessionId) { + mRecoveryController = recoveryController; mSessionId = sessionId; } /** * A new session, started by {@code recoveryManager}. */ - static RecoverySession newInstance(RecoveryManager recoveryManager) { - return new RecoverySession(recoveryManager, newSessionId()); + static RecoverySession newInstance(RecoveryController recoveryController) { + return new RecoverySession(recoveryController, newSessionId()); } /** @@ -66,6 +66,6 @@ public class RecoverySession implements AutoCloseable { @Override public void close() { - mRecoveryManager.closeSession(this); + mRecoveryController.closeSession(this); } } diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl index 274239b218ce..e3f1f472ce5e 100644 --- a/core/java/com/android/internal/widget/ILockSettings.aidl +++ b/core/java/com/android/internal/widget/ILockSettings.aidl @@ -60,7 +60,7 @@ interface ILockSettings { in byte[] token, int requestedQuality, int userId); void unlockUserWithToken(long tokenHandle, in byte[] token, int userId); - // Keystore RecoveryManager methods. + // Keystore RecoveryController methods. // {@code ServiceSpecificException} may be thrown to signal an error, which caller can // convert to {@code RecoveryManagerException}. void initRecoveryService(in String rootCertificateAlias, in byte[] signedPublicKeyList); 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 59855beec625..76508d5817e2 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java @@ -16,12 +16,12 @@ package com.android.server.locksettings.recoverablekeystore; -import static android.security.keystore.RecoveryManager.ERROR_BAD_CERTIFICATE_FORMAT; -import static android.security.keystore.RecoveryManager.ERROR_DECRYPTION_FAILED; -import static android.security.keystore.RecoveryManager.ERROR_INSECURE_USER; -import static android.security.keystore.RecoveryManager.ERROR_NO_SNAPSHOT_PENDING; -import static android.security.keystore.RecoveryManager.ERROR_SERVICE_INTERNAL_ERROR; -import static android.security.keystore.RecoveryManager.ERROR_SESSION_EXPIRED; +import static android.security.keystore.RecoveryController.ERROR_BAD_CERTIFICATE_FORMAT; +import static android.security.keystore.RecoveryController.ERROR_DECRYPTION_FAILED; +import static android.security.keystore.RecoveryController.ERROR_INSECURE_USER; +import static android.security.keystore.RecoveryController.ERROR_NO_SNAPSHOT_PENDING; +import static android.security.keystore.RecoveryController.ERROR_SERVICE_INTERNAL_ERROR; +import static android.security.keystore.RecoveryController.ERROR_SESSION_EXPIRED; import android.annotation.NonNull; import android.annotation.Nullable; @@ -35,8 +35,8 @@ import android.os.UserHandle; import android.security.keystore.KeychainProtectionParams; import android.security.keystore.KeychainSnapshot; +import android.security.keystore.RecoveryController; import android.security.keystore.WrappedApplicationKey; -import android.security.keystore.RecoveryManager; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; @@ -63,7 +63,7 @@ import java.util.concurrent.Executors; import javax.crypto.AEADBadTagException; /** - * Class with {@link RecoveryManager} API implementation and internal methods to interact + * Class with {@link RecoveryController} API implementation and internal methods to interact * with {@code LockSettingsService}. * * @hide diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/WrappedKey.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/WrappedKey.java index 0042e101b4f1..c33c9de95182 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/WrappedKey.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/WrappedKey.java @@ -16,8 +16,8 @@ package com.android.server.locksettings.recoverablekeystore; +import android.security.keystore.RecoveryController; import android.util.Log; -import android.security.keystore.RecoveryManager; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; @@ -97,7 +97,7 @@ public class WrappedKey { /*nonce=*/ cipher.getIV(), /*keyMaterial=*/ encryptedKeyMaterial, /*platformKeyGenerationId=*/ wrappingKey.getGenerationId(), - RecoveryManager.RECOVERY_STATUS_SYNC_IN_PROGRESS); + RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS); } /** @@ -107,14 +107,14 @@ public class WrappedKey { * @param keyMaterial The encrypted bytes of the key material. * @param platformKeyGenerationId The generation ID of the key used to wrap this key. * - * @see RecoveryManager.RECOVERY_STATUS_SYNC_IN_PROGRESS + * @see RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS * @hide */ public WrappedKey(byte[] nonce, byte[] keyMaterial, int platformKeyGenerationId) { mNonce = nonce; mKeyMaterial = keyMaterial; mPlatformKeyGenerationId = platformKeyGenerationId; - mRecoveryStatus = RecoveryManager.RECOVERY_STATUS_SYNC_IN_PROGRESS; + mRecoveryStatus = RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS; } /** 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 5cb7b677dbbd..f0254c6d5dfe 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 @@ -28,8 +28,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import android.content.Context; -import android.content.SharedPreferences; -import android.security.keystore.RecoveryManager; +import android.security.keystore.RecoveryController; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; @@ -283,7 +282,7 @@ public class RecoverableKeyStoreDbTest { Map<String, Integer> statuses = mRecoverableKeyStoreDb.getStatusForAllKeys(uid); assertThat(statuses).hasSize(3); - assertThat(statuses).containsEntry(alias, RecoveryManager.RECOVERY_STATUS_SYNC_IN_PROGRESS); + assertThat(statuses).containsEntry(alias, RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS); assertThat(statuses).containsEntry(alias2, status); assertThat(statuses).containsEntry(alias3, status); |