KeyStoreParameter.java revision 5927c9f1b12f597839a664c1c6593114175cbcd8
1/* 2 * Copyright (C) 2013 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.content.Context; 20 21import java.security.Key; 22import java.security.KeyStore.ProtectionParameter; 23import java.util.Date; 24 25import javax.crypto.Cipher; 26 27/** 28 * Parameters specifying how to secure and restrict the use of a key being 29 * imported into the 30 * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore 31 * facility</a>. The Android KeyStore facility is accessed through a 32 * {@link java.security.KeyStore} API using the {@code AndroidKeyStore} 33 * provider. The {@code context} passed in may be used to pop up some UI to ask 34 * the user to unlock or initialize the Android KeyStore facility. 35 * <p> 36 * Any entries placed in the {@code KeyStore} may be retrieved later. Note that 37 * there is only one logical instance of the {@code KeyStore} per application 38 * UID so apps using the {@code sharedUid} facility will also share a 39 * {@code KeyStore}. 40 */ 41public final class KeyStoreParameter implements ProtectionParameter { 42 private int mFlags; 43 private final Date mKeyValidityStart; 44 private final Date mKeyValidityForOriginationEnd; 45 private final Date mKeyValidityForConsumptionEnd; 46 private final @KeyStoreKeyProperties.PurposeEnum int mPurposes; 47 private final String[] mEncryptionPaddings; 48 private final String[] mSignaturePaddings; 49 private final String[] mDigests; 50 private final String[] mBlockModes; 51 private final boolean mRandomizedEncryptionRequired; 52 private final @KeyStoreKeyProperties.UserAuthenticatorEnum int mUserAuthenticators; 53 private final int mUserAuthenticationValidityDurationSeconds; 54 55 private KeyStoreParameter(int flags, 56 Date keyValidityStart, 57 Date keyValidityForOriginationEnd, 58 Date keyValidityForConsumptionEnd, 59 @KeyStoreKeyProperties.PurposeEnum int purposes, 60 String[] encryptionPaddings, 61 String[] signaturePaddings, 62 String[] digests, 63 String[] blockModes, 64 boolean randomizedEncryptionRequired, 65 @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators, 66 int userAuthenticationValidityDurationSeconds) { 67 if ((userAuthenticationValidityDurationSeconds < 0) 68 && (userAuthenticationValidityDurationSeconds != -1)) { 69 throw new IllegalArgumentException( 70 "userAuthenticationValidityDurationSeconds must not be negative"); 71 } 72 73 mFlags = flags; 74 mKeyValidityStart = keyValidityStart; 75 mKeyValidityForOriginationEnd = keyValidityForOriginationEnd; 76 mKeyValidityForConsumptionEnd = keyValidityForConsumptionEnd; 77 mPurposes = purposes; 78 mEncryptionPaddings = 79 ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings)); 80 mSignaturePaddings = 81 ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings)); 82 mDigests = ArrayUtils.cloneIfNotEmpty(digests); 83 mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes)); 84 mRandomizedEncryptionRequired = randomizedEncryptionRequired; 85 mUserAuthenticators = userAuthenticators; 86 mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds; 87 } 88 89 /** 90 * @hide 91 */ 92 public int getFlags() { 93 return mFlags; 94 } 95 96 /** 97 * Returns {@code true} if this parameter requires entries to be encrypted 98 * on the disk. 99 */ 100 public boolean isEncryptionRequired() { 101 return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0; 102 } 103 104 /** 105 * Gets the time instant before which the key is not yet valid. 106 * 107 * @return instant or {@code null} if not restricted. 108 * @hide 109 */ 110 public Date getKeyValidityStart() { 111 return mKeyValidityStart; 112 } 113 114 /** 115 * Gets the time instant after which the key is no long valid for decryption and verification. 116 * 117 * @return instant or {@code null} if not restricted. 118 * 119 * @hide 120 */ 121 public Date getKeyValidityForConsumptionEnd() { 122 return mKeyValidityForConsumptionEnd; 123 } 124 125 /** 126 * Gets the time instant after which the key is no long valid for encryption and signing. 127 * 128 * @return instant or {@code null} if not restricted. 129 * 130 * @hide 131 */ 132 public Date getKeyValidityForOriginationEnd() { 133 return mKeyValidityForOriginationEnd; 134 } 135 136 /** 137 * Gets the set of purposes for which the key can be used. 138 * 139 * @hide 140 */ 141 public @KeyStoreKeyProperties.PurposeEnum int getPurposes() { 142 return mPurposes; 143 } 144 145 /** 146 * Gets the set of padding schemes with which the key can be used when encrypting/decrypting. 147 * 148 * @hide 149 */ 150 public String[] getEncryptionPaddings() { 151 return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings); 152 } 153 154 /** 155 * Gets the set of padding schemes with which the key can be used when signing or verifying 156 * signatures. 157 * 158 * @hide 159 */ 160 public String[] getSignaturePaddings() { 161 return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings); 162 } 163 164 /** 165 * Gets the set of digest algorithms with which the key can be used. 166 * 167 * @throws IllegalStateException if this set has not been specified. 168 * 169 * @see #isDigestsSpecified() 170 * 171 * @hide 172 */ 173 public String[] getDigests() { 174 if (mDigests == null) { 175 throw new IllegalStateException("Digests not specified"); 176 } 177 return ArrayUtils.cloneIfNotEmpty(mDigests); 178 } 179 180 /** 181 * Returns {@code true} if the set of digest algorithms with which the key can be used has been 182 * specified. 183 * 184 * @see #getDigests() 185 * 186 * @hide 187 */ 188 public boolean isDigestsSpecified() { 189 return mDigests != null; 190 } 191 192 /** 193 * Gets the set of block modes with which the key can be used. 194 * 195 * @hide 196 */ 197 public String[] getBlockModes() { 198 return ArrayUtils.cloneIfNotEmpty(mBlockModes); 199 } 200 201 /** 202 * Returns {@code true} if encryption using this key must be sufficiently randomized to produce 203 * different ciphertexts for the same plaintext every time. The formal cryptographic property 204 * being required is <em>indistinguishability under chosen-plaintext attack ({@code 205 * IND-CPA})</em>. This property is important because it mitigates several classes of 206 * weaknesses due to which ciphertext may leak information about plaintext. For example, if a 207 * given plaintext always produces the same ciphertext, an attacker may see the repeated 208 * ciphertexts and be able to deduce something about the plaintext. 209 * 210 * @hide 211 */ 212 public boolean isRandomizedEncryptionRequired() { 213 return mRandomizedEncryptionRequired; 214 } 215 216 /** 217 * Gets the set of user authenticators which protect access to this key. The key can only be 218 * used iff the user has authenticated to at least one of these user authenticators. 219 * 220 * @return user authenticators or {@code 0} if the key can be used without user authentication. 221 * 222 * @hide 223 */ 224 public @KeyStoreKeyProperties.UserAuthenticatorEnum int getUserAuthenticators() { 225 return mUserAuthenticators; 226 } 227 228 /** 229 * Gets the duration of time (seconds) for which this key can be used after the user 230 * successfully authenticates to one of the associated user authenticators. 231 * 232 * @return duration in seconds or {@code -1} if not restricted. {@code 0} means authentication 233 * is required for every use of the key. 234 * 235 * @hide 236 */ 237 public int getUserAuthenticationValidityDurationSeconds() { 238 return mUserAuthenticationValidityDurationSeconds; 239 } 240 241 /** 242 * Builder class for {@link KeyStoreParameter} objects. 243 * <p> 244 * This will build protection parameters for use with the 245 * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore 246 * facility</a>. 247 * <p> 248 * This can be used to require that KeyStore entries be stored encrypted. 249 * <p> 250 * Example: 251 * 252 * <pre class="prettyprint"> 253 * KeyStoreParameter params = new KeyStoreParameter.Builder(mContext) 254 * .setEncryptionRequired() 255 * .build(); 256 * </pre> 257 */ 258 public final static class Builder { 259 private int mFlags; 260 private Date mKeyValidityStart; 261 private Date mKeyValidityForOriginationEnd; 262 private Date mKeyValidityForConsumptionEnd; 263 private @KeyStoreKeyProperties.PurposeEnum int mPurposes; 264 private String[] mEncryptionPaddings; 265 private String[] mSignaturePaddings; 266 private String[] mDigests; 267 private String[] mBlockModes; 268 private boolean mRandomizedEncryptionRequired = true; 269 private @KeyStoreKeyProperties.UserAuthenticatorEnum int mUserAuthenticators; 270 private int mUserAuthenticationValidityDurationSeconds = -1; 271 272 /** 273 * Creates a new instance of the {@code Builder} with the given 274 * {@code context}. The {@code context} passed in may be used to pop up 275 * some UI to ask the user to unlock or initialize the Android KeyStore 276 * facility. 277 */ 278 public Builder(Context context) { 279 if (context == null) { 280 throw new NullPointerException("context == null"); 281 } 282 283 // Context is currently not used, but will be in the future. 284 } 285 286 /** 287 * Indicates that this key must be encrypted at rest on storage. Note 288 * that enabling this will require that the user enable a strong lock 289 * screen (e.g., PIN, password) before creating or using the generated 290 * key is successful. 291 */ 292 public Builder setEncryptionRequired(boolean required) { 293 if (required) { 294 mFlags |= KeyStore.FLAG_ENCRYPTED; 295 } else { 296 mFlags &= ~KeyStore.FLAG_ENCRYPTED; 297 } 298 return this; 299 } 300 301 /** 302 * Sets the time instant before which the key is not yet valid. 303 * 304 * <p>By default, the key is valid at any instant. 305 * 306 * @see #setKeyValidityEnd(Date) 307 * 308 * @hide 309 */ 310 public Builder setKeyValidityStart(Date startDate) { 311 mKeyValidityStart = startDate; 312 return this; 313 } 314 315 /** 316 * Sets the time instant after which the key is no longer valid. 317 * 318 * <p>By default, the key is valid at any instant. 319 * 320 * @see #setKeyValidityStart(Date) 321 * @see #setKeyValidityForConsumptionEnd(Date) 322 * @see #setKeyValidityForOriginationEnd(Date) 323 * 324 * @hide 325 */ 326 public Builder setKeyValidityEnd(Date endDate) { 327 setKeyValidityForOriginationEnd(endDate); 328 setKeyValidityForConsumptionEnd(endDate); 329 return this; 330 } 331 332 /** 333 * Sets the time instant after which the key is no longer valid for encryption and signing. 334 * 335 * <p>By default, the key is valid at any instant. 336 * 337 * @see #setKeyValidityForConsumptionEnd(Date) 338 * 339 * @hide 340 */ 341 public Builder setKeyValidityForOriginationEnd(Date endDate) { 342 mKeyValidityForOriginationEnd = endDate; 343 return this; 344 } 345 346 /** 347 * Sets the time instant after which the key is no longer valid for decryption and 348 * verification. 349 * 350 * <p>By default, the key is valid at any instant. 351 * 352 * @see #setKeyValidityForOriginationEnd(Date) 353 * 354 * @hide 355 */ 356 public Builder setKeyValidityForConsumptionEnd(Date endDate) { 357 mKeyValidityForConsumptionEnd = endDate; 358 return this; 359 } 360 361 /** 362 * Sets the set of purposes for which the key can be used. 363 * 364 * <p>This must be specified for all keys. There is no default. 365 * 366 * @hide 367 */ 368 public Builder setPurposes(@KeyStoreKeyProperties.PurposeEnum int purposes) { 369 mPurposes = purposes; 370 return this; 371 } 372 373 /** 374 * Sets the set of padding schemes with which the key can be used when 375 * encrypting/decrypting. Attempts to use the key with any other padding scheme will be 376 * rejected. 377 * 378 * <p>This must be specified for keys which are used for encryption/decryption. 379 * 380 * @hide 381 */ 382 public Builder setEncryptionPaddings(String... paddings) { 383 mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings); 384 return this; 385 } 386 387 /** 388 * Sets the set of padding schemes with which the key can be used when 389 * signing/verifying. Attempts to use the key with any other padding scheme will be 390 * rejected. 391 * 392 * <p>This must be specified for RSA keys which are used for signing/verification. 393 * 394 * @hide 395 */ 396 public Builder setSignaturePaddings(String... paddings) { 397 mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings); 398 return this; 399 } 400 401 402 /** 403 * Sets the set of digests with which the key can be used when signing/verifying or 404 * generating MACs. Attempts to use the key with any other digest will be rejected. 405 * 406 * <p>For HMAC keys, the default is the digest specified in {@link Key#getAlgorithm()}. For 407 * asymmetric signing keys this constraint must be specified. 408 * 409 * @hide 410 */ 411 public Builder setDigests(String... digests) { 412 mDigests = ArrayUtils.cloneIfNotEmpty(digests); 413 return this; 414 } 415 416 /** 417 * Sets the set of block modes with which the key can be used when encrypting/decrypting. 418 * Attempts to use the key with any other block modes will be rejected. 419 * 420 * <p>This must be specified for encryption/decryption keys. 421 * 422 * @hide 423 */ 424 public Builder setBlockModes(String... blockModes) { 425 mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes); 426 return this; 427 } 428 429 /** 430 * Sets whether encryption using this key must be sufficiently randomized to produce 431 * different ciphertexts for the same plaintext every time. The formal cryptographic 432 * property being required is <em>indistinguishability under chosen-plaintext attack 433 * ({@code IND-CPA})</em>. This property is important because it mitigates several classes 434 * of weaknesses due to which ciphertext may leak information about plaintext. For example, 435 * if a given plaintext always produces the same ciphertext, an attacker may see the 436 * repeated ciphertexts and be able to deduce something about the plaintext. 437 * 438 * <p>By default, {@code IND-CPA} is required. 439 * 440 * <p>When {@code IND-CPA} is required: 441 * <ul> 442 * <li>transformation which do not offer {@code IND-CPA}, such as symmetric ciphers using 443 * {@code ECB} mode or RSA encryption without padding, are prohibited;</li> 444 * <li>in transformations which use an IV, such as symmetric ciphers in {@code CBC}, 445 * {@code CTR}, and {@code GCM} block modes, caller-provided IVs are rejected when 446 * encrypting, to ensure that only random IVs are used.</li> 447 * 448 * <p>Before disabling this requirement, consider the following approaches instead: 449 * <ul> 450 * <li>If you are generating a random IV for encryption and then initializing a {@code} 451 * Cipher using the IV, the solution is to let the {@code Cipher} generate a random IV 452 * instead. This will occur if the {@code Cipher} is initialized for encryption without an 453 * IV. The IV can then be queried via {@link Cipher#getIV()}.</li> 454 * <li>If you are generating a non-random IV (e.g., an IV derived from something not fully 455 * random, such as the name of the file being encrypted, or transaction ID, or password, 456 * or a device identifier), consider changing your design to use a random IV which will then 457 * be provided in addition to the ciphertext to the entities which need to decrypt the 458 * ciphertext.</li> 459 * <li>If you are using RSA encryption without padding, consider switching to padding 460 * schemes which offer {@code IND-CPA}, such as PKCS#1 or OAEP.</li> 461 * </ul> 462 * 463 * @hide 464 */ 465 public Builder setRandomizedEncryptionRequired(boolean required) { 466 mRandomizedEncryptionRequired = required; 467 return this; 468 } 469 470 /** 471 * Sets the user authenticators which protect access to this key. The key can only be used 472 * iff the user has authenticated to at least one of these user authenticators. 473 * 474 * <p>By default, the key can be used without user authentication. 475 * 476 * @param userAuthenticators user authenticators or {@code 0} if this key can be accessed 477 * without user authentication. 478 * 479 * @see #setUserAuthenticationValidityDurationSeconds(int) 480 * 481 * @hide 482 */ 483 public Builder setUserAuthenticators( 484 @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators) { 485 mUserAuthenticators = userAuthenticators; 486 return this; 487 } 488 489 /** 490 * Sets the duration of time (seconds) for which this key can be used after the user 491 * successfully authenticates to one of the associated user authenticators. 492 * 493 * <p>By default, the user needs to authenticate for every use of the key. 494 * 495 * @param seconds duration in seconds or {@code 0} if the user needs to authenticate for 496 * every use of the key. 497 * 498 * @see #setUserAuthenticators(int) 499 * 500 * @hide 501 */ 502 public Builder setUserAuthenticationValidityDurationSeconds(int seconds) { 503 mUserAuthenticationValidityDurationSeconds = seconds; 504 return this; 505 } 506 507 /** 508 * Builds the instance of the {@code KeyStoreParameter}. 509 * 510 * @throws IllegalArgumentException if a required field is missing 511 * @return built instance of {@code KeyStoreParameter} 512 */ 513 public KeyStoreParameter build() { 514 return new KeyStoreParameter(mFlags, 515 mKeyValidityStart, 516 mKeyValidityForOriginationEnd, 517 mKeyValidityForConsumptionEnd, 518 mPurposes, 519 mEncryptionPaddings, 520 mSignaturePaddings, 521 mDigests, 522 mBlockModes, 523 mRandomizedEncryptionRequired, 524 mUserAuthenticators, 525 mUserAuthenticationValidityDurationSeconds); 526 } 527 } 528} 529