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 17package android.security; 18 19import android.app.KeyguardManager; 20import android.annotation.NonNull; 21import android.annotation.Nullable; 22import android.content.Context; 23import android.security.keystore.KeyGenParameterSpec; 24import android.security.keystore.KeyProperties; 25import android.text.TextUtils; 26 27import java.math.BigInteger; 28import java.security.NoSuchAlgorithmException; 29import 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/** 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 61public 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 private final int mFlags; 82 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 103 * @param keyType key algorithm to use (RSA, DSA, EC) 104 * @param keySize size of key to generate 105 * @param spec the underlying key type parameters 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}. 113 * @hide should be built with KeyPairGeneratorSpecBuilder 114 */ 115 public KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize, 116 AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber, 117 Date startDate, Date endDate, int flags) { 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"); 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"); 132 } 133 134 if (endDate.before(startDate)) { 135 throw new IllegalArgumentException("endDate < startDate"); 136 } 137 138 mContext = context; 139 mKeystoreAlias = keyStoreAlias; 140 mKeyType = keyType; 141 mKeySize = keySize; 142 mSpec = spec; 143 mSubjectDN = subjectDN; 144 mSerialNumber = serialNumber; 145 mStartDate = startDate; 146 mEndDate = endDate; 147 mFlags = flags; 148 } 149 150 /** 151 * Gets the Android context used for operations with this instance. 152 */ 153 public Context getContext() { 154 return mContext; 155 } 156 157 /** 158 * Returns the alias that will be used in the {@code java.security.KeyStore} 159 * in conjunction with the {@code AndroidKeyStore}. 160 */ 161 public String getKeystoreAlias() { 162 return mKeystoreAlias; 163 } 164 165 /** 166 * Returns the type of key pair (e.g., {@code EC}, {@code RSA}) to be generated. See 167 * {@link KeyProperties}.{@code KEY_ALGORITHM} constants. 168 */ 169 @Nullable 170 public @KeyProperties.KeyAlgorithmEnum String getKeyType() { 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. 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. 186 */ 187 @NonNull 188 public AlgorithmParameterSpec getAlgorithmParameterSpec() { 189 return mSpec; 190 } 191 192 /** 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}. 195 */ 196 @NonNull 197 public X500Principal getSubjectDN() { 198 return mSubjectDN; 199 } 200 201 /** 202 * Gets the serial number to be used on the X.509 certificate that will be 203 * put in the {@link java.security.KeyStore}. 204 */ 205 @NonNull 206 public BigInteger getSerialNumber() { 207 return mSerialNumber; 208 } 209 210 /** 211 * Gets the start date to be used on the X.509 certificate that will be put 212 * in the {@link java.security.KeyStore}. 213 */ 214 @NonNull 215 public Date getStartDate() { 216 return mStartDate; 217 } 218 219 /** 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 */ 223 @NonNull 224 public Date getEndDate() { 225 return mEndDate; 226 } 227 228 /** 229 * @hide 230 */ 231 public int getFlags() { 232 return mFlags; 233 } 234 235 /** 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). 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() 246 */ 247 public boolean isEncryptionRequired() { 248 return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0; 249 } 250 251 /** 252 * Builder class for {@link KeyPairGeneratorSpec} objects. 253 * <p> 254 * This will build a parameter spec for use with the 255 * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore 256 * facility</a>. 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 * 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(); 271 * </pre> 272 * 273 * @deprecated Use {@link KeyGenParameterSpec.Builder} instead. 274 */ 275 @Deprecated 276 public final static class Builder { 277 private final Context mContext; 278 279 private String mKeystoreAlias; 280 281 private String mKeyType; 282 283 private int mKeySize = -1; 284 285 private AlgorithmParameterSpec mSpec; 286 287 private X500Principal mSubjectDN; 288 289 private BigInteger mSerialNumber; 290 291 private Date mStartDate; 292 293 private Date mEndDate; 294 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 */ 303 public Builder(@NonNull Context context) { 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 */ 315 @NonNull 316 public Builder setAlias(@NonNull String alias) { 317 if (alias == null) { 318 throw new NullPointerException("alias == null"); 319 } 320 mKeystoreAlias = alias; 321 return this; 322 } 323 324 /** 325 * Sets the type of key pair (e.g., {@code EC}, {@code RSA}) of the key pair to be 326 * generated. See {@link KeyProperties}.{@code KEY_ALGORITHM} constants. 327 * 328 */ 329 @NonNull 330 public Builder setKeyType(@NonNull @KeyProperties.KeyAlgorithmEnum String keyType) 331 throws NoSuchAlgorithmException { 332 if (keyType == null) { 333 throw new NullPointerException("keyType == null"); 334 } else { 335 try { 336 KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(keyType); 337 } catch (IllegalArgumentException e) { 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. 349 */ 350 @NonNull 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 /** 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}. 362 */ 363 public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) { 364 if (spec == null) { 365 throw new NullPointerException("spec == null"); 366 } 367 mSpec = spec; 368 return this; 369 } 370 371 /** 372 * Sets the subject used for the self-signed certificate of the 373 * generated key pair. 374 */ 375 @NonNull 376 public Builder setSubject(@NonNull X500Principal subject) { 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 */ 388 @NonNull 389 public Builder setSerialNumber(@NonNull BigInteger serialNumber) { 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 */ 401 @NonNull 402 public Builder setStartDate(@NonNull Date startDate) { 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 */ 414 @NonNull 415 public Builder setEndDate(@NonNull Date endDate) { 416 if (endDate == null) { 417 throw new NullPointerException("endDate == null"); 418 } 419 mEndDate = endDate; 420 return this; 421 } 422 423 /** 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). 426 * 427 * <p>Note that this feature requires that the secure lock screen (e.g., password, PIN, 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. 432 * 433 * @see KeyguardManager#isDeviceSecure() 434 */ 435 @NonNull 436 public Builder setEncryptionRequired() { 437 mFlags |= KeyStore.FLAG_ENCRYPTED; 438 return this; 439 } 440 441 /** 442 * Builds the instance of the {@code KeyPairGeneratorSpec}. 443 * 444 * @throws IllegalArgumentException if a required field is missing 445 * @return built instance of {@code KeyPairGeneratorSpec} 446 */ 447 @NonNull 448 public KeyPairGeneratorSpec build() { 449 return new KeyPairGeneratorSpec(mContext, 450 mKeystoreAlias, 451 mKeyType, 452 mKeySize, 453 mSpec, 454 mSubjectDN, 455 mSerialNumber, 456 mStartDate, 457 mEndDate, 458 mFlags); 459 } 460 } 461} 462