From 04b682d3945d69f0d29542b18493cb916e2c0f89 Mon Sep 17 00:00:00 2001 From: Max Bires Date: Tue, 14 Jan 2020 16:10:36 -0800 Subject: [PATCH] Changing op per auth keys to allow password Previously, auth per operation keystore keys could only be authorized with biometrics. There is no reason to restrict this functionality to biometrics. This change slightly refactors the key parameter builder interface to allow the caller to specify which authentication types should be allowed for an auth per op key. Bug: 147693375 Bug: 140256692 Test: atest keystore Change-Id: I5cbf3d4e3f0e84d577dbf6b4cb356b1010100925 --- api/current.txt | 11 ++- .../AndroidKeyStoreSecretKeyFactorySpi.java | 1 + .../keystore/KeyGenParameterSpec.java | 72 ++++++++++++++++++- .../android/security/keystore/KeyInfo.java | 19 +++++ .../security/keystore/KeyProperties.java | 21 ++++++ .../security/keystore/KeyProtection.java | 59 ++++++++++++++- .../security/keystore/KeymasterUtils.java | 19 ++--- .../ParcelableKeyGenParameterSpec.java | 3 + .../security/keystore/UserAuthArgs.java | 1 + 9 files changed, 189 insertions(+), 17 deletions(-) diff --git a/api/current.txt b/api/current.txt index c556bd0a4760f..4655531242fc3 100644 --- a/api/current.txt +++ b/api/current.txt @@ -42533,6 +42533,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(); @@ -42567,9 +42568,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); } @@ -42586,6 +42588,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(); @@ -42609,6 +42612,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"; @@ -42655,6 +42660,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(); @@ -42680,9 +42686,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();