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

Commit 09b15d5b authored by Alex Klyubin's avatar Alex Klyubin Committed by Android (Google) Code Review
Browse files

Merge "Add NonNull and Nullable annotations to AndroidKeyStore API." into mnc-dev

parents 5fccffd5 54bb1596
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
package android.security;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -127,6 +129,7 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
     * Returns KEM KDF algorithm (e.g., {@code HKDFwithSHA256} or {@code KDF1withSHA1}) or
     * {@code null} if not specified.
     */
    @Nullable
    public String getKemKdfAlgorithm() {
        return mKemKdfAlgorithm;
    }
@@ -138,6 +141,7 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
     * @see Cipher#getInstance(String)
     * @see #getDemCipherKeySize()
     */
    @Nullable
    public String getDemCipherTransformation() {
        return mDemCipherTransformation;
    }
@@ -158,6 +162,7 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
     * @see Mac#getInstance(String)
     * @see #getDemMacKeySize()
     */
    @Nullable
    public String getDemMacAlgorithm() {
        return mDemMacAlgorithm;
    }
@@ -194,7 +199,8 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
         * Sets KEM KDF algorithm. For example, {@code HKDFwithSHA256}, {@code KDF2withSHA256}, or
         * {@code KDF1withSHA1}.
         */
        public Builder setKemKdfAlgorithm(String algorithm) {
        @NonNull
        public Builder setKemKdfAlgorithm(@Nullable String algorithm) {
            mKemKdfAlgorithm = algorithm;
            return this;
        }
@@ -205,7 +211,8 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
         *
         * @see Cipher#getInstance(String)
         */
        public Builder setDemCipherTransformation(String transformation) {
        @NonNull
        public Builder setDemCipherTransformation(@Nullable String transformation) {
            mDemCipherTransformation = transformation;
            return this;
        }
@@ -217,6 +224,7 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
         *
         * @see #setDemCipherTransformation(String)
         */
        @NonNull
        public Builder setDemCipherKeySize(int sizeBits) {
            mDemCipherKeySize = sizeBits;
            return this;
@@ -227,7 +235,8 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
         *
         * @see Mac#getInstance(String)
         */
        public Builder setDemMacAlgorithm(String algorithm) {
        @NonNull
        public Builder setDemMacAlgorithm(@Nullable String algorithm) {
            mDemMacAlgorithm = algorithm;
            return this;
        }
@@ -239,6 +248,7 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
         *
         * @see #setDemCipherKeySize(int)
         */
        @NonNull
        public Builder setDemMacKeySize(int sizeBits) {
            mDemMacKeySize = sizeBits;
            return this;
@@ -247,6 +257,7 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
        /**
         * Returns a new {@link EcIesParameterSpec} based on the current state of this builder.
         */
        @NonNull
        public EcIesParameterSpec build() {
            int demMacKeySize = (mDemMacKeySize != -1) ? mDemMacKeySize : mDemCipherKeySize;
            return new EcIesParameterSpec(
+21 −13
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 */
package android.security;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.ComponentName;
@@ -217,6 +219,7 @@ public final class KeyChain {
     * successfully installed, otherwise {@link
     * Activity#RESULT_CANCELED} will be returned.
     */
    @NonNull
    public static Intent createInstallIntent() {
        Intent intent = new Intent(ACTION_INSTALL);
        intent.setClassName(CERT_INSTALLER_PACKAGE,
@@ -261,9 +264,10 @@ public final class KeyChain {
     * @param alias The alias to preselect if available, or null if
     *     unavailable.
     */
    public static void choosePrivateKeyAlias(Activity activity, KeyChainAliasCallback response,
    public static void choosePrivateKeyAlias(@NonNull Activity activity,
            @NonNull KeyChainAliasCallback response,
            @KeyStoreKeyProperties.AlgorithmEnum String[] keyTypes, Principal[] issuers,
            String host, int port, String alias) {
            @Nullable String host, int port, @Nullable String alias) {
        choosePrivateKeyAlias(activity, response, keyTypes, issuers, host, port, null, alias);
    }

@@ -306,9 +310,10 @@ public final class KeyChain {
     * @param alias The alias to preselect if available, or null if
     *     unavailable.
     */
    public static void choosePrivateKeyAlias(Activity activity, KeyChainAliasCallback response,
    public static void choosePrivateKeyAlias(@NonNull Activity activity,
            @NonNull KeyChainAliasCallback response,
            @KeyStoreKeyProperties.AlgorithmEnum String[] keyTypes, Principal[] issuers,
            String host, int port, String url, String alias) {
            @Nullable String host, int port, @Nullable String url, @Nullable String alias) {
        /*
         * TODO currently keyTypes, issuers are unused. They are meant
         * to follow the semantics and purpose of X509KeyManager
@@ -361,7 +366,8 @@ public final class KeyChain {
     * returned via {@link KeyChainAliasCallback#alias}.
     * @throws KeyChainException if the alias was valid but there was some problem accessing it.
     */
    public static PrivateKey getPrivateKey(Context context, String alias)
    @Nullable
    public static PrivateKey getPrivateKey(@NonNull Context context, @NonNull String alias)
            throws KeyChainException, InterruptedException {
        if (alias == null) {
            throw new NullPointerException("alias == null");
@@ -396,8 +402,9 @@ public final class KeyChain {
     * returned via {@link KeyChainAliasCallback#alias}.
     * @throws KeyChainException if the alias was valid but there was some problem accessing it.
     */
    public static X509Certificate[] getCertificateChain(Context context, String alias)
            throws KeyChainException, InterruptedException {
    @Nullable
    public static X509Certificate[] getCertificateChain(@NonNull Context context,
            @NonNull String alias) throws KeyChainException, InterruptedException {
        if (alias == null) {
            throw new NullPointerException("alias == null");
        }
@@ -432,7 +439,7 @@ public final class KeyChain {
     * "RSA").
     */
    public static boolean isKeyAlgorithmSupported(
            @KeyStoreKeyProperties.AlgorithmEnum String algorithm) {
            @NonNull @KeyStoreKeyProperties.AlgorithmEnum String algorithm) {
        final String algUpper = algorithm.toUpperCase(Locale.US);
        return KeyStoreKeyProperties.Algorithm.EC.equals(algUpper)
                || KeyStoreKeyProperties.Algorithm.RSA.equals(algUpper);
@@ -446,7 +453,7 @@ public final class KeyChain {
     * that makes it non-exportable.
     */
    public static boolean isBoundKeyAlgorithm(
            @KeyStoreKeyProperties.AlgorithmEnum String algorithm) {
            @NonNull @KeyStoreKeyProperties.AlgorithmEnum String algorithm) {
        if (!isKeyAlgorithmSupported(algorithm)) {
            return false;
        }
@@ -455,7 +462,8 @@ public final class KeyChain {
    }

    /** @hide */
    public static X509Certificate toCertificate(byte[] bytes) {
    @NonNull
    public static X509Certificate toCertificate(@NonNull byte[] bytes) {
        if (bytes == null) {
            throw new IllegalArgumentException("bytes == null");
        }
@@ -496,14 +504,14 @@ public final class KeyChain {
     *
     * Caller should call unbindService on the result when finished.
     */
    public static KeyChainConnection bind(Context context) throws InterruptedException {
    public static KeyChainConnection bind(@NonNull Context context) throws InterruptedException {
        return bindAsUser(context, Process.myUserHandle());
    }

    /**
     * @hide
     */
    public static KeyChainConnection bindAsUser(Context context, UserHandle user)
    public static KeyChainConnection bindAsUser(@NonNull Context context, UserHandle user)
            throws InterruptedException {
        if (context == null) {
            throw new NullPointerException("context == null");
@@ -537,7 +545,7 @@ public final class KeyChain {
        return new KeyChainConnection(context, keyChainServiceConnection, q.take());
    }

    private static void ensureNotOnMainThread(Context context) {
    private static void ensureNotOnMainThread(@NonNull Context context) {
        Looper looper = Looper.myLooper();
        if (looper != null && looper == context.getMainLooper()) {
            throw new IllegalStateException(
+3 −1
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 */
package android.security;

import android.annotation.Nullable;

/**
 * The KeyChainAliasCallback is the callback for {@link
 * KeyChain#choosePrivateKeyAlias}.
@@ -25,5 +27,5 @@ public interface KeyChainAliasCallback {
     * Called with the alias of the certificate chosen by the user, or
     * null if no value was chosen.
     */
    public void alias(String alias);
    public void alias(@Nullable String alias);
}
+26 −3
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package android.security;

import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.KeyguardManager;
import android.content.Context;
import android.text.TextUtils;
@@ -163,6 +166,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
     *
     * @return instant or {@code null} if not restricted.
     */
    @Nullable
    public Date getKeyValidityStart() {
        return mKeyValidityStart;
    }
@@ -172,6 +176,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
     *
     * @return instant or {@code null} if not restricted.
     */
    @Nullable
    public Date getKeyValidityForConsumptionEnd() {
        return mKeyValidityForConsumptionEnd;
    }
@@ -181,6 +186,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
     *
     * @return instant or {@code null} if not restricted.
     */
    @Nullable
    public Date getKeyValidityForOriginationEnd() {
        return mKeyValidityForOriginationEnd;
    }
@@ -195,6 +201,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
    /**
     * Gets the set of padding schemes with which the key can be used when encrypting/decrypting.
     */
    @NonNull
    public @KeyStoreKeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
        return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
    }
@@ -202,6 +209,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
    /**
     * Gets the set of block modes with which the key can be used.
     */
    @NonNull
    public @KeyStoreKeyProperties.BlockModeEnum String[] getBlockModes() {
        return ArrayUtils.cloneIfNotEmpty(mBlockModes);
    }
@@ -269,7 +277,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
         * {@code context} passed in may be used to pop up some UI to ask the user to unlock or
         * initialize the Android KeyStore facility.
         */
        public Builder(Context context) {
        public Builder(@NonNull Context context) {
            if (context == null) {
                throw new NullPointerException("context == null");
            }
@@ -282,7 +290,8 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
         *
         * <p>The alias must be provided. There is no default.
         */
        public Builder setAlias(String alias) {
        @NonNull
        public Builder setAlias(@NonNull String alias) {
            if (alias == null) {
                throw new NullPointerException("alias == null");
            }
@@ -296,6 +305,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
         * <p>By default, the key size will be determines based on the key algorithm. For example,
         * for {@code HmacSHA256}, the key size will default to {@code 256}.
         */
        @NonNull
        public Builder setKeySize(int keySize) {
            mKeySize = keySize;
            return this;
@@ -313,6 +323,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
         *
         * @see KeyguardManager#isDeviceSecure()
         */
        @NonNull
        public Builder setEncryptionRequired() {
            mFlags |= KeyStore.FLAG_ENCRYPTED;
            return this;
@@ -325,6 +336,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
         *
         * @see #setKeyValidityEnd(Date)
         */
        @NonNull
        public Builder setKeyValidityStart(Date startDate) {
            mKeyValidityStart = startDate;
            return this;
@@ -339,6 +351,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
         * @see #setKeyValidityForConsumptionEnd(Date)
         * @see #setKeyValidityForOriginationEnd(Date)
         */
        @NonNull
        public Builder setKeyValidityEnd(Date endDate) {
            setKeyValidityForOriginationEnd(endDate);
            setKeyValidityForConsumptionEnd(endDate);
@@ -352,6 +365,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
         *
         * @see #setKeyValidityForConsumptionEnd(Date)
         */
        @NonNull
        public Builder setKeyValidityForOriginationEnd(Date endDate) {
            mKeyValidityForOriginationEnd = endDate;
            return this;
@@ -365,6 +379,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
         *
         * @see #setKeyValidityForOriginationEnd(Date)
         */
        @NonNull
        public Builder setKeyValidityForConsumptionEnd(Date endDate) {
            mKeyValidityForConsumptionEnd = endDate;
            return this;
@@ -375,6 +390,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
         *
         * <p>This must be specified for all keys. There is no default.
         */
        @NonNull
        public Builder setPurposes(@KeyStoreKeyProperties.PurposeEnum int purposes) {
            mPurposes = purposes;
            return this;
@@ -387,6 +403,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
         *
         * <p>This must be specified for keys which are used for encryption/decryption.
         */
        @NonNull
        public Builder setEncryptionPaddings(
                @KeyStoreKeyProperties.EncryptionPaddingEnum String... paddings) {
            mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
@@ -399,6 +416,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
         *
         * <p>This must be specified for encryption/decryption keys.
         */
        @NonNull
        public Builder setBlockModes(@KeyStoreKeyProperties.BlockModeEnum String... blockModes) {
            mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
            return this;
@@ -436,6 +454,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
         * ciphertext.</li>
         * </ul>
         */
        @NonNull
        public Builder setRandomizedEncryptionRequired(boolean required) {
            mRandomizedEncryptionRequired = required;
            return this;
@@ -456,6 +475,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
         *
         * @see #setUserAuthenticationValidityDurationSeconds(int)
         */
        @NonNull
        public Builder setUserAuthenticationRequired(boolean required) {
            mUserAuthenticationRequired = required;
            return this;
@@ -472,7 +492,9 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
         *
         * @see #setUserAuthenticationRequired(boolean)
         */
        public Builder setUserAuthenticationValidityDurationSeconds(int seconds) {
        @NonNull
        public Builder setUserAuthenticationValidityDurationSeconds(
                @IntRange(from = -1) int seconds) {
            mUserAuthenticationValidityDurationSeconds = seconds;
            return this;
        }
@@ -482,6 +504,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
         *
         * @throws IllegalArgumentException if a required field is missing or violates a constraint.
         */
        @NonNull
        public KeyGeneratorSpec build() {
            return new KeyGeneratorSpec(mContext,
                    mKeystoreAlias,
+47 −9
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@
package android.security;

import android.app.KeyguardManager;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.text.TextUtils;

@@ -286,6 +289,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
    /**
     * Returns the key type (e.g., "EC", "RSA") specified by this parameter.
     */
    @Nullable
    public @KeyStoreKeyProperties.AlgorithmEnum String getKeyType() {
        return mKeyType;
    }
@@ -303,6 +307,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
     * Returns the {@link AlgorithmParameterSpec} that will be used for creation
     * of the key pair.
     */
    @NonNull
    public AlgorithmParameterSpec getAlgorithmParameterSpec() {
        return mSpec;
    }
@@ -311,6 +316,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
     * Gets the subject distinguished name to be used on the X.509 certificate
     * that will be put in the {@link java.security.KeyStore}.
     */
    @NonNull
    public X500Principal getSubjectDN() {
        return mSubjectDN;
    }
@@ -319,6 +325,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
     * Gets the serial number to be used on the X.509 certificate that will be
     * put in the {@link java.security.KeyStore}.
     */
    @NonNull
    public BigInteger getSerialNumber() {
        return mSerialNumber;
    }
@@ -327,6 +334,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
     * Gets the start date to be used on the X.509 certificate that will be put
     * in the {@link java.security.KeyStore}.
     */
    @NonNull
    public Date getStartDate() {
        return mStartDate;
    }
@@ -335,6 +343,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
     * Gets the end date to be used on the X.509 certificate that will be put in
     * the {@link java.security.KeyStore}.
     */
    @NonNull
    public Date getEndDate() {
        return mEndDate;
    }
@@ -359,6 +368,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
     *
     * @return instant or {@code null} if not restricted.
     */
    @Nullable
    public Date getKeyValidityStart() {
        return mKeyValidityStart;
    }
@@ -369,6 +379,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
     *
     * @return instant or {@code null} if not restricted.
     */
    @Nullable
    public Date getKeyValidityForConsumptionEnd() {
        return mKeyValidityForConsumptionEnd;
    }
@@ -378,6 +389,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
     *
     * @return instant or {@code null} if not restricted.
     */
    @Nullable
    public Date getKeyValidityForOriginationEnd() {
        return mKeyValidityForOriginationEnd;
    }
@@ -392,6 +404,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
    /**
     * Gets the set of digest algorithms with which the key can be used.
     */
    @NonNull
    public @KeyStoreKeyProperties.DigestEnum String[] getDigests() {
        return ArrayUtils.cloneIfNotEmpty(mDigests);
    }
@@ -399,6 +412,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
    /**
     * Gets the set of padding schemes with which the key can be used when encrypting/decrypting.
     */
    @NonNull
    public @KeyStoreKeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
        return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
    }
@@ -406,6 +420,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
    /**
     * Gets the set of padding schemes with which the key can be used when signing/verifying.
     */
    @NonNull
    public @KeyStoreKeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() {
        return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
    }
@@ -413,6 +428,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
    /**
     * Gets the set of block modes with which the key can be used.
     */
    @NonNull
    public @KeyStoreKeyProperties.BlockModeEnum String[] getBlockModes() {
        return ArrayUtils.cloneIfNotEmpty(mBlockModes);
    }
@@ -528,7 +544,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         * some UI to ask the user to unlock or initialize the Android KeyStore
         * facility.
         */
        public Builder(Context context) {
        public Builder(@NonNull Context context) {
            if (context == null) {
                throw new NullPointerException("context == null");
            }
@@ -540,7 +556,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         * {@link java.security.KeyStore} instance using the
         * {@code AndroidKeyStore} provider.
         */
        public Builder setAlias(String alias) {
        @NonNull
        public Builder setAlias(@NonNull String alias) {
            if (alias == null) {
                throw new NullPointerException("alias == null");
            }
@@ -551,7 +568,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
        /**
         * Sets the key type (e.g., EC, RSA) of the keypair to be created.
         */
        public Builder setKeyType(@KeyStoreKeyProperties.AlgorithmEnum String keyType)
        @NonNull
        public Builder setKeyType(@NonNull @KeyStoreKeyProperties.AlgorithmEnum String keyType)
                throws NoSuchAlgorithmException {
            if (keyType == null) {
                throw new NullPointerException("keyType == null");
@@ -569,6 +587,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         * key type of RSA this will set the modulus size and for a key type of
         * EC it will select a curve with a matching field size.
         */
        @NonNull
        public Builder setKeySize(int keySize) {
            if (keySize < 0) {
                throw new IllegalArgumentException("keySize < 0");
@@ -581,7 +600,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         * Sets the algorithm-specific key generation parameters. For example, for RSA keys
         * this may be an instance of {@link java.security.spec.RSAKeyGenParameterSpec}.
         */
        public Builder setAlgorithmParameterSpec(AlgorithmParameterSpec spec) {
        public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) {
            if (spec == null) {
                throw new NullPointerException("spec == null");
            }
@@ -597,7 +616,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1 LOLLIPOP_MR1} and older platforms. On
         * newer platforms the subject defaults to {@code CN=fake} if not specified.
         */
        public Builder setSubject(X500Principal subject) {
        @NonNull
        public Builder setSubject(@NonNull X500Principal subject) {
            if (subject == null) {
                throw new NullPointerException("subject == null");
            }
@@ -613,7 +633,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1 LOLLIPOP_MR1} and older platforms. On
         * newer platforms the serial number defaults to {@code 1} if not specified.
         */
        public Builder setSerialNumber(BigInteger serialNumber) {
        @NonNull
        public Builder setSerialNumber(@NonNull BigInteger serialNumber) {
            if (serialNumber == null) {
                throw new NullPointerException("serialNumber == null");
            }
@@ -629,7 +650,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1 LOLLIPOP_MR1} and older platforms. On
         * newer platforms the date defaults to {@code Jan 1 1970} if not specified.
         */
        public Builder setStartDate(Date startDate) {
        @NonNull
        public Builder setStartDate(@NonNull Date startDate) {
            if (startDate == null) {
                throw new NullPointerException("startDate == null");
            }
@@ -645,7 +667,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1 LOLLIPOP_MR1} and older platforms. On
         * newer platforms the date defaults to {@code Jan 1 2048} if not specified.
         */
        public Builder setEndDate(Date endDate) {
        @NonNull
        public Builder setEndDate(@NonNull Date endDate) {
            if (endDate == null) {
                throw new NullPointerException("endDate == null");
            }
@@ -665,6 +688,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         *
         * @see KeyguardManager#isDeviceSecure()
         */
        @NonNull
        public Builder setEncryptionRequired() {
            mFlags |= KeyStore.FLAG_ENCRYPTED;
            return this;
@@ -679,6 +703,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         *
         * @see #setKeyValidityEnd(Date)
         */
        @NonNull
        public Builder setKeyValidityStart(Date startDate) {
            mKeyValidityStart = startDate;
            return this;
@@ -695,6 +720,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         * @see #setKeyValidityForConsumptionEnd(Date)
         * @see #setKeyValidityForOriginationEnd(Date)
         */
        @NonNull
        public Builder setKeyValidityEnd(Date endDate) {
            setKeyValidityForOriginationEnd(endDate);
            setKeyValidityForConsumptionEnd(endDate);
@@ -710,6 +736,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         *
         * @see #setKeyValidityForConsumptionEnd(Date)
         */
        @NonNull
        public Builder setKeyValidityForOriginationEnd(Date endDate) {
            mKeyValidityForOriginationEnd = endDate;
            return this;
@@ -725,6 +752,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         *
         * @see #setKeyValidityForOriginationEnd(Date)
         */
        @NonNull
        public Builder setKeyValidityForConsumptionEnd(Date endDate) {
            mKeyValidityForConsumptionEnd = endDate;
            return this;
@@ -743,6 +771,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         *
         * <p><b>NOTE: This has currently no effect.
         */
        @NonNull
        public Builder setPurposes(@KeyStoreKeyProperties.PurposeEnum int purposes) {
            mPurposes = purposes;
            return this;
@@ -756,6 +785,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         *
         * <p><b>NOTE: This has currently no effect.
         */
        @NonNull
        public Builder setDigests(@KeyStoreKeyProperties.DigestEnum String... digests) {
            mDigests = ArrayUtils.cloneIfNotEmpty(digests);
            return this;
@@ -770,6 +800,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         *
         * <p><b>NOTE: This has currently no effect.
         */
        @NonNull
        public Builder setEncryptionPaddings(
                @KeyStoreKeyProperties.EncryptionPaddingEnum String... paddings) {
            mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
@@ -785,6 +816,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         *
         * <p><b>NOTE: This has currently no effect.
         */
        @NonNull
        public Builder setSignaturePaddings(
                @KeyStoreKeyProperties.SignaturePaddingEnum String... paddings) {
            mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings);
@@ -799,6 +831,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         *
         * <p><b>NOTE: This has currently no effect.
         */
        @NonNull
        public Builder setBlockModes(@KeyStoreKeyProperties.BlockModeEnum String... blockModes) {
            mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
            return this;
@@ -826,6 +859,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         *
         * <p><b>NOTE: This has currently no effect.
         */
        @NonNull
        public Builder setRandomizedEncryptionRequired(boolean required) {
            mRandomizedEncryptionRequired = required;
            return this;
@@ -851,6 +885,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         *
         * @see #setUserAuthenticationValidityDurationSeconds(int)
         */
        @NonNull
        public Builder setUserAuthenticationRequired(boolean required) {
            mUserAuthenticationRequired = required;
            return this;
@@ -872,7 +907,9 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         *
         * @see #setUserAuthenticationRequired(boolean)
         */
        public Builder setUserAuthenticationValidityDurationSeconds(int seconds) {
        @NonNull
        public Builder setUserAuthenticationValidityDurationSeconds(
                @IntRange(from = -1) int seconds) {
            mUserAuthenticationValidityDurationSeconds = seconds;
            return this;
        }
@@ -883,6 +920,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         * @throws IllegalArgumentException if a required field is missing
         * @return built instance of {@code KeyPairGeneratorSpec}
         */
        @NonNull
        public KeyPairGeneratorSpec build() {
            return new KeyPairGeneratorSpec(mContext,
                    mKeystoreAlias,
Loading