Loading core/java/android/security/keystore/RecoveryManager.java→core/java/android/security/keystore/RecoveryController.java +22 −10 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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. * Loading Loading @@ -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. Loading core/java/android/security/keystore/RecoveryControllerException.java +1 −1 Original line number Diff line number Diff line Loading @@ -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 */ Loading core/java/android/security/keystore/RecoverySession.java +6 −6 Original line number Diff line number Diff line Loading @@ -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()); } /** Loading @@ -66,6 +66,6 @@ public class RecoverySession implements AutoCloseable { @Override public void close() { mRecoveryManager.closeSession(this); mRecoveryController.closeSession(this); } } core/java/com/android/internal/widget/ILockSettings.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java +8 −8 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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 Loading Loading
core/java/android/security/keystore/RecoveryManager.java→core/java/android/security/keystore/RecoveryController.java +22 −10 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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. * Loading Loading @@ -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. Loading
core/java/android/security/keystore/RecoveryControllerException.java +1 −1 Original line number Diff line number Diff line Loading @@ -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 */ Loading
core/java/android/security/keystore/RecoverySession.java +6 −6 Original line number Diff line number Diff line Loading @@ -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()); } /** Loading @@ -66,6 +66,6 @@ public class RecoverySession implements AutoCloseable { @Override public void close() { mRecoveryManager.closeSession(this); mRecoveryController.closeSession(this); } }
core/java/com/android/internal/widget/ILockSettings.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading
services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java +8 −8 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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 Loading