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         assertEquals("Public keys should be in X.509 format", "X.509", pubKey.getFormat());
    410         assertNotNull("Public keys should be encodable", pubKey.getEncoded());
    411 
    412         if ("DSA".equalsIgnoreCase(keyType)) {
    413             DSAPublicKey dsaPubKey = (DSAPublicKey) pubKey;
    414             DSAParams actualParams = dsaPubKey.getParams();
    415             assertEquals(keySize, (actualParams.getP().bitLength() + 7) & ~7);
    416             if (spec != null) {
    417                 DSAParameterSpec expectedParams = (DSAParameterSpec) spec;
    418                 assertEquals(expectedParams.getP(), actualParams.getP());
    419                 assertEquals(expectedParams.getQ(), actualParams.getQ());
    420                 assertEquals(expectedParams.getG(), actualParams.getG());
    421             }
    422         } else if ("EC".equalsIgnoreCase(keyType)) {
    423             assertEquals("Curve should be what was specified during initialization", keySize,
    424                     ((ECPublicKey) pubKey).getParams().getCurve().getField().getFieldSize());
    425         } else if ("RSA".equalsIgnoreCase(keyType)) {
    426             RSAPublicKey rsaPubKey = (RSAPublicKey) pubKey;
    427             assertEquals("Modulus size should be what is specified during initialization",
    428                     (keySize + 7) & ~7, (rsaPubKey.getModulus().bitLength() + 7) & ~7);
    429             if (spec != null) {
    430                 RSAKeyGenParameterSpec params = (RSAKeyGenParameterSpec) spec;
    431                 assertEquals((keySize + 7) & ~7, (params.getKeysize() + 7) & ~7);
    432                 assertEquals(params.getPublicExponent(), rsaPubKey.getPublicExponent());
    433             }
    434         }
    435 
    436         final PrivateKey privKey = pair.getPrivate();
    437         assertNotNull("The PrivateKey for the KeyPair should be not null", privKey);
    438         assertEquals(keyType, privKey.getAlgorithm());
    439         assertNull("getFormat() should return null", privKey.getFormat());
    440         assertNull("getEncoded() should return null", privKey.getEncoded());
    441 
    442         KeyStore.Entry entry = mKeyStore.getEntry(alias, null);
    443         assertNotNull("Entry should exist", entry);
    444 
    445         assertTrue("Entry should be a PrivateKeyEntry", entry instanceof KeyStore.PrivateKeyEntry);
    446         KeyStore.PrivateKeyEntry privEntry = (KeyStore.PrivateKeyEntry) entry;
    447 
    448         Certificate userCert = privEntry.getCertificate();
    449         assertTrue("Certificate should be in X.509 format", userCert instanceof X509Certificate);
    450 
    451         final X509Certificate x509userCert = (X509Certificate) userCert;
    452 
    453         assertEquals("PublicKey used to sign certificate should match one returned in KeyPair",
    454                 pubKey, x509userCert.getPublicKey());
    455 
    456         assertEquals("The Subject DN should be the one passed into the params", dn,
    457                 x509userCert.getSubjectDN());
    458 
    459         assertEquals("The Issuer DN should be the same as the Subject DN", dn,
    460                 x509userCert.getIssuerDN());
    461 
    462         assertEquals("The Serial should be the one passed into the params", serial,
    463                 x509userCert.getSerialNumber());
    464 
    465         assertDateEquals("The notBefore date should be the one passed into the params", start,
    466                 x509userCert.getNotBefore());
    467 
    468         assertDateEquals("The notAfter date should be the one passed into the params", end,
    469                 x509userCert.getNotAfter());
    470 
    471         x509userCert.verify(pubKey);
    472 
    473         Certificate[] chain = privEntry.getCertificateChain();
    474         assertEquals("A list of CA certificates should not exist for the generated entry", 1,
    475                 chain.length);
    476 
    477         assertUsableInSSLConnection(privKey, x509userCert);
    478 
    479         assertEquals("Retrieved key and generated key should be equal", privKey,
    480                 privEntry.getPrivateKey());
    481     }
    482 
    483     private static void assertUsableInSSLConnection(final PrivateKey privKey,
    484             final X509Certificate x509userCert) throws Exception {
    485         // TODO this should probably be in something like:
    486         // TestKeyStore.createForClientSelfSigned(...)
    487         String provider = SSLContext.getDefault().getProvider().getName();
    488         TrustManager[] clientTrustManagers = TestKeyStore.createTrustManagers(
    489                 TestKeyStore.getIntermediateCa().keyStore);
    490         SSLContext clientContext = TestSSLContext.createSSLContext("TLS", provider,
    491                 new KeyManager[] {
    492                     TestKeyManager.wrap(new MyKeyManager(privKey, x509userCert))
    493                 }, clientTrustManagers);
    494         TestKeyStore serverKeyStore = TestKeyStore.getServer();
    495         serverKeyStore.keyStore.setCertificateEntry("client-selfSigned", x509userCert);
    496         SSLContext serverContext = TestSSLContext.createSSLContext("TLS", provider,
    497                 serverKeyStore.keyManagers,
    498                 TestKeyStore.createTrustManagers(serverKeyStore.keyStore));
    499         SSLServerSocket serverSocket = (SSLServerSocket) serverContext.getServerSocketFactory()
    500                 .createServerSocket(0);
    501         InetAddress host = InetAddress.getLocalHost();
    502         int port = serverSocket.getLocalPort();
    503 
    504         SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(host, port);
    505         final SSLSocket server = (SSLSocket) serverSocket.accept();
    506         ExecutorService executor = Executors.newSingleThreadExecutor();
    507         Future<Void> future = executor.submit(new Callable<Void>() {
    508             @Override
    509             public Void call() throws Exception {
    510                 server.setNeedClientAuth(true);
    511                 server.setWantClientAuth(true);
    512                 server.startHandshake();
    513                 return null;
    514             }
    515         });
    516         executor.shutdown();
    517         client.startHandshake();
    518         Certificate[] usedClientCerts = client.getSession().getLocalCertificates();
    519         assertNotNull(usedClientCerts);
    520         assertEquals(1, usedClientCerts.length);
    521         assertEquals(x509userCert, usedClientCerts[0]);
    522         future.get();
    523         client.close();
    524         server.close();
    525     }
    526 
    527     private static class MyKeyManager extends X509ExtendedKeyManager {
    528         private final PrivateKey key;
    529         private final X509Certificate[] chain;
    530 
    531         public MyKeyManager(PrivateKey key, X509Certificate cert) {
    532             this.key = key;
    533             this.chain = new X509Certificate[] { cert };
    534         }
    535 
    536         @Override
    537         public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
    538             return "fake";
    539         }
    540 
    541         @Override
    542         public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
    543             throw new UnsupportedOperationException("Not implemented");
    544         }
    545 
    546         @Override
    547         public X509Certificate[] getCertificateChain(String alias) {
    548             return chain;
    549         }
    550 
    551         @Override
    552         public String[] getClientAliases(String keyType, Principal[] issuers) {
    553             return new String[] { "fake" };
    554         }
    555 
    556         @Override
    557         public String[] getServerAliases(String keyType, Principal[] issuers) {
    558             throw new UnsupportedOperationException("Not implemented");
    559         }
    560 
    561         @Override
    562         public PrivateKey getPrivateKey(String alias) {
    563             return key;
    564         }
    565     }
    566 
    567     private static void assertDateEquals(String message, Date date1, Date date2) throws Exception {
    568         SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss");
    569 
    570         String result1 = formatter.format(date1);
    571         String result2 = formatter.format(date2);
    572 
    573         assertEquals(message, result1, result2);
    574     }
    575 }
    576