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