Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2012 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package android.security; |
| 18 | |
Alex Klyubin | eedda45 | 2015-05-07 17:34:24 -0700 | [diff] [blame] | 19 | import android.app.KeyguardManager; |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 20 | import android.annotation.NonNull; |
| 21 | import android.annotation.Nullable; |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 22 | import android.content.Context; |
Alex Klyubin | 3f8d4d8 | 2015-05-13 09:15:00 -0700 | [diff] [blame] | 23 | import android.security.keystore.KeyGenParameterSpec; |
| 24 | import android.security.keystore.KeyProperties; |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 25 | import android.text.TextUtils; |
| 26 | |
| 27 | import java.math.BigInteger; |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 28 | import java.security.NoSuchAlgorithmException; |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 29 | import java.security.PrivateKey; |
| 30 | import java.security.cert.Certificate; |
| 31 | import java.security.spec.AlgorithmParameterSpec; |
| 32 | import java.util.Date; |
| 33 | |
| 34 | import javax.security.auth.x500.X500Principal; |
| 35 | |
| 36 | /** |
Alex Klyubin | 3f8d4d8 | 2015-05-13 09:15:00 -0700 | [diff] [blame] | 37 | * This provides the required parameters needed for initializing the |
| 38 | * {@code KeyPairGenerator} that works with |
| 39 | * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore |
| 40 | * facility</a>. The Android KeyStore facility is accessed through a |
| 41 | * {@link java.security.KeyPairGenerator} API using the {@code AndroidKeyStore} |
| 42 | * provider. The {@code context} passed in may be used to pop up some UI to ask |
| 43 | * the user to unlock or initialize the Android KeyStore facility. |
| 44 | * <p> |
| 45 | * After generation, the {@code keyStoreAlias} is used with the |
| 46 | * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)} |
| 47 | * interface to retrieve the {@link PrivateKey} and its associated |
| 48 | * {@link Certificate} chain. |
| 49 | * <p> |
| 50 | * The KeyPair generator will create a self-signed certificate with the subject |
| 51 | * as its X.509v3 Subject Distinguished Name and as its X.509v3 Issuer |
| 52 | * Distinguished Name along with the other parameters specified with the |
| 53 | * {@link Builder}. |
| 54 | * <p> |
| 55 | * The self-signed X.509 certificate may be replaced at a later time by a |
| 56 | * certificate signed by a real Certificate Authority. |
Alex Klyubin | eedda45 | 2015-05-07 17:34:24 -0700 | [diff] [blame] | 57 | * |
Alex Klyubin | 3f8d4d8 | 2015-05-13 09:15:00 -0700 | [diff] [blame] | 58 | * @deprecated Use {@link KeyGenParameterSpec} instead. |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 59 | */ |
Alex Klyubin | 3f8d4d8 | 2015-05-13 09:15:00 -0700 | [diff] [blame] | 60 | @Deprecated |
Kenny Root | 1c219f6 | 2013-04-18 17:57:03 -0700 | [diff] [blame] | 61 | public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 62 | |
| 63 | private final Context mContext; |
| 64 | |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 65 | private final String mKeystoreAlias; |
| 66 | |
| 67 | private final String mKeyType; |
| 68 | |
| 69 | private final int mKeySize; |
| 70 | |
| 71 | private final AlgorithmParameterSpec mSpec; |
| 72 | |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 73 | private final X500Principal mSubjectDN; |
| 74 | |
| 75 | private final BigInteger mSerialNumber; |
| 76 | |
| 77 | private final Date mStartDate; |
| 78 | |
| 79 | private final Date mEndDate; |
| 80 | |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 81 | private final int mFlags; |
| 82 | |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 83 | /** |
| 84 | * Parameter specification for the "{@code AndroidKeyPairGenerator}" |
| 85 | * instance of the {@link java.security.KeyPairGenerator} API. The |
| 86 | * {@code context} passed in may be used to pop up some UI to ask the user |
| 87 | * to unlock or initialize the Android keystore facility. |
| 88 | * <p> |
| 89 | * After generation, the {@code keyStoreAlias} is used with the |
| 90 | * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)} |
| 91 | * interface to retrieve the {@link PrivateKey} and its associated |
| 92 | * {@link Certificate} chain. |
| 93 | * <p> |
| 94 | * The KeyPair generator will create a self-signed certificate with the |
| 95 | * properties of {@code subjectDN} as its X.509v3 Subject Distinguished Name |
| 96 | * and as its X.509v3 Issuer Distinguished Name, using the specified |
| 97 | * {@code serialNumber}, and the validity date starting at {@code startDate} |
| 98 | * and ending at {@code endDate}. |
| 99 | * |
| 100 | * @param context Android context for the activity |
| 101 | * @param keyStoreAlias name to use for the generated key in the Android |
| 102 | * keystore |
Alex Klyubin | 3f8d4d8 | 2015-05-13 09:15:00 -0700 | [diff] [blame] | 103 | * @param keyType key algorithm to use (RSA, DSA, EC) |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 104 | * @param keySize size of key to generate |
| 105 | * @param spec the underlying key type parameters |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 106 | * @param subjectDN X.509 v3 Subject Distinguished Name |
| 107 | * @param serialNumber X509 v3 certificate serial number |
| 108 | * @param startDate the start of the self-signed certificate validity period |
| 109 | * @param endDate the end date of the self-signed certificate validity |
| 110 | * period |
| 111 | * @throws IllegalArgumentException when any argument is {@code null} or |
| 112 | * {@code endDate} is before {@code startDate}. |
Kenny Root | 1c219f6 | 2013-04-18 17:57:03 -0700 | [diff] [blame] | 113 | * @hide should be built with KeyPairGeneratorSpecBuilder |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 114 | */ |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 115 | public KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize, |
| 116 | AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber, |
Alex Klyubin | 3f8d4d8 | 2015-05-13 09:15:00 -0700 | [diff] [blame] | 117 | Date startDate, Date endDate, int flags) { |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 118 | if (context == null) { |
| 119 | throw new IllegalArgumentException("context == null"); |
| 120 | } else if (TextUtils.isEmpty(keyStoreAlias)) { |
| 121 | throw new IllegalArgumentException("keyStoreAlias must not be empty"); |
Alex Klyubin | 3f8d4d8 | 2015-05-13 09:15:00 -0700 | [diff] [blame] | 122 | } else if (subjectDN == null) { |
| 123 | throw new IllegalArgumentException("subjectDN == null"); |
| 124 | } else if (serialNumber == null) { |
| 125 | throw new IllegalArgumentException("serialNumber == null"); |
| 126 | } else if (startDate == null) { |
| 127 | throw new IllegalArgumentException("startDate == null"); |
| 128 | } else if (endDate == null) { |
| 129 | throw new IllegalArgumentException("endDate == null"); |
| 130 | } else if (endDate.before(startDate)) { |
| 131 | throw new IllegalArgumentException("endDate < startDate"); |
Alex Klyubin | 67d21ae | 2015-04-14 12:48:17 -0700 | [diff] [blame] | 132 | } |
| 133 | |
| 134 | if (endDate.before(startDate)) { |
| 135 | throw new IllegalArgumentException("endDate < startDate"); |
| 136 | } |
| 137 | |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 138 | mContext = context; |
| 139 | mKeystoreAlias = keyStoreAlias; |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 140 | mKeyType = keyType; |
| 141 | mKeySize = keySize; |
| 142 | mSpec = spec; |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 143 | mSubjectDN = subjectDN; |
| 144 | mSerialNumber = serialNumber; |
| 145 | mStartDate = startDate; |
| 146 | mEndDate = endDate; |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 147 | mFlags = flags; |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 148 | } |
| 149 | |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 150 | /** |
| 151 | * Gets the Android context used for operations with this instance. |
| 152 | */ |
| 153 | public Context getContext() { |
| 154 | return mContext; |
| 155 | } |
| 156 | |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 157 | /** |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 158 | * Returns the alias that will be used in the {@code java.security.KeyStore} |
| 159 | * in conjunction with the {@code AndroidKeyStore}. |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 160 | */ |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 161 | public String getKeystoreAlias() { |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 162 | return mKeystoreAlias; |
| 163 | } |
| 164 | |
| 165 | /** |
Alex Klyubin | 622fd93 | 2015-05-12 12:53:23 -0700 | [diff] [blame] | 166 | * Returns the type of key pair (e.g., {@code EC}, {@code RSA}) to be generated. See |
Alex Klyubin | 3f8d4d8 | 2015-05-13 09:15:00 -0700 | [diff] [blame] | 167 | * {@link KeyProperties}.{@code KEY_ALGORITHM} constants. |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 168 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 169 | @Nullable |
Alex Klyubin | 3f8d4d8 | 2015-05-13 09:15:00 -0700 | [diff] [blame] | 170 | public @KeyProperties.KeyAlgorithmEnum String getKeyType() { |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 171 | return mKeyType; |
| 172 | } |
| 173 | |
| 174 | /** |
| 175 | * Returns the key size specified by this parameter. For instance, for RSA |
| 176 | * this will return the modulus size and for EC it will return the field |
| 177 | * size. |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 178 | */ |
| 179 | public int getKeySize() { |
| 180 | return mKeySize; |
| 181 | } |
| 182 | |
| 183 | /** |
| 184 | * Returns the {@link AlgorithmParameterSpec} that will be used for creation |
| 185 | * of the key pair. |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 186 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 187 | @NonNull |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 188 | public AlgorithmParameterSpec getAlgorithmParameterSpec() { |
| 189 | return mSpec; |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 190 | } |
| 191 | |
| 192 | /** |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 193 | * Gets the subject distinguished name to be used on the X.509 certificate |
| 194 | * that will be put in the {@link java.security.KeyStore}. |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 195 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 196 | @NonNull |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 197 | public X500Principal getSubjectDN() { |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 198 | return mSubjectDN; |
| 199 | } |
| 200 | |
| 201 | /** |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 202 | * Gets the serial number to be used on the X.509 certificate that will be |
| 203 | * put in the {@link java.security.KeyStore}. |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 204 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 205 | @NonNull |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 206 | public BigInteger getSerialNumber() { |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 207 | return mSerialNumber; |
| 208 | } |
| 209 | |
| 210 | /** |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 211 | * Gets the start date to be used on the X.509 certificate that will be put |
| 212 | * in the {@link java.security.KeyStore}. |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 213 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 214 | @NonNull |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 215 | public Date getStartDate() { |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 216 | return mStartDate; |
| 217 | } |
| 218 | |
| 219 | /** |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 220 | * Gets the end date to be used on the X.509 certificate that will be put in |
| 221 | * the {@link java.security.KeyStore}. |
| 222 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 223 | @NonNull |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 224 | public Date getEndDate() { |
| 225 | return mEndDate; |
| 226 | } |
| 227 | |
| 228 | /** |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 229 | * @hide |
| 230 | */ |
Alex Klyubin | 3f8d4d8 | 2015-05-13 09:15:00 -0700 | [diff] [blame] | 231 | public int getFlags() { |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 232 | return mFlags; |
| 233 | } |
| 234 | |
| 235 | /** |
Alex Klyubin | eedda45 | 2015-05-07 17:34:24 -0700 | [diff] [blame] | 236 | * Returns {@code true} if the key must be encrypted at rest. This will protect the key pair |
| 237 | * with the secure lock screen credential (e.g., password, PIN, or pattern). |
Alex Klyubin | 3f8d4d8 | 2015-05-13 09:15:00 -0700 | [diff] [blame] | 238 | * |
| 239 | * <p>Note that encrypting the key at rest requires that the secure lock screen (e.g., password, |
| 240 | * PIN, pattern) is set up, otherwise key generation will fail. Moreover, this key will be |
| 241 | * deleted when the secure lock screen is disabled or reset (e.g., by the user or a Device |
| 242 | * Administrator). Finally, this key cannot be used until the user unlocks the secure lock |
| 243 | * screen after boot. |
| 244 | * |
| 245 | * @see KeyguardManager#isDeviceSecure() |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 246 | */ |
| 247 | public boolean isEncryptionRequired() { |
| 248 | return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0; |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 249 | } |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 250 | |
| 251 | /** |
Kenny Root | 1c219f6 | 2013-04-18 17:57:03 -0700 | [diff] [blame] | 252 | * Builder class for {@link KeyPairGeneratorSpec} objects. |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 253 | * <p> |
Kevin Hufnagle | c0c4ac5 | 2016-09-19 11:31:08 -0700 | [diff] [blame] | 254 | * This will build a parameter spec for use with the |
| 255 | * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore |
| 256 | * facility</a>. |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 257 | * <p> |
| 258 | * The required fields must be filled in with the builder. |
| 259 | * <p> |
| 260 | * Example: |
| 261 | * |
| 262 | * <pre class="prettyprint"> |
| 263 | * Calendar start = new Calendar(); |
| 264 | * Calendar end = new Calendar(); |
| 265 | * end.add(1, Calendar.YEAR); |
| 266 | * |
Kenny Root | 1c219f6 | 2013-04-18 17:57:03 -0700 | [diff] [blame] | 267 | * KeyPairGeneratorSpec spec = |
| 268 | * new KeyPairGeneratorSpec.Builder(mContext).setAlias("myKey") |
| 269 | * .setSubject(new X500Principal("CN=myKey")).setSerial(BigInteger.valueOf(1337)) |
| 270 | * .setStartDate(start.getTime()).setEndDate(end.getTime()).build(); |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 271 | * </pre> |
Alex Klyubin | 3f8d4d8 | 2015-05-13 09:15:00 -0700 | [diff] [blame] | 272 | * |
| 273 | * @deprecated Use {@link KeyGenParameterSpec.Builder} instead. |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 274 | */ |
Alex Klyubin | 3f8d4d8 | 2015-05-13 09:15:00 -0700 | [diff] [blame] | 275 | @Deprecated |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 276 | public final static class Builder { |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 277 | private final Context mContext; |
| 278 | |
| 279 | private String mKeystoreAlias; |
| 280 | |
Alex Klyubin | 21a76df | 2015-01-14 13:35:32 -0800 | [diff] [blame] | 281 | private String mKeyType; |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 282 | |
| 283 | private int mKeySize = -1; |
| 284 | |
| 285 | private AlgorithmParameterSpec mSpec; |
| 286 | |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 287 | private X500Principal mSubjectDN; |
| 288 | |
| 289 | private BigInteger mSerialNumber; |
| 290 | |
| 291 | private Date mStartDate; |
| 292 | |
| 293 | private Date mEndDate; |
| 294 | |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 295 | private int mFlags; |
| 296 | |
| 297 | /** |
| 298 | * Creates a new instance of the {@code Builder} with the given |
| 299 | * {@code context}. The {@code context} passed in may be used to pop up |
| 300 | * some UI to ask the user to unlock or initialize the Android KeyStore |
| 301 | * facility. |
| 302 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 303 | public Builder(@NonNull Context context) { |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 304 | if (context == null) { |
| 305 | throw new NullPointerException("context == null"); |
| 306 | } |
| 307 | mContext = context; |
| 308 | } |
| 309 | |
| 310 | /** |
| 311 | * Sets the alias to be used to retrieve the key later from a |
| 312 | * {@link java.security.KeyStore} instance using the |
| 313 | * {@code AndroidKeyStore} provider. |
| 314 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 315 | @NonNull |
| 316 | public Builder setAlias(@NonNull String alias) { |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 317 | if (alias == null) { |
| 318 | throw new NullPointerException("alias == null"); |
| 319 | } |
| 320 | mKeystoreAlias = alias; |
| 321 | return this; |
| 322 | } |
| 323 | |
| 324 | /** |
Alex Klyubin | 622fd93 | 2015-05-12 12:53:23 -0700 | [diff] [blame] | 325 | * Sets the type of key pair (e.g., {@code EC}, {@code RSA}) of the key pair to be |
Alex Klyubin | 3f8d4d8 | 2015-05-13 09:15:00 -0700 | [diff] [blame] | 326 | * generated. See {@link KeyProperties}.{@code KEY_ALGORITHM} constants. |
Alex Klyubin | 622fd93 | 2015-05-12 12:53:23 -0700 | [diff] [blame] | 327 | * |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 328 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 329 | @NonNull |
Alex Klyubin | 3f8d4d8 | 2015-05-13 09:15:00 -0700 | [diff] [blame] | 330 | public Builder setKeyType(@NonNull @KeyProperties.KeyAlgorithmEnum String keyType) |
Alex Klyubin | 4d5443f | 2015-05-06 15:43:52 -0700 | [diff] [blame] | 331 | throws NoSuchAlgorithmException { |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 332 | if (keyType == null) { |
| 333 | throw new NullPointerException("keyType == null"); |
| 334 | } else { |
Alex Klyubin | 4a0ff7c | 2015-06-09 13:25:20 -0700 | [diff] [blame] | 335 | try { |
| 336 | KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(keyType); |
| 337 | } catch (IllegalArgumentException e) { |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 338 | throw new NoSuchAlgorithmException("Unsupported key type: " + keyType); |
| 339 | } |
| 340 | } |
| 341 | mKeyType = keyType; |
| 342 | return this; |
| 343 | } |
| 344 | |
| 345 | /** |
| 346 | * Sets the key size for the keypair to be created. For instance, for a |
| 347 | * key type of RSA this will set the modulus size and for a key type of |
| 348 | * EC it will select a curve with a matching field size. |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 349 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 350 | @NonNull |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 351 | public Builder setKeySize(int keySize) { |
| 352 | if (keySize < 0) { |
| 353 | throw new IllegalArgumentException("keySize < 0"); |
| 354 | } |
| 355 | mKeySize = keySize; |
| 356 | return this; |
| 357 | } |
| 358 | |
| 359 | /** |
Alex Klyubin | cd2329d | 2015-01-14 16:45:51 -0800 | [diff] [blame] | 360 | * Sets the algorithm-specific key generation parameters. For example, for RSA keys |
| 361 | * this may be an instance of {@link java.security.spec.RSAKeyGenParameterSpec}. |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 362 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 363 | public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) { |
Kenny Root | a398598 | 2013-08-16 14:03:29 -0700 | [diff] [blame] | 364 | if (spec == null) { |
| 365 | throw new NullPointerException("spec == null"); |
| 366 | } |
| 367 | mSpec = spec; |
| 368 | return this; |
| 369 | } |
| 370 | |
| 371 | /** |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 372 | * Sets the subject used for the self-signed certificate of the |
| 373 | * generated key pair. |
| 374 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 375 | @NonNull |
| 376 | public Builder setSubject(@NonNull X500Principal subject) { |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 377 | if (subject == null) { |
| 378 | throw new NullPointerException("subject == null"); |
| 379 | } |
| 380 | mSubjectDN = subject; |
| 381 | return this; |
| 382 | } |
| 383 | |
| 384 | /** |
| 385 | * Sets the serial number used for the self-signed certificate of the |
| 386 | * generated key pair. |
| 387 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 388 | @NonNull |
| 389 | public Builder setSerialNumber(@NonNull BigInteger serialNumber) { |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 390 | if (serialNumber == null) { |
| 391 | throw new NullPointerException("serialNumber == null"); |
| 392 | } |
| 393 | mSerialNumber = serialNumber; |
| 394 | return this; |
| 395 | } |
| 396 | |
| 397 | /** |
| 398 | * Sets the start of the validity period for the self-signed certificate |
| 399 | * of the generated key pair. |
| 400 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 401 | @NonNull |
| 402 | public Builder setStartDate(@NonNull Date startDate) { |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 403 | if (startDate == null) { |
| 404 | throw new NullPointerException("startDate == null"); |
| 405 | } |
| 406 | mStartDate = startDate; |
| 407 | return this; |
| 408 | } |
| 409 | |
| 410 | /** |
| 411 | * Sets the end of the validity period for the self-signed certificate |
| 412 | * of the generated key pair. |
| 413 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 414 | @NonNull |
| 415 | public Builder setEndDate(@NonNull Date endDate) { |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 416 | if (endDate == null) { |
| 417 | throw new NullPointerException("endDate == null"); |
| 418 | } |
| 419 | mEndDate = endDate; |
| 420 | return this; |
| 421 | } |
| 422 | |
| 423 | /** |
Alex Klyubin | 5418393 | 2015-05-08 15:25:48 -0700 | [diff] [blame] | 424 | * Indicates that this key pair must be encrypted at rest. This will protect the key pair |
| 425 | * with the secure lock screen credential (e.g., password, PIN, or pattern). |
Alex Klyubin | eedda45 | 2015-05-07 17:34:24 -0700 | [diff] [blame] | 426 | * |
| 427 | * <p>Note that this feature requires that the secure lock screen (e.g., password, PIN, |
Alex Klyubin | 5418393 | 2015-05-08 15:25:48 -0700 | [diff] [blame] | 428 | * pattern) is set up, otherwise key pair generation will fail. Moreover, this key pair will |
| 429 | * be deleted when the secure lock screen is disabled or reset (e.g., by the user or a |
| 430 | * Device Administrator). Finally, this key pair cannot be used until the user unlocks the |
| 431 | * secure lock screen after boot. |
Alex Klyubin | eedda45 | 2015-05-07 17:34:24 -0700 | [diff] [blame] | 432 | * |
| 433 | * @see KeyguardManager#isDeviceSecure() |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 434 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 435 | @NonNull |
Kenny Root | 2eeda72 | 2013-04-10 11:30:58 -0700 | [diff] [blame] | 436 | public Builder setEncryptionRequired() { |
| 437 | mFlags |= KeyStore.FLAG_ENCRYPTED; |
| 438 | return this; |
| 439 | } |
| 440 | |
| 441 | /** |
Kenny Root | 1c219f6 | 2013-04-18 17:57:03 -0700 | [diff] [blame] | 442 | * Builds the instance of the {@code KeyPairGeneratorSpec}. |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 443 | * |
| 444 | * @throws IllegalArgumentException if a required field is missing |
Kenny Root | 1c219f6 | 2013-04-18 17:57:03 -0700 | [diff] [blame] | 445 | * @return built instance of {@code KeyPairGeneratorSpec} |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 446 | */ |
Alex Klyubin | 54bb159 | 2015-05-11 12:30:03 -0700 | [diff] [blame] | 447 | @NonNull |
Kenny Root | 1c219f6 | 2013-04-18 17:57:03 -0700 | [diff] [blame] | 448 | public KeyPairGeneratorSpec build() { |
Alex Klyubin | 855fa31 | 2015-04-02 09:58:08 -0700 | [diff] [blame] | 449 | return new KeyPairGeneratorSpec(mContext, |
| 450 | mKeystoreAlias, |
| 451 | mKeyType, |
| 452 | mKeySize, |
| 453 | mSpec, |
| 454 | mSubjectDN, |
| 455 | mSerialNumber, |
| 456 | mStartDate, |
| 457 | mEndDate, |
Alex Klyubin | 3f8d4d8 | 2015-05-13 09:15:00 -0700 | [diff] [blame] | 458 | mFlags); |
Kenny Root | acb0b5b | 2013-03-28 15:05:03 -0700 | [diff] [blame] | 459 | } |
| 460 | } |
Kenny Root | db02671 | 2012-08-20 10:48:46 -0700 | [diff] [blame] | 461 | } |