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