Merge "Attest device base properties"
This commit is contained in:
@@ -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();
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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,
|
||||
@@ -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;
|
||||
@@ -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
|
||||
*
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
@@ -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.
|
||||
*
|
||||
@@ -1360,6 +1407,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
||||
mUserAuthenticationValidityDurationSeconds,
|
||||
mUserPresenceRequired,
|
||||
mAttestationChallenge,
|
||||
mDevicePropertiesAttestationIncluded,
|
||||
mUniqueIdIncluded,
|
||||
mUserAuthenticationValidWhileOnBody,
|
||||
mInvalidatedByBiometricEnrollment,
|
||||
|
||||
@@ -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;
|
||||
@@ -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());
|
||||
@@ -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();
|
||||
@@ -185,6 +187,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable {
|
||||
userAuthenticationValidityDurationSeconds,
|
||||
userPresenceRequired,
|
||||
attestationChallenge,
|
||||
devicePropertiesAttestationIncluded,
|
||||
uniqueIdIncluded,
|
||||
userAuthenticationValidWhileOnBody,
|
||||
invalidatedByBiometricEnrollment,
|
||||
|
||||
Reference in New Issue
Block a user