Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2c9212f authored by Dorin Drimus's avatar Dorin Drimus Committed by Automerger Merge Worker
Browse files

Merge "Attest device base properties" am: 547aeb27 am: f078d499 am: c5a547bb am: 9acc5b49

Change-Id: Iea656ac64cde6ddff6d0040d9f9c96f052166545
parents b662e8f3 9acc5b49
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -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);
+24 −2
Original line number Original line Diff line number Diff line
@@ -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));
+48 −0
Original line number Original line Diff line number Diff line
@@ -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,
+3 −0
Original line number Original line Diff line number Diff line
@@ -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,