diff options
| author | Dmitry Dementyev <dementyev@google.com> | 2018-01-31 16:09:32 -0800 |
|---|---|---|
| committer | Dmitry Dementyev <dementyev@google.com> | 2018-02-01 17:41:18 -0800 |
| commit | 29b9de5b8a9b38290c2855890ae1f7a93c0b8421 (patch) | |
| tree | 13b9029c41af1de6bcf8e28828fc4713e08c7f13 /core/java | |
| parent | c13b54361d3a229582c2f2a7d479f500c7b86f94 (diff) | |
Update RecoveryController to use KeyStore grant API.
Missing parts:
1) Whitelist locksettingsservice to use grant API.
2) Probably have similar update for recovered keys - they will live in
system service and RecoveryAgent will use getKey() method to access
them.
3) ApplicationKeyStorageTest
Bug: 66499222
Test: adb shell am instrument -w -e package \
com.android.server.locksettings.recoverablekeystore \
com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
Change-Id: I584b89e3f777bed679b2eb5173750f3f1dee3635
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/security/keystore/recovery/RecoveryController.java | 78 | ||||
| -rw-r--r-- | core/java/com/android/internal/widget/ILockSettings.aidl | 2 |
2 files changed, 77 insertions, 3 deletions
diff --git a/core/java/android/security/keystore/recovery/RecoveryController.java b/core/java/android/security/keystore/recovery/RecoveryController.java index 4e4a0374087e..7cd08f76a47e 100644 --- a/core/java/android/security/keystore/recovery/RecoveryController.java +++ b/core/java/android/security/keystore/recovery/RecoveryController.java @@ -26,9 +26,13 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceSpecificException; +import android.security.KeyStore; +import android.security.keystore.AndroidKeyStoreProvider; import com.android.internal.widget.ILockSettings; +import java.security.Key; +import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.List; @@ -113,9 +117,11 @@ public class RecoveryController { private final ILockSettings mBinder; + private final KeyStore mKeyStore; - private RecoveryController(ILockSettings binder) { + private RecoveryController(ILockSettings binder, KeyStore keystore) { mBinder = binder; + mKeyStore = keystore; } /** @@ -133,7 +139,7 @@ public class RecoveryController { public static RecoveryController getInstance(Context context) { ILockSettings lockSettings = ILockSettings.Stub.asInterface(ServiceManager.getService("lock_settings")); - return new RecoveryController(lockSettings); + return new RecoveryController(lockSettings, KeyStore.getInstance()); } /** @@ -430,6 +436,7 @@ public class RecoveryController { } /** + * Deprecated. * Generates a AES256/GCM/NoPADDING key called {@code alias} and loads it into the recoverable * key store. Returns the raw material of the key. * @@ -444,7 +451,6 @@ public class RecoveryController { public byte[] generateAndStoreKey(@NonNull String alias, byte[] account) throws InternalRecoveryServiceException, LockScreenRequiredException { try { - // TODO: add account return mBinder.generateAndStoreKey(alias); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -457,6 +463,72 @@ public class RecoveryController { } /** + * Generates a AES256/GCM/NoPADDING key called {@code alias} and loads it into the recoverable + * key store. Returns {@link javax.crypto.SecretKey}. + * + * @param alias The key alias. + * @param account The account associated with the key. + * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery + * service. + * @throws LockScreenRequiredException if the user has not set a lock screen. This is required + * to generate recoverable keys, as the snapshots are encrypted using a key derived from the + * lock screen. + * @hide + */ + public Key generateKey(@NonNull String alias, byte[] account) + throws InternalRecoveryServiceException, LockScreenRequiredException { + // TODO: update RecoverySession.recoverKeys + try { + String grantAlias = mBinder.generateKey(alias, account); + if (grantAlias == null) { + return null; + } + Key result = AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore( + mKeyStore, + grantAlias, + KeyStore.UID_SELF); + return result; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } catch (UnrecoverableKeyException e) { + throw new InternalRecoveryServiceException("Access to newly generated key failed for"); + } catch (ServiceSpecificException e) { + if (e.errorCode == ERROR_INSECURE_USER) { + throw new LockScreenRequiredException(e.getMessage()); + } + throw wrapUnexpectedServiceSpecificException(e); + } + } + + /** + * Gets a key called {@code alias} from the recoverable key store. + * + * @param alias The key alias. + * @return The key. + * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery + * service. + * @throws UnrecoverableKeyException if key is permanently invalidated or not found. + * @hide + */ + public @Nullable Key getKey(@NonNull String alias) + throws InternalRecoveryServiceException, UnrecoverableKeyException { + try { + String grantAlias = mBinder.getKey(alias); + if (grantAlias == null) { + return null; + } + return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore( + mKeyStore, + grantAlias, + KeyStore.UID_SELF); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } catch (ServiceSpecificException e) { + throw wrapUnexpectedServiceSpecificException(e); + } + } + + /** * Removes a key called {@code alias} from the recoverable key store. * * @param alias The key alias. diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl index 5673814ca362..732534ccbcbe 100644 --- a/core/java/com/android/internal/widget/ILockSettings.aidl +++ b/core/java/com/android/internal/widget/ILockSettings.aidl @@ -66,6 +66,8 @@ interface ILockSettings { void initRecoveryService(in String rootCertificateAlias, in byte[] signedPublicKeyList); KeyChainSnapshot getKeyChainSnapshot(); byte[] generateAndStoreKey(String alias); + String generateKey(String alias, in byte[] account); + String getKey(String alias); void removeKey(String alias); void setSnapshotCreatedPendingIntent(in PendingIntent intent); Map getRecoverySnapshotVersions(); |
