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