summaryrefslogtreecommitdiffstats
path: root/keystore/java/android
diff options
context:
space:
mode:
authorAlex Klyubin <klyubin@google.com>2015-04-29 17:32:00 -0700
committerAlex Klyubin <klyubin@google.com>2015-04-29 19:23:46 -0700
commit058de02073a129301d391c22b050f2d65adadb0f (patch)
treeac044fdec246ab94419443a66d084145a5531b57 /keystore/java/android
parentb62dc82b0c7208f106077b46fc7118da6baa6e13 (diff)
downloadframeworks_base-058de02073a129301d391c22b050f2d65adadb0f.zip
frameworks_base-058de02073a129301d391c22b050f2d65adadb0f.tar.gz
frameworks_base-058de02073a129301d391c22b050f2d65adadb0f.tar.bz2
Enable per-use user authenticated keys to be used.
This makes symmetric Cipher and Mac implementations backed by AndroidKeyStore succeed in their initialization when the key is configured to require user authentication for every use. Users of such keys should obtain an instance of Cipher or Mac, initialize it with the key, and then authorize the operation by passing this Cipher or Mac instance to FingerprintManager.authenticate. Bug: 18088752 Change-Id: Ia15a1e5f8274c3623f665dae1f400ff539639ab1
Diffstat (limited to 'keystore/java/android')
-rw-r--r--keystore/java/android/security/KeyStore.java3
-rw-r--r--keystore/java/android/security/KeyStoreCipherSpi.java5
-rw-r--r--keystore/java/android/security/KeyStoreHmacSpi.java6
3 files changed, 12 insertions, 2 deletions
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index f3b447e..1563863 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -543,6 +543,8 @@ public class KeyStore {
return new KeyStoreException(errorCode, "Key not found");
case VALUE_CORRUPTED:
return new KeyStoreException(errorCode, "Key blob corrupted");
+ case OP_AUTH_NEEDED:
+ return new KeyStoreException(errorCode, "Operation requires authorization");
default:
return new KeyStoreException(errorCode, String.valueOf(errorCode));
}
@@ -572,6 +574,7 @@ public class KeyStore {
case KeymasterDefs.KM_ERROR_KEY_NOT_YET_VALID:
return new KeyNotYetValidException();
case KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED:
+ case OP_AUTH_NEEDED:
{
// We now need to determine whether the key/operation can become usable if user
// authentication is performed, or whether it can never become usable again.
diff --git a/keystore/java/android/security/KeyStoreCipherSpi.java b/keystore/java/android/security/KeyStoreCipherSpi.java
index 9393e32..125ca41 100644
--- a/keystore/java/android/security/KeyStoreCipherSpi.java
+++ b/keystore/java/android/security/KeyStoreCipherSpi.java
@@ -298,7 +298,8 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
mAdditionalEntropyForBegin = null;
if (opResult == null) {
throw new KeyStoreConnectException();
- } else if (opResult.resultCode != KeyStore.NO_ERROR) {
+ } else if ((opResult.resultCode != KeyStore.NO_ERROR)
+ && (opResult.resultCode != KeyStore.OP_AUTH_NEEDED)) {
switch (opResult.resultCode) {
case KeymasterDefs.KM_ERROR_INVALID_NONCE:
throw new InvalidAlgorithmParameterException("Invalid IV");
@@ -309,6 +310,8 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
if (opResult.token == null) {
throw new IllegalStateException("Keystore returned null operation token");
}
+ // The operation handle/token is now either valid for use immediately or needs to be
+ // authorized through user authentication (if the error code was OP_AUTH_NEEDED).
mOperationToken = opResult.token;
mOperationHandle = opResult.operationHandle;
loadAlgorithmSpecificParametersFromBeginResult(keymasterOutputArgs);
diff --git a/keystore/java/android/security/KeyStoreHmacSpi.java b/keystore/java/android/security/KeyStoreHmacSpi.java
index 8d71d1d..2a33721 100644
--- a/keystore/java/android/security/KeyStoreHmacSpi.java
+++ b/keystore/java/android/security/KeyStoreHmacSpi.java
@@ -168,12 +168,16 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
new KeymasterArguments());
if (opResult == null) {
throw new KeyStoreConnectException();
- } else if (opResult.resultCode != KeyStore.NO_ERROR) {
+ } else if ((opResult.resultCode != KeyStore.NO_ERROR)
+ && (opResult.resultCode != KeyStore.OP_AUTH_NEEDED)) {
throw mKeyStore.getInvalidKeyException(mKey.getAlias(), opResult.resultCode);
}
+
if (opResult.token == null) {
throw new IllegalStateException("Keystore returned null operation token");
}
+ // The operation handle/token is now either valid for use immediately or needs to be
+ // authorized through user authentication (if the error code was OP_AUTH_NEEDED).
mOperationToken = opResult.token;
mOperationHandle = opResult.operationHandle;
mChunkedStreamer = new KeyStoreCryptoOperationChunkedStreamer(