1 /*
2  * Copyright 2013 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.keystore.cts;
18 
19 import android.security.KeyPairGeneratorSpec;
20 import android.security.keystore.KeyGenParameterSpec;
21 import android.security.keystore.KeyInfo;
22 import android.security.keystore.KeyProperties;
23 import android.test.AndroidTestCase;
24 import android.test.MoreAsserts;
25 
26 import java.math.BigInteger;
27 import java.net.InetAddress;
28 import java.net.Socket;
29 import java.security.InvalidAlgorithmParameterException;
30 import java.security.KeyPair;
31 import java.security.KeyPairGenerator;
32 import java.security.KeyStore;
33 import java.security.NoSuchAlgorithmException;
34 import java.security.NoSuchProviderException;
35 import java.security.Principal;
36 import java.security.PrivateKey;
37 import java.security.Provider;
38 import java.security.SecureRandom;
39 import java.security.Security;
40 import java.security.Provider.Service;
41 import java.security.cert.Certificate;
42 import java.security.cert.X509Certificate;
43 import java.security.interfaces.ECKey;
44 import java.security.interfaces.ECPublicKey;
45 import java.security.interfaces.RSAPublicKey;
46 import java.security.spec.AlgorithmParameterSpec;
47 import java.security.spec.ECGenParameterSpec;
48 import java.security.spec.ECParameterSpec;
49 import java.security.spec.RSAKeyGenParameterSpec;
50 import java.text.SimpleDateFormat;
51 import java.util.ArrayList;
52 import java.util.Arrays;
53 import java.util.Date;
54 import java.util.HashSet;
55 import java.util.List;
56 import java.util.Locale;
57 import java.util.Map;
58 import java.util.Set;
59 import java.util.TreeMap;
60 import java.util.concurrent.Callable;
61 import java.util.concurrent.ExecutorService;
62 import java.util.concurrent.Executors;
63 import java.util.concurrent.Future;
64 import java.text.DecimalFormatSymbols;
65 
66 import javax.net.ssl.KeyManager;
67 import javax.net.ssl.SSLContext;
68 import javax.net.ssl.SSLServerSocket;
69 import javax.net.ssl.SSLSocket;
70 import javax.net.ssl.X509ExtendedKeyManager;
71 import javax.security.auth.x500.X500Principal;
72 
73 import libcore.java.security.TestKeyStore;
74 import libcore.javax.net.ssl.TestKeyManager;
75 import libcore.javax.net.ssl.TestSSLContext;
76 
77 public class KeyPairGeneratorTest extends AndroidTestCase {
78     private KeyStore mKeyStore;
79 
80     private CountingSecureRandom mRng;
81 
82     private static final String TEST_ALIAS_1 = "test1";
83 
84     private static final String TEST_ALIAS_2 = "test2";
85 
86     private static final String TEST_ALIAS_3 = "test3";
87 
88     private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1");
89 
90     private static final X500Principal TEST_DN_2 = new X500Principal("CN=test2");
91 
92     private static final BigInteger TEST_SERIAL_1 = BigInteger.ONE;
93 
94     private static final BigInteger TEST_SERIAL_2 = BigInteger.valueOf(2L);
95 
96     private static final long NOW_MILLIS = System.currentTimeMillis();
97 
98     /* We have to round this off because X509v3 doesn't store milliseconds. */
99     private static final Date NOW = new Date(NOW_MILLIS - (NOW_MILLIS % 1000L));
100 
101     @SuppressWarnings("deprecation")
102     private static final Date NOW_PLUS_10_YEARS = new Date(NOW.getYear() + 10, 0, 1);
103 
104     private static final long DAY_IN_MILLIS = 1000 * 60 * 60 * 24;
105 
106     private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
107     private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
108     private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1970
109     private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
110 
111     private static final String EXPECTED_PROVIDER_NAME = TestUtils.EXPECTED_PROVIDER_NAME;
112 
113     private static final String[] EXPECTED_ALGORITHMS = {
114         "EC",
115         "RSA",
116     };
117 
118     private static final Map<String, Integer> DEFAULT_KEY_SIZES =
119             new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
120     static {
121         DEFAULT_KEY_SIZES.put("EC", 256);
122         DEFAULT_KEY_SIZES.put("RSA", 2048);
123     }
124 
125     @Override
setUp()126     protected void setUp() throws Exception {
127         super.setUp();
128         mRng = new CountingSecureRandom();
129         mKeyStore = KeyStore.getInstance("AndroidKeyStore");
130         mKeyStore.load(null, null);
131     }
132 
testAlgorithmList()133     public void testAlgorithmList() {
134         // Assert that Android Keystore Provider exposes exactly the expected KeyPairGenerator
135         // algorithms. We don't care whether the algorithms are exposed via aliases, as long as
136         // canonical names of algorithms are accepted. If the Provider exposes extraneous
137         // algorithms, it'll be caught because it'll have to expose at least one Service for such an
138         // algorithm, and this Service's algorithm will not be in the expected set.
139 
140         Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
141         Set<Service> services = provider.getServices();
142         Set<String> actualAlgsLowerCase = new HashSet<String>();
143         Set<String> expectedAlgsLowerCase = new HashSet<String>(
144                 Arrays.asList(TestUtils.toLowerCase(EXPECTED_ALGORITHMS)));
145         for (Service service : services) {
146             if ("KeyPairGenerator".equalsIgnoreCase(service.getType())) {
147                 String algLowerCase = service.getAlgorithm().toLowerCase(Locale.US);
148                 actualAlgsLowerCase.add(algLowerCase);
149             }
150         }
151 
152         TestUtils.assertContentsInAnyOrder(actualAlgsLowerCase,
153                 expectedAlgsLowerCase.toArray(new String[0]));
154     }
155 
testInitialize_LegacySpec()156     public void testInitialize_LegacySpec() throws Exception {
157         @SuppressWarnings("deprecation")
158         KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(getContext())
159                 .setAlias(TEST_ALIAS_1)
160                 .setSubject(TEST_DN_1)
161                 .setSerialNumber(TEST_SERIAL_1)
162                 .setStartDate(NOW)
163                 .setEndDate(NOW_PLUS_10_YEARS)
164                 .build();
165         getRsaGenerator().initialize(spec);
166         getRsaGenerator().initialize(spec, new SecureRandom());
167 
168         getEcGenerator().initialize(spec);
169         getEcGenerator().initialize(spec, new SecureRandom());
170     }
171 
testInitialize_ModernSpec()172     public void testInitialize_ModernSpec() throws Exception {
173         KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
174                 TEST_ALIAS_1,
175                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
176                 .build();
177         getRsaGenerator().initialize(spec);
178         getRsaGenerator().initialize(spec, new SecureRandom());
179 
180         getEcGenerator().initialize(spec);
181         getEcGenerator().initialize(spec, new SecureRandom());
182     }
183 
testInitialize_KeySizeOnly()184     public void testInitialize_KeySizeOnly() throws Exception {
185         try {
186             getRsaGenerator().initialize(1024);
187             fail("KeyPairGenerator should not support setting the key size");
188         } catch (IllegalArgumentException success) {
189         }
190 
191         try {
192             getEcGenerator().initialize(256);
193             fail("KeyPairGenerator should not support setting the key size");
194         } catch (IllegalArgumentException success) {
195         }
196     }
197 
testInitialize_KeySizeAndSecureRandomOnly()198     public void testInitialize_KeySizeAndSecureRandomOnly()
199             throws Exception {
200         try {
201             getRsaGenerator().initialize(1024, new SecureRandom());
202             fail("KeyPairGenerator should not support setting the key size");
203         } catch (IllegalArgumentException success) {
204         }
205 
206         try {
207             getEcGenerator().initialize(1024, new SecureRandom());
208             fail("KeyPairGenerator should not support setting the key size");
209         } catch (IllegalArgumentException success) {
210         }
211     }
212 
testDefaultKeySize()213     public void testDefaultKeySize() throws Exception {
214         for (String algorithm : EXPECTED_ALGORITHMS) {
215             try {
216                 int expectedSizeBits = DEFAULT_KEY_SIZES.get(algorithm);
217                 KeyPairGenerator generator = getGenerator(algorithm);
218                 generator.initialize(getWorkingSpec().build());
219                 KeyPair keyPair = generator.generateKeyPair();
220                 assertEquals(expectedSizeBits,
221                         TestUtils.getKeyInfo(keyPair.getPrivate()).getKeySize());
222             } catch (Throwable e) {
223                 throw new RuntimeException("Failed for " + algorithm, e);
224             }
225         }
226     }
227 
testInitWithUnknownBlockModeFails()228     public void testInitWithUnknownBlockModeFails() {
229         for (String algorithm : EXPECTED_ALGORITHMS) {
230             try {
231                 KeyPairGenerator generator = getGenerator(algorithm);
232                 try {
233                     generator.initialize(getWorkingSpec().setBlockModes("weird").build());
234                     fail();
235                 } catch (InvalidAlgorithmParameterException expected) {}
236             } catch (Throwable e) {
237                 throw new RuntimeException("Failed for " + algorithm, e);
238             }
239         }
240     }
241 
testInitWithUnknownEncryptionPaddingFails()242     public void testInitWithUnknownEncryptionPaddingFails() {
243         for (String algorithm : EXPECTED_ALGORITHMS) {
244             try {
245                 KeyPairGenerator generator = getGenerator(algorithm);
246                 try {
247                     generator.initialize(getWorkingSpec().setEncryptionPaddings("weird").build());
248                     fail();
249                 } catch (InvalidAlgorithmParameterException expected) {}
250             } catch (Throwable e) {
251                 throw new RuntimeException("Failed for " + algorithm, e);
252             }
253         }
254     }
255 
testInitWithUnknownSignaturePaddingFails()256     public void testInitWithUnknownSignaturePaddingFails() {
257         for (String algorithm : EXPECTED_ALGORITHMS) {
258             try {
259                 KeyPairGenerator generator = getGenerator(algorithm);
260                 try {
261                     generator.initialize(getWorkingSpec().setSignaturePaddings("weird").build());
262                     fail();
263                 } catch (InvalidAlgorithmParameterException expected) {}
264             } catch (Throwable e) {
265                 throw new RuntimeException("Failed for " + algorithm, e);
266             }
267         }
268     }
269 
testInitWithUnknownDigestFails()270     public void testInitWithUnknownDigestFails() {
271         for (String algorithm : EXPECTED_ALGORITHMS) {
272             try {
273                 KeyPairGenerator generator = getGenerator(algorithm);
274                 try {
275                     generator.initialize(getWorkingSpec().setDigests("weird").build());
276                     fail();
277                 } catch (InvalidAlgorithmParameterException expected) {}
278             } catch (Throwable e) {
279                 throw new RuntimeException("Failed for " + algorithm, e);
280             }
281         }
282     }
283 
testInitRandomizedEncryptionRequiredButViolatedFails()284     public void testInitRandomizedEncryptionRequiredButViolatedFails() throws Exception {
285         for (String algorithm : EXPECTED_ALGORITHMS) {
286             try {
287                 KeyPairGenerator generator = getGenerator(algorithm);
288                 try {
289                     generator.initialize(getWorkingSpec(
290                             KeyProperties.PURPOSE_ENCRYPT)
291                             .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
292                             .build());
293                     fail();
294                 } catch (InvalidAlgorithmParameterException expected) {}
295             } catch (Throwable e) {
296                 throw new RuntimeException("Failed for " + algorithm, e);
297             }
298         }
299     }
300 
testGenerateHonorsRequestedAuthorizations()301     public void testGenerateHonorsRequestedAuthorizations() throws Exception {
302         Date keyValidityStart = new Date(System.currentTimeMillis() - TestUtils.DAY_IN_MILLIS);
303         Date keyValidityForOriginationEnd =
304                 new Date(System.currentTimeMillis() + TestUtils.DAY_IN_MILLIS);
305         Date keyValidityForConsumptionEnd =
306                 new Date(System.currentTimeMillis() + 3 * TestUtils.DAY_IN_MILLIS);
307         for (String algorithm : EXPECTED_ALGORITHMS) {
308             try {
309                 String[] blockModes =
310                         new String[] {KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC};
311                 String[] encryptionPaddings =
312                         new String[] {KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
313                                 KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1};
314                 String[] digests =
315                         new String[] {KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA1};
316                 int purposes = KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT;
317                 KeyPairGenerator generator = getGenerator(algorithm);
318                 generator.initialize(getWorkingSpec(purposes)
319                         .setBlockModes(blockModes)
320                         .setEncryptionPaddings(encryptionPaddings)
321                         .setDigests(digests)
322                         .setKeyValidityStart(keyValidityStart)
323                         .setKeyValidityForOriginationEnd(keyValidityForOriginationEnd)
324                         .setKeyValidityForConsumptionEnd(keyValidityForConsumptionEnd)
325                         .build());
326                 KeyPair keyPair = generator.generateKeyPair();
327                 assertEquals(algorithm, keyPair.getPrivate().getAlgorithm());
328 
329                 KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
330                 assertEquals(purposes, keyInfo.getPurposes());
331                 TestUtils.assertContentsInAnyOrder(
332                         Arrays.asList(keyInfo.getBlockModes()), blockModes);
333 
334                 List<String> actualEncryptionPaddings =
335                         new ArrayList<String>(Arrays.asList(keyInfo.getEncryptionPaddings()));
336                 // Keystore may have added ENCRYPTION_PADDING_NONE to allow software OAEP
337                 actualEncryptionPaddings.remove(KeyProperties.ENCRYPTION_PADDING_NONE);
338                 TestUtils.assertContentsInAnyOrder(
339                         actualEncryptionPaddings, encryptionPaddings);
340 
341                 List<String> actualDigests =
342                         new ArrayList<String>(Arrays.asList(keyInfo.getDigests()));
343                 // Keystore may have added DIGEST_NONE, to allow software digesting.
344                 actualDigests.remove(KeyProperties.DIGEST_NONE);
345                 TestUtils.assertContentsInAnyOrder(actualDigests, digests);
346 
347                 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
348                 assertEquals(keyValidityStart, keyInfo.getKeyValidityStart());
349                 assertEquals(keyValidityForOriginationEnd,
350                         keyInfo.getKeyValidityForOriginationEnd());
351                 assertEquals(keyValidityForConsumptionEnd,
352                         keyInfo.getKeyValidityForConsumptionEnd());
353                 assertFalse(keyInfo.isUserAuthenticationRequired());
354                 assertFalse(keyInfo.isUserAuthenticationRequirementEnforcedBySecureHardware());
355             } catch (Throwable e) {
356                 throw new RuntimeException("Failed for " + algorithm, e);
357             }
358         }
359     }
360 
361     @SuppressWarnings("deprecation")
testGenerate_EC_LegacySpec()362     public void testGenerate_EC_LegacySpec() throws Exception {
363         // There are three legacy ways to generate an EC key pair using Android Keystore
364         // KeyPairGenerator:
365         // 1. Use an RSA KeyPairGenerator and specify EC as key type,
366         // 2. Use an EC KeyPairGenerator and specify EC as key type,
367         // 3. Use an EC KeyPairGenerator and leave the key type unspecified.
368         //
369         // We test all three.
370 
371         // 1. Use an RSA KeyPairGenerator and specify EC as key type.
372         KeyPairGenerator generator = getRsaGenerator();
373         generator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
374                 .setAlias(TEST_ALIAS_1)
375                 .setKeyType("EC")
376                 .setSubject(TEST_DN_1)
377                 .setSerialNumber(TEST_SERIAL_1)
378                 .setStartDate(NOW)
379                 .setEndDate(NOW_PLUS_10_YEARS)
380                 .build());
381         KeyPair keyPair = generator.generateKeyPair();
382         assertGeneratedKeyPairAndSelfSignedCertificate(
383                 keyPair,
384                 TEST_ALIAS_1,
385                 "EC",
386                 256,
387                 TEST_DN_1,
388                 TEST_SERIAL_1, NOW,
389                 NOW_PLUS_10_YEARS);
390         assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1);
391         assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1);
392         TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
393                 ECCurves.NIST_P_256_SPEC, ((ECPublicKey) keyPair.getPublic()).getParams());
394         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
395         assertEquals(256, keyInfo.getKeySize());
396         assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
397         assertOneOf(keyInfo.getOrigin(),
398                 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
399         assertEquals(
400                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY,
401                 keyInfo.getPurposes());
402         assertFalse(keyInfo.isUserAuthenticationRequired());
403         assertEquals(null, keyInfo.getKeyValidityStart());
404         assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
405         assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
406         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
407         MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
408                 KeyProperties.DIGEST_NONE,
409                 KeyProperties.DIGEST_SHA1,
410                 KeyProperties.DIGEST_SHA224,
411                 KeyProperties.DIGEST_SHA256,
412                 KeyProperties.DIGEST_SHA384,
413                 KeyProperties.DIGEST_SHA512);
414         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
415         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
416 
417         // 2. Use an EC KeyPairGenerator and specify EC as key type.
418         generator = getEcGenerator();
419         generator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
420                 .setAlias(TEST_ALIAS_2)
421                 .setKeyType("EC")
422                 .setSubject(TEST_DN_1)
423                 .setSerialNumber(TEST_SERIAL_1)
424                 .setStartDate(NOW)
425                 .setEndDate(NOW_PLUS_10_YEARS)
426                 .build());
427         keyPair = generator.generateKeyPair();
428         assertGeneratedKeyPairAndSelfSignedCertificate(
429                 keyPair,
430                 TEST_ALIAS_2,
431                 "EC",
432                 256,
433                 TEST_DN_1,
434                 TEST_SERIAL_1,
435                 NOW,
436                 NOW_PLUS_10_YEARS);
437         assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_2);
438         assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_2);
439         TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
440                 ECCurves.NIST_P_256_SPEC, ((ECPublicKey) keyPair.getPublic()).getParams());
441         keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
442         assertEquals(256, keyInfo.getKeySize());
443         assertEquals(TEST_ALIAS_2, keyInfo.getKeystoreAlias());
444         assertOneOf(keyInfo.getOrigin(),
445                 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
446         assertEquals(
447                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY,
448                 keyInfo.getPurposes());
449         assertFalse(keyInfo.isUserAuthenticationRequired());
450         assertEquals(null, keyInfo.getKeyValidityStart());
451         assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
452         assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
453         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
454         MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
455                 KeyProperties.DIGEST_NONE,
456                 KeyProperties.DIGEST_SHA1,
457                 KeyProperties.DIGEST_SHA224,
458                 KeyProperties.DIGEST_SHA256,
459                 KeyProperties.DIGEST_SHA384,
460                 KeyProperties.DIGEST_SHA512);
461         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
462         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
463 
464         // 3. Use an EC KeyPairGenerator and leave the key type unspecified.
465         generator = getEcGenerator();
466         generator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
467                 .setAlias(TEST_ALIAS_3)
468                 .setSubject(TEST_DN_1)
469                 .setSerialNumber(TEST_SERIAL_1)
470                 .setStartDate(NOW)
471                 .setEndDate(NOW_PLUS_10_YEARS)
472                 .build());
473         keyPair = generator.generateKeyPair();
474         assertGeneratedKeyPairAndSelfSignedCertificate(
475                 keyPair,
476                 TEST_ALIAS_3,
477                 "EC",
478                 256,
479                 TEST_DN_1,
480                 TEST_SERIAL_1,
481                 NOW,
482                 NOW_PLUS_10_YEARS);
483         assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_3);
484         assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_3);
485         TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
486                 ECCurves.NIST_P_256_SPEC, ((ECPublicKey) keyPair.getPublic()).getParams());
487         keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
488         assertEquals(256, keyInfo.getKeySize());
489         assertEquals(TEST_ALIAS_3, keyInfo.getKeystoreAlias());
490         assertOneOf(keyInfo.getOrigin(),
491                 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
492         assertEquals(
493                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY,
494                 keyInfo.getPurposes());
495         assertFalse(keyInfo.isUserAuthenticationRequired());
496         assertEquals(null, keyInfo.getKeyValidityStart());
497         assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
498         assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
499         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
500         MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
501                 KeyProperties.DIGEST_NONE,
502                 KeyProperties.DIGEST_SHA1,
503                 KeyProperties.DIGEST_SHA224,
504                 KeyProperties.DIGEST_SHA256,
505                 KeyProperties.DIGEST_SHA384,
506                 KeyProperties.DIGEST_SHA512);
507         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
508         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
509     }
510 
testGenerate_RSA_LegacySpec()511     public void testGenerate_RSA_LegacySpec() throws Exception {
512         KeyPairGenerator generator = getRsaGenerator();
513         generator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
514                 .setAlias(TEST_ALIAS_1)
515                 .setSubject(TEST_DN_1)
516                 .setSerialNumber(TEST_SERIAL_1)
517                 .setStartDate(NOW)
518                 .setEndDate(NOW_PLUS_10_YEARS)
519                 .build());
520         KeyPair keyPair = generator.generateKeyPair();
521         assertGeneratedKeyPairAndSelfSignedCertificate(
522                 keyPair,
523                 TEST_ALIAS_1,
524                 "RSA",
525                 2048,
526                 TEST_DN_1,
527                 TEST_SERIAL_1,
528                 NOW,
529                 NOW_PLUS_10_YEARS);
530         assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1);
531         assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1);
532         assertEquals(RSAKeyGenParameterSpec.F4,
533                 ((RSAPublicKey) keyPair.getPublic()).getPublicExponent());
534         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
535         assertEquals(2048, keyInfo.getKeySize());
536         assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
537         assertOneOf(keyInfo.getOrigin(),
538                 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
539         assertEquals(
540                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
541                         | KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
542                 keyInfo.getPurposes());
543         assertFalse(keyInfo.isUserAuthenticationRequired());
544         assertEquals(null, keyInfo.getKeyValidityStart());
545         assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
546         assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
547         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
548         MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
549                 KeyProperties.DIGEST_NONE,
550                 KeyProperties.DIGEST_MD5,
551                 KeyProperties.DIGEST_SHA1,
552                 KeyProperties.DIGEST_SHA224,
553                 KeyProperties.DIGEST_SHA256,
554                 KeyProperties.DIGEST_SHA384,
555                 KeyProperties.DIGEST_SHA512);
556         MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getEncryptionPaddings()),
557                 KeyProperties.ENCRYPTION_PADDING_NONE,
558                 KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1,
559                 KeyProperties.ENCRYPTION_PADDING_RSA_OAEP);
560         MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getSignaturePaddings()),
561                 KeyProperties.SIGNATURE_PADDING_RSA_PSS,
562                 KeyProperties.SIGNATURE_PADDING_RSA_PKCS1);
563     }
564 
testGenerate_ReplacesOldEntryWithSameAlias()565     public void testGenerate_ReplacesOldEntryWithSameAlias()
566             throws Exception {
567         // Generate the first key
568         {
569             KeyPairGenerator generator = getRsaGenerator();
570             generator.initialize(new KeyGenParameterSpec.Builder(
571                     TEST_ALIAS_1,
572                     KeyProperties.PURPOSE_SIGN
573                             | KeyProperties.PURPOSE_VERIFY
574                             | KeyProperties.PURPOSE_ENCRYPT
575                             | KeyProperties.PURPOSE_DECRYPT)
576                     .setDigests(KeyProperties.DIGEST_NONE)
577                     .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
578                     .setCertificateSubject(TEST_DN_1)
579                     .setCertificateSerialNumber(TEST_SERIAL_1)
580                     .setCertificateNotBefore(NOW)
581                     .setCertificateNotAfter(NOW_PLUS_10_YEARS)
582                     .build());
583             assertGeneratedKeyPairAndSelfSignedCertificate(
584                     generator.generateKeyPair(),
585                     TEST_ALIAS_1,
586                     "RSA",
587                     2048,
588                     TEST_DN_1,
589                     TEST_SERIAL_1,
590                     NOW,
591                     NOW_PLUS_10_YEARS);
592         }
593 
594         // Replace the original key
595         {
596             KeyPairGenerator generator = getRsaGenerator();
597             generator.initialize(new KeyGenParameterSpec.Builder(
598                     TEST_ALIAS_1,
599                     KeyProperties.PURPOSE_SIGN
600                             | KeyProperties.PURPOSE_VERIFY
601                             | KeyProperties.PURPOSE_ENCRYPT
602                             | KeyProperties.PURPOSE_DECRYPT)
603                     .setDigests(KeyProperties.DIGEST_NONE)
604                     .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
605                     .setCertificateSubject(TEST_DN_2)
606                     .setCertificateSerialNumber(TEST_SERIAL_2)
607                     .setCertificateNotBefore(NOW)
608                     .setCertificateNotAfter(NOW_PLUS_10_YEARS)
609                     .build());
610             assertGeneratedKeyPairAndSelfSignedCertificate(
611                     generator.generateKeyPair(),
612                     TEST_ALIAS_1,
613                     "RSA",
614                     2048,
615                     TEST_DN_2,
616                     TEST_SERIAL_2,
617                     NOW,
618                     NOW_PLUS_10_YEARS);
619         }
620     }
621 
testGenerate_DoesNotReplaceOtherEntries()622     public void testGenerate_DoesNotReplaceOtherEntries()
623             throws Exception {
624         // Generate the first key
625         KeyPairGenerator generator = getRsaGenerator();
626         generator.initialize(new KeyGenParameterSpec.Builder(
627                 TEST_ALIAS_1,
628                 KeyProperties.PURPOSE_SIGN
629                         | KeyProperties.PURPOSE_VERIFY
630                         | KeyProperties.PURPOSE_ENCRYPT
631                         | KeyProperties.PURPOSE_DECRYPT)
632                 .setDigests(KeyProperties.DIGEST_NONE)
633                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
634                 .setCertificateSubject(TEST_DN_1)
635                 .setCertificateSerialNumber(TEST_SERIAL_1)
636                 .setCertificateNotBefore(NOW)
637                 .setCertificateNotAfter(NOW_PLUS_10_YEARS)
638                 .build());
639         KeyPair keyPair1 = generator.generateKeyPair();
640         assertGeneratedKeyPairAndSelfSignedCertificate(
641                 keyPair1,
642                 TEST_ALIAS_1,
643                 "RSA",
644                 2048,
645                 TEST_DN_1,
646                 TEST_SERIAL_1,
647                 NOW,
648                 NOW_PLUS_10_YEARS);
649 
650         // Generate the second key
651         generator.initialize(new KeyGenParameterSpec.Builder(
652                 TEST_ALIAS_2,
653                 KeyProperties.PURPOSE_SIGN
654                         | KeyProperties.PURPOSE_VERIFY
655                         | KeyProperties.PURPOSE_ENCRYPT
656                         | KeyProperties.PURPOSE_DECRYPT)
657                 .setDigests(KeyProperties.DIGEST_NONE)
658                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
659                 .setCertificateSubject(TEST_DN_2)
660                 .setCertificateSerialNumber(TEST_SERIAL_2)
661                 .setCertificateNotBefore(NOW)
662                 .setCertificateNotAfter(NOW_PLUS_10_YEARS)
663                 .build());
664         KeyPair keyPair2 = generator.generateKeyPair();
665         assertGeneratedKeyPairAndSelfSignedCertificate(
666                 keyPair2,
667                 TEST_ALIAS_2,
668                 "RSA",
669                 2048,
670                 TEST_DN_2,
671                 TEST_SERIAL_2,
672                 NOW,
673                 NOW_PLUS_10_YEARS);
674 
675         // Check the first key pair again
676         assertGeneratedKeyPairAndSelfSignedCertificate(
677                 keyPair1,
678                 TEST_ALIAS_1,
679                 "RSA",
680                 2048,
681                 TEST_DN_1,
682                 TEST_SERIAL_1,
683                 NOW,
684                 NOW_PLUS_10_YEARS);
685     }
686 
testGenerate_EC_ModernSpec_Defaults()687     public void testGenerate_EC_ModernSpec_Defaults() throws Exception {
688         KeyPairGenerator generator = getEcGenerator();
689         generator.initialize(new KeyGenParameterSpec.Builder(
690                 TEST_ALIAS_1,
691                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
692                 .build());
693         KeyPair keyPair = generator.generateKeyPair();
694         assertGeneratedKeyPairAndSelfSignedCertificate(
695                 keyPair,
696                 TEST_ALIAS_1,
697                 "EC",
698                 256,
699                 DEFAULT_CERT_SUBJECT,
700                 DEFAULT_CERT_SERIAL_NUMBER,
701                 DEFAULT_CERT_NOT_BEFORE,
702                 DEFAULT_CERT_NOT_AFTER);
703         TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
704                 ECCurves.NIST_P_256_SPEC, ((ECKey) keyPair.getPrivate()).getParams());
705         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
706         assertEquals(256, keyInfo.getKeySize());
707         assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
708         assertOneOf(keyInfo.getOrigin(),
709                 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
710         assertEquals(
711                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY, keyInfo.getPurposes());
712         assertFalse(keyInfo.isUserAuthenticationRequired());
713         assertEquals(null, keyInfo.getKeyValidityStart());
714         assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
715         assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
716         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
717         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getDigests()));
718         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
719         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
720     }
721 
testGenerate_RSA_ModernSpec_Defaults()722     public void testGenerate_RSA_ModernSpec_Defaults() throws Exception {
723         KeyPairGenerator generator = getRsaGenerator();
724         generator.initialize(new KeyGenParameterSpec.Builder(
725                 TEST_ALIAS_1,
726                 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
727                 .build());
728         KeyPair keyPair = generator.generateKeyPair();
729         assertGeneratedKeyPairAndSelfSignedCertificate(
730                 keyPair,
731                 TEST_ALIAS_1,
732                 "RSA",
733                 2048,
734                 DEFAULT_CERT_SUBJECT,
735                 DEFAULT_CERT_SERIAL_NUMBER,
736                 DEFAULT_CERT_NOT_BEFORE,
737                 DEFAULT_CERT_NOT_AFTER);
738         assertEquals(RSAKeyGenParameterSpec.F4,
739                 ((RSAPublicKey) keyPair.getPublic()).getPublicExponent());
740         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
741         assertEquals(2048, keyInfo.getKeySize());
742         assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
743         assertOneOf(keyInfo.getOrigin(),
744                 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
745         assertEquals(
746                 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
747                 keyInfo.getPurposes());
748         assertFalse(keyInfo.isUserAuthenticationRequired());
749         assertEquals(null, keyInfo.getKeyValidityStart());
750         assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
751         assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
752         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
753         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getDigests()));
754         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
755         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
756     }
757 
testGenerate_EC_ModernSpec_AsCustomAsPossible()758     public void testGenerate_EC_ModernSpec_AsCustomAsPossible() throws Exception {
759         KeyPairGenerator generator = getEcGenerator();
760         Date keyValidityStart = new Date(System.currentTimeMillis());
761         Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 1000000);
762         Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 10000000);
763 
764         Date certNotBefore = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 7);
765         Date certNotAfter = new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 7);
766         BigInteger certSerialNumber = new BigInteger("12345678");
767         X500Principal certSubject = new X500Principal("cn=hello");
768         generator.initialize(new KeyGenParameterSpec.Builder(
769                 TEST_ALIAS_1,
770                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
771                         | KeyProperties.PURPOSE_ENCRYPT)
772                 .setKeySize(224)
773                 .setDigests(KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512)
774                 .setKeyValidityStart(keyValidityStart)
775                 .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
776                 .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
777                 .setCertificateSerialNumber(certSerialNumber)
778                 .setCertificateSubject(certSubject)
779                 .setCertificateNotBefore(certNotBefore)
780                 .setCertificateNotAfter(certNotAfter)
781                 .build());
782         KeyPair keyPair = generator.generateKeyPair();
783         assertGeneratedKeyPairAndSelfSignedCertificate(
784                 keyPair,
785                 TEST_ALIAS_1,
786                 "EC",
787                 224,
788                 certSubject,
789                 certSerialNumber,
790                 certNotBefore,
791                 certNotAfter);
792         TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
793                 ECCurves.NIST_P_224_SPEC, ((ECKey) keyPair.getPrivate()).getParams());
794         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
795         assertEquals(224, keyInfo.getKeySize());
796         assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
797         assertOneOf(keyInfo.getOrigin(),
798                 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
799         assertEquals(
800                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
801                         | KeyProperties.PURPOSE_ENCRYPT,
802                 keyInfo.getPurposes());
803         assertEquals(keyValidityStart, keyInfo.getKeyValidityStart());
804         assertEquals(keyValidityEndDateForOrigination, keyInfo.getKeyValidityForOriginationEnd());
805         assertEquals(keyValidityEndDateForConsumption, keyInfo.getKeyValidityForConsumptionEnd());
806         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
807 
808         List<String> actualDigests = new ArrayList<String>(Arrays.asList(keyInfo.getDigests()));
809         // Keystore may have added DIGEST_NONE, to allow software digesting.
810         actualDigests.remove(KeyProperties.DIGEST_NONE);
811         TestUtils.assertContentsInAnyOrder(
812                 actualDigests, KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512);
813 
814         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
815         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
816         assertFalse(keyInfo.isUserAuthenticationRequired());
817         assertEquals(-1, keyInfo.getUserAuthenticationValidityDurationSeconds());
818     }
819 
testGenerate_RSA_ModernSpec_AsCustomAsPossible()820     public void testGenerate_RSA_ModernSpec_AsCustomAsPossible() throws Exception {
821         KeyPairGenerator generator = getRsaGenerator();
822         Date keyValidityStart = new Date(System.currentTimeMillis());
823         Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 1000000);
824         Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 10000000);
825 
826         Date certNotBefore = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 210);
827         Date certNotAfter = new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 210);
828         BigInteger certSerialNumber = new BigInteger("1234567890");
829         X500Principal certSubject = new X500Principal("cn=hello2");
830         generator.initialize(new KeyGenParameterSpec.Builder(
831                 TEST_ALIAS_1,
832                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
833                         | KeyProperties.PURPOSE_ENCRYPT)
834                 .setAlgorithmParameterSpec(
835                         new RSAKeyGenParameterSpec(3072, RSAKeyGenParameterSpec.F0))
836                 .setKeySize(3072)
837                 .setDigests(KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512)
838                 .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS,
839                         KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
840                 .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
841                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
842                         KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
843                 .setKeyValidityStart(keyValidityStart)
844                 .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
845                 .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
846                 .setCertificateSerialNumber(certSerialNumber)
847                 .setCertificateSubject(certSubject)
848                 .setCertificateNotBefore(certNotBefore)
849                 .setCertificateNotAfter(certNotAfter)
850                 .build());
851         KeyPair keyPair = generator.generateKeyPair();
852         assertGeneratedKeyPairAndSelfSignedCertificate(
853                 keyPair,
854                 TEST_ALIAS_1,
855                 "RSA",
856                 3072,
857                 certSubject,
858                 certSerialNumber,
859                 certNotBefore,
860                 certNotAfter);
861         assertEquals(RSAKeyGenParameterSpec.F0,
862                 ((RSAPublicKey) keyPair.getPublic()).getPublicExponent());
863         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
864         assertEquals(3072, keyInfo.getKeySize());
865         assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
866         assertOneOf(keyInfo.getOrigin(),
867                 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
868         assertEquals(
869                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
870                         | KeyProperties.PURPOSE_ENCRYPT,
871                 keyInfo.getPurposes());
872         assertEquals(keyValidityStart, keyInfo.getKeyValidityStart());
873         assertEquals(keyValidityEndDateForOrigination, keyInfo.getKeyValidityForOriginationEnd());
874         assertEquals(keyValidityEndDateForConsumption, keyInfo.getKeyValidityForConsumptionEnd());
875 
876         List<String> actualDigests =
877 	    new ArrayList<String>(Arrays.asList(keyInfo.getDigests()));
878         // Keystore may have added DIGEST_NONE, to allow software digesting.
879         actualDigests.remove(KeyProperties.DIGEST_NONE);
880         TestUtils.assertContentsInAnyOrder(
881                 actualDigests, KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512);
882 
883         TestUtils.assertContentsInAnyOrder(Arrays.asList(keyInfo.getSignaturePaddings()),
884                 KeyProperties.SIGNATURE_PADDING_RSA_PKCS1,
885                 KeyProperties.SIGNATURE_PADDING_RSA_PSS);
886         MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getBlockModes()),
887                 KeyProperties.BLOCK_MODE_ECB);
888 
889         List<String> actualEncryptionPaddings =
890                 new ArrayList<String>(Arrays.asList(keyInfo.getEncryptionPaddings()));
891         // Keystore may have added ENCRYPTION_PADDING_NONE, to allow software padding.
892         actualEncryptionPaddings.remove(KeyProperties.ENCRYPTION_PADDING_NONE);
893         TestUtils.assertContentsInAnyOrder(actualEncryptionPaddings,
894                 KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
895                 KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1);
896 
897         assertFalse(keyInfo.isUserAuthenticationRequired());
898         assertEquals(-1, keyInfo.getUserAuthenticationValidityDurationSeconds());
899     }
900 
testGenerate_EC_ModernSpec_UsableForTLSPeerAuth()901     public void testGenerate_EC_ModernSpec_UsableForTLSPeerAuth() throws Exception {
902         KeyPairGenerator generator = getEcGenerator();
903         generator.initialize(new KeyGenParameterSpec.Builder(
904                 TEST_ALIAS_1,
905                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
906                 .setDigests(KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA384)
907                 .build());
908         KeyPair keyPair = generator.generateKeyPair();
909         assertGeneratedKeyPairAndSelfSignedCertificate(
910                 keyPair,
911                 TEST_ALIAS_1,
912                 "EC",
913                 256,
914                 DEFAULT_CERT_SUBJECT,
915                 DEFAULT_CERT_SERIAL_NUMBER,
916                 DEFAULT_CERT_NOT_BEFORE,
917                 DEFAULT_CERT_NOT_AFTER);
918         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
919         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
920         MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
921                 KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA384);
922         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
923         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
924         assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1);
925         assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1);
926     }
927 
testGenerate_RSA_ModernSpec_UsableForTLSPeerAuth()928     public void testGenerate_RSA_ModernSpec_UsableForTLSPeerAuth() throws Exception {
929         KeyPairGenerator generator = getRsaGenerator();
930         generator.initialize(new KeyGenParameterSpec.Builder(
931                 TEST_ALIAS_1,
932                 KeyProperties.PURPOSE_SIGN
933                         | KeyProperties.PURPOSE_VERIFY
934                         | KeyProperties.PURPOSE_DECRYPT)
935                 .setDigests(KeyProperties.DIGEST_NONE,
936                         KeyProperties.DIGEST_SHA256,
937                         KeyProperties.DIGEST_SHA512)
938                 .setEncryptionPaddings(
939                         KeyProperties.ENCRYPTION_PADDING_NONE,
940                         KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
941                 .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
942                 .build());
943         KeyPair keyPair = generator.generateKeyPair();
944         assertGeneratedKeyPairAndSelfSignedCertificate(
945                 keyPair,
946                 TEST_ALIAS_1,
947                 "RSA",
948                 2048,
949                 DEFAULT_CERT_SUBJECT,
950                 DEFAULT_CERT_SERIAL_NUMBER,
951                 DEFAULT_CERT_NOT_BEFORE,
952                 DEFAULT_CERT_NOT_AFTER);
953         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
954         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
955         MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
956                 KeyProperties.DIGEST_NONE,
957                 KeyProperties.DIGEST_SHA256,
958                 KeyProperties.DIGEST_SHA512);
959         MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getSignaturePaddings()),
960                 KeyProperties.SIGNATURE_PADDING_RSA_PKCS1);
961         MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getEncryptionPaddings()),
962                 KeyProperties.ENCRYPTION_PADDING_NONE,
963                 KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1);
964         assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1);
965         assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1);
966     }
967 
968     // TODO: Test fingerprint-authorized and secure lock screen-authorized keys. These can't
969     // currently be tested here because CTS does not require that secure lock screen is set up and
970     // that at least one fingerprint is enrolled.
971 
testGenerate_EC_ModernSpec_KeyNotYetValid()972     public void testGenerate_EC_ModernSpec_KeyNotYetValid() throws Exception {
973         KeyPairGenerator generator = getEcGenerator();
974         Date validityStart = new Date(System.currentTimeMillis() + DAY_IN_MILLIS);
975         generator.initialize(new KeyGenParameterSpec.Builder(
976                 TEST_ALIAS_1,
977                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
978                 .setKeySize(256)
979                 .setDigests(KeyProperties.DIGEST_SHA256)
980                 .setKeyValidityStart(validityStart)
981                 .build());
982         KeyPair keyPair = generator.generateKeyPair();
983         assertGeneratedKeyPairAndSelfSignedCertificate(
984                 keyPair,
985                 TEST_ALIAS_1,
986                 "EC",
987                 256,
988                 DEFAULT_CERT_SUBJECT,
989                 DEFAULT_CERT_SERIAL_NUMBER,
990                 DEFAULT_CERT_NOT_BEFORE,
991                 DEFAULT_CERT_NOT_AFTER);
992         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
993         assertEquals(validityStart, keyInfo.getKeyValidityStart());
994     }
995 
testGenerate_RSA_ModernSpec_KeyExpiredForOrigination()996     public void testGenerate_RSA_ModernSpec_KeyExpiredForOrigination() throws Exception {
997         KeyPairGenerator generator = getRsaGenerator();
998         Date originationEnd = new Date(System.currentTimeMillis() - DAY_IN_MILLIS);
999         generator.initialize(new KeyGenParameterSpec.Builder(
1000                 TEST_ALIAS_1,
1001                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
1002                 .setKeySize(1024)
1003                 .setDigests(KeyProperties.DIGEST_SHA256)
1004                 .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
1005                 .setKeyValidityForOriginationEnd(originationEnd)
1006                 .build());
1007         KeyPair keyPair = generator.generateKeyPair();
1008         assertGeneratedKeyPairAndSelfSignedCertificate(
1009                 keyPair,
1010                 TEST_ALIAS_1,
1011                 "RSA",
1012                 1024,
1013                 DEFAULT_CERT_SUBJECT,
1014                 DEFAULT_CERT_SERIAL_NUMBER,
1015                 DEFAULT_CERT_NOT_BEFORE,
1016                 DEFAULT_CERT_NOT_AFTER);
1017         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
1018         assertEquals(originationEnd, keyInfo.getKeyValidityForOriginationEnd());
1019     }
1020 
testGenerate_EC_ModernSpec_SupportedSizes()1021     public void testGenerate_EC_ModernSpec_SupportedSizes() throws Exception {
1022         assertKeyGenUsingECSizeOnlyUsesCorrectCurve(224, ECCurves.NIST_P_224_SPEC);
1023         assertKeyGenUsingECSizeOnlyUsesCorrectCurve(256, ECCurves.NIST_P_256_SPEC);
1024         assertKeyGenUsingECSizeOnlyUsesCorrectCurve(384, ECCurves.NIST_P_384_SPEC);
1025         assertKeyGenUsingECSizeOnlyUsesCorrectCurve(521, ECCurves.NIST_P_521_SPEC);
1026     }
1027 
testGenerate_EC_ModernSpec_UnsupportedSizesRejected()1028     public void testGenerate_EC_ModernSpec_UnsupportedSizesRejected() throws Exception {
1029         for (int keySizeBits = 0; keySizeBits <= 1024; keySizeBits++) {
1030             if ((keySizeBits == 224) || (keySizeBits == 256) || (keySizeBits == 384)
1031                     || (keySizeBits == 521)) {
1032                 // Skip supported sizes
1033                 continue;
1034             }
1035             KeyPairGenerator generator = getEcGenerator();
1036 
1037             try {
1038                 generator.initialize(new KeyGenParameterSpec.Builder(
1039                         TEST_ALIAS_1,
1040                         KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
1041                         .setKeySize(keySizeBits)
1042                         .build());
1043                 fail("EC KeyPairGenerator initialized with unsupported key size: "
1044                         + keySizeBits + " bits");
1045             } catch (InvalidAlgorithmParameterException expected) {
1046             }
1047         }
1048     }
1049 
testGenerate_EC_ModernSpec_SupportedNamedCurves()1050     public void testGenerate_EC_ModernSpec_SupportedNamedCurves() throws Exception {
1051         assertKeyGenUsingECNamedCurveSupported("P-224", ECCurves.NIST_P_224_SPEC);
1052         assertKeyGenUsingECNamedCurveSupported("p-224", ECCurves.NIST_P_224_SPEC);
1053         assertKeyGenUsingECNamedCurveSupported("secp224r1", ECCurves.NIST_P_224_SPEC);
1054         assertKeyGenUsingECNamedCurveSupported("SECP224R1", ECCurves.NIST_P_224_SPEC);
1055 
1056         assertKeyGenUsingECNamedCurveSupported("P-256", ECCurves.NIST_P_256_SPEC);
1057         assertKeyGenUsingECNamedCurveSupported("p-256", ECCurves.NIST_P_256_SPEC);
1058         assertKeyGenUsingECNamedCurveSupported("secp256r1", ECCurves.NIST_P_256_SPEC);
1059         assertKeyGenUsingECNamedCurveSupported("SECP256R1", ECCurves.NIST_P_256_SPEC);
1060         assertKeyGenUsingECNamedCurveSupported("prime256v1", ECCurves.NIST_P_256_SPEC);
1061         assertKeyGenUsingECNamedCurveSupported("PRIME256V1", ECCurves.NIST_P_256_SPEC);
1062 
1063         assertKeyGenUsingECNamedCurveSupported("P-384", ECCurves.NIST_P_384_SPEC);
1064         assertKeyGenUsingECNamedCurveSupported("p-384", ECCurves.NIST_P_384_SPEC);
1065         assertKeyGenUsingECNamedCurveSupported("secp384r1", ECCurves.NIST_P_384_SPEC);
1066         assertKeyGenUsingECNamedCurveSupported("SECP384R1", ECCurves.NIST_P_384_SPEC);
1067 
1068         assertKeyGenUsingECNamedCurveSupported("P-521", ECCurves.NIST_P_521_SPEC);
1069         assertKeyGenUsingECNamedCurveSupported("p-521", ECCurves.NIST_P_521_SPEC);
1070         assertKeyGenUsingECNamedCurveSupported("secp521r1", ECCurves.NIST_P_521_SPEC);
1071         assertKeyGenUsingECNamedCurveSupported("SECP521R1", ECCurves.NIST_P_521_SPEC);
1072     }
1073 
testGenerate_RSA_ModernSpec_SupportedSizes()1074     public void testGenerate_RSA_ModernSpec_SupportedSizes() throws Exception {
1075         assertKeyGenUsingRSASizeOnlySupported(512);
1076         assertKeyGenUsingRSASizeOnlySupported(768);
1077         assertKeyGenUsingRSASizeOnlySupported(1024);
1078         assertKeyGenUsingRSASizeOnlySupported(2048);
1079         assertKeyGenUsingRSASizeOnlySupported(3072);
1080         assertKeyGenUsingRSASizeOnlySupported(4096);
1081 
1082         // The above use F4. Check that F0 is supported as well, just in case somebody is crazy
1083         // enough.
1084         assertKeyGenUsingRSAKeyGenParameterSpecSupported(new RSAKeyGenParameterSpec(
1085                 2048, RSAKeyGenParameterSpec.F0));
1086     }
1087 
testGenerate_RSA_IndCpaEnforced()1088     public void testGenerate_RSA_IndCpaEnforced() throws Exception {
1089         KeyGenParameterSpec.Builder goodBuilder = new KeyGenParameterSpec.Builder(
1090                 TEST_ALIAS_1, KeyProperties.PURPOSE_ENCRYPT)
1091                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
1092                         KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1);
1093         assertKeyGenInitSucceeds("RSA", goodBuilder.build());
1094 
1095         // Should be fine because IND-CPA restriction applies only to encryption keys
1096         assertKeyGenInitSucceeds("RSA",
1097                 TestUtils.buildUpon(goodBuilder, KeyProperties.PURPOSE_DECRYPT)
1098                         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
1099                         .build());
1100 
1101         assertKeyGenInitThrowsInvalidAlgorithmParameterException("RSA",
1102                 TestUtils.buildUpon(goodBuilder)
1103                         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
1104                         .build());
1105 
1106         assertKeyGenInitSucceeds("RSA",
1107                 TestUtils.buildUpon(goodBuilder)
1108                         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
1109                         .setRandomizedEncryptionRequired(false)
1110                         .build());
1111 
1112         // Should fail because PKCS#7 padding doesn't work with RSA
1113         assertKeyGenInitThrowsInvalidAlgorithmParameterException("RSA",
1114                 TestUtils.buildUpon(goodBuilder)
1115                         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
1116                         .build());
1117     }
1118 
testGenerate_EC_IndCpaEnforced()1119     public void testGenerate_EC_IndCpaEnforced() throws Exception {
1120         KeyGenParameterSpec.Builder goodBuilder = new KeyGenParameterSpec.Builder(
1121                 TEST_ALIAS_2, KeyProperties.PURPOSE_ENCRYPT);
1122         assertKeyGenInitSucceeds("EC", goodBuilder.build());
1123 
1124         // Should be fine because IND-CPA restriction applies only to encryption keys
1125         assertKeyGenInitSucceeds("EC",
1126                 TestUtils.buildUpon(goodBuilder, KeyProperties.PURPOSE_DECRYPT)
1127                         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
1128                         .build());
1129 
1130         assertKeyGenInitThrowsInvalidAlgorithmParameterException("EC",
1131                 TestUtils.buildUpon(goodBuilder)
1132                         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
1133                         .build());
1134 
1135         assertKeyGenInitSucceeds("EC",
1136                 TestUtils.buildUpon(goodBuilder)
1137                         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
1138                         .setRandomizedEncryptionRequired(false)
1139                         .build());
1140     }
1141 
1142     // http://b/28384942
testGenerateWithFarsiLocale()1143     public void testGenerateWithFarsiLocale() throws Exception {
1144         Locale defaultLocale = Locale.getDefault();
1145         // Note that we use farsi here because its number formatter doesn't use
1146         // arabic digits.
1147         Locale fa_IR = Locale.forLanguageTag("fa-IR");
1148         DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(fa_IR);
1149         assertFalse('0' == dfs.getZeroDigit());
1150 
1151         Locale.setDefault(fa_IR);
1152         try {
1153             KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance(
1154                     KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
1155 
1156             keyGenerator.initialize(new KeyGenParameterSpec.Builder(
1157                    TEST_ALIAS_1, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
1158                    .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
1159                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
1160                    .build());
1161 
1162             keyGenerator.generateKeyPair();
1163         } finally {
1164             Locale.setDefault(defaultLocale);
1165         }
1166     }
1167 
assertKeyGenInitSucceeds(String algorithm, AlgorithmParameterSpec params)1168     private void assertKeyGenInitSucceeds(String algorithm, AlgorithmParameterSpec params)
1169             throws Exception {
1170         KeyPairGenerator generator = getGenerator(algorithm);
1171         generator.initialize(params);
1172     }
1173 
assertKeyGenInitThrowsInvalidAlgorithmParameterException( String algorithm, AlgorithmParameterSpec params)1174     private void assertKeyGenInitThrowsInvalidAlgorithmParameterException(
1175             String algorithm, AlgorithmParameterSpec params) throws Exception {
1176         KeyPairGenerator generator = getGenerator(algorithm);
1177         try {
1178             generator.initialize(params);
1179             fail();
1180         } catch (InvalidAlgorithmParameterException expected) {}
1181     }
1182 
assertKeyGenUsingECSizeOnlyUsesCorrectCurve( int keySizeBits, ECParameterSpec expectedParams)1183     private void assertKeyGenUsingECSizeOnlyUsesCorrectCurve(
1184             int keySizeBits, ECParameterSpec expectedParams) throws Exception {
1185         KeyPairGenerator generator = getEcGenerator();
1186         generator.initialize(new KeyGenParameterSpec.Builder(
1187                 TEST_ALIAS_1,
1188                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
1189                 .setKeySize(keySizeBits)
1190                 .build(),
1191                 mRng);
1192         mRng.resetCounters();
1193         KeyPair keyPair = generator.generateKeyPair();
1194         long consumedEntropyAmountBytes = mRng.getOutputSizeBytes();
1195         int expectedKeySize = expectedParams.getCurve().getField().getFieldSize();
1196         assertGeneratedKeyPairAndSelfSignedCertificate(
1197                 keyPair,
1198                 TEST_ALIAS_1,
1199                 "EC",
1200                 expectedKeySize,
1201                 DEFAULT_CERT_SUBJECT,
1202                 DEFAULT_CERT_SERIAL_NUMBER,
1203                 DEFAULT_CERT_NOT_BEFORE,
1204                 DEFAULT_CERT_NOT_AFTER);
1205         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
1206         assertEquals(expectedKeySize, keyInfo.getKeySize());
1207         TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
1208                 expectedParams,
1209                 ((ECKey) keyPair.getPublic()).getParams());
1210         assertEquals(((keySizeBits + 7) / 8) * 8, consumedEntropyAmountBytes * 8);
1211     }
1212 
assertKeyGenUsingECNamedCurveSupported( String curveName, ECParameterSpec expectedParams)1213     private void assertKeyGenUsingECNamedCurveSupported(
1214             String curveName, ECParameterSpec expectedParams) throws Exception {
1215         KeyPairGenerator generator = getEcGenerator();
1216         generator.initialize(new KeyGenParameterSpec.Builder(
1217                 TEST_ALIAS_1,
1218                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
1219                 .setAlgorithmParameterSpec(new ECGenParameterSpec(curveName))
1220                 .build(),
1221                 mRng);
1222         mRng.resetCounters();
1223         KeyPair keyPair = generator.generateKeyPair();
1224         long consumedEntropyAmountBytes = mRng.getOutputSizeBytes();
1225         int expectedKeySize = expectedParams.getCurve().getField().getFieldSize();
1226         assertGeneratedKeyPairAndSelfSignedCertificate(
1227                 keyPair,
1228                 TEST_ALIAS_1,
1229                 "EC",
1230                 expectedKeySize,
1231                 DEFAULT_CERT_SUBJECT,
1232                 DEFAULT_CERT_SERIAL_NUMBER,
1233                 DEFAULT_CERT_NOT_BEFORE,
1234                 DEFAULT_CERT_NOT_AFTER);
1235         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
1236         assertEquals(expectedKeySize, keyInfo.getKeySize());
1237         TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
1238                 expectedParams,
1239                 ((ECKey) keyPair.getPublic()).getParams());
1240         assertEquals(((expectedKeySize + 7) / 8) * 8, consumedEntropyAmountBytes * 8);
1241     }
1242 
assertKeyGenUsingRSASizeOnlySupported(int keySizeBits)1243     private void assertKeyGenUsingRSASizeOnlySupported(int keySizeBits) throws Exception {
1244         KeyPairGenerator generator = getRsaGenerator();
1245         generator.initialize(new KeyGenParameterSpec.Builder(
1246                 TEST_ALIAS_1,
1247                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
1248                 .setKeySize(keySizeBits)
1249                 .build(),
1250                 mRng);
1251         mRng.resetCounters();
1252         KeyPair keyPair = generator.generateKeyPair();
1253         long consumedEntropyAmountBytes = mRng.getOutputSizeBytes();
1254         assertGeneratedKeyPairAndSelfSignedCertificate(
1255                 keyPair,
1256                 TEST_ALIAS_1,
1257                 "RSA",
1258                 keySizeBits,
1259                 DEFAULT_CERT_SUBJECT,
1260                 DEFAULT_CERT_SERIAL_NUMBER,
1261                 DEFAULT_CERT_NOT_BEFORE,
1262                 DEFAULT_CERT_NOT_AFTER);
1263         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
1264         assertEquals(keySizeBits, keyInfo.getKeySize());
1265         assertEquals(((keySizeBits + 7) / 8) * 8, consumedEntropyAmountBytes * 8);
1266     }
1267 
assertKeyGenUsingRSAKeyGenParameterSpecSupported( RSAKeyGenParameterSpec spec)1268     private void assertKeyGenUsingRSAKeyGenParameterSpecSupported(
1269             RSAKeyGenParameterSpec spec) throws Exception {
1270         KeyPairGenerator generator = getRsaGenerator();
1271         generator.initialize(new KeyGenParameterSpec.Builder(
1272                 TEST_ALIAS_1,
1273                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
1274                 .setAlgorithmParameterSpec(spec)
1275                 .build(),
1276                 mRng);
1277         mRng.resetCounters();
1278         KeyPair keyPair = generator.generateKeyPair();
1279         long consumedEntropyAmountBytes = mRng.getOutputSizeBytes();
1280         assertGeneratedKeyPairAndSelfSignedCertificate(
1281                 keyPair,
1282                 TEST_ALIAS_1,
1283                 "RSA",
1284                 spec.getKeysize(),
1285                 DEFAULT_CERT_SUBJECT,
1286                 DEFAULT_CERT_SERIAL_NUMBER,
1287                 DEFAULT_CERT_NOT_BEFORE,
1288                 DEFAULT_CERT_NOT_AFTER);
1289         assertEquals(spec.getPublicExponent(),
1290                 ((RSAPublicKey) keyPair.getPublic()).getPublicExponent());
1291         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
1292         assertEquals(spec.getKeysize(), keyInfo.getKeySize());
1293         assertEquals(((spec.getKeysize() + 7) / 8) * 8, consumedEntropyAmountBytes * 8);
1294     }
1295 
assertSelfSignedCertificateSignatureVerifies(Certificate certificate)1296     private static void assertSelfSignedCertificateSignatureVerifies(Certificate certificate) {
1297         try {
1298             certificate.verify(certificate.getPublicKey());
1299         } catch (Exception e) {
1300             throw new RuntimeException("Failed to verify self-signed certificate signature", e);
1301         }
1302     }
1303 
assertGeneratedKeyPairAndSelfSignedCertificate( KeyPair keyPair, String alias, String expectedKeyAlgorithm, int expectedKeySize, X500Principal expectedCertSubject, BigInteger expectedCertSerialNumber, Date expectedCertNotBefore, Date expectedCertNotAfter)1304     private void assertGeneratedKeyPairAndSelfSignedCertificate(
1305             KeyPair keyPair, String alias,
1306             String expectedKeyAlgorithm,
1307             int expectedKeySize,
1308             X500Principal expectedCertSubject,
1309             BigInteger expectedCertSerialNumber,
1310             Date expectedCertNotBefore,
1311             Date expectedCertNotAfter)
1312             throws Exception {
1313         assertNotNull(keyPair);
1314         TestUtils.assertKeyPairSelfConsistent(keyPair);
1315         TestUtils.assertKeySize(expectedKeySize, keyPair);
1316         assertEquals(expectedKeyAlgorithm, keyPair.getPublic().getAlgorithm());
1317         TestUtils.assertKeyStoreKeyPair(mKeyStore, alias, keyPair);
1318 
1319         X509Certificate cert = (X509Certificate) mKeyStore.getCertificate(alias);
1320         assertEquals(keyPair.getPublic(), cert.getPublicKey());
1321         assertX509CertificateParameters(cert,
1322                 expectedCertSubject,
1323                 expectedCertSerialNumber,
1324                 expectedCertNotBefore,
1325                 expectedCertNotAfter);
1326         // Assert that the certificate chain consists only of the above certificate
1327         MoreAsserts.assertContentsInOrder(
1328                 Arrays.asList(mKeyStore.getCertificateChain(alias)), cert);
1329     }
1330 
assertSelfSignedCertificateSignatureVerifies(String alias)1331     private void assertSelfSignedCertificateSignatureVerifies(String alias) throws Exception {
1332         assertSelfSignedCertificateSignatureVerifies(mKeyStore.getCertificate(alias));
1333     }
1334 
assertKeyPairAndCertificateUsableForTLSPeerAuthentication(String alias)1335     private void assertKeyPairAndCertificateUsableForTLSPeerAuthentication(String alias)
1336             throws Exception {
1337         assertUsableForTLSPeerAuthentication(
1338                 (PrivateKey) mKeyStore.getKey(alias, null),
1339                 mKeyStore.getCertificateChain(alias));
1340     }
1341 
assertX509CertificateParameters( X509Certificate actualCert, X500Principal expectedSubject, BigInteger expectedSerialNumber, Date expectedNotBefore, Date expectedNotAfter)1342     private static void assertX509CertificateParameters(
1343             X509Certificate actualCert,
1344             X500Principal expectedSubject, BigInteger expectedSerialNumber,
1345             Date expectedNotBefore, Date expectedNotAfter) {
1346         assertEquals(expectedSubject, actualCert.getSubjectDN());
1347         assertEquals(expectedSubject, actualCert.getIssuerDN());
1348         assertEquals(expectedSerialNumber, actualCert.getSerialNumber());
1349         assertDateEquals(expectedNotBefore, actualCert.getNotBefore());
1350         assertDateEquals(expectedNotAfter, actualCert.getNotAfter());
1351     }
1352 
assertUsableForTLSPeerAuthentication( PrivateKey privateKey, Certificate[] certificateChain)1353     private static void assertUsableForTLSPeerAuthentication(
1354             PrivateKey privateKey,
1355             Certificate[] certificateChain) throws Exception {
1356         // Set up both client and server to use the same private key + cert, and to trust that cert
1357         // when it's presented by peer. This exercises the use of the private key both in client
1358         // and server scenarios.
1359         X509Certificate[] x509CertificateChain = new X509Certificate[certificateChain.length];
1360         for (int i = 0; i < certificateChain.length; i++) {
1361             x509CertificateChain[i] = (X509Certificate) certificateChain[i];
1362         }
1363         TestKeyStore serverKeyStore = TestKeyStore.getServer();
1364         // Make the peer trust the root certificate in the chain. As opposed to making the peer
1365         // trust the leaf certificate, this will ensure that the whole chain verifies.
1366         serverKeyStore.keyStore.setCertificateEntry(
1367                 "trusted", certificateChain[certificateChain.length - 1]);
1368         SSLContext serverContext = TestSSLContext.createSSLContext("TLS",
1369                 new KeyManager[] {
1370                     TestKeyManager.wrap(new MyKeyManager(privateKey, x509CertificateChain))
1371                 },
1372                 TestKeyStore.createTrustManagers(serverKeyStore.keyStore));
1373         SSLContext clientContext = serverContext;
1374 
1375         if ("EC".equalsIgnoreCase(privateKey.getAlgorithm())) {
1376             // As opposed to RSA (see below) EC keys are used in the same way in all cipher suites.
1377             // Assert that the key works with the default list of cipher suites.
1378             assertSSLConnectionWithClientAuth(
1379                     clientContext, serverContext, null, x509CertificateChain, x509CertificateChain);
1380         } else if ("RSA".equalsIgnoreCase(privateKey.getAlgorithm())) {
1381             // RSA keys are used differently between Forward Secure and non-Forward Secure cipher
1382             // suites. For example, RSA key exchange requires the server to decrypt using its RSA
1383             // private key, whereas ECDHE_RSA key exchange requires the server to sign usnig its
1384             // RSA private key. We thus assert that the key works with Forward Secure cipher suites
1385             // and that it works with non-Forward Secure cipher suites.
1386             List<String> fsCipherSuites = new ArrayList<String>();
1387             List<String> nonFsCipherSuites = new ArrayList<String>();
1388             for (String cipherSuite : clientContext.getDefaultSSLParameters().getCipherSuites()) {
1389                 if (cipherSuite.contains("_ECDHE_RSA_") || cipherSuite.contains("_DHE_RSA_")) {
1390                     fsCipherSuites.add(cipherSuite);
1391                 } else if (cipherSuite.contains("_RSA_WITH_")) {
1392                     nonFsCipherSuites.add(cipherSuite);
1393                 }
1394             }
1395             assertFalse("No FS RSA cipher suites enabled by default", fsCipherSuites.isEmpty());
1396             assertFalse("No non-FS RSA cipher suites enabled", nonFsCipherSuites.isEmpty());
1397 
1398             // Assert that the key works with RSA Forward Secure cipher suites.
1399             assertSSLConnectionWithClientAuth(
1400                     clientContext, serverContext, fsCipherSuites.toArray(new String[0]),
1401                     x509CertificateChain, x509CertificateChain);
1402             // Assert that the key works with RSA non-Forward Secure cipher suites.
1403             assertSSLConnectionWithClientAuth(
1404                     clientContext, serverContext, nonFsCipherSuites.toArray(new String[0]),
1405                     x509CertificateChain, x509CertificateChain);
1406         } else {
1407             fail("Unsupported key algorithm: " + privateKey.getAlgorithm());
1408         }
1409     }
1410 
assertSSLConnectionWithClientAuth( SSLContext clientContext, SSLContext serverContext, String[] enabledCipherSuites, X509Certificate[] expectedClientCertChain, X509Certificate[] expectedServerCertChain)1411     private static void assertSSLConnectionWithClientAuth(
1412             SSLContext clientContext, SSLContext serverContext, String[] enabledCipherSuites,
1413             X509Certificate[] expectedClientCertChain, X509Certificate[] expectedServerCertChain)
1414             throws Exception {
1415         SSLServerSocket serverSocket = (SSLServerSocket) serverContext.getServerSocketFactory()
1416                 .createServerSocket(0);
1417         InetAddress host = InetAddress.getLocalHost();
1418         int port = serverSocket.getLocalPort();
1419         SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(host, port);
1420 
1421         final SSLSocket server = (SSLSocket) serverSocket.accept();
1422         ExecutorService executor = Executors.newSingleThreadExecutor();
1423         Future<Certificate[]> future = executor.submit(new Callable<Certificate[]>() {
1424             @Override
1425             public Certificate[] call() throws Exception {
1426                 server.setNeedClientAuth(true);
1427                 server.setWantClientAuth(true);
1428                 server.startHandshake();
1429                 return server.getSession().getPeerCertificates();
1430             }
1431         });
1432         executor.shutdown();
1433         if (enabledCipherSuites != null) {
1434             client.setEnabledCipherSuites(enabledCipherSuites);
1435         }
1436         client.startHandshake();
1437         Certificate[] usedServerCerts = client.getSession().getPeerCertificates();
1438         Certificate[] usedClientCerts = future.get();
1439         client.close();
1440         server.close();
1441 
1442         assertNotNull(usedServerCerts);
1443         assertEquals(Arrays.asList(expectedServerCertChain), Arrays.asList(usedServerCerts));
1444 
1445         assertNotNull(usedClientCerts);
1446         assertEquals(Arrays.asList(expectedClientCertChain), Arrays.asList(usedClientCerts));
1447     }
1448 
1449     private static class MyKeyManager extends X509ExtendedKeyManager {
1450         private final PrivateKey key;
1451         private final X509Certificate[] chain;
1452 
MyKeyManager(PrivateKey key, X509Certificate[] certChain)1453         public MyKeyManager(PrivateKey key, X509Certificate[] certChain) {
1454             this.key = key;
1455             this.chain = certChain;
1456         }
1457 
1458         @Override
chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket)1459         public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
1460             return "fake";
1461         }
1462 
1463         @Override
chooseServerAlias(String keyType, Principal[] issuers, Socket socket)1464         public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
1465             return "fake";
1466         }
1467 
1468         @Override
getCertificateChain(String alias)1469         public X509Certificate[] getCertificateChain(String alias) {
1470             return chain;
1471         }
1472 
1473         @Override
getClientAliases(String keyType, Principal[] issuers)1474         public String[] getClientAliases(String keyType, Principal[] issuers) {
1475             return new String[] { "fake" };
1476         }
1477 
1478         @Override
getServerAliases(String keyType, Principal[] issuers)1479         public String[] getServerAliases(String keyType, Principal[] issuers) {
1480             return new String[] { "fake" };
1481         }
1482 
1483         @Override
getPrivateKey(String alias)1484         public PrivateKey getPrivateKey(String alias) {
1485             return key;
1486         }
1487     }
1488 
1489 
assertDateEquals(Date date1, Date date2)1490     private static void assertDateEquals(Date date1, Date date2) {
1491         assertDateEquals(null, date1, date2);
1492     }
1493 
assertDateEquals(String message, Date date1, Date date2)1494     private static void assertDateEquals(String message, Date date1, Date date2) {
1495         SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss");
1496 
1497         String result1 = formatter.format(date1);
1498         String result2 = formatter.format(date2);
1499 
1500         assertEquals(message, result1, result2);
1501     }
1502 
getRsaGenerator()1503     private KeyPairGenerator getRsaGenerator()
1504             throws NoSuchAlgorithmException, NoSuchProviderException {
1505         return getGenerator("RSA");
1506     }
1507 
getEcGenerator()1508     private KeyPairGenerator getEcGenerator()
1509             throws NoSuchAlgorithmException, NoSuchProviderException {
1510         return getGenerator("EC");
1511     }
1512 
getGenerator(String algorithm)1513     private KeyPairGenerator getGenerator(String algorithm)
1514             throws NoSuchAlgorithmException, NoSuchProviderException {
1515         return KeyPairGenerator.getInstance(algorithm, "AndroidKeyStore");
1516     }
1517 
assertOneOf(int actual, int... expected)1518     private static void assertOneOf(int actual, int... expected) {
1519         assertOneOf(null, actual, expected);
1520     }
1521 
assertOneOf(String message, int actual, int... expected)1522     private static void assertOneOf(String message, int actual, int... expected) {
1523         for (int expectedValue : expected) {
1524             if (actual == expectedValue) {
1525                 return;
1526             }
1527         }
1528         fail(((message != null) ? message + ". " : "")
1529                 + "Expected one of " + Arrays.asList(expected)
1530                 + ", actual: <" + actual + ">");
1531     }
1532 
getWorkingSpec()1533     private KeyGenParameterSpec.Builder getWorkingSpec() {
1534         return getWorkingSpec(0);
1535     }
1536 
getWorkingSpec(int purposes)1537     private KeyGenParameterSpec.Builder getWorkingSpec(int purposes) {
1538         return new KeyGenParameterSpec.Builder(TEST_ALIAS_1, purposes);
1539     }
1540 }
1541