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