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 <a href="{@docRoot} 255 * training/articles/keystore.html">Android KeyStore facility</a>. 256 * <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 * 266 * KeyPairGeneratorSpec spec = 267 * new KeyPairGeneratorSpec.Builder(mContext).setAlias("myKey") 268 * .setSubject(new X500Principal("CN=myKey")).setSerial(BigInteger.valueOf(1337)) 269 * .setStartDate(start.getTime()).setEndDate(end.getTime()).build(); 270 * </pre> 271 * 272 * @deprecated Use {@link KeyGenParameterSpec.Builder} instead. 273 */ 274 @Deprecated 275 public final static class Builder { 276 private final Context mContext; 277 278 private String mKeystoreAlias; 279 280 private String mKeyType; 281 282 private int mKeySize = -1; 283 284 private AlgorithmParameterSpec mSpec; 285 286 private X500Principal mSubjectDN; 287 288 private BigInteger mSerialNumber; 289 290 private Date mStartDate; 291 292 private Date mEndDate; 293 294 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 */ 302 public Builder(@NonNull Context context) { 303 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 */ 314 @NonNull 315 public Builder setAlias(@NonNull String alias) { 316 if (alias == null) { 317 throw new NullPointerException("alias == null"); 318 } 319 mKeystoreAlias = alias; 320 return this; 321 } 322 323 /** 324 * Sets the type of key pair (e.g., {@code EC}, {@code RSA}) of the key pair to be 325 * generated. See {@link KeyProperties}.{@code KEY_ALGORITHM} constants. 326 * 327 */ 328 @NonNull 329 public Builder setKeyType(@NonNull @KeyProperties.KeyAlgorithmEnum String keyType) 330 throws NoSuchAlgorithmException { 331 if (keyType == null) { 332 throw new NullPointerException("keyType == null"); 333 } else { 334 try { 335 KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(keyType); 336 } catch (IllegalArgumentException e) { 337 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. 348 */ 349 @NonNull 350 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 /** 359 * Sets the algorithm-specific key generation parameters. For example, for RSA keys 360 * this may be an instance of {@link java.security.spec.RSAKeyGenParameterSpec}. 361 */ 362 public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) { 363 if (spec == null) { 364 throw new NullPointerException("spec == null"); 365 } 366 mSpec = spec; 367 return this; 368 } 369 370 /** 371 * Sets the subject used for the self-signed certificate of the 372 * generated key pair. 373 */ 374 @NonNull 375 public Builder setSubject(@NonNull X500Principal subject) { 376 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 */ 387 @NonNull 388 public Builder setSerialNumber(@NonNull BigInteger serialNumber) { 389 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 */ 400 @NonNull 401 public Builder setStartDate(@NonNull Date startDate) { 402 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 */ 413 @NonNull 414 public Builder setEndDate(@NonNull Date endDate) { 415 if (endDate == null) { 416 throw new NullPointerException("endDate == null"); 417 } 418 mEndDate = endDate; 419 return this; 420 } 421 422 /** 423 * 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). 425 * 426 * <p>Note that this feature requires that the secure lock screen (e.g., password, PIN, 427 * 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. 431 * 432 * @see KeyguardManager#isDeviceSecure() 433 */ 434 @NonNull 435 public Builder setEncryptionRequired() { 436 mFlags |= KeyStore.FLAG_ENCRYPTED; 437 return this; 438 } 439 440 /** 441 * Builds the instance of the {@code KeyPairGeneratorSpec}. 442 * 443 * @throws IllegalArgumentException if a required field is missing 444 * @return built instance of {@code KeyPairGeneratorSpec} 445 */ 446 @NonNull 447 public KeyPairGeneratorSpec build() { 448 return new KeyPairGeneratorSpec(mContext, 449 mKeystoreAlias, 450 mKeyType, 451 mKeySize, 452 mSpec, 453 mSubjectDN, 454 mSerialNumber, 455 mStartDate, 456 mEndDate, 457 mFlags); 458 } 459 } 460} 461