blob: d8493175e63fa8db660d3750cc26f678e51f3304 [file] [log] [blame]
Kenny Rootdb026712012-08-20 10:48:46 -07001/*
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
17package android.security;
18
Alex Klyubineedda452015-05-07 17:34:24 -070019import android.app.KeyguardManager;
Alex Klyubin54bb1592015-05-11 12:30:03 -070020import android.annotation.NonNull;
21import android.annotation.Nullable;
Kenny Rootdb026712012-08-20 10:48:46 -070022import android.content.Context;
Alex Klyubin3f8d4d82015-05-13 09:15:00 -070023import android.security.keystore.KeyGenParameterSpec;
24import android.security.keystore.KeyProperties;
Kenny Rootdb026712012-08-20 10:48:46 -070025import android.text.TextUtils;
26
27import java.math.BigInteger;
Kenny Roota3985982013-08-16 14:03:29 -070028import java.security.NoSuchAlgorithmException;
Kenny Rootdb026712012-08-20 10:48:46 -070029import java.security.PrivateKey;
30import java.security.cert.Certificate;
31import java.security.spec.AlgorithmParameterSpec;
32import java.util.Date;
33
34import javax.security.auth.x500.X500Principal;
35
36/**
Alex Klyubin3f8d4d82015-05-13 09:15:00 -070037 * 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 Klyubineedda452015-05-07 17:34:24 -070057 *
Alex Klyubin3f8d4d82015-05-13 09:15:00 -070058 * @deprecated Use {@link KeyGenParameterSpec} instead.
Kenny Rootdb026712012-08-20 10:48:46 -070059 */
Alex Klyubin3f8d4d82015-05-13 09:15:00 -070060@Deprecated
Kenny Root1c219f62013-04-18 17:57:03 -070061public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
Kenny Rootdb026712012-08-20 10:48:46 -070062
63 private final Context mContext;
64
Kenny Roota3985982013-08-16 14:03:29 -070065 private final String mKeystoreAlias;
66
67 private final String mKeyType;
68
69 private final int mKeySize;
70
71 private final AlgorithmParameterSpec mSpec;
72
Kenny Rootdb026712012-08-20 10:48:46 -070073 private final X500Principal mSubjectDN;
74
75 private final BigInteger mSerialNumber;
76
77 private final Date mStartDate;
78
79 private final Date mEndDate;
80
Kenny Root2eeda722013-04-10 11:30:58 -070081 private final int mFlags;
82
Kenny Rootdb026712012-08-20 10:48:46 -070083 /**
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 Klyubin3f8d4d82015-05-13 09:15:00 -0700103 * @param keyType key algorithm to use (RSA, DSA, EC)
Kenny Roota3985982013-08-16 14:03:29 -0700104 * @param keySize size of key to generate
105 * @param spec the underlying key type parameters
Kenny Rootdb026712012-08-20 10:48:46 -0700106 * @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 Root1c219f62013-04-18 17:57:03 -0700113 * @hide should be built with KeyPairGeneratorSpecBuilder
Kenny Rootdb026712012-08-20 10:48:46 -0700114 */
Kenny Roota3985982013-08-16 14:03:29 -0700115 public KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize,
116 AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber,
Alex Klyubin3f8d4d82015-05-13 09:15:00 -0700117 Date startDate, Date endDate, int flags) {
Kenny Rootdb026712012-08-20 10:48:46 -0700118 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 Klyubin3f8d4d82015-05-13 09:15:00 -0700122 } 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 Klyubin67d21ae2015-04-14 12:48:17 -0700132 }
133
134 if (endDate.before(startDate)) {
135 throw new IllegalArgumentException("endDate < startDate");
136 }
137
Kenny Rootdb026712012-08-20 10:48:46 -0700138 mContext = context;
139 mKeystoreAlias = keyStoreAlias;
Kenny Roota3985982013-08-16 14:03:29 -0700140 mKeyType = keyType;
141 mKeySize = keySize;
142 mSpec = spec;
Kenny Rootdb026712012-08-20 10:48:46 -0700143 mSubjectDN = subjectDN;
144 mSerialNumber = serialNumber;
145 mStartDate = startDate;
146 mEndDate = endDate;
Kenny Root2eeda722013-04-10 11:30:58 -0700147 mFlags = flags;
Kenny Rootdb026712012-08-20 10:48:46 -0700148 }
149
Kenny Roota3985982013-08-16 14:03:29 -0700150 /**
151 * Gets the Android context used for operations with this instance.
152 */
153 public Context getContext() {
154 return mContext;
155 }
156
Kenny Rootdb026712012-08-20 10:48:46 -0700157 /**
Kenny Root2eeda722013-04-10 11:30:58 -0700158 * Returns the alias that will be used in the {@code java.security.KeyStore}
159 * in conjunction with the {@code AndroidKeyStore}.
Kenny Rootdb026712012-08-20 10:48:46 -0700160 */
Kenny Root2eeda722013-04-10 11:30:58 -0700161 public String getKeystoreAlias() {
Kenny Rootdb026712012-08-20 10:48:46 -0700162 return mKeystoreAlias;
163 }
164
165 /**
Alex Klyubin622fd932015-05-12 12:53:23 -0700166 * Returns the type of key pair (e.g., {@code EC}, {@code RSA}) to be generated. See
Alex Klyubin3f8d4d82015-05-13 09:15:00 -0700167 * {@link KeyProperties}.{@code KEY_ALGORITHM} constants.
Kenny Rootdb026712012-08-20 10:48:46 -0700168 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700169 @Nullable
Alex Klyubin3f8d4d82015-05-13 09:15:00 -0700170 public @KeyProperties.KeyAlgorithmEnum String getKeyType() {
Kenny Roota3985982013-08-16 14:03:29 -0700171 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 Roota3985982013-08-16 14:03:29 -0700178 */
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 Roota3985982013-08-16 14:03:29 -0700186 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700187 @NonNull
Kenny Roota3985982013-08-16 14:03:29 -0700188 public AlgorithmParameterSpec getAlgorithmParameterSpec() {
189 return mSpec;
Kenny Rootdb026712012-08-20 10:48:46 -0700190 }
191
192 /**
Kenny Root2eeda722013-04-10 11:30:58 -0700193 * 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 Rootdb026712012-08-20 10:48:46 -0700195 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700196 @NonNull
Kenny Root2eeda722013-04-10 11:30:58 -0700197 public X500Principal getSubjectDN() {
Kenny Rootdb026712012-08-20 10:48:46 -0700198 return mSubjectDN;
199 }
200
201 /**
Kenny Root2eeda722013-04-10 11:30:58 -0700202 * Gets the serial number to be used on the X.509 certificate that will be
203 * put in the {@link java.security.KeyStore}.
Kenny Rootdb026712012-08-20 10:48:46 -0700204 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700205 @NonNull
Kenny Root2eeda722013-04-10 11:30:58 -0700206 public BigInteger getSerialNumber() {
Kenny Rootdb026712012-08-20 10:48:46 -0700207 return mSerialNumber;
208 }
209
210 /**
Kenny Root2eeda722013-04-10 11:30:58 -0700211 * Gets the start date to be used on the X.509 certificate that will be put
212 * in the {@link java.security.KeyStore}.
Kenny Rootdb026712012-08-20 10:48:46 -0700213 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700214 @NonNull
Kenny Root2eeda722013-04-10 11:30:58 -0700215 public Date getStartDate() {
Kenny Rootdb026712012-08-20 10:48:46 -0700216 return mStartDate;
217 }
218
219 /**
Kenny Root2eeda722013-04-10 11:30:58 -0700220 * 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 Klyubin54bb1592015-05-11 12:30:03 -0700223 @NonNull
Kenny Root2eeda722013-04-10 11:30:58 -0700224 public Date getEndDate() {
225 return mEndDate;
226 }
227
228 /**
Kenny Rootdb026712012-08-20 10:48:46 -0700229 * @hide
230 */
Alex Klyubin3f8d4d82015-05-13 09:15:00 -0700231 public int getFlags() {
Kenny Root2eeda722013-04-10 11:30:58 -0700232 return mFlags;
233 }
234
235 /**
Alex Klyubineedda452015-05-07 17:34:24 -0700236 * 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 Klyubin3f8d4d82015-05-13 09:15:00 -0700238 *
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 Root2eeda722013-04-10 11:30:58 -0700246 */
247 public boolean isEncryptionRequired() {
248 return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0;
Kenny Rootdb026712012-08-20 10:48:46 -0700249 }
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700250
251 /**
Kenny Root1c219f62013-04-18 17:57:03 -0700252 * Builder class for {@link KeyPairGeneratorSpec} objects.
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700253 * <p>
254 * This will build a parameter spec for use with the <a href="{@docRoot}
Robert Ly716cc7d2014-05-07 21:16:15 -0700255 * training/articles/keystore.html">Android KeyStore facility</a>.
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700256 * <p>
257 * The required fields must be filled in with the builder.
258 * <p>
259 * Example:
260 *
261 * <pre class="prettyprint">
262 * Calendar start = new Calendar();
263 * Calendar end = new Calendar();
264 * end.add(1, Calendar.YEAR);
265 *
Kenny Root1c219f62013-04-18 17:57:03 -0700266 * KeyPairGeneratorSpec spec =
267 * new KeyPairGeneratorSpec.Builder(mContext).setAlias(&quot;myKey&quot;)
268 * .setSubject(new X500Principal(&quot;CN=myKey&quot;)).setSerial(BigInteger.valueOf(1337))
269 * .setStartDate(start.getTime()).setEndDate(end.getTime()).build();
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700270 * </pre>
Alex Klyubin3f8d4d82015-05-13 09:15:00 -0700271 *
272 * @deprecated Use {@link KeyGenParameterSpec.Builder} instead.
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700273 */
Alex Klyubin3f8d4d82015-05-13 09:15:00 -0700274 @Deprecated
Kenny Root2eeda722013-04-10 11:30:58 -0700275 public final static class Builder {
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700276 private final Context mContext;
277
278 private String mKeystoreAlias;
279
Alex Klyubin21a76df2015-01-14 13:35:32 -0800280 private String mKeyType;
Kenny Roota3985982013-08-16 14:03:29 -0700281
282 private int mKeySize = -1;
283
284 private AlgorithmParameterSpec mSpec;
285
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700286 private X500Principal mSubjectDN;
287
288 private BigInteger mSerialNumber;
289
290 private Date mStartDate;
291
292 private Date mEndDate;
293
Kenny Root2eeda722013-04-10 11:30:58 -0700294 private int mFlags;
295
296 /**
297 * Creates a new instance of the {@code Builder} with the given
298 * {@code context}. The {@code context} passed in may be used to pop up
299 * some UI to ask the user to unlock or initialize the Android KeyStore
300 * facility.
301 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700302 public Builder(@NonNull Context context) {
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700303 if (context == null) {
304 throw new NullPointerException("context == null");
305 }
306 mContext = context;
307 }
308
309 /**
310 * Sets the alias to be used to retrieve the key later from a
311 * {@link java.security.KeyStore} instance using the
312 * {@code AndroidKeyStore} provider.
313 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700314 @NonNull
315 public Builder setAlias(@NonNull String alias) {
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700316 if (alias == null) {
317 throw new NullPointerException("alias == null");
318 }
319 mKeystoreAlias = alias;
320 return this;
321 }
322
323 /**
Alex Klyubin622fd932015-05-12 12:53:23 -0700324 * Sets the type of key pair (e.g., {@code EC}, {@code RSA}) of the key pair to be
Alex Klyubin3f8d4d82015-05-13 09:15:00 -0700325 * generated. See {@link KeyProperties}.{@code KEY_ALGORITHM} constants.
Alex Klyubin622fd932015-05-12 12:53:23 -0700326 *
Kenny Roota3985982013-08-16 14:03:29 -0700327 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700328 @NonNull
Alex Klyubin3f8d4d82015-05-13 09:15:00 -0700329 public Builder setKeyType(@NonNull @KeyProperties.KeyAlgorithmEnum String keyType)
Alex Klyubin4d5443f2015-05-06 15:43:52 -0700330 throws NoSuchAlgorithmException {
Kenny Roota3985982013-08-16 14:03:29 -0700331 if (keyType == null) {
332 throw new NullPointerException("keyType == null");
333 } else {
Alex Klyubin4a0ff7c2015-06-09 13:25:20 -0700334 try {
335 KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(keyType);
336 } catch (IllegalArgumentException e) {
Kenny Roota3985982013-08-16 14:03:29 -0700337 throw new NoSuchAlgorithmException("Unsupported key type: " + keyType);
338 }
339 }
340 mKeyType = keyType;
341 return this;
342 }
343
344 /**
345 * Sets the key size for the keypair to be created. For instance, for a
346 * key type of RSA this will set the modulus size and for a key type of
347 * EC it will select a curve with a matching field size.
Kenny Roota3985982013-08-16 14:03:29 -0700348 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700349 @NonNull
Kenny Roota3985982013-08-16 14:03:29 -0700350 public Builder setKeySize(int keySize) {
351 if (keySize < 0) {
352 throw new IllegalArgumentException("keySize < 0");
353 }
354 mKeySize = keySize;
355 return this;
356 }
357
358 /**
Alex Klyubincd2329d2015-01-14 16:45:51 -0800359 * Sets the algorithm-specific key generation parameters. For example, for RSA keys
360 * this may be an instance of {@link java.security.spec.RSAKeyGenParameterSpec}.
Kenny Roota3985982013-08-16 14:03:29 -0700361 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700362 public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) {
Kenny Roota3985982013-08-16 14:03:29 -0700363 if (spec == null) {
364 throw new NullPointerException("spec == null");
365 }
366 mSpec = spec;
367 return this;
368 }
369
370 /**
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700371 * Sets the subject used for the self-signed certificate of the
372 * generated key pair.
373 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700374 @NonNull
375 public Builder setSubject(@NonNull X500Principal subject) {
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700376 if (subject == null) {
377 throw new NullPointerException("subject == null");
378 }
379 mSubjectDN = subject;
380 return this;
381 }
382
383 /**
384 * Sets the serial number used for the self-signed certificate of the
385 * generated key pair.
386 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700387 @NonNull
388 public Builder setSerialNumber(@NonNull BigInteger serialNumber) {
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700389 if (serialNumber == null) {
390 throw new NullPointerException("serialNumber == null");
391 }
392 mSerialNumber = serialNumber;
393 return this;
394 }
395
396 /**
397 * Sets the start of the validity period for the self-signed certificate
398 * of the generated key pair.
399 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700400 @NonNull
401 public Builder setStartDate(@NonNull Date startDate) {
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700402 if (startDate == null) {
403 throw new NullPointerException("startDate == null");
404 }
405 mStartDate = startDate;
406 return this;
407 }
408
409 /**
410 * Sets the end of the validity period for the self-signed certificate
411 * of the generated key pair.
412 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700413 @NonNull
414 public Builder setEndDate(@NonNull Date endDate) {
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700415 if (endDate == null) {
416 throw new NullPointerException("endDate == null");
417 }
418 mEndDate = endDate;
419 return this;
420 }
421
422 /**
Alex Klyubin54183932015-05-08 15:25:48 -0700423 * Indicates that this key pair must be encrypted at rest. This will protect the key pair
424 * with the secure lock screen credential (e.g., password, PIN, or pattern).
Alex Klyubineedda452015-05-07 17:34:24 -0700425 *
426 * <p>Note that this feature requires that the secure lock screen (e.g., password, PIN,
Alex Klyubin54183932015-05-08 15:25:48 -0700427 * pattern) is set up, otherwise key pair generation will fail. Moreover, this key pair will
428 * be deleted when the secure lock screen is disabled or reset (e.g., by the user or a
429 * Device Administrator). Finally, this key pair cannot be used until the user unlocks the
430 * secure lock screen after boot.
Alex Klyubineedda452015-05-07 17:34:24 -0700431 *
432 * @see KeyguardManager#isDeviceSecure()
Kenny Root2eeda722013-04-10 11:30:58 -0700433 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700434 @NonNull
Kenny Root2eeda722013-04-10 11:30:58 -0700435 public Builder setEncryptionRequired() {
436 mFlags |= KeyStore.FLAG_ENCRYPTED;
437 return this;
438 }
439
440 /**
Kenny Root1c219f62013-04-18 17:57:03 -0700441 * Builds the instance of the {@code KeyPairGeneratorSpec}.
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700442 *
443 * @throws IllegalArgumentException if a required field is missing
Kenny Root1c219f62013-04-18 17:57:03 -0700444 * @return built instance of {@code KeyPairGeneratorSpec}
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700445 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700446 @NonNull
Kenny Root1c219f62013-04-18 17:57:03 -0700447 public KeyPairGeneratorSpec build() {
Alex Klyubin855fa312015-04-02 09:58:08 -0700448 return new KeyPairGeneratorSpec(mContext,
449 mKeystoreAlias,
450 mKeyType,
451 mKeySize,
452 mSpec,
453 mSubjectDN,
454 mSerialNumber,
455 mStartDate,
456 mEndDate,
Alex Klyubin3f8d4d82015-05-13 09:15:00 -0700457 mFlags);
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700458 }
459 }
Kenny Rootdb026712012-08-20 10:48:46 -0700460}