Add "Unlocked device required" parameter to keys

Add a keymaster parameter for keys that should be inaccessible when
the device screen is locked. "Locked" here is a state where the device
can be used or accessed without any further trust factor such as a
PIN, password, fingerprint, or trusted face or voice.

This parameter is added to the Java keystore interface for key
creation and import, as well as enums specified by and for the native
keystore process.

Test: go/asym-write-test-plan

Bug: 67752510

Change-Id: I8b88ff8fceeafe14e7613776c9cf5427752d9172
This commit is contained in:
Brian C. Young
2017-11-16 15:36:43 -08:00
parent e2975162dc
commit 55fff3a89d
13 changed files with 180 additions and 64 deletions

View File

@@ -38150,6 +38150,7 @@ package android.security.keystore {
method public boolean isRandomizedEncryptionRequired();
method public boolean isStrongBoxBacked();
method public boolean isTrustedUserPresenceRequired();
method public boolean isUnlockedDeviceRequired();
method public boolean isUserAuthenticationRequired();
method public boolean isUserAuthenticationValidWhileOnBody();
}
@@ -38176,6 +38177,7 @@ package android.security.keystore {
method public android.security.keystore.KeyGenParameterSpec.Builder setRandomizedEncryptionRequired(boolean);
method public android.security.keystore.KeyGenParameterSpec.Builder setSignaturePaddings(java.lang.String...);
method public android.security.keystore.KeyGenParameterSpec.Builder setTrustedUserPresenceRequired(boolean);
method public android.security.keystore.KeyGenParameterSpec.Builder setUnlockedDeviceRequired(boolean);
method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationRequired(boolean);
method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidWhileOnBody(boolean);
method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
@@ -38265,6 +38267,8 @@ package android.security.keystore {
method public boolean isDigestsSpecified();
method public boolean isInvalidatedByBiometricEnrollment();
method public boolean isRandomizedEncryptionRequired();
method public boolean isTrustedUserPresenceRequired();
method public boolean isUnlockedDeviceRequired();
method public boolean isUserAuthenticationRequired();
method public boolean isUserAuthenticationValidWhileOnBody();
}
@@ -38282,6 +38286,8 @@ package android.security.keystore {
method public android.security.keystore.KeyProtection.Builder setKeyValidityStart(java.util.Date);
method public android.security.keystore.KeyProtection.Builder setRandomizedEncryptionRequired(boolean);
method public android.security.keystore.KeyProtection.Builder setSignaturePaddings(java.lang.String...);
method public android.security.keystore.KeyProtection.Builder setTrustedUserPresenceRequired(boolean);
method public android.security.keystore.KeyProtection.Builder setUnlockedDeviceRequired(boolean);
method public android.security.keystore.KeyProtection.Builder setUserAuthenticationRequired(boolean);
method public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidWhileOnBody(boolean);
method public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidityDurationSeconds(int);

View File

@@ -71,7 +71,7 @@ interface IKeystoreService {
in byte[] entropy);
int abort(IBinder handle);
boolean isOperationAuthorized(IBinder token);
int addAuthToken(in byte[] authToken);
int addAuthToken(in byte[] authToken, in int androidId);
int onUserAdded(int userId, int parentId);
int onUserRemoved(int userId);
int attestKey(String alias, in KeymasterArguments params, out KeymasterCertificateChain chain);

View File

@@ -74,6 +74,7 @@ public final class KeymasterDefs {
public static final int KM_TAG_AUTH_TIMEOUT = KM_UINT | 505;
public static final int KM_TAG_ALLOW_WHILE_ON_BODY = KM_BOOL | 506;
public static final int KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED = KM_BOOL | 507;
public static final int KM_TAG_UNLOCKED_DEVICE_REQUIRED = KM_BOOL | 509;
public static final int KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600;
public static final int KM_TAG_APPLICATION_ID = KM_BYTES | 601;
@@ -215,6 +216,7 @@ public final class KeymasterDefs {
public static final int KM_ERROR_MISSING_MIN_MAC_LENGTH = -58;
public static final int KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH = -59;
public static final int KM_ERROR_CANNOT_ATTEST_IDS = -66;
public static final int KM_ERROR_DEVICE_LOCKED = -72;
public static final int KM_ERROR_UNIMPLEMENTED = -100;
public static final int KM_ERROR_VERSION_MISMATCH = -101;
public static final int KM_ERROR_UNKNOWN_ERROR = -1000;
@@ -261,6 +263,7 @@ public final class KeymasterDefs {
sErrorCodeToString.put(KM_ERROR_INVALID_MAC_LENGTH,
"Invalid MAC or authentication tag length");
sErrorCodeToString.put(KM_ERROR_CANNOT_ATTEST_IDS, "Unable to attest device ids");
sErrorCodeToString.put(KM_ERROR_DEVICE_LOCKED, "Device locked");
sErrorCodeToString.put(KM_ERROR_UNIMPLEMENTED, "Not implemented");
sErrorCodeToString.put(KM_ERROR_UNKNOWN_ERROR, "Unknown error");
}

View File

@@ -618,9 +618,9 @@ public class KeyStore {
* @return {@code KeyStore.NO_ERROR} on success, otherwise an error value corresponding to
* a {@code KeymasterDefs.KM_ERROR_} value or {@code KeyStore} ResponseCode.
*/
public int addAuthToken(byte[] authToken) {
public int addAuthToken(byte[] authToken, int userId) {
try {
return mBinder.addAuthToken(authToken);
return mBinder.addAuthToken(authToken, userId);
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return SYSTEM_ERROR;

View File

@@ -243,12 +243,7 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
// Check that user authentication related parameters are acceptable. This method
// will throw an IllegalStateException if there are issues (e.g., secure lock screen
// not set up).
KeymasterUtils.addUserAuthArgs(new KeymasterArguments(),
spec.isUserAuthenticationRequired(),
spec.getUserAuthenticationValidityDurationSeconds(),
spec.isUserAuthenticationValidWhileOnBody(),
spec.isInvalidatedByBiometricEnrollment(),
GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */);
KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), spec);
} catch (IllegalStateException | IllegalArgumentException e) {
throw new InvalidAlgorithmParameterException(e);
}
@@ -284,15 +279,7 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes);
args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterPaddings);
args.addEnums(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
KeymasterUtils.addUserAuthArgs(args,
spec.isUserAuthenticationRequired(),
spec.getUserAuthenticationValidityDurationSeconds(),
spec.isUserAuthenticationValidWhileOnBody(),
spec.isInvalidatedByBiometricEnrollment(),
GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */);
if (spec.isTrustedUserPresenceRequired()) {
args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED);
}
KeymasterUtils.addUserAuthArgs(args, spec);
KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
args,
mKeymasterAlgorithm,

View File

@@ -344,12 +344,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
// Check that user authentication related parameters are acceptable. This method
// will throw an IllegalStateException if there are issues (e.g., secure lock screen
// not set up).
KeymasterUtils.addUserAuthArgs(new KeymasterArguments(),
mSpec.isUserAuthenticationRequired(),
mSpec.getUserAuthenticationValidityDurationSeconds(),
mSpec.isUserAuthenticationValidWhileOnBody(),
mSpec.isInvalidatedByBiometricEnrollment(),
GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */);
KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), mSpec);
} catch (IllegalArgumentException | IllegalStateException e) {
throw new InvalidAlgorithmParameterException(e);
}
@@ -540,12 +535,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterSignaturePaddings);
args.addEnums(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
KeymasterUtils.addUserAuthArgs(args,
mSpec.isUserAuthenticationRequired(),
mSpec.getUserAuthenticationValidityDurationSeconds(),
mSpec.isUserAuthenticationValidWhileOnBody(),
mSpec.isInvalidatedByBiometricEnrollment(),
GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */);
KeymasterUtils.addUserAuthArgs(args, mSpec);
args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, mSpec.getKeyValidityStart());
args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
mSpec.getKeyValidityForOriginationEnd());

