Merge "Attest device base properties" am: 547aeb27e8 am: f078d49979 am: c5a547bb2b am: 9acc5b49d5
Change-Id: Iea656ac64cde6ddff6d0040d9f9c96f052166545
This commit is contained in:
@@ -42745,6 +42745,7 @@ package android.security.keystore {
|
|||||||
method @NonNull public String[] getSignaturePaddings();
|
method @NonNull public String[] getSignaturePaddings();
|
||||||
method public int getUserAuthenticationType();
|
method public int getUserAuthenticationType();
|
||||||
method public int getUserAuthenticationValidityDurationSeconds();
|
method public int getUserAuthenticationValidityDurationSeconds();
|
||||||
|
method public boolean isDevicePropertiesAttestationIncluded();
|
||||||
method @NonNull public boolean isDigestsSpecified();
|
method @NonNull public boolean isDigestsSpecified();
|
||||||
method public boolean isInvalidatedByBiometricEnrollment();
|
method public boolean isInvalidatedByBiometricEnrollment();
|
||||||
method public boolean isRandomizedEncryptionRequired();
|
method public boolean isRandomizedEncryptionRequired();
|
||||||
@@ -42766,6 +42767,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 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 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 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 setDigests(java.lang.String...);
|
||||||
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setEncryptionPaddings(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);
|
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setInvalidatedByBiometricEnrollment(boolean);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package android.security.keystore;
|
package android.security.keystore;
|
||||||
|
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.os.Build;
|
||||||
import android.security.Credentials;
|
import android.security.Credentials;
|
||||||
import android.security.KeyPairGeneratorSpec;
|
import android.security.KeyPairGeneratorSpec;
|
||||||
import android.security.KeyStore;
|
import android.security.KeyStore;
|
||||||
@@ -50,6 +51,7 @@ import libcore.util.EmptyArray;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.KeyPairGenerator;
|
import java.security.KeyPairGenerator;
|
||||||
@@ -495,6 +497,20 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
|
|||||||
if (challenge != null) {
|
if (challenge != null) {
|
||||||
KeymasterArguments args = new KeymasterArguments();
|
KeymasterArguments args = new KeymasterArguments();
|
||||||
args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_CHALLENGE, challenge);
|
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);
|
return getAttestationChain(privateKeyAlias, keyPair, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,8 +620,14 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
|
|||||||
private Iterable<byte[]> getAttestationChain(String privateKeyAlias,
|
private Iterable<byte[]> getAttestationChain(String privateKeyAlias,
|
||||||
KeyPair keyPair, KeymasterArguments args)
|
KeyPair keyPair, KeymasterArguments args)
|
||||||
throws ProviderException {
|
throws ProviderException {
|
||||||
KeymasterCertificateChain outChain = new KeymasterCertificateChain();
|
final KeymasterCertificateChain outChain = new KeymasterCertificateChain();
|
||||||
int errorCode = mKeyStore.attestKey(privateKeyAlias, args, outChain);
|
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) {
|
if (errorCode != KeyStore.NO_ERROR) {
|
||||||
throw new ProviderException("Failed to generate attestation certificate chain",
|
throw new ProviderException("Failed to generate attestation certificate chain",
|
||||||
KeyStore.getKeyStoreException(errorCode));
|
KeyStore.getKeyStoreException(errorCode));
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import android.app.KeyguardManager;
|
|||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
import android.hardware.biometrics.BiometricManager;
|
import android.hardware.biometrics.BiometricManager;
|
||||||
import android.hardware.biometrics.BiometricPrompt;
|
import android.hardware.biometrics.BiometricPrompt;
|
||||||
|
import android.os.Build;
|
||||||
import android.security.GateKeeper;
|
import android.security.GateKeeper;
|
||||||
import android.security.KeyStore;
|
import android.security.KeyStore;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -266,6 +267,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
|||||||
private final @KeyProperties.AuthEnum int mUserAuthenticationType;
|
private final @KeyProperties.AuthEnum int mUserAuthenticationType;
|
||||||
private final boolean mUserPresenceRequired;
|
private final boolean mUserPresenceRequired;
|
||||||
private final byte[] mAttestationChallenge;
|
private final byte[] mAttestationChallenge;
|
||||||
|
private final boolean mDevicePropertiesAttestationIncluded;
|
||||||
private final boolean mUniqueIdIncluded;
|
private final boolean mUniqueIdIncluded;
|
||||||
private final boolean mUserAuthenticationValidWhileOnBody;
|
private final boolean mUserAuthenticationValidWhileOnBody;
|
||||||
private final boolean mInvalidatedByBiometricEnrollment;
|
private final boolean mInvalidatedByBiometricEnrollment;
|
||||||
@@ -305,6 +307,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
|||||||
@KeyProperties.AuthEnum int userAuthenticationType,
|
@KeyProperties.AuthEnum int userAuthenticationType,
|
||||||
boolean userPresenceRequired,
|
boolean userPresenceRequired,
|
||||||
byte[] attestationChallenge,
|
byte[] attestationChallenge,
|
||||||
|
boolean devicePropertiesAttestationIncluded,
|
||||||
boolean uniqueIdIncluded,
|
boolean uniqueIdIncluded,
|
||||||
boolean userAuthenticationValidWhileOnBody,
|
boolean userAuthenticationValidWhileOnBody,
|
||||||
boolean invalidatedByBiometricEnrollment,
|
boolean invalidatedByBiometricEnrollment,
|
||||||
@@ -356,6 +359,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
|||||||
mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
|
mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
|
||||||
mUserAuthenticationType = userAuthenticationType;
|
mUserAuthenticationType = userAuthenticationType;
|
||||||
mAttestationChallenge = Utils.cloneIfNotNull(attestationChallenge);
|
mAttestationChallenge = Utils.cloneIfNotNull(attestationChallenge);
|
||||||
|
mDevicePropertiesAttestationIncluded = devicePropertiesAttestationIncluded;
|
||||||
mUniqueIdIncluded = uniqueIdIncluded;
|
mUniqueIdIncluded = uniqueIdIncluded;
|
||||||
mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody;
|
mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody;
|
||||||
mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
|
mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
|
||||||
@@ -666,6 +670,21 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
|||||||
return Utils.cloneIfNotNull(mAttestationChallenge);
|
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
|
* @hide This is a system-only API
|
||||||
*
|
*
|
||||||
@@ -769,6 +788,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
|||||||
KeyProperties.AUTH_BIOMETRIC_STRONG;
|
KeyProperties.AUTH_BIOMETRIC_STRONG;
|
||||||
private boolean mUserPresenceRequired = false;
|
private boolean mUserPresenceRequired = false;
|
||||||
private byte[] mAttestationChallenge = null;
|
private byte[] mAttestationChallenge = null;
|
||||||
|
private boolean mDevicePropertiesAttestationIncluded = false;
|
||||||
private boolean mUniqueIdIncluded = false;
|
private boolean mUniqueIdIncluded = false;
|
||||||
private boolean mUserAuthenticationValidWhileOnBody;
|
private boolean mUserAuthenticationValidWhileOnBody;
|
||||||
private boolean mInvalidatedByBiometricEnrollment = true;
|
private boolean mInvalidatedByBiometricEnrollment = true;
|
||||||
@@ -834,6 +854,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
|||||||
mUserAuthenticationType = sourceSpec.getUserAuthenticationType();
|
mUserAuthenticationType = sourceSpec.getUserAuthenticationType();
|
||||||
mUserPresenceRequired = sourceSpec.isUserPresenceRequired();
|
mUserPresenceRequired = sourceSpec.isUserPresenceRequired();
|
||||||
mAttestationChallenge = sourceSpec.getAttestationChallenge();
|
mAttestationChallenge = sourceSpec.getAttestationChallenge();
|
||||||
|
mDevicePropertiesAttestationIncluded =
|
||||||
|
sourceSpec.isDevicePropertiesAttestationIncluded();
|
||||||
mUniqueIdIncluded = sourceSpec.isUniqueIdIncluded();
|
mUniqueIdIncluded = sourceSpec.isUniqueIdIncluded();
|
||||||
mUserAuthenticationValidWhileOnBody = sourceSpec.isUserAuthenticationValidWhileOnBody();
|
mUserAuthenticationValidWhileOnBody = sourceSpec.isUserAuthenticationValidWhileOnBody();
|
||||||
mInvalidatedByBiometricEnrollment = sourceSpec.isInvalidatedByBiometricEnrollment();
|
mInvalidatedByBiometricEnrollment = sourceSpec.isInvalidatedByBiometricEnrollment();
|
||||||
@@ -1339,6 +1361,31 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
|||||||
return this;
|
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.
|
* @hide Only system apps can use this method.
|
||||||
*
|
*
|
||||||
@@ -1463,6 +1510,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
|||||||
mUserAuthenticationType,
|
mUserAuthenticationType,
|
||||||
mUserPresenceRequired,
|
mUserPresenceRequired,
|
||||||
mAttestationChallenge,
|
mAttestationChallenge,
|
||||||
|
mDevicePropertiesAttestationIncluded,
|
||||||
mUniqueIdIncluded,
|
mUniqueIdIncluded,
|
||||||
mUserAuthenticationValidWhileOnBody,
|
mUserAuthenticationValidWhileOnBody,
|
||||||
mInvalidatedByBiometricEnrollment,
|
mInvalidatedByBiometricEnrollment,
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable {
|
|||||||
out.writeInt(mSpec.getUserAuthenticationType());
|
out.writeInt(mSpec.getUserAuthenticationType());
|
||||||
out.writeBoolean(mSpec.isUserPresenceRequired());
|
out.writeBoolean(mSpec.isUserPresenceRequired());
|
||||||
out.writeByteArray(mSpec.getAttestationChallenge());
|
out.writeByteArray(mSpec.getAttestationChallenge());
|
||||||
|
out.writeBoolean(mSpec.isDevicePropertiesAttestationIncluded());
|
||||||
out.writeBoolean(mSpec.isUniqueIdIncluded());
|
out.writeBoolean(mSpec.isUniqueIdIncluded());
|
||||||
out.writeBoolean(mSpec.isUserAuthenticationValidWhileOnBody());
|
out.writeBoolean(mSpec.isUserAuthenticationValidWhileOnBody());
|
||||||
out.writeBoolean(mSpec.isInvalidatedByBiometricEnrollment());
|
out.writeBoolean(mSpec.isInvalidatedByBiometricEnrollment());
|
||||||
@@ -157,6 +158,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable {
|
|||||||
final int userAuthenticationTypes = in.readInt();
|
final int userAuthenticationTypes = in.readInt();
|
||||||
final boolean userPresenceRequired = in.readBoolean();
|
final boolean userPresenceRequired = in.readBoolean();
|
||||||
final byte[] attestationChallenge = in.createByteArray();
|
final byte[] attestationChallenge = in.createByteArray();
|
||||||
|
final boolean devicePropertiesAttestationIncluded = in.readBoolean();
|
||||||
final boolean uniqueIdIncluded = in.readBoolean();
|
final boolean uniqueIdIncluded = in.readBoolean();
|
||||||
final boolean userAuthenticationValidWhileOnBody = in.readBoolean();
|
final boolean userAuthenticationValidWhileOnBody = in.readBoolean();
|
||||||
final boolean invalidatedByBiometricEnrollment = in.readBoolean();
|
final boolean invalidatedByBiometricEnrollment = in.readBoolean();
|
||||||
@@ -190,6 +192,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable {
|
|||||||
userAuthenticationTypes,
|
userAuthenticationTypes,
|
||||||
userPresenceRequired,
|
userPresenceRequired,
|
||||||
attestationChallenge,
|
attestationChallenge,
|
||||||
|
devicePropertiesAttestationIncluded,
|
||||||
uniqueIdIncluded,
|
uniqueIdIncluded,
|
||||||
userAuthenticationValidWhileOnBody,
|
userAuthenticationValidWhileOnBody,
|
||||||
invalidatedByBiometricEnrollment,
|
invalidatedByBiometricEnrollment,
|
||||||
|
|||||||
Reference in New Issue
Block a user