• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package android.security;
18 
19 import android.test.AndroidTestCase;
20 
21 import java.io.ByteArrayInputStream;
22 import java.math.BigInteger;
23 import java.security.KeyPair;
24 import java.security.PrivateKey;
25 import java.security.PublicKey;
26 import java.security.SecureRandom;
27 import java.security.cert.Certificate;
28 import java.security.cert.CertificateFactory;
29 import java.security.cert.X509Certificate;
30 import java.security.interfaces.DSAParams;
31 import java.security.interfaces.DSAPublicKey;
32 import java.security.interfaces.ECPublicKey;
33 import java.security.interfaces.RSAPublicKey;
34 import java.security.spec.AlgorithmParameterSpec;
35 import java.security.spec.DSAParameterSpec;
36 import java.security.spec.RSAKeyGenParameterSpec;
37 import java.text.SimpleDateFormat;
38 import java.util.Date;
39 
40 import javax.security.auth.x500.X500Principal;
41 
42 public class AndroidKeyPairGeneratorTest extends AndroidTestCase {
43     private android.security.KeyStore mAndroidKeyStore;
44 
45     private java.security.KeyPairGenerator mGenerator;
46 
47     private static final String TEST_ALIAS_1 = "test1";
48 
49     private static final String TEST_ALIAS_2 = "test2";
50 
51     private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1");
52 
53     private static final X500Principal TEST_DN_2 = new X500Principal("CN=test2");
54 
55     private static final BigInteger TEST_SERIAL_1 = BigInteger.ONE;
56 
57     private static final BigInteger TEST_SERIAL_2 = BigInteger.valueOf(2L);
58 
59     private static final long NOW_MILLIS = System.currentTimeMillis();
60 
61     /* We have to round this off because X509v3 doesn't store milliseconds. */
62     private static final Date NOW = new Date(NOW_MILLIS - (NOW_MILLIS % 1000L));
63 
64     @SuppressWarnings("deprecation")
65     private static final Date NOW_PLUS_10_YEARS = new Date(NOW.getYear() + 10, 0, 1);
66 
67     @Override
setUp()68     protected void setUp() throws Exception {
69         mAndroidKeyStore = android.security.KeyStore.getInstance();
70 
71         assertTrue(mAndroidKeyStore.reset());
72 
73         assertFalse(mAndroidKeyStore.isUnlocked());
74 
75         mGenerator = java.security.KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
76     }
77 
setupPassword()78     private void setupPassword() {
79         assertTrue(mAndroidKeyStore.password("1111"));
80         assertTrue(mAndroidKeyStore.isUnlocked());
81 
82         String[] aliases = mAndroidKeyStore.saw("");
83         assertNotNull(aliases);
84         assertEquals(0, aliases.length);
85     }
86 
testKeyPairGenerator_Initialize_Params_Encrypted_Success()87     public void testKeyPairGenerator_Initialize_Params_Encrypted_Success() throws Exception {
88         setupPassword();
89 
90         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
91                 .setAlias(TEST_ALIAS_1)
92                 .setSubject(TEST_DN_1)
93                 .setSerialNumber(TEST_SERIAL_1)
94                 .setStartDate(NOW)
95                 .setEndDate(NOW_PLUS_10_YEARS)
96                 .setEncryptionRequired()
97                 .build());
98     }
99 
testKeyPairGenerator_Initialize_KeySize_Encrypted_Failure()100     public void testKeyPairGenerator_Initialize_KeySize_Encrypted_Failure() throws Exception {
101         setupPassword();
102 
103         try {
104             mGenerator.initialize(1024);
105             fail("KeyPairGenerator should not support setting the key size");
106         } catch (IllegalArgumentException success) {
107         }
108     }
109 
testKeyPairGenerator_Initialize_KeySizeAndSecureRandom_Encrypted_Failure()110     public void testKeyPairGenerator_Initialize_KeySizeAndSecureRandom_Encrypted_Failure()
111             throws Exception {
112         setupPassword();
113 
114         try {
115             mGenerator.initialize(1024, new SecureRandom());
116             fail("KeyPairGenerator should not support setting the key size");
117         } catch (IllegalArgumentException success) {
118         }
119     }
120 
testKeyPairGenerator_Initialize_ParamsAndSecureRandom_Encrypted_Failure()121     public void testKeyPairGenerator_Initialize_ParamsAndSecureRandom_Encrypted_Failure()
122             throws Exception {
123         setupPassword();
124 
125         mGenerator.initialize(
126                 new KeyPairGeneratorSpec.Builder(getContext())
127                         .setAlias(TEST_ALIAS_1)
128                         .setKeyType("RSA")
129                         .setKeySize(1024)
130                         .setSubject(TEST_DN_1)
131                         .setSerialNumber(TEST_SERIAL_1)
132                         .setStartDate(NOW)
133                         .setEndDate(NOW_PLUS_10_YEARS)
134                         .setEncryptionRequired()
135                         .build(),
136                 new SecureRandom());
137     }
138 
testKeyPairGenerator_GenerateKeyPair_Encrypted_Success()139     public void testKeyPairGenerator_GenerateKeyPair_Encrypted_Success() throws Exception {
140         setupPassword();
141 
142         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
143                 .setAlias(TEST_ALIAS_1)
144                 .setSubject(TEST_DN_1)
145                 .setSerialNumber(TEST_SERIAL_1)
146                 .setStartDate(NOW)
147                 .setEndDate(NOW_PLUS_10_YEARS)
148                 .setEncryptionRequired()
149                 .build());
150 
151         final KeyPair pair = mGenerator.generateKeyPair();
152         assertNotNull("The KeyPair returned should not be null", pair);
153 
154         assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
155                 NOW_PLUS_10_YEARS);
156     }
157 
testKeyPairGenerator_GenerateKeyPair_DSA_Unencrypted_Success()158     public void testKeyPairGenerator_GenerateKeyPair_DSA_Unencrypted_Success() throws Exception {
159         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
160                 .setAlias(TEST_ALIAS_1)
161                 .setKeyType("DSA")
162                 .setSubject(TEST_DN_1)
163                 .setSerialNumber(TEST_SERIAL_1)
164                 .setStartDate(NOW)
165                 .setEndDate(NOW_PLUS_10_YEARS)
166                 .build());
167 
168         final KeyPair pair = mGenerator.generateKeyPair();
169         assertNotNull("The KeyPair returned should not be null", pair);
170 
171         assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 1024, null, TEST_DN_1, TEST_SERIAL_1, NOW,
172                 NOW_PLUS_10_YEARS);
173     }
174 
testKeyPairGenerator_GenerateKeyPair_DSA_2048_Unencrypted_Success()175     public void testKeyPairGenerator_GenerateKeyPair_DSA_2048_Unencrypted_Success()
176             throws Exception {
177         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
178                 .setAlias(TEST_ALIAS_1)
179                 .setKeyType("DSA")
180                 .setKeySize(2048)
181                 .setSubject(TEST_DN_1)
182                 .setSerialNumber(TEST_SERIAL_1)
183                 .setStartDate(NOW)
184                 .setEndDate(NOW_PLUS_10_YEARS)
185                 .build());
186 
187         final KeyPair pair = mGenerator.generateKeyPair();
188         assertNotNull("The KeyPair returned should not be null", pair);
189 
190         assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
191                 NOW_PLUS_10_YEARS);
192     }
193 
testKeyPairGenerator_GenerateKeyPair_DSA_SpecifiedParams_Unencrypted_Success()194     public void testKeyPairGenerator_GenerateKeyPair_DSA_SpecifiedParams_Unencrypted_Success()
195             throws Exception {
196         /*
197          * generated using: openssl dsaparam -C 2048
198          */
199         BigInteger p = new BigInteger(1, new byte[] {
200                 (byte) 0xC0, (byte) 0x3D, (byte) 0x86, (byte) 0x09, (byte) 0xCA, (byte) 0x8C,
201                 (byte) 0x37, (byte) 0xCA, (byte) 0xCC, (byte) 0x4A, (byte) 0x81, (byte) 0xBD,
202                 (byte) 0xD8, (byte) 0x50, (byte) 0x77, (byte) 0xCD, (byte) 0xDD, (byte) 0x32,
203                 (byte) 0x0B, (byte) 0x43, (byte) 0xBF, (byte) 0x42, (byte) 0x06, (byte) 0x5A,
204                 (byte) 0x3D, (byte) 0x18, (byte) 0x50, (byte) 0x47, (byte) 0x79, (byte) 0xE1,
205                 (byte) 0x5B, (byte) 0x86, (byte) 0x03, (byte) 0xB9, (byte) 0x28, (byte) 0x9C,
206                 (byte) 0x18, (byte) 0xA9, (byte) 0xF5, (byte) 0xD6, (byte) 0xF4, (byte) 0x94,
207                 (byte) 0x5B, (byte) 0x87, (byte) 0x58, (byte) 0xCA, (byte) 0xB2, (byte) 0x1E,
208                 (byte) 0xFC, (byte) 0xED, (byte) 0x37, (byte) 0xC3, (byte) 0x49, (byte) 0xAC,
209                 (byte) 0xFA, (byte) 0x46, (byte) 0xDB, (byte) 0x7A, (byte) 0x50, (byte) 0x96,
210                 (byte) 0xCF, (byte) 0x52, (byte) 0xD7, (byte) 0x4E, (byte) 0xEB, (byte) 0x26,
211                 (byte) 0x41, (byte) 0xA2, (byte) 0x6F, (byte) 0x99, (byte) 0x80, (byte) 0x9F,
212                 (byte) 0x0F, (byte) 0x0A, (byte) 0xA8, (byte) 0x0D, (byte) 0xAC, (byte) 0xAB,
213                 (byte) 0xEF, (byte) 0x7D, (byte) 0xE7, (byte) 0x4C, (byte) 0xF1, (byte) 0x88,
214                 (byte) 0x44, (byte) 0xC9, (byte) 0x17, (byte) 0xD0, (byte) 0xBB, (byte) 0xE2,
215                 (byte) 0x01, (byte) 0x8C, (byte) 0xC1, (byte) 0x02, (byte) 0x1D, (byte) 0x3C,
216                 (byte) 0x15, (byte) 0xB7, (byte) 0x41, (byte) 0x30, (byte) 0xD8, (byte) 0x11,
217                 (byte) 0xBD, (byte) 0x6A, (byte) 0x2A, (byte) 0x0D, (byte) 0x36, (byte) 0x44,
218                 (byte) 0x9C, (byte) 0x3F, (byte) 0x32, (byte) 0xE2, (byte) 0x1C, (byte) 0xFB,
219                 (byte) 0xE3, (byte) 0xFF, (byte) 0xCC, (byte) 0x1A, (byte) 0x72, (byte) 0x38,
220                 (byte) 0x37, (byte) 0x69, (byte) 0x5E, (byte) 0x35, (byte) 0x73, (byte) 0xE1,
221                 (byte) 0x1E, (byte) 0x74, (byte) 0x35, (byte) 0x44, (byte) 0x07, (byte) 0xB5,
222                 (byte) 0x2F, (byte) 0x0B, (byte) 0x60, (byte) 0xF4, (byte) 0xA9, (byte) 0xE0,
223                 (byte) 0x81, (byte) 0xB2, (byte) 0xCD, (byte) 0x8B, (byte) 0x82, (byte) 0x76,
224                 (byte) 0x7F, (byte) 0xD4, (byte) 0x17, (byte) 0x32, (byte) 0x86, (byte) 0x98,
225                 (byte) 0x7C, (byte) 0x85, (byte) 0x66, (byte) 0xF6, (byte) 0x77, (byte) 0xED,
226                 (byte) 0x8B, (byte) 0x1A, (byte) 0x52, (byte) 0x16, (byte) 0xDA, (byte) 0x1C,
227                 (byte) 0xA7, (byte) 0x16, (byte) 0x79, (byte) 0x20, (byte) 0x1C, (byte) 0x99,
228                 (byte) 0x5F, (byte) 0x12, (byte) 0x66, (byte) 0x15, (byte) 0x9F, (byte) 0xE5,
229                 (byte) 0x73, (byte) 0xA9, (byte) 0x61, (byte) 0xBA, (byte) 0xA7, (byte) 0x23,
230                 (byte) 0x93, (byte) 0x77, (byte) 0xB5, (byte) 0xF6, (byte) 0xEC, (byte) 0x13,
231                 (byte) 0xBF, (byte) 0x95, (byte) 0x60, (byte) 0x78, (byte) 0x84, (byte) 0xE3,
232                 (byte) 0x44, (byte) 0xEC, (byte) 0x74, (byte) 0xC2, (byte) 0xCB, (byte) 0xD4,
233                 (byte) 0x70, (byte) 0xC5, (byte) 0x7B, (byte) 0xF8, (byte) 0x07, (byte) 0x3B,
234                 (byte) 0xEB, (byte) 0x9F, (byte) 0xC9, (byte) 0x7D, (byte) 0xE0, (byte) 0xA5,
235                 (byte) 0xBA, (byte) 0x68, (byte) 0x7B, (byte) 0xF4, (byte) 0x70, (byte) 0x40,
236                 (byte) 0xAE, (byte) 0xE9, (byte) 0x65, (byte) 0xEE, (byte) 0x5B, (byte) 0x71,
237                 (byte) 0x36, (byte) 0x0B, (byte) 0xB0, (byte) 0xA2, (byte) 0x98, (byte) 0x7D,
238                 (byte) 0xE3, (byte) 0x24, (byte) 0x95, (byte) 0x2B, (byte) 0xC2, (byte) 0x0A,
239                 (byte) 0x78, (byte) 0x3D, (byte) 0xCC, (byte) 0x3A, (byte) 0xEE, (byte) 0xED,
240                 (byte) 0x48, (byte) 0xEB, (byte) 0xA3, (byte) 0x78, (byte) 0xA8, (byte) 0x9D,
241                 (byte) 0x0A, (byte) 0x8F, (byte) 0x9E, (byte) 0x59, (byte) 0x2C, (byte) 0x44,
242                 (byte) 0xB5, (byte) 0xF9, (byte) 0x53, (byte) 0x43,
243         });
244 
245         BigInteger q = new BigInteger(1, new byte[] {
246                 (byte) 0xA1, (byte) 0x9B, (byte) 0x1D, (byte) 0xC0, (byte) 0xE3, (byte) 0xF6,
247                 (byte) 0x4A, (byte) 0x35, (byte) 0xE1, (byte) 0x8A, (byte) 0x43, (byte) 0xC2,
248                 (byte) 0x9C, (byte) 0xF9, (byte) 0x52, (byte) 0x8F, (byte) 0x94, (byte) 0xA1,
249                 (byte) 0x12, (byte) 0x11, (byte) 0xDB, (byte) 0x9A, (byte) 0xB6, (byte) 0x35,
250                 (byte) 0x56, (byte) 0x26, (byte) 0x60, (byte) 0x89, (byte) 0x11, (byte) 0xAC,
251                 (byte) 0xA8, (byte) 0xE5,
252         });
253 
254         BigInteger g = new BigInteger(1, new byte[] {
255                 (byte) 0xA1, (byte) 0x5C, (byte) 0x57, (byte) 0x15, (byte) 0xC3, (byte) 0xD9,
256                 (byte) 0xD7, (byte) 0x41, (byte) 0x89, (byte) 0xD6, (byte) 0xB8, (byte) 0x7B,
257                 (byte) 0xF3, (byte) 0xE0, (byte) 0xB3, (byte) 0xC5, (byte) 0xD1, (byte) 0xAA,
258                 (byte) 0xF9, (byte) 0x55, (byte) 0x48, (byte) 0xF1, (byte) 0xDA, (byte) 0xE8,
259                 (byte) 0x6F, (byte) 0x51, (byte) 0x05, (byte) 0xB2, (byte) 0xC9, (byte) 0x64,
260                 (byte) 0xDA, (byte) 0x5F, (byte) 0xD4, (byte) 0xAA, (byte) 0xFD, (byte) 0x67,
261                 (byte) 0xE0, (byte) 0x10, (byte) 0x2C, (byte) 0x1F, (byte) 0x03, (byte) 0x10,
262                 (byte) 0xD4, (byte) 0x4B, (byte) 0x20, (byte) 0x82, (byte) 0x2B, (byte) 0x04,
263                 (byte) 0xF9, (byte) 0x09, (byte) 0xAE, (byte) 0x28, (byte) 0x3D, (byte) 0x9B,
264                 (byte) 0xFF, (byte) 0x87, (byte) 0x76, (byte) 0xCD, (byte) 0xF0, (byte) 0x11,
265                 (byte) 0xB7, (byte) 0xEA, (byte) 0xE6, (byte) 0xCD, (byte) 0x60, (byte) 0xD3,
266                 (byte) 0x8C, (byte) 0x74, (byte) 0xD3, (byte) 0x45, (byte) 0x63, (byte) 0x69,
267                 (byte) 0x3F, (byte) 0x1D, (byte) 0x31, (byte) 0x25, (byte) 0x49, (byte) 0x97,
268                 (byte) 0x4B, (byte) 0x73, (byte) 0x34, (byte) 0x12, (byte) 0x73, (byte) 0x27,
269                 (byte) 0x4C, (byte) 0xDA, (byte) 0xF3, (byte) 0x08, (byte) 0xA8, (byte) 0xA9,
270                 (byte) 0x27, (byte) 0xE4, (byte) 0xB8, (byte) 0xD6, (byte) 0xB5, (byte) 0xC4,
271                 (byte) 0x18, (byte) 0xED, (byte) 0xBD, (byte) 0x6F, (byte) 0xA2, (byte) 0x36,
272                 (byte) 0xA2, (byte) 0x9C, (byte) 0x27, (byte) 0x62, (byte) 0x7F, (byte) 0x93,
273                 (byte) 0xD7, (byte) 0x52, (byte) 0xA9, (byte) 0x76, (byte) 0x55, (byte) 0x99,
274                 (byte) 0x00, (byte) 0x5B, (byte) 0xC2, (byte) 0xB9, (byte) 0x18, (byte) 0xAC,
275                 (byte) 0x6B, (byte) 0x83, (byte) 0x0D, (byte) 0xA1, (byte) 0xC5, (byte) 0x01,
276                 (byte) 0x1A, (byte) 0xE5, (byte) 0x4D, (byte) 0x2F, (byte) 0xCF, (byte) 0x5D,
277                 (byte) 0xB2, (byte) 0xE7, (byte) 0xC7, (byte) 0xCB, (byte) 0x2C, (byte) 0xFF,
278                 (byte) 0x51, (byte) 0x1B, (byte) 0x9D, (byte) 0xA4, (byte) 0x05, (byte) 0xEB,
279                 (byte) 0x17, (byte) 0xD8, (byte) 0x97, (byte) 0x9D, (byte) 0x0C, (byte) 0x59,
280                 (byte) 0x92, (byte) 0x8A, (byte) 0x03, (byte) 0x34, (byte) 0xFD, (byte) 0x16,
281                 (byte) 0x0F, (byte) 0x2A, (byte) 0xF9, (byte) 0x7D, (byte) 0xC3, (byte) 0x41,
282                 (byte) 0x0D, (byte) 0x06, (byte) 0x5A, (byte) 0x4B, (byte) 0x34, (byte) 0xD5,
283                 (byte) 0xF5, (byte) 0x09, (byte) 0x1C, (byte) 0xCE, (byte) 0xA7, (byte) 0x19,
284                 (byte) 0x6D, (byte) 0x04, (byte) 0x53, (byte) 0x71, (byte) 0xCC, (byte) 0x84,
285                 (byte) 0xA0, (byte) 0xB2, (byte) 0xA0, (byte) 0x68, (byte) 0xA3, (byte) 0x40,
286                 (byte) 0xC0, (byte) 0x67, (byte) 0x38, (byte) 0x96, (byte) 0x73, (byte) 0x2E,
287                 (byte) 0x8E, (byte) 0x2A, (byte) 0x9D, (byte) 0x56, (byte) 0xE9, (byte) 0xAC,
288                 (byte) 0xC7, (byte) 0xEC, (byte) 0x84, (byte) 0x7F, (byte) 0xFC, (byte) 0xE0,
289                 (byte) 0x69, (byte) 0x03, (byte) 0x8B, (byte) 0x48, (byte) 0x64, (byte) 0x76,
290                 (byte) 0x85, (byte) 0xA5, (byte) 0x10, (byte) 0xD9, (byte) 0x31, (byte) 0xC3,
291                 (byte) 0x8B, (byte) 0x07, (byte) 0x48, (byte) 0x62, (byte) 0xF6, (byte) 0x68,
292                 (byte) 0xF2, (byte) 0x96, (byte) 0xB2, (byte) 0x18, (byte) 0x5B, (byte) 0xFF,
293                 (byte) 0x6D, (byte) 0xD1, (byte) 0x6B, (byte) 0xF5, (byte) 0xFD, (byte) 0x81,
294                 (byte) 0xF1, (byte) 0xFD, (byte) 0x04, (byte) 0xF0, (byte) 0x9F, (byte) 0xB7,
295                 (byte) 0x08, (byte) 0x95, (byte) 0x57, (byte) 0x48, (byte) 0x07, (byte) 0x00,
296                 (byte) 0x52, (byte) 0xEC, (byte) 0x75, (byte) 0x91, (byte) 0x02, (byte) 0x11,
297                 (byte) 0xA3, (byte) 0x64, (byte) 0x26, (byte) 0xCA,
298         });
299 
300         AlgorithmParameterSpec spec = new DSAParameterSpec(p, q, g);
301         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
302                 .setAlias(TEST_ALIAS_1)
303                 .setKeyType("DSA")
304                 .setKeySize(2048)
305                 .setAlgorithmParameterSpec(spec)
306                 .setSubject(TEST_DN_1)
307                 .setSerialNumber(TEST_SERIAL_1)
308                 .setStartDate(NOW)
309                 .setEndDate(NOW_PLUS_10_YEARS)
310                 .build());
311 
312         final KeyPair pair = mGenerator.generateKeyPair();
313         assertNotNull("The KeyPair returned should not be null", pair);
314 
315         assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 2048, spec, TEST_DN_1, TEST_SERIAL_1, NOW,
316                 NOW_PLUS_10_YEARS);
317     }
318 
testKeyPairGenerator_GenerateKeyPair_EC_Unencrypted_Success()319     public void testKeyPairGenerator_GenerateKeyPair_EC_Unencrypted_Success() throws Exception {
320         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
321                 .setAlias(TEST_ALIAS_1)
322                 .setKeyType("EC")
323                 .setSubject(TEST_DN_1)
324                 .setSerialNumber(TEST_SERIAL_1)
325                 .setStartDate(NOW)
326                 .setEndDate(NOW_PLUS_10_YEARS)
327                 .build());
328 
329         final KeyPair pair = mGenerator.generateKeyPair();
330         assertNotNull("The KeyPair returned should not be null", pair);
331 
332         assertKeyPairCorrect(pair, TEST_ALIAS_1, "EC", 256, null, TEST_DN_1, TEST_SERIAL_1, NOW,
333                 NOW_PLUS_10_YEARS);
334     }
335 
testKeyPairGenerator_GenerateKeyPair_EC_P521_Unencrypted_Success()336     public void testKeyPairGenerator_GenerateKeyPair_EC_P521_Unencrypted_Success() throws Exception {
337         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
338                 .setAlias(TEST_ALIAS_1)
339                 .setKeyType("EC")
340                 .setKeySize(521)
341                 .setSubject(TEST_DN_1)
342                 .setSerialNumber(TEST_SERIAL_1)
343                 .setStartDate(NOW)
344                 .setEndDate(NOW_PLUS_10_YEARS)
345                 .build());
346 
347         final KeyPair pair = mGenerator.generateKeyPair();
348         assertNotNull("The KeyPair returned should not be null", pair);
349 
350         assertKeyPairCorrect(pair, TEST_ALIAS_1, "EC", 521, null, TEST_DN_1, TEST_SERIAL_1, NOW,
351                 NOW_PLUS_10_YEARS);
352     }
353 
testKeyPairGenerator_GenerateKeyPair_RSA_Unencrypted_Success()354     public void testKeyPairGenerator_GenerateKeyPair_RSA_Unencrypted_Success() throws Exception {
355         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
356                 .setAlias(TEST_ALIAS_1)
357                 .setSubject(TEST_DN_1)
358                 .setSerialNumber(TEST_SERIAL_1)
359                 .setStartDate(NOW)
360                 .setEndDate(NOW_PLUS_10_YEARS)
361                 .build());
362 
363         final KeyPair pair = mGenerator.generateKeyPair();
364         assertNotNull("The KeyPair returned should not be null", pair);
365 
366         assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
367                 NOW_PLUS_10_YEARS);
368     }
369 
testKeyPairGenerator_GenerateKeyPair_RSA_WithParams_Unencrypted_Success()370     public void testKeyPairGenerator_GenerateKeyPair_RSA_WithParams_Unencrypted_Success()
371             throws Exception {
372         AlgorithmParameterSpec spec = new RSAKeyGenParameterSpec(1024, BigInteger.valueOf(3L));
373         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
374                 .setAlias(TEST_ALIAS_1)
375                 .setKeySize(1024)
376                 .setAlgorithmParameterSpec(spec)
377                 .setSubject(TEST_DN_1)
378                 .setSerialNumber(TEST_SERIAL_1)
379                 .setStartDate(NOW)
380                 .setEndDate(NOW_PLUS_10_YEARS)
381                 .build());
382 
383         final KeyPair pair = mGenerator.generateKeyPair();
384         assertNotNull("The KeyPair returned should not be null", pair);
385 
386         assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 1024, spec, TEST_DN_1, TEST_SERIAL_1, NOW,
387                 NOW_PLUS_10_YEARS);
388     }
389 
testKeyPairGenerator_GenerateKeyPair_Replaced_Success()390     public void testKeyPairGenerator_GenerateKeyPair_Replaced_Success() throws Exception {
391         // Generate the first key
392         {
393             mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
394                     .setAlias(TEST_ALIAS_1)
395                     .setSubject(TEST_DN_1)
396                     .setSerialNumber(TEST_SERIAL_1)
397                     .setStartDate(NOW)
398                     .setEndDate(NOW_PLUS_10_YEARS)
399                     .build());
400             final KeyPair pair1 = mGenerator.generateKeyPair();
401             assertNotNull("The KeyPair returned should not be null", pair1);
402             assertKeyPairCorrect(pair1, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1,
403                     NOW, NOW_PLUS_10_YEARS);
404         }
405 
406         // Replace the original key
407         {
408             mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
409                     .setAlias(TEST_ALIAS_2)
410                     .setSubject(TEST_DN_2)
411                     .setSerialNumber(TEST_SERIAL_2)
412                     .setStartDate(NOW)
413                     .setEndDate(NOW_PLUS_10_YEARS)
414                     .build());
415             final KeyPair pair2 = mGenerator.generateKeyPair();
416             assertNotNull("The KeyPair returned should not be null", pair2);
417             assertKeyPairCorrect(pair2, TEST_ALIAS_2, "RSA", 2048, null, TEST_DN_2, TEST_SERIAL_2,
418                     NOW, NOW_PLUS_10_YEARS);
419         }
420     }
421 
testKeyPairGenerator_GenerateKeyPair_Replaced_UnencryptedToEncrypted_Success()422     public void testKeyPairGenerator_GenerateKeyPair_Replaced_UnencryptedToEncrypted_Success()
423             throws Exception {
424         // Generate the first key
425         {
426             mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
427                     .setAlias(TEST_ALIAS_1)
428                     .setSubject(TEST_DN_1)
429                     .setSerialNumber(TEST_SERIAL_1)
430                     .setStartDate(NOW)
431                     .setEndDate(NOW_PLUS_10_YEARS)
432                     .build());
433             final KeyPair pair1 = mGenerator.generateKeyPair();
434             assertNotNull("The KeyPair returned should not be null", pair1);
435             assertKeyPairCorrect(pair1, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1,
436                     NOW, NOW_PLUS_10_YEARS);
437         }
438 
439         // Attempt to replace previous key
440         {
441             mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
442                     .setAlias(TEST_ALIAS_1)
443                     .setSubject(TEST_DN_2)
444                     .setSerialNumber(TEST_SERIAL_2)
445                     .setStartDate(NOW)
446                     .setEndDate(NOW_PLUS_10_YEARS)
447                     .setEncryptionRequired()
448                     .build());
449             try {
450                 mGenerator.generateKeyPair();
451                 fail("Should not be able to generate encrypted key while not initialized");
452             } catch (IllegalStateException expected) {
453             }
454 
455             assertTrue(mAndroidKeyStore.password("1111"));
456             assertTrue(mAndroidKeyStore.isUnlocked());
457 
458             final KeyPair pair2 = mGenerator.generateKeyPair();
459             assertNotNull("The KeyPair returned should not be null", pair2);
460             assertKeyPairCorrect(pair2, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_2, TEST_SERIAL_2,
461                     NOW, NOW_PLUS_10_YEARS);
462         }
463     }
464 
assertKeyPairCorrect(KeyPair pair, String alias, String keyType, int keySize, AlgorithmParameterSpec spec, X500Principal dn, BigInteger serial, Date start, Date end)465     private void assertKeyPairCorrect(KeyPair pair, String alias, String keyType, int keySize,
466             AlgorithmParameterSpec spec, X500Principal dn, BigInteger serial, Date start, Date end)
467             throws Exception {
468         final PublicKey pubKey = pair.getPublic();
469         assertNotNull("The PublicKey for the KeyPair should be not null", pubKey);
470         assertEquals(keyType, pubKey.getAlgorithm());
471 
472         if ("DSA".equalsIgnoreCase(keyType)) {
473             DSAPublicKey dsaPubKey = (DSAPublicKey) pubKey;
474             DSAParams actualParams = dsaPubKey.getParams();
475             assertEquals(keySize, (actualParams.getP().bitLength() + 7) & ~7);
476             if (spec != null) {
477                 DSAParameterSpec expectedParams = (DSAParameterSpec) spec;
478                 assertEquals(expectedParams.getP(), actualParams.getP());
479                 assertEquals(expectedParams.getQ(), actualParams.getQ());
480                 assertEquals(expectedParams.getG(), actualParams.getG());
481             }
482         } else if ("EC".equalsIgnoreCase(keyType)) {
483             assertEquals("Curve should be what was specified during initialization", keySize,
484                     ((ECPublicKey) pubKey).getParams().getCurve().getField().getFieldSize());
485         } else if ("RSA".equalsIgnoreCase(keyType)) {
486             RSAPublicKey rsaPubKey = (RSAPublicKey) pubKey;
487             assertEquals("Modulus size should be what is specified during initialization",
488                     (keySize + 7) & ~7, (rsaPubKey.getModulus().bitLength() + 7) & ~7);
489             if (spec != null) {
490                 RSAKeyGenParameterSpec params = (RSAKeyGenParameterSpec) spec;
491                 assertEquals((keySize + 7) & ~7, (params.getKeysize() + 7) & ~7);
492                 assertEquals(params.getPublicExponent(), rsaPubKey.getPublicExponent());
493             }
494         }
495 
496         final PrivateKey privKey = pair.getPrivate();
497         assertNotNull("The PrivateKey for the KeyPair should be not null", privKey);
498         assertEquals(keyType, privKey.getAlgorithm());
499 
500         final byte[] userCertBytes = mAndroidKeyStore.get(Credentials.USER_CERTIFICATE + alias);
501         assertNotNull("The user certificate should exist for the generated entry", userCertBytes);
502 
503         final CertificateFactory cf = CertificateFactory.getInstance("X.509");
504         final Certificate userCert = cf
505                 .generateCertificate(new ByteArrayInputStream(userCertBytes));
506 
507         assertTrue("Certificate should be in X.509 format", userCert instanceof X509Certificate);
508 
509         final X509Certificate x509userCert = (X509Certificate) userCert;
510 
511         assertEquals("PublicKey used to sign certificate should match one returned in KeyPair",
512                 pubKey, x509userCert.getPublicKey());
513 
514         assertEquals("The Subject DN should be the one passed into the params", dn,
515                 x509userCert.getSubjectDN());
516 
517         assertEquals("The Issuer DN should be the same as the Subject DN", dn,
518                 x509userCert.getIssuerDN());
519 
520         assertEquals("The Serial should be the one passed into the params", serial,
521                 x509userCert.getSerialNumber());
522 
523         assertDateEquals("The notBefore date should be the one passed into the params", start,
524                 x509userCert.getNotBefore());
525 
526         assertDateEquals("The notAfter date should be the one passed into the params", end,
527                 x509userCert.getNotAfter());
528 
529         x509userCert.verify(pubKey);
530 
531         final byte[] caCerts = mAndroidKeyStore.get(Credentials.CA_CERTIFICATE + alias);
532         assertNull("A list of CA certificates should not exist for the generated entry", caCerts);
533 
534         final byte[] pubKeyBytes = mAndroidKeyStore.getPubkey(Credentials.USER_PRIVATE_KEY + alias);
535         assertNotNull("The keystore should return the public key for the generated key",
536                 pubKeyBytes);
537     }
538 
assertDateEquals(String message, Date date1, Date date2)539     private static void assertDateEquals(String message, Date date1, Date date2) throws Exception {
540         SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss");
541 
542         String result1 = formatter.format(date1);
543         String result2 = formatter.format(date2);
544 
545         assertEquals(message, result1, result2);
546     }
547 }
548