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