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                 .setUnlockedDeviceRequired(true)
782                 .build());
783         KeyPair keyPair = generator.generateKeyPair();
784         assertGeneratedKeyPairAndSelfSignedCertificate(
785                 keyPair,
786                 TEST_ALIAS_1,
787                 "EC",
788                 224,
789                 certSubject,
790                 certSerialNumber,
791                 certNotBefore,
792                 certNotAfter);
793         TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
794                 ECCurves.NIST_P_224_SPEC, ((ECKey) keyPair.getPrivate()).getParams());
795         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
796         assertEquals(224, keyInfo.getKeySize());
797         assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
798         assertOneOf(keyInfo.getOrigin(),
799                 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
800         assertEquals(
801                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
802                         | KeyProperties.PURPOSE_ENCRYPT,
803                 keyInfo.getPurposes());
804         assertEquals(keyValidityStart, keyInfo.getKeyValidityStart());
805         assertEquals(keyValidityEndDateForOrigination, keyInfo.getKeyValidityForOriginationEnd());
806         assertEquals(keyValidityEndDateForConsumption, keyInfo.getKeyValidityForConsumptionEnd());
807         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
808 
809         List<String> actualDigests = new ArrayList<String>(Arrays.asList(keyInfo.getDigests()));
810         // Keystore may have added DIGEST_NONE, to allow software digesting.
811         actualDigests.remove(KeyProperties.DIGEST_NONE);
812         TestUtils.assertContentsInAnyOrder(
813                 actualDigests, KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512);
814 
815         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
816         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
817         assertFalse(keyInfo.isUserAuthenticationRequired());
818         assertEquals(-1, keyInfo.getUserAuthenticationValidityDurationSeconds());
819     }
820 
testGenerate_RSA_ModernSpec_AsCustomAsPossible()821     public void testGenerate_RSA_ModernSpec_AsCustomAsPossible() throws Exception {
822         KeyPairGenerator generator = getRsaGenerator();
823         Date keyValidityStart = new Date(System.currentTimeMillis());
824         Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 1000000);
825         Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 10000000);
826 
827         Date certNotBefore = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 210);
828         Date certNotAfter = new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 210);
829         BigInteger certSerialNumber = new BigInteger("1234567890");
830         X500Principal certSubject = new X500Principal("cn=hello2");
831         generator.initialize(new KeyGenParameterSpec.Builder(
832                 TEST_ALIAS_1,
833                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
834                         | KeyProperties.PURPOSE_ENCRYPT)
835                 .setAlgorithmParameterSpec(
836                         new RSAKeyGenParameterSpec(3072, RSAKeyGenParameterSpec.F0))
837                 .setKeySize(3072)
838                 .setDigests(KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512)
839                 .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS,
840                         KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
841                 .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
842                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
843                         KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
844                 .setKeyValidityStart(keyValidityStart)
845                 .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
846                 .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
847                 .setCertificateSerialNumber(certSerialNumber)
848                 .setCertificateSubject(certSubject)
849                 .setCertificateNotBefore(certNotBefore)
850                 .setCertificateNotAfter(certNotAfter)
851                 .setUnlockedDeviceRequired(true)
852                 .build());
853         KeyPair keyPair = generator.generateKeyPair();
854         assertGeneratedKeyPairAndSelfSignedCertificate(
855                 keyPair,
856                 TEST_ALIAS_1,
857                 "RSA",
858                 3072,
859                 certSubject,
860                 certSerialNumber,
861                 certNotBefore,
862                 certNotAfter);
863         assertEquals(RSAKeyGenParameterSpec.F0,
864                 ((RSAPublicKey) keyPair.getPublic()).getPublicExponent());
865         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
866         assertEquals(3072, keyInfo.getKeySize());
867         assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
868         assertOneOf(keyInfo.getOrigin(),
869                 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
870         assertEquals(
871                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
872                         | KeyProperties.PURPOSE_ENCRYPT,
873                 keyInfo.getPurposes());
874         assertEquals(keyValidityStart, keyInfo.getKeyValidityStart());
875         assertEquals(keyValidityEndDateForOrigination, keyInfo.getKeyValidityForOriginationEnd());
876         assertEquals(keyValidityEndDateForConsumption, keyInfo.getKeyValidityForConsumptionEnd());
877 
878         List<String> actualDigests =
879 	    new ArrayList<String>(Arrays.asList(keyInfo.getDigests()));
880         // Keystore may have added DIGEST_NONE, to allow software digesting.
881         actualDigests.remove(KeyProperties.DIGEST_NONE);
882         TestUtils.assertContentsInAnyOrder(
883                 actualDigests, KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512);
884 
885         TestUtils.assertContentsInAnyOrder(Arrays.asList(keyInfo.getSignaturePaddings()),
886                 KeyProperties.SIGNATURE_PADDING_RSA_PKCS1,
887                 KeyProperties.SIGNATURE_PADDING_RSA_PSS);
888         MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getBlockModes()),
889                 KeyProperties.BLOCK_MODE_ECB);
890 
891         List<String> actualEncryptionPaddings =
892                 new ArrayList<String>(Arrays.asList(keyInfo.getEncryptionPaddings()));
893         // Keystore may have added ENCRYPTION_PADDING_NONE, to allow software padding.
894         actualEncryptionPaddings.remove(KeyProperties.ENCRYPTION_PADDING_NONE);
895         TestUtils.assertContentsInAnyOrder(actualEncryptionPaddings,
896                 KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
897                 KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1);
898 
899         assertFalse(keyInfo.isUserAuthenticationRequired());
900         assertEquals(-1, keyInfo.getUserAuthenticationValidityDurationSeconds());
901     }
902 
testGenerate_EC_ModernSpec_UsableForTLSPeerAuth()903     public void testGenerate_EC_ModernSpec_UsableForTLSPeerAuth() throws Exception {
904         KeyPairGenerator generator = getEcGenerator();
905         generator.initialize(new KeyGenParameterSpec.Builder(
906                 TEST_ALIAS_1,
907                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
908                 .setDigests(KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA384)
909                 .build());
910         KeyPair keyPair = generator.generateKeyPair();
911         assertGeneratedKeyPairAndSelfSignedCertificate(
912                 keyPair,
913                 TEST_ALIAS_1,
914                 "EC",
915                 256,
916                 DEFAULT_CERT_SUBJECT,
917                 DEFAULT_CERT_SERIAL_NUMBER,
918                 DEFAULT_CERT_NOT_BEFORE,
919                 DEFAULT_CERT_NOT_AFTER);
920         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
921         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
922         MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
923                 KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA384);
924         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
925         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
926         assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1);
927         assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1);
928     }
929 
testGenerate_RSA_ModernSpec_UsableForTLSPeerAuth()930     public void testGenerate_RSA_ModernSpec_UsableForTLSPeerAuth() throws Exception {
931         KeyPairGenerator generator = getRsaGenerator();
932         generator.initialize(new KeyGenParameterSpec.Builder(
933                 TEST_ALIAS_1,
934                 KeyProperties.PURPOSE_SIGN
935                         | KeyProperties.PURPOSE_VERIFY
936                         | KeyProperties.PURPOSE_DECRYPT)
937                 .setDigests(KeyProperties.DIGEST_NONE,
938                         KeyProperties.DIGEST_SHA256,
939                         KeyProperties.DIGEST_SHA512)
940                 .setEncryptionPaddings(
941                         KeyProperties.ENCRYPTION_PADDING_NONE,
942                         KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
943                 .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
944                 .build());
945         KeyPair keyPair = generator.generateKeyPair();
946         assertGeneratedKeyPairAndSelfSignedCertificate(
947                 keyPair,
948                 TEST_ALIAS_1,
949                 "RSA",
950                 2048,
951                 DEFAULT_CERT_SUBJECT,
952                 DEFAULT_CERT_SERIAL_NUMBER,
953                 DEFAULT_CERT_NOT_BEFORE,
954                 DEFAULT_CERT_NOT_AFTER);
955         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
956         MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
957         MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
958                 KeyProperties.DIGEST_NONE,
959                 KeyProperties.DIGEST_SHA256,
960                 KeyProperties.DIGEST_SHA512);
961         MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getSignaturePaddings()),
962                 KeyProperties.SIGNATURE_PADDING_RSA_PKCS1);
963         MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getEncryptionPaddings()),
964                 KeyProperties.ENCRYPTION_PADDING_NONE,
965                 KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1);
966         assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1);
967         assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1);
968     }
969 
970     // TODO: Test fingerprint-authorized and secure lock screen-authorized keys. These can't
971     // currently be tested here because CTS does not require that secure lock screen is set up and
972     // that at least one fingerprint is enrolled.
973 
testGenerate_EC_ModernSpec_KeyNotYetValid()974     public void testGenerate_EC_ModernSpec_KeyNotYetValid() throws Exception {
975         KeyPairGenerator generator = getEcGenerator();
976         Date validityStart = new Date(System.currentTimeMillis() + DAY_IN_MILLIS);
977         generator.initialize(new KeyGenParameterSpec.Builder(
978                 TEST_ALIAS_1,
979                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
980                 .setKeySize(256)
981                 .setDigests(KeyProperties.DIGEST_SHA256)
982                 .setKeyValidityStart(validityStart)
983                 .build());
984         KeyPair keyPair = generator.generateKeyPair();
985         assertGeneratedKeyPairAndSelfSignedCertificate(
986                 keyPair,
987                 TEST_ALIAS_1,
988                 "EC",
989                 256,
990                 DEFAULT_CERT_SUBJECT,
991                 DEFAULT_CERT_SERIAL_NUMBER,
992                 DEFAULT_CERT_NOT_BEFORE,
993                 DEFAULT_CERT_NOT_AFTER);
994         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
995         assertEquals(validityStart, keyInfo.getKeyValidityStart());
996     }
997 
testGenerate_RSA_ModernSpec_KeyExpiredForOrigination()998     public void testGenerate_RSA_ModernSpec_KeyExpiredForOrigination() throws Exception {
999         KeyPairGenerator generator = getRsaGenerator();
1000         Date originationEnd = new Date(System.currentTimeMillis() - DAY_IN_MILLIS);
1001         generator.initialize(new KeyGenParameterSpec.Builder(
1002                 TEST_ALIAS_1,
1003                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
1004                 .setKeySize(1024)
1005                 .setDigests(KeyProperties.DIGEST_SHA256)
1006                 .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
1007                 .setKeyValidityForOriginationEnd(originationEnd)
1008                 .build());
1009         KeyPair keyPair = generator.generateKeyPair();
1010         assertGeneratedKeyPairAndSelfSignedCertificate(
1011                 keyPair,
1012                 TEST_ALIAS_1,
1013                 "RSA",
1014                 1024,
1015                 DEFAULT_CERT_SUBJECT,
1016                 DEFAULT_CERT_SERIAL_NUMBER,
1017                 DEFAULT_CERT_NOT_BEFORE,
1018                 DEFAULT_CERT_NOT_AFTER);
1019         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
1020         assertEquals(originationEnd, keyInfo.getKeyValidityForOriginationEnd());
1021     }
1022 
testGenerate_EC_ModernSpec_SupportedSizes()1023     public void testGenerate_EC_ModernSpec_SupportedSizes() throws Exception {
1024         assertKeyGenUsingECSizeOnlyUsesCorrectCurve(224, ECCurves.NIST_P_224_SPEC);
1025         assertKeyGenUsingECSizeOnlyUsesCorrectCurve(256, ECCurves.NIST_P_256_SPEC);
1026         assertKeyGenUsingECSizeOnlyUsesCorrectCurve(384, ECCurves.NIST_P_384_SPEC);
1027         assertKeyGenUsingECSizeOnlyUsesCorrectCurve(521, ECCurves.NIST_P_521_SPEC);
1028     }
1029 
testGenerate_EC_ModernSpec_UnsupportedSizesRejected()1030     public void testGenerate_EC_ModernSpec_UnsupportedSizesRejected() throws Exception {
1031         for (int keySizeBits = 0; keySizeBits <= 1024; keySizeBits++) {
1032             if ((keySizeBits == 224) || (keySizeBits == 256) || (keySizeBits == 384)
1033                     || (keySizeBits == 521)) {
1034                 // Skip supported sizes
1035                 continue;
1036             }
1037             KeyPairGenerator generator = getEcGenerator();
1038 
1039             try {
1040                 generator.initialize(new KeyGenParameterSpec.Builder(
1041                         TEST_ALIAS_1,
1042                         KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
1043                         .setKeySize(keySizeBits)
1044                         .build());
1045                 fail("EC KeyPairGenerator initialized with unsupported key size: "
1046                         + keySizeBits + " bits");
1047             } catch (InvalidAlgorithmParameterException expected) {
1048             }
1049         }
1050     }
1051 
testGenerate_EC_ModernSpec_SupportedNamedCurves()1052     public void testGenerate_EC_ModernSpec_SupportedNamedCurves() throws Exception {
1053         assertKeyGenUsingECNamedCurveSupported("P-224", ECCurves.NIST_P_224_SPEC);
1054         assertKeyGenUsingECNamedCurveSupported("p-224", ECCurves.NIST_P_224_SPEC);
1055         assertKeyGenUsingECNamedCurveSupported("secp224r1", ECCurves.NIST_P_224_SPEC);
1056         assertKeyGenUsingECNamedCurveSupported("SECP224R1", ECCurves.NIST_P_224_SPEC);
1057 
1058         assertKeyGenUsingECNamedCurveSupported("P-256", ECCurves.NIST_P_256_SPEC);
1059         assertKeyGenUsingECNamedCurveSupported("p-256", ECCurves.NIST_P_256_SPEC);
1060         assertKeyGenUsingECNamedCurveSupported("secp256r1", ECCurves.NIST_P_256_SPEC);
1061         assertKeyGenUsingECNamedCurveSupported("SECP256R1", ECCurves.NIST_P_256_SPEC);
1062         assertKeyGenUsingECNamedCurveSupported("prime256v1", ECCurves.NIST_P_256_SPEC);
1063         assertKeyGenUsingECNamedCurveSupported("PRIME256V1", ECCurves.NIST_P_256_SPEC);
1064 
1065         assertKeyGenUsingECNamedCurveSupported("P-384", ECCurves.NIST_P_384_SPEC);
1066         assertKeyGenUsingECNamedCurveSupported("p-384", ECCurves.NIST_P_384_SPEC);
1067         assertKeyGenUsingECNamedCurveSupported("secp384r1", ECCurves.NIST_P_384_SPEC);
1068         assertKeyGenUsingECNamedCurveSupported("SECP384R1", ECCurves.NIST_P_384_SPEC);
1069 
1070         assertKeyGenUsingECNamedCurveSupported("P-521", ECCurves.NIST_P_521_SPEC);
1071         assertKeyGenUsingECNamedCurveSupported("p-521", ECCurves.NIST_P_521_SPEC);
1072         assertKeyGenUsingECNamedCurveSupported("secp521r1", ECCurves.NIST_P_521_SPEC);
1073         assertKeyGenUsingECNamedCurveSupported("SECP521R1", ECCurves.NIST_P_521_SPEC);
1074     }
1075 
testGenerate_RSA_ModernSpec_SupportedSizes()1076     public void testGenerate_RSA_ModernSpec_SupportedSizes() throws Exception {
1077         assertKeyGenUsingRSASizeOnlySupported(512);
1078         assertKeyGenUsingRSASizeOnlySupported(768);
1079         assertKeyGenUsingRSASizeOnlySupported(1024);
1080         assertKeyGenUsingRSASizeOnlySupported(2048);
1081         assertKeyGenUsingRSASizeOnlySupported(3072);
1082         assertKeyGenUsingRSASizeOnlySupported(4096);
1083 
1084         // The above use F4. Check that F0 is supported as well, just in case somebody is crazy
1085         // enough.
1086         assertKeyGenUsingRSAKeyGenParameterSpecSupported(new RSAKeyGenParameterSpec(
1087                 2048, RSAKeyGenParameterSpec.F0));
1088     }
1089 
testGenerate_RSA_IndCpaEnforced()1090     public void testGenerate_RSA_IndCpaEnforced() throws Exception {
1091         KeyGenParameterSpec.Builder goodBuilder = new KeyGenParameterSpec.Builder(
1092                 TEST_ALIAS_1, KeyProperties.PURPOSE_ENCRYPT)
1093                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
1094                         KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1);
1095         assertKeyGenInitSucceeds("RSA", goodBuilder.build());
1096 
1097         // Should be fine because IND-CPA restriction applies only to encryption keys
1098         assertKeyGenInitSucceeds("RSA",
1099                 TestUtils.buildUpon(goodBuilder, KeyProperties.PURPOSE_DECRYPT)
1100                         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
1101                         .build());
1102 
1103         assertKeyGenInitThrowsInvalidAlgorithmParameterException("RSA",
1104                 TestUtils.buildUpon(goodBuilder)
1105                         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
1106                         .build());
1107 
1108         assertKeyGenInitSucceeds("RSA",
1109                 TestUtils.buildUpon(goodBuilder)
1110                         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
1111                         .setRandomizedEncryptionRequired(false)
1112                         .build());
1113 
1114         // Should fail because PKCS#7 padding doesn't work with RSA
1115         assertKeyGenInitThrowsInvalidAlgorithmParameterException("RSA",
1116                 TestUtils.buildUpon(goodBuilder)
1117                         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
1118                         .build());
1119     }
1120 
testGenerate_EC_IndCpaEnforced()1121     public void testGenerate_EC_IndCpaEnforced() throws Exception {
1122         KeyGenParameterSpec.Builder goodBuilder = new KeyGenParameterSpec.Builder(
1123                 TEST_ALIAS_2, KeyProperties.PURPOSE_ENCRYPT);
1124         assertKeyGenInitSucceeds("EC", goodBuilder.build());
1125 
1126         // Should be fine because IND-CPA restriction applies only to encryption keys
1127         assertKeyGenInitSucceeds("EC",
1128                 TestUtils.buildUpon(goodBuilder, KeyProperties.PURPOSE_DECRYPT)
1129                         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
1130                         .build());
1131 
1132         assertKeyGenInitThrowsInvalidAlgorithmParameterException("EC",
1133                 TestUtils.buildUpon(goodBuilder)
1134                         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
1135                         .build());
1136 
1137         assertKeyGenInitSucceeds("EC",
1138                 TestUtils.buildUpon(goodBuilder)
1139                         .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
1140                         .setRandomizedEncryptionRequired(false)
1141                         .build());
1142     }
1143 
1144     // http://b/28384942
testGenerateWithFarsiLocale()1145     public void testGenerateWithFarsiLocale() throws Exception {
1146         Locale defaultLocale = Locale.getDefault();
1147         // Note that we use farsi here because its number formatter doesn't use
1148         // arabic digits.
1149         Locale fa_IR = Locale.forLanguageTag("fa-IR");
1150         DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(fa_IR);
1151         assertFalse('0' == dfs.getZeroDigit());
1152 
1153         Locale.setDefault(fa_IR);
1154         try {
1155             KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance(
1156                     KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
1157 
1158             keyGenerator.initialize(new KeyGenParameterSpec.Builder(
1159                    TEST_ALIAS_1, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
1160                    .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
1161                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
1162                    .build());
1163 
1164             keyGenerator.generateKeyPair();
1165         } finally {
1166             Locale.setDefault(defaultLocale);
1167         }
1168     }
1169 
assertKeyGenInitSucceeds(String algorithm, AlgorithmParameterSpec params)1170     private void assertKeyGenInitSucceeds(String algorithm, AlgorithmParameterSpec params)
1171             throws Exception {
1172         KeyPairGenerator generator = getGenerator(algorithm);
1173         generator.initialize(params);
1174     }
1175 
assertKeyGenInitThrowsInvalidAlgorithmParameterException( String algorithm, AlgorithmParameterSpec params)1176     private void assertKeyGenInitThrowsInvalidAlgorithmParameterException(
1177             String algorithm, AlgorithmParameterSpec params) throws Exception {
1178         KeyPairGenerator generator = getGenerator(algorithm);
1179         try {
1180             generator.initialize(params);
1181             fail();
1182         } catch (InvalidAlgorithmParameterException expected) {}
1183     }
1184 
assertKeyGenUsingECSizeOnlyUsesCorrectCurve( int keySizeBits, ECParameterSpec expectedParams)1185     private void assertKeyGenUsingECSizeOnlyUsesCorrectCurve(
1186             int keySizeBits, ECParameterSpec expectedParams) throws Exception {
1187         KeyPairGenerator generator = getEcGenerator();
1188         generator.initialize(new KeyGenParameterSpec.Builder(
1189                 TEST_ALIAS_1,
1190                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
1191                 .setKeySize(keySizeBits)
1192                 .build(),
1193                 mRng);
1194         mRng.resetCounters();
1195         KeyPair keyPair = generator.generateKeyPair();
1196         long consumedEntropyAmountBytes = mRng.getOutputSizeBytes();
1197         int expectedKeySize = expectedParams.getCurve().getField().getFieldSize();
1198         assertGeneratedKeyPairAndSelfSignedCertificate(
1199                 keyPair,
1200                 TEST_ALIAS_1,
1201                 "EC",
1202                 expectedKeySize,
1203                 DEFAULT_CERT_SUBJECT,
1204                 DEFAULT_CERT_SERIAL_NUMBER,
1205                 DEFAULT_CERT_NOT_BEFORE,
1206                 DEFAULT_CERT_NOT_AFTER);
1207         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
1208         assertEquals(expectedKeySize, keyInfo.getKeySize());
1209         TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
1210                 expectedParams,
1211                 ((ECKey) keyPair.getPublic()).getParams());
1212         assertEquals(((keySizeBits + 7) / 8) * 8, consumedEntropyAmountBytes * 8);
1213     }
1214 
assertKeyGenUsingECNamedCurveSupported( String curveName, ECParameterSpec expectedParams)1215     private void assertKeyGenUsingECNamedCurveSupported(
1216             String curveName, ECParameterSpec expectedParams) throws Exception {
1217         KeyPairGenerator generator = getEcGenerator();
1218         generator.initialize(new KeyGenParameterSpec.Builder(
1219                 TEST_ALIAS_1,
1220                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
1221                 .setAlgorithmParameterSpec(new ECGenParameterSpec(curveName))
1222                 .build(),
1223                 mRng);
1224         mRng.resetCounters();
1225         KeyPair keyPair = generator.generateKeyPair();
1226         long consumedEntropyAmountBytes = mRng.getOutputSizeBytes();
1227         int expectedKeySize = expectedParams.getCurve().getField().getFieldSize();
1228         assertGeneratedKeyPairAndSelfSignedCertificate(
1229                 keyPair,
1230                 TEST_ALIAS_1,
1231                 "EC",
1232                 expectedKeySize,
1233                 DEFAULT_CERT_SUBJECT,
1234                 DEFAULT_CERT_SERIAL_NUMBER,
1235                 DEFAULT_CERT_NOT_BEFORE,
1236                 DEFAULT_CERT_NOT_AFTER);
1237         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
1238         assertEquals(expectedKeySize, keyInfo.getKeySize());
1239         TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
1240                 expectedParams,
1241                 ((ECKey) keyPair.getPublic()).getParams());
1242         assertEquals(((expectedKeySize + 7) / 8) * 8, consumedEntropyAmountBytes * 8);
1243     }
1244 
assertKeyGenUsingRSASizeOnlySupported(int keySizeBits)1245     private void assertKeyGenUsingRSASizeOnlySupported(int keySizeBits) throws Exception {
1246         KeyPairGenerator generator = getRsaGenerator();
1247         generator.initialize(new KeyGenParameterSpec.Builder(
1248                 TEST_ALIAS_1,
1249                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
1250                 .setKeySize(keySizeBits)
1251                 .build(),
1252                 mRng);
1253         mRng.resetCounters();
1254         KeyPair keyPair = generator.generateKeyPair();
1255         long consumedEntropyAmountBytes = mRng.getOutputSizeBytes();
1256         assertGeneratedKeyPairAndSelfSignedCertificate(
1257                 keyPair,
1258                 TEST_ALIAS_1,
1259                 "RSA",
1260                 keySizeBits,
1261                 DEFAULT_CERT_SUBJECT,
1262                 DEFAULT_CERT_SERIAL_NUMBER,
1263                 DEFAULT_CERT_NOT_BEFORE,
1264                 DEFAULT_CERT_NOT_AFTER);
1265         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
1266         assertEquals(keySizeBits, keyInfo.getKeySize());
1267         assertEquals(((keySizeBits + 7) / 8) * 8, consumedEntropyAmountBytes * 8);
1268     }
1269 
assertKeyGenUsingRSAKeyGenParameterSpecSupported( RSAKeyGenParameterSpec spec)1270     private void assertKeyGenUsingRSAKeyGenParameterSpecSupported(
1271             RSAKeyGenParameterSpec spec) throws Exception {
1272         KeyPairGenerator generator = getRsaGenerator();
1273         generator.initialize(new KeyGenParameterSpec.Builder(
1274                 TEST_ALIAS_1,
1275                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
1276                 .setAlgorithmParameterSpec(spec)
1277                 .build(),
1278                 mRng);
1279         mRng.resetCounters();
1280         KeyPair keyPair = generator.generateKeyPair();
1281         long consumedEntropyAmountBytes = mRng.getOutputSizeBytes();
1282         assertGeneratedKeyPairAndSelfSignedCertificate(
1283                 keyPair,
1284                 TEST_ALIAS_1,
1285                 "RSA",
1286                 spec.getKeysize(),
1287                 DEFAULT_CERT_SUBJECT,
1288                 DEFAULT_CERT_SERIAL_NUMBER,
1289                 DEFAULT_CERT_NOT_BEFORE,
1290                 DEFAULT_CERT_NOT_AFTER);
1291         assertEquals(spec.getPublicExponent(),
1292                 ((RSAPublicKey) keyPair.getPublic()).getPublicExponent());
1293         KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
1294         assertEquals(spec.getKeysize(), keyInfo.getKeySize());
1295         assertEquals(((spec.getKeysize() + 7) / 8) * 8, consumedEntropyAmountBytes * 8);
1296     }
1297 
assertSelfSignedCertificateSignatureVerifies(Certificate certificate)1298     private static void assertSelfSignedCertificateSignatureVerifies(Certificate certificate) {
1299         try {
1300             certificate.verify(certificate.getPublicKey());
1301         } catch (Exception e) {
1302             throw new RuntimeException("Failed to verify self-signed certificate signature", e);
1303         }
1304     }
1305 
assertGeneratedKeyPairAndSelfSignedCertificate( KeyPair keyPair, String alias, String expectedKeyAlgorithm, int expectedKeySize, X500Principal expectedCertSubject, BigInteger expectedCertSerialNumber, Date expectedCertNotBefore, Date expectedCertNotAfter)1306     private void assertGeneratedKeyPairAndSelfSignedCertificate(
1307             KeyPair keyPair, String alias,
1308             String expectedKeyAlgorithm,
1309             int expectedKeySize,
1310             X500Principal expectedCertSubject,
1311             BigInteger expectedCertSerialNumber,
1312             Date expectedCertNotBefore,
1313             Date expectedCertNotAfter)
1314             throws Exception {
1315         assertNotNull(keyPair);
1316         TestUtils.assertKeyPairSelfConsistent(keyPair);
1317         TestUtils.assertKeySize(expectedKeySize, keyPair);
1318         assertEquals(expectedKeyAlgorithm, keyPair.getPublic().getAlgorithm());
1319         TestUtils.assertKeyStoreKeyPair(mKeyStore, alias, keyPair);
1320 
1321         X509Certificate cert = (X509Certificate) mKeyStore.getCertificate(alias);
1322         assertEquals(keyPair.getPublic(), cert.getPublicKey());
1323         assertX509CertificateParameters(cert,
1324                 expectedCertSubject,
1325                 expectedCertSerialNumber,
1326                 expectedCertNotBefore,
1327                 expectedCertNotAfter);
1328         // Assert that the certificate chain consists only of the above certificate
1329         MoreAsserts.assertContentsInOrder(
1330                 Arrays.asList(mKeyStore.getCertificateChain(alias)), cert);
1331     }
1332 
assertSelfSignedCertificateSignatureVerifies(String alias)1333     private void assertSelfSignedCertificateSignatureVerifies(String alias) throws Exception {
1334         assertSelfSignedCertificateSignatureVerifies(mKeyStore.getCertificate(alias));
1335     }
1336 
assertKeyPairAndCertificateUsableForTLSPeerAuthentication(String alias)1337     private void assertKeyPairAndCertificateUsableForTLSPeerAuthentication(String alias)
1338             throws Exception {
1339         assertUsableForTLSPeerAuthentication(
1340                 (PrivateKey) mKeyStore.getKey(alias, null),
1341                 mKeyStore.getCertificateChain(alias));
1342     }
1343 
assertX509CertificateParameters( X509Certificate actualCert, X500Principal expectedSubject, BigInteger expectedSerialNumber, Date expectedNotBefore, Date expectedNotAfter)1344     private static void assertX509CertificateParameters(
1345             X509Certificate actualCert,
1346             X500Principal expectedSubject, BigInteger expectedSerialNumber,
1347             Date expectedNotBefore, Date expectedNotAfter) {
1348         assertEquals(expectedSubject, actualCert.getSubjectDN());
1349         assertEquals(expectedSubject, actualCert.getIssuerDN());
1350         assertEquals(expectedSerialNumber, actualCert.getSerialNumber());
1351         assertDateEquals(expectedNotBefore, actualCert.getNotBefore());
1352         assertDateEquals(expectedNotAfter, actualCert.getNotAfter());
1353     }
1354 
assertUsableForTLSPeerAuthentication( PrivateKey privateKey, Certificate[] certificateChain)1355     private static void assertUsableForTLSPeerAuthentication(
1356             PrivateKey privateKey,
1357             Certificate[] certificateChain) throws Exception {
1358         // Set up both client and server to use the same private key + cert, and to trust that cert
1359         // when it's presented by peer. This exercises the use of the private key both in client
1360         // and server scenarios.
1361         X509Certificate[] x509CertificateChain = new X509Certificate[certificateChain.length];
1362         for (int i = 0; i < certificateChain.length; i++) {
1363             x509CertificateChain[i] = (X509Certificate) certificateChain[i];
1364         }
1365         TestKeyStore serverKeyStore = TestKeyStore.getServer();
1366         // Make the peer trust the root certificate in the chain. As opposed to making the peer
1367         // trust the leaf certificate, this will ensure that the whole chain verifies.
1368         serverKeyStore.keyStore.setCertificateEntry(
1369                 "trusted", certificateChain[certificateChain.length - 1]);
1370         SSLContext serverContext = TestSSLContext.createSSLContext("TLS",
1371                 new KeyManager[] {
1372                     TestKeyManager.wrap(new MyKeyManager(privateKey, x509CertificateChain))
1373                 },
1374                 TestKeyStore.createTrustManagers(serverKeyStore.keyStore));
1375         SSLContext clientContext = serverContext;
1376 
1377         if ("EC".equalsIgnoreCase(privateKey.getAlgorithm())) {
1378             // As opposed to RSA (see below) EC keys are used in the same way in all cipher suites.
1379             // Assert that the key works with the default list of cipher suites.
1380             assertSSLConnectionWithClientAuth(
1381                     clientContext, serverContext, null, x509CertificateChain, x509CertificateChain);
1382         } else if ("RSA".equalsIgnoreCase(privateKey.getAlgorithm())) {
1383             // RSA keys are used differently between Forward Secure and non-Forward Secure cipher
1384             // suites. For example, RSA key exchange requires the server to decrypt using its RSA
1385             // private key, whereas ECDHE_RSA key exchange requires the server to sign usnig its
1386             // RSA private key. We thus assert that the key works with Forward Secure cipher suites
1387             // and that it works with non-Forward Secure cipher suites.
1388             List<String> fsCipherSuites = new ArrayList<String>();
1389             List<String> nonFsCipherSuites = new ArrayList<String>();
1390             for (String cipherSuite : clientContext.getDefaultSSLParameters().getCipherSuites()) {
1391                 if (cipherSuite.contains("_ECDHE_RSA_") || cipherSuite.contains("_DHE_RSA_")) {
1392                     fsCipherSuites.add(cipherSuite);
1393                 } else if (cipherSuite.contains("_RSA_WITH_")) {
1394                     nonFsCipherSuites.add(cipherSuite);
1395                 }
1396             }
1397             assertFalse("No FS RSA cipher suites enabled by default", fsCipherSuites.isEmpty());
1398             assertFalse("No non-FS RSA cipher suites enabled", nonFsCipherSuites.isEmpty());
1399 
1400             // Assert that the key works with RSA Forward Secure cipher suites.
1401             assertSSLConnectionWithClientAuth(
1402                     clientContext, serverContext, fsCipherSuites.toArray(new String[0]),
1403                     x509CertificateChain, x509CertificateChain);
1404             // Assert that the key works with RSA non-Forward Secure cipher suites.
1405             assertSSLConnectionWithClientAuth(
1406                     clientContext, serverContext, nonFsCipherSuites.toArray(new String[0]),
1407                     x509CertificateChain, x509CertificateChain);
1408         } else {
1409             fail("Unsupported key algorithm: " + privateKey.getAlgorithm());
1410         }
1411     }
1412 
assertSSLConnectionWithClientAuth( SSLContext clientContext, SSLContext serverContext, String[] enabledCipherSuites, X509Certificate[] expectedClientCertChain, X509Certificate[] expectedServerCertChain)1413     private static void assertSSLConnectionWithClientAuth(
1414             SSLContext clientContext, SSLContext serverContext, String[] enabledCipherSuites,
1415             X509Certificate[] expectedClientCertChain, X509Certificate[] expectedServerCertChain)
1416             throws Exception {
1417         SSLServerSocket serverSocket = (SSLServerSocket) serverContext.getServerSocketFactory()
1418                 .createServerSocket(0);
1419         InetAddress host = InetAddress.getLocalHost();
1420         int port = serverSocket.getLocalPort();
1421         SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(host, port);
1422 
1423         final SSLSocket server = (SSLSocket) serverSocket.accept();
1424         ExecutorService executor = Executors.newSingleThreadExecutor();
1425         Future<Certificate[]> future = executor.submit(new Callable<Certificate[]>() {
1426             @Override
1427             public Certificate[] call() throws Exception {
1428                 server.setNeedClientAuth(true);
1429                 server.setWantClientAuth(true);
1430                 server.startHandshake();
1431                 return server.getSession().getPeerCertificates();
1432             }
1433         });
1434         executor.shutdown();
1435         if (enabledCipherSuites != null) {
1436             client.setEnabledCipherSuites(enabledCipherSuites);
1437         }
1438         client.startHandshake();
1439         Certificate[] usedServerCerts = client.getSession().getPeerCertificates();
1440         Certificate[] usedClientCerts = future.get();
1441         client.close();
1442         server.close();
1443 
1444         assertNotNull(usedServerCerts);
1445         assertEquals(Arrays.asList(expectedServerCertChain), Arrays.asList(usedServerCerts));
1446 
1447         assertNotNull(usedClientCerts);
1448         assertEquals(Arrays.asList(expectedClientCertChain), Arrays.asList(usedClientCerts));
1449     }
1450 
1451     private static class MyKeyManager extends X509ExtendedKeyManager {
1452         private final PrivateKey key;
1453         private final X509Certificate[] chain;
1454 
MyKeyManager(PrivateKey key, X509Certificate[] certChain)1455         public MyKeyManager(PrivateKey key, X509Certificate[] certChain) {
1456             this.key = key;
1457             this.chain = certChain;
1458         }
1459 
1460         @Override
chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket)1461         public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
1462             return "fake";
1463         }
1464 
1465         @Override
chooseServerAlias(String keyType, Principal[] issuers, Socket socket)1466         public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
1467             return "fake";
1468         }
1469 
1470         @Override
getCertificateChain(String alias)1471         public X509Certificate[] getCertificateChain(String alias) {
1472             return chain;
1473         }
1474 
1475         @Override
getClientAliases(String keyType, Principal[] issuers)1476         public String[] getClientAliases(String keyType, Principal[] issuers) {
1477             return new String[] { "fake" };
1478         }
1479 
1480         @Override
getServerAliases(String keyType, Principal[] issuers)1481         public String[] getServerAliases(String keyType, Principal[] issuers) {
1482             return new String[] { "fake" };
1483         }
1484 
1485         @Override
getPrivateKey(String alias)1486         public PrivateKey getPrivateKey(String alias) {
1487             return key;
1488         }
1489     }
1490 
1491 
assertDateEquals(Date date1, Date date2)1492     private static void assertDateEquals(Date date1, Date date2) {
1493         assertDateEquals(null, date1, date2);
1494     }
1495 
assertDateEquals(String message, Date date1, Date date2)1496     private static void assertDateEquals(String message, Date date1, Date date2) {
1497         SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss");
1498 
1499         String result1 = formatter.format(date1);
1500         String result2 = formatter.format(date2);
1501 
1502         assertEquals(message, result1, result2);
1503     }
1504 
getRsaGenerator()1505     private KeyPairGenerator getRsaGenerator()
1506             throws NoSuchAlgorithmException, NoSuchProviderException {
1507         return getGenerator("RSA");
1508     }
1509 
getEcGenerator()1510     private KeyPairGenerator getEcGenerator()
1511             throws NoSuchAlgorithmException, NoSuchProviderException {
1512         return getGenerator("EC");
1513     }
1514 
getGenerator(String algorithm)1515     private KeyPairGenerator getGenerator(String algorithm)
1516             throws NoSuchAlgorithmException, NoSuchProviderException {
1517         return KeyPairGenerator.getInstance(algorithm, "AndroidKeyStore");
1518     }
1519 
assertOneOf(int actual, int... expected)1520     private static void assertOneOf(int actual, int... expected) {
1521         assertOneOf(null, actual, expected);
1522     }
1523 
assertOneOf(String message, int actual, int... expected)1524     private static void assertOneOf(String message, int actual, int... expected) {
1525         for (int expectedValue : expected) {
1526             if (actual == expectedValue) {
1527                 return;
1528             }
1529         }
1530         fail(((message != null) ? message + ". " : "")
1531                 + "Expected one of " + Arrays.asList(expected)
1532                 + ", actual: <" + actual + ">");
1533     }
1534 
getWorkingSpec()1535     private KeyGenParameterSpec.Builder getWorkingSpec() {
1536         return getWorkingSpec(0);
1537     }
1538 
getWorkingSpec(int purposes)1539     private KeyGenParameterSpec.Builder getWorkingSpec(int purposes) {
1540         return new KeyGenParameterSpec.Builder(TEST_ALIAS_1, purposes);
1541     }
1542 }
1543