KeyGenParameterSpec.java revision 8d8c7477746c357d54f586fc92e8d422a4fc6441
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;
243876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubinimport android.security.KeyStore;
253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.text.TextUtils;
263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport java.math.BigInteger;
283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport java.security.KeyPairGenerator;
2983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubinimport java.security.Signature;
303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport java.security.cert.Certificate;
313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport java.security.spec.AlgorithmParameterSpec;
323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport java.util.Date;
333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport javax.crypto.Cipher;
353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport javax.crypto.KeyGenerator;
3683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubinimport javax.crypto.Mac;
373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport javax.security.auth.x500.X500Principal;
383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin/**
403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link AlgorithmParameterSpec} for initializing a {@link KeyPairGenerator} or a
413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link KeyGenerator} of the <a href="{@docRoot}training/articles/keystore.html">Android Keystore
4272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * system</a>. The spec determines authorized uses of the key, such as whether user authentication
4372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * is required for using the key, what operations are authorized (e.g., signing, but not
4472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * decryption) and with what parameters (e.g., only with a particular padding scheme or digest), the
4572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * key's validity start and end dates. Key use authorizations expressed in the spec apply only to
4672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * secret keys and private keys -- public keys can be used for any supported operations.
473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>To generate an asymmetric key pair or a symmetric key, create an instance of this class using
493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * the {@link Builder}, initialize a {@code KeyPairGenerator} or a {@code KeyGenerator} of the
503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * desired key type (e.g., {@code EC} or {@code AES} -- see
513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link KeyProperties}.{@code KEY_ALGORITHM} constants) from the {@code AndroidKeyStore} provider
5272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * with the {@code KeyGenParameterSpec} instance, and then generate a key or key pair using
5372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * {@link KeyGenerator#generateKey()} or {@link KeyPairGenerator#generateKeyPair()}.
543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>The generated key pair or key will be returned by the generator and also stored in the Android
5672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * Keystore under the alias specified in this spec. To obtain the secret or private key from the
5772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * Android Keystore use {@link java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)}
583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * or {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null)}.
5972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * To obtain the public key from the Android Keystore use
603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link java.security.KeyStore#getCertificate(String)} and then
613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link Certificate#getPublicKey()}.
623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
6372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <p>To help obtain algorithm-specific public parameters of key pairs stored in the Android
6472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * Keystore, generated private keys implement {@link java.security.interfaces.ECKey} or
6572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * {@link java.security.interfaces.RSAKey} interfaces whereas public keys implement
6672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * {@link java.security.interfaces.ECPublicKey} or {@link java.security.interfaces.RSAPublicKey}
6772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * interfaces.
6872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *
693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>For asymmetric key pairs, a self-signed X.509 certificate will be also generated and stored in
7072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * the Android Keystore. This is because the {@link java.security.KeyStore} abstraction does not
713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * support storing key pairs without a certificate. The subject, serial number, and validity dates
723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * of the certificate can be customized in this spec. The self-signed certificate may be replaced at
733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * a later time by a certificate signed by a Certificate Authority (CA).
743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
75acb7efd0d6dbde2506bb333e400a281f422df3fcAlex Klyubin * <p>NOTE: If a private key is not authorized to sign the self-signed certificate, then the
76acb7efd0d6dbde2506bb333e400a281f422df3fcAlex Klyubin * certificate will be created with an invalid signature which will not verify. Such a certificate
77e4928a2912297751108c7045ce3343ec63edcc01Alex Klyubin * is still useful because it provides access to the public key. To generate a valid signature for
78e4928a2912297751108c7045ce3343ec63edcc01Alex Klyubin * the certificate the key needs to be authorized for all of the following:
7983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <ul>
8083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <li>{@link KeyProperties#PURPOSE_SIGN},</li>
8183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <li>operation without requiring the user to be authenticated (see
8283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * {@link Builder#setUserAuthenticationRequired(boolean)}),</li>
83856aebe571e2efe332c1258b3131bfbae6f4b396Alex Klyubin * <li>signing/origination at this moment in time (see {@link Builder#setKeyValidityStart(Date)}
84856aebe571e2efe332c1258b3131bfbae6f4b396Alex Klyubin * and {@link Builder#setKeyValidityForOriginationEnd(Date)}),</li>
85e4928a2912297751108c7045ce3343ec63edcc01Alex Klyubin * <li>suitable digest,</li>
86e4928a2912297751108c7045ce3343ec63edcc01Alex Klyubin * <li>(RSA keys only) padding scheme {@link KeyProperties#SIGNATURE_PADDING_RSA_PKCS1}.</li>
8783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * </ul>
88acb7efd0d6dbde2506bb333e400a281f422df3fcAlex Klyubin *
893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>NOTE: The key material of the generated symmetric and private keys is not accessible. The key
903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * material of the public keys is accessible.
913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
921b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * <p>Instances of this class are immutable.
931b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin *
9472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <p><h3>Example: NIST P-256 EC key pair for signing/verification using ECDSA</h3>
9572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * This example illustrates how to generate a NIST P-256 (aka secp256r1 aka prime256v1) EC key pair
9672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * in the Android KeyStore system under alias {@code key1} where the private key is authorized to be
9772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * used only for signing using SHA-256, SHA-384, or SHA-512 digest and only if the user has been
9872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * authenticated within the last five minutes. The use of public key is unrestricted, thus
9972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * permitting signature verification using any padding schemes and digests, and without user
10072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * authentication.
1013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <pre> {@code
1023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
10372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *         KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
1043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keyPairGenerator.initialize(
1051b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin *         new KeyGenParameterSpec.Builder(
1061b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin *                 "key1",
10772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *                 KeyProperties.PURPOSE_SIGN)
10872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *                 .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
1091b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin *                 .setDigests(KeyProperties.DIGEST_SHA256,
1101b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin *                         KeyProperties.DIGEST_SHA384,
1111b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin *                         KeyProperties.DIGEST_SHA512)
11272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *                 // Only permit the private key to be used if the user authenticated
1133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *                 // within the last five minutes.
1143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *                 .setUserAuthenticationRequired(true)
1153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *                 .setUserAuthenticationValidityDurationSeconds(5 * 60)
1163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *                 .build());
1173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyPair keyPair = keyPairGenerator.generateKeyPair();
11872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * Signature signature = Signature.getInstance("SHA256withECDSA");
11972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * signature.initSign(keyPair.getPrivate());
12072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * ...
12172245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *
12272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * // The key pair can also be obtained from the Android Keystore any time as follows:
12372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
12472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * keyStore.load(null);
12572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null);
12672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
12772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * }</pre>
12872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *
12972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <p><h3>Example: RSA key pair for signing/verification using RSA-PSS</h3>
13072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * This example illustrates how to generate an RSA key pair in the Android KeyStore system under
13172245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * alias {@code key1} authorized to be used only for signing using the RSA-PSS signature padding
13272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * scheme with SHA-256 or SHA-512 digests. The use of public key is unrestricted, thus permitting
13372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * signature verification using any padding schemes and digests.
13472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <pre> {@code
13572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
13672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *         KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
13772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * keyPairGenerator.initialize(
13872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *         new KeyGenParameterSpec.Builder(
13972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *                 "key1",
14072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *                 KeyProperties.PURPOSE_SIGN)
14172245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *                 .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
14272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *                 .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS)
14372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *                 .build());
14472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyPair keyPair = keyPairGenerator.generateKeyPair();
14572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * Signature signature = Signature.getInstance("SHA256withRSA/PSS");
14672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * signature.initSign(keyPair.getPrivate());
14772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * ...
1483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
1493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * // The key pair can also be obtained from the Android Keystore any time as follows:
1503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
1513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keyStore.load(null);
1523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null);
1533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
1543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * }</pre>
1553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
15672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <p><h3>Example: RSA key pair for encryption/decryption using RSA OAEP</h3>
15772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * This example illustrates how to generate an RSA key pair in the Android KeyStore system under
15872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * alias {@code key1} where the private key is authorized to be used only for decryption using RSA
15972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * OAEP encryption padding scheme with SHA-256 or SHA-512 digests. The use of public key is
16072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * unrestricted, thus permitting encryption using any padding schemes and digests.
16172245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <pre> {@code
16272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
16372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *         KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
16472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * keyPairGenerator.initialize(
16572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *         new KeyGenParameterSpec.Builder(
16672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *                 "key1",
16772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *                 KeyProperties.PURPOSE_DECRYPT)
16872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *                 .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
16972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
17072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *                 .build());
17172245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyPair keyPair = keyPairGenerator.generateKeyPair();
17272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
17372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
17472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * ...
17572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *
17672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * // The key pair can also be obtained from the Android Keystore any time as follows:
17772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
17872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * keyStore.load(null);
17972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null);
18072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
18172245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * }</pre>
18272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *
18372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <p><h3>Example: AES key for encryption/decryption in GCM mode</h3>
1843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * The following example illustrates how to generate an AES key in the Android KeyStore system under
185a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * alias {@code key2} authorized to be used only for encryption/decryption in GCM mode with no
186cb3bb3f03ac253052cd42a32a54e63c2ee9b9a95Alex Klyubin * padding.
1873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <pre> {@code
1883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyGenerator keyGenerator = KeyGenerator.getInstance(
18972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *         KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
1903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keyGenerator.initialize(
1913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *         new KeyGenParameterSpec.Builder("key2",
1923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *                 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
193a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin *                 .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
194a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin *                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
1953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *                 .build());
1963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * SecretKey key = keyGenerator.generateKey();
1973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin *
19872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
19972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * cipher.init(Cipher.ENCRYPT_MODE, key);
20072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * ...
20172245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *
20272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * // The key can also be obtained from the Android Keystore any time as follows:
20372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
20472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * keyStore.load(null);
20572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * key = (SecretKey) keyStore.getKey("key2", null);
20672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * }</pre>
20772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *
20872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <p><h3>Example: HMAC key for generating a MAC using SHA-256</h3>
20972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * This example illustrates how to generate an HMAC key in the Android KeyStore system under alias
21072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * {@code key2} authorized to be used only for generating an HMAC using SHA-256.
21172245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <pre> {@code
21272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyGenerator keyGenerator = KeyGenerator.getInstance(
21372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *         KeyProperties.KEY_ALGORITHM_HMAC_SHA256, "AndroidKeyStore");
21472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * keyGenerator.initialize(
21572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *         new KeyGenParameterSpec.Builder("key2", KeyProperties.PURPOSE_SIGN).build());
21672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * SecretKey key = keyGenerator.generateKey();
21772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * Mac mac = Mac.getInstance("HmacSHA256");
21872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * mac.init(key);
21972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * ...
22072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin *
2213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * // The key can also be obtained from the Android Keystore any time as follows:
2223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
2233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keyStore.load(null);
2243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * key = (SecretKey) keyStore.getKey("key2", null);
2253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * }</pre>
2263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */
2273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinpublic final class KeyGenParameterSpec implements AlgorithmParameterSpec {
2283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
2293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
2303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
2313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1970
2323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
2333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
2343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final String mKeystoreAlias;
2353876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin    private final int mUid;
2363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final int mKeySize;
2373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final AlgorithmParameterSpec mSpec;
2383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final X500Principal mCertificateSubject;
2393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final BigInteger mCertificateSerialNumber;
2403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final Date mCertificateNotBefore;
2413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final Date mCertificateNotAfter;
2423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final Date mKeyValidityStart;
2433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final Date mKeyValidityForOriginationEnd;
2443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final Date mKeyValidityForConsumptionEnd;
2453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final @KeyProperties.PurposeEnum int mPurposes;
2463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final @KeyProperties.DigestEnum String[] mDigests;
2473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
2483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
2493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final @KeyProperties.BlockModeEnum String[] mBlockModes;
2503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final boolean mRandomizedEncryptionRequired;
2513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final boolean mUserAuthenticationRequired;
2523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    private final int mUserAuthenticationValidityDurationSeconds;
2538d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden    private final byte[] mAttestationChallenge;
2548d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden    private final boolean mUniqueIdIncluded;
2553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
2563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
2573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * @hide should be built with Builder
2583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
2593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public KeyGenParameterSpec(
2603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            String keyStoreAlias,
2613876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin            int uid,
2623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            int keySize,
2633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            AlgorithmParameterSpec spec,
2643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            X500Principal certificateSubject,
2653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            BigInteger certificateSerialNumber,
2663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            Date certificateNotBefore,
2673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            Date certificateNotAfter,
2683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            Date keyValidityStart,
2693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            Date keyValidityForOriginationEnd,
2703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            Date keyValidityForConsumptionEnd,
2713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            @KeyProperties.PurposeEnum int purposes,
2723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            @KeyProperties.DigestEnum String[] digests,
2733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            @KeyProperties.EncryptionPaddingEnum String[] encryptionPaddings,
2743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            @KeyProperties.SignaturePaddingEnum String[] signaturePaddings,
2753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            @KeyProperties.BlockModeEnum String[] blockModes,
2763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            boolean randomizedEncryptionRequired,
2773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            boolean userAuthenticationRequired,
2788d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden            int userAuthenticationValidityDurationSeconds,
2798d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden            byte[] attestationChallenge,
2808d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden            boolean uniqueIdIncluded) {
2813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        if (TextUtils.isEmpty(keyStoreAlias)) {
2823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            throw new IllegalArgumentException("keyStoreAlias must not be empty");
2833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
2843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
2853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        if (certificateSubject == null) {
2863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            certificateSubject = DEFAULT_CERT_SUBJECT;
2873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
2883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        if (certificateNotBefore == null) {
2893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            certificateNotBefore = DEFAULT_CERT_NOT_BEFORE;
2903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
2913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        if (certificateNotAfter == null) {
2923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            certificateNotAfter = DEFAULT_CERT_NOT_AFTER;
2933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
2943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        if (certificateSerialNumber == null) {
2953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            certificateSerialNumber = DEFAULT_CERT_SERIAL_NUMBER;
2963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
2973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
2983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        if (certificateNotAfter.before(certificateNotBefore)) {
2993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            throw new IllegalArgumentException("certificateNotAfter < certificateNotBefore");
3003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
3013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mKeystoreAlias = keyStoreAlias;
3033876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin        mUid = uid;
3043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mKeySize = keySize;
3053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mSpec = spec;
3063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mCertificateSubject = certificateSubject;
3073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mCertificateSerialNumber = certificateSerialNumber;
3081b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        mCertificateNotBefore = Utils.cloneIfNotNull(certificateNotBefore);
3091b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        mCertificateNotAfter = Utils.cloneIfNotNull(certificateNotAfter);
3101b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
3111b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
3121b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
3133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mPurposes = purposes;
3143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mDigests = ArrayUtils.cloneIfNotEmpty(digests);
3153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mEncryptionPaddings =
3163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings));
3173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings));
3183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes));
3193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mRandomizedEncryptionRequired = randomizedEncryptionRequired;
3203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mUserAuthenticationRequired = userAuthenticationRequired;
3213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
3228d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        mAttestationChallenge = Utils.cloneIfNotNull(attestationChallenge);
3238d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        mUniqueIdIncluded = uniqueIdIncluded;
3243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
3253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
3273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the alias that will be used in the {@code java.security.KeyStore}
3283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * in conjunction with the {@code AndroidKeyStore}.
3293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
3301b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin    @NonNull
3313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public String getKeystoreAlias() {
3323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mKeystoreAlias;
3333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
3343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
3363876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin     * Returns the UID which will own the key. {@code -1} is an alias for the UID of the current
3373876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin     * process.
3383876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin     *
3393876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin     * @hide
3403876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin     */
3413876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin    public int getUid() {
3423876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin        return mUid;
3433876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin    }
3443876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin
3453876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin    /**
3463ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin     * Returns the requested key size. If {@code -1}, the size should be looked up from
3473ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin     * {@link #getAlgorithmParameterSpec()}, if provided, otherwise an algorithm-specific default
3483ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin     * size should be used.
3493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
3503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public int getKeySize() {
3513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mKeySize;
3523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
3533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
3551b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin     * Returns the key algorithm-specific {@link AlgorithmParameterSpec} that will be used for
3561b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin     * creation of the key or {@code null} if algorithm-specific defaults should be used.
3573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
3581b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin    @Nullable
3593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public AlgorithmParameterSpec getAlgorithmParameterSpec() {
3603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mSpec;
3613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
3623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
3643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the subject distinguished name to be used on the X.509 certificate that will be put
3653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * in the {@link java.security.KeyStore}.
3663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
3673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
3683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public X500Principal getCertificateSubject() {
3693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mCertificateSubject;
3703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
3713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
3733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the serial number to be used on the X.509 certificate that will be put in the
3743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * {@link java.security.KeyStore}.
3753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
3763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
3773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public BigInteger getCertificateSerialNumber() {
3783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mCertificateSerialNumber;
3793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
3803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
3823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the start date to be used on the X.509 certificate that will be put in the
3833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * {@link java.security.KeyStore}.
3843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
3853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
3863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public Date getCertificateNotBefore() {
3871b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        return Utils.cloneIfNotNull(mCertificateNotBefore);
3883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
3893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
3913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the end date to be used on the X.509 certificate that will be put in the
3923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * {@link java.security.KeyStore}.
3933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
3943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
3953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public Date getCertificateNotAfter() {
3961b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        return Utils.cloneIfNotNull(mCertificateNotAfter);
3973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
3983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
3993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
4003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the time instant before which the key is not yet valid or {@code null} if not
4013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * restricted.
4023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
4033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @Nullable
4043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public Date getKeyValidityStart() {
4051b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        return Utils.cloneIfNotNull(mKeyValidityStart);
4063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
4073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
4083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
4093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the time instant after which the key is no longer valid for decryption and
4103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * verification or {@code null} if not restricted.
4113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
4123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @Nullable
4133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public Date getKeyValidityForConsumptionEnd() {
4141b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        return Utils.cloneIfNotNull(mKeyValidityForConsumptionEnd);
4153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
4163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
4173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
4183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the time instant after which the key is no longer valid for encryption and signing
4193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * or {@code null} if not restricted.
4203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
4213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @Nullable
4223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public Date getKeyValidityForOriginationEnd() {
4231b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin        return Utils.cloneIfNotNull(mKeyValidityForOriginationEnd);
4243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
4253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
4263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
4273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the set of purposes (e.g., encrypt, decrypt, sign) for which the key can be used.
4283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Attempts to use the key for any other purpose will be rejected.
4293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
4303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * <p>See {@link KeyProperties}.{@code PURPOSE} flags.
4313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
4323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public @KeyProperties.PurposeEnum int getPurposes() {
4333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mPurposes;
4343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
4353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
4363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
4373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384} with which the
4383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * key can be used or {@code null} if not specified.
4393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
4403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * <p>See {@link KeyProperties}.{@code DIGEST} constants.
4413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
4423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * @throws IllegalStateException if this set has not been specified.
4433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
4443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * @see #isDigestsSpecified()
4453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
4463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
4473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public @KeyProperties.DigestEnum String[] getDigests() {
4483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        if (mDigests == null) {
4493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            throw new IllegalStateException("Digests not specified");
4503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
4513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return ArrayUtils.cloneIfNotEmpty(mDigests);
4523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
4533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
4543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
4553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns {@code true} if the set of digest algorithms with which the key can be used has been
4563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * specified.
4573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
4583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * @see #getDigests()
4593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
4603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
4613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public boolean isDigestsSpecified() {
4623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mDigests != null;
4633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
4643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
4653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
4663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns the set of padding schemes (e.g., {@code PKCS7Padding}, {@code OEAPPadding},
4673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * {@code PKCS1Padding}, {@code NoPadding}) with which the key can be used when
4683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * encrypting/decrypting. Attempts to use the key with any other padding scheme will be
4693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * rejected.
4703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
4713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants.
4723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
4733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
4743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public @KeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
4753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
4763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
4773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
4783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
4793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Gets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key
4803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * can be used when signing/verifying. Attempts to use the key with any other padding scheme
4813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * will be rejected.
4823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
4833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants.
4843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
4853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
4863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public @KeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() {
4873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
4883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
4893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
4903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
491a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin     * Gets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be used
4923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * when encrypting/decrypting. Attempts to use the key with any other block modes will be
4933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * rejected.
4943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
4953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants.
4963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
4973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @NonNull
4983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public @KeyProperties.BlockModeEnum String[] getBlockModes() {
4993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return ArrayUtils.cloneIfNotEmpty(mBlockModes);
5003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
5013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
5023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
5033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Returns {@code true} if encryption using this key must be sufficiently randomized to produce
5043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * different ciphertexts for the same plaintext every time. The formal cryptographic property
5053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * being required is <em>indistinguishability under chosen-plaintext attack ({@code
5063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * IND-CPA})</em>. This property is important because it mitigates several classes of
5073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * weaknesses due to which ciphertext may leak information about plaintext.  For example, if a
5083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * given plaintext always produces the same ciphertext, an attacker may see the repeated
5093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * ciphertexts and be able to deduce something about the plaintext.
5103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
5113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public boolean isRandomizedEncryptionRequired() {
5123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mRandomizedEncryptionRequired;
5133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
5143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
5153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
51683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * Returns {@code true} if the key is authorized to be used only if the user has been
51783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * authenticated.
5183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
51983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * <p>This authorization applies only to secret key and private key operations. Public key
52083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * operations are not restricted.
5213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
5223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * @see #getUserAuthenticationValidityDurationSeconds()
52383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * @see Builder#setUserAuthenticationRequired(boolean)
5243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
5253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public boolean isUserAuthenticationRequired() {
5263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mUserAuthenticationRequired;
5273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
5283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
5293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
53083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * Gets the duration of time (seconds) for which this key is authorized to be used after the
53183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * user is successfully authenticated. This has effect only if user authentication is required
53283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * (see {@link #isUserAuthenticationRequired()}).
5333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
53483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * <p>This authorization applies only to secret key and private key operations. Public key
53583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * operations are not restricted.
5363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
5373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * @return duration in seconds or {@code -1} if authentication is required for every use of the
53883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     *         key.
5393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
5403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * @see #isUserAuthenticationRequired()
54183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin     * @see Builder#setUserAuthenticationValidityDurationSeconds(int)
5423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
5433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public int getUserAuthenticationValidityDurationSeconds() {
5443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return mUserAuthenticationValidityDurationSeconds;
5453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
5463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
5473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    /**
5488d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * Returns the attestation challenge value that will be placed in attestation certificate for
5498d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * this key pair.
5508d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     *
5518d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * <p>If this method returns non-{@code null}, the public key certificate for this key pair will
5528d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * contain an extension that describes the details of the key's configuration and
5538d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * authorizations, including the content of the attestation challenge value. If the key is in
5548d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * secure hardware, and if the secure hardware supports attestation, the certificate will be
5558d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * signed by a chain of certificates rooted at a trustworthy CA key. Otherwise the chain will
5568d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * be rooted at an untrusted certificate.
5578d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     *
5588d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * <p>If this method returns {@code null}, and the spec is used to generate an asymmetric (RSA
5598d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * or EC) key pair, the public key will have a self-signed certificate if it has purpose {@link
5608d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * KeyProperties#PURPOSE_SIGN} (see {@link #KeyGenParameterSpec(String, int)). If does not have
5618d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * purpose {@link KeyProperties#PURPOSE_SIGN}, it will have a fake certificate.
5628d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     *
5638d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * <p>Symmetric keys, such as AES and HMAC keys, do not have public key certificates. If a
5648d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * {@link KeyGenParameterSpec} with {@link #hasAttestationCertificate()} returning
5658d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * non-{@code null} is used to generate a symmetric (AES or HMAC) key,
5668d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * {@link KeyGenerator#generateKey())} will throw
5678d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * {@link java.security.InvalidAlgorithmParameterException}.
5688d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     *
5698d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * @see Builder#setAttestationChallenge(byte[])
5708d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     */
5718d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden    /*
5728d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * TODO(swillden): Update this documentation to describe the hardware and software root keys,
5738d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * including information about CRL/OCSP services for discovering revocations, and to link to
5748d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * documentation of the extension format and content.
5758d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     */
5768d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden    public byte[] getAttestationChallenge() {
5778d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        return Utils.cloneIfNotNull(mAttestationChallenge);
5788d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden    }
5798d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden
5808d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden    /**
5818d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * @hide This is a system-only API
5828d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     *
5838d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     * Returns {@code true} if the attestation certificate will contain a unique ID field.
5848d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden     */
5858d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden    public boolean isUniqueIdIncluded() {
5868d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        return mUniqueIdIncluded;
5878d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden    }
5888d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden
5898d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden    /**
5903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Builder of {@link KeyGenParameterSpec} instances.
5913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     */
5923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public final static class Builder {
5933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private final String mKeystoreAlias;
5943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private @KeyProperties.PurposeEnum int mPurposes;
5953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
5963876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin        private int mUid = KeyStore.UID_SELF;
5973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private int mKeySize = -1;
5983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private AlgorithmParameterSpec mSpec;
5993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private X500Principal mCertificateSubject;
6003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private BigInteger mCertificateSerialNumber;
6013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private Date mCertificateNotBefore;
6023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private Date mCertificateNotAfter;
6033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private Date mKeyValidityStart;
6043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private Date mKeyValidityForOriginationEnd;
6053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private Date mKeyValidityForConsumptionEnd;
6063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private @KeyProperties.DigestEnum String[] mDigests;
6073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
6083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
6093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private @KeyProperties.BlockModeEnum String[] mBlockModes;
6103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private boolean mRandomizedEncryptionRequired = true;
6113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private boolean mUserAuthenticationRequired;
6123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        private int mUserAuthenticationValidityDurationSeconds = -1;
6138d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        private byte[] mAttestationChallenge = null;
6148d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        private boolean mUniqueIdIncluded = false;
6153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
6163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
6173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Creates a new instance of the {@code Builder}.
6183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
6193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @param keystoreAlias alias of the entry in which the generated key will appear in
6201b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin         *        Android KeyStore. Must not be empty.
6213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @param purposes set of purposes (e.g., encrypt, decrypt, sign) for which the key can be
6223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *        used. Attempts to use the key for any other purpose will be rejected.
6233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
6243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *        <p>If the set of purposes for which the key can be used does not contain
6253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *        {@link KeyProperties#PURPOSE_SIGN}, the self-signed certificate generated by
6263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *        {@link KeyPairGenerator} of {@code AndroidKeyStore} provider will contain an
6273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *        invalid signature. This is OK if the certificate is only used for obtaining the
6283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *        public key from Android KeyStore.
6293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
6303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *        <p>See {@link KeyProperties}.{@code PURPOSE} flags.
6313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
6323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder(@NonNull String keystoreAlias, @KeyProperties.PurposeEnum int purposes) {
6333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            if (keystoreAlias == null) {
6343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                throw new NullPointerException("keystoreAlias == null");
6351b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin            } else if (keystoreAlias.isEmpty()) {
6361b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin                throw new IllegalArgumentException("keystoreAlias must not be empty");
6373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            }
6383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mKeystoreAlias = keystoreAlias;
6393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mPurposes = purposes;
6403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
6413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
6423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
6433876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin         * Sets the UID which will own the key.
6443876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin         *
6453876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin         * @param uid UID or {@code -1} for the UID of the current process.
6463876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin         *
6473876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin         * @hide
6483876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin         */
6493876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin        @NonNull
6503876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin        public Builder setUid(int uid) {
6513876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin            mUid = uid;
6523876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin            return this;
6533876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin        }
6543876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin
6553876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin        /**
6563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the size (in bits) of the key to be generated. For instance, for RSA keys this sets
6573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * the modulus size, for EC keys this selects a curve with a matching field size, and for
6583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * symmetric keys this sets the size of the bitstring which is their key material.
6593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
6603ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin         * <p>The default key size is specific to each key algorithm. If key size is not set
6613ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin         * via this method, it should be looked up from the algorithm-specific parameters (if any)
6623ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin         * provided via
6633ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin         * {@link #setAlgorithmParameterSpec(AlgorithmParameterSpec) setAlgorithmParameterSpec}.
6643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
6653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
6663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setKeySize(int keySize) {
6673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            if (keySize < 0) {
6683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                throw new IllegalArgumentException("keySize < 0");
6693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            }
6703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mKeySize = keySize;
6713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
6723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
6733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
6743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
6753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the algorithm-specific key generation parameters. For example, for RSA keys this may
6761b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin         * be an instance of {@link java.security.spec.RSAKeyGenParameterSpec} whereas for EC keys
6771b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin         * this may be an instance of {@link java.security.spec.ECGenParameterSpec}.
6781b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin         *
6791b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin         * <p>These key generation parameters must match other explicitly set parameters (if any),
6801b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin         * such as key size.
6813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
6823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) {
6833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            if (spec == null) {
6843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                throw new NullPointerException("spec == null");
6853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            }
6863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mSpec = spec;
6873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
6883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
6893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
6903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
6913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the subject used for the self-signed certificate of the generated key pair.
6923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
6933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, the subject is {@code CN=fake}.
6943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
6953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
6963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setCertificateSubject(@NonNull X500Principal subject) {
6973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            if (subject == null) {
6983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                throw new NullPointerException("subject == null");
6993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            }
7003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mCertificateSubject = subject;
7013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
7023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
7033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
7043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
7053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the serial number used for the self-signed certificate of the generated key pair.
7063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
7073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, the serial number is {@code 1}.
7083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
7093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
7103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setCertificateSerialNumber(@NonNull BigInteger serialNumber) {
7113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            if (serialNumber == null) {
7123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                throw new NullPointerException("serialNumber == null");
7133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            }
7143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mCertificateSerialNumber = serialNumber;
7153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
7163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
7173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
7183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
7193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the start of the validity period for the self-signed certificate of the generated
7203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * key pair.
7213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
7223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, this date is {@code Jan 1 1970}.
7233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
7243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
7253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setCertificateNotBefore(@NonNull Date date) {
7263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            if (date == null) {
7273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                throw new NullPointerException("date == null");
7283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            }
7291b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin            mCertificateNotBefore = Utils.cloneIfNotNull(date);
7303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
7313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
7323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
7333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
7343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the end of the validity period for the self-signed certificate of the generated key
7353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * pair.
7363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
7373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, this date is {@code Jan 1 2048}.
7383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
7393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
7403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setCertificateNotAfter(@NonNull Date date) {
7413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            if (date == null) {
7423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                throw new NullPointerException("date == null");
7433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            }
7441b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin            mCertificateNotAfter = Utils.cloneIfNotNull(date);
7453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
7463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
7473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
7483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
7493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the time instant before which the key is not yet valid.
7503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
7513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, the key is valid at any instant.
7523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
7533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @see #setKeyValidityEnd(Date)
7543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
7553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
7563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setKeyValidityStart(Date startDate) {
7571b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin            mKeyValidityStart = Utils.cloneIfNotNull(startDate);
7583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
7593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
7603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
7613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
7623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the time instant after which the key is no longer valid.
7633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
7643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, the key is valid at any instant.
7653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
7663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @see #setKeyValidityStart(Date)
7673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @see #setKeyValidityForConsumptionEnd(Date)
7683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @see #setKeyValidityForOriginationEnd(Date)
7693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
7703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
7713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setKeyValidityEnd(Date endDate) {
7723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            setKeyValidityForOriginationEnd(endDate);
7733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            setKeyValidityForConsumptionEnd(endDate);
7743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
7753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
7763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
7773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
7783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the time instant after which the key is no longer valid for encryption and signing.
7793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
7803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, the key is valid at any instant.
7813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
7823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @see #setKeyValidityForConsumptionEnd(Date)
7833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
7843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
7853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setKeyValidityForOriginationEnd(Date endDate) {
7861b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin            mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(endDate);
7873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
7883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
7893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
7903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
7913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the time instant after which the key is no longer valid for decryption and
7923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * verification.
7933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
7943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, the key is valid at any instant.
7953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
7963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @see #setKeyValidityForOriginationEnd(Date)
7973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
7983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
7993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setKeyValidityForConsumptionEnd(Date endDate) {
8001b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin            mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(endDate);
8013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
8023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
8033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
8043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
8053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the set of digests algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which
8063867709fb3840fa26072fef66ba7121a0e41871fAlex Klyubin         * the key can be used. Attempts to use the key with any other digest algorithm will be
8073867709fb3840fa26072fef66ba7121a0e41871fAlex Klyubin         * rejected.
8083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
8093867709fb3840fa26072fef66ba7121a0e41871fAlex Klyubin         * <p>This must be specified for signing/verification keys and RSA encryption/decryption
8103867709fb3840fa26072fef66ba7121a0e41871fAlex Klyubin         * keys used with RSA OAEP padding scheme because these operations involve a digest. For
8113867709fb3840fa26072fef66ba7121a0e41871fAlex Klyubin         * HMAC keys, the default is the digest associated with the key algorithm (e.g.,
812c58153b2d7418f44f2b0e397478be808e91decefAlex Klyubin         * {@code SHA-256} for key algorithm {@code HmacSHA256}). HMAC keys cannot be authorized
813c58153b2d7418f44f2b0e397478be808e91decefAlex Klyubin         * for more than one digest.
8143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
815dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * <p>For private keys used for TLS/SSL client or server authentication it is usually
816dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * necessary to authorize the use of no digest ({@link KeyProperties#DIGEST_NONE}). This is
817dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * because TLS/SSL stacks typically generate the necessary digest(s) themselves and then use
818dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * a private key to sign it.
819dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         *
820dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * <p>See {@link KeyProperties}.{@code DIGEST} constants.
8213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
8223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
8233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setDigests(@KeyProperties.DigestEnum String... digests) {
8243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mDigests = ArrayUtils.cloneIfNotEmpty(digests);
8253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
8263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
8273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
8283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
8293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the set of padding schemes (e.g., {@code PKCS7Padding}, {@code OAEPPadding},
8303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * {@code PKCS1Padding}, {@code NoPadding}) with which the key can be used when
8313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * encrypting/decrypting. Attempts to use the key with any other padding scheme will be
8323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * rejected.
8333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
8343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>This must be specified for keys which are used for encryption/decryption.
8353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
836dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * <p>For RSA private keys used by TLS/SSL servers to authenticate themselves to clients it
837dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * is usually necessary to authorize the use of no/any padding
838e4928a2912297751108c7045ce3343ec63edcc01Alex Klyubin         * ({@link KeyProperties#ENCRYPTION_PADDING_NONE}) and/or PKCS#1 encryption padding
839e4928a2912297751108c7045ce3343ec63edcc01Alex Klyubin         * ({@link KeyProperties#ENCRYPTION_PADDING_RSA_PKCS1}). This is because RSA decryption is
840dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * required by some cipher suites, and some stacks request decryption using no padding
841dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         * whereas others request PKCS#1 padding.
842dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin         *
8433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants.
8443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
8453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
8463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setEncryptionPaddings(
8473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                @KeyProperties.EncryptionPaddingEnum String... paddings) {
8483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
8493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
8503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
8513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
8523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
8533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key
8543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * can be used when signing/verifying. Attempts to use the key with any other padding scheme
8553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * will be rejected.
8563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
8573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>This must be specified for RSA keys which are used for signing/verification.
8583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
8593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants.
8603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
8613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
8623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setSignaturePaddings(
8633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                @KeyProperties.SignaturePaddingEnum String... paddings) {
8643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings);
8653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
8663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
8673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
8683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
869a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin         * Sets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be
870a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin         * used when encrypting/decrypting. Attempts to use the key with any other block modes will
871a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin         * be rejected.
8723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
873a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin         * <p>This must be specified for symmetric encryption/decryption keys.
8743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
8753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants.
8763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
8773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
8783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setBlockModes(@KeyProperties.BlockModeEnum String... blockModes) {
8793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
8803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
8813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
8823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
8833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
8843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Sets whether encryption using this key must be sufficiently randomized to produce
8853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * different ciphertexts for the same plaintext every time. The formal cryptographic
8863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * property being required is <em>indistinguishability under chosen-plaintext attack
8873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * ({@code IND-CPA})</em>. This property is important because it mitigates several classes
8883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * of weaknesses due to which ciphertext may leak information about plaintext. For example,
8893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * if a given plaintext always produces the same ciphertext, an attacker may see the
8903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * repeated ciphertexts and be able to deduce something about the plaintext.
8913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
8923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>By default, {@code IND-CPA} is required.
8933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
8943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>When {@code IND-CPA} is required:
8953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <ul>
8963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <li>encryption/decryption transformation which do not offer {@code IND-CPA}, such as
8973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * {@code ECB} with a symmetric encryption algorithm, or RSA encryption/decryption without
8983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * padding, are prohibited;</li>
899a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin         * <li>in block modes which use an IV, such as {@code GCM}, {@code CBC}, and {@code CTR},
9003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * caller-provided IVs are rejected when encrypting, to ensure that only random IVs are
9013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * used.</li>
9023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * </ul>
9033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
9043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <p>Before disabling this requirement, consider the following approaches instead:
9053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <ul>
9063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <li>If you are generating a random IV for encryption and then initializing a {@code}
9073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Cipher using the IV, the solution is to let the {@code Cipher} generate a random IV
9083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * instead. This will occur if the {@code Cipher} is initialized for encryption without an
9093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * IV. The IV can then be queried via {@link Cipher#getIV()}.</li>
9103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <li>If you are generating a non-random IV (e.g., an IV derived from something not fully
9113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * random, such as the name of the file being encrypted, or transaction ID, or password,
9123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * or a device identifier), consider changing your design to use a random IV which will then
9133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * be provided in addition to the ciphertext to the entities which need to decrypt the
9143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * ciphertext.</li>
9153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <li>If you are using RSA encryption without padding, consider switching to encryption
9163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * padding schemes which offer {@code IND-CPA}, such as PKCS#1 or OAEP.</li>
9173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * </ul>
9183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
9193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
9203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setRandomizedEncryptionRequired(boolean required) {
9213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mRandomizedEncryptionRequired = required;
9223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
9233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
9243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
9253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
92683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * Sets whether this key is authorized to be used only if the user has been authenticated.
9273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
92883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <p>By default, the key is authorized to be used regardless of whether the user has been
92983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * authenticated.
9303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
93183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <p>When user authentication is required:
93283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <ul>
93383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <li>The key can only be generated if secure lock screen is set up (see
93483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * {@link KeyguardManager#isDeviceSecure()}). Additionally, if the key requires that user
93583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * authentication takes place for every use of the key (see
93683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * {@link #setUserAuthenticationValidityDurationSeconds(int)}), at least one fingerprint
93783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * must be enrolled (see {@link FingerprintManager#hasEnrolledFingerprints()}).</li>
93883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <li>The use of the key must be authorized by the user by authenticating to this Android
93983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * device using a subset of their secure lock screen credentials such as
94083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * password/PIN/pattern or fingerprint.
9413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
9423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * information</a>.
94383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <li>The key will become <em>irreversibly invalidated</em> once the secure lock screen is
94483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * disabled (reconfigured to None, Swipe or other mode which does not authenticate the user)
94583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * or when the secure lock screen is forcibly reset (e.g., by a Device Administrator).
94683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * Additionally, if the key requires that user authentication takes place for every use of
94783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * the key, it is also irreversibly invalidated once a new fingerprint is enrolled or once\
94883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * no more fingerprints are enrolled. Attempts to initialize cryptographic operations using
94983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * such keys will throw {@link KeyPermanentlyInvalidatedException}.</li>
95083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * </ul>
9513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
95283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <p>This authorization applies only to secret key and private key operations. Public key
95383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * operations are not restricted.
9543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
9553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @see #setUserAuthenticationValidityDurationSeconds(int)
95683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * @see KeyguardManager#isDeviceSecure()
95783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * @see FingerprintManager#hasEnrolledFingerprints()
9583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
9593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
9603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setUserAuthenticationRequired(boolean required) {
9613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mUserAuthenticationRequired = required;
9623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
9633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
9643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
9653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
96683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * Sets the duration of time (seconds) for which this key is authorized to be used after the
96783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * user is successfully authenticated. This has effect if the key requires user
96883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * authentication for its use (see {@link #setUserAuthenticationRequired(boolean)}).
96983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         *
97083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <p>By default, if user authentication is required, it must take place for every use of
97183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * the key.
97283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         *
97383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <p>Cryptographic operations involving keys which require user authentication to take
97483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * place for every operation can only use fingerprint authentication. This is achieved by
97583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * initializing a cryptographic operation ({@link Signature}, {@link Cipher}, {@link Mac})
97683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * with the key, wrapping it into a {@link FingerprintManager.CryptoObject}, invoking
97783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * {@code FingerprintManager.authenticate} with {@code CryptoObject}, and proceeding with
97883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * the cryptographic operation only if the authentication flow succeeds.
97983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         *
98083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * <p>Cryptographic operations involving keys which are authorized to be used for a duration
98183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * of time after a successful user authentication event can only use secure lock screen
98283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * authentication. These cryptographic operations will throw
98383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * {@link UserNotAuthenticatedException} during initialization if the user needs to be
98483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * authenticated to proceed. This situation can be resolved by the user unlocking the secure
98583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * lock screen of the Android or by going through the confirm credential flow initiated by
98683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * {@link KeyguardManager#createConfirmDeviceCredentialIntent(CharSequence, CharSequence)}.
98783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * Once resolved, initializing a new cryptographic operation using this key (or any other
98883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * key which is authorized to be used for a fixed duration of time after user
98983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * authentication) should succeed provided the user authentication flow completed
99083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * successfully.
99183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         *
99283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * @param seconds duration in seconds or {@code -1} if user authentication must take place
99383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         *        for every use of the key.
9943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         *
9953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * @see #setUserAuthenticationRequired(boolean)
99683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * @see FingerprintManager
99783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * @see FingerprintManager.CryptoObject
99883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin         * @see KeyguardManager
9993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
10003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
10013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setUserAuthenticationValidityDurationSeconds(
10023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                @IntRange(from = -1) int seconds) {
10031b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin            if (seconds < -1) {
10041b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin                throw new IllegalArgumentException("seconds must be -1 or larger");
10051b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin            }
10063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            mUserAuthenticationValidityDurationSeconds = seconds;
10073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return this;
10083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
10093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin
10108d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        /*
10118d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * TODO(swillden): Update this documentation to describe the hardware and software root
10128d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * keys, including information about CRL/OCSP services for discovering revocations, and to
10138d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * link to documentation of the extension format and content.
10148d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         */
10158d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        /**
10168d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * Sets whether an attestation certificate will be generated for this key pair, and what
10178d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * challenge value will be placed in the certificate.  The attestation certificate chain
10188d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * can be retrieved with with {@link java.security.KeyStore#getCertificateChain(String)}.
10198d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         *
10208d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * <p>If {@code attestationChallenge} is not {@code null}, the public key certificate for
10218d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * this key pair will contain an extension that describes the details of the key's
10228d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * configuration and authorizations, including the {@code attestationChallenge} value. If
10238d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * the key is in secure hardware, and if the secure hardware supports attestation, the
10248d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * certificate will be signed by a chain of certificates rooted at a trustworthy CA key.
10258d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * Otherwise the chain will be rooted at an untrusted certificate.
10268d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         *
10278d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * <p>The purpose of the challenge value is to enable relying parties to verify that the key
10288d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * was created in response to a specific request. If attestation is desired but no
10298d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * challenged is needed, any non-{@code null} value may be used, including an empty byte
10308d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * array.
10318d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         *
10328d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * <p>If {@code attestationChallenge} is {@code null}, and this spec is used to generate an
10338d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * asymmetric (RSA or EC) key pair, the public key certificate will be self-signed if the
10348d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * key has purpose {@link KeyProperties#PURPOSE_SIGN} (see
10358d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * {@link #KeyGenParameterSpec(String, int)). If the key does not have purpose
10368d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * {@link KeyProperties#PURPOSE_SIGN}, it is not possible to use the key to sign a
10378d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * certificate, so the public key certificate will contain a dummy signature.
10388d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         *
10398d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * <p>Symmetric keys, such as AES and HMAC keys, do not have public key certificates. If a
10408d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * {@code getAttestationChallenge} returns non-{@code null} and the spec is used to
10418d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * generate a symmetric (AES or HMAC) key, {@link KeyGenerator#generateKey()} will throw
10428d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * {@link java.security.InvalidAlgorithmParameterException}.
10438d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         *
10448d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * @see Builder#setAttestationChallenge(String attestationChallenge)
10458d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         */
10468d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        @NonNull
10478d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        public Builder setAttestationChallenge(byte[] attestationChallenge) {
10488d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden            mAttestationChallenge = attestationChallenge;
10498d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden            return this;
10508d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        }
10518d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden
10528d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        /**
10538d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * @hide Only system apps can use this method.
10548d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         *
10558d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         * Sets whether to include a temporary unique ID field in the attestation certificate.
10568d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden         */
10578d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        @NonNull
10588d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        public Builder setUniqueIdIncluded(boolean uniqueIdIncluded) {
10598d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden            mUniqueIdIncluded = uniqueIdIncluded;
10608d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden            return this;
10618d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden        }
10628d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden
10633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        /**
10643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * Builds an instance of {@code KeyGenParameterSpec}.
10653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         */
10663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        @NonNull
10673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public KeyGenParameterSpec build() {
10683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            return new KeyGenParameterSpec(
10693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mKeystoreAlias,
10703876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin                    mUid,
10713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mKeySize,
10723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mSpec,
10733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mCertificateSubject,
10743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mCertificateSerialNumber,
10753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mCertificateNotBefore,
10763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mCertificateNotAfter,
10773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mKeyValidityStart,
10783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mKeyValidityForOriginationEnd,
10793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mKeyValidityForConsumptionEnd,
10803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mPurposes,
10813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mDigests,
10823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mEncryptionPaddings,
10833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mSignaturePaddings,
10843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mBlockModes,
10853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mRandomizedEncryptionRequired,
10863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mUserAuthenticationRequired,
10878d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden                    mUserAuthenticationValidityDurationSeconds,
10888d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden                    mAttestationChallenge,
10898d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden                    mUniqueIdIncluded);
10903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        }
10913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    }
10923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin}
1093