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