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 17package android.security.keystore; 18 19import android.annotation.NonNull; 20import android.annotation.Nullable; 21 22import java.security.PrivateKey; 23import java.security.spec.KeySpec; 24import java.util.Date; 25 26import 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 * } 51 * }</pre> 52 * 53 * <p><h3>Example: Private Key</h3> 54 * The following example illustrates how to obtain a {@code KeyInfo} describing the provided 55 * Android KeyStore {@link PrivateKey}. 56 * <pre> {@code 57 * PrivateKey key = ...; // Android KeyStore key 58 * 59 * KeyFactory factory = KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore"); 60 * KeyInfo keyInfo; 61 * try { 62 * keyInfo = factory.getKeySpec(key, KeyInfo.class); 63 * } catch (InvalidKeySpecException e) { 64 * // Not an Android KeyStore key. 65 * } 66 * }</pre> 67 */ 68public class KeyInfo implements KeySpec { 69 private final String mKeystoreAlias; 70 private final int mKeySize; 71 private final boolean mInsideSecureHardware; 72 private final @KeyProperties.OriginEnum int mOrigin; 73 private final Date mKeyValidityStart; 74 private final Date mKeyValidityForOriginationEnd; 75 private final Date mKeyValidityForConsumptionEnd; 76 private final @KeyProperties.PurposeEnum int mPurposes; 77 private final @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; 78 private final @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; 79 private final @KeyProperties.DigestEnum String[] mDigests; 80 private final @KeyProperties.BlockModeEnum String[] mBlockModes; 81 private final boolean mUserAuthenticationRequired; 82 private final int mUserAuthenticationValidityDurationSeconds; 83 private final boolean mUserAuthenticationRequirementEnforcedBySecureHardware; 84 85 /** 86 * @hide 87 */ 88 public KeyInfo(String keystoreKeyAlias, 89 boolean insideSecureHardware, 90 @KeyProperties.OriginEnum int origin, 91 int keySize, 92 Date keyValidityStart, 93 Date keyValidityForOriginationEnd, 94 Date keyValidityForConsumptionEnd, 95 @KeyProperties.PurposeEnum int purposes, 96 @KeyProperties.EncryptionPaddingEnum String[] encryptionPaddings, 97 @KeyProperties.SignaturePaddingEnum String[] signaturePaddings, 98 @KeyProperties.DigestEnum String[] digests, 99 @KeyProperties.BlockModeEnum String[] blockModes, 100 boolean userAuthenticationRequired, 101 int userAuthenticationValidityDurationSeconds, 102 boolean userAuthenticationRequirementEnforcedBySecureHardware) { 103 mKeystoreAlias = keystoreKeyAlias; 104 mInsideSecureHardware = insideSecureHardware; 105 mOrigin = origin; 106 mKeySize = keySize; 107 mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart); 108 mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd); 109 mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd); 110 mPurposes = purposes; 111 mEncryptionPaddings = 112 ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings)); 113 mSignaturePaddings = 114 ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings)); 115 mDigests = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(digests)); 116 mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes)); 117 mUserAuthenticationRequired = userAuthenticationRequired; 118 mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds; 119 mUserAuthenticationRequirementEnforcedBySecureHardware = 120 userAuthenticationRequirementEnforcedBySecureHardware; 121 } 122 123 /** 124 * Gets the entry alias under which the key is stored in the {@code AndroidKeyStore}. 125 */ 126 public String getKeystoreAlias() { 127 return mKeystoreAlias; 128 } 129 130 /** 131 * Returns {@code true} if the key resides inside secure hardware (e.g., Trusted Execution 132 * Environment (TEE) or Secure Element (SE)). Key material of such keys is available in 133 * plaintext only inside the secure hardware and is not exposed outside of it. 134 */ 135 public boolean isInsideSecureHardware() { 136 return mInsideSecureHardware; 137 } 138 139 /** 140 * Gets the origin of the key. See {@link KeyProperties}.{@code ORIGIN} constants. 141 */ 142 public @KeyProperties.OriginEnum int getOrigin() { 143 return mOrigin; 144 } 145 146 /** 147 * Gets the size of the key in bits. 148 */ 149 public int getKeySize() { 150 return mKeySize; 151 } 152 153 /** 154 * Gets the time instant before which the key is not yet valid. 155 * 156 * @return instant or {@code null} if not restricted. 157 */ 158 @Nullable 159 public Date getKeyValidityStart() { 160 return Utils.cloneIfNotNull(mKeyValidityStart); 161 } 162 163 /** 164 * Gets the time instant after which the key is no long valid for decryption and verification. 165 * 166 * @return instant or {@code null} if not restricted. 167 */ 168 @Nullable 169 public Date getKeyValidityForConsumptionEnd() { 170 return Utils.cloneIfNotNull(mKeyValidityForConsumptionEnd); 171 } 172 173 /** 174 * Gets the time instant after which the key is no long valid for encryption and signing. 175 * 176 * @return instant or {@code null} if not restricted. 177 */ 178 @Nullable 179 public Date getKeyValidityForOriginationEnd() { 180 return Utils.cloneIfNotNull(mKeyValidityForOriginationEnd); 181 } 182 183 /** 184 * Gets the set of purposes (e.g., encrypt, decrypt, sign) for which the key can be used. 185 * Attempts to use the key for any other purpose will be rejected. 186 * 187 * <p>See {@link KeyProperties}.{@code PURPOSE} flags. 188 */ 189 public @KeyProperties.PurposeEnum int getPurposes() { 190 return mPurposes; 191 } 192 193 /** 194 * Gets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be used 195 * when encrypting/decrypting. Attempts to use the key with any other block modes will be 196 * rejected. 197 * 198 * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants. 199 */ 200 @NonNull 201 public @KeyProperties.BlockModeEnum String[] getBlockModes() { 202 return ArrayUtils.cloneIfNotEmpty(mBlockModes); 203 } 204 205 /** 206 * Gets the set of padding schemes (e.g., {@code PKCS7Padding}, {@code PKCS1Padding}, 207 * {@code NoPadding}) with which the key can be used when encrypting/decrypting. Attempts to use 208 * the key with any other padding scheme will be rejected. 209 * 210 * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants. 211 */ 212 @NonNull 213 public @KeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() { 214 return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings); 215 } 216 217 /** 218 * Gets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key 219 * can be used when signing/verifying. Attempts to use the key with any other padding scheme 220 * will be rejected. 221 * 222 * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants. 223 */ 224 @NonNull 225 public @KeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() { 226 return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings); 227 } 228 229 /** 230 * Gets the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which the key 231 * can be used. 232 * 233 * <p>See {@link KeyProperties}.{@code DIGEST} constants. 234 */ 235 @NonNull 236 public @KeyProperties.DigestEnum String[] getDigests() { 237 return ArrayUtils.cloneIfNotEmpty(mDigests); 238 } 239 240 /** 241 * Returns {@code true} if the key is authorized to be used only if the user has been 242 * authenticated. 243 * 244 * <p>This authorization applies only to secret key and private key operations. Public key 245 * operations are not restricted. 246 * 247 * @see #getUserAuthenticationValidityDurationSeconds() 248 * @see KeyGenParameterSpec.Builder#setUserAuthenticationRequired(boolean) 249 * @see KeyProtection.Builder#setUserAuthenticationRequired(boolean) 250 */ 251 public boolean isUserAuthenticationRequired() { 252 return mUserAuthenticationRequired; 253 } 254 255 /** 256 * Gets the duration of time (seconds) for which this key is authorized to be used after the 257 * user is successfully authenticated. This has effect only if user authentication is required 258 * (see {@link #isUserAuthenticationRequired()}). 259 * 260 * <p>This authorization applies only to secret key and private key operations. Public key 261 * operations are not restricted. 262 * 263 * @return duration in seconds or {@code -1} if authentication is required for every use of the 264 * key. 265 * 266 * @see #isUserAuthenticationRequired() 267 */ 268 public int getUserAuthenticationValidityDurationSeconds() { 269 return mUserAuthenticationValidityDurationSeconds; 270 } 271 272 /** 273 * Returns {@code true} if the requirement that this key can only be used if the user has been 274 * authenticated if enforced by secure hardware (e.g., Trusted Execution Environment (TEE) or 275 * Secure Element (SE)). 276 * 277 * @see #isUserAuthenticationRequired() 278 */ 279 public boolean isUserAuthenticationRequirementEnforcedBySecureHardware() { 280 return mUserAuthenticationRequirementEnforcedBySecureHardware; 281 } 282} 283