diff --git a/api/current.txt b/api/current.txt index a7367e8c49434..fcfa7cfd11c3e 100644 --- a/api/current.txt +++ b/api/current.txt @@ -42600,6 +42600,7 @@ package android.security.keystore { method @NonNull public String getKeystoreAlias(); method public int getPurposes(); method @NonNull public String[] getSignaturePaddings(); + method public int getUserAuthenticationType(); method public int getUserAuthenticationValidityDurationSeconds(); method @NonNull public boolean isDigestsSpecified(); method public boolean isInvalidatedByBiometricEnrollment(); @@ -42634,9 +42635,10 @@ package android.security.keystore { method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setRandomizedEncryptionRequired(boolean); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setSignaturePaddings(java.lang.String...); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUnlockedDeviceRequired(boolean); + method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationParameters(@IntRange(from=0xffffffff) int, int); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationRequired(boolean); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidWhileOnBody(boolean); - method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidityDurationSeconds(@IntRange(from=0xffffffff) int); + method @Deprecated @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidityDurationSeconds(@IntRange(from=0xffffffff) int); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUserConfirmationRequired(boolean); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUserPresenceRequired(boolean); } @@ -42653,6 +42655,7 @@ package android.security.keystore { method public int getOrigin(); method public int getPurposes(); method @NonNull public String[] getSignaturePaddings(); + method public int getUserAuthenticationType(); method public int getUserAuthenticationValidityDurationSeconds(); method public boolean isInsideSecureHardware(); method public boolean isInvalidatedByBiometricEnrollment(); @@ -42676,6 +42679,8 @@ package android.security.keystore { } public abstract class KeyProperties { + field public static final int AUTH_BIOMETRIC_STRONG = 2; // 0x2 + field public static final int AUTH_DEVICE_CREDENTIAL = 1; // 0x1 field public static final String BLOCK_MODE_CBC = "CBC"; field public static final String BLOCK_MODE_CTR = "CTR"; field public static final String BLOCK_MODE_ECB = "ECB"; @@ -42722,6 +42727,7 @@ package android.security.keystore { method @Nullable public java.util.Date getKeyValidityStart(); method public int getPurposes(); method @NonNull public String[] getSignaturePaddings(); + method public int getUserAuthenticationType(); method public int getUserAuthenticationValidityDurationSeconds(); method public boolean isDigestsSpecified(); method public boolean isInvalidatedByBiometricEnrollment(); @@ -42747,9 +42753,10 @@ package android.security.keystore { method @NonNull public android.security.keystore.KeyProtection.Builder setRandomizedEncryptionRequired(boolean); method @NonNull public android.security.keystore.KeyProtection.Builder setSignaturePaddings(java.lang.String...); method @NonNull public android.security.keystore.KeyProtection.Builder setUnlockedDeviceRequired(boolean); + method @NonNull public android.security.keystore.KeyProtection.Builder setUserAuthenticationParameters(@IntRange(from=0xffffffff) int, int); method @NonNull public android.security.keystore.KeyProtection.Builder setUserAuthenticationRequired(boolean); method @NonNull public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidWhileOnBody(boolean); - method @NonNull public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidityDurationSeconds(@IntRange(from=0xffffffff) int); + method @Deprecated @NonNull public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidityDurationSeconds(@IntRange(from=0xffffffff) int); method @NonNull public android.security.keystore.KeyProtection.Builder setUserConfirmationRequired(boolean); method @NonNull public android.security.keystore.KeyProtection.Builder setUserPresenceRequired(boolean); } diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java index a2d23558616b7..8dbb5f544ad4d 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java @@ -206,6 +206,7 @@ public class AndroidKeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi { blockModes, userAuthenticationRequired, (int) userAuthenticationValidityDurationSeconds, + keymasterHwEnforcedUserAuthenticators, userAuthenticationRequirementEnforcedBySecureHardware, userAuthenticationValidWhileOnBody, trustedUserPresenceRequred, diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java index 450dd3301253f..d683041fbfdcd 100644 --- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java +++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java @@ -263,6 +263,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu private final boolean mRandomizedEncryptionRequired; private final boolean mUserAuthenticationRequired; private final int mUserAuthenticationValidityDurationSeconds; + private final @KeyProperties.AuthEnum int mUserAuthenticationType; private final boolean mUserPresenceRequired; private final byte[] mAttestationChallenge; private final boolean mUniqueIdIncluded; @@ -301,6 +302,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu boolean randomizedEncryptionRequired, boolean userAuthenticationRequired, int userAuthenticationValidityDurationSeconds, + @KeyProperties.AuthEnum int userAuthenticationType, boolean userPresenceRequired, byte[] attestationChallenge, boolean uniqueIdIncluded, @@ -352,6 +354,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mUserAuthenticationRequired = userAuthenticationRequired; mUserPresenceRequired = userPresenceRequired; mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds; + mUserAuthenticationType = userAuthenticationType; mAttestationChallenge = Utils.cloneIfNotNull(attestationChallenge); mUniqueIdIncluded = uniqueIdIncluded; mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody; @@ -604,6 +607,22 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu return mUserAuthenticationValidityDurationSeconds; } + /** + * Gets the modes of authentication that can authorize use of this key. This has effect only if + * user authentication is required (see {@link #isUserAuthenticationRequired()}). + * + *

This authorization applies only to secret key and private key operations. Public key + * operations are not restricted. + * + * @return integer representing the bitwse OR of all acceptable authentication types for the + * key. + * + * @see #isUserAuthenticationRequired() + * @see Builder#setUserAuthenticationParameters(int, int) + */ + public @KeyProperties.AuthEnum int getUserAuthenticationType() { + return mUserAuthenticationType; + } /** * 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. @@ -746,6 +765,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu private boolean mRandomizedEncryptionRequired = true; private boolean mUserAuthenticationRequired; private int mUserAuthenticationValidityDurationSeconds = -1; + private @KeyProperties.AuthEnum int mUserAuthenticationType; private boolean mUserPresenceRequired = false; private byte[] mAttestationChallenge = null; private boolean mUniqueIdIncluded = false; @@ -810,6 +830,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mUserAuthenticationRequired = sourceSpec.isUserAuthenticationRequired(); mUserAuthenticationValidityDurationSeconds = sourceSpec.getUserAuthenticationValidityDurationSeconds(); + mUserAuthenticationType = sourceSpec.getUserAuthenticationType(); mUserPresenceRequired = sourceSpec.isUserPresenceRequired(); mAttestationChallenge = sourceSpec.getAttestationChallenge(); mUniqueIdIncluded = sourceSpec.isUniqueIdIncluded(); @@ -1207,14 +1228,62 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu * @see BiometricPrompt * @see BiometricPrompt.CryptoObject * @see KeyguardManager + * @deprecated See {@link #setUserAuthenticationParameters(int, int)} */ + @Deprecated @NonNull public Builder setUserAuthenticationValidityDurationSeconds( @IntRange(from = -1) int seconds) { if (seconds < -1) { throw new IllegalArgumentException("seconds must be -1 or larger"); } - mUserAuthenticationValidityDurationSeconds = seconds; + if (seconds == -1) { + return setUserAuthenticationParameters(0, KeyProperties.AUTH_BIOMETRIC_STRONG); + } + return setUserAuthenticationParameters(seconds, KeyProperties.AUTH_BIOMETRIC_STRONG); + } + + /** + * Sets the duration of time (seconds) and authorization type for which this key is + * authorized to be used after the user is successfully authenticated. This has effect if + * the key requires user authentication for its use (see + * {@link #setUserAuthenticationRequired(boolean)}). + * + *

By default, if user authentication is required, it must take place for every use of + * the key. + * + *

These cryptographic operations will throw {@link UserNotAuthenticatedException} during + * initialization if the user needs to be authenticated to proceed. This situation can be + * resolved by the user authenticating with the appropriate biometric or credential as + * required by the key. See {@link BiometricPrompt.Builder#setAllowedAuthenticators(int)} + * and {@link BiometricManager.Authenticators}. + * + *

Once resolved, initializing a new cryptographic operation using this key (or any other + * key which is authorized to be used for a fixed duration of time after user + * authentication) should succeed provided the user authentication flow completed + * successfully. + * + * @param timeout duration in seconds or {@code 0} if user authentication must take place + * for every use of the key. {@code -1} is also accepted for legacy purposes. It is + * functionally the same as {@code 0}. + * @param type set of authentication types which can authorize use of the key. See + * {@link KeyProperties}.{@code AUTH} flags. + * + * @see #setUserAuthenticationRequired(boolean) + * @see BiometricPrompt + * @see BiometricPrompt.CryptoObject + * @see KeyguardManager + */ + @NonNull + public Builder setUserAuthenticationParameters(@IntRange(from = -1) int timeout, + @KeyProperties.AuthEnum int type) { + if (timeout < -1) { + throw new IllegalArgumentException("timeout must be -1 or larger"); + } else if (timeout == -1) { + timeout = 0; + } + mUserAuthenticationValidityDurationSeconds = timeout; + mUserAuthenticationType = type; return this; } @@ -1392,6 +1461,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mRandomizedEncryptionRequired, mUserAuthenticationRequired, mUserAuthenticationValidityDurationSeconds, + mUserAuthenticationType, mUserPresenceRequired, mAttestationChallenge, mUniqueIdIncluded, diff --git a/keystore/java/android/security/keystore/KeyInfo.java b/keystore/java/android/security/keystore/KeyInfo.java index 0a75cd5268b7b..d891a25dba681 100644 --- a/keystore/java/android/security/keystore/KeyInfo.java +++ b/keystore/java/android/security/keystore/KeyInfo.java @@ -78,6 +78,7 @@ public class KeyInfo implements KeySpec { private final @KeyProperties.BlockModeEnum String[] mBlockModes; private final boolean mUserAuthenticationRequired; private final int mUserAuthenticationValidityDurationSeconds; + private final @KeyProperties.AuthEnum int mUserAuthenticationType; private final boolean mUserAuthenticationRequirementEnforcedBySecureHardware; private final boolean mUserAuthenticationValidWhileOnBody; private final boolean mTrustedUserPresenceRequired; @@ -101,6 +102,7 @@ public class KeyInfo implements KeySpec { @KeyProperties.BlockModeEnum String[] blockModes, boolean userAuthenticationRequired, int userAuthenticationValidityDurationSeconds, + @KeyProperties.AuthEnum int userAuthenticationType, boolean userAuthenticationRequirementEnforcedBySecureHardware, boolean userAuthenticationValidWhileOnBody, boolean trustedUserPresenceRequired, @@ -122,6 +124,7 @@ public class KeyInfo implements KeySpec { mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes)); mUserAuthenticationRequired = userAuthenticationRequired; mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds; + mUserAuthenticationType = userAuthenticationType; mUserAuthenticationRequirementEnforcedBySecureHardware = userAuthenticationRequirementEnforcedBySecureHardware; mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody; @@ -300,6 +303,22 @@ public class KeyInfo implements KeySpec { return mUserAuthenticationValidityDurationSeconds; } + /** + * Gets the acceptable user authentication types for which this key can be authorized to be + * used. This has effect only if user authentication is required (see + * {@link #isUserAuthenticationRequired()}). + * + *

This authorization applies only to secret key and private key operations. Public key + * operations are not restricted. + * + * @return integer representing the accepted forms of user authentication for this key + * + * @see #isUserAuthenticationRequired() + */ + public @KeyProperties.AuthEnum int getUserAuthenticationType() { + return mUserAuthenticationType; + } + /** * Returns {@code true} if the requirement that this key can only be used if the user has been * authenticated is enforced by secure hardware (e.g., Trusted Execution Environment (TEE) or diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java index f12a659039eef..c58a1236d475c 100644 --- a/keystore/java/android/security/keystore/KeyProperties.java +++ b/keystore/java/android/security/keystore/KeyProperties.java @@ -35,6 +35,27 @@ import java.util.Locale; public abstract class KeyProperties { private KeyProperties() {} + /** + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(flag = true, prefix = { "AUTH_" }, value = { + AUTH_BIOMETRIC_STRONG, + AUTH_DEVICE_CREDENTIAL, + }) + public @interface AuthEnum {} + + /** + * The non-biometric credential used to secure the device (i.e., PIN, pattern, or password) + */ + public static final int AUTH_DEVICE_CREDENTIAL = 1 << 0; + + /** + * Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the + * requirements for Strong, as defined by the Android CDD. + */ + public static final int AUTH_BIOMETRIC_STRONG = 1 << 1; + /** * @hide */ diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java index 26181a65dc1de..e230b7c3708bd 100644 --- a/keystore/java/android/security/keystore/KeyProtection.java +++ b/keystore/java/android/security/keystore/KeyProtection.java @@ -225,6 +225,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { private final @KeyProperties.BlockModeEnum String[] mBlockModes; private final boolean mRandomizedEncryptionRequired; private final boolean mUserAuthenticationRequired; + private final @KeyProperties.AuthEnum int mUserAuthenticationType; private final int mUserAuthenticationValidityDurationSeconds; private final boolean mUserPresenceRequred; private final boolean mUserAuthenticationValidWhileOnBody; @@ -246,6 +247,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { @KeyProperties.BlockModeEnum String[] blockModes, boolean randomizedEncryptionRequired, boolean userAuthenticationRequired, + @KeyProperties.AuthEnum int userAuthenticationType, int userAuthenticationValidityDurationSeconds, boolean userPresenceRequred, boolean userAuthenticationValidWhileOnBody, @@ -267,6 +269,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes)); mRandomizedEncryptionRequired = randomizedEncryptionRequired; mUserAuthenticationRequired = userAuthenticationRequired; + mUserAuthenticationType = userAuthenticationType; mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds; mUserPresenceRequred = userPresenceRequred; mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody; @@ -429,6 +432,10 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { return mUserConfirmationRequired; } + public @KeyProperties.AuthEnum int getUserAuthenticationType() { + return mUserAuthenticationType; + } + /** * Gets the duration of time (seconds) for which this key is authorized to be used after the * user is successfully authenticated. This has effect only if user authentication is required @@ -555,6 +562,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { private @KeyProperties.BlockModeEnum String[] mBlockModes; private boolean mRandomizedEncryptionRequired = true; private boolean mUserAuthenticationRequired; + private @KeyProperties.AuthEnum int mUserAuthenticationType; private int mUserAuthenticationValidityDurationSeconds = -1; private boolean mUserPresenceRequired = false; private boolean mUserAuthenticationValidWhileOnBody; @@ -850,14 +858,62 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { * @see BiometricPrompt * @see BiometricPrompt.CryptoObject * @see KeyguardManager + * @deprecated See {@link #setUserAuthenticationParameters(int, int)} */ + @Deprecated @NonNull public Builder setUserAuthenticationValidityDurationSeconds( @IntRange(from = -1) int seconds) { if (seconds < -1) { throw new IllegalArgumentException("seconds must be -1 or larger"); } - mUserAuthenticationValidityDurationSeconds = seconds; + if (seconds == -1) { + return setUserAuthenticationParameters(0, KeyProperties.AUTH_BIOMETRIC_STRONG); + } + return setUserAuthenticationParameters(seconds, KeyProperties.AUTH_BIOMETRIC_STRONG); + } + + /** + * Sets the duration of time (seconds) and authorization type for which this key is + * authorized to be used after the user is successfully authenticated. This has effect if + * the key requires user authentication for its use (see + * {@link #setUserAuthenticationRequired(boolean)}). + * + *

By default, if user authentication is required, it must take place for every use of + * the key. + * + *

These cryptographic operations will throw {@link UserNotAuthenticatedException} during + * initialization if the user needs to be authenticated to proceed. This situation can be + * resolved by the user authenticating with the appropriate biometric or credential as + * required by the key. See {@link BiometricPrompt.Builder#setAllowedAuthenticators(int)} + * and {@link BiometricManager.Authenticators}. + * + *

Once resolved, initializing a new cryptographic operation using this key (or any other + * key which is authorized to be used for a fixed duration of time after user + * authentication) should succeed provided the user authentication flow completed + * successfully. + * + * @param timeout duration in seconds or {@code 0} if user authentication must take place + * for every use of the key. {@code -1} is also accepted for legacy purposes. It is + * functionally the same as {@code 0}. + * @param type set of authentication types which can authorize use of the key. See + * {@link KeyProperties}.{@code AUTH} flags. + * + * @see #setUserAuthenticationRequired(boolean) + * @see BiometricPrompt + * @see BiometricPrompt.CryptoObject + * @see KeyguardManager + */ + @NonNull + public Builder setUserAuthenticationParameters(@IntRange(from = -1) int timeout, + @KeyProperties.AuthEnum int type) { + if (timeout < -1) { + throw new IllegalArgumentException("timeout must be -1 or larger"); + } else if (timeout == -1) { + timeout = 0; + } + mUserAuthenticationValidityDurationSeconds = timeout; + mUserAuthenticationType = type; return this; } @@ -1002,6 +1058,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { mBlockModes, mRandomizedEncryptionRequired, mUserAuthenticationRequired, + mUserAuthenticationType, mUserAuthenticationValidityDurationSeconds, mUserPresenceRequired, mUserAuthenticationValidWhileOnBody, diff --git a/keystore/java/android/security/keystore/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java index 79e48cdfdd8ef..37b1f23ba55a1 100644 --- a/keystore/java/android/security/keystore/KeymasterUtils.java +++ b/keystore/java/android/security/keystore/KeymasterUtils.java @@ -88,17 +88,9 @@ public abstract class KeymasterUtils { * Adds keymaster arguments to express the key's authorization policy supported by user * authentication. * - * @param userAuthenticationRequired whether user authentication is required to authorize the - * use of the key. - * @param userAuthenticationValidityDurationSeconds duration of time (seconds) for which user - * authentication is valid as authorization for using the key or {@code -1} if every - * use of the key needs authorization. - * @param boundToSpecificSecureUserId if non-zero, specify which SID the key will be bound to, - * overriding the default logic in this method where the key is bound to either the root - * SID of the current user, or the fingerprint SID if explicit fingerprint authorization - * is requested. - * @param userConfirmationRequired whether user confirmation is required to authorize the use - * of the key. + * @param args The arguments sent to keymaster that need to be populated from the spec + * @param spec The user authentication relevant portions of the spec passed in from the caller. + * This spec will be translated into the relevant keymaster tags to be loaded into args. * @throws IllegalStateException if user authentication is required but the system is in a wrong * state (e.g., secure lock screen not set up) for generating or importing keys that * require user authentication. @@ -122,7 +114,7 @@ public abstract class KeymasterUtils { return; } - if (spec.getUserAuthenticationValidityDurationSeconds() == -1) { + if (spec.getUserAuthenticationValidityDurationSeconds() == 0) { PackageManager pm = KeyStore.getApplicationContext().getPackageManager(); // Every use of this key needs to be authorized by the user. This currently means // fingerprint or face auth. @@ -168,7 +160,8 @@ public abstract class KeymasterUtils { 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.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, spec.getUserAuthenticationType()); if (spec.isUserAuthenticationValidWhileOnBody()) { throw new ProviderException("Key validity extension while device is on-body is not " diff --git a/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java b/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java index 98e458930a7f2..9c9773e5d145b 100644 --- a/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java +++ b/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java @@ -97,6 +97,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { out.writeBoolean(mSpec.isRandomizedEncryptionRequired()); out.writeBoolean(mSpec.isUserAuthenticationRequired()); out.writeInt(mSpec.getUserAuthenticationValidityDurationSeconds()); + out.writeInt(mSpec.getUserAuthenticationType()); out.writeBoolean(mSpec.isUserPresenceRequired()); out.writeByteArray(mSpec.getAttestationChallenge()); out.writeBoolean(mSpec.isUniqueIdIncluded()); @@ -153,6 +154,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { final boolean randomizedEncryptionRequired = in.readBoolean(); final boolean userAuthenticationRequired = in.readBoolean(); final int userAuthenticationValidityDurationSeconds = in.readInt(); + final int userAuthenticationTypes = in.readInt(); final boolean userPresenceRequired = in.readBoolean(); final byte[] attestationChallenge = in.createByteArray(); final boolean uniqueIdIncluded = in.readBoolean(); @@ -185,6 +187,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { randomizedEncryptionRequired, userAuthenticationRequired, userAuthenticationValidityDurationSeconds, + userAuthenticationTypes, userPresenceRequired, attestationChallenge, uniqueIdIncluded, diff --git a/keystore/java/android/security/keystore/UserAuthArgs.java b/keystore/java/android/security/keystore/UserAuthArgs.java index 69520606f1016..c9e9bf0ab82f2 100644 --- a/keystore/java/android/security/keystore/UserAuthArgs.java +++ b/keystore/java/android/security/keystore/UserAuthArgs.java @@ -28,6 +28,7 @@ public interface UserAuthArgs { boolean isUserAuthenticationRequired(); int getUserAuthenticationValidityDurationSeconds(); + @KeyProperties.AuthEnum int getUserAuthenticationType(); boolean isUserAuthenticationValidWhileOnBody(); boolean isInvalidatedByBiometricEnrollment(); boolean isUserConfirmationRequired();