summaryrefslogtreecommitdiffstats
path: root/keystore
diff options
context:
space:
mode:
authorAlex Klyubin <klyubin@google.com>2015-04-01 14:41:28 -0700
committerAlex Klyubin <klyubin@google.com>2015-04-01 18:35:36 -0700
commit2ea13d42689ab10456a575772d069c91ae9b6075 (patch)
tree06f9b1c815855c276132d8ace87850e86d13bada /keystore
parent6c3d3db3b4644aee68a6ac9e80dfe21ee62ac597 (diff)
downloadframeworks_base-2ea13d42689ab10456a575772d069c91ae9b6075.zip
frameworks_base-2ea13d42689ab10456a575772d069c91ae9b6075.tar.gz
frameworks_base-2ea13d42689ab10456a575772d069c91ae9b6075.tar.bz2
Add fingerprint-specific AndroidKeyStore API.
Bug: 18088752 Change-Id: I333d3ffc820d28ae678e28dafc2e8a24cb7eb073
Diffstat (limited to 'keystore')
-rw-r--r--keystore/java/android/security/AndroidKeyStore.java4
-rw-r--r--keystore/java/android/security/KeyGeneratorSpec.java38
-rw-r--r--keystore/java/android/security/KeyStoreKeyConstraints.java9
-rw-r--r--keystore/java/android/security/KeyStoreKeyGeneratorSpi.java4
-rw-r--r--keystore/java/android/security/KeyStoreKeySpec.java16
-rw-r--r--keystore/java/android/security/KeyStoreParameter.java38
-rw-r--r--keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java6
-rw-r--r--keystore/java/android/security/KeymasterUtils.java3
-rw-r--r--keystore/java/android/security/NewFingerprintEnrolledException.java41
9 files changed, 153 insertions, 6 deletions
diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/AndroidKeyStore.java
index dcc79be..0bd1dbd 100644
--- a/keystore/java/android/security/AndroidKeyStore.java
+++ b/keystore/java/android/security/AndroidKeyStore.java
@@ -540,6 +540,10 @@ public class AndroidKeyStore extends KeyStoreSpi {
KeyStoreKeyConstraints.UserAuthenticator.allToKeymaster(
params.getUserAuthenticators()));
}
+ if (params.isInvalidatedOnNewFingerprintEnrolled()) {
+ // TODO: Add the invalidate on fingerprint enrolled constraint once Keymaster supports
+ // that.
+ }
if (params.getUserAuthenticationValidityDurationSeconds() != null) {
args.addInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
params.getUserAuthenticationValidityDurationSeconds());
diff --git a/keystore/java/android/security/KeyGeneratorSpec.java b/keystore/java/android/security/KeyGeneratorSpec.java
index 9122d8e..02b0816 100644
--- a/keystore/java/android/security/KeyGeneratorSpec.java
+++ b/keystore/java/android/security/KeyGeneratorSpec.java
@@ -59,6 +59,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
private final Integer mMaxUsesPerBoot;
private final Set<Integer> mUserAuthenticators;
private final Integer mUserAuthenticationValidityDurationSeconds;
+ private final boolean mInvalidatedOnNewFingerprintEnrolled;
private KeyGeneratorSpec(
Context context,
@@ -74,7 +75,8 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
Integer minSecondsBetweenOperations,
Integer maxUsesPerBoot,
Set<Integer> userAuthenticators,
- Integer userAuthenticationValidityDurationSeconds) {
+ Integer userAuthenticationValidityDurationSeconds,
+ boolean invalidatedOnNewFingerprintEnrolled) {
if (context == null) {
throw new IllegalArgumentException("context == null");
} else if (TextUtils.isEmpty(keyStoreAlias)) {
@@ -101,6 +103,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
? new HashSet<Integer>(userAuthenticators)
: Collections.<Integer>emptySet();
mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
+ mInvalidatedOnNewFingerprintEnrolled = invalidatedOnNewFingerprintEnrolled;
}
/**
@@ -239,6 +242,19 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
}
/**
+ * Returns {@code true} if this key must be permanently invalidated once a new fingerprint is
+ * enrolled. This constraint only has effect if fingerprint reader is one of the user
+ * authenticators protecting access to this key.
+ *
+ * @see #getUserAuthenticators()
+ *
+ * @hide
+ */
+ public boolean isInvalidatedOnNewFingerprintEnrolled() {
+ return mInvalidatedOnNewFingerprintEnrolled;
+ }
+
+ /**
* Returns {@code true} if the key must be encrypted in the {@link java.security.KeyStore}.
*/
public boolean isEncryptionRequired() {
@@ -260,6 +276,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
private Integer mMaxUsesPerBoot;
private Set<Integer> mUserAuthenticators;
private Integer mUserAuthenticationValidityDurationSeconds;
+ private boolean mInvalidatedOnNewFingerprintEnrolled;
/**
* Creates a new instance of the {@code Builder} with the given {@code context}. The
@@ -473,6 +490,22 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
}
/**
+ * Sets whether this key must be invalidated (permanently) once a new fingerprint is
+ * enrolled. This only has effect if fingerprint reader is one of the user authenticators
+ * protecting access to the key.
+ *
+ * <p>By default, enrolling a new fingerprint does not invalidate the key.
+ *
+ * @see #setUserAuthenticators(Set)
+ *
+ * @hide
+ */
+ public Builder setInvalidatedOnNewFingerprintEnrolled(boolean invalidated) {
+ mInvalidatedOnNewFingerprintEnrolled = invalidated;
+ return this;
+ }
+
+ /**
* Builds a new instance instance of {@code KeyGeneratorSpec}.
*
* @throws IllegalArgumentException if a required field is missing or violates a constraint.
@@ -481,7 +514,8 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
return new KeyGeneratorSpec(mContext, mKeystoreAlias, mFlags, mKeySize,
mKeyValidityStart, mKeyValidityForOriginationEnd, mKeyValidityForConsumptionEnd,
mPurposes, mPadding, mBlockMode, mMinSecondsBetweenOperations, mMaxUsesPerBoot,
- mUserAuthenticators, mUserAuthenticationValidityDurationSeconds);
+ mUserAuthenticators, mUserAuthenticationValidityDurationSeconds,
+ mInvalidatedOnNewFingerprintEnrolled);
}
}
}
diff --git a/keystore/java/android/security/KeyStoreKeyConstraints.java b/keystore/java/android/security/KeyStoreKeyConstraints.java
index c27ccb1..75034d1 100644
--- a/keystore/java/android/security/KeyStoreKeyConstraints.java
+++ b/keystore/java/android/security/KeyStoreKeyConstraints.java
@@ -537,6 +537,9 @@ public abstract class KeyStoreKeyConstraints {
/** Lock screen. */
public static final int LOCK_SCREEN = 1;
+ /** Fingerprint reader/sensor. */
+ public static final int FINGERPRINT_READER = 1 << 1;
+
/**
* @hide
*/
@@ -544,6 +547,8 @@ public abstract class KeyStoreKeyConstraints {
switch (userAuthenticator) {
case LOCK_SCREEN:
return LOCK_SCREEN;
+ case FINGERPRINT_READER:
+ return FINGERPRINT_READER;
default:
throw new IllegalArgumentException(
"Unknown user authenticator: " + userAuthenticator);
@@ -557,6 +562,8 @@ public abstract class KeyStoreKeyConstraints {
switch (userAuthenticator) {
case LOCK_SCREEN:
return LOCK_SCREEN;
+ case FINGERPRINT_READER:
+ return FINGERPRINT_READER;
default:
throw new IllegalArgumentException(
"Unknown user authenticator: " + userAuthenticator);
@@ -600,6 +607,8 @@ public abstract class KeyStoreKeyConstraints {
switch (userAuthenticator) {
case LOCK_SCREEN:
return "LOCK_SCREEN";
+ case FINGERPRINT_READER:
+ return "FINGERPRINT_READER";
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 69533b4..8b0a3e9 100644
--- a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
@@ -141,6 +141,10 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
KeyStoreKeyConstraints.UserAuthenticator.allToKeymaster(
spec.getUserAuthenticators()));
}
+ if (spec.isInvalidatedOnNewFingerprintEnrolled()) {
+ // TODO: Add the invalidate on fingerprint enrolled constraint once Keymaster supports
+ // that.
+ }
if (spec.getUserAuthenticationValidityDurationSeconds() != null) {
args.addInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
spec.getUserAuthenticationValidityDurationSeconds());
diff --git a/keystore/java/android/security/KeyStoreKeySpec.java b/keystore/java/android/security/KeyStoreKeySpec.java
index ddeefbd..e5e5acc 100644
--- a/keystore/java/android/security/KeyStoreKeySpec.java
+++ b/keystore/java/android/security/KeyStoreKeySpec.java
@@ -45,6 +45,7 @@ public class KeyStoreKeySpec implements KeySpec {
private final Set<Integer> mUserAuthenticators;
private final Set<Integer> mTeeBackedUserAuthenticators;
private final Integer mUserAuthenticationValidityDurationSeconds;
+ private final boolean mInvalidatedOnNewFingerprintEnrolled;
/**
@@ -63,7 +64,8 @@ public class KeyStoreKeySpec implements KeySpec {
Integer maxUsesPerBoot,
Set<Integer> userAuthenticators,
Set<Integer> teeBackedUserAuthenticators,
- Integer userAuthenticationValidityDurationSeconds) {
+ Integer userAuthenticationValidityDurationSeconds,
+ boolean invalidatedOnNewFingerprintEnrolled) {
mKeystoreAlias = keystoreKeyAlias;
mOrigin = origin;
mKeySize = keySize;
@@ -84,6 +86,7 @@ public class KeyStoreKeySpec implements KeySpec {
? new HashSet<Integer>(teeBackedUserAuthenticators)
: Collections.<Integer>emptySet();
mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
+ mInvalidatedOnNewFingerprintEnrolled = invalidatedOnNewFingerprintEnrolled;
}
/**
@@ -223,4 +226,15 @@ public class KeyStoreKeySpec implements KeySpec {
public Integer getUserAuthenticationValidityDurationSeconds() {
return mUserAuthenticationValidityDurationSeconds;
}
+
+ /**
+ * Returns {@code true} if this key will be permanently invalidated once a new fingerprint is
+ * enrolled. This constraint only has effect if fingerprint reader is one of the user
+ * authenticators protecting access to this key.
+ *
+ * @see #getUserAuthenticators()
+ */
+ public boolean isInvalidatedOnNewFingerprintEnrolled() {
+ return mInvalidatedOnNewFingerprintEnrolled;
+ }
}
diff --git a/keystore/java/android/security/KeyStoreParameter.java b/keystore/java/android/security/KeyStoreParameter.java
index 2428c2a..b1b638f 100644
--- a/keystore/java/android/security/KeyStoreParameter.java
+++ b/keystore/java/android/security/KeyStoreParameter.java
@@ -59,6 +59,7 @@ public final class KeyStoreParameter implements ProtectionParameter {
private final Integer mMaxUsesPerBoot;
private final Set<Integer> mUserAuthenticators;
private final Integer mUserAuthenticationValidityDurationSeconds;
+ private final boolean mInvalidatedOnNewFingerprintEnrolled;
private KeyStoreParameter(int flags, Date keyValidityStart,
Date keyValidityForOriginationEnd, Date keyValidityForConsumptionEnd,
@@ -70,7 +71,8 @@ public final class KeyStoreParameter implements ProtectionParameter {
Integer minSecondsBetweenOperations,
Integer maxUsesPerBoot,
Set<Integer> userAuthenticators,
- Integer userAuthenticationValidityDurationSeconds) {
+ Integer userAuthenticationValidityDurationSeconds,
+ boolean invalidatedOnNewFingerprintEnrolled) {
if ((userAuthenticationValidityDurationSeconds != null)
&& (userAuthenticationValidityDurationSeconds < 0)) {
throw new IllegalArgumentException(
@@ -92,6 +94,7 @@ public final class KeyStoreParameter implements ProtectionParameter {
? new HashSet<Integer>(userAuthenticators)
: Collections.<Integer>emptySet();
mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
+ mInvalidatedOnNewFingerprintEnrolled = invalidatedOnNewFingerprintEnrolled;
}
/**
@@ -245,6 +248,19 @@ public final class KeyStoreParameter implements ProtectionParameter {
}
/**
+ * Returns {@code true} if this key must be permanently invalidated once a new fingerprint is
+ * enrolled. This constraint only has effect if fingerprint reader is one of the user
+ * authenticators protecting access to this key.
+ *
+ * @see #getUserAuthenticators()
+ *
+ * @hide
+ */
+ public boolean isInvalidatedOnNewFingerprintEnrolled() {
+ return mInvalidatedOnNewFingerprintEnrolled;
+ }
+
+ /**
* Builder class for {@link KeyStoreParameter} objects.
* <p>
* This will build protection parameters for use with the
@@ -275,6 +291,7 @@ public final class KeyStoreParameter implements ProtectionParameter {
private Integer mMaxUsesPerBoot;
private Set<Integer> mUserAuthenticators;
private Integer mUserAuthenticationValidityDurationSeconds;
+ private boolean mInvalidatedOnNewFingerprintEnrolled;
/**
* Creates a new instance of the {@code Builder} with the given
@@ -496,6 +513,22 @@ public final class KeyStoreParameter implements ProtectionParameter {
}
/**
+ * Sets whether this key must be invalidated (permanently) whenever a new fingerprint is
+ * enrolled. This only has effect if fingerprint reader is one of the user authenticators
+ * protecting access to the key.
+ *
+ * <p>By default, enrolling a new fingerprint does not invalidate the key.
+ *
+ * @see #setUserAuthenticators(Set)
+ *
+ * @hide
+ */
+ public Builder setInvalidatedOnNewFingerprintEnrolled(boolean invalidated) {
+ mInvalidatedOnNewFingerprintEnrolled = invalidated;
+ return this;
+ }
+
+ /**
* Builds the instance of the {@code KeyStoreParameter}.
*
* @throws IllegalArgumentException if a required field is missing
@@ -506,7 +539,8 @@ public final class KeyStoreParameter implements ProtectionParameter {
mKeyValidityForOriginationEnd, mKeyValidityForConsumptionEnd, mPurposes,
mAlgorithm, mPadding, mDigest, mBlockMode, mMinSecondsBetweenOperations,
mMaxUsesPerBoot, mUserAuthenticators,
- mUserAuthenticationValidityDurationSeconds);
+ mUserAuthenticationValidityDurationSeconds,
+ mInvalidatedOnNewFingerprintEnrolled);
}
}
}
diff --git a/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java b/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java
index f552759..c205d9d 100644
--- a/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java
+++ b/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java
@@ -142,6 +142,9 @@ public class KeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
KeyStoreKeyConstraints.UserAuthenticator.allFromKeymaster(
hwEnforcedUserAuthenticatorIds);
+ // TODO: Populate the value below from key characteristics once Keymaster is ready.
+ boolean invalidatedOnNewFingerprintEnrolled = false;
+
return new KeyStoreKeySpec(entryAlias,
origin,
keySize,
@@ -158,7 +161,8 @@ public class KeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
KeymasterUtils.getInt(keyCharacteristics, KeymasterDefs.KM_TAG_MAX_USES_PER_BOOT),
userAuthenticators,
teeBackedUserAuthenticators,
- KeymasterUtils.getInt(keyCharacteristics, KeymasterDefs.KM_TAG_AUTH_TIMEOUT));
+ KeymasterUtils.getInt(keyCharacteristics, KeymasterDefs.KM_TAG_AUTH_TIMEOUT),
+ invalidatedOnNewFingerprintEnrolled);
}
@Override
diff --git a/keystore/java/android/security/KeymasterUtils.java b/keystore/java/android/security/KeymasterUtils.java
index 2645cf4..c3092d5 100644
--- a/keystore/java/android/security/KeymasterUtils.java
+++ b/keystore/java/android/security/KeymasterUtils.java
@@ -46,6 +46,9 @@ public abstract class KeymasterUtils {
switch (e.getErrorCode()) {
case KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED:
return new UserNotAuthenticatedException();
+ // TODO: Handle TBD Keymaster error code "invalid key: new fingerprint enrolled"
+ // case KeymasterDefs.KM_ERROR_TBD
+ // return new NewFingerprintEnrolledException();
default:
return new CryptoOperationException("Crypto operation failed", e);
}
diff --git a/keystore/java/android/security/NewFingerprintEnrolledException.java b/keystore/java/android/security/NewFingerprintEnrolledException.java
new file mode 100644
index 0000000..6da4a2a
--- /dev/null
+++ b/keystore/java/android/security/NewFingerprintEnrolledException.java
@@ -0,0 +1,41 @@
+/*
+ * 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 key used by the
+ * operation is permanently invalid because a new fingerprint was enrolled.
+ *
+ * @hide
+ */
+public class NewFingerprintEnrolledException extends CryptoOperationException {
+
+ /**
+ * Constructs a new {@code NewFingerprintEnrolledException} without detail message and cause.
+ */
+ public NewFingerprintEnrolledException() {
+ super("Invalid key: new fingerprint enrolled");
+ }
+
+ /**
+ * Constructs a new {@code NewFingerprintEnrolledException} with the provided detail message and
+ * no cause.
+ */
+ public NewFingerprintEnrolledException(String message) {
+ super(message);
+ }
+}