View File

@@ -497,12 +497,7 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
importArgs.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterEncryptionPaddings);
importArgs.addEnums(KeymasterDefs.KM_TAG_PADDING,
KeyProperties.SignaturePadding.allToKeymaster(spec.getSignaturePaddings()));
KeymasterUtils.addUserAuthArgs(importArgs,
spec.isUserAuthenticationRequired(),
spec.getUserAuthenticationValidityDurationSeconds(),
spec.isUserAuthenticationValidWhileOnBody(),
spec.isInvalidatedByBiometricEnrollment(),
spec.getBoundToSpecificSecureUserId());
KeymasterUtils.addUserAuthArgs(importArgs, spec);
importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
spec.getKeyValidityStart());
importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
@@ -699,12 +694,7 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
int[] keymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster(
params.getEncryptionPaddings());
args.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings);
KeymasterUtils.addUserAuthArgs(args,
params.isUserAuthenticationRequired(),
params.getUserAuthenticationValidityDurationSeconds(),
params.isUserAuthenticationValidWhileOnBody(),
params.isInvalidatedByBiometricEnrollment(),
params.getBoundToSpecificSecureUserId());
KeymasterUtils.addUserAuthArgs(args, params);
KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
args,
keymasterAlgorithm,

View File

@@ -21,6 +21,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.KeyguardManager;
import android.hardware.fingerprint.FingerprintManager;
import android.security.GateKeeper;
import android.security.KeyStore;
import android.text.TextUtils;
@@ -232,7 +233,7 @@ import javax.security.auth.x500.X500Principal;
* key = (SecretKey) keyStore.getKey("key2", null);
* }</pre>
*/
public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAuthArgs {
private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
@@ -264,6 +265,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
private final boolean mUserAuthenticationValidWhileOnBody;
private final boolean mInvalidatedByBiometricEnrollment;
private final boolean mIsStrongBoxBacked;
private final boolean mUnlockedDeviceRequired;
/**
* @hide should be built with Builder
@@ -293,7 +295,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
boolean uniqueIdIncluded,
boolean userAuthenticationValidWhileOnBody,
boolean invalidatedByBiometricEnrollment,
boolean isStrongBoxBacked) {
boolean isStrongBoxBacked,
boolean unlockedDeviceRequired) {
if (TextUtils.isEmpty(keyStoreAlias)) {
throw new IllegalArgumentException("keyStoreAlias must not be empty");
}
@@ -341,6 +344,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody;
mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
mIsStrongBoxBacked = isStrongBoxBacked;
mUnlockedDeviceRequired = unlockedDeviceRequired;
}
/**
@@ -645,6 +649,22 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
return mIsStrongBoxBacked;
}
/**
* Returns {@code true} if the key cannot be used unless the device screen is unlocked.
*
* @see Builder#SetUnlockedDeviceRequired(boolean)
*/
public boolean isUnlockedDeviceRequired() {
return mUnlockedDeviceRequired;
}
/**
* @hide
*/
public long getBoundToSpecificSecureUserId() {
return GateKeeper.INVALID_SECURE_USER_ID;
}
/**
* Builder of {@link KeyGenParameterSpec} instances.
*/
@@ -675,6 +695,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
private boolean mUserAuthenticationValidWhileOnBody;
private boolean mInvalidatedByBiometricEnrollment = true;
private boolean mIsStrongBoxBacked = false;
private boolean mUnlockedDeviceRequired = false;
/**
* Creates a new instance of the {@code Builder}.
@@ -1219,6 +1240,18 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
return this;
}
/**
* Sets whether the keystore requires the screen to be unlocked before allowing decryption
* using this key. If this is set to {@code true}, any attempt to decrypt using this key
* while the screen is locked will fail. A locked device requires a PIN, password,
* fingerprint, or other trusted factor to access.
*/
@NonNull
public Builder setUnlockedDeviceRequired(boolean unlockedDeviceRequired) {
mUnlockedDeviceRequired = unlockedDeviceRequired;
return this;
}
/**
* Builds an instance of {@code KeyGenParameterSpec}.
*/
@@ -1249,7 +1282,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
mUniqueIdIncluded,
mUserAuthenticationValidWhileOnBody,
mInvalidatedByBiometricEnrollment,
mIsStrongBoxBacked);
mIsStrongBoxBacked,
mUnlockedDeviceRequired);
}
}
}

