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.KeyPairGenerator;
22import java.security.KeyStore.ProtectionParameter;
23
24/**
25 * This provides the optional parameters that can be specified for
26 * {@code KeyStore} entries that work with
27 * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore
28 * facility</a>. The Android KeyStore facility is accessed through a
29 * {@link java.security.KeyStore} API using the {@code AndroidKeyStore}
30 * provider. The {@code context} passed in may be used to pop up some UI to ask
31 * the user to unlock or initialize the Android KeyStore facility.
32 * <p>
33 * Any entries placed in the {@code KeyStore} may be retrieved later. Note that
34 * there is only one logical instance of the {@code KeyStore} per application
35 * UID so apps using the {@code sharedUid} facility will also share a
36 * {@code KeyStore}.
37 * <p>
38 * Keys may be generated using the {@link KeyPairGenerator} facility with a
39 * {@link KeyPairGeneratorSpec} to specify the entry's {@code alias}. A
40 * self-signed X.509 certificate will be attached to generated entries, but that
41 * may be replaced at a later time by a certificate signed by a real Certificate
42 * Authority.
43 */
44public final class KeyStoreParameter implements ProtectionParameter {
45    private int mFlags;
46
47    private KeyStoreParameter(int flags) {
48        mFlags = flags;
49    }
50
51    /**
52     * @hide
53     */
54    public int getFlags() {
55        return mFlags;
56    }
57
58    /**
59     * Returns {@code true} if this parameter requires entries to be encrypted
60     * on the disk.
61     */
62    public boolean isEncryptionRequired() {
63        return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0;
64    }
65
66    /**
67     * Builder class for {@link KeyStoreParameter} objects.
68     * <p>
69     * This will build protection parameters for use with the
70     * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore
71     * facility</a>.
72     * <p>
73     * This can be used to require that KeyStore entries be stored encrypted.
74     * <p>
75     * Example:
76     *
77     * <pre class="prettyprint">
78     * KeyStoreParameter params = new KeyStoreParameter.Builder(mContext)
79     *         .setEncryptionRequired()
80     *         .build();
81     * </pre>
82     */
83    public final static class Builder {
84        private int mFlags;
85
86        /**
87         * Creates a new instance of the {@code Builder} with the given
88         * {@code context}. The {@code context} passed in may be used to pop up
89         * some UI to ask the user to unlock or initialize the Android KeyStore
90         * facility.
91         */
92        public Builder(Context context) {
93            if (context == null) {
94                throw new NullPointerException("context == null");
95            }
96
97            // Context is currently not used, but will be in the future.
98        }
99
100        /**
101         * Indicates that this key must be encrypted at rest on storage. Note
102         * that enabling this will require that the user enable a strong lock
103         * screen (e.g., PIN, password) before creating or using the generated
104         * key is successful.
105         */
106        public Builder setEncryptionRequired(boolean required) {
107            if (required) {
108                mFlags |= KeyStore.FLAG_ENCRYPTED;
109            } else {
110                mFlags &= ~KeyStore.FLAG_ENCRYPTED;
111            }
112            return this;
113        }
114
115        /**
116         * Builds the instance of the {@code KeyPairGeneratorSpec}.
117         *
118         * @throws IllegalArgumentException if a required field is missing
119         * @return built instance of {@code KeyPairGeneratorSpec}
120         */
121        public KeyStoreParameter build() {
122            return new KeyStoreParameter(mFlags);
123        }
124    }
125}
126