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 19a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Rootimport com.android.org.conscrypt.NativeCrypto; 20a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 21db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport android.content.Context; 22db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport android.text.TextUtils; 23db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 24db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.math.BigInteger; 25a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Rootimport java.security.NoSuchAlgorithmException; 26db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.PrivateKey; 27db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.cert.Certificate; 28db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.spec.AlgorithmParameterSpec; 29a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Rootimport java.security.spec.DSAParameterSpec; 30a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Rootimport java.security.spec.RSAKeyGenParameterSpec; 31db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.util.Date; 32db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 33db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport javax.security.auth.x500.X500Principal; 34db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 35db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root/** 36acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * This provides the required parameters needed for initializing the 371c219f619291ba818bc2542390a2988539d94ed0Kenny Root * {@code KeyPairGenerator} that works with 38716cc7dcac1bb9279326ab92a78a246b3a70de4eRobert Ly * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore 391c219f619291ba818bc2542390a2988539d94ed0Kenny Root * facility</a>. The Android KeyStore facility is accessed through a 402eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * {@link java.security.KeyPairGenerator} API using the {@code AndroidKeyStore} 412eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * provider. The {@code context} passed in may be used to pop up some UI to ask 422eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * the user to unlock or initialize the Android KeyStore facility. 43acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * <p> 44acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * After generation, the {@code keyStoreAlias} is used with the 45acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)} 46acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * interface to retrieve the {@link PrivateKey} and its associated 47acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * {@link Certificate} chain. 48acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * <p> 49acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * The KeyPair generator will create a self-signed certificate with the subject 50acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * as its X.509v3 Subject Distinguished Name and as its X.509v3 Issuer 51acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Distinguished Name along with the other parameters specified with the 52acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * {@link Builder}. 53acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * <p> 542eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * The self-signed X.509 certificate may be replaced at a later time by a 552eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * certificate signed by a real Certificate Authority. 56db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 571c219f619291ba818bc2542390a2988539d94ed0Kenny Rootpublic final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { 58a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root /* 59a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * These must be kept in sync with system/security/keystore/defaults.h 60a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root */ 61a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 62a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root /* DSA */ 63a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private static final int DSA_DEFAULT_KEY_SIZE = 1024; 64a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private static final int DSA_MIN_KEY_SIZE = 512; 65a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private static final int DSA_MAX_KEY_SIZE = 8192; 66a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 67a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root /* EC */ 68a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private static final int EC_DEFAULT_KEY_SIZE = 256; 69a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private static final int EC_MIN_KEY_SIZE = 192; 70a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private static final int EC_MAX_KEY_SIZE = 521; 71a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 72a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root /* RSA */ 73a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private static final int RSA_DEFAULT_KEY_SIZE = 2048; 74a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private static final int RSA_MIN_KEY_SIZE = 512; 75a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private static final int RSA_MAX_KEY_SIZE = 8192; 76db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 77db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private final Context mContext; 78db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 79a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private final String mKeystoreAlias; 80a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 81a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private final String mKeyType; 82a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 83a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private final int mKeySize; 84a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 85a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private final AlgorithmParameterSpec mSpec; 86a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 87db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private final X500Principal mSubjectDN; 88db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 89db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private final BigInteger mSerialNumber; 90db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 91db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private final Date mStartDate; 92db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 93db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root private final Date mEndDate; 94db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 952eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root private final int mFlags; 962eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root 97db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /** 98db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * Parameter specification for the "{@code AndroidKeyPairGenerator}" 99db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * instance of the {@link java.security.KeyPairGenerator} API. The 100db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * {@code context} passed in may be used to pop up some UI to ask the user 101db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * to unlock or initialize the Android keystore facility. 102db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * <p> 103db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * After generation, the {@code keyStoreAlias} is used with the 104db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)} 105db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * interface to retrieve the {@link PrivateKey} and its associated 106db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * {@link Certificate} chain. 107db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * <p> 108db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * The KeyPair generator will create a self-signed certificate with the 109db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * properties of {@code subjectDN} as its X.509v3 Subject Distinguished Name 110db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * and as its X.509v3 Issuer Distinguished Name, using the specified 111db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * {@code serialNumber}, and the validity date starting at {@code startDate} 112db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * and ending at {@code endDate}. 113db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * 114db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * @param context Android context for the activity 115db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * @param keyStoreAlias name to use for the generated key in the Android 116db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * keystore 117a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * @param keyType key algorithm to use (RSA, DSA, EC) 118a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * @param keySize size of key to generate 119a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * @param spec the underlying key type parameters 120db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * @param subjectDN X.509 v3 Subject Distinguished Name 121db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * @param serialNumber X509 v3 certificate serial number 122db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * @param startDate the start of the self-signed certificate validity period 123db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * @param endDate the end date of the self-signed certificate validity 124db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * period 125db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * @throws IllegalArgumentException when any argument is {@code null} or 126db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * {@code endDate} is before {@code startDate}. 1271c219f619291ba818bc2542390a2988539d94ed0Kenny Root * @hide should be built with KeyPairGeneratorSpecBuilder 128db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 129a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root public KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize, 130a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber, 131a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root Date startDate, Date endDate, int flags) { 132db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root if (context == null) { 133db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root throw new IllegalArgumentException("context == null"); 134db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } else if (TextUtils.isEmpty(keyStoreAlias)) { 135db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root throw new IllegalArgumentException("keyStoreAlias must not be empty"); 136db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } else if (subjectDN == null) { 137db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root throw new IllegalArgumentException("subjectDN == null"); 138db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } else if (serialNumber == null) { 139db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root throw new IllegalArgumentException("serialNumber == null"); 140db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } else if (startDate == null) { 141db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root throw new IllegalArgumentException("startDate == null"); 142db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } else if (endDate == null) { 143db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root throw new IllegalArgumentException("endDate == null"); 144db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } else if (endDate.before(startDate)) { 145db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root throw new IllegalArgumentException("endDate < startDate"); 146db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 147db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 148a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root final int keyTypeInt = KeyStore.getKeyTypeForAlgorithm(keyType); 149a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root if (keySize == -1) { 150a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root keySize = getDefaultKeySizeForType(keyTypeInt); 151a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 152a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root checkCorrectParametersSpec(keyTypeInt, keySize, spec); 153a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root checkValidKeySize(keyTypeInt, keySize); 154a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 155db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mContext = context; 156db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mKeystoreAlias = keyStoreAlias; 157a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root mKeyType = keyType; 158a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root mKeySize = keySize; 159a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root mSpec = spec; 160db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mSubjectDN = subjectDN; 161db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mSerialNumber = serialNumber; 162db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mStartDate = startDate; 163db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root mEndDate = endDate; 1642eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root mFlags = flags; 165db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 166db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 167a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private static int getDefaultKeySizeForType(int keyType) { 168a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root if (keyType == NativeCrypto.EVP_PKEY_DSA) { 169a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return DSA_DEFAULT_KEY_SIZE; 170a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } else if (keyType == NativeCrypto.EVP_PKEY_EC) { 171a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return EC_DEFAULT_KEY_SIZE; 172a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } else if (keyType == NativeCrypto.EVP_PKEY_RSA) { 173a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return RSA_DEFAULT_KEY_SIZE; 174a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 175a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root throw new IllegalArgumentException("Invalid key type " + keyType); 176a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 177a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 178a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private static void checkValidKeySize(int keyType, int keySize) { 179a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root if (keyType == NativeCrypto.EVP_PKEY_DSA) { 180a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root if (keySize < DSA_MIN_KEY_SIZE || keySize > DSA_MAX_KEY_SIZE) { 181a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root throw new IllegalArgumentException("DSA keys must be >= " + DSA_MIN_KEY_SIZE 182a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root + " and <= " + DSA_MAX_KEY_SIZE); 183a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 184a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } else if (keyType == NativeCrypto.EVP_PKEY_EC) { 185a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) { 186a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root throw new IllegalArgumentException("EC keys must be >= " + EC_MIN_KEY_SIZE 187a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root + " and <= " + EC_MAX_KEY_SIZE); 188a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 189a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } else if (keyType == NativeCrypto.EVP_PKEY_RSA) { 190a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) { 191a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root throw new IllegalArgumentException("RSA keys must be >= " + RSA_MIN_KEY_SIZE 192a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root + " and <= " + RSA_MAX_KEY_SIZE); 193a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 194a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } else { 195a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root throw new IllegalArgumentException("Invalid key type " + keyType); 196a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 197a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 198a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 199a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private static void checkCorrectParametersSpec(int keyType, int keySize, 200a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root AlgorithmParameterSpec spec) { 201a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root if (keyType == NativeCrypto.EVP_PKEY_DSA && spec != null) { 202a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root if (!(spec instanceof DSAParameterSpec)) { 203a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root throw new IllegalArgumentException("DSA keys must have DSAParameterSpec specified"); 204a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 205a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } else if (keyType == NativeCrypto.EVP_PKEY_RSA && spec != null) { 206a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root if (spec instanceof RSAKeyGenParameterSpec) { 207a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) spec; 208a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root if (keySize != -1 && keySize != rsaSpec.getKeysize()) { 209a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root throw new IllegalArgumentException("RSA key size must match: " + keySize 210a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root + " vs " + rsaSpec.getKeysize()); 211a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 212a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } else { 213a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root throw new IllegalArgumentException("RSA may only use RSAKeyGenParameterSpec"); 214a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 215a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 216a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 217a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 218a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root /** 219a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * Gets the Android context used for operations with this instance. 220a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root */ 221a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root public Context getContext() { 222a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return mContext; 223a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 224a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 225db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /** 2262eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * Returns the alias that will be used in the {@code java.security.KeyStore} 2272eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * in conjunction with the {@code AndroidKeyStore}. 228db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 2292eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public String getKeystoreAlias() { 230db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root return mKeystoreAlias; 231db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 232db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 233db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /** 234a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * Returns the key type (e.g., "RSA", "DSA", "EC") specified by this 235a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * parameter. 236db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 237a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root public String getKeyType() { 238a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return mKeyType; 239a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 240a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 241a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root /** 242a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * Returns the key size specified by this parameter. For instance, for RSA 243a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * this will return the modulus size and for EC it will return the field 244a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * size. 245a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root */ 246a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root public int getKeySize() { 247a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return mKeySize; 248a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 249a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 250a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root /** 251a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * Returns the {@link AlgorithmParameterSpec} that will be used for creation 252a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * of the key pair. 253a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root */ 254a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root public AlgorithmParameterSpec getAlgorithmParameterSpec() { 255a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return mSpec; 256db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 257db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 258db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /** 2592eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * Gets the subject distinguished name to be used on the X.509 certificate 2602eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * that will be put in the {@link java.security.KeyStore}. 261db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 2622eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public X500Principal getSubjectDN() { 263db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root return mSubjectDN; 264db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 265db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 266db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /** 2672eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * Gets the serial number to be used on the X.509 certificate that will be 2682eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * put in the {@link java.security.KeyStore}. 269db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 2702eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public BigInteger getSerialNumber() { 271db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root return mSerialNumber; 272db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 273db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 274db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /** 2752eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * Gets the start date to be used on the X.509 certificate that will be put 2762eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * in the {@link java.security.KeyStore}. 277db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 2782eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public Date getStartDate() { 279db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root return mStartDate; 280db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 281db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root 282db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root /** 2832eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * Gets the end date to be used on the X.509 certificate that will be put in 2842eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * the {@link java.security.KeyStore}. 285db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */ 2862eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public Date getEndDate() { 287db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root return mEndDate; 288db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root } 289acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 290acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root /** 2912eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * @hide 2922eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root */ 2932eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root int getFlags() { 2942eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root return mFlags; 2952eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root } 2962eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root 2972eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root /** 2982eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * Returns {@code true} if this parameter will require generated keys to be 2992eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * encrypted in the {@link java.security.KeyStore}. 3002eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root */ 3012eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public boolean isEncryptionRequired() { 3022eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0; 3032eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root } 3042eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root 3052eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root /** 3061c219f619291ba818bc2542390a2988539d94ed0Kenny Root * Builder class for {@link KeyPairGeneratorSpec} objects. 307acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * <p> 308acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * This will build a parameter spec for use with the <a href="{@docRoot} 309716cc7dcac1bb9279326ab92a78a246b3a70de4eRobert Ly * training/articles/keystore.html">Android KeyStore facility</a>. 310acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * <p> 311acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * The required fields must be filled in with the builder. 312acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * <p> 313acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Example: 314acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * 315acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * <pre class="prettyprint"> 316acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Calendar start = new Calendar(); 317acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Calendar end = new Calendar(); 318acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * end.add(1, Calendar.YEAR); 319acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * 3201c219f619291ba818bc2542390a2988539d94ed0Kenny Root * KeyPairGeneratorSpec spec = 3211c219f619291ba818bc2542390a2988539d94ed0Kenny Root * new KeyPairGeneratorSpec.Builder(mContext).setAlias("myKey") 3221c219f619291ba818bc2542390a2988539d94ed0Kenny Root * .setSubject(new X500Principal("CN=myKey")).setSerial(BigInteger.valueOf(1337)) 3231c219f619291ba818bc2542390a2988539d94ed0Kenny Root * .setStartDate(start.getTime()).setEndDate(end.getTime()).build(); 324acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * </pre> 325acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root */ 3262eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public final static class Builder { 327acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root private final Context mContext; 328acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 329acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root private String mKeystoreAlias; 330acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 331a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private String mKeyType = "RSA"; 332a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 333a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private int mKeySize = -1; 334a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 335a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root private AlgorithmParameterSpec mSpec; 336a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 337acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root private X500Principal mSubjectDN; 338acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 339acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root private BigInteger mSerialNumber; 340acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 341acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root private Date mStartDate; 342acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 343acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root private Date mEndDate; 344acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 3452eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root private int mFlags; 3462eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root 3472eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root /** 3482eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * Creates a new instance of the {@code Builder} with the given 3492eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * {@code context}. The {@code context} passed in may be used to pop up 3502eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * some UI to ask the user to unlock or initialize the Android KeyStore 3512eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * facility. 3522eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root */ 353acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root public Builder(Context context) { 354acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root if (context == null) { 355acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root throw new NullPointerException("context == null"); 356acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 357acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root mContext = context; 358acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 359acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 360acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root /** 361acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Sets the alias to be used to retrieve the key later from a 362acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * {@link java.security.KeyStore} instance using the 363acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * {@code AndroidKeyStore} provider. 364acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root */ 365acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root public Builder setAlias(String alias) { 366acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root if (alias == null) { 367acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root throw new NullPointerException("alias == null"); 368acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 369acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root mKeystoreAlias = alias; 370acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root return this; 371acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 372acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 373acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root /** 374a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * Sets the key type (e.g., RSA, DSA, EC) of the keypair to be created. 375a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root */ 376a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root public Builder setKeyType(String keyType) throws NoSuchAlgorithmException { 377a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root if (keyType == null) { 378a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root throw new NullPointerException("keyType == null"); 379a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } else { 380a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root try { 381a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root KeyStore.getKeyTypeForAlgorithm(keyType); 382a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } catch (IllegalArgumentException e) { 383a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root throw new NoSuchAlgorithmException("Unsupported key type: " + keyType); 384a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 385a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 386a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root mKeyType = keyType; 387a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return this; 388a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 389a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 390a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root /** 391a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * Sets the key size for the keypair to be created. For instance, for a 392a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * key type of RSA this will set the modulus size and for a key type of 393a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * EC it will select a curve with a matching field size. 394a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root */ 395a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root public Builder setKeySize(int keySize) { 396a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root if (keySize < 0) { 397a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root throw new IllegalArgumentException("keySize < 0"); 398a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 399a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root mKeySize = keySize; 400a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return this; 401a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 402a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 403a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root /** 404a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * Sets the underlying key type's parameters. This is required for DSA 405a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * where you must set this to an instance of 406a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root * {@link java.security.spec.DSAParameterSpec}. 407a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root */ 408a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root public Builder setAlgorithmParameterSpec(AlgorithmParameterSpec spec) { 409a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root if (spec == null) { 410a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root throw new NullPointerException("spec == null"); 411a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 412a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root mSpec = spec; 413a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return this; 414a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 415a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 416a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root /** 417acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Sets the subject used for the self-signed certificate of the 418acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * generated key pair. 419acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root */ 420acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root public Builder setSubject(X500Principal subject) { 421acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root if (subject == null) { 422acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root throw new NullPointerException("subject == null"); 423acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 424acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root mSubjectDN = subject; 425acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root return this; 426acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 427acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 428acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root /** 429acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Sets the serial number used for the self-signed certificate of the 430acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * generated key pair. 431acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root */ 432acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root public Builder setSerialNumber(BigInteger serialNumber) { 433acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root if (serialNumber == null) { 434acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root throw new NullPointerException("serialNumber == null"); 435acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 436acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root mSerialNumber = serialNumber; 437acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root return this; 438acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 439acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 440acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root /** 441acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Sets the start of the validity period for the self-signed certificate 442acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * of the generated key pair. 443acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root */ 444acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root public Builder setStartDate(Date startDate) { 445acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root if (startDate == null) { 446acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root throw new NullPointerException("startDate == null"); 447acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 448acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root mStartDate = startDate; 449acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root return this; 450acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 451acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 452acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root /** 453acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Sets the end of the validity period for the self-signed certificate 454acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * of the generated key pair. 455acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root */ 456acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root public Builder setEndDate(Date endDate) { 457acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root if (endDate == null) { 458acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root throw new NullPointerException("endDate == null"); 459acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 460acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root mEndDate = endDate; 461acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root return this; 462acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 463acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root 464acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root /** 4652eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * Indicates that this key must be encrypted at rest on storage. Note 4662eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * that enabling this will require that the user enable a strong lock 4672eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * screen (e.g., PIN, password) before creating or using the generated 4682eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * key is successful. 4692eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root */ 4702eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public Builder setEncryptionRequired() { 4712eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root mFlags |= KeyStore.FLAG_ENCRYPTED; 4722eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root return this; 4732eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root } 4742eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root 4752eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root /** 4761c219f619291ba818bc2542390a2988539d94ed0Kenny Root * Builds the instance of the {@code KeyPairGeneratorSpec}. 477acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * 478acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * @throws IllegalArgumentException if a required field is missing 4791c219f619291ba818bc2542390a2988539d94ed0Kenny Root * @return built instance of {@code KeyPairGeneratorSpec} 480acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root */ 4811c219f619291ba818bc2542390a2988539d94ed0Kenny Root public KeyPairGeneratorSpec build() { 482a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root return new KeyPairGeneratorSpec(mContext, mKeystoreAlias, mKeyType, mKeySize, mSpec, 483a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root mSubjectDN, mSerialNumber, mStartDate, mEndDate, mFlags); 484acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 485acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root } 486db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root} 487