1db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root/*
2db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * Copyright (C) 2012 The Android Open Source Project
3db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root *
4db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * Licensed under the Apache License, Version 2.0 (the "License");
5db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * you may not use this file except in compliance with the License.
6db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * You may obtain a copy of the License at
7db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root *
8db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root *      http://www.apache.org/licenses/LICENSE-2.0
9db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root *
10db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * Unless required by applicable law or agreed to in writing, software
11db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * distributed under the License is distributed on an "AS IS" BASIS,
12db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * See the License for the specific language governing permissions and
14db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root * limitations under the License.
15db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */
16db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
17db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootpackage android.security;
18db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
19a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Rootimport com.android.org.conscrypt.NativeCrypto;
20a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
21db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport android.content.Context;
22db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport android.text.TextUtils;
23db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
24db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.math.BigInteger;
25a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Rootimport java.security.NoSuchAlgorithmException;
26db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.PrivateKey;
27db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.cert.Certificate;
28db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.spec.AlgorithmParameterSpec;
29a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Rootimport java.security.spec.DSAParameterSpec;
30a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Rootimport java.security.spec.RSAKeyGenParameterSpec;
31db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.util.Date;
32db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
33db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport javax.security.auth.x500.X500Principal;
34db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
35db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root/**
36acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * This provides the required parameters needed for initializing the
371c219f619291ba818bc2542390a2988539d94ed0Kenny Root * {@code KeyPairGenerator} that works with
38716cc7dcac1bb9279326ab92a78a246b3a70de4eRobert Ly * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore
391c219f619291ba818bc2542390a2988539d94ed0Kenny Root * facility</a>. The Android KeyStore facility is accessed through a
402eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * {@link java.security.KeyPairGenerator} API using the {@code AndroidKeyStore}
412eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * provider. The {@code context} passed in may be used to pop up some UI to ask
422eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * the user to unlock or initialize the Android KeyStore facility.
43acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * <p>
44acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * After generation, the {@code keyStoreAlias} is used with the
45acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)}
46acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * interface to retrieve the {@link PrivateKey} and its associated
47acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * {@link Certificate} chain.
48acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * <p>
49acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * The KeyPair generator will create a self-signed certificate with the subject
50acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * as its X.509v3 Subject Distinguished Name and as its X.509v3 Issuer
51acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * Distinguished Name along with the other parameters specified with the
52acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * {@link Builder}.
53acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root * <p>
542eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * The self-signed X.509 certificate may be replaced at a later time by a
552eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root * certificate signed by a real Certificate Authority.
56db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */
571c219f619291ba818bc2542390a2988539d94ed0Kenny Rootpublic final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
58a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    /*
59a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * These must be kept in sync with system/security/keystore/defaults.h
60a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     */
61a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
62a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    /* DSA */
63a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private static final int DSA_DEFAULT_KEY_SIZE = 1024;
64a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private static final int DSA_MIN_KEY_SIZE = 512;
65a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private static final int DSA_MAX_KEY_SIZE = 8192;
66a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
67a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    /* EC */
68a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private static final int EC_DEFAULT_KEY_SIZE = 256;
69a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private static final int EC_MIN_KEY_SIZE = 192;
70a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private static final int EC_MAX_KEY_SIZE = 521;
71a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
72a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    /* RSA */
73a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private static final int RSA_DEFAULT_KEY_SIZE = 2048;
74a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private static final int RSA_MIN_KEY_SIZE = 512;
75a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private static final int RSA_MAX_KEY_SIZE = 8192;
76db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
77db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    private final Context mContext;
78db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
79a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private final String mKeystoreAlias;
80a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
81a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private final String mKeyType;
82a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
83a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private final int mKeySize;
84a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
85a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private final AlgorithmParameterSpec mSpec;
86a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
87db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    private final X500Principal mSubjectDN;
88db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
89db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    private final BigInteger mSerialNumber;
90db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
91db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    private final Date mStartDate;
92db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
93db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    private final Date mEndDate;
94db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
952eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    private final int mFlags;
962eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root
97db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    /**
98db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * Parameter specification for the "{@code AndroidKeyPairGenerator}"
99db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * instance of the {@link java.security.KeyPairGenerator} API. The
100db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * {@code context} passed in may be used to pop up some UI to ask the user
101db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * to unlock or initialize the Android keystore facility.
102db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * <p>
103db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * After generation, the {@code keyStoreAlias} is used with the
104db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)}
105db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * interface to retrieve the {@link PrivateKey} and its associated
106db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * {@link Certificate} chain.
107db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * <p>
108db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * The KeyPair generator will create a self-signed certificate with the
109db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * properties of {@code subjectDN} as its X.509v3 Subject Distinguished Name
110db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * and as its X.509v3 Issuer Distinguished Name, using the specified
111db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * {@code serialNumber}, and the validity date starting at {@code startDate}
112db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * and ending at {@code endDate}.
113db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     *
114db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * @param context Android context for the activity
115db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * @param keyStoreAlias name to use for the generated key in the Android
116db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     *            keystore
117a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * @param keyType key algorithm to use (RSA, DSA, EC)
118a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * @param keySize size of key to generate
119a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * @param spec the underlying key type parameters
120db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * @param subjectDN X.509 v3 Subject Distinguished Name
121db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * @param serialNumber X509 v3 certificate serial number
122db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * @param startDate the start of the self-signed certificate validity period
123db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * @param endDate the end date of the self-signed certificate validity
124db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     *            period
125db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * @throws IllegalArgumentException when any argument is {@code null} or
126db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     *             {@code endDate} is before {@code startDate}.
1271c219f619291ba818bc2542390a2988539d94ed0Kenny Root     * @hide should be built with KeyPairGeneratorSpecBuilder
128db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     */
129a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    public KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize,
130a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber,
131a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            Date startDate, Date endDate, int flags) {
132db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        if (context == null) {
133db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root            throw new IllegalArgumentException("context == null");
134db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        } else if (TextUtils.isEmpty(keyStoreAlias)) {
135db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root            throw new IllegalArgumentException("keyStoreAlias must not be empty");
136db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        } else if (subjectDN == null) {
137db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root            throw new IllegalArgumentException("subjectDN == null");
138db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        } else if (serialNumber == null) {
139db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root            throw new IllegalArgumentException("serialNumber == null");
140db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        } else if (startDate == null) {
141db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root            throw new IllegalArgumentException("startDate == null");
142db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        } else if (endDate == null) {
143db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root            throw new IllegalArgumentException("endDate == null");
144db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        } else if (endDate.before(startDate)) {
145db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root            throw new IllegalArgumentException("endDate < startDate");
146db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        }
147db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
148a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        final int keyTypeInt = KeyStore.getKeyTypeForAlgorithm(keyType);
149a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        if (keySize == -1) {
150a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            keySize = getDefaultKeySizeForType(keyTypeInt);
151a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        }
152a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        checkCorrectParametersSpec(keyTypeInt, keySize, spec);
153a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        checkValidKeySize(keyTypeInt, keySize);
154a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
155db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        mContext = context;
156db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        mKeystoreAlias = keyStoreAlias;
157a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        mKeyType = keyType;
158a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        mKeySize = keySize;
159a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        mSpec = spec;
160db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        mSubjectDN = subjectDN;
161db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        mSerialNumber = serialNumber;
162db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        mStartDate = startDate;
163db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        mEndDate = endDate;
1642eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        mFlags = flags;
165db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    }
166db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
167a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private static int getDefaultKeySizeForType(int keyType) {
168a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        if (keyType == NativeCrypto.EVP_PKEY_DSA) {
169a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return DSA_DEFAULT_KEY_SIZE;
170a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        } else if (keyType == NativeCrypto.EVP_PKEY_EC) {
171a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return EC_DEFAULT_KEY_SIZE;
172a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        } else if (keyType == NativeCrypto.EVP_PKEY_RSA) {
173a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return RSA_DEFAULT_KEY_SIZE;
174a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        }
175a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        throw new IllegalArgumentException("Invalid key type " + keyType);
176a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    }
177a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
178a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private static void checkValidKeySize(int keyType, int keySize) {
179a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        if (keyType == NativeCrypto.EVP_PKEY_DSA) {
180a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            if (keySize < DSA_MIN_KEY_SIZE || keySize > DSA_MAX_KEY_SIZE) {
181a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                throw new IllegalArgumentException("DSA keys must be >= " + DSA_MIN_KEY_SIZE
182a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                        + " and <= " + DSA_MAX_KEY_SIZE);
183a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            }
184a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        } else if (keyType == NativeCrypto.EVP_PKEY_EC) {
185a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) {
186a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                throw new IllegalArgumentException("EC keys must be >= " + EC_MIN_KEY_SIZE
187a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                        + " and <= " + EC_MAX_KEY_SIZE);
188a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            }
189a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        } else if (keyType == NativeCrypto.EVP_PKEY_RSA) {
190a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
191a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                throw new IllegalArgumentException("RSA keys must be >= " + RSA_MIN_KEY_SIZE
192a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                        + " and <= " + RSA_MAX_KEY_SIZE);
193a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            }
194a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        } else {
195a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            throw new IllegalArgumentException("Invalid key type " + keyType);
196a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        }
197a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    }
198a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
199a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private static void checkCorrectParametersSpec(int keyType, int keySize,
200a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            AlgorithmParameterSpec spec) {
201a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        if (keyType == NativeCrypto.EVP_PKEY_DSA && spec != null) {
202a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            if (!(spec instanceof DSAParameterSpec)) {
203a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                throw new IllegalArgumentException("DSA keys must have DSAParameterSpec specified");
204a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            }
205a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        } else if (keyType == NativeCrypto.EVP_PKEY_RSA && spec != null) {
206a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            if (spec instanceof RSAKeyGenParameterSpec) {
207a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) spec;
208a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                if (keySize != -1 && keySize != rsaSpec.getKeysize()) {
209a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                    throw new IllegalArgumentException("RSA key size must match: " + keySize
210a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                            + " vs " + rsaSpec.getKeysize());
211a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                }
212a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            } else {
213a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                throw new IllegalArgumentException("RSA may only use RSAKeyGenParameterSpec");
214a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            }
215a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        }
216a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    }
217a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
218a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    /**
219a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * Gets the Android context used for operations with this instance.
220a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     */
221a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    public Context getContext() {
222a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        return mContext;
223a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    }
224a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
225db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    /**
2262eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * Returns the alias that will be used in the {@code java.security.KeyStore}
2272eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * in conjunction with the {@code AndroidKeyStore}.
228db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     */
2292eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public String getKeystoreAlias() {
230db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        return mKeystoreAlias;
231db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    }
232db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
233db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    /**
234a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * Returns the key type (e.g., "RSA", "DSA", "EC") specified by this
235a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * parameter.
236db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     */
237a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    public String getKeyType() {
238a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        return mKeyType;
239a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    }
240a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
241a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    /**
242a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * Returns the key size specified by this parameter. For instance, for RSA
243a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * this will return the modulus size and for EC it will return the field
244a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * size.
245a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     */
246a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    public int getKeySize() {
247a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        return mKeySize;
248a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    }
249a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
250a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    /**
251a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * Returns the {@link AlgorithmParameterSpec} that will be used for creation
252a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * of the key pair.
253a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     */
254a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    public AlgorithmParameterSpec getAlgorithmParameterSpec() {
255a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        return mSpec;
256db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    }
257db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
258db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    /**
2592eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * Gets the subject distinguished name to be used on the X.509 certificate
2602eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * that will be put in the {@link java.security.KeyStore}.
261db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     */
2622eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public X500Principal getSubjectDN() {
263db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        return mSubjectDN;
264db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    }
265db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
266db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    /**
2672eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * Gets the serial number to be used on the X.509 certificate that will be
2682eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * put in the {@link java.security.KeyStore}.
269db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     */
2702eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public BigInteger getSerialNumber() {
271db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        return mSerialNumber;
272db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    }
273db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
274db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    /**
2752eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * Gets the start date to be used on the X.509 certificate that will be put
2762eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * in the {@link java.security.KeyStore}.
277db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     */
2782eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public Date getStartDate() {
279db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        return mStartDate;
280db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    }
281db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
282db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    /**
2832eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * Gets the end date to be used on the X.509 certificate that will be put in
2842eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * the {@link java.security.KeyStore}.
285db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     */
2862eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public Date getEndDate() {
287db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        return mEndDate;
288db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    }
289acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
290acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root    /**
2912eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * @hide
2922eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     */
2932eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    int getFlags() {
2942eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        return mFlags;
2952eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    }
2962eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root
2972eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    /**
2982eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * Returns {@code true} if this parameter will require generated keys to be
2992eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * encrypted in the {@link java.security.KeyStore}.
3002eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     */
3012eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public boolean isEncryptionRequired() {
3022eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0;
3032eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    }
3042eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root
3052eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    /**
3061c219f619291ba818bc2542390a2988539d94ed0Kenny Root     * Builder class for {@link KeyPairGeneratorSpec} objects.
307acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * <p>
308acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * This will build a parameter spec for use with the <a href="{@docRoot}
309716cc7dcac1bb9279326ab92a78a246b3a70de4eRobert Ly     * training/articles/keystore.html">Android KeyStore facility</a>.
310acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * <p>
311acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * The required fields must be filled in with the builder.
312acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * <p>
313acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * Example:
314acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     *
315acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * <pre class="prettyprint">
316acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * Calendar start = new Calendar();
317acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * Calendar end = new Calendar();
318acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * end.add(1, Calendar.YEAR);
319acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     *
3201c219f619291ba818bc2542390a2988539d94ed0Kenny Root     * KeyPairGeneratorSpec spec =
3211c219f619291ba818bc2542390a2988539d94ed0Kenny Root     *         new KeyPairGeneratorSpec.Builder(mContext).setAlias(&quot;myKey&quot;)
3221c219f619291ba818bc2542390a2988539d94ed0Kenny Root     *                 .setSubject(new X500Principal(&quot;CN=myKey&quot;)).setSerial(BigInteger.valueOf(1337))
3231c219f619291ba818bc2542390a2988539d94ed0Kenny Root     *                 .setStartDate(start.getTime()).setEndDate(end.getTime()).build();
324acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * </pre>
325acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     */
3262eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public final static class Builder {
327acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        private final Context mContext;
328acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
329acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        private String mKeystoreAlias;
330acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
331a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        private String mKeyType = "RSA";
332a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
333a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        private int mKeySize = -1;
334a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
335a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        private AlgorithmParameterSpec mSpec;
336a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
337acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        private X500Principal mSubjectDN;
338acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
339acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        private BigInteger mSerialNumber;
340acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
341acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        private Date mStartDate;
342acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
343acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        private Date mEndDate;
344acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
3452eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        private int mFlags;
3462eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root
3472eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        /**
3482eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root         * Creates a new instance of the {@code Builder} with the given
3492eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root         * {@code context}. The {@code context} passed in may be used to pop up
3502eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root         * some UI to ask the user to unlock or initialize the Android KeyStore
3512eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root         * facility.
3522eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root         */
353acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        public Builder(Context context) {
354acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            if (context == null) {
355acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root                throw new NullPointerException("context == null");
356acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            }
357acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            mContext = context;
358acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        }
359acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
360acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        /**
361acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * Sets the alias to be used to retrieve the key later from a
362acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * {@link java.security.KeyStore} instance using the
363acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * {@code AndroidKeyStore} provider.
364acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         */
365acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        public Builder setAlias(String alias) {
366acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            if (alias == null) {
367acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root                throw new NullPointerException("alias == null");
368acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            }
369acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            mKeystoreAlias = alias;
370acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            return this;
371acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        }
372acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
373acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        /**
374a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root         * Sets the key type (e.g., RSA, DSA, EC) of the keypair to be created.
375a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root         */
376a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        public Builder setKeyType(String keyType) throws NoSuchAlgorithmException {
377a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            if (keyType == null) {
378a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                throw new NullPointerException("keyType == null");
379a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            } else {
380a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                try {
381a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                    KeyStore.getKeyTypeForAlgorithm(keyType);
382a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                } catch (IllegalArgumentException e) {
383a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                    throw new NoSuchAlgorithmException("Unsupported key type: " + keyType);
384a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                }
385a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            }
386a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            mKeyType = keyType;
387a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return this;
388a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        }
389a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
390a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        /**
391a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root         * Sets the key size for the keypair to be created. For instance, for a
392a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root         * key type of RSA this will set the modulus size and for a key type of
393a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root         * EC it will select a curve with a matching field size.
394a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root         */
395a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        public Builder setKeySize(int keySize) {
396a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            if (keySize < 0) {
397a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                throw new IllegalArgumentException("keySize < 0");
398a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            }
399a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            mKeySize = keySize;
400a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return this;
401a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        }
402a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
403a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        /**
404a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root         * Sets the underlying key type's parameters. This is required for DSA
405a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root         * where you must set this to an instance of
406a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root         * {@link java.security.spec.DSAParameterSpec}.
407a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root         */
408a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        public Builder setAlgorithmParameterSpec(AlgorithmParameterSpec spec) {
409a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            if (spec == null) {
410a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                throw new NullPointerException("spec == null");
411a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            }
412a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            mSpec = spec;
413a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return this;
414a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        }
415a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
416a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        /**
417acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * Sets the subject used for the self-signed certificate of the
418acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * generated key pair.
419acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         */
420acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        public Builder setSubject(X500Principal subject) {
421acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            if (subject == null) {
422acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root                throw new NullPointerException("subject == null");
423acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            }
424acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            mSubjectDN = subject;
425acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            return this;
426acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        }
427acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
428acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        /**
429acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * Sets the serial number used for the self-signed certificate of the
430acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * generated key pair.
431acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         */
432acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        public Builder setSerialNumber(BigInteger serialNumber) {
433acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            if (serialNumber == null) {
434acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root                throw new NullPointerException("serialNumber == null");
435acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            }
436acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            mSerialNumber = serialNumber;
437acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            return this;
438acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        }
439acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
440acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        /**
441acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * Sets the start of the validity period for the self-signed certificate
442acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * of the generated key pair.
443acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         */
444acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        public Builder setStartDate(Date startDate) {
445acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            if (startDate == null) {
446acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root                throw new NullPointerException("startDate == null");
447acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            }
448acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            mStartDate = startDate;
449acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            return this;
450acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        }
451acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
452acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        /**
453acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * Sets the end of the validity period for the self-signed certificate
454acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * of the generated key pair.
455acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         */
456acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        public Builder setEndDate(Date endDate) {
457acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            if (endDate == null) {
458acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root                throw new NullPointerException("endDate == null");
459acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            }
460acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            mEndDate = endDate;
461acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            return this;
462acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        }
463acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
464acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        /**
4652eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root         * Indicates that this key must be encrypted at rest on storage. Note
4662eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root         * that enabling this will require that the user enable a strong lock
4672eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root         * screen (e.g., PIN, password) before creating or using the generated
4682eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root         * key is successful.
4692eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root         */
4702eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        public Builder setEncryptionRequired() {
4712eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root            mFlags |= KeyStore.FLAG_ENCRYPTED;
4722eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root            return this;
4732eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        }
4742eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root
4752eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        /**
4761c219f619291ba818bc2542390a2988539d94ed0Kenny Root         * Builds the instance of the {@code KeyPairGeneratorSpec}.
477acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         *
478acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * @throws IllegalArgumentException if a required field is missing
4791c219f619291ba818bc2542390a2988539d94ed0Kenny Root         * @return built instance of {@code KeyPairGeneratorSpec}
480acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         */
4811c219f619291ba818bc2542390a2988539d94ed0Kenny Root        public KeyPairGeneratorSpec build() {
482a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return new KeyPairGeneratorSpec(mContext, mKeystoreAlias, mKeyType, mKeySize, mSpec,
483a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                    mSubjectDN, mSerialNumber, mStartDate, mEndDate, mFlags);
484acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        }
485acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root    }
486db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root}
487