View File

@@ -212,7 +212,7 @@ import javax.crypto.Mac;
* ...
* }</pre>
*/
public final class KeyProtection implements ProtectionParameter {
public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
private final Date mKeyValidityStart;
private final Date mKeyValidityForOriginationEnd;
private final Date mKeyValidityForConsumptionEnd;
@@ -228,6 +228,8 @@ public final class KeyProtection implements ProtectionParameter {
private final boolean mInvalidatedByBiometricEnrollment;
private final long mBoundToSecureUserId;
private final boolean mCriticalToDeviceEncryption;
private final boolean mTrustedUserPresenceRequired;
private final boolean mUnlockedDeviceRequired;
private KeyProtection(
Date keyValidityStart,
@@ -241,10 +243,12 @@ public final class KeyProtection implements ProtectionParameter {
boolean randomizedEncryptionRequired,
boolean userAuthenticationRequired,
int userAuthenticationValidityDurationSeconds,
boolean trustedUserPresenceRequired,
boolean userAuthenticationValidWhileOnBody,
boolean invalidatedByBiometricEnrollment,
long boundToSecureUserId,
boolean criticalToDeviceEncryption) {
boolean criticalToDeviceEncryption,
boolean unlockedDeviceRequired) {
mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
@@ -262,6 +266,8 @@ public final class KeyProtection implements ProtectionParameter {
mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
mBoundToSecureUserId = boundToSecureUserId;
mCriticalToDeviceEncryption = criticalToDeviceEncryption;
mTrustedUserPresenceRequired = trustedUserPresenceRequired;
mUnlockedDeviceRequired = unlockedDeviceRequired;
}
/**
@@ -413,6 +419,14 @@ public final class KeyProtection implements ProtectionParameter {
return mUserAuthenticationValidityDurationSeconds;
}
/**
* Returns {@code true} if the key is authorized to be used only if a test of user presence has
* been performed between the {@code Signature.initSign()} and {@code Signature.sign()} calls.
*/
public boolean isTrustedUserPresenceRequired() {
return mTrustedUserPresenceRequired;
}
/**
* Returns {@code true} if the key will be de-authorized when the device is removed from the
* user's body. This option has no effect on keys that don't have an authentication validity
@@ -470,6 +484,15 @@ public final class KeyProtection implements ProtectionParameter {
return mCriticalToDeviceEncryption;
}
/**
* Returns {@code true} if the key cannot be used unless the device screen is unlocked.
*
* @see Builder#SetRequireDeviceUnlocked(boolean)
*/
public boolean isUnlockedDeviceRequired() {
return mUnlockedDeviceRequired;
}
/**
* Builder of {@link KeyProtection} instances.
*/
@@ -488,6 +511,9 @@ public final class KeyProtection implements ProtectionParameter {
private int mUserAuthenticationValidityDurationSeconds = -1;
private boolean mUserAuthenticationValidWhileOnBody;
private boolean mInvalidatedByBiometricEnrollment = true;
private boolean mTrustedUserPresenceRequired = false;
private boolean mUnlockedDeviceRequired = false;
private long mBoundToSecureUserId = GateKeeper.INVALID_SECURE_USER_ID;
private boolean mCriticalToDeviceEncryption = false;
@@ -763,6 +789,16 @@ public final class KeyProtection implements ProtectionParameter {
return this;
}
/**
* Sets whether a test of user presence is required to be performed between the
* {@code Signature.initSign()} and {@code Signature.sign()} method calls.
*/
@NonNull
public Builder setTrustedUserPresenceRequired(boolean required) {
mTrustedUserPresenceRequired = required;
return this;
}
/**
* Sets whether the key will remain authorized only until the device is removed from the
* user's body up to the limit of the authentication validity period (see
@@ -844,6 +880,18 @@ public final class KeyProtection implements ProtectionParameter {
return this;
}
/**
* Sets whether the keystore requires the screen to be unlocked before allowing decryption
* using this key. If this is set to {@code true}, any attempt to decrypt using this key
* while the screen is locked will fail. A locked device requires a PIN, password,
* fingerprint, or other trusted factor to access.
*/
@NonNull
public Builder setUnlockedDeviceRequired(boolean unlockedDeviceRequired) {
mUnlockedDeviceRequired = unlockedDeviceRequired;
return this;
}
/**
* Builds an instance of {@link KeyProtection}.
*
@@ -863,10 +911,12 @@ public final class KeyProtection implements ProtectionParameter {
mRandomizedEncryptionRequired,
mUserAuthenticationRequired,
mUserAuthenticationValidityDurationSeconds,
mTrustedUserPresenceRequired,
mUserAuthenticationValidWhileOnBody,
mInvalidatedByBiometricEnrollment,
mBoundToSecureUserId,
mCriticalToDeviceEncryption);
mCriticalToDeviceEncryption,
mUnlockedDeviceRequired);
}
}
}

View File

@@ -98,17 +98,23 @@ public abstract class KeymasterUtils {
* require user authentication.
*/
public static void addUserAuthArgs(KeymasterArguments args,
boolean userAuthenticationRequired,
int userAuthenticationValidityDurationSeconds,
boolean userAuthenticationValidWhileOnBody,
boolean invalidatedByBiometricEnrollment,
long boundToSpecificSecureUserId) {
if (!userAuthenticationRequired) {
UserAuthArgs spec) {
args.addUnsignedInt(KeymasterDefs.KM_TAG_USER_ID, 0);
if (spec.isTrustedUserPresenceRequired()) {
args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED);
}
if (spec.isUnlockedDeviceRequired()) {
args.addBoolean(KeymasterDefs.KM_TAG_UNLOCKED_DEVICE_REQUIRED);
}
if (!spec.isUserAuthenticationRequired()) {
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
return;
}
if (userAuthenticationValidityDurationSeconds == -1) {
if (spec.getUserAuthenticationValidityDurationSeconds() == -1) {
// Every use of this key needs to be authorized by the user. This currently means
// fingerprint-only auth.
FingerprintManager fingerprintManager =
@@ -124,9 +130,9 @@ public abstract class KeymasterUtils {
}
long sid;
if (boundToSpecificSecureUserId != GateKeeper.INVALID_SECURE_USER_ID) {
sid = boundToSpecificSecureUserId;
} else if (invalidatedByBiometricEnrollment) {
if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) {
sid = 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;
@@ -139,14 +145,14 @@ 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_FINGERPRINT);
if (userAuthenticationValidWhileOnBody) {
if (spec.isUserAuthenticationValidWhileOnBody()) {
throw new ProviderException("Key validity extension while device is on-body is not "
+ "supported for keys requiring fingerprint authentication");
}
} else {
long sid;
if (boundToSpecificSecureUserId != GateKeeper.INVALID_SECURE_USER_ID) {
sid = boundToSpecificSecureUserId;
if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) {
sid = spec.getBoundToSpecificSecureUserId();
} else {
// The key is authorized for use for the specified amount of time after the user has
// authenticated. Whatever unlocks the secure lock screen should authorize this key.
@@ -157,8 +163,8 @@ public abstract class KeymasterUtils {
args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_FINGERPRINT);
args.addUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
userAuthenticationValidityDurationSeconds);
if (userAuthenticationValidWhileOnBody) {
spec.getUserAuthenticationValidityDurationSeconds());
if (spec.isUserAuthenticationValidWhileOnBody()) {
args.addBoolean(KeymasterDefs.KM_TAG_ALLOW_WHILE_ON_BODY);
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2017 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.keystore;
/**
* @hide
*
* This is an interface to encapsulate the user authentication arguments that
* are passed to KeymasterUtils.addUserAuthArgs. Classes that represent
* authorization characteristics for new or imported keys can implement this
* interface to be passed to that method.
*/
public interface UserAuthArgs {
boolean isUserAuthenticationRequired();
int getUserAuthenticationValidityDurationSeconds();
boolean isUserAuthenticationValidWhileOnBody();
boolean isInvalidatedByBiometricEnrollment();
boolean isTrustedUserPresenceRequired();
boolean isUnlockedDeviceRequired();
long getBoundToSpecificSecureUserId();
}

View File

@@ -421,7 +421,7 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
byteToken[i] = token.get(i);
}
// Send to Keystore
KeyStore.getInstance().addAuthToken(byteToken);
KeyStore.getInstance().addAuthToken(byteToken, mCurrentUserId);
}
if (client != null && client.onAuthenticated(fingerId, groupId)) {
removeClient(client);

View File

@@ -19,6 +19,8 @@ package com.android.server.policy.keyguard;
import android.app.ActivityManager;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.security.IKeystoreService;
import android.util.Slog;
import com.android.internal.policy.IKeyguardService;
@@ -51,11 +53,16 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub {
private final LockPatternUtils mLockPatternUtils;
private final StateCallback mCallback;
IKeystoreService mKeystoreService;
public KeyguardStateMonitor(Context context, IKeyguardService service, StateCallback callback) {
mLockPatternUtils = new LockPatternUtils(context);
mCurrentUserId = ActivityManager.getCurrentUser();
mCallback = callback;
mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager
.getService("android.security.keystore"));
try {
service.addStateMonitorCallback(this);
} catch (RemoteException e) {
@@ -86,6 +93,12 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub {
@Override // Binder interface
public void onShowingStateChanged(boolean showing) {
mIsShowing = showing;
if (showing) try {
mKeystoreService.lock(mCurrentUserId); // as long as this doesn't recur...
} catch (RemoteException e) {
Slog.e(TAG, "Error locking keystore", e);
}
}
@Override // Binder interface