KeyGenParameterSpec.java revision 3867709fb3840fa26072fef66ba7121a0e41871f
13f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin/*
23f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Copyright (C) 2012 The Android Open Source Project
33f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
43f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Licensed under the Apache License, Version 2.0 (the "License");
53f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * you may not use this file except in compliance with the License.
63f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * You may obtain a copy of the License at
73f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
83f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *      http://www.apache.org/licenses/LICENSE-2.0
93f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Unless required by applicable law or agreed to in writing, software
113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * distributed under the License is distributed on an "AS IS" BASIS,
123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * See the License for the specific language governing permissions and
143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * limitations under the License.
153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */
163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinpackage android.security.keystore;
183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.annotation.IntRange;
203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.annotation.NonNull;
213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.annotation.Nullable;
2283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubinimport android.app.KeyguardManager;
2383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubinimport android.hardware.fingerprint.FingerprintManager;
243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.text.TextUtils;
253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport java.math.BigInteger;
273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport java.security.KeyPairGenerator;
2883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubinimport java.security.Signature;
293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport java.security.cert.Certificate;
303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport java.security.spec.AlgorithmParameterSpec;
313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport java.util.Date;
323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport javax.crypto.Cipher;
343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport javax.crypto.KeyGenerator;
3583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubinimport javax.crypto.Mac;
363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport javax.security.auth.x500.X500Principal;
373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin/**
393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link AlgorithmParameterSpec} for initializing a {@link KeyPairGenerator} or a
403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link KeyGenerator} of the <a href="{@docRoot}training/articles/keystore.html">Android Keystore
413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * system</a>. The spec determines whether user authentication is required for using the key, what
4296481c3ddc6c58cfcad2a5cb9325ee2b24b0c540Alex Klyubin * uses the key is authorized for (e.g., only for signing -- decryption not permitted), the key's
4396481c3ddc6c58cfcad2a5cb9325ee2b24b0c540Alex Klyubin * validity start and end dates.
443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>To generate an asymmetric key pair or a symmetric key, create an instance of this class using
463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * the {@link Builder}, initialize a {@code KeyPairGenerator} or a {@code KeyGenerator} of the
473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * desired key type (e.g., {@code EC} or {@code AES} -- see
483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link KeyProperties}.{@code KEY_ALGORITHM} constants) from the {@code AndroidKeyStore} provider
493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * with the {@code KeyPairGeneratorSpec} instance, and then generate a key or key pair using
503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link KeyPairGenerator#generateKeyPair()}.
513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>The generated key pair or key will be returned by the generator and also stored in the Android
533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Keystore system under the alias specified in this spec. To obtain the secret or private key from
543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * the Android KeyStore use {@link java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)}
553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * or {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null)}.
563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * To obtain the public key from the Android Keystore system use
573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link java.security.KeyStore#getCertificate(String)} and then
583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link Certificate#getPublicKey()}.
593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>For asymmetric key pairs, a self-signed X.509 certificate will be also generated and stored in
613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * the Android KeyStore. This is because the {@link java.security.KeyStore} abstraction does not
623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * support storing key pairs without a certificate. The subject, serial number, and validity dates
633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * of the certificate can be customized in this spec. The self-signed certificate may be replaced at
643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * a later time by a certificate signed by a Certificate Authority (CA).
653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
66acb7efd0d6dbde2506bb333e400a281f422df3fcAlex Klyubin * <p>NOTE: If a private key is not authorized to sign the self-signed certificate, then the
67acb7efd0d6dbde2506bb333e400a281f422df3fcAlex Klyubin * certificate will be created with an invalid signature which will not verify. Such a certificate
68acb7efd0d6dbde2506bb333e400a281f422df3fcAlex Klyubin * is still useful because it provides access to the public key. To generate a valid
6983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * signature for the certificate the key needs to be authorized for all of the following:
7083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <ul>
7183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <li>{@link KeyProperties#PURPOSE_SIGN},</li>
7283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <li>operation without requiring the user to be authenticated (see
7383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * {@link Builder#setUserAuthenticationRequired(boolean)}),</li>
7483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <li>suitable digest or {@link KeyProperties#DIGEST_NONE},</li>
7583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <li>(RSA keys only) padding scheme {@link KeyProperties#SIGNATURE_PADDING_RSA_PKCS1} or
7683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * {@link KeyProperties#ENCRYPTION_PADDING_NONE}.</li>
7783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * </ul>
78acb7efd0d6dbde2506bb333e400a281f422df3fcAlex Klyubin *
793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>NOTE: The key material of the generated symmetric and private keys is not accessible. The key
803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * material of the public keys is accessible.
813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
821b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * <p>Instances of this class are immutable.
831b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin *
843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p><h3>Example: Asymmetric key pair</h3>
853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * The following example illustrates how to generate an EC key pair in the Android KeyStore system
863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * under alias {@code key1} authorized to be used only for signing using SHA-256, SHA-384,
873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * or SHA-512 digest and only if the user has been authenticated within the last five minutes.
883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <pre> {@code
893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *         KeyProperties.KEY_ALGORITHM_EC,
913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *         "AndroidKeyStore");
923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keyPairGenerator.initialize(
931b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin *         new KeyGenParameterSpec.Builder(
941b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin *                 "key1",
953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
961b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin *                 .setDigests(KeyProperties.DIGEST_SHA256,
971b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin *                         KeyProperties.DIGEST_SHA384,
981b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin *                         KeyProperties.DIGEST_SHA512)
993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *                 // Only permit this key to be used if the user authenticated
1003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *                 // within the last five minutes.
1013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *                 .setUserAuthenticationRequired(true)
1023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *                 .setUserAuthenticationValidityDurationSeconds(5 * 60)
1033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *                 .build());
1043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyPair keyPair = keyPairGenerator.generateKeyPair();
1053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
1063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * // The key pair can also be obtained from the Android Keystore any time as follows:
1073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
1083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keyStore.load(null);
1093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null);
1103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
1113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * }</pre>
1123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
1133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p><h3>Example: Symmetric key</h3>
1143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * The following example illustrates how to generate an AES key in the Android KeyStore system under
115a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * alias {@code key2} authorized to be used only for encryption/decryption in GCM mode with no
116cb3bb3f03ac253052cd42a32a54e63c2ee9b9a95Alex Klyubin * padding.
1173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <pre> {@code
1183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyGenerator keyGenerator = KeyGenerator.getInstance(
1191b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin *         KeyProperties.KEY_ALGORITHM_AES,
1203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *         "AndroidKeyStore");
1213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keyGenerator.initialize(
1223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *         new KeyGenParameterSpec.Builder("key2",
1233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *                 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
124a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin *                 .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
125a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin *                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
1263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *                 .build());
1273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * SecretKey key = keyGenerator.generateKey();
1283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
1293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * // The key can also be obtained from the Android Keystore any time as follows:
1303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
1313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keyStore.load(null);
1323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * key = (SecretKey) keyStore.getKey("key2", null);
1333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * }</pre>
1343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */
1353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinpublic final class KeyGenParameterSpec implements AlgorithmParameterSpec {
1363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
1373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
1383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
1393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1970
1403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
1413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
1423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final String mKeystoreAlias;
1433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final int mKeySize;
1443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final AlgorithmParameterSpec mSpec;
1453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final X500Principal mCertificateSubject;
1463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final BigInteger mCertificateSerialNumber;
1473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final Date mCertificateNotBefore;
1483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final Date mCertificateNotAfter;
1493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final Date mKeyValidityStart;
1503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final Date mKeyValidityForOriginationEnd;
1513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final Date mKeyValidityForConsumptionEnd;
1523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final @KeyProperties.PurposeEnum int mPurposes;
1533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final @KeyProperties.DigestEnum String[] mDigests;
1543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
1553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
1563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final @KeyProperties.BlockModeEnum String[] mBlockModes;
1573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final boolean mRandomizedEncryptionRequired;
1583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final boolean mUserAuthenticationRequired;
1593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final int mUserAuthenticationValidityDurationSeconds;
1603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
1613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
1623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * @hide should be built with Builder
1633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
1643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public KeyGenParameterSpec(
1653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            String keyStoreAlias,
1663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            int keySize,
1673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            AlgorithmParameterSpec spec,
1683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            X500Principal certificateSubject,
1693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            BigInteger certificateSerialNumber,
1703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            Date certificateNotBefore,
1713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            Date certificateNotAfter,
1723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            Date keyValidityStart,
1733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            Date keyValidityForOriginationEnd,
1743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            Date keyValidityForConsumptionEnd,
1753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            @KeyProperties.PurposeEnum int purposes,
1763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            @KeyProperties.DigestEnum String[] digests,
1773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            @KeyProperties.EncryptionPaddingEnum String[] encryptionPaddings,
1783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            @KeyProperties.SignaturePaddingEnum String[] signaturePaddings,
1793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            @KeyProperties.BlockModeEnum String[] blockModes,
1803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            boolean randomizedEncryptionRequired,
1813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            boolean userAuthenticationRequired,
1823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            int userAuthenticationValidityDurationSeconds) {
1833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        if (TextUtils.isEmpty(keyStoreAlias)) {
1843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            throw new IllegalArgumentException("keyStoreAlias must not be empty");
1853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
1863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
1873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        if (certificateSubject == null) {
1883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            certificateSubject = DEFAULT_CERT_SUBJECT;
1893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
1903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        if (certificateNotBefore == null) {
1913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            certificateNotBefore = DEFAULT_CERT_NOT_BEFORE;
1923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
1933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        if (certificateNotAfter == null) {
1943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            certificateNotAfter = DEFAULT_CERT_NOT_AFTER;
1953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
1963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        if (certificateSerialNumber == null) {
1973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            certificateSerialNumber = DEFAULT_CERT_SERIAL_NUMBER;
1983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
1993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
2003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        if (certificateNotAfter.before(certificateNotBefore)) {
2013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            throw new IllegalArgumentException("certificateNotAfter < certificateNotBefore");
2023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
2033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
2043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mKeystoreAlias = keyStoreAlias;
2053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mKeySize = keySize;
2063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mSpec = spec;
2073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mCertificateSubject = certificateSubject;
2083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mCertificateSerialNumber = certificateSerialNumber;
2091b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        mCertificateNotBefore = Utils.cloneIfNotNull(certificateNotBefore);
2101b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        mCertificateNotAfter = Utils.cloneIfNotNull(certificateNotAfter);
2111b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
2121b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
2131b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
2143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mPurposes = purposes;
2153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mDigests = ArrayUtils.cloneIfNotEmpty(digests);
2163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mEncryptionPaddings =
2173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings));
2183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings));
2193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes));
2203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mRandomizedEncryptionRequired = randomizedEncryptionRequired;
2213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mUserAuthenticationRequired = userAuthenticationRequired;
2223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
2233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
2243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
2253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
2263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the alias that will be used in the {@code java.security.KeyStore}
2273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * in conjunction with the {@code AndroidKeyStore}.
2283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
2291b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin    @NonNull
2303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public String getKeystoreAlias() {
2313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mKeystoreAlias;
2323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
2333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
2343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
2353ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin     * Returns the requested key size. If {@code -1}, the size should be looked up from
2363ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin     * {@link #getAlgorithmParameterSpec()}, if provided, otherwise an algorithm-specific default
2373ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin     * size should be used.
2383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
2393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public int getKeySize() {
2403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mKeySize;
2413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
2423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
2433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
2441b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin     * Returns the key algorithm-specific {@link AlgorithmParameterSpec} that will be used for
2451b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin     * creation of the key or {@code null} if algorithm-specific defaults should be used.
2463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
2471b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin    @Nullable
2483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public AlgorithmParameterSpec getAlgorithmParameterSpec() {
2493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mSpec;
2503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
2513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
2523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
2533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the subject distinguished name to be used on the X.509 certificate that will be put
2543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * in the {@link java.security.KeyStore}.
2553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
2563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
2573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public X500Principal getCertificateSubject() {
2583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mCertificateSubject;
2593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
2603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
2613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
2623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the serial number to be used on the X.509 certificate that will be put in the
2633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * {@link java.security.KeyStore}.
2643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
2653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
2663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public BigInteger getCertificateSerialNumber() {
2673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mCertificateSerialNumber;
2683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
2693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
2703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
2713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the start date to be used on the X.509 certificate that will be put in the
2723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * {@link java.security.KeyStore}.
2733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
2743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
2753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public Date getCertificateNotBefore() {
2761b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        return Utils.cloneIfNotNull(mCertificateNotBefore);
2773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
2783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
2793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
2803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the end date to be used on the X.509 certificate that will be put in the
2813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * {@link java.security.KeyStore}.
2823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
2833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
2843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public Date getCertificateNotAfter() {
2851b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        return Utils.cloneIfNotNull(mCertificateNotAfter);
2863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
2873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
2883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
2893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the time instant before which the key is not yet valid or {@code null} if not
2903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * restricted.
2913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
2923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @Nullable
2933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public Date getKeyValidityStart() {
2941b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        return Utils.cloneIfNotNull(mKeyValidityStart);
2953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
2963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
2973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
2983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the time instant after which the key is no longer valid for decryption and
2993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * verification or {@code null} if not restricted.
3003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
3013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @Nullable
3023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public Date getKeyValidityForConsumptionEnd() {
3031b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        return Utils.cloneIfNotNull(mKeyValidityForConsumptionEnd);
3043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
3053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
3073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the time instant after which the key is no longer valid for encryption and signing
3083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * or {@code null} if not restricted.
3093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
3103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @Nullable
3113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public Date getKeyValidityForOriginationEnd() {
3121b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        return Utils.cloneIfNotNull(mKeyValidityForOriginationEnd);
3133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
3143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
3163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the set of purposes (e.g., encrypt, decrypt, sign) for which the key can be used.
3173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Attempts to use the key for any other purpose will be rejected.
3183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
3193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * <p>See {@link KeyProperties}.{@code PURPOSE} flags.
3203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
3213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public @KeyProperties.PurposeEnum int getPurposes() {
3223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mPurposes;
3233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
3243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
3263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384} with which the
3273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * key can be used or {@code null} if not specified.
3283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
3293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * <p>See {@link KeyProperties}.{@code DIGEST} constants.
3303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
3313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * @throws IllegalStateException if this set has not been specified.
3323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
3333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * @see #isDigestsSpecified()
3343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
3353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
3363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public @KeyProperties.DigestEnum String[] getDigests() {
3373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        if (mDigests == null) {
3383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            throw new IllegalStateException("Digests not specified");
3393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
3403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return ArrayUtils.cloneIfNotEmpty(mDigests);
3413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
3423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
3443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns {@code true} if the set of digest algorithms with which the key can be used has been
3453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * specified.
3463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
3473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * @see #getDigests()
3483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
3493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
3503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public boolean isDigestsSpecified() {
3513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mDigests != null;
3523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
3533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
3553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the set of padding schemes (e.g., {@code PKCS7Padding}, {@code OEAPPadding},
3563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * {@code PKCS1Padding}, {@code NoPadding}) with which the key can be used when
3573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * encrypting/decrypting. Attempts to use the key with any other padding scheme will be
3583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * rejected.
3593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
3603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants.
3613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
3623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
3633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public @KeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
3643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
3653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
3663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
3683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Gets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key
3693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * can be used when signing/verifying. Attempts to use the key with any other padding scheme
3703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * will be rejected.
3713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
3723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants.
3733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
3743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
3753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public @KeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() {
3763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
3773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
3783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
380a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin     * Gets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be used
3813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * when encrypting/decrypting. Attempts to use the key with any other block modes will be
3823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * rejected.
3833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
3843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants.
3853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
3863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
3873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public @KeyProperties.BlockModeEnum String[] getBlockModes() {
3883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return ArrayUtils.cloneIfNotEmpty(mBlockModes);
3893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
3903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
3923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns {@code true} if encryption using this key must be sufficiently randomized to produce
3933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * different ciphertexts for the same plaintext every time. The formal cryptographic property
3943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * being required is <em>indistinguishability under chosen-plaintext attack ({@code
3953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * IND-CPA})</em>. This property is important because it mitigates several classes of
3963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * weaknesses due to which ciphertext may leak information about plaintext.  For example, if a
3973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * given plaintext always produces the same ciphertext, an attacker may see the repeated
3983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * ciphertexts and be able to deduce something about the plaintext.
3993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
4003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public boolean isRandomizedEncryptionRequired() {
4013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mRandomizedEncryptionRequired;
4023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
4033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
4043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
40583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * Returns {@code true} if the key is authorized to be used only if the user has been
40683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * authenticated.
4073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
40883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * <p>This authorization applies only to secret key and private key operations. Public key
40983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * operations are not restricted.
4103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
4113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * @see #getUserAuthenticationValidityDurationSeconds()
41283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * @see Builder#setUserAuthenticationRequired(boolean)
4133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
4143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public boolean isUserAuthenticationRequired() {
4153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mUserAuthenticationRequired;
4163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
4173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
4183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
41983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * Gets the duration of time (seconds) for which this key is authorized to be used after the
42083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * user is successfully authenticated. This has effect only if user authentication is required
42183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * (see {@link #isUserAuthenticationRequired()}).
4223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
42383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * <p>This authorization applies only to secret key and private key operations. Public key
42483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * operations are not restricted.
4253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
4263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * @return duration in seconds or {@code -1} if authentication is required for every use of the
42783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     *         key.
4283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
4293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * @see #isUserAuthenticationRequired()
43083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * @see Builder#setUserAuthenticationValidityDurationSeconds(int)
4313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
4323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public int getUserAuthenticationValidityDurationSeconds() {
4333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mUserAuthenticationValidityDurationSeconds;
4343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
4353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
4363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
4373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Builder of {@link KeyGenParameterSpec} instances.
4383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
4393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public final static class Builder {
4403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private final String mKeystoreAlias;
4413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private @KeyProperties.PurposeEnum int mPurposes;
4423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
4433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private int mKeySize = -1;
4443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private AlgorithmParameterSpec mSpec;
4453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private X500Principal mCertificateSubject;
4463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private BigInteger mCertificateSerialNumber;
4473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private Date mCertificateNotBefore;
4483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private Date mCertificateNotAfter;
4493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private Date mKeyValidityStart;
4503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private Date mKeyValidityForOriginationEnd;
4513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private Date mKeyValidityForConsumptionEnd;
4523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private @KeyProperties.DigestEnum String[] mDigests;
4533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
4543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
4553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private @KeyProperties.BlockModeEnum String[] mBlockModes;
4563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private boolean mRandomizedEncryptionRequired = true;
4573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private boolean mUserAuthenticationRequired;
4583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private int mUserAuthenticationValidityDurationSeconds = -1;
4593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
4603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
4613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Creates a new instance of the {@code Builder}.
4623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
4633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @param keystoreAlias alias of the entry in which the generated key will appear in
4641b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin         *        Android KeyStore. Must not be empty.
4653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @param purposes set of purposes (e.g., encrypt, decrypt, sign) for which the key can be
4663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *        used. Attempts to use the key for any other purpose will be rejected.
4673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
4683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *        <p>If the set of purposes for which the key can be used does not contain
4693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *        {@link KeyProperties#PURPOSE_SIGN}, the self-signed certificate generated by
4703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *        {@link KeyPairGenerator} of {@code AndroidKeyStore} provider will contain an
4713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *        invalid signature. This is OK if the certificate is only used for obtaining the
4723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *        public key from Android KeyStore.
4733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
4743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *        <p>See {@link KeyProperties}.{@code PURPOSE} flags.
4753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
4763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder(@NonNull String keystoreAlias, @KeyProperties.PurposeEnum int purposes) {
4773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            if (keystoreAlias == null) {
4783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                throw new NullPointerException("keystoreAlias == null");
4791b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin            } else if (keystoreAlias.isEmpty()) {
4801b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin                throw new IllegalArgumentException("keystoreAlias must not be empty");
4813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            }
4823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mKeystoreAlias = keystoreAlias;
4833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mPurposes = purposes;
4843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
4853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
4863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
4873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the size (in bits) of the key to be generated. For instance, for RSA keys this sets
4883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * the modulus size, for EC keys this selects a curve with a matching field size, and for
4893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * symmetric keys this sets the size of the bitstring which is their key material.
4903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
4913ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin         * <p>The default key size is specific to each key algorithm. If key size is not set
4923ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin         * via this method, it should be looked up from the algorithm-specific parameters (if any)
4933ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin         * provided via
4943ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin         * {@link #setAlgorithmParameterSpec(AlgorithmParameterSpec) setAlgorithmParameterSpec}.
4953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
4963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
4973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setKeySize(int keySize) {
4983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            if (keySize < 0) {
4993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                throw new IllegalArgumentException("keySize < 0");
5003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            }
5013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mKeySize = keySize;
5023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
5033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
5043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
5053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
5063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the algorithm-specific key generation parameters. For example, for RSA keys this may
5071b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin         * be an instance of {@link java.security.spec.RSAKeyGenParameterSpec} whereas for EC keys
5081b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin         * this may be an instance of {@link java.security.spec.ECGenParameterSpec}.
5091b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin         *
5101b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin         * <p>These key generation parameters must match other explicitly set parameters (if any),
5111b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin         * such as key size.
5123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
5133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) {
5143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            if (spec == null) {
5153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                throw new NullPointerException("spec == null");
5163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            }
5173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mSpec = spec;
5183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
5193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
5203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
5213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
5223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the subject used for the self-signed certificate of the generated key pair.
5233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
5243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, the subject is {@code CN=fake}.
5253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
5263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
5273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setCertificateSubject(@NonNull X500Principal subject) {
5283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            if (subject == null) {
5293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                throw new NullPointerException("subject == null");
5303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            }
5313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mCertificateSubject = subject;
5323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
5333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
5343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
5353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
5363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the serial number used for the self-signed certificate of the generated key pair.
5373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
5383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, the serial number is {@code 1}.
5393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
5403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
5413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setCertificateSerialNumber(@NonNull BigInteger serialNumber) {
5423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            if (serialNumber == null) {
5433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                throw new NullPointerException("serialNumber == null");
5443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            }
5453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mCertificateSerialNumber = serialNumber;
5463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
5473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
5483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
5493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
5503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the start of the validity period for the self-signed certificate of the generated
5513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * key pair.
5523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
5533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, this date is {@code Jan 1 1970}.
5543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
5553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
5563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setCertificateNotBefore(@NonNull Date date) {
5573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            if (date == null) {
5583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                throw new NullPointerException("date == null");
5593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            }
5601b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin            mCertificateNotBefore = Utils.cloneIfNotNull(date);
5613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
5623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
5633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
5643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
5653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the end of the validity period for the self-signed certificate of the generated key
5663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * pair.
5673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
5683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, this date is {@code Jan 1 2048}.
5693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
5703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
5713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setCertificateNotAfter(@NonNull Date date) {
5723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            if (date == null) {
5733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                throw new NullPointerException("date == null");
5743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            }
5751b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin            mCertificateNotAfter = Utils.cloneIfNotNull(date);
5763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
5773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
5783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
5793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
5803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the time instant before which the key is not yet valid.
5813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
5823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, the key is valid at any instant.
5833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
5843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @see #setKeyValidityEnd(Date)
5853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
5863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
5873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setKeyValidityStart(Date startDate) {
5881b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin            mKeyValidityStart = Utils.cloneIfNotNull(startDate);
5893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
5903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
5913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
5923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
5933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the time instant after which the key is no longer valid.
5943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
5953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, the key is valid at any instant.
5963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
5973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @see #setKeyValidityStart(Date)
5983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @see #setKeyValidityForConsumptionEnd(Date)
5993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @see #setKeyValidityForOriginationEnd(Date)
6003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
6013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
6023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setKeyValidityEnd(Date endDate) {
6033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            setKeyValidityForOriginationEnd(endDate);
6043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            setKeyValidityForConsumptionEnd(endDate);
6053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
6063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
6073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
6083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
6093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the time instant after which the key is no longer valid for encryption and signing.
6103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
6113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, the key is valid at any instant.
6123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
6133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @see #setKeyValidityForConsumptionEnd(Date)
6143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
6153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
6163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setKeyValidityForOriginationEnd(Date endDate) {
6171b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin            mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(endDate);
6183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
6193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
6203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
6213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
6223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the time instant after which the key is no longer valid for decryption and
6233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * verification.
6243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
6253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, the key is valid at any instant.
6263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
6273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @see #setKeyValidityForOriginationEnd(Date)
6283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
6293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
6303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setKeyValidityForConsumptionEnd(Date endDate) {
6311b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin            mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(endDate);
6323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
6333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
6343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
6353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
6363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the set of digests algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which
6373867709fb3840fa26072fef66ba7121a0e41871fAlex Klyubin         * the key can be used. Attempts to use the key with any other digest algorithm will be
6383867709fb3840fa26072fef66ba7121a0e41871fAlex Klyubin         * rejected.
6393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
6403867709fb3840fa26072fef66ba7121a0e41871fAlex Klyubin         * <p>This must be specified for signing/verification keys and RSA encryption/decryption
6413867709fb3840fa26072fef66ba7121a0e41871fAlex Klyubin         * keys used with RSA OAEP padding scheme because these operations involve a digest. For
6423867709fb3840fa26072fef66ba7121a0e41871fAlex Klyubin         * HMAC keys, the default is the digest associated with the key algorithm (e.g.,
643dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * {@code SHA-256} for key algorithm {@code HmacSHA256}).
6443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
645dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * <p>For private keys used for TLS/SSL client or server authentication it is usually
646dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * necessary to authorize the use of no digest ({@link KeyProperties#DIGEST_NONE}). This is
647dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * because TLS/SSL stacks typically generate the necessary digest(s) themselves and then use
648dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * a private key to sign it.
649dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         *
650dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * <p>See {@link KeyProperties}.{@code DIGEST} constants.
6513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
6523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
6533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setDigests(@KeyProperties.DigestEnum String... digests) {
6543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mDigests = ArrayUtils.cloneIfNotEmpty(digests);
6553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
6563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
6573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
6583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
6593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the set of padding schemes (e.g., {@code PKCS7Padding}, {@code OAEPPadding},
6603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * {@code PKCS1Padding}, {@code NoPadding}) with which the key can be used when
6613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * encrypting/decrypting. Attempts to use the key with any other padding scheme will be
6623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * rejected.
6633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
6643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>This must be specified for keys which are used for encryption/decryption.
6653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
666dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * <p>For RSA private keys used by TLS/SSL servers to authenticate themselves to clients it
667dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * is usually necessary to authorize the use of no/any padding
668dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * ({@link KeyProperties#ENCRYPTION_PADDING_NONE}). This is because RSA decryption is
669dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * required by some cipher suites, and some stacks request decryption using no padding
670dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * whereas others request PKCS#1 padding.
671dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         *
6723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants.
6733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
6743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
6753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setEncryptionPaddings(
6763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                @KeyProperties.EncryptionPaddingEnum String... paddings) {
6773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
6783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
6793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
6803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
6813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
6823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key
6833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * can be used when signing/verifying. Attempts to use the key with any other padding scheme
6843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * will be rejected.
6853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
6863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>This must be specified for RSA keys which are used for signing/verification.
6873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
6883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants.
6893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
6903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
6913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setSignaturePaddings(
6923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                @KeyProperties.SignaturePaddingEnum String... paddings) {
6933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings);
6943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
6953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
6963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
6973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
698a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin         * Sets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be
699a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin         * used when encrypting/decrypting. Attempts to use the key with any other block modes will
700a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin         * be rejected.
7013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
702a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin         * <p>This must be specified for symmetric encryption/decryption keys.
7033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
7043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants.
7053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
7063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
7073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setBlockModes(@KeyProperties.BlockModeEnum String... blockModes) {
7083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
7093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
7103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
7113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
7123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
7133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets whether encryption using this key must be sufficiently randomized to produce
7143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * different ciphertexts for the same plaintext every time. The formal cryptographic
7153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * property being required is <em>indistinguishability under chosen-plaintext attack
7163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * ({@code IND-CPA})</em>. This property is important because it mitigates several classes
7173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * of weaknesses due to which ciphertext may leak information about plaintext. For example,
7183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * if a given plaintext always produces the same ciphertext, an attacker may see the
7193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * repeated ciphertexts and be able to deduce something about the plaintext.
7203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
7213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, {@code IND-CPA} is required.
7223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
7233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>When {@code IND-CPA} is required:
7243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <ul>
7253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <li>encryption/decryption transformation which do not offer {@code IND-CPA}, such as
7263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * {@code ECB} with a symmetric encryption algorithm, or RSA encryption/decryption without
7273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * padding, are prohibited;</li>
728a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin         * <li>in block modes which use an IV, such as {@code GCM}, {@code CBC}, and {@code CTR},
7293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * caller-provided IVs are rejected when encrypting, to ensure that only random IVs are
7303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * used.</li>
7313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * </ul>
7323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
7333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>Before disabling this requirement, consider the following approaches instead:
7343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <ul>
7353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <li>If you are generating a random IV for encryption and then initializing a {@code}
7363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Cipher using the IV, the solution is to let the {@code Cipher} generate a random IV
7373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * instead. This will occur if the {@code Cipher} is initialized for encryption without an
7383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * IV. The IV can then be queried via {@link Cipher#getIV()}.</li>
7393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <li>If you are generating a non-random IV (e.g., an IV derived from something not fully
7403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * random, such as the name of the file being encrypted, or transaction ID, or password,
7413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * or a device identifier), consider changing your design to use a random IV which will then
7423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * be provided in addition to the ciphertext to the entities which need to decrypt the
7433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * ciphertext.</li>
7443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <li>If you are using RSA encryption without padding, consider switching to encryption
7453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * padding schemes which offer {@code IND-CPA}, such as PKCS#1 or OAEP.</li>
7463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * </ul>
7473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
7483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
7493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setRandomizedEncryptionRequired(boolean required) {
7503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mRandomizedEncryptionRequired = required;
7513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
7523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
7533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
7543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
75583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * Sets whether this key is authorized to be used only if the user has been authenticated.
7563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
75783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <p>By default, the key is authorized to be used regardless of whether the user has been
75883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * authenticated.
7593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
76083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <p>When user authentication is required:
76183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <ul>
76283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <li>The key can only be generated if secure lock screen is set up (see
76383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * {@link KeyguardManager#isDeviceSecure()}). Additionally, if the key requires that user
76483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * authentication takes place for every use of the key (see
76583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * {@link #setUserAuthenticationValidityDurationSeconds(int)}), at least one fingerprint
76683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * must be enrolled (see {@link FingerprintManager#hasEnrolledFingerprints()}).</li>
76783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <li>The use of the key must be authorized by the user by authenticating to this Android
76883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * device using a subset of their secure lock screen credentials such as
76983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * password/PIN/pattern or fingerprint.
7703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
7713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * information</a>.
77283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <li>The key will become <em>irreversibly invalidated</em> once the secure lock screen is
77383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * disabled (reconfigured to None, Swipe or other mode which does not authenticate the user)
77483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * or when the secure lock screen is forcibly reset (e.g., by a Device Administrator).
77583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * Additionally, if the key requires that user authentication takes place for every use of
77683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * the key, it is also irreversibly invalidated once a new fingerprint is enrolled or once\
77783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * no more fingerprints are enrolled. Attempts to initialize cryptographic operations using
77883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * such keys will throw {@link KeyPermanentlyInvalidatedException}.</li>
77983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * </ul>
7803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
78183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <p>This authorization applies only to secret key and private key operations. Public key
78283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * operations are not restricted.
7833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
7843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @see #setUserAuthenticationValidityDurationSeconds(int)
78583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * @see KeyguardManager#isDeviceSecure()
78683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * @see FingerprintManager#hasEnrolledFingerprints()
7873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
7883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
7893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setUserAuthenticationRequired(boolean required) {
7903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mUserAuthenticationRequired = required;
7913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
7923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
7933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
7943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
79583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * Sets the duration of time (seconds) for which this key is authorized to be used after the
79683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * user is successfully authenticated. This has effect if the key requires user
79783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * authentication for its use (see {@link #setUserAuthenticationRequired(boolean)}).
79883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         *
79983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <p>By default, if user authentication is required, it must take place for every use of
80083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * the key.
80183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         *
80283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <p>Cryptographic operations involving keys which require user authentication to take
80383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * place for every operation can only use fingerprint authentication. This is achieved by
80483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * initializing a cryptographic operation ({@link Signature}, {@link Cipher}, {@link Mac})
80583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * with the key, wrapping it into a {@link FingerprintManager.CryptoObject}, invoking
80683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * {@code FingerprintManager.authenticate} with {@code CryptoObject}, and proceeding with
80783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * the cryptographic operation only if the authentication flow succeeds.
80883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         *
80983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <p>Cryptographic operations involving keys which are authorized to be used for a duration
81083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * of time after a successful user authentication event can only use secure lock screen
81183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * authentication. These cryptographic operations will throw
81283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * {@link UserNotAuthenticatedException} during initialization if the user needs to be
81383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * authenticated to proceed. This situation can be resolved by the user unlocking the secure
81483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * lock screen of the Android or by going through the confirm credential flow initiated by
81583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * {@link KeyguardManager#createConfirmDeviceCredentialIntent(CharSequence, CharSequence)}.
81683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * Once resolved, initializing a new cryptographic operation using this key (or any other
81783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * key which is authorized to be used for a fixed duration of time after user
81883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * authentication) should succeed provided the user authentication flow completed
81983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * successfully.
82083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         *
82183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * @param seconds duration in seconds or {@code -1} if user authentication must take place
82283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         *        for every use of the key.
8233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
8243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @see #setUserAuthenticationRequired(boolean)
82583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * @see FingerprintManager
82683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * @see FingerprintManager.CryptoObject
82783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * @see KeyguardManager
8283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
8293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
8303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setUserAuthenticationValidityDurationSeconds(
8313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                @IntRange(from = -1) int seconds) {
8321b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin            if (seconds < -1) {
8331b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin                throw new IllegalArgumentException("seconds must be -1 or larger");
8341b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin            }
8353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mUserAuthenticationValidityDurationSeconds = seconds;
8363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
8373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
8383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
8393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
8403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Builds an instance of {@code KeyGenParameterSpec}.
8413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
8423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
8433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public KeyGenParameterSpec build() {
8443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return new KeyGenParameterSpec(
8453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mKeystoreAlias,
8463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mKeySize,
8473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mSpec,
8483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mCertificateSubject,
8493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mCertificateSerialNumber,
8503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mCertificateNotBefore,
8513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mCertificateNotAfter,
8523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mKeyValidityStart,
8533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mKeyValidityForOriginationEnd,
8543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mKeyValidityForConsumptionEnd,
8553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mPurposes,
8563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mDigests,
8573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mEncryptionPaddings,
8583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mSignaturePaddings,
8593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mBlockModes,
8603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mRandomizedEncryptionRequired,
8613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mUserAuthenticationRequired,
8623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mUserAuthenticationValidityDurationSeconds);
8633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
8643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
8653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin}
866