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 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.app.KeyguardManager; 22 import android.content.Context; 23 import android.security.keystore.KeyGenParameterSpec; 24 import android.security.keystore.KeyProperties; 25 import android.text.TextUtils; 26 27 import java.math.BigInteger; 28 import java.security.NoSuchAlgorithmException; 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 /** 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. 57 * 58 * @deprecated Use {@link KeyGenParameterSpec} instead. 59 */ 60 @Deprecated 61 public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { 62 63 private final Context mContext; 64 65 private final String mKeystoreAlias; 66 67 private final String mKeyType; 68 69 private final int mKeySize; 70 71 private final AlgorithmParameterSpec mSpec; 72 73 private final X500Principal mSubjectDN; 74 75 private final BigInteger mSerialNumber; 76 77 private final Date mStartDate; 78 79 private final Date mEndDate; 80 81 /** 82 * Parameter specification for the "{@code AndroidKeyPairGenerator}" 83 * instance of the {@link java.security.KeyPairGenerator} API. The 84 * {@code context} passed in may be used to pop up some UI to ask the user 85 * to unlock or initialize the Android keystore facility. 86 * <p> 87 * After generation, the {@code keyStoreAlias} is used with the 88 * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)} 89 * interface to retrieve the {@link PrivateKey} and its associated 90 * {@link Certificate} chain. 91 * <p> 92 * The KeyPair generator will create a self-signed certificate with the 93 * properties of {@code subjectDN} as its X.509v3 Subject Distinguished Name 94 * and as its X.509v3 Issuer Distinguished Name, using the specified 95 * {@code serialNumber}, and the validity date starting at {@code startDate} 96 * and ending at {@code endDate}. 97 * 98 * @param context Android context for the activity 99 * @param keyStoreAlias name to use for the generated key in the Android 100 * keystore 101 * @param keyType key algorithm to use (RSA, DSA, EC) 102 * @param keySize size of key to generate 103 * @param spec the underlying key type parameters 104 * @param subjectDN X.509 v3 Subject Distinguished Name 105 * @param serialNumber X509 v3 certificate serial number 106 * @param startDate the start of the self-signed certificate validity period 107 * @param endDate the end date of the self-signed certificate validity 108 * period 109 * @throws IllegalArgumentException when any argument is {@code null} or 110 * {@code endDate} is before {@code startDate}. 111 * @hide should be built with KeyPairGeneratorSpecBuilder 112 */ KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize, AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber, Date startDate, Date endDate, int flags)113 public KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize, 114 AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber, 115 Date startDate, Date endDate, int flags) { 116 if (context == null) { 117 throw new IllegalArgumentException("context == null"); 118 } else if (TextUtils.isEmpty(keyStoreAlias)) { 119 throw new IllegalArgumentException("keyStoreAlias must not be empty"); 120 } else if (subjectDN == null) { 121 throw new IllegalArgumentException("subjectDN == null"); 122 } else if (serialNumber == null) { 123 throw new IllegalArgumentException("serialNumber == null"); 124 } else if (startDate == null) { 125 throw new IllegalArgumentException("startDate == null"); 126 } else if (endDate == null) { 127 throw new IllegalArgumentException("endDate == null"); 128 } else if (endDate.before(startDate)) { 129 throw new IllegalArgumentException("endDate < startDate"); 130 } 131 132 if (endDate.before(startDate)) { 133 throw new IllegalArgumentException("endDate < startDate"); 134 } 135 136 mContext = context; 137 mKeystoreAlias = keyStoreAlias; 138 mKeyType = keyType; 139 mKeySize = keySize; 140 mSpec = spec; 141 mSubjectDN = subjectDN; 142 mSerialNumber = serialNumber; 143 mStartDate = startDate; 144 mEndDate = endDate; 145 } 146 147 /** 148 * Gets the Android context used for operations with this instance. 149 */ getContext()150 public Context getContext() { 151 return mContext; 152 } 153 154 /** 155 * Returns the alias that will be used in the {@code java.security.KeyStore} 156 * in conjunction with the {@code AndroidKeyStore}. 157 */ getKeystoreAlias()158 public String getKeystoreAlias() { 159 return mKeystoreAlias; 160 } 161 162 /** 163 * Returns the type of key pair (e.g., {@code EC}, {@code RSA}) to be generated. See 164 * {@link KeyProperties}.{@code KEY_ALGORITHM} constants. 165 */ 166 @Nullable getKeyType()167 public @KeyProperties.KeyAlgorithmEnum String getKeyType() { 168 return mKeyType; 169 } 170 171 /** 172 * Returns the key size specified by this parameter. For instance, for RSA 173 * this will return the modulus size and for EC it will return the field 174 * size. 175 */ getKeySize()176 public int getKeySize() { 177 return mKeySize; 178 } 179 180 /** 181 * Returns the {@link AlgorithmParameterSpec} that will be used for creation 182 * of the key pair. 183 */ 184 @NonNull getAlgorithmParameterSpec()185 public AlgorithmParameterSpec getAlgorithmParameterSpec() { 186 return mSpec; 187 } 188 189 /** 190 * Gets the subject distinguished name to be used on the X.509 certificate 191 * that will be put in the {@link java.security.KeyStore}. 192 */ 193 @NonNull getSubjectDN()194 public X500Principal getSubjectDN() { 195 return mSubjectDN; 196 } 197 198 /** 199 * Gets the serial number to be used on the X.509 certificate that will be 200 * put in the {@link java.security.KeyStore}. 201 */ 202 @NonNull getSerialNumber()203 public BigInteger getSerialNumber() { 204 return mSerialNumber; 205 } 206 207 /** 208 * Gets the start date to be used on the X.509 certificate that will be put 209 * in the {@link java.security.KeyStore}. 210 */ 211 @NonNull getStartDate()212 public Date getStartDate() { 213 return mStartDate; 214 } 215 216 /** 217 * Gets the end date to be used on the X.509 certificate that will be put in 218 * the {@link java.security.KeyStore}. 219 */ 220 @NonNull getEndDate()221 public Date getEndDate() { 222 return mEndDate; 223 } 224 225 /** 226 * @hide 227 */ getFlags()228 public int getFlags() { 229 return 0; 230 } 231 232 /** 233 * Returns {@code true} if the key must be encrypted at rest. This will protect the key pair 234 * with the secure lock screen credential (e.g., password, PIN, or pattern). 235 * 236 * <p>Note that encrypting the key at rest requires that the secure lock screen (e.g., password, 237 * PIN, pattern) is set up, otherwise key generation will fail. Moreover, this key will be 238 * deleted when the secure lock screen is disabled or reset (e.g., by the user or a Device 239 * Administrator). Finally, this key cannot be used until the user unlocks the secure lock 240 * screen after boot. 241 * 242 * @see KeyguardManager#isDeviceSecure() 243 * 244 * @deprecated Encryption at rest is on by default. If extra binding to the lockscreen screen 245 * credential is desired use 246 * {@link KeyGenParameterSpec.Builder#setUserAuthenticationRequired(boolean)}. 247 * This flag will be ignored from Android S. 248 */ 249 @Deprecated isEncryptionRequired()250 public boolean isEncryptionRequired() { 251 return false; 252 } 253 254 /** 255 * Builder class for {@link KeyPairGeneratorSpec} objects. 256 * <p> 257 * This will build a parameter spec for use with the 258 * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore 259 * facility</a>. 260 * <p> 261 * The required fields must be filled in with the builder. 262 * <p> 263 * Example: 264 * 265 * <pre class="prettyprint"> 266 * Calendar start = Calendar.getInstance(); 267 * Calendar end = Calendar.getInstance(); 268 * end.add(Calendar.YEAR, 1); 269 * 270 * KeyPairGeneratorSpec spec = 271 * new KeyPairGeneratorSpec.Builder(mContext).setAlias("myKey") 272 * .setSubject(new X500Principal("CN=myKey")).setSerialNumber(BigInteger.valueOf(1337)) 273 * .setStartDate(start.getTime()).setEndDate(end.getTime()).build(); 274 * </pre> 275 * 276 * @deprecated Use {@link KeyGenParameterSpec.Builder} instead. 277 */ 278 @Deprecated 279 public final static class Builder { 280 private final Context mContext; 281 282 private String mKeystoreAlias; 283 284 private String mKeyType; 285 286 private int mKeySize = -1; 287 288 private AlgorithmParameterSpec mSpec; 289 290 private X500Principal mSubjectDN; 291 292 private BigInteger mSerialNumber; 293 294 private Date mStartDate; 295 296 private Date mEndDate; 297 298 /** 299 * Creates a new instance of the {@code Builder} with the given 300 * {@code context}. The {@code context} passed in may be used to pop up 301 * some UI to ask the user to unlock or initialize the Android KeyStore 302 * facility. 303 */ Builder(@onNull Context context)304 public Builder(@NonNull Context context) { 305 if (context == null) { 306 throw new NullPointerException("context == null"); 307 } 308 mContext = context; 309 } 310 311 /** 312 * Sets the alias to be used to retrieve the key later from a 313 * {@link java.security.KeyStore} instance using the 314 * {@code AndroidKeyStore} provider. 315 */ 316 @NonNull setAlias(@onNull String alias)317 public Builder setAlias(@NonNull String alias) { 318 if (alias == null) { 319 throw new NullPointerException("alias == null"); 320 } 321 mKeystoreAlias = alias; 322 return this; 323 } 324 325 /** 326 * Sets the type of key pair (e.g., {@code EC}, {@code RSA}) of the key pair to be 327 * generated. See {@link KeyProperties}.{@code KEY_ALGORITHM} constants. 328 * 329 */ 330 @NonNull setKeyType(@onNull @eyProperties.KeyAlgorithmEnum String keyType)331 public Builder setKeyType(@NonNull @KeyProperties.KeyAlgorithmEnum String keyType) 332 throws NoSuchAlgorithmException { 333 if (keyType == null) { 334 throw new NullPointerException("keyType == null"); 335 } else { 336 try { 337 KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(keyType); 338 } catch (IllegalArgumentException e) { 339 throw new NoSuchAlgorithmException("Unsupported key type: " + keyType); 340 } 341 } 342 mKeyType = keyType; 343 return this; 344 } 345 346 /** 347 * Sets the key size for the keypair to be created. For instance, for a 348 * key type of RSA this will set the modulus size and for a key type of 349 * EC it will select a curve with a matching field size. 350 */ 351 @NonNull setKeySize(int keySize)352 public Builder setKeySize(int keySize) { 353 if (keySize < 0) { 354 throw new IllegalArgumentException("keySize < 0"); 355 } 356 mKeySize = keySize; 357 return this; 358 } 359 360 /** 361 * Sets the algorithm-specific key generation parameters. For example, for RSA keys 362 * this may be an instance of {@link java.security.spec.RSAKeyGenParameterSpec}. 363 */ setAlgorithmParameterSpec(@onNull AlgorithmParameterSpec spec)364 public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) { 365 if (spec == null) { 366 throw new NullPointerException("spec == null"); 367 } 368 mSpec = spec; 369 return this; 370 } 371 372 /** 373 * Sets the subject used for the self-signed certificate of the 374 * generated key pair. 375 */ 376 @NonNull setSubject(@onNull X500Principal subject)377 public Builder setSubject(@NonNull X500Principal subject) { 378 if (subject == null) { 379 throw new NullPointerException("subject == null"); 380 } 381 mSubjectDN = subject; 382 return this; 383 } 384 385 /** 386 * Sets the serial number used for the self-signed certificate of the 387 * generated key pair. 388 */ 389 @NonNull setSerialNumber(@onNull BigInteger serialNumber)390 public Builder setSerialNumber(@NonNull BigInteger serialNumber) { 391 if (serialNumber == null) { 392 throw new NullPointerException("serialNumber == null"); 393 } 394 mSerialNumber = serialNumber; 395 return this; 396 } 397 398 /** 399 * Sets the start of the validity period for the self-signed certificate 400 * of the generated key pair. 401 */ 402 @NonNull setStartDate(@onNull Date startDate)403 public Builder setStartDate(@NonNull Date startDate) { 404 if (startDate == null) { 405 throw new NullPointerException("startDate == null"); 406 } 407 mStartDate = startDate; 408 return this; 409 } 410 411 /** 412 * Sets the end of the validity period for the self-signed certificate 413 * of the generated key pair. 414 */ 415 @NonNull setEndDate(@onNull Date endDate)416 public Builder setEndDate(@NonNull Date endDate) { 417 if (endDate == null) { 418 throw new NullPointerException("endDate == null"); 419 } 420 mEndDate = endDate; 421 return this; 422 } 423 424 /** 425 * Indicates that this key pair must be encrypted at rest. This will protect the key pair 426 * with the secure lock screen credential (e.g., password, PIN, or pattern). 427 * 428 * <p>Note that this feature requires that the secure lock screen (e.g., password, PIN, 429 * pattern) is set up, otherwise key pair generation will fail. Moreover, this key pair will 430 * be deleted when the secure lock screen is disabled or reset (e.g., by the user or a 431 * Device Administrator). Finally, this key pair cannot be used until the user unlocks the 432 * secure lock screen after boot. 433 * 434 * @see KeyguardManager#isDeviceSecure() 435 * 436 * @deprecated Data at rest encryption is enabled by default. If extra binding to the 437 * lockscreen credential is desired, use 438 * {@link KeyGenParameterSpec.Builder#setUserAuthenticationRequired(boolean)}. 439 * This flag will be ignored from Android S. 440 */ 441 @NonNull 442 @Deprecated setEncryptionRequired()443 public Builder setEncryptionRequired() { 444 return this; 445 } 446 447 /** 448 * Builds the instance of the {@code KeyPairGeneratorSpec}. 449 * 450 * @throws IllegalArgumentException if a required field is missing 451 * @return built instance of {@code KeyPairGeneratorSpec} 452 */ 453 @NonNull build()454 public KeyPairGeneratorSpec build() { 455 return new KeyPairGeneratorSpec(mContext, 456 mKeystoreAlias, 457 mKeyType, 458 mKeySize, 459 mSpec, 460 mSubjectDN, 461 mSerialNumber, 462 mStartDate, 463 mEndDate, 464 0); 465 } 466 } 467 } 468