1db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root/* 2db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * Copyright (C) 2012 The Android Open Source Project 3db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * 4db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 5db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * you may not use this file except in compliance with the License. 6db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * You may obtain a copy of the License at 7db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * 8db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * http://www.apache.org/licenses/LICENSE-2.0 9db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * 10db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * Unless required by applicable law or agreed to in writing, software 11db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * distributed under the License is distributed on an "AS IS" BASIS, 12db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * See the License for the specific language governing permissions and 14db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * limitations under the License. 15db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 16db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 17db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootpackage android.security; 18db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 19eedda45ad7d829b4d65936d33e8aa6fa9c9c1ecdAlex Klyubinimport android.app.KeyguardManager; 2054bb1596e470144932943046ec7a99551d020ba0Alex Klyubinimport android.annotation.NonNull; 2154bb1596e470144932943046ec7a99551d020ba0Alex Klyubinimport android.annotation.Nullable; 22db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport android.content.Context; 233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.security.keystore.KeyGenParameterSpec; 243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.security.keystore.KeyProperties; 25db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport android.text.TextUtils; 26db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 27db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.math.BigInteger; 28a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Rootimport java.security.NoSuchAlgorithmException; 29db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.PrivateKey; 30db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.cert.Certificate; 31db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.spec.AlgorithmParameterSpec; 32db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.util.Date; 33db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 34db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport javax.security.auth.x500.X500Principal; 35db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 36db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root/** 373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * This provides the required parameters needed for initializing the 383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@code KeyPairGenerator} that works with 393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore 403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * facility</a>. The Android KeyStore facility is accessed through a 413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link java.security.KeyPairGenerator} API using the {@code AndroidKeyStore} 423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * provider. The {@code context} passed in may be used to pop up some UI to ask 433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * the user to unlock or initialize the Android KeyStore facility. 443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p> 453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * After generation, the {@code keyStoreAlias} is used with the 463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)} 473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * interface to retrieve the {@link PrivateKey} and its associated 483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link Certificate} chain. 493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p> 503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * The KeyPair generator will create a self-signed certificate with the subject 513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * as its X.509v3 Subject Distinguished Name and as its X.509v3 Issuer 523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Distinguished Name along with the other parameters specified with the 533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link Builder}. 543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p> 553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * The self-signed X.509 certificate may be replaced at a later time by a 563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * certificate signed by a real Certificate Authority. 57eedda45ad7d829b4d65936d33e8aa6fa9c9c1ecdAlex Klyubin * 583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @deprecated Use {@link KeyGenParameterSpec} instead. 59db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin@Deprecated 611c219f619291ba818bc2542390a2988539d94ed0Kenny Rootpublic final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { 62db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 63db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private final Context mContext; 64db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 65a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private final String mKeystoreAlias; 66a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 67a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private final String mKeyType; 68a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 69a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private final int mKeySize; 70a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 71a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private final AlgorithmParameterSpec mSpec; 72a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 73db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private final X500Principal mSubjectDN; 74db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 75db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private final BigInteger mSerialNumber; 76db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 77db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private final Date mStartDate; 78db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 79db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private final Date mEndDate; 80db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 812eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root private final int mFlags; 822eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root 83db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /** 84db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * Parameter specification for the "{@code AndroidKeyPairGenerator}" 85db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * instance of the {@link java.security.KeyPairGenerator} API. The 86db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * {@code context} passed in may be used to pop up some UI to ask the user 87db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * to unlock or initialize the Android keystore facility. 88db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * <p> 89db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * After generation, the {@code keyStoreAlias} is used with the 90db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)} 91db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * interface to retrieve the {@link PrivateKey} and its associated 92db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * {@link Certificate} chain. 93db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * <p> 94db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * The KeyPair generator will create a self-signed certificate with the 95db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * properties of {@code subjectDN} as its X.509v3 Subject Distinguished Name 96db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * and as its X.509v3 Issuer Distinguished Name, using the specified 97db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * {@code serialNumber}, and the validity date starting at {@code startDate} 98db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * and ending at {@code endDate}. 99db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * 100db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * @param context Android context for the activity 101db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * @param keyStoreAlias name to use for the generated key in the Android 102db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * keystore 1033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @param keyType key algorithm to use (RSA, DSA, EC) 104a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * @param keySize size of key to generate 105a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * @param spec the underlying key type parameters 106db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * @param subjectDN X.509 v3 Subject Distinguished Name 107db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * @param serialNumber X509 v3 certificate serial number 108db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * @param startDate the start of the self-signed certificate validity period 109db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * @param endDate the end date of the self-signed certificate validity 110db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * period 111db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * @throws IllegalArgumentException when any argument is {@code null} or 112db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * {@code endDate} is before {@code startDate}. 1131c219f619291ba818bc2542390a2988539d94ed0Kenny Root * @hide should be built with KeyPairGeneratorSpecBuilder 114db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 115a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root public KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize, 116a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber, 1173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin Date startDate, Date endDate, int flags) { 118db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root if (context == null) { 119db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root throw new IllegalArgumentException("context == null"); 120db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } else if (TextUtils.isEmpty(keyStoreAlias)) { 121db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root throw new IllegalArgumentException("keyStoreAlias must not be empty"); 1223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } else if (subjectDN == null) { 1233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new IllegalArgumentException("subjectDN == null"); 1243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } else if (serialNumber == null) { 1253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new IllegalArgumentException("serialNumber == null"); 1263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } else if (startDate == null) { 1273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new IllegalArgumentException("startDate == null"); 1283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } else if (endDate == null) { 1293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new IllegalArgumentException("endDate == null"); 1303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } else if (endDate.before(startDate)) { 1313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new IllegalArgumentException("endDate < startDate"); 13267d21aef98bbafd0def2cacc6254e644e911c8ddAlex Klyubin } 13367d21aef98bbafd0def2cacc6254e644e911c8ddAlex Klyubin 13467d21aef98bbafd0def2cacc6254e644e911c8ddAlex Klyubin if (endDate.before(startDate)) { 13567d21aef98bbafd0def2cacc6254e644e911c8ddAlex Klyubin throw new IllegalArgumentException("endDate < startDate"); 13667d21aef98bbafd0def2cacc6254e644e911c8ddAlex Klyubin } 13767d21aef98bbafd0def2cacc6254e644e911c8ddAlex Klyubin 138db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mContext = context; 139db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mKeystoreAlias = keyStoreAlias; 140a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root mKeyType = keyType; 141a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root mKeySize = keySize; 142a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root mSpec = spec; 143db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mSubjectDN = subjectDN; 144db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mSerialNumber = serialNumber; 145db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mStartDate = startDate; 146db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mEndDate = endDate; 1472eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root mFlags = flags; 148db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 149db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 150a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root /** 151a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * Gets the Android context used for operations with this instance. 152a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root */ 153a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root public Context getContext() { 154a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return mContext; 155a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 156a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 157db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /** 1582eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * Returns the alias that will be used in the {@code java.security.KeyStore} 1592eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * in conjunction with the {@code AndroidKeyStore}. 160db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 1612eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public String getKeystoreAlias() { 162db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root return mKeystoreAlias; 163db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 164db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 165db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /** 166622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * Returns the type of key pair (e.g., {@code EC}, {@code RSA}) to be generated. See 1673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link KeyProperties}.{@code KEY_ALGORITHM} constants. 168db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 16954bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @Nullable 1703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public @KeyProperties.KeyAlgorithmEnum String getKeyType() { 171a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return mKeyType; 172a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 173a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 174a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root /** 175a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * Returns the key size specified by this parameter. For instance, for RSA 176a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * this will return the modulus size and for EC it will return the field 177a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * size. 178a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root */ 179a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root public int getKeySize() { 180a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return mKeySize; 181a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 182a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 183a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root /** 184a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * Returns the {@link AlgorithmParameterSpec} that will be used for creation 185a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * of the key pair. 186a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root */ 18754bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 188a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root public AlgorithmParameterSpec getAlgorithmParameterSpec() { 189a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return mSpec; 190db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 191db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 192db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /** 1932eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * Gets the subject distinguished name to be used on the X.509 certificate 1942eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * that will be put in the {@link java.security.KeyStore}. 195db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 19654bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 1972eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public X500Principal getSubjectDN() { 198db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root return mSubjectDN; 199db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 200db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 201db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /** 2022eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * Gets the serial number to be used on the X.509 certificate that will be 2032eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * put in the {@link java.security.KeyStore}. 204db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 20554bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 2062eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public BigInteger getSerialNumber() { 207db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root return mSerialNumber; 208db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 209db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 210db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /** 2112eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * Gets the start date to be used on the X.509 certificate that will be put 2122eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * in the {@link java.security.KeyStore}. 213db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 21454bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 2152eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public Date getStartDate() { 216db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root return mStartDate; 217db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 218db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 219db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /** 2202eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * Gets the end date to be used on the X.509 certificate that will be put in 2212eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * the {@link java.security.KeyStore}. 222db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 22354bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 2242eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public Date getEndDate() { 225db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root return mEndDate; 226db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 227acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 228acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root /** 2292eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * @hide 2302eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root */ 2313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public int getFlags() { 2322eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root return mFlags; 2332eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root } 2342eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root 2352eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root /** 236eedda45ad7d829b4d65936d33e8aa6fa9c9c1ecdAlex Klyubin * Returns {@code true} if the key must be encrypted at rest. This will protect the key pair 237eedda45ad7d829b4d65936d33e8aa6fa9c9c1ecdAlex Klyubin * with the secure lock screen credential (e.g., password, PIN, or pattern). 238855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin * 2393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>Note that encrypting the key at rest requires that the secure lock screen (e.g., password, 2403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * PIN, pattern) is set up, otherwise key generation will fail. Moreover, this key will be 2413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * deleted when the secure lock screen is disabled or reset (e.g., by the user or a Device 2423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Administrator). Finally, this key cannot be used until the user unlocks the secure lock 2433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * screen after boot. 244855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin * 2453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see KeyguardManager#isDeviceSecure() 246855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin */ 2473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public boolean isEncryptionRequired() { 2483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0; 249855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin } 250855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin 251855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin /** 2521c219f619291ba818bc2542390a2988539d94ed0Kenny Root * Builder class for {@link KeyPairGeneratorSpec} objects. 253acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * <p> 254acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * This will build a parameter spec for use with the <a href="{@docRoot} 255716cc7dcac1bb9279326ab92a78a246b3a70de4eRobert Ly * training/articles/keystore.html">Android KeyStore facility</a>. 256acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * <p> 257acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * The required fields must be filled in with the builder. 258acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * <p> 259acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Example: 260acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * 261acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * <pre class="prettyprint"> 262acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Calendar start = new Calendar(); 263acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Calendar end = new Calendar(); 264acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * end.add(1, Calendar.YEAR); 265acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * 2661c219f619291ba818bc2542390a2988539d94ed0Kenny Root * KeyPairGeneratorSpec spec = 2671c219f619291ba818bc2542390a2988539d94ed0Kenny Root * new KeyPairGeneratorSpec.Builder(mContext).setAlias("myKey") 2681c219f619291ba818bc2542390a2988539d94ed0Kenny Root * .setSubject(new X500Principal("CN=myKey")).setSerial(BigInteger.valueOf(1337)) 2691c219f619291ba818bc2542390a2988539d94ed0Kenny Root * .setStartDate(start.getTime()).setEndDate(end.getTime()).build(); 270acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * </pre> 2713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 2723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @deprecated Use {@link KeyGenParameterSpec.Builder} instead. 273acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root */ 2743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @Deprecated 2752eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public final static class Builder { 276acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root private final Context mContext; 277acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 278acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root private String mKeystoreAlias; 279acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 28021a76df55cf4b956f4d34f57c7b9e694d0363f54Alex Klyubin private String mKeyType; 281a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 282a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private int mKeySize = -1; 283a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 284a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private AlgorithmParameterSpec mSpec; 285a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 286acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root private X500Principal mSubjectDN; 287acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 288acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root private BigInteger mSerialNumber; 289acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 290acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root private Date mStartDate; 291acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 292acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root private Date mEndDate; 293acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 2942eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root private int mFlags; 2952eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root 2962eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root /** 2972eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * Creates a new instance of the {@code Builder} with the given 2982eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * {@code context}. The {@code context} passed in may be used to pop up 2992eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * some UI to ask the user to unlock or initialize the Android KeyStore 3002eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * facility. 3012eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root */ 30254bb1596e470144932943046ec7a99551d020ba0Alex Klyubin public Builder(@NonNull Context context) { 303acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root if (context == null) { 304acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root throw new NullPointerException("context == null"); 305acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 306acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root mContext = context; 307acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 308acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 309acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root /** 310acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Sets the alias to be used to retrieve the key later from a 311acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * {@link java.security.KeyStore} instance using the 312acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * {@code AndroidKeyStore} provider. 313acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root */ 31454bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 31554bb1596e470144932943046ec7a99551d020ba0Alex Klyubin public Builder setAlias(@NonNull String alias) { 316acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root if (alias == null) { 317acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root throw new NullPointerException("alias == null"); 318acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 319acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root mKeystoreAlias = alias; 320acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root return this; 321acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 322acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 323acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root /** 324622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * Sets the type of key pair (e.g., {@code EC}, {@code RSA}) of the key pair to be 3253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * generated. See {@link KeyProperties}.{@code KEY_ALGORITHM} constants. 326622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin * 327a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root */ 32854bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 3293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setKeyType(@NonNull @KeyProperties.KeyAlgorithmEnum String keyType) 3304d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin throws NoSuchAlgorithmException { 331a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root if (keyType == null) { 332a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root throw new NullPointerException("keyType == null"); 333a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } else { 3344a0ff7ca984d29bd34b02e54441957cad65e8b53Alex Klyubin try { 3354a0ff7ca984d29bd34b02e54441957cad65e8b53Alex Klyubin KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(keyType); 3364a0ff7ca984d29bd34b02e54441957cad65e8b53Alex Klyubin } catch (IllegalArgumentException e) { 337a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root throw new NoSuchAlgorithmException("Unsupported key type: " + keyType); 338a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 339a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 340a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root mKeyType = keyType; 341a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return this; 342a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 343a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 344a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root /** 345a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * Sets the key size for the keypair to be created. For instance, for a 346a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * key type of RSA this will set the modulus size and for a key type of 347a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * EC it will select a curve with a matching field size. 348a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root */ 34954bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 350a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root public Builder setKeySize(int keySize) { 351a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root if (keySize < 0) { 352a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root throw new IllegalArgumentException("keySize < 0"); 353a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 354a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root mKeySize = keySize; 355a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return this; 356a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 357a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 358a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root /** 359cd2329dbfa5aef82c38ffa36a478bbaf5088af92Alex Klyubin * Sets the algorithm-specific key generation parameters. For example, for RSA keys 360cd2329dbfa5aef82c38ffa36a478bbaf5088af92Alex Klyubin * this may be an instance of {@link java.security.spec.RSAKeyGenParameterSpec}. 361a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root */ 36254bb1596e470144932943046ec7a99551d020ba0Alex Klyubin public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) { 363a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root if (spec == null) { 364a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root throw new NullPointerException("spec == null"); 365a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 366a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root mSpec = spec; 367a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return this; 368a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 369a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 370a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root /** 371acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Sets the subject used for the self-signed certificate of the 372acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * generated key pair. 373acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root */ 37454bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 37554bb1596e470144932943046ec7a99551d020ba0Alex Klyubin public Builder setSubject(@NonNull X500Principal subject) { 376acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root if (subject == null) { 377acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root throw new NullPointerException("subject == null"); 378acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 379acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root mSubjectDN = subject; 380acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root return this; 381acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 382acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 383acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root /** 384acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Sets the serial number used for the self-signed certificate of the 385acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * generated key pair. 386acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root */ 38754bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 38854bb1596e470144932943046ec7a99551d020ba0Alex Klyubin public Builder setSerialNumber(@NonNull BigInteger serialNumber) { 389acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root if (serialNumber == null) { 390acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root throw new NullPointerException("serialNumber == null"); 391acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 392acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root mSerialNumber = serialNumber; 393acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root return this; 394acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 395acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 396acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root /** 397acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Sets the start of the validity period for the self-signed certificate 398acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * of the generated key pair. 399acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root */ 40054bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 40154bb1596e470144932943046ec7a99551d020ba0Alex Klyubin public Builder setStartDate(@NonNull Date startDate) { 402acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root if (startDate == null) { 403acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root throw new NullPointerException("startDate == null"); 404acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 405acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root mStartDate = startDate; 406acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root return this; 407acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 408acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 409acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root /** 410acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Sets the end of the validity period for the self-signed certificate 411acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * of the generated key pair. 412acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root */ 41354bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 41454bb1596e470144932943046ec7a99551d020ba0Alex Klyubin public Builder setEndDate(@NonNull Date endDate) { 415acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root if (endDate == null) { 416acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root throw new NullPointerException("endDate == null"); 417acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 418acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root mEndDate = endDate; 419acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root return this; 420acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 421acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 422acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root /** 4235418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * Indicates that this key pair must be encrypted at rest. This will protect the key pair 4245418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * with the secure lock screen credential (e.g., password, PIN, or pattern). 425eedda45ad7d829b4d65936d33e8aa6fa9c9c1ecdAlex Klyubin * 426eedda45ad7d829b4d65936d33e8aa6fa9c9c1ecdAlex Klyubin * <p>Note that this feature requires that the secure lock screen (e.g., password, PIN, 4275418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * pattern) is set up, otherwise key pair generation will fail. Moreover, this key pair will 4285418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * be deleted when the secure lock screen is disabled or reset (e.g., by the user or a 4295418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * Device Administrator). Finally, this key pair cannot be used until the user unlocks the 4305418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * secure lock screen after boot. 431eedda45ad7d829b4d65936d33e8aa6fa9c9c1ecdAlex Klyubin * 432eedda45ad7d829b4d65936d33e8aa6fa9c9c1ecdAlex Klyubin * @see KeyguardManager#isDeviceSecure() 4332eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root */ 43454bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 4352eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public Builder setEncryptionRequired() { 4362eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root mFlags |= KeyStore.FLAG_ENCRYPTED; 4372eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root return this; 4382eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root } 4392eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root 4402eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root /** 4411c219f619291ba818bc2542390a2988539d94ed0Kenny Root * Builds the instance of the {@code KeyPairGeneratorSpec}. 442acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * 443acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * @throws IllegalArgumentException if a required field is missing 4441c219f619291ba818bc2542390a2988539d94ed0Kenny Root * @return built instance of {@code KeyPairGeneratorSpec} 445acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root */ 44654bb1596e470144932943046ec7a99551d020ba0Alex Klyubin @NonNull 4471c219f619291ba818bc2542390a2988539d94ed0Kenny Root public KeyPairGeneratorSpec build() { 448855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin return new KeyPairGeneratorSpec(mContext, 449855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin mKeystoreAlias, 450855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin mKeyType, 451855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin mKeySize, 452855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin mSpec, 453855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin mSubjectDN, 454855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin mSerialNumber, 455855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin mStartDate, 456855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin mEndDate, 4573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mFlags); 458acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 459acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 460db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root} 461