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.test.AndroidTestCase;
     21 
     22 import java.math.BigInteger;
     23 import java.net.InetAddress;
     24 import java.net.Socket;
     25 import java.security.KeyPair;
     26 import java.security.KeyPairGenerator;
     27 import java.security.KeyStore;
     28 import java.security.Principal;
     29 import java.security.PrivateKey;
     30 import java.security.PublicKey;
     31 import java.security.SecureRandom;
     32 import java.security.cert.Certificate;
     33 import java.security.cert.X509Certificate;
     34 import java.security.interfaces.DSAParams;
     35 import java.security.interfaces.DSAPublicKey;
     36 import java.security.interfaces.ECPublicKey;
     37 import java.security.interfaces.RSAPublicKey;
     38 import java.security.spec.AlgorithmParameterSpec;
     39 import java.security.spec.DSAParameterSpec;
     40 import java.security.spec.RSAKeyGenParameterSpec;
     41 import java.text.SimpleDateFormat;
     42 import java.util.Date;
     43 import java.util.concurrent.Callable;
     44 import java.util.concurrent.ExecutorService;
     45 import java.util.concurrent.Executors;
     46 import java.util.concurrent.Future;
     47 
     48 import javax.net.ssl.KeyManager;
     49 import javax.net.ssl.SSLContext;
     50 import javax.net.ssl.SSLServerSocket;
     51 import javax.net.ssl.SSLSocket;
     52 import javax.net.ssl.TrustManager;
     53 import javax.net.ssl.X509ExtendedKeyManager;
     54 import javax.security.auth.x500.X500Principal;
     55 
     56 import libcore.java.security.TestKeyStore;
     57 import libcore.javax.net.ssl.TestKeyManager;
     58 import libcore.javax.net.ssl.TestSSLContext;
     59 
     60 public class AndroidKeyPairGeneratorTest extends AndroidTestCase {
     61     private KeyPairGenerator mGenerator;
     62 
     63     private KeyStore mKeyStore;
     64 
     65     private static final String TEST_ALIAS_1 = "test1";
     66 
     67     private static final String TEST_ALIAS_2 = "test2";
     68 
     69     private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1");
     70 
     71     private static final X500Principal TEST_DN_2 = new X500Principal("CN=test2");
     72 
     73     private static final BigInteger TEST_SERIAL_1 = BigInteger.ONE;
     74 
     75     private static final BigInteger TEST_SERIAL_2 = BigInteger.valueOf(2L);
     76 
     77     private static final long NOW_MILLIS = System.currentTimeMillis();
     78 
     79     /* We have to round this off because X509v3 doesn't store milliseconds. */
     80     private static final Date NOW = new Date(NOW_MILLIS - (NOW_MILLIS % 1000L));
     81 
     82     @SuppressWarnings("deprecation")
     83     private static final Date NOW_PLUS_10_YEARS = new Date(NOW.getYear() + 10, 0, 1);
     84 
     85     @Override
     86     protected void setUp() throws Exception {
     87         mKeyStore = KeyStore.getInstance("AndroidKeyStore");
     88         mKeyStore.load(null, null);
     89 
     90         mGenerator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
     91     }
     92 
     93     public void testKeyPairGenerator_Initialize_Params_Unencrypted_Success() throws Exception {
     94         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
     95                 .setAlias(TEST_ALIAS_1)
     96                 .setSubject(TEST_DN_1)
     97                 .setSerialNumber(TEST_SERIAL_1)
     98                 .setStartDate(NOW)
     99                 .setEndDate(NOW_PLUS_10_YEARS)
    100                 .build());
    101     }
    102 
    103     public void testKeyPairGenerator_Initialize_KeySize_Unencrypted_Failure() throws Exception {
    104         try {
    105             mGenerator.initialize(1024);
    106             fail("KeyPairGenerator should not support setting the key size");
    107         } catch (IllegalArgumentException success) {
    108         }
    109     }
    110 
    111     public void testKeyPairGenerator_Initialize_KeySizeAndSecureRandom_Unencrypted_Failure()
    112             throws Exception {
    113         try {
    114             mGenerator.initialize(1024, new SecureRandom());
    115             fail("KeyPairGenerator should not support setting the key size");
    116         } catch (IllegalArgumentException success) {
    117         }
    118     }
    119 
    120     public void testKeyPairGenerator_Initialize_ParamsAndSecureRandom_Unencrypted_Failure()
    121             throws Exception {
    122         mGenerator.initialize(
    123                 new KeyPairGeneratorSpec.Builder(getContext())
    124                         .setAlias(TEST_ALIAS_1)
    125                         .setSubject(TEST_DN_1)
    126                         .setSerialNumber(TEST_SERIAL_1)
    127                         .setStartDate(NOW)
    128                         .setEndDate(NOW_PLUS_10_YEARS)
    129                         .build(),
    130                 new SecureRandom());
    131     }
    132 
    133     public void testKeyPairGenerator_GenerateKeyPair_DSA_Unencrypted_Success() throws Exception {
    134         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
    135                 .setAlias(TEST_ALIAS_1)
    136                 .setKeyType("DSA")
    137                 .setSubject(TEST_DN_1)
    138                 .setSerialNumber(TEST_SERIAL_1)
    139                 .setStartDate(NOW)
    140                 .setEndDate(NOW_PLUS_10_YEARS)
    141                 .build());
    142 
    143         final KeyPair pair = mGenerator.generateKeyPair();
    144         assertNotNull("The KeyPair returned should not be null", pair);
    145 
    146         assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 1024, null, TEST_DN_1, TEST_SERIAL_1, NOW,
    147                 NOW_PLUS_10_YEARS);
    148     }
    149 
    150     public void testKeyPairGenerator_GenerateKeyPair_DSA_2048_Unencrypted_Success()
    151             throws Exception {
    152         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
    153                 .setAlias(TEST_ALIAS_1)
    154                 .setKeyType("DSA")
    155                 .setKeySize(2048)
    156                 .setSubject(TEST_DN_1)
    157                 .setSerialNumber(TEST_SERIAL_1)
    158                 .setStartDate(NOW)
    159                 .setEndDate(NOW_PLUS_10_YEARS)
    160                 .build());
    161 
    162         final KeyPair pair = mGenerator.generateKeyPair();
    163         assertNotNull("The KeyPair returned should not be null", pair);
    164 
    165         assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
    166                 NOW_PLUS_10_YEARS);
    167     }
    168 
    169     public void testKeyPairGenerator_GenerateKeyPair_DSA_SpecifiedParams_Unencrypted_Success()
    170             throws Exception {
    171         /*
    172          * generated using: openssl dsaparam -C 2048
    173          */
    174         BigInteger p = new BigInteger(1, new byte[] {
    175                 (byte) 0xC0, (byte) 0x3D, (byte) 0x86, (byte) 0x09, (byte) 0xCA, (byte) 0x8C,
    176                 (byte) 0x37, (byte) 0xCA, (byte) 0xCC, (byte) 0x4A, (byte) 0x81, (byte) 0xBD,
    177                 (byte) 0xD8, (byte) 0x50, (byte) 0x77, (byte) 0xCD, (byte) 0xDD, (byte) 0x32,
    178                 (byte) 0x0B, (byte) 0x43, (byte) 0xBF, (byte) 0x42, (byte) 0x06, (byte) 0x5A,
    179                 (byte) 0x3D, (byte) 0x18, (byte) 0x50, (byte) 0x47, (byte) 0x79, (byte) 0xE1,
    180                 (byte) 0x5B, (byte) 0x86, (byte) 0x03, (byte) 0xB9, (byte) 0x28, (byte) 0x9C,
    181                 (byte) 0x18, (byte) 0xA9, (byte) 0xF5, (byte) 0xD6, (byte) 0xF4, (byte) 0x94,
    182                 (byte) 0x5B, (byte) 0x87, (byte) 0x58, (byte) 0xCA, (byte) 0xB2, (byte) 0x1E,
    183                 (byte) 0xFC, (byte) 0xED, (byte) 0x37, (byte) 0xC3, (byte) 0x49, (byte) 0xAC,
    184                 (byte) 0xFA, (byte) 0x46, (byte) 0xDB, (byte) 0x7A, (byte) 0x50, (byte) 0x96,
    185                 (byte) 0xCF, (byte) 0x52, (byte) 0xD7, (byte) 0x4E, (byte) 0xEB, (byte) 0x26,
    186                 (byte) 0x41, (byte) 0xA2, (byte) 0x6F, (byte) 0x99, (byte) 0x80, (byte) 0x9F,
    187                 (byte) 0x0F, (byte) 0x0A, (byte) 0xA8, (byte) 0x0D, (byte) 0xAC, (byte) 0xAB,
    188                 (byte) 0xEF, (byte) 0x7D, (byte) 0xE7, (byte) 0x4C, (byte) 0xF1, (byte) 0x88,
    189                 (byte) 0x44, (byte) 0xC9, (byte) 0x17, (byte) 0xD0, (byte) 0xBB, (byte) 0xE2,
    190                 (byte) 0x01, (byte) 0x8C, (byte) 0xC1, (byte) 0x02, (byte) 0x1D, (byte) 0x3C,
    191                 (byte) 0x15, (byte) 0xB7, (byte) 0x41, (byte) 0x30, (byte) 0xD8, (byte) 0x11,
    192                 (byte) 0xBD, (byte) 0x6A, (byte) 0x2A, (byte) 0x0D, (byte) 0x36, (byte) 0x44,
    193                 (byte) 0x9C, (byte) 0x3F, (byte) 0x32, (byte) 0xE2, (byte) 0x1C, (byte) 0xFB,
    194                 (byte) 0xE3, (byte) 0xFF, (byte) 0xCC, (byte) 0x1A, (byte) 0x72, (byte) 0x38,
    195                 (byte) 0x37, (byte) 0x69, (byte) 0x5E, (byte) 0x35, (byte) 0x73, (byte) 0xE1,
    196                 (byte) 0x1E, (byte) 0x74, (byte) 0x35, (byte) 0x44, (byte) 0x07, (byte) 0xB5,
    197                 (byte) 0x2F, (byte) 0x0B, (byte) 0x60, (byte) 0xF4, (byte) 0xA9, (byte) 0xE0,
    198                 (byte) 0x81, (byte) 0xB2, (byte) 0xCD, (byte) 0x8B, (byte) 0x82, (byte) 0x76,
    199                 (byte) 0x7F, (byte) 0xD4, (byte) 0x17, (byte) 0x32, (byte) 0x86, (byte) 0x98,
    200                 (byte) 0x7C, (byte) 0x85, (byte) 0x66, (byte) 0xF6, (byte) 0x77, (byte) 0xED,
    201                 (byte) 0x8B, (byte) 0x1A, (byte) 0x52, (byte) 0x16, (byte) 0xDA, (byte) 0x1C,
    202                 (byte) 0xA7, (byte) 0x16, (byte) 0x79, (byte) 0x20, (byte) 0x1C, (byte) 0x99,
    203                 (byte) 0x5F, (byte) 0x12, (byte) 0x66, (byte) 0x15, (byte) 0x9F, (byte) 0xE5,
    204                 (byte) 0x73, (byte) 0xA9, (byte) 0x61, (byte) 0xBA, (byte) 0xA7, (byte) 0x23,
    205                 (byte) 0x93, (byte) 0x77, (byte) 0xB5, (byte) 0xF6, (byte) 0xEC, (byte) 0x13,
    206                 (byte) 0xBF, (byte) 0x95, (byte) 0x60, (byte) 0x78, (byte) 0x84, (byte) 0xE3,
    207                 (byte) 0x44, (byte) 0xEC, (byte) 0x74, (byte) 0xC2, (byte) 0xCB, (byte) 0xD4,
    208                 (byte) 0x70, (byte) 0xC5, (byte) 0x7B, (byte) 0xF8, (byte) 0x07, (byte) 0x3B,
    209                 (byte) 0xEB, (byte) 0x9F, (byte) 0xC9, (byte) 0x7D, (byte) 0xE0, (byte) 0xA5,
    210                 (byte) 0xBA, (byte) 0x68, (byte) 0x7B, (byte) 0xF4, (byte) 0x70, (byte) 0x40,
    211                 (byte) 0xAE, (byte) 0xE9, (byte) 0x65, (byte) 0xEE, (byte) 0x5B, (byte) 0x71,
    212                 (byte) 0x36, (byte) 0x0B, (byte) 0xB0, (byte) 0xA2, (byte) 0x98, (byte) 0x7D,
    213                 (byte) 0xE3, (byte) 0x24, (byte) 0x95, (byte) 0x2B, (byte) 0xC2, (byte) 0x0A,
    214                 (byte) 0x78, (byte) 0x3D, (byte) 0xCC, (byte) 0x3A, (byte) 0xEE, (byte) 0xED,
    215                 (byte) 0x48, (byte) 0xEB, (byte) 0xA3, (byte) 0x78, (byte) 0xA8, (byte) 0x9D,
    216                 (byte) 0x0A, (byte) 0x8F, (byte) 0x9E, (byte) 0x59, (byte) 0x2C, (byte) 0x44,
    217                 (byte) 0xB5, (byte) 0xF9, (byte) 0x53, (byte) 0x43,
    218         });
    219 
    220         BigInteger q = new BigInteger(1, new byte[] {
    221                 (byte) 0xA1, (byte) 0x9B, (byte) 0x1D, (byte) 0xC0, (byte) 0xE3, (byte) 0xF6,
    222                 (byte) 0x4A, (byte) 0x35, (byte) 0xE1, (byte) 0x8A, (byte) 0x43, (byte) 0xC2,
    223                 (byte) 0x9C, (byte) 0xF9, (byte) 0x52, (byte) 0x8F, (byte) 0x94, (byte) 0xA1,
    224                 (byte) 0x12, (byte) 0x11, (byte) 0xDB, (byte) 0x9A, (byte) 0xB6, (byte) 0x35,
    225                 (byte) 0x56, (byte) 0x26, (byte) 0x60, (byte) 0x89, (byte) 0x11, (byte) 0xAC,
    226                 (byte) 0xA8, (byte) 0xE5,
    227         });
    228 
    229         BigInteger g = new BigInteger(1, new byte[] {
    230                 (byte) 0xA1, (byte) 0x5C, (byte) 0x57, (byte) 0x15, (byte) 0xC3, (byte) 0xD9,
    231                 (byte) 0xD7, (byte) 0x41, (byte) 0x89, (byte) 0xD6, (byte) 0xB8, (byte) 0x7B,
    232                 (byte) 0xF3, (byte) 0xE0, (byte) 0xB3, (byte) 0xC5, (byte) 0xD1, (byte) 0xAA,
    233                 (byte) 0xF9, (byte) 0x55, (byte) 0x48, (byte) 0xF1, (byte) 0xDA, (byte) 0xE8,
    234                 (byte) 0x6F, (byte) 0x51, (byte) 0x05, (byte) 0xB2, (byte) 0xC9, (byte) 0x64,
    235                 (byte) 0xDA, (byte) 0x5F, (byte) 0xD4, (byte) 0xAA, (byte) 0xFD, (byte) 0x67,
    236                 (byte) 0xE0, (byte) 0x10, (byte) 0x2C, (byte) 0x1F, (byte) 0x03, (byte) 0x10,
    237                 (byte) 0xD4, (byte) 0x4B, (byte) 0x20, (byte) 0x82, (byte) 0x2B, (byte) 0x04,
    238                 (byte) 0xF9, (byte) 0x09, (byte) 0xAE, (byte) 0x28, (byte) 0x3D, (byte) 0x9B,
    239                 (byte) 0xFF, (byte) 0x87, (byte) 0x76, (byte) 0xCD, (byte) 0xF0, (byte) 0x11,
    240                 (byte) 0xB7, (byte) 0xEA, (byte) 0xE6, (byte) 0xCD, (byte) 0x60, (byte) 0xD3,
    241                 (byte) 0x8C, (byte) 0x74, (byte) 0xD3, (byte) 0x45, (byte) 0x63, (byte) 0x69,
    242                 (byte) 0x3F, (byte) 0x1D, (byte) 0x31, (byte) 0x25, (byte) 0x49, (byte) 0x97,
    243                 (byte) 0x4B, (byte) 0x73, (byte) 0x34, (byte) 0x12, (byte) 0x73, (byte) 0x27,
    244                 (byte) 0x4C, (byte) 0xDA, (byte) 0xF3, (byte) 0x08, (byte) 0xA8, (byte) 0xA9,
    245                 (byte) 0x27, (byte) 0xE4, (byte) 0xB8, (byte) 0xD6, (byte) 0xB5, (byte) 0xC4,
    246                 (byte) 0x18, (byte) 0xED, (byte) 0xBD, (byte) 0x6F, (byte) 0xA2, (byte) 0x36,
    247                 (byte) 0xA2, (byte) 0x9C, (byte) 0x27, (byte) 0x62, (byte) 0x7F, (byte) 0x93,
    248                 (byte) 0xD7, (byte) 0x52, (byte) 0xA9, (byte) 0x76, (byte) 0x55, (byte) 0x99,
    249                 (byte) 0x00, (byte) 0x5B, (byte) 0xC2, (byte) 0xB9, (byte) 0x18, (byte) 0xAC,
    250                 (byte) 0x6B, (byte) 0x83, (byte) 0x0D, (byte) 0xA1, (byte) 0xC5, (byte) 0x01,
    251                 (byte) 0x1A, (byte) 0xE5, (byte) 0x4D, (byte) 0x2F, (byte) 0xCF, (byte) 0x5D,
    252                 (byte) 0xB2, (byte) 0xE7, (byte) 0xC7, (byte) 0xCB, (byte) 0x2C, (byte) 0xFF,
    253                 (byte) 0x51, (byte) 0x1B, (byte) 0x9D, (byte) 0xA4, (byte) 0x05, (byte) 0xEB,
    254                 (byte) 0x17, (byte) 0xD8, (byte) 0x97, (byte) 0x9D, (byte) 0x0C, (byte) 0x59,
    255                 (byte) 0x92, (byte) 0x8A, (byte) 0x03, (byte) 0x34, (byte) 0xFD, (byte) 0x16,
    256                 (byte) 0x0F, (byte) 0x2A, (byte) 0xF9, (byte) 0x7D, (byte) 0xC3, (byte) 0x41,
    257                 (byte) 0x0D, (byte) 0x06, (byte) 0x5A, (byte) 0x4B, (byte) 0x34, (byte) 0xD5,
    258                 (byte) 0xF5, (byte) 0x09, (byte) 0x1C, (byte) 0xCE, (byte) 0xA7, (byte) 0x19,
    259                 (byte) 0x6D, (byte) 0x04, (byte) 0x53, (byte) 0x71, (byte) 0xCC, (byte) 0x84,
    260                 (byte) 0xA0, (byte) 0xB2, (byte) 0xA0, (byte) 0x68, (byte) 0xA3, (byte) 0x40,
    261                 (byte) 0xC0, (byte) 0x67, (byte) 0x38, (byte) 0x96, (byte) 0x73, (byte) 0x2E,
    262                 (byte) 0x8E, (byte) 0x2A, (byte) 0x9D, (byte) 0x56, (byte) 0xE9, (byte) 0xAC,
    263                 (byte) 0xC7, (byte) 0xEC, (byte) 0x84, (byte) 0x7F, (byte) 0xFC, (byte) 0xE0,
    264                 (byte) 0x69, (byte) 0x03, (byte) 0x8B, (byte) 0x48, (byte) 0x64, (byte) 0x76,
    265                 (byte) 0x85, (byte) 0xA5, (byte) 0x10, (byte) 0xD9, (byte) 0x31, (byte) 0xC3,
    266                 (byte) 0x8B, (byte) 0x07, (byte) 0x48, (byte) 0x62, (byte) 0xF6, (byte) 0x68,
    267                 (byte) 0xF2, (byte) 0x96, (byte) 0xB2, (byte) 0x18, (byte) 0x5B, (byte) 0xFF,
    268                 (byte) 0x6D, (byte) 0xD1, (byte) 0x6B, (byte) 0xF5, (byte) 0xFD, (byte) 0x81,
    269                 (byte) 0xF1, (byte) 0xFD, (byte) 0x04, (byte) 0xF0, (byte) 0x9F, (byte) 0xB7,
    270                 (byte) 0x08, (byte) 0x95, (byte) 0x57, (byte) 0x48, (byte) 0x07, (byte) 0x00,
    271                 (byte) 0x52, (byte) 0xEC, (byte) 0x75, (byte) 0x91, (byte) 0x02, (byte) 0x11,
    272                 (byte) 0xA3, (byte) 0x64, (byte) 0x26, (byte) 0xCA,
    273         });
    274 
    275         AlgorithmParameterSpec spec = new DSAParameterSpec(p, q, g);
    276         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
    277                 .setAlias(TEST_ALIAS_1)
    278                 .setKeyType("DSA")
    279                 .setKeySize(2048)
    280                 .setAlgorithmParameterSpec(spec)
    281                 .setSubject(TEST_DN_1)
    282                 .setSerialNumber(TEST_SERIAL_1)
    283                 .setStartDate(NOW)
    284                 .setEndDate(NOW_PLUS_10_YEARS)
    285                 .build());
    286 
    287         final KeyPair pair = mGenerator.generateKeyPair();
    288         assertNotNull("The KeyPair returned should not be null", pair);
    289 
    290         assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 2048, spec, TEST_DN_1, TEST_SERIAL_1, NOW,
    291                 NOW_PLUS_10_YEARS);
    292     }
    293 
    294     public void testKeyPairGenerator_GenerateKeyPair_EC_Unencrypted_Success() throws Exception {
    295         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
    296                 .setAlias(TEST_ALIAS_1)
    297                 .setKeyType("EC")
    298                 .setSubject(TEST_DN_1)
    299                 .setSerialNumber(TEST_SERIAL_1)
    300                 .setStartDate(NOW)
    301                 .setEndDate(NOW_PLUS_10_YEARS)
    302                 .build());
    303 
    304         final KeyPair pair = mGenerator.generateKeyPair();
    305         assertNotNull("The KeyPair returned should not be null", pair);
    306 
    307         assertKeyPairCorrect(pair, TEST_ALIAS_1, "EC", 256, null, TEST_DN_1, TEST_SERIAL_1, NOW,
    308                 NOW_PLUS_10_YEARS);
    309     }
    310 
    311     public void testKeyPairGenerator_GenerateKeyPair_EC_P521_Unencrypted_Success() throws Exception {
    312         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
    313                 .setAlias(TEST_ALIAS_1)
    314                 .setKeyType("EC")
    315                 .setKeySize(521)
    316                 .setSubject(TEST_DN_1)
    317                 .setSerialNumber(TEST_SERIAL_1)
    318                 .setStartDate(NOW)
    319                 .setEndDate(NOW_PLUS_10_YEARS)
    320                 .build());
    321 
    322         final KeyPair pair = mGenerator.generateKeyPair();
    323         assertNotNull("The KeyPair returned should not be null", pair);
    324 
    325         assertKeyPairCorrect(pair, TEST_ALIAS_1, "EC", 521, null, TEST_DN_1, TEST_SERIAL_1, NOW,
    326                 NOW_PLUS_10_YEARS);
    327     }
    328 
    329     public void testKeyPairGenerator_GenerateKeyPair_RSA_Unencrypted_Success() throws Exception {
    330         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
    331                 .setAlias(TEST_ALIAS_1)
    332                 .setSubject(TEST_DN_1)
    333                 .setSerialNumber(TEST_SERIAL_1)
    334                 .setStartDate(NOW)
    335                 .setEndDate(NOW_PLUS_10_YEARS)
    336                 .build());
    337 
    338         final KeyPair pair = mGenerator.generateKeyPair();
    339         assertNotNull("The KeyPair returned should not be null", pair);
    340 
    341         assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
    342                 NOW_PLUS_10_YEARS);
    343     }
    344 
    345     public void testKeyPairGenerator_GenerateKeyPair_Replaced_Unencrypted_Success()
    346             throws Exception {
    347         // Generate the first key
    348         {
    349             mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
    350                     .setAlias(TEST_ALIAS_1).setSubject(TEST_DN_1).setSerialNumber(TEST_SERIAL_1)
    351                     .setStartDate(NOW).setEndDate(NOW_PLUS_10_YEARS).build());
    352             final KeyPair pair1 = mGenerator.generateKeyPair();
    353             assertNotNull("The KeyPair returned should not be null", pair1);
    354             assertKeyPairCorrect(pair1, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1,
    355                     NOW, NOW_PLUS_10_YEARS);
    356         }
    357 
    358         // Replace the original key
    359         {
    360             mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
    361                     .setAlias(TEST_ALIAS_1).setSubject(TEST_DN_2).setSerialNumber(TEST_SERIAL_2)
    362                     .setStartDate(NOW).setEndDate(NOW_PLUS_10_YEARS).build());
    363             final KeyPair pair2 = mGenerator.generateKeyPair();
    364             assertNotNull("The KeyPair returned should not be null", pair2);
    365             assertKeyPairCorrect(pair2, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_2, TEST_SERIAL_2,
    366                     NOW, NOW_PLUS_10_YEARS);
    367         }
    368     }
    369 
    370     public void testKeyPairGenerator_GenerateKeyPair_No_Collision_Unencrypted_Success()
    371             throws Exception {
    372         // Generate the first key
    373         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
    374                 .setAlias(TEST_ALIAS_1)
    375                 .setSubject(TEST_DN_1)
    376                 .setSerialNumber(TEST_SERIAL_1)
    377                 .setStartDate(NOW)
    378                 .setEndDate(NOW_PLUS_10_YEARS)
    379                 .build());
    380         final KeyPair pair1 = mGenerator.generateKeyPair();
    381         assertNotNull("The KeyPair returned should not be null", pair1);
    382         assertKeyPairCorrect(pair1, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
    383                 NOW_PLUS_10_YEARS);
    384 
    385         // Generate the second key
    386         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
    387                 .setAlias(TEST_ALIAS_2)
    388                 .setSubject(TEST_DN_2)
    389                 .setSerialNumber(TEST_SERIAL_2)
    390                 .setStartDate(NOW)
    391                 .setEndDate(NOW_PLUS_10_YEARS)
    392                 .build());
    393         final KeyPair pair2 = mGenerator.generateKeyPair();
    394         assertNotNull("The KeyPair returned should not be null", pair2);
    395         assertKeyPairCorrect(pair2, TEST_ALIAS_2, "RSA", 2048, null, TEST_DN_2, TEST_SERIAL_2, NOW,
    396                 NOW_PLUS_10_YEARS);
    397 
    398         // Check the first key again
    399         assertKeyPairCorrect(pair1, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
    400                 NOW_PLUS_10_YEARS);
    401     }
    402 
    403     private void assertKeyPairCorrect(KeyPair pair, String alias, String keyType, int keySize,
    404             AlgorithmParameterSpec spec, X500Principal dn, BigInteger serial, Date start, Date end)
    405             throws Exception {
    406         final PublicKey pubKey = pair.getPublic();
    407         assertNotNull("The PublicKey for the KeyPair should be not null", pubKey);
    408         assertEquals(keyType, pubKey.getAlgorithm());
    409 
    410         if ("DSA".equalsIgnoreCase(keyType)) {
    411             DSAPublicKey dsaPubKey = (DSAPublicKey) pubKey;
    412             DSAParams actualParams = dsaPubKey.getParams();
    413             assertEquals(keySize, (actualParams.getP().bitLength() + 7) & ~7);
    414             if (spec != null) {
    415                 DSAParameterSpec expectedParams = (DSAParameterSpec) spec;
    416                 assertEquals(expectedParams.getP(), actualParams.getP());
    417                 assertEquals(expectedParams.getQ(), actualParams.getQ());
    418                 assertEquals(expectedParams.getG(), actualParams.getG());
    419             }
    420         } else if ("EC".equalsIgnoreCase(keyType)) {
    421             assertEquals("Curve should be what was specified during initialization", keySize,
    422                     ((ECPublicKey) pubKey).getParams().getCurve().getField().getFieldSize());
    423         } else if ("RSA".equalsIgnoreCase(keyType)) {
    424             RSAPublicKey rsaPubKey = (RSAPublicKey) pubKey;
    425             assertEquals("Modulus size should be what is specified during initialization",
    426                     (keySize + 7) & ~7, (rsaPubKey.getModulus().bitLength() + 7) & ~7);
    427             if (spec != null) {
    428                 RSAKeyGenParameterSpec params = (RSAKeyGenParameterSpec) spec;
    429                 assertEquals((keySize + 7) & ~7, (params.getKeysize() + 7) & ~7);
    430                 assertEquals(params.getPublicExponent(), rsaPubKey.getPublicExponent());
    431             }
    432         }
    433 
    434         final PrivateKey privKey = pair.getPrivate();
    435         assertNotNull("The PrivateKey for the KeyPair should be not null", privKey);
    436         assertEquals(keyType, privKey.getAlgorithm());
    437 
    438         KeyStore.Entry entry = mKeyStore.getEntry(alias, null);
    439         assertNotNull("Entry should exist", entry);
    440 
    441         assertTrue("Entry should be a PrivateKeyEntry", entry instanceof KeyStore.PrivateKeyEntry);
    442         KeyStore.PrivateKeyEntry privEntry = (KeyStore.PrivateKeyEntry) entry;
    443 
    444         Certificate userCert = privEntry.getCertificate();
    445         assertTrue("Certificate should be in X.509 format", userCert instanceof X509Certificate);
    446 
    447         final X509Certificate x509userCert = (X509Certificate) userCert;
    448 
    449         assertEquals("PublicKey used to sign certificate should match one returned in KeyPair",
    450                 pubKey, x509userCert.getPublicKey());
    451 
    452         assertEquals("The Subject DN should be the one passed into the params", dn,
    453                 x509userCert.getSubjectDN());
    454 
    455         assertEquals("The Issuer DN should be the same as the Subject DN", dn,
    456                 x509userCert.getIssuerDN());
    457 
    458         assertEquals("The Serial should be the one passed into the params", serial,
    459                 x509userCert.getSerialNumber());
    460 
    461         assertDateEquals("The notBefore date should be the one passed into the params", start,
    462                 x509userCert.getNotBefore());
    463 
    464         assertDateEquals("The notAfter date should be the one passed into the params", end,
    465                 x509userCert.getNotAfter());
    466 
    467         x509userCert.verify(pubKey);
    468 
    469         Certificate[] chain = privEntry.getCertificateChain();
    470         assertEquals("A list of CA certificates should not exist for the generated entry", 1,
    471                 chain.length);
    472 
    473         assertUsableInSSLConnection(privKey, x509userCert);
    474     }
    475 
    476     private static void assertUsableInSSLConnection(final PrivateKey privKey,
    477             final X509Certificate x509userCert) throws Exception {
    478         // TODO this should probably be in something like:
    479         // TestKeyStore.createForClientSelfSigned(...)
    480         String provider = SSLContext.getDefault().getProvider().getName();
    481         TrustManager[] clientTrustManagers = TestKeyStore.createTrustManagers(
    482                 TestKeyStore.getIntermediateCa().keyStore);
    483         SSLContext clientContext = TestSSLContext.createSSLContext("TLS", provider,
    484                 new KeyManager[] {
    485                     TestKeyManager.wrap(new MyKeyManager(privKey, x509userCert))
    486                 }, clientTrustManagers);
    487         TestKeyStore serverKeyStore = TestKeyStore.getServer();
    488         serverKeyStore.keyStore.setCertificateEntry("client-selfSigned", x509userCert);
    489         SSLContext serverContext = TestSSLContext.createSSLContext("TLS", provider,
    490                 serverKeyStore.keyManagers,
    491                 TestKeyStore.createTrustManagers(serverKeyStore.keyStore));
    492         SSLServerSocket serverSocket = (SSLServerSocket) serverContext.getServerSocketFactory()
    493                 .createServerSocket(0);
    494         InetAddress host = InetAddress.getLocalHost();
    495         int port = serverSocket.getLocalPort();
    496 
    497         SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(host, port);
    498         final SSLSocket server = (SSLSocket) serverSocket.accept();
    499         ExecutorService executor = Executors.newSingleThreadExecutor();
    500         Future<Void> future = executor.submit(new Callable<Void>() {
    501             @Override
    502             public Void call() throws Exception {
    503                 server.setNeedClientAuth(true);
    504                 server.setWantClientAuth(true);
    505                 server.startHandshake();
    506                 return null;
    507             }
    508         });
    509         executor.shutdown();
    510         client.startHandshake();
    511         Certificate[] usedClientCerts = client.getSession().getLocalCertificates();
    512         assertNotNull(usedClientCerts);
    513         assertEquals(1, usedClientCerts.length);
    514         assertEquals(x509userCert, usedClientCerts[0]);
    515         future.get();
    516         client.close();
    517         server.close();
    518     }
    519 
    520     private static class MyKeyManager extends X509ExtendedKeyManager {
    521         private final PrivateKey key;
    522         private final X509Certificate[] chain;
    523 
    524         public MyKeyManager(PrivateKey key, X509Certificate cert) {
    525             this.key = key;
    526             this.chain = new X509Certificate[] { cert };
    527         }
    528 
    529         @Override
    530         public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
    531             return "fake";
    532         }
    533 
    534         @Override
    535         public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
    536             throw new UnsupportedOperationException("Not implemented");
    537         }
    538 
    539         @Override
    540         public X509Certificate[] getCertificateChain(String alias) {
    541             return chain;
    542         }
    543 
    544         @Override
    545         public String[] getClientAliases(String keyType, Principal[] issuers) {
    546             return new String[] { "fake" };
    547         }
    548 
    549         @Override
    550         public String[] getServerAliases(String keyType, Principal[] issuers) {
    551             throw new UnsupportedOperationException("Not implemented");
    552         }
    553 
    554         @Override
    555         public PrivateKey getPrivateKey(String alias) {
    556             return key;
    557         }
    558     }
    559 
    560     private static void assertDateEquals(String message, Date date1, Date date2) throws Exception {
    561         SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss");
    562 
    563         String result1 = formatter.format(date1);
    564         String result2 = formatter.format(date2);
    565 
    566         assertEquals(message, result1, result2);
    567     }
    568 }
    569