Merge "Refactor AddUserAuthArgs for extensibility" into pi-dev

This commit is contained in:
TreeHugger Robot
2018-03-27 22:13:37 +00:00
committed by Android (Google) Code Review
8 changed files with 95 additions and 64 deletions

View File

@@ -38608,6 +38608,7 @@ package android.security.keystore {
method public boolean isDigestsSpecified();
method public boolean isInvalidatedByBiometricEnrollment();
method public boolean isRandomizedEncryptionRequired();
method public boolean isTrustedUserPresenceRequired();
method public boolean isUserAuthenticationRequired();
method public boolean isUserAuthenticationValidWhileOnBody();
method public boolean isUserConfirmationRequired();
@@ -38626,6 +38627,7 @@ 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 setUserAuthenticationRequired(boolean);
method public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidWhileOnBody(boolean);
method public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidityDurationSeconds(int);

View File

@@ -243,13 +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 */,
spec.isUserConfirmationRequired());
KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), spec);
} catch (IllegalStateException | IllegalArgumentException e) {
throw new InvalidAlgorithmParameterException(e);
}
@@ -285,16 +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 */,
spec.isUserConfirmationRequired());
if (spec.isTrustedUserPresenceRequired()) {
args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED);
}
KeymasterUtils.addUserAuthArgs(args, spec);
KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
args,
mKeymasterAlgorithm,

View File

@@ -344,13 +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 */,
mSpec.isUserConfirmationRequired());
KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), mSpec);
} catch (IllegalArgumentException | IllegalStateException e) {
throw new InvalidAlgorithmParameterException(e);
}
@@ -541,13 +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 */,
mSpec.isUserConfirmationRequired());
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,13 +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(),
spec.isUserConfirmationRequired());
KeymasterUtils.addUserAuthArgs(importArgs, spec);
importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
spec.getKeyValidityStart());
importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
@@ -700,13 +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(),
params.isUserConfirmationRequired());
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");
@@ -668,6 +669,13 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
return mIsStrongBoxBacked;
}
/**
* @hide
*/
public long getBoundToSpecificSecureUserId() {
return GateKeeper.INVALID_SECURE_USER_ID;
}
/**
* Builder of {@link KeyGenParameterSpec} instances.
*/

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;
@@ -224,6 +224,7 @@ public final class KeyProtection implements ProtectionParameter {
private final boolean mRandomizedEncryptionRequired;
private final boolean mUserAuthenticationRequired;
private final int mUserAuthenticationValidityDurationSeconds;
private final boolean mTrustedUserPresenceRequred;
private final boolean mUserAuthenticationValidWhileOnBody;
private final boolean mInvalidatedByBiometricEnrollment;
private final long mBoundToSecureUserId;
@@ -242,6 +243,7 @@ public final class KeyProtection implements ProtectionParameter {
boolean randomizedEncryptionRequired,
boolean userAuthenticationRequired,
int userAuthenticationValidityDurationSeconds,
boolean trustedUserPresenceRequred,
boolean userAuthenticationValidWhileOnBody,
boolean invalidatedByBiometricEnrollment,
long boundToSecureUserId,
@@ -260,6 +262,7 @@ public final class KeyProtection implements ProtectionParameter {
mRandomizedEncryptionRequired = randomizedEncryptionRequired;
mUserAuthenticationRequired = userAuthenticationRequired;
mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
mTrustedUserPresenceRequred = trustedUserPresenceRequred;
mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody;
mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
mBoundToSecureUserId = boundToSecureUserId;
@@ -436,6 +439,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 mTrustedUserPresenceRequred;
}
/**
* 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
@@ -509,6 +520,7 @@ public final class KeyProtection implements ProtectionParameter {
private boolean mRandomizedEncryptionRequired = true;
private boolean mUserAuthenticationRequired;
private int mUserAuthenticationValidityDurationSeconds = -1;
private boolean mTrustedUserPresenceRequired = false;
private boolean mUserAuthenticationValidWhileOnBody;
private boolean mInvalidatedByBiometricEnrollment = true;
private boolean mUserConfirmationRequired;
@@ -810,6 +822,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
@@ -910,6 +932,7 @@ public final class KeyProtection implements ProtectionParameter {
mRandomizedEncryptionRequired,
mUserAuthenticationRequired,
mUserAuthenticationValidityDurationSeconds,
mTrustedUserPresenceRequired,
mUserAuthenticationValidWhileOnBody,
mInvalidatedByBiometricEnrollment,
mBoundToSecureUserId,

View File

@@ -18,6 +18,7 @@ package android.security.keystore;
import android.util.Log;
import android.hardware.fingerprint.FingerprintManager;
import android.os.UserHandle;
import android.security.GateKeeper;
import android.security.KeyStore;
import android.security.keymaster.KeymasterArguments;
@@ -101,22 +102,21 @@ public abstract class KeymasterUtils {
* require user authentication.
*/
public static void addUserAuthArgs(KeymasterArguments args,
boolean userAuthenticationRequired,
int userAuthenticationValidityDurationSeconds,
boolean userAuthenticationValidWhileOnBody,
boolean invalidatedByBiometricEnrollment,
long boundToSpecificSecureUserId,
boolean userConfirmationRequired) {
if (userConfirmationRequired) {
UserAuthArgs spec) {
if (spec.isUserConfirmationRequired()) {
args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_CONFIRMATION_REQUIRED);
}
if (!userAuthenticationRequired) {
if (spec.isTrustedUserPresenceRequired()) {
args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_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 =
@@ -132,9 +132,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;
@@ -147,14 +147,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.
@@ -165,8 +165,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 isUserConfirmationRequired();
long getBoundToSpecificSecureUserId();
boolean isTrustedUserPresenceRequired();
}