summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorBo Zhu <bozhu@google.com>2018-02-26 15:54:25 -0800
committerBo Zhu <bozhu@google.com>2018-02-27 09:18:59 -0800
commit2c8e5383c836d2dfa39b0be6bfa281285667a880 (patch)
tree0aaed80045387f482767810ec2ccf5e7187e10f3 /core/java
parentfc7c749817cdb77bc159325d44cf0b7fbad634ef (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.java43
-rw-r--r--core/java/com/android/internal/widget/ILockSettings.aidl1
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);