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 <a href="{@docRoot}
255     * training/articles/keystore.html">Android KeyStore facility</a>.
256     * <p>
257     * The required fields must be filled in with the builder.
258     * <p>
259     * Example:
260     *
261     * <pre class="prettyprint">
262     * Calendar start = new Calendar();
263     * Calendar end = new Calendar();
264     * end.add(1, Calendar.YEAR);
265     *
266     * KeyPairGeneratorSpec spec =
267     *         new KeyPairGeneratorSpec.Builder(mContext).setAlias(&quot;myKey&quot;)
268     *                 .setSubject(new X500Principal(&quot;CN=myKey&quot;)).setSerial(BigInteger.valueOf(1337))
269     *                 .setStartDate(start.getTime()).setEndDate(end.getTime()).build();
270     * </pre>
271     *
272     *  @deprecated Use {@link KeyGenParameterSpec.Builder} instead.
273     */
274    @Deprecated
275    public final static class Builder {
276        private final Context mContext;
277
278        private String mKeystoreAlias;
279
280        private String mKeyType;
281
282        private int mKeySize = -1;
283
284        private AlgorithmParameterSpec mSpec;
285
286        private X500Principal mSubjectDN;
287
288        private BigInteger mSerialNumber;
289
290        private Date mStartDate;
291
292        private Date mEndDate;
293
294        private int mFlags;
295
296        /**
297         * Creates a new instance of the {@code Builder} with the given
298         * {@code context}. The {@code context} passed in may be used to pop up
299         * some UI to ask the user to unlock or initialize the Android KeyStore
300         * facility.
301         */
302        public Builder(@NonNull Context context) {
303            if (context == null) {
304                throw new NullPointerException("context == null");
305            }
306            mContext = context;
307        }
308
309        /**
310         * Sets the alias to be used to retrieve the key later from a
311         * {@link java.security.KeyStore} instance using the
312         * {@code AndroidKeyStore} provider.
313         */
314        @NonNull
315        public Builder setAlias(@NonNull String alias) {
316            if (alias == null) {
317                throw new NullPointerException("alias == null");
318            }
319            mKeystoreAlias = alias;
320            return this;
321        }
322
323        /**
324         * Sets the type of key pair (e.g., {@code EC}, {@code RSA}) of the key pair to be
325         * generated. See {@link KeyProperties}.{@code KEY_ALGORITHM} constants.
326         *
327         */
328        @NonNull
329        public Builder setKeyType(@NonNull @KeyProperties.KeyAlgorithmEnum String keyType)
330                throws NoSuchAlgorithmException {
331            if (keyType == null) {
332                throw new NullPointerException("keyType == null");
333            } else {
334                try {
335                    KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(keyType);
336                } catch (IllegalArgumentException e) {
337                    throw new NoSuchAlgorithmException("Unsupported key type: " + keyType);
338                }
339            }
340            mKeyType = keyType;
341            return this;
342        }
343
344        /**
345         * Sets the key size for the keypair to be created. For instance, for a
346         * key type of RSA this will set the modulus size and for a key type of
347         * EC it will select a curve with a matching field size.
348         */
349        @NonNull
350        public Builder setKeySize(int keySize) {
351            if (keySize < 0) {
352                throw new IllegalArgumentException("keySize < 0");
353            }
354            mKeySize = keySize;
355            return this;
356        }
357
358        /**
359         * Sets the algorithm-specific key generation parameters. For example, for RSA keys
360         * this may be an instance of {@link java.security.spec.RSAKeyGenParameterSpec}.
361         */
362        public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) {
363            if (spec == null) {
364                throw new NullPointerException("spec == null");
365            }
366            mSpec = spec;
367            return this;
368        }
369
370        /**
371         * Sets the subject used for the self-signed certificate of the
372         * generated key pair.
373         */
374        @NonNull
375        public Builder setSubject(@NonNull X500Principal subject) {
376            if (subject == null) {
377                throw new NullPointerException("subject == null");
378            }
379            mSubjectDN = subject;
380            return this;
381        }
382
383        /**
384         * Sets the serial number used for the self-signed certificate of the
385         * generated key pair.
386         */
387        @NonNull
388        public Builder setSerialNumber(@NonNull BigInteger serialNumber) {
389            if (serialNumber == null) {
390                throw new NullPointerException("serialNumber == null");
391            }
392            mSerialNumber = serialNumber;
393            return this;
394        }
395
396        /**
397         * Sets the start of the validity period for the self-signed certificate
398         * of the generated key pair.
399         */
400        @NonNull
401        public Builder setStartDate(@NonNull Date startDate) {
402            if (startDate == null) {
403                throw new NullPointerException("startDate == null");
404            }
405            mStartDate = startDate;
406            return this;
407        }
408
409        /**
410         * Sets the end of the validity period for the self-signed certificate
411         * of the generated key pair.
412         */
413        @NonNull
414        public Builder setEndDate(@NonNull Date endDate) {
415            if (endDate == null) {
416                throw new NullPointerException("endDate == null");
417            }
418            mEndDate = endDate;
419            return this;
420        }
421
422        /**
423         * Indicates that this key pair must be encrypted at rest. This will protect the key pair
424         * with the secure lock screen credential (e.g., password, PIN, or pattern).
425         *
426         * <p>Note that this feature requires that the secure lock screen (e.g., password, PIN,
427         * pattern) is set up, otherwise key pair generation will fail. Moreover, this key pair will
428         * be deleted when the secure lock screen is disabled or reset (e.g., by the user or a
429         * Device Administrator). Finally, this key pair cannot be used until the user unlocks the
430         * secure lock screen after boot.
431         *
432         * @see KeyguardManager#isDeviceSecure()
433         */
434        @NonNull
435        public Builder setEncryptionRequired() {
436            mFlags |= KeyStore.FLAG_ENCRYPTED;
437            return this;
438        }
439
440        /**
441         * Builds the instance of the {@code KeyPairGeneratorSpec}.
442         *
443         * @throws IllegalArgumentException if a required field is missing
444         * @return built instance of {@code KeyPairGeneratorSpec}
445         */
446        @NonNull
447        public KeyPairGeneratorSpec build() {
448            return new KeyPairGeneratorSpec(mContext,
449                    mKeystoreAlias,
450                    mKeyType,
451                    mKeySize,
452                    mSpec,
453                    mSubjectDN,
454                    mSerialNumber,
455                    mStartDate,
456                    mEndDate,
457                    mFlags);
458        }
459    }
460}
461