Loading core/api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -8435,10 +8435,12 @@ package android.security.keystore { } public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec { method @Nullable public int[] getAttestationIds(); method public int getNamespace(); } public static final class KeyGenParameterSpec.Builder { method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setAttestationIds(@NonNull int[]); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setNamespace(int); method @Deprecated @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUid(int); } keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java +64 −6 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.security.keystore; import android.annotation.Nullable; import android.content.Context; import android.os.Build; import android.security.Credentials; import android.security.KeyPairGeneratorSpec; Loading @@ -25,6 +26,8 @@ import android.security.keymaster.KeyCharacteristics; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterCertificateChain; import android.security.keymaster.KeymasterDefs; import android.telephony.TelephonyManager; import android.util.ArraySet; import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector; import com.android.internal.org.bouncycastle.asn1.ASN1InputStream; Loading Loading @@ -477,11 +480,11 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato success = true; return keyPair; } catch (ProviderException e) { } catch (ProviderException | IllegalArgumentException | DeviceIdAttestationException e) { if ((mSpec.getPurposes() & KeyProperties.PURPOSE_WRAP_KEY) != 0) { throw new SecureKeyImportUnavailableException(e); } else { throw e; throw new ProviderException(e); } } finally { if (!success) { Loading @@ -491,7 +494,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato } private Iterable<byte[]> createCertificateChain(final String privateKeyAlias, KeyPair keyPair) throws ProviderException { throws ProviderException, DeviceIdAttestationException { byte[] challenge = mSpec.getAttestationChallenge(); if (challenge != null) { KeymasterArguments args = new KeymasterArguments(); Loading @@ -510,6 +513,60 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato Build.MODEL.getBytes(StandardCharsets.UTF_8)); } int[] idTypes = mSpec.getAttestationIds(); if (idTypes != null) { final Set<Integer> idTypesSet = new ArraySet<>(idTypes.length); for (int idType : idTypes) { idTypesSet.add(idType); } TelephonyManager telephonyService = null; if (idTypesSet.contains(AttestationUtils.ID_TYPE_IMEI) || idTypesSet.contains(AttestationUtils.ID_TYPE_MEID)) { telephonyService = (TelephonyManager) KeyStore.getApplicationContext().getSystemService( Context.TELEPHONY_SERVICE); if (telephonyService == null) { throw new DeviceIdAttestationException( "Unable to access telephony service"); } } for (final Integer idType : idTypesSet) { switch (idType) { case AttestationUtils.ID_TYPE_SERIAL: args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_SERIAL, Build.getSerial().getBytes(StandardCharsets.UTF_8) ); break; case AttestationUtils.ID_TYPE_IMEI: { final String imei = telephonyService.getImei(0); if (imei == null) { throw new DeviceIdAttestationException("Unable to retrieve IMEI"); } args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_IMEI, imei.getBytes(StandardCharsets.UTF_8) ); break; } case AttestationUtils.ID_TYPE_MEID: { final String meid = telephonyService.getMeid(0); if (meid == null) { throw new DeviceIdAttestationException("Unable to retrieve MEID"); } args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_MEID, meid.getBytes(StandardCharsets.UTF_8) ); break; } case AttestationUtils.USE_INDIVIDUAL_ATTESTATION: { args.addBoolean(KeymasterDefs.KM_TAG_DEVICE_UNIQUE_ATTESTATION); break; } default: throw new IllegalArgumentException("Unknown device ID type " + idType); } } } return getAttestationChain(privateKeyAlias, keyPair, args); } Loading Loading @@ -547,7 +604,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato } } private KeymasterArguments constructKeyGenerationArguments() { private KeymasterArguments constructKeyGenerationArguments() throws IllegalArgumentException, DeviceIdAttestationException { KeymasterArguments args = new KeymasterArguments(); args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits); args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm); Loading @@ -565,9 +623,9 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato mSpec.getKeyValidityForConsumptionEnd()); addAlgorithmSpecificParameters(args); if (mSpec.isUniqueIdIncluded()) if (mSpec.isUniqueIdIncluded()) { args.addBoolean(KeymasterDefs.KM_TAG_INCLUDE_UNIQUE_ID); } return args; } Loading keystore/java/android/security/keystore/ArrayUtils.java +8 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,14 @@ public abstract class ArrayUtils { return ((array != null) && (array.length > 0)) ? array.clone() : array; } /** * Clones an array if it is not null and has a length greater than 0. Otherwise, returns the * array. */ public static int[] cloneIfNotEmpty(int[] array) { return ((array != null) && (array.length > 0)) ? array.clone() : array; } public static byte[] cloneIfNotEmpty(byte[] array) { return ((array != null) && (array.length > 0)) ? array.clone() : array; } Loading keystore/java/android/security/keystore/KeyGenParameterSpec.java +45 −0 Original line number Diff line number Diff line Loading @@ -267,6 +267,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu private final boolean mUserPresenceRequired; private final byte[] mAttestationChallenge; private final boolean mDevicePropertiesAttestationIncluded; private final int[] mAttestationIds; private final boolean mUniqueIdIncluded; private final boolean mUserAuthenticationValidWhileOnBody; private final boolean mInvalidatedByBiometricEnrollment; Loading Loading @@ -308,6 +309,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu boolean userPresenceRequired, byte[] attestationChallenge, boolean devicePropertiesAttestationIncluded, int[] attestationIds, boolean uniqueIdIncluded, boolean userAuthenticationValidWhileOnBody, boolean invalidatedByBiometricEnrollment, Loading Loading @@ -361,6 +363,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mUserAuthenticationType = userAuthenticationType; mAttestationChallenge = Utils.cloneIfNotNull(attestationChallenge); mDevicePropertiesAttestationIncluded = devicePropertiesAttestationIncluded; mAttestationIds = attestationIds; mUniqueIdIncluded = uniqueIdIncluded; mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody; mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment; Loading Loading @@ -719,6 +722,25 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu return mDevicePropertiesAttestationIncluded; } /** * @hide * Allows the caller to specify device IDs to be attested to in the certificate for the * generated key pair. These values are the enums specified in * {@link android.security.keystore.AttestationUtils} * * @see android.security.keystore.AttestationUtils#ID_TYPE_SERIAL * @see android.security.keystore.AttestationUtils#ID_TYPE_IMEI * @see android.security.keystore.AttestationUtils#ID_TYPE_MEID * @see android.security.keystore.AttestationUtils#USE_INDIVIDUAL_ATTESTATION * * @return integer array representing the requested device IDs to attest. */ @SystemApi @Nullable public int[] getAttestationIds() { return Utils.cloneIfNotNull(mAttestationIds); } /** * @hide This is a system-only API * Loading Loading @@ -834,6 +856,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu private boolean mUserPresenceRequired = false; private byte[] mAttestationChallenge = null; private boolean mDevicePropertiesAttestationIncluded = false; private int[] mAttestationIds = null; private boolean mUniqueIdIncluded = false; private boolean mUserAuthenticationValidWhileOnBody; private boolean mInvalidatedByBiometricEnrollment = true; Loading Loading @@ -902,6 +925,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mAttestationChallenge = sourceSpec.getAttestationChallenge(); mDevicePropertiesAttestationIncluded = sourceSpec.isDevicePropertiesAttestationIncluded(); mAttestationIds = sourceSpec.getAttestationIds(); mUniqueIdIncluded = sourceSpec.isUniqueIdIncluded(); mUserAuthenticationValidWhileOnBody = sourceSpec.isUserAuthenticationValidWhileOnBody(); mInvalidatedByBiometricEnrollment = sourceSpec.isInvalidatedByBiometricEnrollment(); Loading Loading @@ -1472,6 +1496,26 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu return this; } /** * @hide * Sets which IDs to attest in the attestation certificate for the key. The acceptable * values in this integer array are the enums specified in * {@link android.security.keystore.AttestationUtils} * * @param attestationIds the array of ID types to attest to in the certificate. * * @see android.security.keystore.AttestationUtils#ID_TYPE_SERIAL * @see android.security.keystore.AttestationUtils#ID_TYPE_IMEI * @see android.security.keystore.AttestationUtils#ID_TYPE_MEID * @see android.security.keystore.AttestationUtils#USE_INDIVIDUAL_ATTESTATION */ @SystemApi @NonNull public Builder setAttestationIds(@NonNull int[] attestationIds) { mAttestationIds = attestationIds; return this; } /** * @hide Only system apps can use this method. * Loading Loading @@ -1638,6 +1682,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mUserPresenceRequired, mAttestationChallenge, mDevicePropertiesAttestationIncluded, mAttestationIds, mUniqueIdIncluded, mUserAuthenticationValidWhileOnBody, mInvalidatedByBiometricEnrollment, Loading keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java +3 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { out.writeBoolean(mSpec.isUserPresenceRequired()); out.writeByteArray(mSpec.getAttestationChallenge()); out.writeBoolean(mSpec.isDevicePropertiesAttestationIncluded()); out.writeIntArray(mSpec.getAttestationIds()); out.writeBoolean(mSpec.isUniqueIdIncluded()); out.writeBoolean(mSpec.isUserAuthenticationValidWhileOnBody()); out.writeBoolean(mSpec.isInvalidatedByBiometricEnrollment()); Loading Loading @@ -160,6 +161,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { final boolean userPresenceRequired = in.readBoolean(); final byte[] attestationChallenge = in.createByteArray(); final boolean devicePropertiesAttestationIncluded = in.readBoolean(); final int[] attestationIds = in.createIntArray(); final boolean uniqueIdIncluded = in.readBoolean(); final boolean userAuthenticationValidWhileOnBody = in.readBoolean(); final boolean invalidatedByBiometricEnrollment = in.readBoolean(); Loading Loading @@ -195,6 +197,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { userPresenceRequired, attestationChallenge, devicePropertiesAttestationIncluded, attestationIds, uniqueIdIncluded, userAuthenticationValidWhileOnBody, invalidatedByBiometricEnrollment, Loading Loading
core/api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -8435,10 +8435,12 @@ package android.security.keystore { } public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec { method @Nullable public int[] getAttestationIds(); method public int getNamespace(); } public static final class KeyGenParameterSpec.Builder { method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setAttestationIds(@NonNull int[]); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setNamespace(int); method @Deprecated @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUid(int); }
keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java +64 −6 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.security.keystore; import android.annotation.Nullable; import android.content.Context; import android.os.Build; import android.security.Credentials; import android.security.KeyPairGeneratorSpec; Loading @@ -25,6 +26,8 @@ import android.security.keymaster.KeyCharacteristics; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterCertificateChain; import android.security.keymaster.KeymasterDefs; import android.telephony.TelephonyManager; import android.util.ArraySet; import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector; import com.android.internal.org.bouncycastle.asn1.ASN1InputStream; Loading Loading @@ -477,11 +480,11 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato success = true; return keyPair; } catch (ProviderException e) { } catch (ProviderException | IllegalArgumentException | DeviceIdAttestationException e) { if ((mSpec.getPurposes() & KeyProperties.PURPOSE_WRAP_KEY) != 0) { throw new SecureKeyImportUnavailableException(e); } else { throw e; throw new ProviderException(e); } } finally { if (!success) { Loading @@ -491,7 +494,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato } private Iterable<byte[]> createCertificateChain(final String privateKeyAlias, KeyPair keyPair) throws ProviderException { throws ProviderException, DeviceIdAttestationException { byte[] challenge = mSpec.getAttestationChallenge(); if (challenge != null) { KeymasterArguments args = new KeymasterArguments(); Loading @@ -510,6 +513,60 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato Build.MODEL.getBytes(StandardCharsets.UTF_8)); } int[] idTypes = mSpec.getAttestationIds(); if (idTypes != null) { final Set<Integer> idTypesSet = new ArraySet<>(idTypes.length); for (int idType : idTypes) { idTypesSet.add(idType); } TelephonyManager telephonyService = null; if (idTypesSet.contains(AttestationUtils.ID_TYPE_IMEI) || idTypesSet.contains(AttestationUtils.ID_TYPE_MEID)) { telephonyService = (TelephonyManager) KeyStore.getApplicationContext().getSystemService( Context.TELEPHONY_SERVICE); if (telephonyService == null) { throw new DeviceIdAttestationException( "Unable to access telephony service"); } } for (final Integer idType : idTypesSet) { switch (idType) { case AttestationUtils.ID_TYPE_SERIAL: args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_SERIAL, Build.getSerial().getBytes(StandardCharsets.UTF_8) ); break; case AttestationUtils.ID_TYPE_IMEI: { final String imei = telephonyService.getImei(0); if (imei == null) { throw new DeviceIdAttestationException("Unable to retrieve IMEI"); } args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_IMEI, imei.getBytes(StandardCharsets.UTF_8) ); break; } case AttestationUtils.ID_TYPE_MEID: { final String meid = telephonyService.getMeid(0); if (meid == null) { throw new DeviceIdAttestationException("Unable to retrieve MEID"); } args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_MEID, meid.getBytes(StandardCharsets.UTF_8) ); break; } case AttestationUtils.USE_INDIVIDUAL_ATTESTATION: { args.addBoolean(KeymasterDefs.KM_TAG_DEVICE_UNIQUE_ATTESTATION); break; } default: throw new IllegalArgumentException("Unknown device ID type " + idType); } } } return getAttestationChain(privateKeyAlias, keyPair, args); } Loading Loading @@ -547,7 +604,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato } } private KeymasterArguments constructKeyGenerationArguments() { private KeymasterArguments constructKeyGenerationArguments() throws IllegalArgumentException, DeviceIdAttestationException { KeymasterArguments args = new KeymasterArguments(); args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits); args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm); Loading @@ -565,9 +623,9 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato mSpec.getKeyValidityForConsumptionEnd()); addAlgorithmSpecificParameters(args); if (mSpec.isUniqueIdIncluded()) if (mSpec.isUniqueIdIncluded()) { args.addBoolean(KeymasterDefs.KM_TAG_INCLUDE_UNIQUE_ID); } return args; } Loading
keystore/java/android/security/keystore/ArrayUtils.java +8 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,14 @@ public abstract class ArrayUtils { return ((array != null) && (array.length > 0)) ? array.clone() : array; } /** * Clones an array if it is not null and has a length greater than 0. Otherwise, returns the * array. */ public static int[] cloneIfNotEmpty(int[] array) { return ((array != null) && (array.length > 0)) ? array.clone() : array; } public static byte[] cloneIfNotEmpty(byte[] array) { return ((array != null) && (array.length > 0)) ? array.clone() : array; } Loading
keystore/java/android/security/keystore/KeyGenParameterSpec.java +45 −0 Original line number Diff line number Diff line Loading @@ -267,6 +267,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu private final boolean mUserPresenceRequired; private final byte[] mAttestationChallenge; private final boolean mDevicePropertiesAttestationIncluded; private final int[] mAttestationIds; private final boolean mUniqueIdIncluded; private final boolean mUserAuthenticationValidWhileOnBody; private final boolean mInvalidatedByBiometricEnrollment; Loading Loading @@ -308,6 +309,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu boolean userPresenceRequired, byte[] attestationChallenge, boolean devicePropertiesAttestationIncluded, int[] attestationIds, boolean uniqueIdIncluded, boolean userAuthenticationValidWhileOnBody, boolean invalidatedByBiometricEnrollment, Loading Loading @@ -361,6 +363,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mUserAuthenticationType = userAuthenticationType; mAttestationChallenge = Utils.cloneIfNotNull(attestationChallenge); mDevicePropertiesAttestationIncluded = devicePropertiesAttestationIncluded; mAttestationIds = attestationIds; mUniqueIdIncluded = uniqueIdIncluded; mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody; mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment; Loading Loading @@ -719,6 +722,25 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu return mDevicePropertiesAttestationIncluded; } /** * @hide * Allows the caller to specify device IDs to be attested to in the certificate for the * generated key pair. These values are the enums specified in * {@link android.security.keystore.AttestationUtils} * * @see android.security.keystore.AttestationUtils#ID_TYPE_SERIAL * @see android.security.keystore.AttestationUtils#ID_TYPE_IMEI * @see android.security.keystore.AttestationUtils#ID_TYPE_MEID * @see android.security.keystore.AttestationUtils#USE_INDIVIDUAL_ATTESTATION * * @return integer array representing the requested device IDs to attest. */ @SystemApi @Nullable public int[] getAttestationIds() { return Utils.cloneIfNotNull(mAttestationIds); } /** * @hide This is a system-only API * Loading Loading @@ -834,6 +856,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu private boolean mUserPresenceRequired = false; private byte[] mAttestationChallenge = null; private boolean mDevicePropertiesAttestationIncluded = false; private int[] mAttestationIds = null; private boolean mUniqueIdIncluded = false; private boolean mUserAuthenticationValidWhileOnBody; private boolean mInvalidatedByBiometricEnrollment = true; Loading Loading @@ -902,6 +925,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mAttestationChallenge = sourceSpec.getAttestationChallenge(); mDevicePropertiesAttestationIncluded = sourceSpec.isDevicePropertiesAttestationIncluded(); mAttestationIds = sourceSpec.getAttestationIds(); mUniqueIdIncluded = sourceSpec.isUniqueIdIncluded(); mUserAuthenticationValidWhileOnBody = sourceSpec.isUserAuthenticationValidWhileOnBody(); mInvalidatedByBiometricEnrollment = sourceSpec.isInvalidatedByBiometricEnrollment(); Loading Loading @@ -1472,6 +1496,26 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu return this; } /** * @hide * Sets which IDs to attest in the attestation certificate for the key. The acceptable * values in this integer array are the enums specified in * {@link android.security.keystore.AttestationUtils} * * @param attestationIds the array of ID types to attest to in the certificate. * * @see android.security.keystore.AttestationUtils#ID_TYPE_SERIAL * @see android.security.keystore.AttestationUtils#ID_TYPE_IMEI * @see android.security.keystore.AttestationUtils#ID_TYPE_MEID * @see android.security.keystore.AttestationUtils#USE_INDIVIDUAL_ATTESTATION */ @SystemApi @NonNull public Builder setAttestationIds(@NonNull int[] attestationIds) { mAttestationIds = attestationIds; return this; } /** * @hide Only system apps can use this method. * Loading Loading @@ -1638,6 +1682,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mUserPresenceRequired, mAttestationChallenge, mDevicePropertiesAttestationIncluded, mAttestationIds, mUniqueIdIncluded, mUserAuthenticationValidWhileOnBody, mInvalidatedByBiometricEnrollment, Loading
keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java +3 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { out.writeBoolean(mSpec.isUserPresenceRequired()); out.writeByteArray(mSpec.getAttestationChallenge()); out.writeBoolean(mSpec.isDevicePropertiesAttestationIncluded()); out.writeIntArray(mSpec.getAttestationIds()); out.writeBoolean(mSpec.isUniqueIdIncluded()); out.writeBoolean(mSpec.isUserAuthenticationValidWhileOnBody()); out.writeBoolean(mSpec.isInvalidatedByBiometricEnrollment()); Loading Loading @@ -160,6 +161,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { final boolean userPresenceRequired = in.readBoolean(); final byte[] attestationChallenge = in.createByteArray(); final boolean devicePropertiesAttestationIncluded = in.readBoolean(); final int[] attestationIds = in.createIntArray(); final boolean uniqueIdIncluded = in.readBoolean(); final boolean userAuthenticationValidWhileOnBody = in.readBoolean(); final boolean invalidatedByBiometricEnrollment = in.readBoolean(); Loading Loading @@ -195,6 +197,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { userPresenceRequired, attestationChallenge, devicePropertiesAttestationIncluded, attestationIds, uniqueIdIncluded, userAuthenticationValidWhileOnBody, invalidatedByBiometricEnrollment, Loading