summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2018-11-16 22:52:30 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2018-11-16 22:52:30 +0000
commit278913ae620c06f1bbdf70e8d52c0a6eae33ce29 (patch)
tree078be8d2624cd984f0a82ec7161c5eb7220ee1af
parent992cd354fcebfd78ff7dc0eb2acf362d14497eef (diff)
parent057b743fe90ff6b9d19db297e12d9f6055439276 (diff)
Merge "Update KeyStore for new biometric modalities"
-rw-r--r--core/java/android/security/keymaster/KeymasterDefs.java2
-rw-r--r--keystore/java/android/security/KeyStore.java26
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java4
-rw-r--r--keystore/java/android/security/keystore/KeymasterUtils.java41
4 files changed, 54 insertions, 19 deletions
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index f4dcce1e7e58..15ded8d1b7b1 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -154,7 +154,7 @@ public final class KeymasterDefs {
// User authenticators.
public static final int HW_AUTH_PASSWORD = 1 << 0;
- public static final int HW_AUTH_FINGERPRINT = 1 << 1;
+ public static final int HW_AUTH_BIOMETRIC = 1 << 1;
// Error codes.
public static final int KM_ERROR_OK = 0;
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 835b735ad55f..fec800dcb306 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -23,6 +23,7 @@ import android.app.Application;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Binder;
import android.os.IBinder;
@@ -1254,7 +1255,7 @@ public class KeyStore {
return new UserNotAuthenticatedException();
}
- long fingerprintOnlySid = getFingerprintOnlySid();
+ final long fingerprintOnlySid = getFingerprintOnlySid();
if ((fingerprintOnlySid != 0)
&& (keySids.contains(KeymasterArguments.toUint64(fingerprintOnlySid)))) {
// One of the key's SIDs is the current fingerprint SID -- user can be
@@ -1262,6 +1263,14 @@ public class KeyStore {
return new UserNotAuthenticatedException();
}
+ final long faceOnlySid = getFaceOnlySid();
+ if ((faceOnlySid != 0)
+ && (keySids.contains(KeymasterArguments.toUint64(faceOnlySid)))) {
+ // One of the key's SIDs is the current face SID -- user can be
+ // authenticated against that SID.
+ return new UserNotAuthenticatedException();
+ }
+
// None of the key's SIDs can ever be authenticated
return new KeyPermanentlyInvalidatedException();
}
@@ -1272,6 +1281,21 @@ public class KeyStore {
}
}
+ private long getFaceOnlySid() {
+ final PackageManager packageManager = mContext.getPackageManager();
+ if (!packageManager.hasSystemFeature(PackageManager.FEATURE_FACE)) {
+ return 0;
+ }
+ FaceManager faceManager = mContext.getSystemService(FaceManager.class);
+ if (faceManager == null) {
+ return 0;
+ }
+
+ // TODO: Restore USE_BIOMETRIC or USE_BIOMETRIC_INTERNAL permission check in
+ // FaceManager.getAuthenticatorId once the ID is no longer needed here.
+ return faceManager.getAuthenticatorId();
+ }
+
private long getFingerprintOnlySid() {
final PackageManager packageManager = mContext.getPackageManager();
if (!packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
index 7bbc09964584..a2d23558616b 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
@@ -182,8 +182,8 @@ public class AndroidKeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED);
boolean invalidatedByBiometricEnrollment = false;
- if (keymasterSwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_FINGERPRINT
- || keymasterHwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_FINGERPRINT) {
+ if (keymasterSwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_BIOMETRIC
+ || keymasterHwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_BIOMETRIC) {
// Fingerprint-only key; will be invalidated if the root SID isn't in the SID list.
invalidatedByBiometricEnrollment = keymasterSecureUserIds != null
&& !keymasterSecureUserIds.isEmpty()
diff --git a/keystore/java/android/security/keystore/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java
index f829bb7cfeed..52896b59ddaf 100644
--- a/keystore/java/android/security/keystore/KeymasterUtils.java
+++ b/keystore/java/android/security/keystore/KeymasterUtils.java
@@ -16,7 +16,7 @@
package android.security.keystore;
-import android.app.ActivityManager;
+import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.security.GateKeeper;
import android.security.KeyStore;
@@ -24,6 +24,8 @@ import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;
import java.security.ProviderException;
+import java.util.ArrayList;
+import java.util.List;
/**
* @hide
@@ -121,35 +123,44 @@ public abstract class KeymasterUtils {
if (spec.getUserAuthenticationValidityDurationSeconds() == -1) {
// Every use of this key needs to be authorized by the user. This currently means
- // fingerprint-only auth.
+ // fingerprint or face auth.
FingerprintManager fingerprintManager =
KeyStore.getApplicationContext().getSystemService(FingerprintManager.class);
+ FaceManager faceManager =
+ KeyStore.getApplicationContext().getSystemService(FaceManager.class);
// TODO: Restore USE_FINGERPRINT permission check in
// FingerprintManager.getAuthenticatorId once the ID is no longer needed here.
- long fingerprintOnlySid =
+ final long fingerprintOnlySid =
(fingerprintManager != null) ? fingerprintManager.getAuthenticatorId() : 0;
- if (fingerprintOnlySid == 0) {
+ final long faceOnlySid =
+ (faceManager != null) ? faceManager.getAuthenticatorId() : 0;
+
+ if (fingerprintOnlySid == 0 && faceOnlySid == 0) {
throw new IllegalStateException(
- "At least one fingerprint must be enrolled to create keys requiring user"
+ "At least one biometric must be enrolled to create keys requiring user"
+ " authentication for every use");
}
- long sid;
+ List<Long> sids = new ArrayList<>();
if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) {
- sid = spec.getBoundToSpecificSecureUserId();
+ sids.add(spec.getBoundToSpecificSecureUserId());
} else if (spec.isInvalidatedByBiometricEnrollment()) {
- // The fingerprint-only SID will change on fingerprint enrollment or removal of all,
- // enrolled fingerprints, invalidating the key.
- sid = fingerprintOnlySid;
+ // The biometric-only SIDs will change on biometric enrollment or removal of all
+ // enrolled templates, invalidating the key.
+ sids.add(fingerprintOnlySid);
+ sids.add(faceOnlySid);
} else {
// The root SID will *not* change on fingerprint enrollment, or removal of all
// enrolled fingerprints, allowing the key to remain valid.
- sid = getRootSid();
+ sids.add(getRootSid());
+ }
+
+ for (int i = 0; i < sids.size(); i++) {
+ args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
+ KeymasterArguments.toUint64(sids.get(i)));
}
+ args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_BIOMETRIC);
- args.addUnsignedLong(
- KeymasterDefs.KM_TAG_USER_SECURE_ID, KeymasterArguments.toUint64(sid));
- args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_FINGERPRINT);
if (spec.isUserAuthenticationValidWhileOnBody()) {
throw new ProviderException("Key validity extension while device is on-body is not "
+ "supported for keys requiring fingerprint authentication");
@@ -166,7 +177,7 @@ public abstract class KeymasterUtils {
args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
KeymasterArguments.toUint64(sid));
args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
- KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_FINGERPRINT);
+ KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_BIOMETRIC);
args.addUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
spec.getUserAuthenticationValidityDurationSeconds());
if (spec.isUserAuthenticationValidWhileOnBody()) {