blob: d023866ca7024c94db2ece65763e60121f31d585 [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>
Kevin Hufnaglec0c4ac52016-09-19 11:31:08 -0700254 * This will build a parameter spec for use with the
255 * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore
256 * facility</a>.
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700257 * <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 Root1c219f62013-04-18 17:57:03 -0700267 * KeyPairGeneratorSpec spec =
268 * new KeyPairGeneratorSpec.Builder(mContext).setAlias(&quot;myKey&quot;)
269 * .setSubject(new X500Principal(&quot;CN=myKey&quot;)).setSerial(BigInteger.valueOf(1337))
270 * .setStartDate(start.getTime()).setEndDate(end.getTime()).build();
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700271 * </pre>
Alex Klyubin3f8d4d82015-05-13 09:15:00 -0700272 *
273 * @deprecated Use {@link KeyGenParameterSpec.Builder} instead.
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700274 */
Alex Klyubin3f8d4d82015-05-13 09:15:00 -0700275 @Deprecated
Kenny Root2eeda722013-04-10 11:30:58 -0700276 public final static class Builder {
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700277 private final Context mContext;
278
279 private String mKeystoreAlias;
280
Alex Klyubin21a76df2015-01-14 13:35:32 -0800281 private String mKeyType;
Kenny Roota3985982013-08-16 14:03:29 -0700282
283 private int mKeySize = -1;
284
285 private AlgorithmParameterSpec mSpec;
286
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700287 private X500Principal mSubjectDN;
288
289 private BigInteger mSerialNumber;
290
291 private Date mStartDate;
292
293 private Date mEndDate;
294
Kenny Root2eeda722013-04-10 11:30:58 -0700295 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 Klyubin54bb1592015-05-11 12:30:03 -0700303 public Builder(@NonNull Context context) {
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700304 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 Klyubin54bb1592015-05-11 12:30:03 -0700315 @NonNull
316 public Builder setAlias(@NonNull String alias) {
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700317 if (alias == null) {
318 throw new NullPointerException("alias == null");
319 }
320 mKeystoreAlias = alias;
321 return this;
322 }
323
324 /**
Alex Klyubin622fd932015-05-12 12:53:23 -0700325 * 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 -0700326 * generated. See {@link KeyProperties}.{@code KEY_ALGORITHM} constants.
Alex Klyubin622fd932015-05-12 12:53:23 -0700327 *
Kenny Roota3985982013-08-16 14:03:29 -0700328 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700329 @NonNull
Alex Klyubin3f8d4d82015-05-13 09:15:00 -0700330 public Builder setKeyType(@NonNull @KeyProperties.KeyAlgorithmEnum String keyType)
Alex Klyubin4d5443f2015-05-06 15:43:52 -0700331 throws NoSuchAlgorithmException {
Kenny Roota3985982013-08-16 14:03:29 -0700332 if (keyType == null) {
333 throw new NullPointerException("keyType == null");
334 } else {
Alex Klyubin4a0ff7c2015-06-09 13:25:20 -0700335 try {
336 KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(keyType);
337 } catch (IllegalArgumentException e) {
Kenny Roota3985982013-08-16 14:03:29 -0700338 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 Roota3985982013-08-16 14:03:29 -0700349 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700350 @NonNull
Kenny Roota3985982013-08-16 14:03:29 -0700351 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 Klyubincd2329d2015-01-14 16:45:51 -0800360 * 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 Roota3985982013-08-16 14:03:29 -0700362 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700363 public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) {
Kenny Roota3985982013-08-16 14:03:29 -0700364 if (spec == null) {
365 throw new NullPointerException("spec == null");
366 }
367 mSpec = spec;
368 return this;
369 }
370
371 /**
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700372 * Sets the subject used for the self-signed certificate of the
373 * generated key pair.
374 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700375 @NonNull
376 public Builder setSubject(@NonNull X500Principal subject) {
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700377 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 Klyubin54bb1592015-05-11 12:30:03 -0700388 @NonNull
389 public Builder setSerialNumber(@NonNull BigInteger serialNumber) {
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700390 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 Klyubin54bb1592015-05-11 12:30:03 -0700401 @NonNull
402 public Builder setStartDate(@NonNull Date startDate) {
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700403 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 Klyubin54bb1592015-05-11 12:30:03 -0700414 @NonNull
415 public Builder setEndDate(@NonNull Date endDate) {
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700416 if (endDate == null) {
417 throw new NullPointerException("endDate == null");
418 }
419 mEndDate = endDate;
420 return this;
421 }
422
423 /**
Alex Klyubin54183932015-05-08 15:25:48 -0700424 * 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 Klyubineedda452015-05-07 17:34:24 -0700426 *
427 * <p>Note that this feature requires that the secure lock screen (e.g., password, PIN,
Alex Klyubin54183932015-05-08 15:25:48 -0700428 * 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 Klyubineedda452015-05-07 17:34:24 -0700432 *
433 * @see KeyguardManager#isDeviceSecure()
Kenny Root2eeda722013-04-10 11:30:58 -0700434 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700435 @NonNull
Kenny Root2eeda722013-04-10 11:30:58 -0700436 public Builder setEncryptionRequired() {
437 mFlags |= KeyStore.FLAG_ENCRYPTED;
438 return this;
439 }
440
441 /**
Kenny Root1c219f62013-04-18 17:57:03 -0700442 * Builds the instance of the {@code KeyPairGeneratorSpec}.
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700443 *
444 * @throws IllegalArgumentException if a required field is missing
Kenny Root1c219f62013-04-18 17:57:03 -0700445 * @return built instance of {@code KeyPairGeneratorSpec}
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700446 */
Alex Klyubin54bb1592015-05-11 12:30:03 -0700447 @NonNull
Kenny Root1c219f62013-04-18 17:57:03 -0700448 public KeyPairGeneratorSpec build() {
Alex Klyubin855fa312015-04-02 09:58:08 -0700449 return new KeyPairGeneratorSpec(mContext,
450 mKeystoreAlias,
451 mKeyType,
452 mKeySize,
453 mSpec,
454 mSubjectDN,
455 mSerialNumber,
456 mStartDate,
457 mEndDate,
Alex Klyubin3f8d4d82015-05-13 09:15:00 -0700458 mFlags);
Kenny Rootacb0b5b2013-03-28 15:05:03 -0700459 }
460 }
Kenny Rootdb026712012-08-20 10:48:46 -0700461}