/*
 * Copyright 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.keystore.cts;

import android.security.KeyPairGeneratorSpec;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyInfo;
import android.security.keystore.KeyProperties;
import android.test.AndroidTestCase;
import android.test.MoreAsserts;

import java.math.BigInteger;
import java.net.InetAddress;
import java.net.Socket;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.interfaces.ECKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.X509ExtendedKeyManager;
import javax.security.auth.x500.X500Principal;

import libcore.java.security.TestKeyStore;
import libcore.javax.net.ssl.TestKeyManager;
import libcore.javax.net.ssl.TestSSLContext;

public class KeyPairGeneratorTest extends AndroidTestCase {
    private KeyStore mKeyStore;

    private CountingSecureRandom mRng;

    private static final String TEST_ALIAS_1 = "test1";

    private static final String TEST_ALIAS_2 = "test2";

    private static final String TEST_ALIAS_3 = "test3";

    private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1");

    private static final X500Principal TEST_DN_2 = new X500Principal("CN=test2");

    private static final BigInteger TEST_SERIAL_1 = BigInteger.ONE;

    private static final BigInteger TEST_SERIAL_2 = BigInteger.valueOf(2L);

    private static final long NOW_MILLIS = System.currentTimeMillis();

    /* We have to round this off because X509v3 doesn't store milliseconds. */
    private static final Date NOW = new Date(NOW_MILLIS - (NOW_MILLIS % 1000L));

    @SuppressWarnings("deprecation")
    private static final Date NOW_PLUS_10_YEARS = new Date(NOW.getYear() + 10, 0, 1);

    private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
    private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
    private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1970
    private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mRng = new CountingSecureRandom();
        mKeyStore = KeyStore.getInstance("AndroidKeyStore");
        mKeyStore.load(null, null);
    }

    public void testInitialize_LegacySpec() throws Exception {
        @SuppressWarnings("deprecation")
        KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(getContext())
                .setAlias(TEST_ALIAS_1)
                .setSubject(TEST_DN_1)
                .setSerialNumber(TEST_SERIAL_1)
                .setStartDate(NOW)
                .setEndDate(NOW_PLUS_10_YEARS)
                .build();
        getRsaGenerator().initialize(spec);
        getRsaGenerator().initialize(spec, new SecureRandom());

        getEcGenerator().initialize(spec);
        getEcGenerator().initialize(spec, new SecureRandom());
    }

    public void testInitialize_ModernSpec() throws Exception {
        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
                TEST_ALIAS_1,
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
                .build();
        getRsaGenerator().initialize(spec);
        getRsaGenerator().initialize(spec, new SecureRandom());

        getEcGenerator().initialize(spec);
        getEcGenerator().initialize(spec, new SecureRandom());
    }

    public void testInitialize_KeySizeOnly() throws Exception {
        try {
            getRsaGenerator().initialize(1024);
            fail("KeyPairGenerator should not support setting the key size");
        } catch (IllegalArgumentException success) {
        }

        try {
            getEcGenerator().initialize(256);
            fail("KeyPairGenerator should not support setting the key size");
        } catch (IllegalArgumentException success) {
        }
    }

    public void testInitialize_KeySizeAndSecureRandomOnly()
            throws Exception {
        try {
            getRsaGenerator().initialize(1024, new SecureRandom());
            fail("KeyPairGenerator should not support setting the key size");
        } catch (IllegalArgumentException success) {
        }

        try {
            getEcGenerator().initialize(1024, new SecureRandom());
            fail("KeyPairGenerator should not support setting the key size");
        } catch (IllegalArgumentException success) {
        }
    }

    @SuppressWarnings("deprecation")
    public void testGenerate_EC_LegacySpec() throws Exception {
        // There are three legacy ways to generate an EC key pair using Android Keystore
        // KeyPairGenerator:
        // 1. Use an RSA KeyPairGenerator and specify EC as key type,
        // 2. Use an EC KeyPairGenerator and specify EC as key type,
        // 3. Use an EC KeyPairGenerator and leave the key type unspecified.
        //
        // We test all three.

        // 1. Use an RSA KeyPairGenerator and specify EC as key type.
        KeyPairGenerator generator = getRsaGenerator();
        generator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
                .setAlias(TEST_ALIAS_1)
                .setKeyType("EC")
                .setSubject(TEST_DN_1)
                .setSerialNumber(TEST_SERIAL_1)
                .setStartDate(NOW)
                .setEndDate(NOW_PLUS_10_YEARS)
                .build());
        KeyPair keyPair = generator.generateKeyPair();
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair,
                TEST_ALIAS_1,
                "EC",
                256,
                TEST_DN_1,
                TEST_SERIAL_1, NOW,
                NOW_PLUS_10_YEARS);
        assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1);
        assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1);
        TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
                ECCurves.NIST_P_256_SPEC, ((ECPublicKey) keyPair.getPublic()).getParams());
        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
        assertEquals(256, keyInfo.getKeySize());
        assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
        assertOneOf(keyInfo.getOrigin(),
                KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
        assertEquals(
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY,
                keyInfo.getPurposes());
        assertFalse(keyInfo.isUserAuthenticationRequired());
        assertEquals(null, keyInfo.getKeyValidityStart());
        assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
        assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
                KeyProperties.DIGEST_NONE);
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));

        // 2. Use an EC KeyPairGenerator and specify EC as key type.
        generator = getEcGenerator();
        generator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
                .setAlias(TEST_ALIAS_2)
                .setKeyType("EC")
                .setSubject(TEST_DN_1)
                .setSerialNumber(TEST_SERIAL_1)
                .setStartDate(NOW)
                .setEndDate(NOW_PLUS_10_YEARS)
                .build());
        keyPair = generator.generateKeyPair();
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair,
                TEST_ALIAS_2,
                "EC",
                256,
                TEST_DN_1,
                TEST_SERIAL_1,
                NOW,
                NOW_PLUS_10_YEARS);
        assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_2);
        assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_2);
        TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
                ECCurves.NIST_P_256_SPEC, ((ECPublicKey) keyPair.getPublic()).getParams());
        keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
        assertEquals(256, keyInfo.getKeySize());
        assertEquals(TEST_ALIAS_2, keyInfo.getKeystoreAlias());
        assertOneOf(keyInfo.getOrigin(),
                KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
        assertEquals(
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY,
                keyInfo.getPurposes());
        assertFalse(keyInfo.isUserAuthenticationRequired());
        assertEquals(null, keyInfo.getKeyValidityStart());
        assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
        assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
                KeyProperties.DIGEST_NONE);
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));

        // 3. Use an EC KeyPairGenerator and leave the key type unspecified.
        generator = getEcGenerator();
        generator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
                .setAlias(TEST_ALIAS_3)
                .setSubject(TEST_DN_1)
                .setSerialNumber(TEST_SERIAL_1)
                .setStartDate(NOW)
                .setEndDate(NOW_PLUS_10_YEARS)
                .build());
        keyPair = generator.generateKeyPair();
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair,
                TEST_ALIAS_3,
                "EC",
                256,
                TEST_DN_1,
                TEST_SERIAL_1,
                NOW,
                NOW_PLUS_10_YEARS);
        assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_3);
        assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_3);
        TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
                ECCurves.NIST_P_256_SPEC, ((ECPublicKey) keyPair.getPublic()).getParams());
        keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
        assertEquals(256, keyInfo.getKeySize());
        assertEquals(TEST_ALIAS_3, keyInfo.getKeystoreAlias());
        assertOneOf(keyInfo.getOrigin(),
                KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
        assertEquals(
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY,
                keyInfo.getPurposes());
        assertFalse(keyInfo.isUserAuthenticationRequired());
        assertEquals(null, keyInfo.getKeyValidityStart());
        assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
        assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
                KeyProperties.DIGEST_NONE);
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
    }

    public void testGenerate_RSA_LegacySpec() throws Exception {
        KeyPairGenerator generator = getRsaGenerator();
        generator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
                .setAlias(TEST_ALIAS_1)
                .setSubject(TEST_DN_1)
                .setSerialNumber(TEST_SERIAL_1)
                .setStartDate(NOW)
                .setEndDate(NOW_PLUS_10_YEARS)
                .build());
        KeyPair keyPair = generator.generateKeyPair();
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair,
                TEST_ALIAS_1,
                "RSA",
                2048,
                TEST_DN_1,
                TEST_SERIAL_1,
                NOW,
                NOW_PLUS_10_YEARS);
        assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1);
        assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1);
        assertEquals(RSAKeyGenParameterSpec.F4,
                ((RSAPublicKey) keyPair.getPublic()).getPublicExponent());
        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
        assertEquals(2048, keyInfo.getKeySize());
        assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
        assertOneOf(keyInfo.getOrigin(),
                KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
        assertEquals(
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
                        | KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
                keyInfo.getPurposes());
        assertFalse(keyInfo.isUserAuthenticationRequired());
        assertEquals(null, keyInfo.getKeyValidityStart());
        assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
        assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
                KeyProperties.DIGEST_NONE);
        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getEncryptionPaddings()),
                KeyProperties.ENCRYPTION_PADDING_NONE);
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
    }

    public void testGenerate_ReplacesOldEntryWithSameAlias()
            throws Exception {
        // Generate the first key
        {
            KeyPairGenerator generator = getRsaGenerator();
            generator.initialize(new KeyGenParameterSpec.Builder(
                    TEST_ALIAS_1,
                    KeyProperties.PURPOSE_SIGN
                            | KeyProperties.PURPOSE_VERIFY
                            | KeyProperties.PURPOSE_ENCRYPT
                            | KeyProperties.PURPOSE_DECRYPT)
                    .setDigests(KeyProperties.DIGEST_NONE)
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                    .setCertificateSubject(TEST_DN_1)
                    .setCertificateSerialNumber(TEST_SERIAL_1)
                    .setCertificateNotBefore(NOW)
                    .setCertificateNotAfter(NOW_PLUS_10_YEARS)
                    .build());
            assertGeneratedKeyPairAndSelfSignedCertificate(
                    generator.generateKeyPair(),
                    TEST_ALIAS_1,
                    "RSA",
                    2048,
                    TEST_DN_1,
                    TEST_SERIAL_1,
                    NOW,
                    NOW_PLUS_10_YEARS);
        }

        // Replace the original key
        {
            KeyPairGenerator generator = getRsaGenerator();
            generator.initialize(new KeyGenParameterSpec.Builder(
                    TEST_ALIAS_1,
                    KeyProperties.PURPOSE_SIGN
                            | KeyProperties.PURPOSE_VERIFY
                            | KeyProperties.PURPOSE_ENCRYPT
                            | KeyProperties.PURPOSE_DECRYPT)
                    .setDigests(KeyProperties.DIGEST_NONE)
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                    .setCertificateSubject(TEST_DN_2)
                    .setCertificateSerialNumber(TEST_SERIAL_2)
                    .setCertificateNotBefore(NOW)
                    .setCertificateNotAfter(NOW_PLUS_10_YEARS)
                    .build());
            assertGeneratedKeyPairAndSelfSignedCertificate(
                    generator.generateKeyPair(),
                    TEST_ALIAS_1,
                    "RSA",
                    2048,
                    TEST_DN_2,
                    TEST_SERIAL_2,
                    NOW,
                    NOW_PLUS_10_YEARS);
        }
    }

    public void testGenerate_DoesNotReplaceOtherEntries()
            throws Exception {
        // Generate the first key
        KeyPairGenerator generator = getRsaGenerator();
        generator.initialize(new KeyGenParameterSpec.Builder(
                TEST_ALIAS_1,
                KeyProperties.PURPOSE_SIGN
                        | KeyProperties.PURPOSE_VERIFY
                        | KeyProperties.PURPOSE_ENCRYPT
                        | KeyProperties.PURPOSE_DECRYPT)
                .setDigests(KeyProperties.DIGEST_NONE)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                .setCertificateSubject(TEST_DN_1)
                .setCertificateSerialNumber(TEST_SERIAL_1)
                .setCertificateNotBefore(NOW)
                .setCertificateNotAfter(NOW_PLUS_10_YEARS)
                .build());
        KeyPair keyPair1 = generator.generateKeyPair();
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair1,
                TEST_ALIAS_1,
                "RSA",
                2048,
                TEST_DN_1,
                TEST_SERIAL_1,
                NOW,
                NOW_PLUS_10_YEARS);

        // Generate the second key
        generator.initialize(new KeyGenParameterSpec.Builder(
                TEST_ALIAS_2,
                KeyProperties.PURPOSE_SIGN
                        | KeyProperties.PURPOSE_VERIFY
                        | KeyProperties.PURPOSE_ENCRYPT
                        | KeyProperties.PURPOSE_DECRYPT)
                .setDigests(KeyProperties.DIGEST_NONE)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                .setCertificateSubject(TEST_DN_2)
                .setCertificateSerialNumber(TEST_SERIAL_2)
                .setCertificateNotBefore(NOW)
                .setCertificateNotAfter(NOW_PLUS_10_YEARS)
                .build());
        KeyPair keyPair2 = generator.generateKeyPair();
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair2,
                TEST_ALIAS_2,
                "RSA",
                2048,
                TEST_DN_2,
                TEST_SERIAL_2,
                NOW,
                NOW_PLUS_10_YEARS);

        // Check the first key pair again
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair1,
                TEST_ALIAS_1,
                "RSA",
                2048,
                TEST_DN_1,
                TEST_SERIAL_1,
                NOW,
                NOW_PLUS_10_YEARS);
    }

    public void testGenerate_EC_ModernSpec_Defaults() throws Exception {
        KeyPairGenerator generator = getEcGenerator();
        generator.initialize(new KeyGenParameterSpec.Builder(
                TEST_ALIAS_1,
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
                .build());
        KeyPair keyPair = generator.generateKeyPair();
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair,
                TEST_ALIAS_1,
                "EC",
                256,
                DEFAULT_CERT_SUBJECT,
                DEFAULT_CERT_SERIAL_NUMBER,
                DEFAULT_CERT_NOT_BEFORE,
                DEFAULT_CERT_NOT_AFTER);
        TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
                ECCurves.NIST_P_256_SPEC, ((ECKey) keyPair.getPrivate()).getParams());
        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
        assertEquals(256, keyInfo.getKeySize());
        assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
        assertOneOf(keyInfo.getOrigin(),
                KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
        assertEquals(
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY, keyInfo.getPurposes());
        assertFalse(keyInfo.isUserAuthenticationRequired());
        assertEquals(null, keyInfo.getKeyValidityStart());
        assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
        assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getDigests()));
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
    }

    public void testGenerate_RSA_ModernSpec_Defaults() throws Exception {
        KeyPairGenerator generator = getRsaGenerator();
        generator.initialize(new KeyGenParameterSpec.Builder(
                TEST_ALIAS_1,
                KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                .build());
        KeyPair keyPair = generator.generateKeyPair();
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair,
                TEST_ALIAS_1,
                "RSA",
                2048,
                DEFAULT_CERT_SUBJECT,
                DEFAULT_CERT_SERIAL_NUMBER,
                DEFAULT_CERT_NOT_BEFORE,
                DEFAULT_CERT_NOT_AFTER);
        assertEquals(RSAKeyGenParameterSpec.F4,
                ((RSAPublicKey) keyPair.getPublic()).getPublicExponent());
        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
        assertEquals(2048, keyInfo.getKeySize());
        assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
        assertOneOf(keyInfo.getOrigin(),
                KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
        assertEquals(
                KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
                keyInfo.getPurposes());
        assertFalse(keyInfo.isUserAuthenticationRequired());
        assertEquals(null, keyInfo.getKeyValidityStart());
        assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
        assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getDigests()));
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
    }

    public void testGenerate_EC_ModernSpec_AsCustomAsPossible() throws Exception {
        KeyPairGenerator generator = getEcGenerator();
        Date keyValidityStart = new Date(System.currentTimeMillis());
        Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 1000000);
        Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 10000000);

        Date certNotBefore = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 7);
        Date certNotAfter = new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 7);
        BigInteger certSerialNumber = new BigInteger("12345678");
        X500Principal certSubject = new X500Principal("cn=hello");
        generator.initialize(new KeyGenParameterSpec.Builder(
                TEST_ALIAS_1,
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
                        | KeyProperties.PURPOSE_ENCRYPT)
                .setKeySize(224)
                .setDigests(KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512)
                .setKeyValidityStart(keyValidityStart)
                .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
                .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
                .setCertificateSerialNumber(certSerialNumber)
                .setCertificateSubject(certSubject)
                .setCertificateNotBefore(certNotBefore)
                .setCertificateNotAfter(certNotAfter)
                .build());
        KeyPair keyPair = generator.generateKeyPair();
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair,
                TEST_ALIAS_1,
                "EC",
                224,
                certSubject,
                certSerialNumber,
                certNotBefore,
                certNotAfter);
        TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
                ECCurves.NIST_P_224_SPEC, ((ECKey) keyPair.getPrivate()).getParams());
        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
        assertEquals(224, keyInfo.getKeySize());
        assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
        assertOneOf(keyInfo.getOrigin(),
                KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
        assertEquals(
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
                        | KeyProperties.PURPOSE_ENCRYPT,
                keyInfo.getPurposes());
        assertEquals(keyValidityStart, keyInfo.getKeyValidityStart());
        assertEquals(keyValidityEndDateForOrigination, keyInfo.getKeyValidityForOriginationEnd());
        assertEquals(keyValidityEndDateForConsumption, keyInfo.getKeyValidityForConsumptionEnd());
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
                KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512);
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
        assertFalse(keyInfo.isUserAuthenticationRequired());
        assertEquals(-1, keyInfo.getUserAuthenticationValidityDurationSeconds());
    }

    public void testGenerate_RSA_ModernSpec_AsCustomAsPossible() throws Exception {
        KeyPairGenerator generator = getRsaGenerator();
        Date keyValidityStart = new Date(System.currentTimeMillis());
        Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 1000000);
        Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 10000000);

        Date certNotBefore = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 210);
        Date certNotAfter = new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 210);
        BigInteger certSerialNumber = new BigInteger("1234567890");
        X500Principal certSubject = new X500Principal("cn=hello2");
        generator.initialize(new KeyGenParameterSpec.Builder(
                TEST_ALIAS_1,
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
                        | KeyProperties.PURPOSE_ENCRYPT)
                .setAlgorithmParameterSpec(
                        new RSAKeyGenParameterSpec(3072, RSAKeyGenParameterSpec.F0))
                .setKeySize(3072)
                .setDigests(KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512)
                .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS,
                        KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
                .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
                        KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
                .setKeyValidityStart(keyValidityStart)
                .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
                .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
                .setCertificateSerialNumber(certSerialNumber)
                .setCertificateSubject(certSubject)
                .setCertificateNotBefore(certNotBefore)
                .setCertificateNotAfter(certNotAfter)
                .build());
        KeyPair keyPair = generator.generateKeyPair();
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair,
                TEST_ALIAS_1,
                "RSA",
                3072,
                certSubject,
                certSerialNumber,
                certNotBefore,
                certNotAfter);
        assertEquals(RSAKeyGenParameterSpec.F0,
                ((RSAPublicKey) keyPair.getPublic()).getPublicExponent());
        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
        assertEquals(3072, keyInfo.getKeySize());
        assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
        assertOneOf(keyInfo.getOrigin(),
                KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
        assertEquals(
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
                        | KeyProperties.PURPOSE_ENCRYPT,
                keyInfo.getPurposes());
        assertEquals(keyValidityStart, keyInfo.getKeyValidityStart());
        assertEquals(keyValidityEndDateForOrigination, keyInfo.getKeyValidityForOriginationEnd());
        assertEquals(keyValidityEndDateForConsumption, keyInfo.getKeyValidityForConsumptionEnd());
        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
                KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512);
        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getSignaturePaddings()),
                KeyProperties.SIGNATURE_PADDING_RSA_PKCS1,
                KeyProperties.SIGNATURE_PADDING_RSA_PSS);
        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getBlockModes()),
                KeyProperties.BLOCK_MODE_ECB);
        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getEncryptionPaddings()),
                KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1,
                KeyProperties.ENCRYPTION_PADDING_RSA_OAEP);
        assertFalse(keyInfo.isUserAuthenticationRequired());
        assertEquals(-1, keyInfo.getUserAuthenticationValidityDurationSeconds());
    }

    public void testGenerate_EC_ModernSpec_UsableForTLSPeerAuth() throws Exception {
        KeyPairGenerator generator = getEcGenerator();
        generator.initialize(new KeyGenParameterSpec.Builder(
                TEST_ALIAS_1,
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
                .setDigests(KeyProperties.DIGEST_NONE)
                .build());
        KeyPair keyPair = generator.generateKeyPair();
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair,
                TEST_ALIAS_1,
                "EC",
                256,
                DEFAULT_CERT_SUBJECT,
                DEFAULT_CERT_SERIAL_NUMBER,
                DEFAULT_CERT_NOT_BEFORE,
                DEFAULT_CERT_NOT_AFTER);
        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
                KeyProperties.DIGEST_NONE);
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
        assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1);
        assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1);
    }

    public void testGenerate_RSA_ModernSpec_UsableForTLSPeerAuth() throws Exception {
        KeyPairGenerator generator = getRsaGenerator();
        generator.initialize(new KeyGenParameterSpec.Builder(
                TEST_ALIAS_1,
                KeyProperties.PURPOSE_SIGN
                        | KeyProperties.PURPOSE_VERIFY
                        | KeyProperties.PURPOSE_DECRYPT)
                .setDigests(KeyProperties.DIGEST_NONE)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                .build());
        KeyPair keyPair = generator.generateKeyPair();
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair,
                TEST_ALIAS_1,
                "RSA",
                2048,
                DEFAULT_CERT_SUBJECT,
                DEFAULT_CERT_SERIAL_NUMBER,
                DEFAULT_CERT_NOT_BEFORE,
                DEFAULT_CERT_NOT_AFTER);
        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
                KeyProperties.DIGEST_NONE);
        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getEncryptionPaddings()),
                KeyProperties.ENCRYPTION_PADDING_NONE);
        assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1);
        assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1);
    }

    // TODO: Test fingerprint-authorized and secure lock screen-authorized keys. These can't
    // currently be tested here because CTS does not require that secure lock screen is set up and
    // that at least one fingerprint is enrolled.

    public void testGenerate_EC_ModernSpec_SupportedSizes() throws Exception {
        assertKeyGenUsingECSizeOnlyUsesCorrectCurve(224, ECCurves.NIST_P_224_SPEC);
        assertKeyGenUsingECSizeOnlyUsesCorrectCurve(256, ECCurves.NIST_P_256_SPEC);
        assertKeyGenUsingECSizeOnlyUsesCorrectCurve(384, ECCurves.NIST_P_384_SPEC);
        assertKeyGenUsingECSizeOnlyUsesCorrectCurve(521, ECCurves.NIST_P_521_SPEC);
    }

    public void testGenerate_EC_ModernSpec_UnsupportedSizesRejected() throws Exception {
        for (int keySizeBits = 0; keySizeBits <= 1024; keySizeBits++) {
            if ((keySizeBits == 224) || (keySizeBits == 256) || (keySizeBits == 384)
                    || (keySizeBits == 521)) {
                // Skip supported sizes
                continue;
            }
            KeyPairGenerator generator = getEcGenerator();

            try {
                generator.initialize(new KeyGenParameterSpec.Builder(
                        TEST_ALIAS_1,
                        KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
                        .setKeySize(keySizeBits)
                        .build());
                fail("EC KeyPairGenerator initialized with unsupported key size: "
                        + keySizeBits + " bits");
            } catch (InvalidAlgorithmParameterException expected) {
            }
        }
    }

    public void testGenerate_EC_ModernSpec_SupportedNamedCurves() throws Exception {
        assertKeyGenUsingECNamedCurveSupported("P-224", ECCurves.NIST_P_224_SPEC);
        assertKeyGenUsingECNamedCurveSupported("p-224", ECCurves.NIST_P_224_SPEC);
        assertKeyGenUsingECNamedCurveSupported("secp224r1", ECCurves.NIST_P_224_SPEC);
        assertKeyGenUsingECNamedCurveSupported("SECP224R1", ECCurves.NIST_P_224_SPEC);

        assertKeyGenUsingECNamedCurveSupported("P-256", ECCurves.NIST_P_256_SPEC);
        assertKeyGenUsingECNamedCurveSupported("p-256", ECCurves.NIST_P_256_SPEC);
        assertKeyGenUsingECNamedCurveSupported("secp256r1", ECCurves.NIST_P_256_SPEC);
        assertKeyGenUsingECNamedCurveSupported("SECP256R1", ECCurves.NIST_P_256_SPEC);
        assertKeyGenUsingECNamedCurveSupported("prime256v1", ECCurves.NIST_P_256_SPEC);
        assertKeyGenUsingECNamedCurveSupported("PRIME256V1", ECCurves.NIST_P_256_SPEC);

        assertKeyGenUsingECNamedCurveSupported("P-384", ECCurves.NIST_P_384_SPEC);
        assertKeyGenUsingECNamedCurveSupported("p-384", ECCurves.NIST_P_384_SPEC);
        assertKeyGenUsingECNamedCurveSupported("secp384r1", ECCurves.NIST_P_384_SPEC);
        assertKeyGenUsingECNamedCurveSupported("SECP384R1", ECCurves.NIST_P_384_SPEC);

        assertKeyGenUsingECNamedCurveSupported("P-521", ECCurves.NIST_P_521_SPEC);
        assertKeyGenUsingECNamedCurveSupported("p-521", ECCurves.NIST_P_521_SPEC);
        assertKeyGenUsingECNamedCurveSupported("secp521r1", ECCurves.NIST_P_521_SPEC);
        assertKeyGenUsingECNamedCurveSupported("SECP521R1", ECCurves.NIST_P_521_SPEC);
    }

    public void testGenerate_RSA_ModernSpec_SupportedSizes() throws Exception {
        assertKeyGenUsingRSASizeOnlySupported(512);
        assertKeyGenUsingRSASizeOnlySupported(768);
        assertKeyGenUsingRSASizeOnlySupported(1024);
        assertKeyGenUsingRSASizeOnlySupported(2048);
        assertKeyGenUsingRSASizeOnlySupported(3072);
        assertKeyGenUsingRSASizeOnlySupported(4096);

        // The above use F4. Check that F0 is supported as well, just in case somebody is crazy
        // enough.
        assertKeyGenUsingRSAKeyGenParameterSpecSupported(new RSAKeyGenParameterSpec(
                2048, RSAKeyGenParameterSpec.F0));
    }

    private void assertKeyGenUsingECSizeOnlyUsesCorrectCurve(
            int keySizeBits, ECParameterSpec expectedParams) throws Exception {
        KeyPairGenerator generator = getEcGenerator();
        generator.initialize(new KeyGenParameterSpec.Builder(
                TEST_ALIAS_1,
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
                .setKeySize(keySizeBits)
                .build(),
                mRng);
        mRng.resetCounters();
        KeyPair keyPair = generator.generateKeyPair();
        long consumedEntropyAmountBytes = mRng.getOutputSizeBytes();
        int expectedKeySize = expectedParams.getCurve().getField().getFieldSize();
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair,
                TEST_ALIAS_1,
                "EC",
                expectedKeySize,
                DEFAULT_CERT_SUBJECT,
                DEFAULT_CERT_SERIAL_NUMBER,
                DEFAULT_CERT_NOT_BEFORE,
                DEFAULT_CERT_NOT_AFTER);
        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
        assertEquals(expectedKeySize, keyInfo.getKeySize());
        TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
                expectedParams,
                ((ECKey) keyPair.getPublic()).getParams());
        assertEquals(((keySizeBits + 7) / 8) * 8, consumedEntropyAmountBytes * 8);
    }

    private void assertKeyGenUsingECNamedCurveSupported(
            String curveName, ECParameterSpec expectedParams) throws Exception {
        KeyPairGenerator generator = getEcGenerator();
        generator.initialize(new KeyGenParameterSpec.Builder(
                TEST_ALIAS_1,
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
                .setAlgorithmParameterSpec(new ECGenParameterSpec(curveName))
                .build(),
                mRng);
        mRng.resetCounters();
        KeyPair keyPair = generator.generateKeyPair();
        long consumedEntropyAmountBytes = mRng.getOutputSizeBytes();
        int expectedKeySize = expectedParams.getCurve().getField().getFieldSize();
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair,
                TEST_ALIAS_1,
                "EC",
                expectedKeySize,
                DEFAULT_CERT_SUBJECT,
                DEFAULT_CERT_SERIAL_NUMBER,
                DEFAULT_CERT_NOT_BEFORE,
                DEFAULT_CERT_NOT_AFTER);
        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
        assertEquals(expectedKeySize, keyInfo.getKeySize());
        TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
                expectedParams,
                ((ECKey) keyPair.getPublic()).getParams());
        assertEquals(((expectedKeySize + 7) / 8) * 8, consumedEntropyAmountBytes * 8);
    }

    private void assertKeyGenUsingRSASizeOnlySupported(int keySizeBits) throws Exception {
        KeyPairGenerator generator = getRsaGenerator();
        generator.initialize(new KeyGenParameterSpec.Builder(
                TEST_ALIAS_1,
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
                .setKeySize(keySizeBits)
                .build(),
                mRng);
        mRng.resetCounters();
        KeyPair keyPair = generator.generateKeyPair();
        long consumedEntropyAmountBytes = mRng.getOutputSizeBytes();
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair,
                TEST_ALIAS_1,
                "RSA",
                keySizeBits,
                DEFAULT_CERT_SUBJECT,
                DEFAULT_CERT_SERIAL_NUMBER,
                DEFAULT_CERT_NOT_BEFORE,
                DEFAULT_CERT_NOT_AFTER);
        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
        assertEquals(keySizeBits, keyInfo.getKeySize());
        assertEquals(((keySizeBits + 7) / 8) * 8, consumedEntropyAmountBytes * 8);
    }

    private void assertKeyGenUsingRSAKeyGenParameterSpecSupported(
            RSAKeyGenParameterSpec spec) throws Exception {
        KeyPairGenerator generator = getRsaGenerator();
        generator.initialize(new KeyGenParameterSpec.Builder(
                TEST_ALIAS_1,
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
                .setAlgorithmParameterSpec(spec)
                .build(),
                mRng);
        mRng.resetCounters();
        KeyPair keyPair = generator.generateKeyPair();
        long consumedEntropyAmountBytes = mRng.getOutputSizeBytes();
        assertGeneratedKeyPairAndSelfSignedCertificate(
                keyPair,
                TEST_ALIAS_1,
                "RSA",
                spec.getKeysize(),
                DEFAULT_CERT_SUBJECT,
                DEFAULT_CERT_SERIAL_NUMBER,
                DEFAULT_CERT_NOT_BEFORE,
                DEFAULT_CERT_NOT_AFTER);
        assertEquals(spec.getPublicExponent(),
                ((RSAPublicKey) keyPair.getPublic()).getPublicExponent());
        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
        assertEquals(spec.getKeysize(), keyInfo.getKeySize());
        assertEquals(((spec.getKeysize() + 7) / 8) * 8, consumedEntropyAmountBytes * 8);
    }

    private static void assertSelfSignedCertificateSignatureVerifies(Certificate certificate) {
        try {
            certificate.verify(certificate.getPublicKey());
        } catch (Exception e) {
            throw new RuntimeException("Failed to verify self-signed certificate signature", e);
        }
    }

    private void assertGeneratedKeyPairAndSelfSignedCertificate(
            KeyPair keyPair, String alias,
            String expectedKeyAlgorithm,
            int expectedKeySize,
            X500Principal expectedCertSubject,
            BigInteger expectedCertSerialNumber,
            Date expectedCertNotBefore,
            Date expectedCertNotAfter)
            throws Exception {
        assertNotNull(keyPair);
        TestUtils.assertKeyPairSelfConsistent(keyPair);
        TestUtils.assertKeySize(expectedKeySize, keyPair);
        assertEquals(expectedKeyAlgorithm, keyPair.getPublic().getAlgorithm());
        TestUtils.assertKeyStoreKeyPair(mKeyStore, alias, keyPair);

        X509Certificate cert = (X509Certificate) mKeyStore.getCertificate(alias);
        assertEquals(keyPair.getPublic(), cert.getPublicKey());
        assertX509CertificateParameters(cert,
                expectedCertSubject,
                expectedCertSerialNumber,
                expectedCertNotBefore,
                expectedCertNotAfter);
        // Assert that the certificate chain consists only of the above certificate
        MoreAsserts.assertContentsInOrder(
                Arrays.asList(mKeyStore.getCertificateChain(alias)), cert);
    }

    private void assertSelfSignedCertificateSignatureVerifies(String alias) throws Exception {
        assertSelfSignedCertificateSignatureVerifies(mKeyStore.getCertificate(alias));
    }

    private void assertKeyPairAndCertificateUsableForTLSPeerAuthentication(String alias)
            throws Exception {
        assertUsableForTLSPeerAuthentication(
                (PrivateKey) mKeyStore.getKey(alias, null),
                mKeyStore.getCertificateChain(alias));
    }

    private static void assertX509CertificateParameters(
            X509Certificate actualCert,
            X500Principal expectedSubject, BigInteger expectedSerialNumber,
            Date expectedNotBefore, Date expectedNotAfter) {
        assertEquals(expectedSubject, actualCert.getSubjectDN());
        assertEquals(expectedSubject, actualCert.getIssuerDN());
        assertEquals(expectedSerialNumber, actualCert.getSerialNumber());
        assertDateEquals(expectedNotBefore, actualCert.getNotBefore());
        assertDateEquals(expectedNotAfter, actualCert.getNotAfter());
    }

    private static void assertUsableForTLSPeerAuthentication(
            PrivateKey privateKey,
            Certificate[] certificateChain) throws Exception {
        // Set up both client and server to use the same private key + cert, and to trust that cert
        // when it's presented by peer. This exercises the use of the private key both in client
        // and server scenarios.
        X509Certificate[] x509CertificateChain = new X509Certificate[certificateChain.length];
        for (int i = 0; i < certificateChain.length; i++) {
            x509CertificateChain[i] = (X509Certificate) certificateChain[i];
        }
        TestKeyStore serverKeyStore = TestKeyStore.getServer();
        // Make the peer trust the root certificate in the chain. As opposed to making the peer
        // trust the leaf certificate, this will ensure that the whole chain verifies.
        serverKeyStore.keyStore.setCertificateEntry(
                "trusted", certificateChain[certificateChain.length - 1]);
        SSLContext serverContext = TestSSLContext.createSSLContext("TLS",
                new KeyManager[] {
                    TestKeyManager.wrap(new MyKeyManager(privateKey, x509CertificateChain))
                },
                TestKeyStore.createTrustManagers(serverKeyStore.keyStore));
        SSLContext clientContext = serverContext;

        if ("EC".equalsIgnoreCase(privateKey.getAlgorithm())) {
            // As opposed to RSA (see below) EC keys are used in the same way in all cipher suites.
            // Assert that the key works with the default list of cipher suites.
            assertSSLConnectionWithClientAuth(
                    clientContext, serverContext, null, x509CertificateChain, x509CertificateChain);
        } else if ("RSA".equalsIgnoreCase(privateKey.getAlgorithm())) {
            // RSA keys are used differently between Forward Secure and non-Forward Secure cipher
            // suites. For example, RSA key exchange requires the server to decrypt using its RSA
            // private key, whereas ECDHE_RSA key exchange requires the server to sign usnig its
            // RSA private key. We thus assert that the key works with Forward Secure cipher suites
            // and that it works with non-Forward Secure cipher suites.
            List<String> fsCipherSuites = new ArrayList<String>();
            List<String> nonFsCipherSuites = new ArrayList<String>();
            for (String cipherSuite : clientContext.getDefaultSSLParameters().getCipherSuites()) {
                if (cipherSuite.contains("_ECDHE_RSA_") || cipherSuite.contains("_DHE_RSA_")) {
                    fsCipherSuites.add(cipherSuite);
                } else if (cipherSuite.contains("_RSA_WITH_")) {
                    nonFsCipherSuites.add(cipherSuite);
                }
            }
            assertFalse("No FS RSA cipher suites enabled by default", fsCipherSuites.isEmpty());
            assertFalse("No non-FS RSA cipher suites enabled", nonFsCipherSuites.isEmpty());

            // Assert that the key works with RSA Forward Secure cipher suites.
            assertSSLConnectionWithClientAuth(
                    clientContext, serverContext, fsCipherSuites.toArray(new String[0]),
                    x509CertificateChain, x509CertificateChain);
            // Assert that the key works with RSA non-Forward Secure cipher suites.
            assertSSLConnectionWithClientAuth(
                    clientContext, serverContext, nonFsCipherSuites.toArray(new String[0]),
                    x509CertificateChain, x509CertificateChain);
        } else {
            fail("Unsupported key algorithm: " + privateKey.getAlgorithm());
        }
    }

    private static void assertSSLConnectionWithClientAuth(
            SSLContext clientContext, SSLContext serverContext, String[] enabledCipherSuites,
            X509Certificate[] expectedClientCertChain, X509Certificate[] expectedServerCertChain)
            throws Exception {
        SSLServerSocket serverSocket = (SSLServerSocket) serverContext.getServerSocketFactory()
                .createServerSocket(0);
        InetAddress host = InetAddress.getLocalHost();
        int port = serverSocket.getLocalPort();
        SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(host, port);

        final SSLSocket server = (SSLSocket) serverSocket.accept();
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<Certificate[]> future = executor.submit(new Callable<Certificate[]>() {
            @Override
            public Certificate[] call() throws Exception {
                server.setNeedClientAuth(true);
                server.setWantClientAuth(true);
                server.startHandshake();
                return server.getSession().getPeerCertificates();
            }
        });
        executor.shutdown();
        if (enabledCipherSuites != null) {
            client.setEnabledCipherSuites(enabledCipherSuites);
        }
        client.startHandshake();
        Certificate[] usedServerCerts = client.getSession().getPeerCertificates();
        Certificate[] usedClientCerts = future.get();
        client.close();
        server.close();

        assertNotNull(usedServerCerts);
        assertEquals(Arrays.asList(expectedServerCertChain), Arrays.asList(usedServerCerts));

        assertNotNull(usedClientCerts);
        assertEquals(Arrays.asList(expectedClientCertChain), Arrays.asList(usedClientCerts));
    }

    private static class MyKeyManager extends X509ExtendedKeyManager {
        private final PrivateKey key;
        private final X509Certificate[] chain;

        public MyKeyManager(PrivateKey key, X509Certificate[] certChain) {
            this.key = key;
            this.chain = certChain;
        }

        @Override
        public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
            return "fake";
        }

        @Override
        public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
            return "fake";
        }

        @Override
        public X509Certificate[] getCertificateChain(String alias) {
            return chain;
        }

        @Override
        public String[] getClientAliases(String keyType, Principal[] issuers) {
            return new String[] { "fake" };
        }

        @Override
        public String[] getServerAliases(String keyType, Principal[] issuers) {
            return new String[] { "fake" };
        }

        @Override
        public PrivateKey getPrivateKey(String alias) {
            return key;
        }
    }


    private static void assertDateEquals(Date date1, Date date2) {
        assertDateEquals(null, date1, date2);
    }

    private static void assertDateEquals(String message, Date date1, Date date2) {
        SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss");

        String result1 = formatter.format(date1);
        String result2 = formatter.format(date2);

        assertEquals(message, result1, result2);
    }

    private KeyPairGenerator getRsaGenerator()
            throws NoSuchAlgorithmException, NoSuchProviderException {
        return KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
    }

    private KeyPairGenerator getEcGenerator()
            throws NoSuchAlgorithmException, NoSuchProviderException {
        return KeyPairGenerator.getInstance("EC", "AndroidKeyStore");
    }

    private static void assertOneOf(int actual, int... expected) {
        assertOneOf(null, actual, expected);
    }

    private static void assertOneOf(String message, int actual, int... expected) {
        for (int expectedValue : expected) {
            if (actual == expectedValue) {
                return;
            }
        }
        fail(((message != null) ? message + ". " : "")
                + "Expected one of " + Arrays.asList(expected)
                + ", actual: <" + actual + ">");
    }
}
