summaryrefslogtreecommitdiffstats
path: root/keystore/java/android/security
diff options
context:
space:
mode:
authorAlex Klyubin <klyubin@google.com>2015-04-01 17:34:36 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2015-04-01 17:34:37 +0000
commitc461452eb78867032092b2fce14c2fcb3e7ab34e (patch)
tree5b338ecfe89e6901b712d9a40bb359e99dadd440 /keystore/java/android/security
parentc6cc9d820d007a6b11df2bb3274d40743e1f1d87 (diff)
parentc8e557470fc94733c9340c4c67ee69c225bbaa70 (diff)
downloadframeworks_base-c461452eb78867032092b2fce14c2fcb3e7ab34e.zip
frameworks_base-c461452eb78867032092b2fce14c2fcb3e7ab34e.tar.gz
frameworks_base-c461452eb78867032092b2fce14c2fcb3e7ab34e.tar.bz2
Merge "Hook in user authenticators and their exceptions."
Diffstat (limited to 'keystore/java/android/security')
-rw-r--r--keystore/java/android/security/AndroidKeyStore.java7
-rw-r--r--keystore/java/android/security/KeyStoreCipherSpi.java7
-rw-r--r--keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java6
-rw-r--r--keystore/java/android/security/KeyStoreHmacSpi.java7
-rw-r--r--keystore/java/android/security/KeyStoreKeyConstraints.java86
-rw-r--r--keystore/java/android/security/KeyStoreKeyGeneratorSpi.java10
-rw-r--r--keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java18
-rw-r--r--keystore/java/android/security/KeymasterUtils.java15
-rw-r--r--keystore/java/android/security/UserNotAuthenticatedException.java33
9 files changed, 159 insertions, 30 deletions
diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/AndroidKeyStore.java
index 846d1f1..4650d27 100644
--- a/keystore/java/android/security/AndroidKeyStore.java
+++ b/keystore/java/android/security/AndroidKeyStore.java
@@ -536,10 +536,9 @@ public class AndroidKeyStore extends KeyStoreSpi {
if (params.getUserAuthenticators().isEmpty()) {
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
} else {
- // TODO: Pass-in user authenticator IDs once the Keymaster API has stabilized
-// for (int userAuthenticatorId : params.getUserAuthenticators()) {
-// args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_ID, userAuthenticatorId);
-// }
+ args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
+ KeyStoreKeyConstraints.UserAuthenticator.allToKeymaster(
+ params.getUserAuthenticators()));
}
if (params.getUserAuthenticationValidityDurationSeconds() != null) {
args.addInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
diff --git a/keystore/java/android/security/KeyStoreCipherSpi.java b/keystore/java/android/security/KeyStoreCipherSpi.java
index bdaa812..5219086 100644
--- a/keystore/java/android/security/KeyStoreCipherSpi.java
+++ b/keystore/java/android/security/KeyStoreCipherSpi.java
@@ -224,8 +224,7 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
if (opResult == null) {
throw new KeyStoreConnectException();
} else if (opResult.resultCode != KeyStore.NO_ERROR) {
- throw new CryptoOperationException("Failed to start keystore operation",
- KeymasterUtils.getExceptionForKeymasterError(opResult.resultCode));
+ throw KeymasterUtils.getCryptoOperationException(opResult.resultCode);
}
if (opResult.token == null) {
@@ -252,7 +251,7 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
try {
output = mMainDataStreamer.update(input, inputOffset, inputLen);
} catch (KeymasterException e) {
- throw new CryptoOperationException("Keystore operation failed", e);
+ throw KeymasterUtils.getCryptoOperationException(e);
}
if (output.length == 0) {
@@ -297,7 +296,7 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
case KeymasterDefs.KM_ERROR_VERIFICATION_FAILED:
throw new AEADBadTagException();
default:
- throw new CryptoOperationException("Keystore operation failed", e);
+ throw KeymasterUtils.getCryptoOperationException(e);
}
}
diff --git a/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
index 2b279f6..993614b 100644
--- a/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
+++ b/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
@@ -120,7 +120,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
if (opResult == null) {
throw new KeyStoreConnectException();
} else if (opResult.resultCode != KeyStore.NO_ERROR) {
- throw KeymasterUtils.getExceptionForKeymasterError(opResult.resultCode);
+ throw KeymasterUtils.getKeymasterException(opResult.resultCode);
}
if (opResult.inputConsumed == chunk.length) {
@@ -203,7 +203,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
if (opResult == null) {
throw new KeyStoreConnectException();
} else if (opResult.resultCode != KeyStore.NO_ERROR) {
- throw KeymasterUtils.getExceptionForKeymasterError(opResult.resultCode);
+ throw KeymasterUtils.getKeymasterException(opResult.resultCode);
}
return concat(output, opResult.output);
@@ -227,7 +227,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
if (opResult == null) {
throw new KeyStoreConnectException();
} else if (opResult.resultCode != KeyStore.NO_ERROR) {
- throw KeymasterUtils.getExceptionForKeymasterError(opResult.resultCode);
+ throw KeymasterUtils.getKeymasterException(opResult.resultCode);
}
if (opResult.inputConsumed < chunk.length) {
diff --git a/keystore/java/android/security/KeyStoreHmacSpi.java b/keystore/java/android/security/KeyStoreHmacSpi.java
index 841b90d..1297cc2 100644
--- a/keystore/java/android/security/KeyStoreHmacSpi.java
+++ b/keystore/java/android/security/KeyStoreHmacSpi.java
@@ -103,8 +103,7 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
if (opResult == null) {
throw new KeyStoreConnectException();
} else if (opResult.resultCode != KeyStore.NO_ERROR) {
- throw new CryptoOperationException("Failed to start keystore operation",
- KeymasterUtils.getExceptionForKeymasterError(opResult.resultCode));
+ throw KeymasterUtils.getCryptoOperationException(opResult.resultCode);
}
mOperationToken = opResult.token;
if (mOperationToken == null) {
@@ -131,7 +130,7 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
try {
output = mChunkedStreamer.update(input, offset, len);
} catch (KeymasterException e) {
- throw new CryptoOperationException("Keystore operation failed", e);
+ throw KeymasterUtils.getCryptoOperationException(e);
}
if ((output != null) && (output.length != 0)) {
throw new CryptoOperationException("Update operation unexpectedly produced output");
@@ -148,7 +147,7 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
try {
result = mChunkedStreamer.doFinal(null, 0, 0);
} catch (KeymasterException e) {
- throw new CryptoOperationException("Keystore operation failed", e);
+ throw KeymasterUtils.getCryptoOperationException(e);
}
engineReset();
diff --git a/keystore/java/android/security/KeyStoreKeyConstraints.java b/keystore/java/android/security/KeyStoreKeyConstraints.java
index c011083..c27ccb1 100644
--- a/keystore/java/android/security/KeyStoreKeyConstraints.java
+++ b/keystore/java/android/security/KeyStoreKeyConstraints.java
@@ -23,7 +23,10 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Locale;
+import java.util.Set;
/**
* Constraints for {@code AndroidKeyStore} keys.
@@ -520,4 +523,87 @@ public abstract class KeyStoreKeyConstraints {
}
}
}
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({UserAuthenticator.LOCK_SCREEN})
+ public @interface UserAuthenticatorEnum {}
+
+ /**
+ * User authenticators which can be used to restrict/protect access to keys.
+ */
+ public static abstract class UserAuthenticator {
+ private UserAuthenticator() {}
+
+ /** Lock screen. */
+ public static final int LOCK_SCREEN = 1;
+
+ /**
+ * @hide
+ */
+ public static int toKeymaster(@UserAuthenticatorEnum int userAuthenticator) {
+ switch (userAuthenticator) {
+ case LOCK_SCREEN:
+ return LOCK_SCREEN;
+ default:
+ throw new IllegalArgumentException(
+ "Unknown user authenticator: " + userAuthenticator);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public static @UserAuthenticatorEnum int fromKeymaster(int userAuthenticator) {
+ switch (userAuthenticator) {
+ case LOCK_SCREEN:
+ return LOCK_SCREEN;
+ default:
+ throw new IllegalArgumentException(
+ "Unknown user authenticator: " + userAuthenticator);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public static int allToKeymaster(Set<Integer> userAuthenticators) {
+ int result = 0;
+ for (@UserAuthenticatorEnum int userAuthenticator : userAuthenticators) {
+ result |= toKeymaster(userAuthenticator);
+ }
+ return result;
+ }
+
+ /**
+ * @hide
+ */
+ public static Set<Integer> allFromKeymaster(int userAuthenticators) {
+ int userAuthenticator = 1;
+ Set<Integer> result = null;
+ while (userAuthenticators != 0) {
+ if ((userAuthenticators & 1) != 0) {
+ if (result == null) {
+ result = new HashSet<Integer>();
+ }
+ result.add(fromKeymaster(userAuthenticator));
+ }
+ userAuthenticators >>>= 1;
+ userAuthenticator <<= 1;
+ }
+ return (result != null) ? result : Collections.<Integer>emptySet();
+ }
+
+ /**
+ * @hide
+ */
+ public static String toString(@UserAuthenticatorEnum int userAuthenticator) {
+ switch (userAuthenticator) {
+ case LOCK_SCREEN:
+ return "LOCK_SCREEN";
+ default:
+ throw new IllegalArgumentException(
+ "Unknown user authenticator: " + userAuthenticator);
+ }
+ }
+ }
}
diff --git a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
index 7796de8..09fee1b 100644
--- a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
@@ -136,10 +136,9 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
if (spec.getUserAuthenticators().isEmpty()) {
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
} else {
- // TODO: Pass-in user authenticator IDs once the Keymaster API has stabilized
-// for (int userAuthenticatorId : spec.getUserAuthenticators()) {
-// args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_ID, userAuthenticatorId);
-// }
+ args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
+ KeyStoreKeyConstraints.UserAuthenticator.allToKeymaster(
+ spec.getUserAuthenticators()));
}
if (spec.getUserAuthenticationValidityDurationSeconds() != null) {
args.addInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
@@ -175,8 +174,7 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
int errorCode = mKeyStore.generateKey(
keyAliasInKeystore, args, additionalEntropy, flags, new KeyCharacteristics());
if (errorCode != KeyStore.NO_ERROR) {
- throw new CryptoOperationException("Failed to generate key",
- KeymasterUtils.getExceptionForKeymasterError(errorCode));
+ throw KeymasterUtils.getCryptoOperationException(errorCode);
}
String keyAlgorithmJCA =
KeyStoreKeyConstraints.Algorithm.toJCASecretKeyAlgorithm(mAlgorithm, mDigest);
diff --git a/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java b/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java
index 8921ba1..88255a8 100644
--- a/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java
+++ b/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java
@@ -22,7 +22,6 @@ import android.security.keymaster.KeymasterDefs;
import java.security.InvalidKeyException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
-import java.util.Collections;
import java.util.Set;
import javax.crypto.SecretKey;
@@ -113,13 +112,16 @@ public class KeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
throw new InvalidKeySpecException("Unsupported key characteristic", e);
}
- // TODO: Read user authentication IDs once the Keymaster API has stabilized
- Set<Integer> userAuthenticators = Collections.emptySet();
- Set<Integer> teeBackedUserAuthenticators = Collections.emptySet();
-// Set<Integer> userAuthenticators = new HashSet<Integer>(
-// getInts(keyCharacteristics, KeymasterDefs.KM_TAG_USER_AUTH_ID));
-// Set<Integer> teeBackedUserAuthenticators = new HashSet<Integer>(
-// keyCharacteristics.hwEnforced.getInts(KeymasterDefs.KM_TAG_USER_AUTH_ID));
+ int swEnforcedUserAuthenticatorIds =
+ keyCharacteristics.swEnforced.getInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
+ int hwEnforcedUserAuthenticatorIds =
+ keyCharacteristics.hwEnforced.getInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
+ int userAuthenticatorIds = swEnforcedUserAuthenticatorIds | hwEnforcedUserAuthenticatorIds;
+ Set<Integer> userAuthenticators =
+ KeyStoreKeyConstraints.UserAuthenticator.allFromKeymaster(userAuthenticatorIds);
+ Set<Integer> teeBackedUserAuthenticators =
+ KeyStoreKeyConstraints.UserAuthenticator.allFromKeymaster(
+ hwEnforcedUserAuthenticatorIds);
return new KeyStoreKeySpec(entryAlias,
origin,
diff --git a/keystore/java/android/security/KeymasterUtils.java b/keystore/java/android/security/KeymasterUtils.java
index 6bb9636..2645cf4 100644
--- a/keystore/java/android/security/KeymasterUtils.java
+++ b/keystore/java/android/security/KeymasterUtils.java
@@ -29,7 +29,7 @@ import java.util.List;
public abstract class KeymasterUtils {
private KeymasterUtils() {}
- public static KeymasterException getExceptionForKeymasterError(int keymasterErrorCode) {
+ public static KeymasterException getKeymasterException(int keymasterErrorCode) {
switch (keymasterErrorCode) {
case KeymasterDefs.KM_ERROR_INVALID_AUTHORIZATION_TIMEOUT:
// The name of this parameter significantly differs between Keymaster and framework
@@ -42,6 +42,19 @@ public abstract class KeymasterUtils {
}
}
+ public static CryptoOperationException getCryptoOperationException(KeymasterException e) {
+ switch (e.getErrorCode()) {
+ case KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED:
+ return new UserNotAuthenticatedException();
+ default:
+ return new CryptoOperationException("Crypto operation failed", e);
+ }
+ }
+
+ public static CryptoOperationException getCryptoOperationException(int keymasterErrorCode) {
+ return getCryptoOperationException(getKeymasterException(keymasterErrorCode));
+ }
+
public static Integer getInt(KeyCharacteristics keyCharacteristics, int tag) {
if (keyCharacteristics.hwEnforced.containsTag(tag)) {
return keyCharacteristics.hwEnforced.getInt(tag, -1);
diff --git a/keystore/java/android/security/UserNotAuthenticatedException.java b/keystore/java/android/security/UserNotAuthenticatedException.java
new file mode 100644
index 0000000..b45817c
--- /dev/null
+++ b/keystore/java/android/security/UserNotAuthenticatedException.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security;
+
+/**
+ * Indicates that a cryptographic operation could not be performed because the user has not been
+ * authenticated recently enough.
+ *
+ * @hide
+ */
+public class UserNotAuthenticatedException extends CryptoOperationException {
+ public UserNotAuthenticatedException() {
+ super("User not authenticated");
+ }
+
+ public UserNotAuthenticatedException(String message) {
+ super(message);
+ }
+}