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 * }}</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 */
66public 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     */
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     */
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     */
145    public boolean isInsideSecureHardware() {
146        return mInsideSecureHardware;
147    }
148
149    /**
150     * Gets the origin of the key. See {@link KeyProperties}.{@code ORIGIN} constants.
151     */
152    public @KeyProperties.OriginEnum int getOrigin() {
153        return mOrigin;
154    }
155
156    /**
157     * Gets the size of the key in bits.
158     */
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
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
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
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     */
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
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
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
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
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     */
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     */
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     */
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     */
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     */
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     */
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     */
336    public boolean isTrustedUserPresenceRequired() {
337        return mTrustedUserPresenceRequired;
338    }
339}
340