1/*
2 * Copyright (C) 2012 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.app.KeyguardManager;
20import android.annotation.NonNull;
21import android.annotation.Nullable;
22import android.content.Context;
23import android.security.keystore.KeyGenParameterSpec;
24import android.security.keystore.KeyProperties;
25import android.text.TextUtils;
26
27import java.math.BigInteger;
28import java.security.NoSuchAlgorithmException;
29import java.security.PrivateKey;
30import java.security.cert.Certificate;
31import java.security.spec.AlgorithmParameterSpec;
32import java.util.Date;
33
34import javax.security.auth.x500.X500Principal;
35
36/**
37 * This provides the required parameters needed for initializing the
38 * {@code KeyPairGenerator} that works with
39 * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore
40 * facility</a>. The Android KeyStore facility is accessed through a
41 * {@link java.security.KeyPairGenerator} API using the {@code AndroidKeyStore}
42 * provider. The {@code context} passed in may be used to pop up some UI to ask
43 * the user to unlock or initialize the Android KeyStore facility.
44 * <p>
45 * After generation, the {@code keyStoreAlias} is used with the
46 * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)}
47 * interface to retrieve the {@link PrivateKey} and its associated
48 * {@link Certificate} chain.
49 * <p>
50 * The KeyPair generator will create a self-signed certificate with the subject
51 * as its X.509v3 Subject Distinguished Name and as its X.509v3 Issuer
52 * Distinguished Name along with the other parameters specified with the
53 * {@link Builder}.
54 * <p>
55 * The self-signed X.509 certificate may be replaced at a later time by a
56 * certificate signed by a real Certificate Authority.
57 *
58 * @deprecated Use {@link KeyGenParameterSpec} instead.
59 */
60@Deprecated
61public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
62
63    private final Context mContext;
64
65    private final String mKeystoreAlias;
66
67    private final String mKeyType;
68
69    private final int mKeySize;
70
71    private final AlgorithmParameterSpec mSpec;
72
73    private final X500Principal mSubjectDN;
74
75    private final BigInteger mSerialNumber;
76
77    private final Date mStartDate;
78
79    private final Date mEndDate;
80
81    private final int mFlags;
82
83    /**
84     * Parameter specification for the "{@code AndroidKeyPairGenerator}"
85     * instance of the {@link java.security.KeyPairGenerator} API. The
86     * {@code context} passed in may be used to pop up some UI to ask the user
87     * to unlock or initialize the Android keystore facility.
88     * <p>
89     * After generation, the {@code keyStoreAlias} is used with the
90     * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)}
91     * interface to retrieve the {@link PrivateKey} and its associated
92     * {@link Certificate} chain.
93     * <p>
94     * The KeyPair generator will create a self-signed certificate with the
95     * properties of {@code subjectDN} as its X.509v3 Subject Distinguished Name
96     * and as its X.509v3 Issuer Distinguished Name, using the specified
97     * {@code serialNumber}, and the validity date starting at {@code startDate}
98     * and ending at {@code endDate}.
99     *
100     * @param context Android context for the activity
101     * @param keyStoreAlias name to use for the generated key in the Android
102     *            keystore
103     * @param keyType key algorithm to use (RSA, DSA, EC)
104     * @param keySize size of key to generate
105     * @param spec the underlying key type parameters
106     * @param subjectDN X.509 v3 Subject Distinguished Name
107     * @param serialNumber X509 v3 certificate serial number
108     * @param startDate the start of the self-signed certificate validity period
109     * @param endDate the end date of the self-signed certificate validity
110     *            period
111     * @throws IllegalArgumentException when any argument is {@code null} or
112     *             {@code endDate} is before {@code startDate}.
113     * @hide should be built with KeyPairGeneratorSpecBuilder
114     */
115    public KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize,
116            AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber,
117            Date startDate, Date endDate, int flags) {
118        if (context == null) {
119            throw new IllegalArgumentException("context == null");
120        } else if (TextUtils.isEmpty(keyStoreAlias)) {
121            throw new IllegalArgumentException("keyStoreAlias must not be empty");
122        } else if (subjectDN == null) {
123            throw new IllegalArgumentException("subjectDN == null");
124        } else if (serialNumber == null) {
125            throw new IllegalArgumentException("serialNumber == null");
126        } else if (startDate == null) {
127            throw new IllegalArgumentException("startDate == null");
128        } else if (endDate == null) {
129            throw new IllegalArgumentException("endDate == null");
130        } else if (endDate.before(startDate)) {
131            throw new IllegalArgumentException("endDate < startDate");
132        }
133
134        if (endDate.before(startDate)) {
135            throw new IllegalArgumentException("endDate < startDate");
136        }
137
138        mContext = context;
139        mKeystoreAlias = keyStoreAlias;
140        mKeyType = keyType;
141        mKeySize = keySize;
142        mSpec = spec;
143        mSubjectDN = subjectDN;
144        mSerialNumber = serialNumber;
145        mStartDate = startDate;
146        mEndDate = endDate;
147        mFlags = flags;
148    }
149
150    /**
151     * Gets the Android context used for operations with this instance.
152     */
153    public Context getContext() {
154        return mContext;
155    }
156
157    /**
158     * Returns the alias that will be used in the {@code java.security.KeyStore}
159     * in conjunction with the {@code AndroidKeyStore}.
160     */
161    public String getKeystoreAlias() {
162        return mKeystoreAlias;
163    }
164
165    /**
166     * Returns the type of key pair (e.g., {@code EC}, {@code RSA}) to be generated. See
167     * {@link KeyProperties}.{@code KEY_ALGORITHM} constants.
168     */
169    @Nullable
170    public @KeyProperties.KeyAlgorithmEnum String getKeyType() {
171        return mKeyType;
172    }
173
174    /**
175     * Returns the key size specified by this parameter. For instance, for RSA
176     * this will return the modulus size and for EC it will return the field
177     * size.
178     */
179    public int getKeySize() {
180        return mKeySize;
181    }
182
183    /**
184     * Returns the {@link AlgorithmParameterSpec} that will be used for creation
185     * of the key pair.
186     */
187    @NonNull
188    public AlgorithmParameterSpec getAlgorithmParameterSpec() {
189        return mSpec;
190    }
191
192    /**
193     * Gets the subject distinguished name to be used on the X.509 certificate
194     * that will be put in the {@link java.security.KeyStore}.
195     */
196    @NonNull
197    public X500Principal getSubjectDN() {
198        return mSubjectDN;
199    }
200
201    /**
202     * Gets the serial number to be used on the X.509 certificate that will be
203     * put in the {@link java.security.KeyStore}.
204     */
205    @NonNull
206    public BigInteger getSerialNumber() {
207        return mSerialNumber;
208    }
209
210    /**
211     * Gets the start date to be used on the X.509 certificate that will be put
212     * in the {@link java.security.KeyStore}.
213     */
214    @NonNull
215    public Date getStartDate() {
216        return mStartDate;
217    }
218
219    /**
220     * Gets the end date to be used on the X.509 certificate that will be put in
221     * the {@link java.security.KeyStore}.
222     */
223    @NonNull
224    public Date getEndDate() {
225        return mEndDate;
226    }
227
228    /**
229     * @hide
230     */
231    public int getFlags() {
232        return mFlags;
233    }
234
235    /**
236     * Returns {@code true} if the key must be encrypted at rest. This will protect the key pair
237     * with the secure lock screen credential (e.g., password, PIN, or pattern).
238     *
239     * <p>Note that encrypting the key at rest requires that the secure lock screen (e.g., password,
240     * PIN, pattern) is set up, otherwise key generation will fail. Moreover, this key will be
241     * deleted when the secure lock screen is disabled or reset (e.g., by the user or a Device
242     * Administrator). Finally, this key cannot be used until the user unlocks the secure lock
243     * screen after boot.
244     *
245     * @see KeyguardManager#isDeviceSecure()
246     */
247    public boolean isEncryptionRequired() {
248        return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0;
249    }
250
251    /**
252     * Builder class for {@link KeyPairGeneratorSpec} objects.
253     * <p>
254     * This will build a parameter spec for use with the
255     * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore
256     * facility</a>.
257     * <p>
258     * The required fields must be filled in with the builder.
259     * <p>
260     * Example:
261     *
262     * <pre class="prettyprint">
263     * Calendar start = new Calendar();
264     * Calendar end = new Calendar();
265     * end.add(1, Calendar.YEAR);
266     *
267     * KeyPairGeneratorSpec spec =
268     *         new KeyPairGeneratorSpec.Builder(mContext).setAlias(&quot;myKey&quot;)
269     *                 .setSubject(new X500Principal(&quot;CN=myKey&quot;)).setSerial(BigInteger.valueOf(1337))
270     *                 .setStartDate(start.getTime()).setEndDate(end.getTime()).build();
271     * </pre>
272     *
273     *  @deprecated Use {@link KeyGenParameterSpec.Builder} instead.
274     */
275    @Deprecated
276    public final static class Builder {
277        private final Context mContext;
278
279        private String mKeystoreAlias;
280
281        private String mKeyType;
282
283        private int mKeySize = -1;
284
285        private AlgorithmParameterSpec mSpec;
286
287        private X500Principal mSubjectDN;
288
289        private BigInteger mSerialNumber;
290
291        private Date mStartDate;
292
293        private Date mEndDate;
294
295        private int mFlags;
296
297        /**
298         * Creates a new instance of the {@code Builder} with the given
299         * {@code context}. The {@code context} passed in may be used to pop up
300         * some UI to ask the user to unlock or initialize the Android KeyStore
301         * facility.
302         */
303        public Builder(@NonNull Context context) {
304            if (context == null) {
305                throw new NullPointerException("context == null");
306            }
307            mContext = context;
308        }
309
310        /**
311         * Sets the alias to be used to retrieve the key later from a
312         * {@link java.security.KeyStore} instance using the
313         * {@code AndroidKeyStore} provider.
314         */
315        @NonNull
316        public Builder setAlias(@NonNull String alias) {
317            if (alias == null) {
318                throw new NullPointerException("alias == null");
319            }
320            mKeystoreAlias = alias;
321            return this;
322        }
323
324        /**
325         * Sets the type of key pair (e.g., {@code EC}, {@code RSA}) of the key pair to be
326         * generated. See {@link KeyProperties}.{@code KEY_ALGORITHM} constants.
327         *
328         */
329        @NonNull
330        public Builder setKeyType(@NonNull @KeyProperties.KeyAlgorithmEnum String keyType)
331                throws NoSuchAlgorithmException {
332            if (keyType == null) {
333                throw new NullPointerException("keyType == null");
334            } else {
335                try {
336                    KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(keyType);
337                } catch (IllegalArgumentException e) {
338                    throw new NoSuchAlgorithmException("Unsupported key type: " + keyType);
339                }
340            }
341            mKeyType = keyType;
342            return this;
343        }
344
345        /**
346         * Sets the key size for the keypair to be created. For instance, for a
347         * key type of RSA this will set the modulus size and for a key type of
348         * EC it will select a curve with a matching field size.
349         */
350        @NonNull
351        public Builder setKeySize(int keySize) {
352            if (keySize < 0) {
353                throw new IllegalArgumentException("keySize < 0");
354            }
355            mKeySize = keySize;
356            return this;
357        }
358
359        /**
360         * Sets the algorithm-specific key generation parameters. For example, for RSA keys
361         * this may be an instance of {@link java.security.spec.RSAKeyGenParameterSpec}.
362         */
363        public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) {
364            if (spec == null) {
365                throw new NullPointerException("spec == null");
366            }
367            mSpec = spec;
368            return this;
369        }
370
371        /**
372         * Sets the subject used for the self-signed certificate of the
373         * generated key pair.
374         */
375        @NonNull
376        public Builder setSubject(@NonNull X500Principal subject) {
377            if (subject == null) {
378                throw new NullPointerException("subject == null");
379            }
380            mSubjectDN = subject;
381            return this;
382        }
383
384        /**
385         * Sets the serial number used for the self-signed certificate of the
386         * generated key pair.
387         */
388        @NonNull
389        public Builder setSerialNumber(@NonNull BigInteger serialNumber) {
390            if (serialNumber == null) {
391                throw new NullPointerException("serialNumber == null");
392            }
393            mSerialNumber = serialNumber;
394            return this;
395        }
396
397        /**
398         * Sets the start of the validity period for the self-signed certificate
399         * of the generated key pair.
400         */
401        @NonNull
402        public Builder setStartDate(@NonNull Date startDate) {
403            if (startDate == null) {
404                throw new NullPointerException("startDate == null");
405            }
406            mStartDate = startDate;
407            return this;
408        }
409
410        /**
411         * Sets the end of the validity period for the self-signed certificate
412         * of the generated key pair.
413         */
414        @NonNull
415        public Builder setEndDate(@NonNull Date endDate) {
416            if (endDate == null) {
417                throw new NullPointerException("endDate == null");
418            }
419            mEndDate = endDate;
420            return this;
421        }
422
423        /**
424         * Indicates that this key pair must be encrypted at rest. This will protect the key pair
425         * with the secure lock screen credential (e.g., password, PIN, or pattern).
426         *
427         * <p>Note that this feature requires that the secure lock screen (e.g., password, PIN,
428         * pattern) is set up, otherwise key pair generation will fail. Moreover, this key pair will
429         * be deleted when the secure lock screen is disabled or reset (e.g., by the user or a
430         * Device Administrator). Finally, this key pair cannot be used until the user unlocks the
431         * secure lock screen after boot.
432         *
433         * @see KeyguardManager#isDeviceSecure()
434         */
435        @NonNull
436        public Builder setEncryptionRequired() {
437            mFlags |= KeyStore.FLAG_ENCRYPTED;
438            return this;
439        }
440
441        /**
442         * Builds the instance of the {@code KeyPairGeneratorSpec}.
443         *
444         * @throws IllegalArgumentException if a required field is missing
445         * @return built instance of {@code KeyPairGeneratorSpec}
446         */
447        @NonNull
448        public KeyPairGeneratorSpec build() {
449            return new KeyPairGeneratorSpec(mContext,
450                    mKeystoreAlias,
451                    mKeyType,
452                    mKeySize,
453                    mSpec,
454                    mSubjectDN,
455                    mSerialNumber,
456                    mStartDate,
457                    mEndDate,
458                    mFlags);
459        }
460    }
461}
462