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
19eedda45ad7d829b4d65936d33e8aa6fa9c9c1ecdAlex Klyubinimport android.app.KeyguardManager;
2054bb1596e470144932943046ec7a99551d020ba0Alex Klyubinimport android.annotation.NonNull;
2154bb1596e470144932943046ec7a99551d020ba0Alex Klyubinimport android.annotation.Nullable;
22db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport android.content.Context;
233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.security.keystore.KeyGenParameterSpec;
243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.security.keystore.KeyProperties;
25db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport android.text.TextUtils;
26db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
27db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.math.BigInteger;
28a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Rootimport java.security.NoSuchAlgorithmException;
29db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.PrivateKey;
30db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.cert.Certificate;
31db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.security.spec.AlgorithmParameterSpec;
32db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport java.util.Date;
33db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
34db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Rootimport javax.security.auth.x500.X500Principal;
35db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
36db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root/**
373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * This provides the required parameters needed for initializing the
383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@code KeyPairGenerator} that works with
393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore
403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * facility</a>. The Android KeyStore facility is accessed through a
413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link java.security.KeyPairGenerator} API using the {@code AndroidKeyStore}
423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * provider. The {@code context} passed in may be used to pop up some UI to ask
433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * the user to unlock or initialize the Android KeyStore facility.
443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>
453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * After generation, the {@code keyStoreAlias} is used with the
463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)}
473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * interface to retrieve the {@link PrivateKey} and its associated
483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link Certificate} chain.
493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>
503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * The KeyPair generator will create a self-signed certificate with the subject
513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * as its X.509v3 Subject Distinguished Name and as its X.509v3 Issuer
523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Distinguished Name along with the other parameters specified with the
533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link Builder}.
543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>
553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * The self-signed X.509 certificate may be replaced at a later time by a
563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * certificate signed by a real Certificate Authority.
57eedda45ad7d829b4d65936d33e8aa6fa9c9c1ecdAlex Klyubin *
583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @deprecated Use {@link KeyGenParameterSpec} instead.
59db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root */
603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin@Deprecated
611c219f619291ba818bc2542390a2988539d94ed0Kenny Rootpublic final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
62db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
63db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    private final Context mContext;
64db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
65a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private final String mKeystoreAlias;
66a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
67a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private final String mKeyType;
68a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
69a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private final int mKeySize;
70a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
71a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    private final AlgorithmParameterSpec mSpec;
72a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
73db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    private final X500Principal mSubjectDN;
74db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
75db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    private final BigInteger mSerialNumber;
76db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
77db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    private final Date mStartDate;
78db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
79db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    private final Date mEndDate;
80db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
812eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    private final int mFlags;
822eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root
83db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    /**
84db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * Parameter specification for the "{@code AndroidKeyPairGenerator}"
85db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * instance of the {@link java.security.KeyPairGenerator} API. The
86db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * {@code context} passed in may be used to pop up some UI to ask the user
87db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * to unlock or initialize the Android keystore facility.
88db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * <p>
89db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * After generation, the {@code keyStoreAlias} is used with the
90db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)}
91db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * interface to retrieve the {@link PrivateKey} and its associated
92db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * {@link Certificate} chain.
93db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * <p>
94db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * The KeyPair generator will create a self-signed certificate with the
95db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * properties of {@code subjectDN} as its X.509v3 Subject Distinguished Name
96db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * and as its X.509v3 Issuer Distinguished Name, using the specified
97db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * {@code serialNumber}, and the validity date starting at {@code startDate}
98db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * and ending at {@code endDate}.
99db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     *
100db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * @param context Android context for the activity
101db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * @param keyStoreAlias name to use for the generated key in the Android
102db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     *            keystore
1033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * @param keyType key algorithm to use (RSA, DSA, EC)
104a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * @param keySize size of key to generate
105a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * @param spec the underlying key type parameters
106db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * @param subjectDN X.509 v3 Subject Distinguished Name
107db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * @param serialNumber X509 v3 certificate serial number
108db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * @param startDate the start of the self-signed certificate validity period
109db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * @param endDate the end date of the self-signed certificate validity
110db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     *            period
111db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     * @throws IllegalArgumentException when any argument is {@code null} or
112db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     *             {@code endDate} is before {@code startDate}.
1131c219f619291ba818bc2542390a2988539d94ed0Kenny Root     * @hide should be built with KeyPairGeneratorSpecBuilder
114db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     */
115a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    public KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize,
116a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber,
1173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            Date startDate, Date endDate, int flags) {
118db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        if (context == null) {
119db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root            throw new IllegalArgumentException("context == null");
120db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        } else if (TextUtils.isEmpty(keyStoreAlias)) {
121db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root            throw new IllegalArgumentException("keyStoreAlias must not be empty");
1223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        } else if (subjectDN == null) {
1233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            throw new IllegalArgumentException("subjectDN == null");
1243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        } else if (serialNumber == null) {
1253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            throw new IllegalArgumentException("serialNumber == null");
1263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        } else if (startDate == null) {
1273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            throw new IllegalArgumentException("startDate == null");
1283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        } else if (endDate == null) {
1293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            throw new IllegalArgumentException("endDate == null");
1303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        } else if (endDate.before(startDate)) {
1313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin            throw new IllegalArgumentException("endDate < startDate");
13267d21aef98bbafd0def2cacc6254e644e911c8ddAlex Klyubin        }
13367d21aef98bbafd0def2cacc6254e644e911c8ddAlex Klyubin
13467d21aef98bbafd0def2cacc6254e644e911c8ddAlex Klyubin        if (endDate.before(startDate)) {
13567d21aef98bbafd0def2cacc6254e644e911c8ddAlex Klyubin            throw new IllegalArgumentException("endDate < startDate");
13667d21aef98bbafd0def2cacc6254e644e911c8ddAlex Klyubin        }
13767d21aef98bbafd0def2cacc6254e644e911c8ddAlex Klyubin
138db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        mContext = context;
139db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        mKeystoreAlias = keyStoreAlias;
140a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        mKeyType = keyType;
141a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        mKeySize = keySize;
142a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        mSpec = spec;
143db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        mSubjectDN = subjectDN;
144db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        mSerialNumber = serialNumber;
145db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        mStartDate = startDate;
146db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        mEndDate = endDate;
1472eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        mFlags = flags;
148db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    }
149db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
150a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    /**
151a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * Gets the Android context used for operations with this instance.
152a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     */
153a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    public Context getContext() {
154a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        return mContext;
155a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    }
156a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
157db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    /**
1582eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * Returns the alias that will be used in the {@code java.security.KeyStore}
1592eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * in conjunction with the {@code AndroidKeyStore}.
160db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     */
1612eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public String getKeystoreAlias() {
162db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        return mKeystoreAlias;
163db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    }
164db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
165db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    /**
166622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin     * Returns the type of key pair (e.g., {@code EC}, {@code RSA}) to be generated. See
1673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * {@link KeyProperties}.{@code KEY_ALGORITHM} constants.
168db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     */
16954bb1596e470144932943046ec7a99551d020ba0Alex Klyubin    @Nullable
1703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public @KeyProperties.KeyAlgorithmEnum String getKeyType() {
171a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        return mKeyType;
172a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    }
173a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
174a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    /**
175a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * Returns the key size specified by this parameter. For instance, for RSA
176a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * this will return the modulus size and for EC it will return the field
177a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * size.
178a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     */
179a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    public int getKeySize() {
180a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        return mKeySize;
181a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    }
182a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
183a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    /**
184a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * Returns the {@link AlgorithmParameterSpec} that will be used for creation
185a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     * of the key pair.
186a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root     */
18754bb1596e470144932943046ec7a99551d020ba0Alex Klyubin    @NonNull
188a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    public AlgorithmParameterSpec getAlgorithmParameterSpec() {
189a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        return mSpec;
190db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    }
191db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
192db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    /**
1932eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * Gets the subject distinguished name to be used on the X.509 certificate
1942eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * that will be put in the {@link java.security.KeyStore}.
195db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     */
19654bb1596e470144932943046ec7a99551d020ba0Alex Klyubin    @NonNull
1972eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public X500Principal getSubjectDN() {
198db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        return mSubjectDN;
199db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    }
200db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
201db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    /**
2022eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * Gets the serial number to be used on the X.509 certificate that will be
2032eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * put in the {@link java.security.KeyStore}.
204db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     */
20554bb1596e470144932943046ec7a99551d020ba0Alex Klyubin    @NonNull
2062eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public BigInteger getSerialNumber() {
207db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        return mSerialNumber;
208db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    }
209db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
210db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    /**
2112eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * Gets the start date to be used on the X.509 certificate that will be put
2122eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * in the {@link java.security.KeyStore}.
213db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     */
21454bb1596e470144932943046ec7a99551d020ba0Alex Klyubin    @NonNull
2152eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public Date getStartDate() {
216db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        return mStartDate;
217db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    }
218db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root
219db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    /**
2202eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * Gets the end date to be used on the X.509 certificate that will be put in
2212eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * the {@link java.security.KeyStore}.
222db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root     */
22354bb1596e470144932943046ec7a99551d020ba0Alex Klyubin    @NonNull
2242eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public Date getEndDate() {
225db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root        return mEndDate;
226db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root    }
227acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
228acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root    /**
2292eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     * @hide
2302eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root     */
2313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public int getFlags() {
2322eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        return mFlags;
2332eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    }
2342eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root
2352eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    /**
236eedda45ad7d829b4d65936d33e8aa6fa9c9c1ecdAlex Klyubin     * Returns {@code true} if the key must be encrypted at rest. This will protect the key pair
237eedda45ad7d829b4d65936d33e8aa6fa9c9c1ecdAlex Klyubin     * with the secure lock screen credential (e.g., password, PIN, or pattern).
238855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin     *
2393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * <p>Note that encrypting the key at rest requires that the secure lock screen (e.g., password,
2403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * PIN, pattern) is set up, otherwise key generation will fail. Moreover, this key will be
2413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * deleted when the secure lock screen is disabled or reset (e.g., by the user or a Device
2423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * Administrator). Finally, this key cannot be used until the user unlocks the secure lock
2433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * screen after boot.
244855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin     *
2453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     * @see KeyguardManager#isDeviceSecure()
246855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin     */
2473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    public boolean isEncryptionRequired() {
2483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0;
249855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin    }
250855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin
251855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin    /**
2521c219f619291ba818bc2542390a2988539d94ed0Kenny Root     * Builder class for {@link KeyPairGeneratorSpec} objects.
253acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * <p>
254acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * This will build a parameter spec for use with the <a href="{@docRoot}
255716cc7dcac1bb9279326ab92a78a246b3a70de4eRobert Ly     * training/articles/keystore.html">Android KeyStore facility</a>.
256acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * <p>
257acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * The required fields must be filled in with the builder.
258acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * <p>
259acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * Example:
260acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     *
261acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * <pre class="prettyprint">
262acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * Calendar start = new Calendar();
263acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * Calendar end = new Calendar();
264acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * end.add(1, Calendar.YEAR);
265acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     *
2661c219f619291ba818bc2542390a2988539d94ed0Kenny Root     * KeyPairGeneratorSpec spec =
2671c219f619291ba818bc2542390a2988539d94ed0Kenny Root     *         new KeyPairGeneratorSpec.Builder(mContext).setAlias(&quot;myKey&quot;)
2681c219f619291ba818bc2542390a2988539d94ed0Kenny Root     *                 .setSubject(new X500Principal(&quot;CN=myKey&quot;)).setSerial(BigInteger.valueOf(1337))
2691c219f619291ba818bc2542390a2988539d94ed0Kenny Root     *                 .setStartDate(start.getTime()).setEndDate(end.getTime()).build();
270acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     * </pre>
2713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *
2723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin     *  @deprecated Use {@link KeyGenParameterSpec.Builder} instead.
273acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root     */
2743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin    @Deprecated
2752eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public final static class Builder {
276acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        private final Context mContext;
277acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
278acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        private String mKeystoreAlias;
279acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
28021a76df55cf4b956f4d34f57c7b9e694d0363f54Alex Klyubin        private String mKeyType;
281a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
282a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        private int mKeySize = -1;
283a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
284a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        private AlgorithmParameterSpec mSpec;
285a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
286acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        private X500Principal mSubjectDN;
287acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
288acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        private BigInteger mSerialNumber;
289acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
290acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        private Date mStartDate;
291acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
292acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        private Date mEndDate;
293acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
2942eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        private int mFlags;
2952eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root
2962eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        /**
2972eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root         * Creates a new instance of the {@code Builder} with the given
2982eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root         * {@code context}. The {@code context} passed in may be used to pop up
2992eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root         * some UI to ask the user to unlock or initialize the Android KeyStore
3002eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root         * facility.
3012eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root         */
30254bb1596e470144932943046ec7a99551d020ba0Alex Klyubin        public Builder(@NonNull Context context) {
303acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            if (context == null) {
304acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root                throw new NullPointerException("context == null");
305acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            }
306acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            mContext = context;
307acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        }
308acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
309acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        /**
310acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * Sets the alias to be used to retrieve the key later from a
311acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * {@link java.security.KeyStore} instance using the
312acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * {@code AndroidKeyStore} provider.
313acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         */
31454bb1596e470144932943046ec7a99551d020ba0Alex Klyubin        @NonNull
31554bb1596e470144932943046ec7a99551d020ba0Alex Klyubin        public Builder setAlias(@NonNull String alias) {
316acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            if (alias == null) {
317acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root                throw new NullPointerException("alias == null");
318acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            }
319acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            mKeystoreAlias = alias;
320acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            return this;
321acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        }
322acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
323acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        /**
324622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin         * Sets the type of key pair (e.g., {@code EC}, {@code RSA}) of the key pair to be
3253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin         * generated. See {@link KeyProperties}.{@code KEY_ALGORITHM} constants.
326622fd932fd33c6e86c86c8a24082674ad077a810Alex Klyubin         *
327a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root         */
32854bb1596e470144932943046ec7a99551d020ba0Alex Klyubin        @NonNull
3293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin        public Builder setKeyType(@NonNull @KeyProperties.KeyAlgorithmEnum String keyType)
3304d5443f37f2bc58be8d22ed50024c39a5a1fbc8fAlex Klyubin                throws NoSuchAlgorithmException {
331a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            if (keyType == null) {
332a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                throw new NullPointerException("keyType == null");
333a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            } else {
3344a0ff7ca984d29bd34b02e54441957cad65e8b53Alex Klyubin                try {
3354a0ff7ca984d29bd34b02e54441957cad65e8b53Alex Klyubin                    KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(keyType);
3364a0ff7ca984d29bd34b02e54441957cad65e8b53Alex Klyubin                } catch (IllegalArgumentException e) {
337a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                    throw new NoSuchAlgorithmException("Unsupported key type: " + keyType);
338a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                }
339a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            }
340a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            mKeyType = keyType;
341a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return this;
342a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        }
343a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
344a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        /**
345a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root         * Sets the key size for the keypair to be created. For instance, for a
346a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root         * key type of RSA this will set the modulus size and for a key type of
347a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root         * EC it will select a curve with a matching field size.
348a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root         */
34954bb1596e470144932943046ec7a99551d020ba0Alex Klyubin        @NonNull
350a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        public Builder setKeySize(int keySize) {
351a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            if (keySize < 0) {
352a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                throw new IllegalArgumentException("keySize < 0");
353a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            }
354a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            mKeySize = keySize;
355a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return this;
356a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        }
357a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
358a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        /**
359cd2329dbfa5aef82c38ffa36a478bbaf5088af92Alex Klyubin         * Sets the algorithm-specific key generation parameters. For example, for RSA keys
360cd2329dbfa5aef82c38ffa36a478bbaf5088af92Alex Klyubin         * this may be an instance of {@link java.security.spec.RSAKeyGenParameterSpec}.
361a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root         */
36254bb1596e470144932943046ec7a99551d020ba0Alex Klyubin        public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) {
363a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            if (spec == null) {
364a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root                throw new NullPointerException("spec == null");
365a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            }
366a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            mSpec = spec;
367a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return this;
368a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        }
369a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
370a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        /**
371acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * Sets the subject used for the self-signed certificate of the
372acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * generated key pair.
373acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         */
37454bb1596e470144932943046ec7a99551d020ba0Alex Klyubin        @NonNull
37554bb1596e470144932943046ec7a99551d020ba0Alex Klyubin        public Builder setSubject(@NonNull X500Principal subject) {
376acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            if (subject == null) {
377acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root                throw new NullPointerException("subject == null");
378acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            }
379acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            mSubjectDN = subject;
380acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            return this;
381acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        }
382acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
383acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        /**
384acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * Sets the serial number used for the self-signed certificate of the
385acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * generated key pair.
386acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         */
38754bb1596e470144932943046ec7a99551d020ba0Alex Klyubin        @NonNull
38854bb1596e470144932943046ec7a99551d020ba0Alex Klyubin        public Builder setSerialNumber(@NonNull BigInteger serialNumber) {
389acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            if (serialNumber == null) {
390acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root                throw new NullPointerException("serialNumber == null");
391acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            }
392acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            mSerialNumber = serialNumber;
393acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            return this;
394acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        }
395acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
396acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        /**
397acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * Sets the start of the validity period for the self-signed certificate
398acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * of the generated key pair.
399acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         */
40054bb1596e470144932943046ec7a99551d020ba0Alex Klyubin        @NonNull
40154bb1596e470144932943046ec7a99551d020ba0Alex Klyubin        public Builder setStartDate(@NonNull Date startDate) {
402acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            if (startDate == null) {
403acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root                throw new NullPointerException("startDate == null");
404acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            }
405acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            mStartDate = startDate;
406acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            return this;
407acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        }
408acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
409acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        /**
410acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * Sets the end of the validity period for the self-signed certificate
411acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * of the generated key pair.
412acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         */
41354bb1596e470144932943046ec7a99551d020ba0Alex Klyubin        @NonNull
41454bb1596e470144932943046ec7a99551d020ba0Alex Klyubin        public Builder setEndDate(@NonNull Date endDate) {
415acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            if (endDate == null) {
416acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root                throw new NullPointerException("endDate == null");
417acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            }
418acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            mEndDate = endDate;
419acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root            return this;
420acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        }
421acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root
422acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        /**
4235418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin         * Indicates that this key pair must be encrypted at rest. This will protect the key pair
4245418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin         * with the secure lock screen credential (e.g., password, PIN, or pattern).
425eedda45ad7d829b4d65936d33e8aa6fa9c9c1ecdAlex Klyubin         *
426eedda45ad7d829b4d65936d33e8aa6fa9c9c1ecdAlex Klyubin         * <p>Note that this feature requires that the secure lock screen (e.g., password, PIN,
4275418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin         * pattern) is set up, otherwise key pair generation will fail. Moreover, this key pair will
4285418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin         * be deleted when the secure lock screen is disabled or reset (e.g., by the user or a
4295418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin         * Device Administrator). Finally, this key pair cannot be used until the user unlocks the
4305418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin         * secure lock screen after boot.
431eedda45ad7d829b4d65936d33e8aa6fa9c9c1ecdAlex Klyubin         *
432eedda45ad7d829b4d65936d33e8aa6fa9c9c1ecdAlex Klyubin         * @see KeyguardManager#isDeviceSecure()
4332eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root         */
43454bb1596e470144932943046ec7a99551d020ba0Alex Klyubin        @NonNull
4352eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        public Builder setEncryptionRequired() {
4362eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root            mFlags |= KeyStore.FLAG_ENCRYPTED;
4372eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root            return this;
4382eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        }
4392eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root
4402eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        /**
4411c219f619291ba818bc2542390a2988539d94ed0Kenny Root         * Builds the instance of the {@code KeyPairGeneratorSpec}.
442acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         *
443acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         * @throws IllegalArgumentException if a required field is missing
4441c219f619291ba818bc2542390a2988539d94ed0Kenny Root         * @return built instance of {@code KeyPairGeneratorSpec}
445acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root         */
44654bb1596e470144932943046ec7a99551d020ba0Alex Klyubin        @NonNull
4471c219f619291ba818bc2542390a2988539d94ed0Kenny Root        public KeyPairGeneratorSpec build() {
448855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin            return new KeyPairGeneratorSpec(mContext,
449855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin                    mKeystoreAlias,
450855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin                    mKeyType,
451855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin                    mKeySize,
452855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin                    mSpec,
453855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin                    mSubjectDN,
454855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin                    mSerialNumber,
455855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin                    mStartDate,
456855fa31eb5ff68d131f3e496920594d875841cb0Alex Klyubin                    mEndDate,
4573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin                    mFlags);
458acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root        }
459acb0b5b220b2cb15f5a800a356bb25f47252a6eaKenny Root    }
460db026710ec0adcf7f72dfb24c65d38a882ee26d8Kenny Root}
461