1 /* 2 * Copyright (C) 2015 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.keystore; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 22 import java.security.PrivateKey; 23 import java.security.spec.KeySpec; 24 import java.util.Date; 25 26 import javax.crypto.SecretKey; 27 28 /** 29 * Information about a key from the <a href="{@docRoot}training/articles/keystore.html">Android 30 * Keystore system</a>. This class describes whether the key material is available in 31 * plaintext outside of secure hardware, whether user authentication is required for using the key 32 * and whether this requirement is enforced by secure hardware, the key's origin, what uses the key 33 * is authorized for (e.g., only in {@code GCM} mode, or signing only), whether the key should be 34 * encrypted at rest, the key's and validity start and end dates. 35 * 36 * <p>Instances of this class are immutable. 37 * 38 * <p><h3>Example: Symmetric Key</h3> 39 * The following example illustrates how to obtain a {@code KeyInfo} describing the provided Android 40 * Keystore {@link SecretKey}. 41 * <pre>{@code 42 * SecretKey key = ...; // Android Keystore key 43 * 44 * SecretKeyFactory factory = SecretKeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore"); 45 * KeyInfo keyInfo; 46 * try { 47 * keyInfo = (KeyInfo) factory.getKeySpec(key, KeyInfo.class); 48 * } catch (InvalidKeySpecException e) { 49 * // Not an Android KeyStore key. 50 * }}</pre> 51 * 52 * <p><h3>Example: Private Key</h3> 53 * The following example illustrates how to obtain a {@code KeyInfo} describing the provided 54 * Android KeyStore {@link PrivateKey}. 55 * <pre>{@code 56 * PrivateKey key = ...; // Android KeyStore key 57 * 58 * KeyFactory factory = KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore"); 59 * KeyInfo keyInfo; 60 * try { 61 * keyInfo = factory.getKeySpec(key, KeyInfo.class); 62 * } catch (InvalidKeySpecException e) { 63 * // Not an Android KeyStore key. 64 * }}</pre> 65 */ 66 public class KeyInfo implements KeySpec { 67 private final String mKeystoreAlias; 68 private final int mKeySize; 69 private final boolean mInsideSecureHardware; 70 private final @KeyProperties.OriginEnum int mOrigin; 71 private final Date mKeyValidityStart; 72 private final Date mKeyValidityForOriginationEnd; 73 private final Date mKeyValidityForConsumptionEnd; 74 private final @KeyProperties.PurposeEnum int mPurposes; 75 private final @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; 76 private final @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; 77 private final @KeyProperties.DigestEnum String[] mDigests; 78 private final @KeyProperties.BlockModeEnum String[] mBlockModes; 79 private final boolean mUserAuthenticationRequired; 80 private final int mUserAuthenticationValidityDurationSeconds; 81 private final boolean mUserAuthenticationRequirementEnforcedBySecureHardware; 82 private final boolean mUserAuthenticationValidWhileOnBody; 83 private final boolean mTrustedUserPresenceRequired; 84 private final boolean mInvalidatedByBiometricEnrollment; 85 private final boolean mUserConfirmationRequired; 86 87 /** 88 * @hide 89 */ KeyInfo(String keystoreKeyAlias, boolean insideSecureHardware, @KeyProperties.OriginEnum int origin, int keySize, Date keyValidityStart, Date keyValidityForOriginationEnd, Date keyValidityForConsumptionEnd, @KeyProperties.PurposeEnum int purposes, @KeyProperties.EncryptionPaddingEnum String[] encryptionPaddings, @KeyProperties.SignaturePaddingEnum String[] signaturePaddings, @KeyProperties.DigestEnum String[] digests, @KeyProperties.BlockModeEnum String[] blockModes, boolean userAuthenticationRequired, int userAuthenticationValidityDurationSeconds, boolean userAuthenticationRequirementEnforcedBySecureHardware, boolean userAuthenticationValidWhileOnBody, boolean trustedUserPresenceRequired, boolean invalidatedByBiometricEnrollment, boolean userConfirmationRequired)90 public KeyInfo(String keystoreKeyAlias, 91 boolean insideSecureHardware, 92 @KeyProperties.OriginEnum int origin, 93 int keySize, 94 Date keyValidityStart, 95 Date keyValidityForOriginationEnd, 96 Date keyValidityForConsumptionEnd, 97 @KeyProperties.PurposeEnum int purposes, 98 @KeyProperties.EncryptionPaddingEnum String[] encryptionPaddings, 99 @KeyProperties.SignaturePaddingEnum String[] signaturePaddings, 100 @KeyProperties.DigestEnum String[] digests, 101 @KeyProperties.BlockModeEnum String[] blockModes, 102 boolean userAuthenticationRequired, 103 int userAuthenticationValidityDurationSeconds, 104 boolean userAuthenticationRequirementEnforcedBySecureHardware, 105 boolean userAuthenticationValidWhileOnBody, 106 boolean trustedUserPresenceRequired, 107 boolean invalidatedByBiometricEnrollment, 108 boolean userConfirmationRequired) { 109 mKeystoreAlias = keystoreKeyAlias; 110 mInsideSecureHardware = insideSecureHardware; 111 mOrigin = origin; 112 mKeySize = keySize; 113 mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart); 114 mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd); 115 mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd); 116 mPurposes = purposes; 117 mEncryptionPaddings = 118 ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings)); 119 mSignaturePaddings = 120 ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings)); 121 mDigests = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(digests)); 122 mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes)); 123 mUserAuthenticationRequired = userAuthenticationRequired; 124 mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds; 125 mUserAuthenticationRequirementEnforcedBySecureHardware = 126 userAuthenticationRequirementEnforcedBySecureHardware; 127 mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody; 128 mTrustedUserPresenceRequired = trustedUserPresenceRequired; 129 mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment; 130 mUserConfirmationRequired = userConfirmationRequired; 131 } 132 133 /** 134 * Gets the entry alias under which the key is stored in the {@code AndroidKeyStore}. 135 */ getKeystoreAlias()136 public String getKeystoreAlias() { 137 return mKeystoreAlias; 138 } 139 140 /** 141 * Returns {@code true} if the key resides inside secure hardware (e.g., Trusted Execution 142 * Environment (TEE) or Secure Element (SE)). Key material of such keys is available in 143 * plaintext only inside the secure hardware and is not exposed outside of it. 144 */ isInsideSecureHardware()145 public boolean isInsideSecureHardware() { 146 return mInsideSecureHardware; 147 } 148 149 /** 150 * Gets the origin of the key. See {@link KeyProperties}.{@code ORIGIN} constants. 151 */ getOrigin()152 public @KeyProperties.OriginEnum int getOrigin() { 153 return mOrigin; 154 } 155 156 /** 157 * Gets the size of the key in bits. 158 */ getKeySize()159 public int getKeySize() { 160 return mKeySize; 161 } 162 163 /** 164 * Gets the time instant before which the key is not yet valid. 165 * 166 * @return instant or {@code null} if not restricted. 167 */ 168 @Nullable getKeyValidityStart()169 public Date getKeyValidityStart() { 170 return Utils.cloneIfNotNull(mKeyValidityStart); 171 } 172 173 /** 174 * Gets the time instant after which the key is no long valid for decryption and verification. 175 * 176 * @return instant or {@code null} if not restricted. 177 */ 178 @Nullable getKeyValidityForConsumptionEnd()179 public Date getKeyValidityForConsumptionEnd() { 180 return Utils.cloneIfNotNull(mKeyValidityForConsumptionEnd); 181 } 182 183 /** 184 * Gets the time instant after which the key is no long valid for encryption and signing. 185 * 186 * @return instant or {@code null} if not restricted. 187 */ 188 @Nullable getKeyValidityForOriginationEnd()189 public Date getKeyValidityForOriginationEnd() { 190 return Utils.cloneIfNotNull(mKeyValidityForOriginationEnd); 191 } 192 193 /** 194 * Gets the set of purposes (e.g., encrypt, decrypt, sign) for which the key can be used. 195 * Attempts to use the key for any other purpose will be rejected. 196 * 197 * <p>See {@link KeyProperties}.{@code PURPOSE} flags. 198 */ getPurposes()199 public @KeyProperties.PurposeEnum int getPurposes() { 200 return mPurposes; 201 } 202 203 /** 204 * Gets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be used 205 * when encrypting/decrypting. Attempts to use the key with any other block modes will be 206 * rejected. 207 * 208 * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants. 209 */ 210 @NonNull getBlockModes()211 public @KeyProperties.BlockModeEnum String[] getBlockModes() { 212 return ArrayUtils.cloneIfNotEmpty(mBlockModes); 213 } 214 215 /** 216 * Gets the set of padding schemes (e.g., {@code PKCS7Padding}, {@code PKCS1Padding}, 217 * {@code NoPadding}) with which the key can be used when encrypting/decrypting. Attempts to use 218 * the key with any other padding scheme will be rejected. 219 * 220 * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants. 221 */ 222 @NonNull getEncryptionPaddings()223 public @KeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() { 224 return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings); 225 } 226 227 /** 228 * Gets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key 229 * can be used when signing/verifying. Attempts to use the key with any other padding scheme 230 * will be rejected. 231 * 232 * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants. 233 */ 234 @NonNull getSignaturePaddings()235 public @KeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() { 236 return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings); 237 } 238 239 /** 240 * Gets the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which the key 241 * can be used. 242 * 243 * <p>See {@link KeyProperties}.{@code DIGEST} constants. 244 */ 245 @NonNull getDigests()246 public @KeyProperties.DigestEnum String[] getDigests() { 247 return ArrayUtils.cloneIfNotEmpty(mDigests); 248 } 249 250 /** 251 * Returns {@code true} if the key is authorized to be used only if the user has been 252 * authenticated. 253 * 254 * <p>This authorization applies only to secret key and private key operations. Public key 255 * operations are not restricted. 256 * 257 * @see #getUserAuthenticationValidityDurationSeconds() 258 * @see KeyGenParameterSpec.Builder#setUserAuthenticationRequired(boolean) 259 * @see KeyProtection.Builder#setUserAuthenticationRequired(boolean) 260 */ isUserAuthenticationRequired()261 public boolean isUserAuthenticationRequired() { 262 return mUserAuthenticationRequired; 263 } 264 265 /** 266 * Returns {@code true} if the key is authorized to be used only for messages confirmed by the 267 * user. 268 * 269 * Confirmation is separate from user authentication (see 270 * {@link #isUserAuthenticationRequired()}). Keys can be created that require confirmation but 271 * not user authentication, or user authentication but not confirmation, or both. Confirmation 272 * verifies that some user with physical possession of the device has approved a displayed 273 * message. User authentication verifies that the correct user is present and has 274 * authenticated. 275 * 276 * <p>This authorization applies only to secret key and private key operations. Public key 277 * operations are not restricted. 278 * 279 * @see KeyGenParameterSpec.Builder#setUserConfirmationRequired(boolean) 280 * @see KeyProtection.Builder#setUserConfirmationRequired(boolean) 281 */ isUserConfirmationRequired()282 public boolean isUserConfirmationRequired() { 283 return mUserConfirmationRequired; 284 } 285 286 /** 287 * Gets the duration of time (seconds) for which this key is authorized to be used after the 288 * user is successfully authenticated. This has effect only if user authentication is required 289 * (see {@link #isUserAuthenticationRequired()}). 290 * 291 * <p>This authorization applies only to secret key and private key operations. Public key 292 * operations are not restricted. 293 * 294 * @return duration in seconds or {@code -1} if authentication is required for every use of the 295 * key. 296 * 297 * @see #isUserAuthenticationRequired() 298 */ getUserAuthenticationValidityDurationSeconds()299 public int getUserAuthenticationValidityDurationSeconds() { 300 return mUserAuthenticationValidityDurationSeconds; 301 } 302 303 /** 304 * Returns {@code true} if the requirement that this key can only be used if the user has been 305 * authenticated is enforced by secure hardware (e.g., Trusted Execution Environment (TEE) or 306 * Secure Element (SE)). 307 * 308 * @see #isUserAuthenticationRequired() 309 */ isUserAuthenticationRequirementEnforcedBySecureHardware()310 public boolean isUserAuthenticationRequirementEnforcedBySecureHardware() { 311 return mUserAuthenticationRequirementEnforcedBySecureHardware; 312 } 313 314 /** 315 * Returns {@code true} if this key will become unusable when the device is removed from the 316 * user's body. This is possible only for keys with a specified validity duration, and only on 317 * devices with an on-body sensor. Always returns {@code false} on devices that lack an on-body 318 * sensor. 319 */ isUserAuthenticationValidWhileOnBody()320 public boolean isUserAuthenticationValidWhileOnBody() { 321 return mUserAuthenticationValidWhileOnBody; 322 } 323 324 /** 325 * Returns {@code true} if the key will be invalidated by enrollment of a new fingerprint or 326 * removal of all fingerprints. 327 */ isInvalidatedByBiometricEnrollment()328 public boolean isInvalidatedByBiometricEnrollment() { 329 return mInvalidatedByBiometricEnrollment; 330 } 331 332 /** 333 * Returns {@code true} if the key can only be only be used if a test for user presence has 334 * succeeded since Signature.initSign() has been called. 335 */ isTrustedUserPresenceRequired()336 public boolean isTrustedUserPresenceRequired() { 337 return mTrustedUserPresenceRequired; 338 } 339 } 340