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 44682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * decryption), with what parameters (e.g., only with a particular padding scheme or digest), and 45682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * the key's validity start and end dates. Key use authorizations expressed in the spec apply 46682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * only to 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 * 94682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * <p><h3>Known issues</h3> 95682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * A known bug in Android 6.0 (API Level 23) causes user authentication-related authorizations to be 96682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * enforced even for public keys. To work around this issue extract the public key material to use 97682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * outside of Android Keystore. For example: 98682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * <pre> {@code 99682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * PublicKey unrestrictedPublicKey = 100682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * KeyFactory.getInstance(publicKey.getAlgorithm()).generatePublic( 101682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * new X509EncodedKeySpec(publicKey.getEncoded())); 102682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * }</pre> 103682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * 10472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <p><h3>Example: NIST P-256 EC key pair for signing/verification using ECDSA</h3> 10572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * This example illustrates how to generate a NIST P-256 (aka secp256r1 aka prime256v1) EC key pair 10672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * in the Android KeyStore system under alias {@code key1} where the private key is authorized to be 10772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * used only for signing using SHA-256, SHA-384, or SHA-512 digest and only if the user has been 108682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * authenticated within the last five minutes. The use of the public key is unrestricted (See Known 109682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * Issues). 1103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <pre> {@code 1113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance( 11272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore"); 1133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keyPairGenerator.initialize( 1141b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * new KeyGenParameterSpec.Builder( 1151b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * "key1", 11672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyProperties.PURPOSE_SIGN) 11772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1")) 1181b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * .setDigests(KeyProperties.DIGEST_SHA256, 1191b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * KeyProperties.DIGEST_SHA384, 1201b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * KeyProperties.DIGEST_SHA512) 12172245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * // Only permit the private key to be used if the user authenticated 1223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * // within the last five minutes. 1233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * .setUserAuthenticationRequired(true) 1243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * .setUserAuthenticationValidityDurationSeconds(5 * 60) 1253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * .build()); 1263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyPair keyPair = keyPairGenerator.generateKeyPair(); 12772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * Signature signature = Signature.getInstance("SHA256withECDSA"); 12872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * signature.initSign(keyPair.getPrivate()); 12972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * ... 13072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * 13172245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * // The key pair can also be obtained from the Android Keystore any time as follows: 13272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 13372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * keyStore.load(null); 13472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null); 13572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey(); 13672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * }</pre> 13772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * 13872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <p><h3>Example: RSA key pair for signing/verification using RSA-PSS</h3> 13972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * This example illustrates how to generate an RSA key pair in the Android KeyStore system under 14072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * alias {@code key1} authorized to be used only for signing using the RSA-PSS signature padding 141682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * scheme with SHA-256 or SHA-512 digests. The use of the public key is unrestricted. 14272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <pre> {@code 14372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance( 14472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore"); 14572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * keyPairGenerator.initialize( 14672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * new KeyGenParameterSpec.Builder( 14772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * "key1", 14872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyProperties.PURPOSE_SIGN) 14972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512) 15072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS) 15172245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * .build()); 15272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyPair keyPair = keyPairGenerator.generateKeyPair(); 15372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * Signature signature = Signature.getInstance("SHA256withRSA/PSS"); 15472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * signature.initSign(keyPair.getPrivate()); 15572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * ... 1563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 1573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * // The key pair can also be obtained from the Android Keystore any time as follows: 1583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 1593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keyStore.load(null); 1603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null); 1613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey(); 1623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * }</pre> 1633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 16472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <p><h3>Example: RSA key pair for encryption/decryption using RSA OAEP</h3> 16572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * This example illustrates how to generate an RSA key pair in the Android KeyStore system under 16672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * alias {@code key1} where the private key is authorized to be used only for decryption using RSA 167682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * OAEP encryption padding scheme with SHA-256 or SHA-512 digests. The use of the public key is 168682c24e22811d4ee17ae1cd61bf255c3f7e722b7Trevor Johns * unrestricted. 16972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <pre> {@code 17072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance( 17172245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore"); 17272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * keyPairGenerator.initialize( 17372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * new KeyGenParameterSpec.Builder( 17472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * "key1", 17572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyProperties.PURPOSE_DECRYPT) 17672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512) 17772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP) 17872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * .build()); 17972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyPair keyPair = keyPairGenerator.generateKeyPair(); 18072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); 18172245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); 18272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * ... 18372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * 18472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * // The key pair can also be obtained from the Android Keystore any time as follows: 18572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 18672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * keyStore.load(null); 18772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null); 18872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey(); 18972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * }</pre> 19072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * 19172245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <p><h3>Example: AES key for encryption/decryption in GCM mode</h3> 1923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * The following example illustrates how to generate an AES key in the Android KeyStore system under 193a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * alias {@code key2} authorized to be used only for encryption/decryption in GCM mode with no 194cb3bb3f03ac253052cd42a32a54e63c2ee9b9a95Alex Klyubin * padding. 1953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <pre> {@code 1963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyGenerator keyGenerator = KeyGenerator.getInstance( 19772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore"); 1983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keyGenerator.initialize( 1993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * new KeyGenParameterSpec.Builder("key2", 2003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) 201a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * .setBlockModes(KeyProperties.BLOCK_MODE_GCM) 202a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) 2033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * .build()); 2043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * SecretKey key = keyGenerator.generateKey(); 2053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 20672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); 20772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * cipher.init(Cipher.ENCRYPT_MODE, key); 20872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * ... 20972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * 21072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * // The key can also be obtained from the Android Keystore any time as follows: 21172245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 21272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * keyStore.load(null); 21372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * key = (SecretKey) keyStore.getKey("key2", null); 21472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * }</pre> 21572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * 21672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <p><h3>Example: HMAC key for generating a MAC using SHA-256</h3> 21772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * This example illustrates how to generate an HMAC key in the Android KeyStore system under alias 21872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * {@code key2} authorized to be used only for generating an HMAC using SHA-256. 21972245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * <pre> {@code 22072245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyGenerator keyGenerator = KeyGenerator.getInstance( 22172245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * KeyProperties.KEY_ALGORITHM_HMAC_SHA256, "AndroidKeyStore"); 22272245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * keyGenerator.initialize( 22372245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * new KeyGenParameterSpec.Builder("key2", KeyProperties.PURPOSE_SIGN).build()); 22472245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * SecretKey key = keyGenerator.generateKey(); 22572245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * Mac mac = Mac.getInstance("HmacSHA256"); 22672245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * mac.init(key); 22772245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * ... 22872245d7909763dd1ed4cf4082aa1042e0ea61f4dAlex Klyubin * 2293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * // The key can also be obtained from the Android Keystore any time as follows: 2303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 2313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keyStore.load(null); 2323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * key = (SecretKey) keyStore.getKey("key2", null); 2333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * }</pre> 2343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 2353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinpublic final class KeyGenParameterSpec implements AlgorithmParameterSpec { 2363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 2373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake"); 2383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1"); 2393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1970 2403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048 2413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 2423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final String mKeystoreAlias; 2433876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin private final int mUid; 2443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final int mKeySize; 2453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final AlgorithmParameterSpec mSpec; 2463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final X500Principal mCertificateSubject; 2473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final BigInteger mCertificateSerialNumber; 2483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final Date mCertificateNotBefore; 2493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final Date mCertificateNotAfter; 2503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final Date mKeyValidityStart; 2513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final Date mKeyValidityForOriginationEnd; 2523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final Date mKeyValidityForConsumptionEnd; 2533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final @KeyProperties.PurposeEnum int mPurposes; 2543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final @KeyProperties.DigestEnum String[] mDigests; 2553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; 2563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; 2573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final @KeyProperties.BlockModeEnum String[] mBlockModes; 2583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final boolean mRandomizedEncryptionRequired; 2593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final boolean mUserAuthenticationRequired; 2603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final int mUserAuthenticationValidityDurationSeconds; 2618d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden private final byte[] mAttestationChallenge; 2628d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden private final boolean mUniqueIdIncluded; 263adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden private final boolean mUserAuthenticationValidWhileOnBody; 264c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden private final boolean mInvalidatedByBiometricEnrollment; 2653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 2663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 2673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @hide should be built with Builder 2683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 2693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public KeyGenParameterSpec( 2703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin String keyStoreAlias, 2713876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin int uid, 2723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin int keySize, 2733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin AlgorithmParameterSpec spec, 2743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin X500Principal certificateSubject, 2753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin BigInteger certificateSerialNumber, 2763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin Date certificateNotBefore, 2773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin Date certificateNotAfter, 2783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin Date keyValidityStart, 2793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin Date keyValidityForOriginationEnd, 2803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin Date keyValidityForConsumptionEnd, 2813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @KeyProperties.PurposeEnum int purposes, 2823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @KeyProperties.DigestEnum String[] digests, 2833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @KeyProperties.EncryptionPaddingEnum String[] encryptionPaddings, 2843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @KeyProperties.SignaturePaddingEnum String[] signaturePaddings, 2853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @KeyProperties.BlockModeEnum String[] blockModes, 2863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin boolean randomizedEncryptionRequired, 2873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin boolean userAuthenticationRequired, 2888d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden int userAuthenticationValidityDurationSeconds, 2898d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden byte[] attestationChallenge, 290adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden boolean uniqueIdIncluded, 291c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden boolean userAuthenticationValidWhileOnBody, 292c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden boolean invalidatedByBiometricEnrollment) { 2933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (TextUtils.isEmpty(keyStoreAlias)) { 2943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new IllegalArgumentException("keyStoreAlias must not be empty"); 2953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 2963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 2973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (certificateSubject == null) { 2983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin certificateSubject = DEFAULT_CERT_SUBJECT; 2993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (certificateNotBefore == null) { 3013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin certificateNotBefore = DEFAULT_CERT_NOT_BEFORE; 3023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (certificateNotAfter == null) { 3043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin certificateNotAfter = DEFAULT_CERT_NOT_AFTER; 3053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (certificateSerialNumber == null) { 3073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin certificateSerialNumber = DEFAULT_CERT_SERIAL_NUMBER; 3083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 3103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (certificateNotAfter.before(certificateNotBefore)) { 3113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new IllegalArgumentException("certificateNotAfter < certificateNotBefore"); 3123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 3143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeystoreAlias = keyStoreAlias; 3153876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin mUid = uid; 3163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeySize = keySize; 3173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mSpec = spec; 3183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mCertificateSubject = certificateSubject; 3193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mCertificateSerialNumber = certificateSerialNumber; 3201b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mCertificateNotBefore = Utils.cloneIfNotNull(certificateNotBefore); 3211b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mCertificateNotAfter = Utils.cloneIfNotNull(certificateNotAfter); 3221b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart); 3231b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd); 3241b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd); 3253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mPurposes = purposes; 3263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mDigests = ArrayUtils.cloneIfNotEmpty(digests); 3273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mEncryptionPaddings = 3283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings)); 3293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings)); 3303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes)); 3313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mRandomizedEncryptionRequired = randomizedEncryptionRequired; 3323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mUserAuthenticationRequired = userAuthenticationRequired; 3333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds; 3348d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden mAttestationChallenge = Utils.cloneIfNotNull(attestationChallenge); 3358d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden mUniqueIdIncluded = uniqueIdIncluded; 336adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody; 337c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment; 3383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 3403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 3413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the alias that will be used in the {@code java.security.KeyStore} 3423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * in conjunction with the {@code AndroidKeyStore}. 3433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 3441b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin @NonNull 3453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public String getKeystoreAlias() { 3463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mKeystoreAlias; 3473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 3493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 3503876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin * Returns the UID which will own the key. {@code -1} is an alias for the UID of the current 3513876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin * process. 3523876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin * 3533876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin * @hide 3543876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin */ 3553876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin public int getUid() { 3563876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin return mUid; 3573876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin } 3583876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin 3593876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin /** 3603ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin * Returns the requested key size. If {@code -1}, the size should be looked up from 3613ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin * {@link #getAlgorithmParameterSpec()}, if provided, otherwise an algorithm-specific default 3623ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin * size should be used. 3633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 3643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public int getKeySize() { 3653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mKeySize; 3663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 3683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 3691b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * Returns the key algorithm-specific {@link AlgorithmParameterSpec} that will be used for 3701b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * creation of the key or {@code null} if algorithm-specific defaults should be used. 3713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 3721b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin @Nullable 3733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public AlgorithmParameterSpec getAlgorithmParameterSpec() { 3743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mSpec; 3753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 3773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 3783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the subject distinguished name to be used on the X.509 certificate that will be put 3793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * in the {@link java.security.KeyStore}. 3803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 3813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 3823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public X500Principal getCertificateSubject() { 3833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mCertificateSubject; 3843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 3863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 3873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the serial number to be used on the X.509 certificate that will be put in the 3883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link java.security.KeyStore}. 3893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 3903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 3913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public BigInteger getCertificateSerialNumber() { 3923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mCertificateSerialNumber; 3933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 3953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 3963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the start date to be used on the X.509 certificate that will be put in the 3973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link java.security.KeyStore}. 3983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 3993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 4003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Date getCertificateNotBefore() { 4011b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin return Utils.cloneIfNotNull(mCertificateNotBefore); 4023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 4033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 4043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 4053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the end date to be used on the X.509 certificate that will be put in the 4063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link java.security.KeyStore}. 4073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 4083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 4093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Date getCertificateNotAfter() { 4101b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin return Utils.cloneIfNotNull(mCertificateNotAfter); 4113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 4123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 4133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 4143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the time instant before which the key is not yet valid or {@code null} if not 4153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * restricted. 4163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 4173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @Nullable 4183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Date getKeyValidityStart() { 4191b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin return Utils.cloneIfNotNull(mKeyValidityStart); 4203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 4213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 4223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 4233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the time instant after which the key is no longer valid for decryption and 4243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * verification or {@code null} if not restricted. 4253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 4263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @Nullable 4273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Date getKeyValidityForConsumptionEnd() { 4281b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin return Utils.cloneIfNotNull(mKeyValidityForConsumptionEnd); 4293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 4303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 4313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 4323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the time instant after which the key is no longer valid for encryption and signing 4333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * or {@code null} if not restricted. 4343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 4353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @Nullable 4363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Date getKeyValidityForOriginationEnd() { 4371b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin return Utils.cloneIfNotNull(mKeyValidityForOriginationEnd); 4383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 4393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 4403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 4413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the set of purposes (e.g., encrypt, decrypt, sign) for which the key can be used. 4423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Attempts to use the key for any other purpose will be rejected. 4433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 4443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code PURPOSE} flags. 4453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 4463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public @KeyProperties.PurposeEnum int getPurposes() { 4473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mPurposes; 4483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 4493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 4503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 4513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384} with which the 4523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * key can be used or {@code null} if not specified. 4533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 4543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code DIGEST} constants. 4553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 4563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @throws IllegalStateException if this set has not been specified. 4573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 4583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #isDigestsSpecified() 4593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 4603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 4613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public @KeyProperties.DigestEnum String[] getDigests() { 4623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (mDigests == null) { 4633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new IllegalStateException("Digests not specified"); 4643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 4653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return ArrayUtils.cloneIfNotEmpty(mDigests); 4663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 4673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 4683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 4693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns {@code true} if the set of digest algorithms with which the key can be used has been 4703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * specified. 4713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 4723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #getDigests() 4733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 4743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 4753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public boolean isDigestsSpecified() { 4763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mDigests != null; 4773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 4783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 4793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 4803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the set of padding schemes (e.g., {@code PKCS7Padding}, {@code OEAPPadding}, 4813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@code PKCS1Padding}, {@code NoPadding}) with which the key can be used when 4823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * encrypting/decrypting. Attempts to use the key with any other padding scheme will be 4833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * rejected. 4843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 4853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants. 4863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 4873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 4883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public @KeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() { 4893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings); 4903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 4913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 4923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 4933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Gets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key 4943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * can be used when signing/verifying. Attempts to use the key with any other padding scheme 4953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * will be rejected. 4963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 4973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants. 4983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 4993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 5003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public @KeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() { 5013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings); 5023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 5043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 505a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * Gets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be used 5063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * when encrypting/decrypting. Attempts to use the key with any other block modes will be 5073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * rejected. 5083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 5093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants. 5103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 5113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 5123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public @KeyProperties.BlockModeEnum String[] getBlockModes() { 5133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return ArrayUtils.cloneIfNotEmpty(mBlockModes); 5143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 5163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 5173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns {@code true} if encryption using this key must be sufficiently randomized to produce 5183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * different ciphertexts for the same plaintext every time. The formal cryptographic property 5193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * being required is <em>indistinguishability under chosen-plaintext attack ({@code 5203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * IND-CPA})</em>. This property is important because it mitigates several classes of 5213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * weaknesses due to which ciphertext may leak information about plaintext. For example, if a 5223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * given plaintext always produces the same ciphertext, an attacker may see the repeated 5233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * ciphertexts and be able to deduce something about the plaintext. 5243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 5253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public boolean isRandomizedEncryptionRequired() { 5263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mRandomizedEncryptionRequired; 5273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 5293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 53083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * Returns {@code true} if the key is authorized to be used only if the user has been 53183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * authenticated. 5323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 53383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <p>This authorization applies only to secret key and private key operations. Public key 53483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * operations are not restricted. 5353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 5363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #getUserAuthenticationValidityDurationSeconds() 53783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * @see Builder#setUserAuthenticationRequired(boolean) 5383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 5393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public boolean isUserAuthenticationRequired() { 5403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mUserAuthenticationRequired; 5413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 5433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 54483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * Gets the duration of time (seconds) for which this key is authorized to be used after the 54583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * user is successfully authenticated. This has effect only if user authentication is required 54683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * (see {@link #isUserAuthenticationRequired()}). 5473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 54883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <p>This authorization applies only to secret key and private key operations. Public key 54983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * operations are not restricted. 5503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 5513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @return duration in seconds or {@code -1} if authentication is required for every use of the 55283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * key. 5533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 5543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #isUserAuthenticationRequired() 55583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * @see Builder#setUserAuthenticationValidityDurationSeconds(int) 5563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 5573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public int getUserAuthenticationValidityDurationSeconds() { 5583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mUserAuthenticationValidityDurationSeconds; 5593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 5613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 5628d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * Returns the attestation challenge value that will be placed in attestation certificate for 5638d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * this key pair. 5648d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * 5658d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * <p>If this method returns non-{@code null}, the public key certificate for this key pair will 5668d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * contain an extension that describes the details of the key's configuration and 5678d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * authorizations, including the content of the attestation challenge value. If the key is in 5688d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * secure hardware, and if the secure hardware supports attestation, the certificate will be 5698d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * signed by a chain of certificates rooted at a trustworthy CA key. Otherwise the chain will 5708d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * be rooted at an untrusted certificate. 5718d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * 5728d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * <p>If this method returns {@code null}, and the spec is used to generate an asymmetric (RSA 5738d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * or EC) key pair, the public key will have a self-signed certificate if it has purpose {@link 5748d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * KeyProperties#PURPOSE_SIGN} (see {@link #KeyGenParameterSpec(String, int)). If does not have 5758d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * purpose {@link KeyProperties#PURPOSE_SIGN}, it will have a fake certificate. 5768d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * 5778d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * <p>Symmetric keys, such as AES and HMAC keys, do not have public key certificates. If a 5788d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * {@link KeyGenParameterSpec} with {@link #hasAttestationCertificate()} returning 5798d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * non-{@code null} is used to generate a symmetric (AES or HMAC) key, 5808d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * {@link KeyGenerator#generateKey())} will throw 5818d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * {@link java.security.InvalidAlgorithmParameterException}. 5828d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * 5838d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * @see Builder#setAttestationChallenge(byte[]) 5848d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden */ 5858d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden public byte[] getAttestationChallenge() { 5868d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden return Utils.cloneIfNotNull(mAttestationChallenge); 5878d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden } 5888d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden 5898d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden /** 5908d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * @hide This is a system-only API 5918d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * 5928d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * Returns {@code true} if the attestation certificate will contain a unique ID field. 5938d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden */ 5948d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden public boolean isUniqueIdIncluded() { 5958d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden return mUniqueIdIncluded; 5968d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden } 5978d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden 5988d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden /** 59926e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * Returns {@code true} if the key will remain authorized only until the device is removed from 60026e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * the user's body, up to the validity duration. This option has no effect on keys that don't 60126e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * have an authentication validity duration, and has no effect if the device lacks an on-body 60226e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * sensor. 603adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden * 604adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden * <p>Authorization applies only to secret key and private key operations. Public key operations 605adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden * are not restricted. 606adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden * 607adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden * @see #isUserAuthenticationRequired() 608adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden * @see #getUserAuthenticationValidityDurationSeconds() 609adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden * @see Builder#setUserAuthenticationValidWhileOnBody(boolean) 610adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden */ 611adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden public boolean isUserAuthenticationValidWhileOnBody() { 612adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden return mUserAuthenticationValidWhileOnBody; 613adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden } 614adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden 615adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden /** 616c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * Returns {@code true} if the key is irreversibly invalidated when a new fingerprint is 617c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * enrolled or all enrolled fingerprints are removed. This has effect only for keys that 618c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * require fingerprint user authentication for every use. 619c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * 620c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * @see #isUserAuthenticationRequired() 621c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * @see #getUserAuthenticationValidityDurationSeconds() 622c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * @see Builder#setInvalidatedByBiometricEnrollment(boolean) 623c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden */ 624c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden public boolean isInvalidatedByBiometricEnrollment() { 625c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden return mInvalidatedByBiometricEnrollment; 626c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden } 627c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden 628c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden /** 6293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Builder of {@link KeyGenParameterSpec} instances. 6303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 6313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public final static class Builder { 6323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final String mKeystoreAlias; 6333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private @KeyProperties.PurposeEnum int mPurposes; 6343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 6353876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin private int mUid = KeyStore.UID_SELF; 6363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private int mKeySize = -1; 6373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private AlgorithmParameterSpec mSpec; 6383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private X500Principal mCertificateSubject; 6393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private BigInteger mCertificateSerialNumber; 6403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private Date mCertificateNotBefore; 6413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private Date mCertificateNotAfter; 6423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private Date mKeyValidityStart; 6433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private Date mKeyValidityForOriginationEnd; 6443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private Date mKeyValidityForConsumptionEnd; 6453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private @KeyProperties.DigestEnum String[] mDigests; 6463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; 6473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; 6483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private @KeyProperties.BlockModeEnum String[] mBlockModes; 6493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private boolean mRandomizedEncryptionRequired = true; 6503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private boolean mUserAuthenticationRequired; 6513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private int mUserAuthenticationValidityDurationSeconds = -1; 6528d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden private byte[] mAttestationChallenge = null; 6538d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden private boolean mUniqueIdIncluded = false; 654adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden private boolean mUserAuthenticationValidWhileOnBody; 655c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden private boolean mInvalidatedByBiometricEnrollment = true; 6563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 6573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 6583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Creates a new instance of the {@code Builder}. 6593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 6603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @param keystoreAlias alias of the entry in which the generated key will appear in 6611b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * Android KeyStore. Must not be empty. 6623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @param purposes set of purposes (e.g., encrypt, decrypt, sign) for which the key can be 6633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * used. Attempts to use the key for any other purpose will be rejected. 6643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 6653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>If the set of purposes for which the key can be used does not contain 6663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link KeyProperties#PURPOSE_SIGN}, the self-signed certificate generated by 6673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link KeyPairGenerator} of {@code AndroidKeyStore} provider will contain an 6683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * invalid signature. This is OK if the certificate is only used for obtaining the 6693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * public key from Android KeyStore. 6703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 6713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code PURPOSE} flags. 6723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 6733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder(@NonNull String keystoreAlias, @KeyProperties.PurposeEnum int purposes) { 6743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (keystoreAlias == null) { 6753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new NullPointerException("keystoreAlias == null"); 6761b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin } else if (keystoreAlias.isEmpty()) { 6771b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin throw new IllegalArgumentException("keystoreAlias must not be empty"); 6783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 6793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeystoreAlias = keystoreAlias; 6803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mPurposes = purposes; 6813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 6823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 6833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 6843876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin * Sets the UID which will own the key. 6853876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin * 6863876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin * @param uid UID or {@code -1} for the UID of the current process. 6873876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin * 6883876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin * @hide 6893876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin */ 6903876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin @NonNull 6913876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin public Builder setUid(int uid) { 6923876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin mUid = uid; 6933876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin return this; 6943876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin } 6953876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin 6963876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin /** 6973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the size (in bits) of the key to be generated. For instance, for RSA keys this sets 6983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * the modulus size, for EC keys this selects a curve with a matching field size, and for 6993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * symmetric keys this sets the size of the bitstring which is their key material. 7003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7013ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin * <p>The default key size is specific to each key algorithm. If key size is not set 7023ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin * via this method, it should be looked up from the algorithm-specific parameters (if any) 7033ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin * provided via 7043ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin * {@link #setAlgorithmParameterSpec(AlgorithmParameterSpec) setAlgorithmParameterSpec}. 7053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 7063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 7073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setKeySize(int keySize) { 7083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (keySize < 0) { 7093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new IllegalArgumentException("keySize < 0"); 7103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 7113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeySize = keySize; 7123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 7133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 7143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 7153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 7163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the algorithm-specific key generation parameters. For example, for RSA keys this may 7171b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * be an instance of {@link java.security.spec.RSAKeyGenParameterSpec} whereas for EC keys 7181b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * this may be an instance of {@link java.security.spec.ECGenParameterSpec}. 7191b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * 7201b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * <p>These key generation parameters must match other explicitly set parameters (if any), 7211b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * such as key size. 7223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 7233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) { 7243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (spec == null) { 7253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new NullPointerException("spec == null"); 7263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 7273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mSpec = spec; 7283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 7293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 7303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 7313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 7323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the subject used for the self-signed certificate of the generated key pair. 7333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, the subject is {@code CN=fake}. 7353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 7363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 7373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setCertificateSubject(@NonNull X500Principal subject) { 7383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (subject == null) { 7393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new NullPointerException("subject == null"); 7403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 7413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mCertificateSubject = subject; 7423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 7433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 7443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 7453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 7463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the serial number used for the self-signed certificate of the generated key pair. 7473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, the serial number is {@code 1}. 7493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 7503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 7513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setCertificateSerialNumber(@NonNull BigInteger serialNumber) { 7523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (serialNumber == null) { 7533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new NullPointerException("serialNumber == null"); 7543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 7553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mCertificateSerialNumber = serialNumber; 7563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 7573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 7583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 7593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 7603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the start of the validity period for the self-signed certificate of the generated 7613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * key pair. 7623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, this date is {@code Jan 1 1970}. 7643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 7653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 7663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setCertificateNotBefore(@NonNull Date date) { 7673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (date == null) { 7683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new NullPointerException("date == null"); 7693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 7701b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mCertificateNotBefore = Utils.cloneIfNotNull(date); 7713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 7723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 7733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 7743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 7753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the end of the validity period for the self-signed certificate of the generated key 7763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * pair. 7773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, this date is {@code Jan 1 2048}. 7793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 7803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 7813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setCertificateNotAfter(@NonNull Date date) { 7823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (date == null) { 7833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new NullPointerException("date == null"); 7843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 7851b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mCertificateNotAfter = Utils.cloneIfNotNull(date); 7863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 7873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 7883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 7893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 7903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the time instant before which the key is not yet valid. 7913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, the key is valid at any instant. 7933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #setKeyValidityEnd(Date) 7953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 7963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 7973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setKeyValidityStart(Date startDate) { 7981b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mKeyValidityStart = Utils.cloneIfNotNull(startDate); 7993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 8003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 8013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 8023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 8033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the time instant after which the key is no longer valid. 8043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 8053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, the key is valid at any instant. 8063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 8073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #setKeyValidityStart(Date) 8083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #setKeyValidityForConsumptionEnd(Date) 8093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #setKeyValidityForOriginationEnd(Date) 8103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 8113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 8123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setKeyValidityEnd(Date endDate) { 8133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin setKeyValidityForOriginationEnd(endDate); 8143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin setKeyValidityForConsumptionEnd(endDate); 8153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 8163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 8173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 8183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 8193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the time instant after which the key is no longer valid for encryption and signing. 8203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 8213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, the key is valid at any instant. 8223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 8233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #setKeyValidityForConsumptionEnd(Date) 8243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 8253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 8263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setKeyValidityForOriginationEnd(Date endDate) { 8271b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(endDate); 8283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 8293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 8303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 8313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 8323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the time instant after which the key is no longer valid for decryption and 8333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * verification. 8343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 8353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, the key is valid at any instant. 8363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 8373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #setKeyValidityForOriginationEnd(Date) 8383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 8393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 8403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setKeyValidityForConsumptionEnd(Date endDate) { 8411b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(endDate); 8423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 8433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 8443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 8453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 8463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the set of digests algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which 8473867709fb3840fa26072fef66ba7121a0e41871fAlex Klyubin * the key can be used. Attempts to use the key with any other digest algorithm will be 8483867709fb3840fa26072fef66ba7121a0e41871fAlex Klyubin * rejected. 8493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 8503867709fb3840fa26072fef66ba7121a0e41871fAlex Klyubin * <p>This must be specified for signing/verification keys and RSA encryption/decryption 8513867709fb3840fa26072fef66ba7121a0e41871fAlex Klyubin * keys used with RSA OAEP padding scheme because these operations involve a digest. For 8523867709fb3840fa26072fef66ba7121a0e41871fAlex Klyubin * HMAC keys, the default is the digest associated with the key algorithm (e.g., 853c58153b2d7418f44f2b0e397478be808e91decefAlex Klyubin * {@code SHA-256} for key algorithm {@code HmacSHA256}). HMAC keys cannot be authorized 854c58153b2d7418f44f2b0e397478be808e91decefAlex Klyubin * for more than one digest. 8553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 856dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * <p>For private keys used for TLS/SSL client or server authentication it is usually 857dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * necessary to authorize the use of no digest ({@link KeyProperties#DIGEST_NONE}). This is 858dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * because TLS/SSL stacks typically generate the necessary digest(s) themselves and then use 859dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * a private key to sign it. 860dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * 861dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * <p>See {@link KeyProperties}.{@code DIGEST} constants. 8623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 8633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 8643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setDigests(@KeyProperties.DigestEnum String... digests) { 8653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mDigests = ArrayUtils.cloneIfNotEmpty(digests); 8663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 8673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 8683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 8693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 8703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the set of padding schemes (e.g., {@code PKCS7Padding}, {@code OAEPPadding}, 8713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@code PKCS1Padding}, {@code NoPadding}) with which the key can be used when 8723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * encrypting/decrypting. Attempts to use the key with any other padding scheme will be 8733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * rejected. 8743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 8753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>This must be specified for keys which are used for encryption/decryption. 8763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 877dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * <p>For RSA private keys used by TLS/SSL servers to authenticate themselves to clients it 878dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * is usually necessary to authorize the use of no/any padding 879e4928a2912297751108c7045ce3343ec63edcc01Alex Klyubin * ({@link KeyProperties#ENCRYPTION_PADDING_NONE}) and/or PKCS#1 encryption padding 880e4928a2912297751108c7045ce3343ec63edcc01Alex Klyubin * ({@link KeyProperties#ENCRYPTION_PADDING_RSA_PKCS1}). This is because RSA decryption is 881dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * required by some cipher suites, and some stacks request decryption using no padding 882dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * whereas others request PKCS#1 padding. 883dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * 8843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants. 8853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 8863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 8873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setEncryptionPaddings( 8883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @KeyProperties.EncryptionPaddingEnum String... paddings) { 8893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings); 8903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 8913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 8923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 8933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 8943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key 8953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * can be used when signing/verifying. Attempts to use the key with any other padding scheme 8963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * will be rejected. 8973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 8983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>This must be specified for RSA keys which are used for signing/verification. 8993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 9003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants. 9013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 9023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 9033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setSignaturePaddings( 9043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @KeyProperties.SignaturePaddingEnum String... paddings) { 9053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings); 9063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 9073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 9083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 9093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 910a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * Sets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be 911a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * used when encrypting/decrypting. Attempts to use the key with any other block modes will 912a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * be rejected. 9133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 914a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * <p>This must be specified for symmetric encryption/decryption keys. 9153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 9163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants. 9173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 9183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 9193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setBlockModes(@KeyProperties.BlockModeEnum String... blockModes) { 9203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes); 9213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 9223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 9233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 9243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 9253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets whether encryption using this key must be sufficiently randomized to produce 9263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * different ciphertexts for the same plaintext every time. The formal cryptographic 9273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * property being required is <em>indistinguishability under chosen-plaintext attack 9283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * ({@code IND-CPA})</em>. This property is important because it mitigates several classes 9293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * of weaknesses due to which ciphertext may leak information about plaintext. For example, 9303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * if a given plaintext always produces the same ciphertext, an attacker may see the 9313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * repeated ciphertexts and be able to deduce something about the plaintext. 9323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 9333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, {@code IND-CPA} is required. 9343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 9353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>When {@code IND-CPA} is required: 9363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <ul> 9373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <li>encryption/decryption transformation which do not offer {@code IND-CPA}, such as 9383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@code ECB} with a symmetric encryption algorithm, or RSA encryption/decryption without 9393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * padding, are prohibited;</li> 940a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * <li>in block modes which use an IV, such as {@code GCM}, {@code CBC}, and {@code CTR}, 9413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * caller-provided IVs are rejected when encrypting, to ensure that only random IVs are 9423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * used.</li> 9433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * </ul> 9443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 9453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>Before disabling this requirement, consider the following approaches instead: 9463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <ul> 9473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <li>If you are generating a random IV for encryption and then initializing a {@code} 9483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Cipher using the IV, the solution is to let the {@code Cipher} generate a random IV 9493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * instead. This will occur if the {@code Cipher} is initialized for encryption without an 9503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * IV. The IV can then be queried via {@link Cipher#getIV()}.</li> 9513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <li>If you are generating a non-random IV (e.g., an IV derived from something not fully 9523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * random, such as the name of the file being encrypted, or transaction ID, or password, 9533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * or a device identifier), consider changing your design to use a random IV which will then 9543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * be provided in addition to the ciphertext to the entities which need to decrypt the 9553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * ciphertext.</li> 9563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <li>If you are using RSA encryption without padding, consider switching to encryption 9573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * padding schemes which offer {@code IND-CPA}, such as PKCS#1 or OAEP.</li> 9583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * </ul> 9593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 9603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 9613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setRandomizedEncryptionRequired(boolean required) { 9623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mRandomizedEncryptionRequired = required; 9633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 9643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 9653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 9663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 96783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * Sets whether this key is authorized to be used only if the user has been authenticated. 9683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 96983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <p>By default, the key is authorized to be used regardless of whether the user has been 97083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * authenticated. 9713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 97283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <p>When user authentication is required: 97383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <ul> 97483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <li>The key can only be generated if secure lock screen is set up (see 97583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * {@link KeyguardManager#isDeviceSecure()}). Additionally, if the key requires that user 97683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * authentication takes place for every use of the key (see 97783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * {@link #setUserAuthenticationValidityDurationSeconds(int)}), at least one fingerprint 97883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * must be enrolled (see {@link FingerprintManager#hasEnrolledFingerprints()}).</li> 97983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <li>The use of the key must be authorized by the user by authenticating to this Android 98083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * device using a subset of their secure lock screen credentials such as 98183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * password/PIN/pattern or fingerprint. 9823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More 9833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * information</a>. 98483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <li>The key will become <em>irreversibly invalidated</em> once the secure lock screen is 98583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * disabled (reconfigured to None, Swipe or other mode which does not authenticate the user) 98683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * or when the secure lock screen is forcibly reset (e.g., by a Device Administrator). 98783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * Additionally, if the key requires that user authentication takes place for every use of 98883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * the key, it is also irreversibly invalidated once a new fingerprint is enrolled or once\ 989c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * no more fingerprints are enrolled, unless {@link 990c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * #setInvalidatedByBiometricEnrollment(boolean)} is used to allow validity after 991c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * enrollment. Attempts to initialize cryptographic operations using such keys will throw 992c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * {@link KeyPermanentlyInvalidatedException}.</li> 99383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * </ul> 9943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 99583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <p>This authorization applies only to secret key and private key operations. Public key 99683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * operations are not restricted. 9973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 9983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #setUserAuthenticationValidityDurationSeconds(int) 99983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * @see KeyguardManager#isDeviceSecure() 100083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * @see FingerprintManager#hasEnrolledFingerprints() 10013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 10023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 10033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setUserAuthenticationRequired(boolean required) { 10043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mUserAuthenticationRequired = required; 10053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 10063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 10073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 10083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 100983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * Sets the duration of time (seconds) for which this key is authorized to be used after the 101083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * user is successfully authenticated. This has effect if the key requires user 101183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * authentication for its use (see {@link #setUserAuthenticationRequired(boolean)}). 101283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * 101383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <p>By default, if user authentication is required, it must take place for every use of 101483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * the key. 101583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * 101683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <p>Cryptographic operations involving keys which require user authentication to take 101783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * place for every operation can only use fingerprint authentication. This is achieved by 101883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * initializing a cryptographic operation ({@link Signature}, {@link Cipher}, {@link Mac}) 101983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * with the key, wrapping it into a {@link FingerprintManager.CryptoObject}, invoking 102083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * {@code FingerprintManager.authenticate} with {@code CryptoObject}, and proceeding with 102183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * the cryptographic operation only if the authentication flow succeeds. 102283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * 102383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * <p>Cryptographic operations involving keys which are authorized to be used for a duration 102483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * of time after a successful user authentication event can only use secure lock screen 102583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * authentication. These cryptographic operations will throw 102683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * {@link UserNotAuthenticatedException} during initialization if the user needs to be 102783cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * authenticated to proceed. This situation can be resolved by the user unlocking the secure 102883cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * lock screen of the Android or by going through the confirm credential flow initiated by 102983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * {@link KeyguardManager#createConfirmDeviceCredentialIntent(CharSequence, CharSequence)}. 103083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * Once resolved, initializing a new cryptographic operation using this key (or any other 103183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * key which is authorized to be used for a fixed duration of time after user 103283cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * authentication) should succeed provided the user authentication flow completed 103383cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * successfully. 103483cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * 103583cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * @param seconds duration in seconds or {@code -1} if user authentication must take place 103683cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * for every use of the key. 10373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 10383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #setUserAuthenticationRequired(boolean) 103983cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * @see FingerprintManager 104083cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * @see FingerprintManager.CryptoObject 104183cc7a347f4775821ebeed04a2244b8b847be516Alex Klyubin * @see KeyguardManager 10423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 10433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 10443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setUserAuthenticationValidityDurationSeconds( 10453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @IntRange(from = -1) int seconds) { 10461b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin if (seconds < -1) { 10471b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin throw new IllegalArgumentException("seconds must be -1 or larger"); 10481b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin } 10493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mUserAuthenticationValidityDurationSeconds = seconds; 10503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 10513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 10523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 10538d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden /* 10548d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * TODO(swillden): Update this documentation to describe the hardware and software root 10558d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * keys, including information about CRL/OCSP services for discovering revocations, and to 10568d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * link to documentation of the extension format and content. 10578d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden */ 10588d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden /** 10598d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * Sets whether an attestation certificate will be generated for this key pair, and what 10608d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * challenge value will be placed in the certificate. The attestation certificate chain 10618d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * can be retrieved with with {@link java.security.KeyStore#getCertificateChain(String)}. 10628d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * 10638d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * <p>If {@code attestationChallenge} is not {@code null}, the public key certificate for 10648d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * this key pair will contain an extension that describes the details of the key's 10658d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * configuration and authorizations, including the {@code attestationChallenge} value. If 10668d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * the key is in secure hardware, and if the secure hardware supports attestation, the 10678d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * certificate will be signed by a chain of certificates rooted at a trustworthy CA key. 10688d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * Otherwise the chain will be rooted at an untrusted certificate. 10698d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * 10708d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * <p>The purpose of the challenge value is to enable relying parties to verify that the key 10718d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * was created in response to a specific request. If attestation is desired but no 10728d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * challenged is needed, any non-{@code null} value may be used, including an empty byte 10738d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * array. 10748d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * 10758d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * <p>If {@code attestationChallenge} is {@code null}, and this spec is used to generate an 10768d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * asymmetric (RSA or EC) key pair, the public key certificate will be self-signed if the 10778d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * key has purpose {@link KeyProperties#PURPOSE_SIGN} (see 10788d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * {@link #KeyGenParameterSpec(String, int)). If the key does not have purpose 10798d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * {@link KeyProperties#PURPOSE_SIGN}, it is not possible to use the key to sign a 10808d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * certificate, so the public key certificate will contain a dummy signature. 10818d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * 10828d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * <p>Symmetric keys, such as AES and HMAC keys, do not have public key certificates. If a 10838d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * {@code getAttestationChallenge} returns non-{@code null} and the spec is used to 10848d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * generate a symmetric (AES or HMAC) key, {@link KeyGenerator#generateKey()} will throw 10858d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * {@link java.security.InvalidAlgorithmParameterException}. 10868d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * 10878d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * @see Builder#setAttestationChallenge(String attestationChallenge) 10888d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden */ 10898d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden @NonNull 10908d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden public Builder setAttestationChallenge(byte[] attestationChallenge) { 10918d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden mAttestationChallenge = attestationChallenge; 10928d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden return this; 10938d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden } 10948d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden 10958d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden /** 10968d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * @hide Only system apps can use this method. 10978d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * 10988d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden * Sets whether to include a temporary unique ID field in the attestation certificate. 10998d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden */ 11008d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden @NonNull 11018d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden public Builder setUniqueIdIncluded(boolean uniqueIdIncluded) { 11028d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden mUniqueIdIncluded = uniqueIdIncluded; 11038d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden return this; 11048d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden } 11058d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden 11063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 110726e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * Sets whether the key will remain authorized only until the device is removed from the 110826e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * user's body up to the limit of the authentication validity period (see 110926e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * {@link #setUserAuthenticationValidityDurationSeconds} and 111026e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * {@link #setUserAuthenticationRequired}). Once the device has been removed from the 111126e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * user's body, the key will be considered unauthorized and the user will need to 111226e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * re-authenticate to use it. For keys without an authentication validity period this 111326e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * parameter has no effect. 1114adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden * 111526e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * <p>Similarly, on devices that do not have an on-body sensor, this parameter will have no 111626e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * effect; the device will always be considered to be "on-body" and the key will therefore 111726e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * remain authorized until the validity period ends. 1118adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden * 111926e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * @param remainsValid if {@code true}, and if the device supports on-body detection, key 112026e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * will be invalidated when the device is removed from the user's body or when the 112126e8d553e52055955db83061c5799ba4439ebe1bShawn Willden * authentication validity expires, whichever occurs first. 1122adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden */ 1123adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden @NonNull 1124adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden public Builder setUserAuthenticationValidWhileOnBody(boolean remainsValid) { 1125adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden mUserAuthenticationValidWhileOnBody = remainsValid; 1126adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden return this; 1127adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden } 1128adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden 1129adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden /** 1130c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * Sets whether this key should be invalidated on fingerprint enrollment. This 1131c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * applies only to keys which require user authentication (see {@link 1132c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * #setUserAuthenticationRequired(boolean)}) and if no positive validity duration has been 1133c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * set (see {@link #setUserAuthenticationValidityDurationSeconds(int)}, meaning the key is 1134c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * valid for fingerprint authentication only. 1135c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * 1136c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * <p>By default, {@code invalidateKey} is {@code true}, so keys that are valid for 1137c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * fingerprint authentication only are <em>irreversibly invalidated</em> when a new 1138c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * fingerprint is enrolled, or when all existing fingerprints are deleted. That may be 1139c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * changed by calling this method with {@code invalidateKey} set to {@code false}. 1140c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * 1141c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * <p>Invalidating keys on enrollment of a new finger or unenrollment of all fingers 1142c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * improves security by ensuring that an unauthorized person who obtains the password can't 1143c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * gain the use of fingerprint-authenticated keys by enrolling their own finger. However, 1144c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * invalidating keys makes key-dependent operations impossible, requiring some fallback 1145c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden * procedure to authenticate the user and set up a new key. 1146c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden */ 1147c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden @NonNull 1148c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden public Builder setInvalidatedByBiometricEnrollment(boolean invalidateKey) { 1149c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden mInvalidatedByBiometricEnrollment = invalidateKey; 1150c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden return this; 1151c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden } 1152c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden 1153c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden /** 11543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Builds an instance of {@code KeyGenParameterSpec}. 11553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 11563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 11573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public KeyGenParameterSpec build() { 11583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return new KeyGenParameterSpec( 11593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeystoreAlias, 11603876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin mUid, 11613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeySize, 11623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mSpec, 11633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mCertificateSubject, 11643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mCertificateSerialNumber, 11653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mCertificateNotBefore, 11663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mCertificateNotAfter, 11673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeyValidityStart, 11683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeyValidityForOriginationEnd, 11693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeyValidityForConsumptionEnd, 11703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mPurposes, 11713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mDigests, 11723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mEncryptionPaddings, 11733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mSignaturePaddings, 11743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mBlockModes, 11753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mRandomizedEncryptionRequired, 11763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mUserAuthenticationRequired, 11778d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden mUserAuthenticationValidityDurationSeconds, 11788d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden mAttestationChallenge, 1179adef49640d6339e6b4a6ad736c5815e35d9b8803Shawn Willden mUniqueIdIncluded, 1180c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden mUserAuthenticationValidWhileOnBody, 1181c38eae5229a820966008ae1885af90cd27c265e7Shawn Willden mInvalidatedByBiometricEnrollment); 11823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 11833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 11843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin} 1185