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