Loading api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -41304,6 +41304,7 @@ package android.security.keystore { method public int getPurposes(); method @NonNull public String[] getSignaturePaddings(); method public int getUserAuthenticationValidityDurationSeconds(); method public boolean isDevicePropertiesAttestationIncluded(); method @NonNull public boolean isDigestsSpecified(); method public boolean isInvalidatedByBiometricEnrollment(); method public boolean isRandomizedEncryptionRequired(); Loading @@ -41325,6 +41326,7 @@ package android.security.keystore { method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotBefore(@NonNull java.util.Date); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSerialNumber(@NonNull java.math.BigInteger); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSubject(@NonNull javax.security.auth.x500.X500Principal); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setDevicePropertiesAttestationIncluded(boolean); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setDigests(java.lang.String...); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setEncryptionPaddings(java.lang.String...); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setInvalidatedByBiometricEnrollment(boolean); keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java +24 −4 Original line number Diff line number Diff line Loading @@ -17,11 +17,10 @@ package android.security.keystore; import android.annotation.Nullable; import android.os.Build; import android.security.Credentials; import android.security.GateKeeper; import android.security.KeyPairGeneratorSpec; import android.security.KeyStore; import android.security.KeyStoreException; import android.security.keymaster.KeyCharacteristics; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterCertificateChain; Loading Loading @@ -52,6 +51,7 @@ import libcore.util.EmptyArray; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; Loading Loading @@ -494,6 +494,20 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato if (challenge != null) { KeymasterArguments args = new KeymasterArguments(); args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_CHALLENGE, challenge); if (mSpec.isDevicePropertiesAttestationIncluded()) { args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_BRAND, Build.BRAND.getBytes(StandardCharsets.UTF_8)); args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_DEVICE, Build.DEVICE.getBytes(StandardCharsets.UTF_8)); args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_PRODUCT, Build.PRODUCT.getBytes(StandardCharsets.UTF_8)); args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_MANUFACTURER, Build.MANUFACTURER.getBytes(StandardCharsets.UTF_8)); args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_MODEL, Build.MODEL.getBytes(StandardCharsets.UTF_8)); } return getAttestationChain(privateKeyAlias, keyPair, args); } Loading Loading @@ -603,8 +617,14 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato private Iterable<byte[]> getAttestationChain(String privateKeyAlias, KeyPair keyPair, KeymasterArguments args) throws ProviderException { KeymasterCertificateChain outChain = new KeymasterCertificateChain(); int errorCode = mKeyStore.attestKey(privateKeyAlias, args, outChain); final KeymasterCertificateChain outChain = new KeymasterCertificateChain(); final int errorCode; if (mSpec.isDevicePropertiesAttestationIncluded() && mSpec.getAttestationChallenge() == null) { throw new ProviderException("An attestation challenge must be provided when requesting " + "device properties attestation."); } errorCode = mKeyStore.attestKey(privateKeyAlias, args, outChain); if (errorCode != KeyStore.NO_ERROR) { throw new ProviderException("Failed to generate attestation certificate chain", KeyStore.getKeyStoreException(errorCode)); Loading keystore/java/android/security/keystore/KeyGenParameterSpec.java +48 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.app.KeyguardManager; import android.compat.annotation.UnsupportedAppUsage; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricPrompt; import android.os.Build; import android.security.GateKeeper; import android.security.KeyStore; import android.text.TextUtils; Loading Loading @@ -264,6 +265,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu private final int mUserAuthenticationValidityDurationSeconds; private final boolean mUserPresenceRequired; private final byte[] mAttestationChallenge; private final boolean mDevicePropertiesAttestationIncluded; private final boolean mUniqueIdIncluded; private final boolean mUserAuthenticationValidWhileOnBody; private final boolean mInvalidatedByBiometricEnrollment; Loading Loading @@ -301,6 +303,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu int userAuthenticationValidityDurationSeconds, boolean userPresenceRequired, byte[] attestationChallenge, boolean devicePropertiesAttestationIncluded, boolean uniqueIdIncluded, boolean userAuthenticationValidWhileOnBody, boolean invalidatedByBiometricEnrollment, Loading Loading @@ -350,6 +353,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mUserPresenceRequired = userPresenceRequired; mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds; mAttestationChallenge = Utils.cloneIfNotNull(attestationChallenge); mDevicePropertiesAttestationIncluded = devicePropertiesAttestationIncluded; mUniqueIdIncluded = uniqueIdIncluded; mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody; mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment; Loading Loading @@ -643,6 +647,21 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu return Utils.cloneIfNotNull(mAttestationChallenge); } /** * Returns {@code true} if attestation for the base device properties ({@link Build#BRAND}, * {@link Build#DEVICE}, {@link Build#MANUFACTURER}, {@link Build#MODEL}, {@link Build#PRODUCT}) * was requested to be added in the attestation certificate for the generated key. * * {@link javax.crypto.KeyGenerator#generateKey()} will throw * {@link java.security.ProviderException} if device properties attestation fails or is not * supported. * * @see Builder#setDevicePropertiesAttestationIncluded(boolean) */ public boolean isDevicePropertiesAttestationIncluded() { return mDevicePropertiesAttestationIncluded; } /** * @hide This is a system-only API * Loading Loading @@ -734,6 +753,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu private int mUserAuthenticationValidityDurationSeconds = -1; private boolean mUserPresenceRequired = false; private byte[] mAttestationChallenge = null; private boolean mDevicePropertiesAttestationIncluded = false; private boolean mUniqueIdIncluded = false; private boolean mUserAuthenticationValidWhileOnBody; private boolean mInvalidatedByBiometricEnrollment = true; Loading Loading @@ -797,6 +817,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu sourceSpec.getUserAuthenticationValidityDurationSeconds(); mUserPresenceRequired = sourceSpec.isUserPresenceRequired(); mAttestationChallenge = sourceSpec.getAttestationChallenge(); mDevicePropertiesAttestationIncluded = sourceSpec.isDevicePropertiesAttestationIncluded(); mUniqueIdIncluded = sourceSpec.isUniqueIdIncluded(); mUserAuthenticationValidWhileOnBody = sourceSpec.isUserAuthenticationValidWhileOnBody(); mInvalidatedByBiometricEnrollment = sourceSpec.isInvalidatedByBiometricEnrollment(); Loading Loading @@ -1251,6 +1273,31 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu return this; } /** * Sets whether to include the base device properties in the attestation certificate. * * <p>If {@code attestationChallenge} is not {@code null}, the public key certificate for * this key pair will contain an extension that describes the details of the key's * configuration and authorizations, including the device properties values (brand, device, * manufacturer, model, product). These should be the same as in ({@link Build#BRAND}, * {@link Build#DEVICE}, {@link Build#MANUFACTURER}, {@link Build#MODEL}, * {@link Build#PRODUCT}). The attestation certificate chain can * be retrieved with {@link java.security.KeyStore#getCertificateChain(String)}. * * <p> If {@code attestationChallenge} is {@code null}, the public key certificate for * this key pair will not contain the extension with the requested attested values. * * <p> {@link javax.crypto.KeyGenerator#generateKey()} will throw * {@link java.security.ProviderException} if device properties attestation fails or is not * supported. */ @NonNull public Builder setDevicePropertiesAttestationIncluded( boolean devicePropertiesAttestationIncluded) { mDevicePropertiesAttestationIncluded = devicePropertiesAttestationIncluded; return this; } /** * @hide Only system apps can use this method. * Loading Loading @@ -1360,6 +1407,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mUserAuthenticationValidityDurationSeconds, mUserPresenceRequired, mAttestationChallenge, mDevicePropertiesAttestationIncluded, mUniqueIdIncluded, mUserAuthenticationValidWhileOnBody, mInvalidatedByBiometricEnrollment, Loading keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java +4 −1 Original line number Diff line number Diff line Loading @@ -16,8 +16,8 @@ package android.security.keystore; import android.os.Parcelable; import android.os.Parcel; import android.os.Parcelable; import java.math.BigInteger; import java.security.spec.AlgorithmParameterSpec; Loading Loading @@ -99,6 +99,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { out.writeInt(mSpec.getUserAuthenticationValidityDurationSeconds()); out.writeBoolean(mSpec.isUserPresenceRequired()); out.writeByteArray(mSpec.getAttestationChallenge()); out.writeBoolean(mSpec.isDevicePropertiesAttestationIncluded()); out.writeBoolean(mSpec.isUniqueIdIncluded()); out.writeBoolean(mSpec.isUserAuthenticationValidWhileOnBody()); out.writeBoolean(mSpec.isInvalidatedByBiometricEnrollment()); Loading Loading @@ -154,6 +155,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { final int userAuthenticationValidityDurationSeconds = in.readInt(); final boolean userPresenceRequired = in.readBoolean(); final byte[] attestationChallenge = in.createByteArray(); final boolean devicePropertiesAttestationIncluded = in.readBoolean(); final boolean uniqueIdIncluded = in.readBoolean(); final boolean userAuthenticationValidWhileOnBody = in.readBoolean(); final boolean invalidatedByBiometricEnrollment = in.readBoolean(); Loading Loading @@ -185,6 +187,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { userAuthenticationValidityDurationSeconds, userPresenceRequired, attestationChallenge, devicePropertiesAttestationIncluded, uniqueIdIncluded, userAuthenticationValidWhileOnBody, invalidatedByBiometricEnrollment, Loading Loading
api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -41304,6 +41304,7 @@ package android.security.keystore { method public int getPurposes(); method @NonNull public String[] getSignaturePaddings(); method public int getUserAuthenticationValidityDurationSeconds(); method public boolean isDevicePropertiesAttestationIncluded(); method @NonNull public boolean isDigestsSpecified(); method public boolean isInvalidatedByBiometricEnrollment(); method public boolean isRandomizedEncryptionRequired(); Loading @@ -41325,6 +41326,7 @@ package android.security.keystore { method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotBefore(@NonNull java.util.Date); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSerialNumber(@NonNull java.math.BigInteger); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSubject(@NonNull javax.security.auth.x500.X500Principal); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setDevicePropertiesAttestationIncluded(boolean); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setDigests(java.lang.String...); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setEncryptionPaddings(java.lang.String...); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setInvalidatedByBiometricEnrollment(boolean);
keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java +24 −4 Original line number Diff line number Diff line Loading @@ -17,11 +17,10 @@ package android.security.keystore; import android.annotation.Nullable; import android.os.Build; import android.security.Credentials; import android.security.GateKeeper; import android.security.KeyPairGeneratorSpec; import android.security.KeyStore; import android.security.KeyStoreException; import android.security.keymaster.KeyCharacteristics; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterCertificateChain; Loading Loading @@ -52,6 +51,7 @@ import libcore.util.EmptyArray; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; Loading Loading @@ -494,6 +494,20 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato if (challenge != null) { KeymasterArguments args = new KeymasterArguments(); args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_CHALLENGE, challenge); if (mSpec.isDevicePropertiesAttestationIncluded()) { args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_BRAND, Build.BRAND.getBytes(StandardCharsets.UTF_8)); args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_DEVICE, Build.DEVICE.getBytes(StandardCharsets.UTF_8)); args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_PRODUCT, Build.PRODUCT.getBytes(StandardCharsets.UTF_8)); args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_MANUFACTURER, Build.MANUFACTURER.getBytes(StandardCharsets.UTF_8)); args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_MODEL, Build.MODEL.getBytes(StandardCharsets.UTF_8)); } return getAttestationChain(privateKeyAlias, keyPair, args); } Loading Loading @@ -603,8 +617,14 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato private Iterable<byte[]> getAttestationChain(String privateKeyAlias, KeyPair keyPair, KeymasterArguments args) throws ProviderException { KeymasterCertificateChain outChain = new KeymasterCertificateChain(); int errorCode = mKeyStore.attestKey(privateKeyAlias, args, outChain); final KeymasterCertificateChain outChain = new KeymasterCertificateChain(); final int errorCode; if (mSpec.isDevicePropertiesAttestationIncluded() && mSpec.getAttestationChallenge() == null) { throw new ProviderException("An attestation challenge must be provided when requesting " + "device properties attestation."); } errorCode = mKeyStore.attestKey(privateKeyAlias, args, outChain); if (errorCode != KeyStore.NO_ERROR) { throw new ProviderException("Failed to generate attestation certificate chain", KeyStore.getKeyStoreException(errorCode)); Loading
keystore/java/android/security/keystore/KeyGenParameterSpec.java +48 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.app.KeyguardManager; import android.compat.annotation.UnsupportedAppUsage; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricPrompt; import android.os.Build; import android.security.GateKeeper; import android.security.KeyStore; import android.text.TextUtils; Loading Loading @@ -264,6 +265,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu private final int mUserAuthenticationValidityDurationSeconds; private final boolean mUserPresenceRequired; private final byte[] mAttestationChallenge; private final boolean mDevicePropertiesAttestationIncluded; private final boolean mUniqueIdIncluded; private final boolean mUserAuthenticationValidWhileOnBody; private final boolean mInvalidatedByBiometricEnrollment; Loading Loading @@ -301,6 +303,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu int userAuthenticationValidityDurationSeconds, boolean userPresenceRequired, byte[] attestationChallenge, boolean devicePropertiesAttestationIncluded, boolean uniqueIdIncluded, boolean userAuthenticationValidWhileOnBody, boolean invalidatedByBiometricEnrollment, Loading Loading @@ -350,6 +353,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mUserPresenceRequired = userPresenceRequired; mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds; mAttestationChallenge = Utils.cloneIfNotNull(attestationChallenge); mDevicePropertiesAttestationIncluded = devicePropertiesAttestationIncluded; mUniqueIdIncluded = uniqueIdIncluded; mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody; mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment; Loading Loading @@ -643,6 +647,21 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu return Utils.cloneIfNotNull(mAttestationChallenge); } /** * Returns {@code true} if attestation for the base device properties ({@link Build#BRAND}, * {@link Build#DEVICE}, {@link Build#MANUFACTURER}, {@link Build#MODEL}, {@link Build#PRODUCT}) * was requested to be added in the attestation certificate for the generated key. * * {@link javax.crypto.KeyGenerator#generateKey()} will throw * {@link java.security.ProviderException} if device properties attestation fails or is not * supported. * * @see Builder#setDevicePropertiesAttestationIncluded(boolean) */ public boolean isDevicePropertiesAttestationIncluded() { return mDevicePropertiesAttestationIncluded; } /** * @hide This is a system-only API * Loading Loading @@ -734,6 +753,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu private int mUserAuthenticationValidityDurationSeconds = -1; private boolean mUserPresenceRequired = false; private byte[] mAttestationChallenge = null; private boolean mDevicePropertiesAttestationIncluded = false; private boolean mUniqueIdIncluded = false; private boolean mUserAuthenticationValidWhileOnBody; private boolean mInvalidatedByBiometricEnrollment = true; Loading Loading @@ -797,6 +817,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu sourceSpec.getUserAuthenticationValidityDurationSeconds(); mUserPresenceRequired = sourceSpec.isUserPresenceRequired(); mAttestationChallenge = sourceSpec.getAttestationChallenge(); mDevicePropertiesAttestationIncluded = sourceSpec.isDevicePropertiesAttestationIncluded(); mUniqueIdIncluded = sourceSpec.isUniqueIdIncluded(); mUserAuthenticationValidWhileOnBody = sourceSpec.isUserAuthenticationValidWhileOnBody(); mInvalidatedByBiometricEnrollment = sourceSpec.isInvalidatedByBiometricEnrollment(); Loading Loading @@ -1251,6 +1273,31 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu return this; } /** * Sets whether to include the base device properties in the attestation certificate. * * <p>If {@code attestationChallenge} is not {@code null}, the public key certificate for * this key pair will contain an extension that describes the details of the key's * configuration and authorizations, including the device properties values (brand, device, * manufacturer, model, product). These should be the same as in ({@link Build#BRAND}, * {@link Build#DEVICE}, {@link Build#MANUFACTURER}, {@link Build#MODEL}, * {@link Build#PRODUCT}). The attestation certificate chain can * be retrieved with {@link java.security.KeyStore#getCertificateChain(String)}. * * <p> If {@code attestationChallenge} is {@code null}, the public key certificate for * this key pair will not contain the extension with the requested attested values. * * <p> {@link javax.crypto.KeyGenerator#generateKey()} will throw * {@link java.security.ProviderException} if device properties attestation fails or is not * supported. */ @NonNull public Builder setDevicePropertiesAttestationIncluded( boolean devicePropertiesAttestationIncluded) { mDevicePropertiesAttestationIncluded = devicePropertiesAttestationIncluded; return this; } /** * @hide Only system apps can use this method. * Loading Loading @@ -1360,6 +1407,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mUserAuthenticationValidityDurationSeconds, mUserPresenceRequired, mAttestationChallenge, mDevicePropertiesAttestationIncluded, mUniqueIdIncluded, mUserAuthenticationValidWhileOnBody, mInvalidatedByBiometricEnrollment, Loading
keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java +4 −1 Original line number Diff line number Diff line Loading @@ -16,8 +16,8 @@ package android.security.keystore; import android.os.Parcelable; import android.os.Parcel; import android.os.Parcelable; import java.math.BigInteger; import java.security.spec.AlgorithmParameterSpec; Loading Loading @@ -99,6 +99,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { out.writeInt(mSpec.getUserAuthenticationValidityDurationSeconds()); out.writeBoolean(mSpec.isUserPresenceRequired()); out.writeByteArray(mSpec.getAttestationChallenge()); out.writeBoolean(mSpec.isDevicePropertiesAttestationIncluded()); out.writeBoolean(mSpec.isUniqueIdIncluded()); out.writeBoolean(mSpec.isUserAuthenticationValidWhileOnBody()); out.writeBoolean(mSpec.isInvalidatedByBiometricEnrollment()); Loading Loading @@ -154,6 +155,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { final int userAuthenticationValidityDurationSeconds = in.readInt(); final boolean userPresenceRequired = in.readBoolean(); final byte[] attestationChallenge = in.createByteArray(); final boolean devicePropertiesAttestationIncluded = in.readBoolean(); final boolean uniqueIdIncluded = in.readBoolean(); final boolean userAuthenticationValidWhileOnBody = in.readBoolean(); final boolean invalidatedByBiometricEnrollment = in.readBoolean(); Loading Loading @@ -185,6 +187,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { userAuthenticationValidityDurationSeconds, userPresenceRequired, attestationChallenge, devicePropertiesAttestationIncluded, uniqueIdIncluded, userAuthenticationValidWhileOnBody, invalidatedByBiometricEnrollment, Loading