diff options
| author | Bo Zhu <bozhu@google.com> | 2018-02-26 15:54:25 -0800 |
|---|---|---|
| committer | Bo Zhu <bozhu@google.com> | 2018-02-27 09:18:59 -0800 |
| commit | 2c8e5383c836d2dfa39b0be6bfa281285667a880 (patch) | |
| tree | 0aaed80045387f482767810ec2ccf5e7187e10f3 /core/java | |
| parent | fc7c749817cdb77bc159325d44cf0b7fbad634ef (diff) | |
Add a new API to import a key provided by the caller, such that this key
can also be synced to the remote service
This API may be useful for backward-compatibility work, e.g., recovering
a key that's backed up in Android Q+ to Android P without updating the
Android P Frameworks code. This API may also be useful for other use cases.
Bug: 73785182
Change-Id: I1022dffb6a12bdf3df2022db5739169fcc9347d2
Test: adb shell am instrument -w -e package \
com.android.server.locksettings.recoverablekeystore \
com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/security/keystore/recovery/RecoveryController.java | 43 | ||||
| -rw-r--r-- | core/java/com/android/internal/widget/ILockSettings.aidl | 1 |
2 files changed, 44 insertions, 0 deletions
diff --git a/core/java/android/security/keystore/recovery/RecoveryController.java b/core/java/android/security/keystore/recovery/RecoveryController.java index 0683e02b66a7..426ca5c472b9 100644 --- a/core/java/android/security/keystore/recovery/RecoveryController.java +++ b/core/java/android/security/keystore/recovery/RecoveryController.java @@ -113,6 +113,14 @@ public class RecoveryController { */ public static final int ERROR_DECRYPTION_FAILED = 26; + /** + * Error thrown if the format of a given key is invalid. This might be because the key has a + * wrong length, invalid content, etc. + * + * @hide + */ + public static final int ERROR_INVALID_KEY_FORMAT = 27; + private final ILockSettings mBinder; private final KeyStore mKeyStore; @@ -461,6 +469,7 @@ public class RecoveryController { } } + // TODO: Unhide the following APIs, generateKey(), importKey(), and getKey() /** * @deprecated Use {@link #generateKey(String)}. * @removed @@ -503,6 +512,40 @@ public class RecoveryController { } /** + * Imports a 256-bit recoverable AES key with the given {@code alias} and the raw bytes {@code + * keyBytes}. + * + * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery + * service. + * @throws LockScreenRequiredException if the user does not have a lock screen set. A lock + * screen is required to generate recoverable keys. + * + * @hide + */ + public Key importKey(@NonNull String alias, byte[] keyBytes) + throws InternalRecoveryServiceException, LockScreenRequiredException { + try { + String grantAlias = mBinder.importKey(alias, keyBytes); + if (grantAlias == null) { + throw new InternalRecoveryServiceException("Null grant alias"); + } + return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore( + mKeyStore, + grantAlias, + KeyStore.UID_SELF); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } catch (UnrecoverableKeyException e) { + throw new InternalRecoveryServiceException("Failed to get key from keystore", e); + } 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. diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl index d3fc644c2341..7c9cf7a183cd 100644 --- a/core/java/com/android/internal/widget/ILockSettings.aidl +++ b/core/java/com/android/internal/widget/ILockSettings.aidl @@ -68,6 +68,7 @@ interface ILockSettings { KeyChainSnapshot getKeyChainSnapshot(); byte[] generateAndStoreKey(String alias); String generateKey(String alias); + String importKey(String alias, in byte[] keyBytes); String getKey(String alias); void removeKey(String alias); void setSnapshotCreatedPendingIntent(in PendingIntent intent); |
