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.security.keystore.KeyGenParameterSpec; 21 import android.security.keystore.KeyInfo; 22 import android.security.keystore.KeyProperties; 23 import android.test.AndroidTestCase; 24 import android.test.MoreAsserts; 25 26 import java.math.BigInteger; 27 import java.net.InetAddress; 28 import java.net.Socket; 29 import java.security.InvalidAlgorithmParameterException; 30 import java.security.KeyPair; 31 import java.security.KeyPairGenerator; 32 import java.security.KeyStore; 33 import java.security.NoSuchAlgorithmException; 34 import java.security.NoSuchProviderException; 35 import java.security.Principal; 36 import java.security.PrivateKey; 37 import java.security.Provider; 38 import java.security.SecureRandom; 39 import java.security.Security; 40 import java.security.Provider.Service; 41 import java.security.cert.Certificate; 42 import java.security.cert.X509Certificate; 43 import java.security.interfaces.ECKey; 44 import java.security.interfaces.ECPublicKey; 45 import java.security.interfaces.RSAPublicKey; 46 import java.security.spec.AlgorithmParameterSpec; 47 import java.security.spec.ECGenParameterSpec; 48 import java.security.spec.ECParameterSpec; 49 import java.security.spec.RSAKeyGenParameterSpec; 50 import java.text.SimpleDateFormat; 51 import java.util.ArrayList; 52 import java.util.Arrays; 53 import java.util.Date; 54 import java.util.HashSet; 55 import java.util.List; 56 import java.util.Locale; 57 import java.util.Map; 58 import java.util.Set; 59 import java.util.TreeMap; 60 import java.util.concurrent.Callable; 61 import java.util.concurrent.ExecutorService; 62 import java.util.concurrent.Executors; 63 import java.util.concurrent.Future; 64 import java.text.DecimalFormatSymbols; 65 66 import javax.net.ssl.KeyManager; 67 import javax.net.ssl.SSLContext; 68 import javax.net.ssl.SSLServerSocket; 69 import javax.net.ssl.SSLSocket; 70 import javax.net.ssl.X509ExtendedKeyManager; 71 import javax.security.auth.x500.X500Principal; 72 73 import libcore.java.security.TestKeyStore; 74 import libcore.javax.net.ssl.TestKeyManager; 75 import libcore.javax.net.ssl.TestSSLContext; 76 77 public class KeyPairGeneratorTest extends AndroidTestCase { 78 private KeyStore mKeyStore; 79 80 private CountingSecureRandom mRng; 81 82 private static final String TEST_ALIAS_1 = "test1"; 83 84 private static final String TEST_ALIAS_2 = "test2"; 85 86 private static final String TEST_ALIAS_3 = "test3"; 87 88 private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1"); 89 90 private static final X500Principal TEST_DN_2 = new X500Principal("CN=test2"); 91 92 private static final BigInteger TEST_SERIAL_1 = BigInteger.ONE; 93 94 private static final BigInteger TEST_SERIAL_2 = BigInteger.valueOf(2L); 95 96 private static final long NOW_MILLIS = System.currentTimeMillis(); 97 98 /* We have to round this off because X509v3 doesn't store milliseconds. */ 99 private static final Date NOW = new Date(NOW_MILLIS - (NOW_MILLIS % 1000L)); 100 101 @SuppressWarnings("deprecation") 102 private static final Date NOW_PLUS_10_YEARS = new Date(NOW.getYear() + 10, 0, 1); 103 104 private static final long DAY_IN_MILLIS = 1000 * 60 * 60 * 24; 105 106 private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake"); 107 private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1"); 108 private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1970 109 private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048 110 111 private static final String EXPECTED_PROVIDER_NAME = TestUtils.EXPECTED_PROVIDER_NAME; 112 113 private static final String[] EXPECTED_ALGORITHMS = { 114 "EC", 115 "RSA", 116 }; 117 118 private static final Map<String, Integer> DEFAULT_KEY_SIZES = 119 new TreeMap<>(String.CASE_INSENSITIVE_ORDER); 120 static { 121 DEFAULT_KEY_SIZES.put("EC", 256); 122 DEFAULT_KEY_SIZES.put("RSA", 2048); 123 } 124 125 @Override 126 protected void setUp() throws Exception { 127 super.setUp(); 128 mRng = new CountingSecureRandom(); 129 mKeyStore = KeyStore.getInstance("AndroidKeyStore"); 130 mKeyStore.load(null, null); 131 } 132 133 public void testAlgorithmList() { 134 // Assert that Android Keystore Provider exposes exactly the expected KeyPairGenerator 135 // algorithms. We don't care whether the algorithms are exposed via aliases, as long as 136 // canonical names of algorithms are accepted. If the Provider exposes extraneous 137 // algorithms, it'll be caught because it'll have to expose at least one Service for such an 138 // algorithm, and this Service's algorithm will not be in the expected set. 139 140 Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME); 141 Set<Service> services = provider.getServices(); 142 Set<String> actualAlgsLowerCase = new HashSet<String>(); 143 Set<String> expectedAlgsLowerCase = new HashSet<String>( 144 Arrays.asList(TestUtils.toLowerCase(EXPECTED_ALGORITHMS))); 145 for (Service service : services) { 146 if ("KeyPairGenerator".equalsIgnoreCase(service.getType())) { 147 String algLowerCase = service.getAlgorithm().toLowerCase(Locale.US); 148 actualAlgsLowerCase.add(algLowerCase); 149 } 150 } 151 152 TestUtils.assertContentsInAnyOrder(actualAlgsLowerCase, 153 expectedAlgsLowerCase.toArray(new String[0])); 154 } 155 156 public void testInitialize_LegacySpec() throws Exception { 157 @SuppressWarnings("deprecation") 158 KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(getContext()) 159 .setAlias(TEST_ALIAS_1) 160 .setSubject(TEST_DN_1) 161 .setSerialNumber(TEST_SERIAL_1) 162 .setStartDate(NOW) 163 .setEndDate(NOW_PLUS_10_YEARS) 164 .build(); 165 getRsaGenerator().initialize(spec); 166 getRsaGenerator().initialize(spec, new SecureRandom()); 167 168 getEcGenerator().initialize(spec); 169 getEcGenerator().initialize(spec, new SecureRandom()); 170 } 171 172 public void testInitialize_ModernSpec() throws Exception { 173 KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder( 174 TEST_ALIAS_1, 175 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY) 176 .build(); 177 getRsaGenerator().initialize(spec); 178 getRsaGenerator().initialize(spec, new SecureRandom()); 179 180 getEcGenerator().initialize(spec); 181 getEcGenerator().initialize(spec, new SecureRandom()); 182 } 183 184 public void testInitialize_KeySizeOnly() throws Exception { 185 try { 186 getRsaGenerator().initialize(1024); 187 fail("KeyPairGenerator should not support setting the key size"); 188 } catch (IllegalArgumentException success) { 189 } 190 191 try { 192 getEcGenerator().initialize(256); 193 fail("KeyPairGenerator should not support setting the key size"); 194 } catch (IllegalArgumentException success) { 195 } 196 } 197 198 public void testInitialize_KeySizeAndSecureRandomOnly() 199 throws Exception { 200 try { 201 getRsaGenerator().initialize(1024, new SecureRandom()); 202 fail("KeyPairGenerator should not support setting the key size"); 203 } catch (IllegalArgumentException success) { 204 } 205 206 try { 207 getEcGenerator().initialize(1024, new SecureRandom()); 208 fail("KeyPairGenerator should not support setting the key size"); 209 } catch (IllegalArgumentException success) { 210 } 211 } 212 213 public void testDefaultKeySize() throws Exception { 214 for (String algorithm : EXPECTED_ALGORITHMS) { 215 try { 216 int expectedSizeBits = DEFAULT_KEY_SIZES.get(algorithm); 217 KeyPairGenerator generator = getGenerator(algorithm); 218 generator.initialize(getWorkingSpec().build()); 219 KeyPair keyPair = generator.generateKeyPair(); 220 assertEquals(expectedSizeBits, 221 TestUtils.getKeyInfo(keyPair.getPrivate()).getKeySize()); 222 } catch (Throwable e) { 223 throw new RuntimeException("Failed for " + algorithm, e); 224 } 225 } 226 } 227 228 public void testInitWithUnknownBlockModeFails() { 229 for (String algorithm : EXPECTED_ALGORITHMS) { 230 try { 231 KeyPairGenerator generator = getGenerator(algorithm); 232 try { 233 generator.initialize(getWorkingSpec().setBlockModes("weird").build()); 234 fail(); 235 } catch (InvalidAlgorithmParameterException expected) {} 236 } catch (Throwable e) { 237 throw new RuntimeException("Failed for " + algorithm, e); 238 } 239 } 240 } 241 242 public void testInitWithUnknownEncryptionPaddingFails() { 243 for (String algorithm : EXPECTED_ALGORITHMS) { 244 try { 245 KeyPairGenerator generator = getGenerator(algorithm); 246 try { 247 generator.initialize(getWorkingSpec().setEncryptionPaddings("weird").build()); 248 fail(); 249 } catch (InvalidAlgorithmParameterException expected) {} 250 } catch (Throwable e) { 251 throw new RuntimeException("Failed for " + algorithm, e); 252 } 253 } 254 } 255 256 public void testInitWithUnknownSignaturePaddingFails() { 257 for (String algorithm : EXPECTED_ALGORITHMS) { 258 try { 259 KeyPairGenerator generator = getGenerator(algorithm); 260 try { 261 generator.initialize(getWorkingSpec().setSignaturePaddings("weird").build()); 262 fail(); 263 } catch (InvalidAlgorithmParameterException expected) {} 264 } catch (Throwable e) { 265 throw new RuntimeException("Failed for " + algorithm, e); 266 } 267 } 268 } 269 270 public void testInitWithUnknownDigestFails() { 271 for (String algorithm : EXPECTED_ALGORITHMS) { 272 try { 273 KeyPairGenerator generator = getGenerator(algorithm); 274 try { 275 generator.initialize(getWorkingSpec().setDigests("weird").build()); 276 fail(); 277 } catch (InvalidAlgorithmParameterException expected) {} 278 } catch (Throwable e) { 279 throw new RuntimeException("Failed for " + algorithm, e); 280 } 281 } 282 } 283 284 public void testInitRandomizedEncryptionRequiredButViolatedFails() throws Exception { 285 for (String algorithm : EXPECTED_ALGORITHMS) { 286 try { 287 KeyPairGenerator generator = getGenerator(algorithm); 288 try { 289 generator.initialize(getWorkingSpec( 290 KeyProperties.PURPOSE_ENCRYPT) 291 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) 292 .build()); 293 fail(); 294 } catch (InvalidAlgorithmParameterException expected) {} 295 } catch (Throwable e) { 296 throw new RuntimeException("Failed for " + algorithm, e); 297 } 298 } 299 } 300 301 public void testGenerateHonorsRequestedAuthorizations() throws Exception { 302 Date keyValidityStart = new Date(System.currentTimeMillis() - TestUtils.DAY_IN_MILLIS); 303 Date keyValidityForOriginationEnd = 304 new Date(System.currentTimeMillis() + TestUtils.DAY_IN_MILLIS); 305 Date keyValidityForConsumptionEnd = 306 new Date(System.currentTimeMillis() + 3 * TestUtils.DAY_IN_MILLIS); 307 for (String algorithm : EXPECTED_ALGORITHMS) { 308 try { 309 String[] blockModes = 310 new String[] {KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC}; 311 String[] encryptionPaddings = 312 new String[] {KeyProperties.ENCRYPTION_PADDING_RSA_OAEP, 313 KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1}; 314 String[] digests = 315 new String[] {KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA1}; 316 int purposes = KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT; 317 KeyPairGenerator generator = getGenerator(algorithm); 318 generator.initialize(getWorkingSpec(purposes) 319 .setBlockModes(blockModes) 320 .setEncryptionPaddings(encryptionPaddings) 321 .setDigests(digests) 322 .setKeyValidityStart(keyValidityStart) 323 .setKeyValidityForOriginationEnd(keyValidityForOriginationEnd) 324 .setKeyValidityForConsumptionEnd(keyValidityForConsumptionEnd) 325 .build()); 326 KeyPair keyPair = generator.generateKeyPair(); 327 assertEquals(algorithm, keyPair.getPrivate().getAlgorithm()); 328 329 KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 330 assertEquals(purposes, keyInfo.getPurposes()); 331 TestUtils.assertContentsInAnyOrder( 332 Arrays.asList(keyInfo.getBlockModes()), blockModes); 333 334 List<String> actualEncryptionPaddings = 335 new ArrayList<String>(Arrays.asList(keyInfo.getEncryptionPaddings())); 336 // Keystore may have added ENCRYPTION_PADDING_NONE to allow software OAEP 337 actualEncryptionPaddings.remove(KeyProperties.ENCRYPTION_PADDING_NONE); 338 TestUtils.assertContentsInAnyOrder( 339 actualEncryptionPaddings, encryptionPaddings); 340 341 List<String> actualDigests = 342 new ArrayList<String>(Arrays.asList(keyInfo.getDigests())); 343 // Keystore may have added DIGEST_NONE, to allow software digesting. 344 actualDigests.remove(KeyProperties.DIGEST_NONE); 345 TestUtils.assertContentsInAnyOrder(actualDigests, digests); 346 347 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings())); 348 assertEquals(keyValidityStart, keyInfo.getKeyValidityStart()); 349 assertEquals(keyValidityForOriginationEnd, 350 keyInfo.getKeyValidityForOriginationEnd()); 351 assertEquals(keyValidityForConsumptionEnd, 352 keyInfo.getKeyValidityForConsumptionEnd()); 353 assertFalse(keyInfo.isUserAuthenticationRequired()); 354 assertFalse(keyInfo.isUserAuthenticationRequirementEnforcedBySecureHardware()); 355 } catch (Throwable e) { 356 throw new RuntimeException("Failed for " + algorithm, e); 357 } 358 } 359 } 360 361 @SuppressWarnings("deprecation") 362 public void testGenerate_EC_LegacySpec() throws Exception { 363 // There are three legacy ways to generate an EC key pair using Android Keystore 364 // KeyPairGenerator: 365 // 1. Use an RSA KeyPairGenerator and specify EC as key type, 366 // 2. Use an EC KeyPairGenerator and specify EC as key type, 367 // 3. Use an EC KeyPairGenerator and leave the key type unspecified. 368 // 369 // We test all three. 370 371 // 1. Use an RSA KeyPairGenerator and specify EC as key type. 372 KeyPairGenerator generator = getRsaGenerator(); 373 generator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 374 .setAlias(TEST_ALIAS_1) 375 .setKeyType("EC") 376 .setSubject(TEST_DN_1) 377 .setSerialNumber(TEST_SERIAL_1) 378 .setStartDate(NOW) 379 .setEndDate(NOW_PLUS_10_YEARS) 380 .build()); 381 KeyPair keyPair = generator.generateKeyPair(); 382 assertGeneratedKeyPairAndSelfSignedCertificate( 383 keyPair, 384 TEST_ALIAS_1, 385 "EC", 386 256, 387 TEST_DN_1, 388 TEST_SERIAL_1, NOW, 389 NOW_PLUS_10_YEARS); 390 assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1); 391 assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1); 392 TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent( 393 ECCurves.NIST_P_256_SPEC, ((ECPublicKey) keyPair.getPublic()).getParams()); 394 KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 395 assertEquals(256, keyInfo.getKeySize()); 396 assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias()); 397 assertOneOf(keyInfo.getOrigin(), 398 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN); 399 assertEquals( 400 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY, 401 keyInfo.getPurposes()); 402 assertFalse(keyInfo.isUserAuthenticationRequired()); 403 assertEquals(null, keyInfo.getKeyValidityStart()); 404 assertEquals(null, keyInfo.getKeyValidityForOriginationEnd()); 405 assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd()); 406 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes())); 407 MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()), 408 KeyProperties.DIGEST_NONE, 409 KeyProperties.DIGEST_SHA1, 410 KeyProperties.DIGEST_SHA224, 411 KeyProperties.DIGEST_SHA256, 412 KeyProperties.DIGEST_SHA384, 413 KeyProperties.DIGEST_SHA512); 414 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings())); 415 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings())); 416 417 // 2. Use an EC KeyPairGenerator and specify EC as key type. 418 generator = getEcGenerator(); 419 generator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 420 .setAlias(TEST_ALIAS_2) 421 .setKeyType("EC") 422 .setSubject(TEST_DN_1) 423 .setSerialNumber(TEST_SERIAL_1) 424 .setStartDate(NOW) 425 .setEndDate(NOW_PLUS_10_YEARS) 426 .build()); 427 keyPair = generator.generateKeyPair(); 428 assertGeneratedKeyPairAndSelfSignedCertificate( 429 keyPair, 430 TEST_ALIAS_2, 431 "EC", 432 256, 433 TEST_DN_1, 434 TEST_SERIAL_1, 435 NOW, 436 NOW_PLUS_10_YEARS); 437 assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_2); 438 assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_2); 439 TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent( 440 ECCurves.NIST_P_256_SPEC, ((ECPublicKey) keyPair.getPublic()).getParams()); 441 keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 442 assertEquals(256, keyInfo.getKeySize()); 443 assertEquals(TEST_ALIAS_2, keyInfo.getKeystoreAlias()); 444 assertOneOf(keyInfo.getOrigin(), 445 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN); 446 assertEquals( 447 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY, 448 keyInfo.getPurposes()); 449 assertFalse(keyInfo.isUserAuthenticationRequired()); 450 assertEquals(null, keyInfo.getKeyValidityStart()); 451 assertEquals(null, keyInfo.getKeyValidityForOriginationEnd()); 452 assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd()); 453 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes())); 454 MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()), 455 KeyProperties.DIGEST_NONE, 456 KeyProperties.DIGEST_SHA1, 457 KeyProperties.DIGEST_SHA224, 458 KeyProperties.DIGEST_SHA256, 459 KeyProperties.DIGEST_SHA384, 460 KeyProperties.DIGEST_SHA512); 461 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings())); 462 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings())); 463 464 // 3. Use an EC KeyPairGenerator and leave the key type unspecified. 465 generator = getEcGenerator(); 466 generator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 467 .setAlias(TEST_ALIAS_3) 468 .setSubject(TEST_DN_1) 469 .setSerialNumber(TEST_SERIAL_1) 470 .setStartDate(NOW) 471 .setEndDate(NOW_PLUS_10_YEARS) 472 .build()); 473 keyPair = generator.generateKeyPair(); 474 assertGeneratedKeyPairAndSelfSignedCertificate( 475 keyPair, 476 TEST_ALIAS_3, 477 "EC", 478 256, 479 TEST_DN_1, 480 TEST_SERIAL_1, 481 NOW, 482 NOW_PLUS_10_YEARS); 483 assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_3); 484 assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_3); 485 TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent( 486 ECCurves.NIST_P_256_SPEC, ((ECPublicKey) keyPair.getPublic()).getParams()); 487 keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 488 assertEquals(256, keyInfo.getKeySize()); 489 assertEquals(TEST_ALIAS_3, keyInfo.getKeystoreAlias()); 490 assertOneOf(keyInfo.getOrigin(), 491 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN); 492 assertEquals( 493 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY, 494 keyInfo.getPurposes()); 495 assertFalse(keyInfo.isUserAuthenticationRequired()); 496 assertEquals(null, keyInfo.getKeyValidityStart()); 497 assertEquals(null, keyInfo.getKeyValidityForOriginationEnd()); 498 assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd()); 499 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes())); 500 MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()), 501 KeyProperties.DIGEST_NONE, 502 KeyProperties.DIGEST_SHA1, 503 KeyProperties.DIGEST_SHA224, 504 KeyProperties.DIGEST_SHA256, 505 KeyProperties.DIGEST_SHA384, 506 KeyProperties.DIGEST_SHA512); 507 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings())); 508 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings())); 509 } 510 511 public void testGenerate_RSA_LegacySpec() throws Exception { 512 KeyPairGenerator generator = getRsaGenerator(); 513 generator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) 514 .setAlias(TEST_ALIAS_1) 515 .setSubject(TEST_DN_1) 516 .setSerialNumber(TEST_SERIAL_1) 517 .setStartDate(NOW) 518 .setEndDate(NOW_PLUS_10_YEARS) 519 .build()); 520 KeyPair keyPair = generator.generateKeyPair(); 521 assertGeneratedKeyPairAndSelfSignedCertificate( 522 keyPair, 523 TEST_ALIAS_1, 524 "RSA", 525 2048, 526 TEST_DN_1, 527 TEST_SERIAL_1, 528 NOW, 529 NOW_PLUS_10_YEARS); 530 assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1); 531 assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1); 532 assertEquals(RSAKeyGenParameterSpec.F4, 533 ((RSAPublicKey) keyPair.getPublic()).getPublicExponent()); 534 KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 535 assertEquals(2048, keyInfo.getKeySize()); 536 assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias()); 537 assertOneOf(keyInfo.getOrigin(), 538 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN); 539 assertEquals( 540 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY 541 | KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT, 542 keyInfo.getPurposes()); 543 assertFalse(keyInfo.isUserAuthenticationRequired()); 544 assertEquals(null, keyInfo.getKeyValidityStart()); 545 assertEquals(null, keyInfo.getKeyValidityForOriginationEnd()); 546 assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd()); 547 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes())); 548 MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()), 549 KeyProperties.DIGEST_NONE, 550 KeyProperties.DIGEST_MD5, 551 KeyProperties.DIGEST_SHA1, 552 KeyProperties.DIGEST_SHA224, 553 KeyProperties.DIGEST_SHA256, 554 KeyProperties.DIGEST_SHA384, 555 KeyProperties.DIGEST_SHA512); 556 MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getEncryptionPaddings()), 557 KeyProperties.ENCRYPTION_PADDING_NONE, 558 KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1, 559 KeyProperties.ENCRYPTION_PADDING_RSA_OAEP); 560 MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getSignaturePaddings()), 561 KeyProperties.SIGNATURE_PADDING_RSA_PSS, 562 KeyProperties.SIGNATURE_PADDING_RSA_PKCS1); 563 } 564 565 public void testGenerate_ReplacesOldEntryWithSameAlias() 566 throws Exception { 567 // Generate the first key 568 { 569 KeyPairGenerator generator = getRsaGenerator(); 570 generator.initialize(new KeyGenParameterSpec.Builder( 571 TEST_ALIAS_1, 572 KeyProperties.PURPOSE_SIGN 573 | KeyProperties.PURPOSE_VERIFY 574 | KeyProperties.PURPOSE_ENCRYPT 575 | KeyProperties.PURPOSE_DECRYPT) 576 .setDigests(KeyProperties.DIGEST_NONE) 577 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) 578 .setCertificateSubject(TEST_DN_1) 579 .setCertificateSerialNumber(TEST_SERIAL_1) 580 .setCertificateNotBefore(NOW) 581 .setCertificateNotAfter(NOW_PLUS_10_YEARS) 582 .build()); 583 assertGeneratedKeyPairAndSelfSignedCertificate( 584 generator.generateKeyPair(), 585 TEST_ALIAS_1, 586 "RSA", 587 2048, 588 TEST_DN_1, 589 TEST_SERIAL_1, 590 NOW, 591 NOW_PLUS_10_YEARS); 592 } 593 594 // Replace the original key 595 { 596 KeyPairGenerator generator = getRsaGenerator(); 597 generator.initialize(new KeyGenParameterSpec.Builder( 598 TEST_ALIAS_1, 599 KeyProperties.PURPOSE_SIGN 600 | KeyProperties.PURPOSE_VERIFY 601 | KeyProperties.PURPOSE_ENCRYPT 602 | KeyProperties.PURPOSE_DECRYPT) 603 .setDigests(KeyProperties.DIGEST_NONE) 604 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) 605 .setCertificateSubject(TEST_DN_2) 606 .setCertificateSerialNumber(TEST_SERIAL_2) 607 .setCertificateNotBefore(NOW) 608 .setCertificateNotAfter(NOW_PLUS_10_YEARS) 609 .build()); 610 assertGeneratedKeyPairAndSelfSignedCertificate( 611 generator.generateKeyPair(), 612 TEST_ALIAS_1, 613 "RSA", 614 2048, 615 TEST_DN_2, 616 TEST_SERIAL_2, 617 NOW, 618 NOW_PLUS_10_YEARS); 619 } 620 } 621 622 public void testGenerate_DoesNotReplaceOtherEntries() 623 throws Exception { 624 // Generate the first key 625 KeyPairGenerator generator = getRsaGenerator(); 626 generator.initialize(new KeyGenParameterSpec.Builder( 627 TEST_ALIAS_1, 628 KeyProperties.PURPOSE_SIGN 629 | KeyProperties.PURPOSE_VERIFY 630 | KeyProperties.PURPOSE_ENCRYPT 631 | KeyProperties.PURPOSE_DECRYPT) 632 .setDigests(KeyProperties.DIGEST_NONE) 633 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) 634 .setCertificateSubject(TEST_DN_1) 635 .setCertificateSerialNumber(TEST_SERIAL_1) 636 .setCertificateNotBefore(NOW) 637 .setCertificateNotAfter(NOW_PLUS_10_YEARS) 638 .build()); 639 KeyPair keyPair1 = generator.generateKeyPair(); 640 assertGeneratedKeyPairAndSelfSignedCertificate( 641 keyPair1, 642 TEST_ALIAS_1, 643 "RSA", 644 2048, 645 TEST_DN_1, 646 TEST_SERIAL_1, 647 NOW, 648 NOW_PLUS_10_YEARS); 649 650 // Generate the second key 651 generator.initialize(new KeyGenParameterSpec.Builder( 652 TEST_ALIAS_2, 653 KeyProperties.PURPOSE_SIGN 654 | KeyProperties.PURPOSE_VERIFY 655 | KeyProperties.PURPOSE_ENCRYPT 656 | KeyProperties.PURPOSE_DECRYPT) 657 .setDigests(KeyProperties.DIGEST_NONE) 658 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) 659 .setCertificateSubject(TEST_DN_2) 660 .setCertificateSerialNumber(TEST_SERIAL_2) 661 .setCertificateNotBefore(NOW) 662 .setCertificateNotAfter(NOW_PLUS_10_YEARS) 663 .build()); 664 KeyPair keyPair2 = generator.generateKeyPair(); 665 assertGeneratedKeyPairAndSelfSignedCertificate( 666 keyPair2, 667 TEST_ALIAS_2, 668 "RSA", 669 2048, 670 TEST_DN_2, 671 TEST_SERIAL_2, 672 NOW, 673 NOW_PLUS_10_YEARS); 674 675 // Check the first key pair again 676 assertGeneratedKeyPairAndSelfSignedCertificate( 677 keyPair1, 678 TEST_ALIAS_1, 679 "RSA", 680 2048, 681 TEST_DN_1, 682 TEST_SERIAL_1, 683 NOW, 684 NOW_PLUS_10_YEARS); 685 } 686 687 public void testGenerate_EC_ModernSpec_Defaults() throws Exception { 688 KeyPairGenerator generator = getEcGenerator(); 689 generator.initialize(new KeyGenParameterSpec.Builder( 690 TEST_ALIAS_1, 691 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY) 692 .build()); 693 KeyPair keyPair = generator.generateKeyPair(); 694 assertGeneratedKeyPairAndSelfSignedCertificate( 695 keyPair, 696 TEST_ALIAS_1, 697 "EC", 698 256, 699 DEFAULT_CERT_SUBJECT, 700 DEFAULT_CERT_SERIAL_NUMBER, 701 DEFAULT_CERT_NOT_BEFORE, 702 DEFAULT_CERT_NOT_AFTER); 703 TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent( 704 ECCurves.NIST_P_256_SPEC, ((ECKey) keyPair.getPrivate()).getParams()); 705 KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 706 assertEquals(256, keyInfo.getKeySize()); 707 assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias()); 708 assertOneOf(keyInfo.getOrigin(), 709 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN); 710 assertEquals( 711 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY, keyInfo.getPurposes()); 712 assertFalse(keyInfo.isUserAuthenticationRequired()); 713 assertEquals(null, keyInfo.getKeyValidityStart()); 714 assertEquals(null, keyInfo.getKeyValidityForOriginationEnd()); 715 assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd()); 716 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes())); 717 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getDigests())); 718 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings())); 719 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings())); 720 } 721 722 public void testGenerate_RSA_ModernSpec_Defaults() throws Exception { 723 KeyPairGenerator generator = getRsaGenerator(); 724 generator.initialize(new KeyGenParameterSpec.Builder( 725 TEST_ALIAS_1, 726 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) 727 .build()); 728 KeyPair keyPair = generator.generateKeyPair(); 729 assertGeneratedKeyPairAndSelfSignedCertificate( 730 keyPair, 731 TEST_ALIAS_1, 732 "RSA", 733 2048, 734 DEFAULT_CERT_SUBJECT, 735 DEFAULT_CERT_SERIAL_NUMBER, 736 DEFAULT_CERT_NOT_BEFORE, 737 DEFAULT_CERT_NOT_AFTER); 738 assertEquals(RSAKeyGenParameterSpec.F4, 739 ((RSAPublicKey) keyPair.getPublic()).getPublicExponent()); 740 KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 741 assertEquals(2048, keyInfo.getKeySize()); 742 assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias()); 743 assertOneOf(keyInfo.getOrigin(), 744 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN); 745 assertEquals( 746 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT, 747 keyInfo.getPurposes()); 748 assertFalse(keyInfo.isUserAuthenticationRequired()); 749 assertEquals(null, keyInfo.getKeyValidityStart()); 750 assertEquals(null, keyInfo.getKeyValidityForOriginationEnd()); 751 assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd()); 752 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes())); 753 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getDigests())); 754 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings())); 755 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings())); 756 } 757 758 public void testGenerate_EC_ModernSpec_AsCustomAsPossible() throws Exception { 759 KeyPairGenerator generator = getEcGenerator(); 760 Date keyValidityStart = new Date(System.currentTimeMillis()); 761 Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 1000000); 762 Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 10000000); 763 764 Date certNotBefore = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 7); 765 Date certNotAfter = new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 7); 766 BigInteger certSerialNumber = new BigInteger("12345678"); 767 X500Principal certSubject = new X500Principal("cn=hello"); 768 generator.initialize(new KeyGenParameterSpec.Builder( 769 TEST_ALIAS_1, 770 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY 771 | KeyProperties.PURPOSE_ENCRYPT) 772 .setKeySize(224) 773 .setDigests(KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512) 774 .setKeyValidityStart(keyValidityStart) 775 .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination) 776 .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption) 777 .setCertificateSerialNumber(certSerialNumber) 778 .setCertificateSubject(certSubject) 779 .setCertificateNotBefore(certNotBefore) 780 .setCertificateNotAfter(certNotAfter) 781 .setUnlockedDeviceRequired(true) 782 .build()); 783 KeyPair keyPair = generator.generateKeyPair(); 784 assertGeneratedKeyPairAndSelfSignedCertificate( 785 keyPair, 786 TEST_ALIAS_1, 787 "EC", 788 224, 789 certSubject, 790 certSerialNumber, 791 certNotBefore, 792 certNotAfter); 793 TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent( 794 ECCurves.NIST_P_224_SPEC, ((ECKey) keyPair.getPrivate()).getParams()); 795 KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 796 assertEquals(224, keyInfo.getKeySize()); 797 assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias()); 798 assertOneOf(keyInfo.getOrigin(), 799 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN); 800 assertEquals( 801 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY 802 | KeyProperties.PURPOSE_ENCRYPT, 803 keyInfo.getPurposes()); 804 assertEquals(keyValidityStart, keyInfo.getKeyValidityStart()); 805 assertEquals(keyValidityEndDateForOrigination, keyInfo.getKeyValidityForOriginationEnd()); 806 assertEquals(keyValidityEndDateForConsumption, keyInfo.getKeyValidityForConsumptionEnd()); 807 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes())); 808 809 List<String> actualDigests = new ArrayList<String>(Arrays.asList(keyInfo.getDigests())); 810 // Keystore may have added DIGEST_NONE, to allow software digesting. 811 actualDigests.remove(KeyProperties.DIGEST_NONE); 812 TestUtils.assertContentsInAnyOrder( 813 actualDigests, KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512); 814 815 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings())); 816 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings())); 817 assertFalse(keyInfo.isUserAuthenticationRequired()); 818 assertEquals(-1, keyInfo.getUserAuthenticationValidityDurationSeconds()); 819 } 820 821 public void testGenerate_RSA_ModernSpec_AsCustomAsPossible() throws Exception { 822 KeyPairGenerator generator = getRsaGenerator(); 823 Date keyValidityStart = new Date(System.currentTimeMillis()); 824 Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 1000000); 825 Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 10000000); 826 827 Date certNotBefore = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 210); 828 Date certNotAfter = new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 210); 829 BigInteger certSerialNumber = new BigInteger("1234567890"); 830 X500Principal certSubject = new X500Principal("cn=hello2"); 831 generator.initialize(new KeyGenParameterSpec.Builder( 832 TEST_ALIAS_1, 833 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY 834 | KeyProperties.PURPOSE_ENCRYPT) 835 .setAlgorithmParameterSpec( 836 new RSAKeyGenParameterSpec(3072, RSAKeyGenParameterSpec.F0)) 837 .setKeySize(3072) 838 .setDigests(KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512) 839 .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS, 840 KeyProperties.SIGNATURE_PADDING_RSA_PKCS1) 841 .setBlockModes(KeyProperties.BLOCK_MODE_ECB) 842 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP, 843 KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) 844 .setKeyValidityStart(keyValidityStart) 845 .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination) 846 .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption) 847 .setCertificateSerialNumber(certSerialNumber) 848 .setCertificateSubject(certSubject) 849 .setCertificateNotBefore(certNotBefore) 850 .setCertificateNotAfter(certNotAfter) 851 .setUnlockedDeviceRequired(true) 852 .build()); 853 KeyPair keyPair = generator.generateKeyPair(); 854 assertGeneratedKeyPairAndSelfSignedCertificate( 855 keyPair, 856 TEST_ALIAS_1, 857 "RSA", 858 3072, 859 certSubject, 860 certSerialNumber, 861 certNotBefore, 862 certNotAfter); 863 assertEquals(RSAKeyGenParameterSpec.F0, 864 ((RSAPublicKey) keyPair.getPublic()).getPublicExponent()); 865 KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 866 assertEquals(3072, keyInfo.getKeySize()); 867 assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias()); 868 assertOneOf(keyInfo.getOrigin(), 869 KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN); 870 assertEquals( 871 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY 872 | KeyProperties.PURPOSE_ENCRYPT, 873 keyInfo.getPurposes()); 874 assertEquals(keyValidityStart, keyInfo.getKeyValidityStart()); 875 assertEquals(keyValidityEndDateForOrigination, keyInfo.getKeyValidityForOriginationEnd()); 876 assertEquals(keyValidityEndDateForConsumption, keyInfo.getKeyValidityForConsumptionEnd()); 877 878 List<String> actualDigests = 879 new ArrayList<String>(Arrays.asList(keyInfo.getDigests())); 880 // Keystore may have added DIGEST_NONE, to allow software digesting. 881 actualDigests.remove(KeyProperties.DIGEST_NONE); 882 TestUtils.assertContentsInAnyOrder( 883 actualDigests, KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512); 884 885 TestUtils.assertContentsInAnyOrder(Arrays.asList(keyInfo.getSignaturePaddings()), 886 KeyProperties.SIGNATURE_PADDING_RSA_PKCS1, 887 KeyProperties.SIGNATURE_PADDING_RSA_PSS); 888 MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getBlockModes()), 889 KeyProperties.BLOCK_MODE_ECB); 890 891 List<String> actualEncryptionPaddings = 892 new ArrayList<String>(Arrays.asList(keyInfo.getEncryptionPaddings())); 893 // Keystore may have added ENCRYPTION_PADDING_NONE, to allow software padding. 894 actualEncryptionPaddings.remove(KeyProperties.ENCRYPTION_PADDING_NONE); 895 TestUtils.assertContentsInAnyOrder(actualEncryptionPaddings, 896 KeyProperties.ENCRYPTION_PADDING_RSA_OAEP, 897 KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1); 898 899 assertFalse(keyInfo.isUserAuthenticationRequired()); 900 assertEquals(-1, keyInfo.getUserAuthenticationValidityDurationSeconds()); 901 } 902 903 public void testGenerate_EC_ModernSpec_UsableForTLSPeerAuth() throws Exception { 904 KeyPairGenerator generator = getEcGenerator(); 905 generator.initialize(new KeyGenParameterSpec.Builder( 906 TEST_ALIAS_1, 907 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY) 908 .setDigests(KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA384) 909 .build()); 910 KeyPair keyPair = generator.generateKeyPair(); 911 assertGeneratedKeyPairAndSelfSignedCertificate( 912 keyPair, 913 TEST_ALIAS_1, 914 "EC", 915 256, 916 DEFAULT_CERT_SUBJECT, 917 DEFAULT_CERT_SERIAL_NUMBER, 918 DEFAULT_CERT_NOT_BEFORE, 919 DEFAULT_CERT_NOT_AFTER); 920 KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 921 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes())); 922 MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()), 923 KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA384); 924 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings())); 925 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings())); 926 assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1); 927 assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1); 928 } 929 930 public void testGenerate_RSA_ModernSpec_UsableForTLSPeerAuth() throws Exception { 931 KeyPairGenerator generator = getRsaGenerator(); 932 generator.initialize(new KeyGenParameterSpec.Builder( 933 TEST_ALIAS_1, 934 KeyProperties.PURPOSE_SIGN 935 | KeyProperties.PURPOSE_VERIFY 936 | KeyProperties.PURPOSE_DECRYPT) 937 .setDigests(KeyProperties.DIGEST_NONE, 938 KeyProperties.DIGEST_SHA256, 939 KeyProperties.DIGEST_SHA512) 940 .setEncryptionPaddings( 941 KeyProperties.ENCRYPTION_PADDING_NONE, 942 KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) 943 .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1) 944 .build()); 945 KeyPair keyPair = generator.generateKeyPair(); 946 assertGeneratedKeyPairAndSelfSignedCertificate( 947 keyPair, 948 TEST_ALIAS_1, 949 "RSA", 950 2048, 951 DEFAULT_CERT_SUBJECT, 952 DEFAULT_CERT_SERIAL_NUMBER, 953 DEFAULT_CERT_NOT_BEFORE, 954 DEFAULT_CERT_NOT_AFTER); 955 KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 956 MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes())); 957 MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()), 958 KeyProperties.DIGEST_NONE, 959 KeyProperties.DIGEST_SHA256, 960 KeyProperties.DIGEST_SHA512); 961 MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getSignaturePaddings()), 962 KeyProperties.SIGNATURE_PADDING_RSA_PKCS1); 963 MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getEncryptionPaddings()), 964 KeyProperties.ENCRYPTION_PADDING_NONE, 965 KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1); 966 assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1); 967 assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1); 968 } 969 970 // TODO: Test fingerprint-authorized and secure lock screen-authorized keys. These can't 971 // currently be tested here because CTS does not require that secure lock screen is set up and 972 // that at least one fingerprint is enrolled. 973 974 public void testGenerate_EC_ModernSpec_KeyNotYetValid() throws Exception { 975 KeyPairGenerator generator = getEcGenerator(); 976 Date validityStart = new Date(System.currentTimeMillis() + DAY_IN_MILLIS); 977 generator.initialize(new KeyGenParameterSpec.Builder( 978 TEST_ALIAS_1, 979 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY) 980 .setKeySize(256) 981 .setDigests(KeyProperties.DIGEST_SHA256) 982 .setKeyValidityStart(validityStart) 983 .build()); 984 KeyPair keyPair = generator.generateKeyPair(); 985 assertGeneratedKeyPairAndSelfSignedCertificate( 986 keyPair, 987 TEST_ALIAS_1, 988 "EC", 989 256, 990 DEFAULT_CERT_SUBJECT, 991 DEFAULT_CERT_SERIAL_NUMBER, 992 DEFAULT_CERT_NOT_BEFORE, 993 DEFAULT_CERT_NOT_AFTER); 994 KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 995 assertEquals(validityStart, keyInfo.getKeyValidityStart()); 996 } 997 998 public void testGenerate_RSA_ModernSpec_KeyExpiredForOrigination() throws Exception { 999 KeyPairGenerator generator = getRsaGenerator(); 1000 Date originationEnd = new Date(System.currentTimeMillis() - DAY_IN_MILLIS); 1001 generator.initialize(new KeyGenParameterSpec.Builder( 1002 TEST_ALIAS_1, 1003 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY) 1004 .setKeySize(1024) 1005 .setDigests(KeyProperties.DIGEST_SHA256) 1006 .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1) 1007 .setKeyValidityForOriginationEnd(originationEnd) 1008 .build()); 1009 KeyPair keyPair = generator.generateKeyPair(); 1010 assertGeneratedKeyPairAndSelfSignedCertificate( 1011 keyPair, 1012 TEST_ALIAS_1, 1013 "RSA", 1014 1024, 1015 DEFAULT_CERT_SUBJECT, 1016 DEFAULT_CERT_SERIAL_NUMBER, 1017 DEFAULT_CERT_NOT_BEFORE, 1018 DEFAULT_CERT_NOT_AFTER); 1019 KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 1020 assertEquals(originationEnd, keyInfo.getKeyValidityForOriginationEnd()); 1021 } 1022 1023 public void testGenerate_EC_ModernSpec_SupportedSizes() throws Exception { 1024 assertKeyGenUsingECSizeOnlyUsesCorrectCurve(224, ECCurves.NIST_P_224_SPEC); 1025 assertKeyGenUsingECSizeOnlyUsesCorrectCurve(256, ECCurves.NIST_P_256_SPEC); 1026 assertKeyGenUsingECSizeOnlyUsesCorrectCurve(384, ECCurves.NIST_P_384_SPEC); 1027 assertKeyGenUsingECSizeOnlyUsesCorrectCurve(521, ECCurves.NIST_P_521_SPEC); 1028 } 1029 1030 public void testGenerate_EC_ModernSpec_UnsupportedSizesRejected() throws Exception { 1031 for (int keySizeBits = 0; keySizeBits <= 1024; keySizeBits++) { 1032 if ((keySizeBits == 224) || (keySizeBits == 256) || (keySizeBits == 384) 1033 || (keySizeBits == 521)) { 1034 // Skip supported sizes 1035 continue; 1036 } 1037 KeyPairGenerator generator = getEcGenerator(); 1038 1039 try { 1040 generator.initialize(new KeyGenParameterSpec.Builder( 1041 TEST_ALIAS_1, 1042 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY) 1043 .setKeySize(keySizeBits) 1044 .build()); 1045 fail("EC KeyPairGenerator initialized with unsupported key size: " 1046 + keySizeBits + " bits"); 1047 } catch (InvalidAlgorithmParameterException expected) { 1048 } 1049 } 1050 } 1051 1052 public void testGenerate_EC_ModernSpec_SupportedNamedCurves() throws Exception { 1053 assertKeyGenUsingECNamedCurveSupported("P-224", ECCurves.NIST_P_224_SPEC); 1054 assertKeyGenUsingECNamedCurveSupported("p-224", ECCurves.NIST_P_224_SPEC); 1055 assertKeyGenUsingECNamedCurveSupported("secp224r1", ECCurves.NIST_P_224_SPEC); 1056 assertKeyGenUsingECNamedCurveSupported("SECP224R1", ECCurves.NIST_P_224_SPEC); 1057 1058 assertKeyGenUsingECNamedCurveSupported("P-256", ECCurves.NIST_P_256_SPEC); 1059 assertKeyGenUsingECNamedCurveSupported("p-256", ECCurves.NIST_P_256_SPEC); 1060 assertKeyGenUsingECNamedCurveSupported("secp256r1", ECCurves.NIST_P_256_SPEC); 1061 assertKeyGenUsingECNamedCurveSupported("SECP256R1", ECCurves.NIST_P_256_SPEC); 1062 assertKeyGenUsingECNamedCurveSupported("prime256v1", ECCurves.NIST_P_256_SPEC); 1063 assertKeyGenUsingECNamedCurveSupported("PRIME256V1", ECCurves.NIST_P_256_SPEC); 1064 1065 assertKeyGenUsingECNamedCurveSupported("P-384", ECCurves.NIST_P_384_SPEC); 1066 assertKeyGenUsingECNamedCurveSupported("p-384", ECCurves.NIST_P_384_SPEC); 1067 assertKeyGenUsingECNamedCurveSupported("secp384r1", ECCurves.NIST_P_384_SPEC); 1068 assertKeyGenUsingECNamedCurveSupported("SECP384R1", ECCurves.NIST_P_384_SPEC); 1069 1070 assertKeyGenUsingECNamedCurveSupported("P-521", ECCurves.NIST_P_521_SPEC); 1071 assertKeyGenUsingECNamedCurveSupported("p-521", ECCurves.NIST_P_521_SPEC); 1072 assertKeyGenUsingECNamedCurveSupported("secp521r1", ECCurves.NIST_P_521_SPEC); 1073 assertKeyGenUsingECNamedCurveSupported("SECP521R1", ECCurves.NIST_P_521_SPEC); 1074 } 1075 1076 public void testGenerate_RSA_ModernSpec_SupportedSizes() throws Exception { 1077 assertKeyGenUsingRSASizeOnlySupported(512); 1078 assertKeyGenUsingRSASizeOnlySupported(768); 1079 assertKeyGenUsingRSASizeOnlySupported(1024); 1080 assertKeyGenUsingRSASizeOnlySupported(2048); 1081 assertKeyGenUsingRSASizeOnlySupported(3072); 1082 assertKeyGenUsingRSASizeOnlySupported(4096); 1083 1084 // The above use F4. Check that F0 is supported as well, just in case somebody is crazy 1085 // enough. 1086 assertKeyGenUsingRSAKeyGenParameterSpecSupported(new RSAKeyGenParameterSpec( 1087 2048, RSAKeyGenParameterSpec.F0)); 1088 } 1089 1090 public void testGenerate_RSA_IndCpaEnforced() throws Exception { 1091 KeyGenParameterSpec.Builder goodBuilder = new KeyGenParameterSpec.Builder( 1092 TEST_ALIAS_1, KeyProperties.PURPOSE_ENCRYPT) 1093 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP, 1094 KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1); 1095 assertKeyGenInitSucceeds("RSA", goodBuilder.build()); 1096 1097 // Should be fine because IND-CPA restriction applies only to encryption keys 1098 assertKeyGenInitSucceeds("RSA", 1099 TestUtils.buildUpon(goodBuilder, KeyProperties.PURPOSE_DECRYPT) 1100 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) 1101 .build()); 1102 1103 assertKeyGenInitThrowsInvalidAlgorithmParameterException("RSA", 1104 TestUtils.buildUpon(goodBuilder) 1105 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) 1106 .build()); 1107 1108 assertKeyGenInitSucceeds("RSA", 1109 TestUtils.buildUpon(goodBuilder) 1110 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) 1111 .setRandomizedEncryptionRequired(false) 1112 .build()); 1113 1114 // Should fail because PKCS#7 padding doesn't work with RSA 1115 assertKeyGenInitThrowsInvalidAlgorithmParameterException("RSA", 1116 TestUtils.buildUpon(goodBuilder) 1117 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7) 1118 .build()); 1119 } 1120 1121 public void testGenerate_EC_IndCpaEnforced() throws Exception { 1122 KeyGenParameterSpec.Builder goodBuilder = new KeyGenParameterSpec.Builder( 1123 TEST_ALIAS_2, KeyProperties.PURPOSE_ENCRYPT); 1124 assertKeyGenInitSucceeds("EC", goodBuilder.build()); 1125 1126 // Should be fine because IND-CPA restriction applies only to encryption keys 1127 assertKeyGenInitSucceeds("EC", 1128 TestUtils.buildUpon(goodBuilder, KeyProperties.PURPOSE_DECRYPT) 1129 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) 1130 .build()); 1131 1132 assertKeyGenInitThrowsInvalidAlgorithmParameterException("EC", 1133 TestUtils.buildUpon(goodBuilder) 1134 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) 1135 .build()); 1136 1137 assertKeyGenInitSucceeds("EC", 1138 TestUtils.buildUpon(goodBuilder) 1139 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) 1140 .setRandomizedEncryptionRequired(false) 1141 .build()); 1142 } 1143 1144 // http://b/28384942 1145 public void testGenerateWithFarsiLocale() throws Exception { 1146 Locale defaultLocale = Locale.getDefault(); 1147 // Note that we use farsi here because its number formatter doesn't use 1148 // arabic digits. 1149 Locale fa_IR = Locale.forLanguageTag("fa-IR"); 1150 DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(fa_IR); 1151 assertFalse('0' == dfs.getZeroDigit()); 1152 1153 Locale.setDefault(fa_IR); 1154 try { 1155 KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance( 1156 KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore"); 1157 1158 keyGenerator.initialize(new KeyGenParameterSpec.Builder( 1159 TEST_ALIAS_1, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) 1160 .setBlockModes(KeyProperties.BLOCK_MODE_ECB) 1161 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) 1162 .build()); 1163 1164 keyGenerator.generateKeyPair(); 1165 } finally { 1166 Locale.setDefault(defaultLocale); 1167 } 1168 } 1169 1170 private void assertKeyGenInitSucceeds(String algorithm, AlgorithmParameterSpec params) 1171 throws Exception { 1172 KeyPairGenerator generator = getGenerator(algorithm); 1173 generator.initialize(params); 1174 } 1175 1176 private void assertKeyGenInitThrowsInvalidAlgorithmParameterException( 1177 String algorithm, AlgorithmParameterSpec params) throws Exception { 1178 KeyPairGenerator generator = getGenerator(algorithm); 1179 try { 1180 generator.initialize(params); 1181 fail(); 1182 } catch (InvalidAlgorithmParameterException expected) {} 1183 } 1184 1185 private void assertKeyGenUsingECSizeOnlyUsesCorrectCurve( 1186 int keySizeBits, ECParameterSpec expectedParams) throws Exception { 1187 KeyPairGenerator generator = getEcGenerator(); 1188 generator.initialize(new KeyGenParameterSpec.Builder( 1189 TEST_ALIAS_1, 1190 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY) 1191 .setKeySize(keySizeBits) 1192 .build(), 1193 mRng); 1194 mRng.resetCounters(); 1195 KeyPair keyPair = generator.generateKeyPair(); 1196 long consumedEntropyAmountBytes = mRng.getOutputSizeBytes(); 1197 int expectedKeySize = expectedParams.getCurve().getField().getFieldSize(); 1198 assertGeneratedKeyPairAndSelfSignedCertificate( 1199 keyPair, 1200 TEST_ALIAS_1, 1201 "EC", 1202 expectedKeySize, 1203 DEFAULT_CERT_SUBJECT, 1204 DEFAULT_CERT_SERIAL_NUMBER, 1205 DEFAULT_CERT_NOT_BEFORE, 1206 DEFAULT_CERT_NOT_AFTER); 1207 KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 1208 assertEquals(expectedKeySize, keyInfo.getKeySize()); 1209 TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent( 1210 expectedParams, 1211 ((ECKey) keyPair.getPublic()).getParams()); 1212 assertEquals(((keySizeBits + 7) / 8) * 8, consumedEntropyAmountBytes * 8); 1213 } 1214 1215 private void assertKeyGenUsingECNamedCurveSupported( 1216 String curveName, ECParameterSpec expectedParams) throws Exception { 1217 KeyPairGenerator generator = getEcGenerator(); 1218 generator.initialize(new KeyGenParameterSpec.Builder( 1219 TEST_ALIAS_1, 1220 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY) 1221 .setAlgorithmParameterSpec(new ECGenParameterSpec(curveName)) 1222 .build(), 1223 mRng); 1224 mRng.resetCounters(); 1225 KeyPair keyPair = generator.generateKeyPair(); 1226 long consumedEntropyAmountBytes = mRng.getOutputSizeBytes(); 1227 int expectedKeySize = expectedParams.getCurve().getField().getFieldSize(); 1228 assertGeneratedKeyPairAndSelfSignedCertificate( 1229 keyPair, 1230 TEST_ALIAS_1, 1231 "EC", 1232 expectedKeySize, 1233 DEFAULT_CERT_SUBJECT, 1234 DEFAULT_CERT_SERIAL_NUMBER, 1235 DEFAULT_CERT_NOT_BEFORE, 1236 DEFAULT_CERT_NOT_AFTER); 1237 KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 1238 assertEquals(expectedKeySize, keyInfo.getKeySize()); 1239 TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent( 1240 expectedParams, 1241 ((ECKey) keyPair.getPublic()).getParams()); 1242 assertEquals(((expectedKeySize + 7) / 8) * 8, consumedEntropyAmountBytes * 8); 1243 } 1244 1245 private void assertKeyGenUsingRSASizeOnlySupported(int keySizeBits) throws Exception { 1246 KeyPairGenerator generator = getRsaGenerator(); 1247 generator.initialize(new KeyGenParameterSpec.Builder( 1248 TEST_ALIAS_1, 1249 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY) 1250 .setKeySize(keySizeBits) 1251 .build(), 1252 mRng); 1253 mRng.resetCounters(); 1254 KeyPair keyPair = generator.generateKeyPair(); 1255 long consumedEntropyAmountBytes = mRng.getOutputSizeBytes(); 1256 assertGeneratedKeyPairAndSelfSignedCertificate( 1257 keyPair, 1258 TEST_ALIAS_1, 1259 "RSA", 1260 keySizeBits, 1261 DEFAULT_CERT_SUBJECT, 1262 DEFAULT_CERT_SERIAL_NUMBER, 1263 DEFAULT_CERT_NOT_BEFORE, 1264 DEFAULT_CERT_NOT_AFTER); 1265 KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 1266 assertEquals(keySizeBits, keyInfo.getKeySize()); 1267 assertEquals(((keySizeBits + 7) / 8) * 8, consumedEntropyAmountBytes * 8); 1268 } 1269 1270 private void assertKeyGenUsingRSAKeyGenParameterSpecSupported( 1271 RSAKeyGenParameterSpec spec) throws Exception { 1272 KeyPairGenerator generator = getRsaGenerator(); 1273 generator.initialize(new KeyGenParameterSpec.Builder( 1274 TEST_ALIAS_1, 1275 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY) 1276 .setAlgorithmParameterSpec(spec) 1277 .build(), 1278 mRng); 1279 mRng.resetCounters(); 1280 KeyPair keyPair = generator.generateKeyPair(); 1281 long consumedEntropyAmountBytes = mRng.getOutputSizeBytes(); 1282 assertGeneratedKeyPairAndSelfSignedCertificate( 1283 keyPair, 1284 TEST_ALIAS_1, 1285 "RSA", 1286 spec.getKeysize(), 1287 DEFAULT_CERT_SUBJECT, 1288 DEFAULT_CERT_SERIAL_NUMBER, 1289 DEFAULT_CERT_NOT_BEFORE, 1290 DEFAULT_CERT_NOT_AFTER); 1291 assertEquals(spec.getPublicExponent(), 1292 ((RSAPublicKey) keyPair.getPublic()).getPublicExponent()); 1293 KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate()); 1294 assertEquals(spec.getKeysize(), keyInfo.getKeySize()); 1295 assertEquals(((spec.getKeysize() + 7) / 8) * 8, consumedEntropyAmountBytes * 8); 1296 } 1297 1298 private static void assertSelfSignedCertificateSignatureVerifies(Certificate certificate) { 1299 try { 1300 certificate.verify(certificate.getPublicKey()); 1301 } catch (Exception e) { 1302 throw new RuntimeException("Failed to verify self-signed certificate signature", e); 1303 } 1304 } 1305 1306 private void assertGeneratedKeyPairAndSelfSignedCertificate( 1307 KeyPair keyPair, String alias, 1308 String expectedKeyAlgorithm, 1309 int expectedKeySize, 1310 X500Principal expectedCertSubject, 1311 BigInteger expectedCertSerialNumber, 1312 Date expectedCertNotBefore, 1313 Date expectedCertNotAfter) 1314 throws Exception { 1315 assertNotNull(keyPair); 1316 TestUtils.assertKeyPairSelfConsistent(keyPair); 1317 TestUtils.assertKeySize(expectedKeySize, keyPair); 1318 assertEquals(expectedKeyAlgorithm, keyPair.getPublic().getAlgorithm()); 1319 TestUtils.assertKeyStoreKeyPair(mKeyStore, alias, keyPair); 1320 1321 X509Certificate cert = (X509Certificate) mKeyStore.getCertificate(alias); 1322 assertEquals(keyPair.getPublic(), cert.getPublicKey()); 1323 assertX509CertificateParameters(cert, 1324 expectedCertSubject, 1325 expectedCertSerialNumber, 1326 expectedCertNotBefore, 1327 expectedCertNotAfter); 1328 // Assert that the certificate chain consists only of the above certificate 1329 MoreAsserts.assertContentsInOrder( 1330 Arrays.asList(mKeyStore.getCertificateChain(alias)), cert); 1331 } 1332 1333 private void assertSelfSignedCertificateSignatureVerifies(String alias) throws Exception { 1334 assertSelfSignedCertificateSignatureVerifies(mKeyStore.getCertificate(alias)); 1335 } 1336 1337 private void assertKeyPairAndCertificateUsableForTLSPeerAuthentication(String alias) 1338 throws Exception { 1339 assertUsableForTLSPeerAuthentication( 1340 (PrivateKey) mKeyStore.getKey(alias, null), 1341 mKeyStore.getCertificateChain(alias)); 1342 } 1343 1344 private static void assertX509CertificateParameters( 1345 X509Certificate actualCert, 1346 X500Principal expectedSubject, BigInteger expectedSerialNumber, 1347 Date expectedNotBefore, Date expectedNotAfter) { 1348 assertEquals(expectedSubject, actualCert.getSubjectDN()); 1349 assertEquals(expectedSubject, actualCert.getIssuerDN()); 1350 assertEquals(expectedSerialNumber, actualCert.getSerialNumber()); 1351 assertDateEquals(expectedNotBefore, actualCert.getNotBefore()); 1352 assertDateEquals(expectedNotAfter, actualCert.getNotAfter()); 1353 } 1354 1355 private static void assertUsableForTLSPeerAuthentication( 1356 PrivateKey privateKey, 1357 Certificate[] certificateChain) throws Exception { 1358 // Set up both client and server to use the same private key + cert, and to trust that cert 1359 // when it's presented by peer. This exercises the use of the private key both in client 1360 // and server scenarios. 1361 X509Certificate[] x509CertificateChain = new X509Certificate[certificateChain.length]; 1362 for (int i = 0; i < certificateChain.length; i++) { 1363 x509CertificateChain[i] = (X509Certificate) certificateChain[i]; 1364 } 1365 TestKeyStore serverKeyStore = TestKeyStore.getServer(); 1366 // Make the peer trust the root certificate in the chain. As opposed to making the peer 1367 // trust the leaf certificate, this will ensure that the whole chain verifies. 1368 serverKeyStore.keyStore.setCertificateEntry( 1369 "trusted", certificateChain[certificateChain.length - 1]); 1370 SSLContext serverContext = TestSSLContext.createSSLContext("TLS", 1371 new KeyManager[] { 1372 TestKeyManager.wrap(new MyKeyManager(privateKey, x509CertificateChain)) 1373 }, 1374 TestKeyStore.createTrustManagers(serverKeyStore.keyStore)); 1375 SSLContext clientContext = serverContext; 1376 1377 if ("EC".equalsIgnoreCase(privateKey.getAlgorithm())) { 1378 // As opposed to RSA (see below) EC keys are used in the same way in all cipher suites. 1379 // Assert that the key works with the default list of cipher suites. 1380 assertSSLConnectionWithClientAuth( 1381 clientContext, serverContext, null, x509CertificateChain, x509CertificateChain); 1382 } else if ("RSA".equalsIgnoreCase(privateKey.getAlgorithm())) { 1383 // RSA keys are used differently between Forward Secure and non-Forward Secure cipher 1384 // suites. For example, RSA key exchange requires the server to decrypt using its RSA 1385 // private key, whereas ECDHE_RSA key exchange requires the server to sign usnig its 1386 // RSA private key. We thus assert that the key works with Forward Secure cipher suites 1387 // and that it works with non-Forward Secure cipher suites. 1388 List<String> fsCipherSuites = new ArrayList<String>(); 1389 List<String> nonFsCipherSuites = new ArrayList<String>(); 1390 for (String cipherSuite : clientContext.getDefaultSSLParameters().getCipherSuites()) { 1391 if (cipherSuite.contains("_ECDHE_RSA_") || cipherSuite.contains("_DHE_RSA_")) { 1392 fsCipherSuites.add(cipherSuite); 1393 } else if (cipherSuite.contains("_RSA_WITH_")) { 1394 nonFsCipherSuites.add(cipherSuite); 1395 } 1396 } 1397 assertFalse("No FS RSA cipher suites enabled by default", fsCipherSuites.isEmpty()); 1398 assertFalse("No non-FS RSA cipher suites enabled", nonFsCipherSuites.isEmpty()); 1399 1400 // Assert that the key works with RSA Forward Secure cipher suites. 1401 assertSSLConnectionWithClientAuth( 1402 clientContext, serverContext, fsCipherSuites.toArray(new String[0]), 1403 x509CertificateChain, x509CertificateChain); 1404 // Assert that the key works with RSA non-Forward Secure cipher suites. 1405 assertSSLConnectionWithClientAuth( 1406 clientContext, serverContext, nonFsCipherSuites.toArray(new String[0]), 1407 x509CertificateChain, x509CertificateChain); 1408 } else { 1409 fail("Unsupported key algorithm: " + privateKey.getAlgorithm()); 1410 } 1411 } 1412 1413 private static void assertSSLConnectionWithClientAuth( 1414 SSLContext clientContext, SSLContext serverContext, String[] enabledCipherSuites, 1415 X509Certificate[] expectedClientCertChain, X509Certificate[] expectedServerCertChain) 1416 throws Exception { 1417 SSLServerSocket serverSocket = (SSLServerSocket) serverContext.getServerSocketFactory() 1418 .createServerSocket(0); 1419 InetAddress host = InetAddress.getLocalHost(); 1420 int port = serverSocket.getLocalPort(); 1421 SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(host, port); 1422 1423 final SSLSocket server = (SSLSocket) serverSocket.accept(); 1424 ExecutorService executor = Executors.newSingleThreadExecutor(); 1425 Future<Certificate[]> future = executor.submit(new Callable<Certificate[]>() { 1426 @Override 1427 public Certificate[] call() throws Exception { 1428 server.setNeedClientAuth(true); 1429 server.setWantClientAuth(true); 1430 server.startHandshake(); 1431 return server.getSession().getPeerCertificates(); 1432 } 1433 }); 1434 executor.shutdown(); 1435 if (enabledCipherSuites != null) { 1436 client.setEnabledCipherSuites(enabledCipherSuites); 1437 } 1438 client.startHandshake(); 1439 Certificate[] usedServerCerts = client.getSession().getPeerCertificates(); 1440 Certificate[] usedClientCerts = future.get(); 1441 client.close(); 1442 server.close(); 1443 1444 assertNotNull(usedServerCerts); 1445 assertEquals(Arrays.asList(expectedServerCertChain), Arrays.asList(usedServerCerts)); 1446 1447 assertNotNull(usedClientCerts); 1448 assertEquals(Arrays.asList(expectedClientCertChain), Arrays.asList(usedClientCerts)); 1449 } 1450 1451 private static class MyKeyManager extends X509ExtendedKeyManager { 1452 private final PrivateKey key; 1453 private final X509Certificate[] chain; 1454 1455 public MyKeyManager(PrivateKey key, X509Certificate[] certChain) { 1456 this.key = key; 1457 this.chain = certChain; 1458 } 1459 1460 @Override 1461 public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { 1462 return "fake"; 1463 } 1464 1465 @Override 1466 public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { 1467 return "fake"; 1468 } 1469 1470 @Override 1471 public X509Certificate[] getCertificateChain(String alias) { 1472 return chain; 1473 } 1474 1475 @Override 1476 public String[] getClientAliases(String keyType, Principal[] issuers) { 1477 return new String[] { "fake" }; 1478 } 1479 1480 @Override 1481 public String[] getServerAliases(String keyType, Principal[] issuers) { 1482 return new String[] { "fake" }; 1483 } 1484 1485 @Override 1486 public PrivateKey getPrivateKey(String alias) { 1487 return key; 1488 } 1489 } 1490 1491 1492 private static void assertDateEquals(Date date1, Date date2) { 1493 assertDateEquals(null, date1, date2); 1494 } 1495 1496 private static void assertDateEquals(String message, Date date1, Date date2) { 1497 SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss"); 1498 1499 String result1 = formatter.format(date1); 1500 String result2 = formatter.format(date2); 1501 1502 assertEquals(message, result1, result2); 1503 } 1504 1505 private KeyPairGenerator getRsaGenerator() 1506 throws NoSuchAlgorithmException, NoSuchProviderException { 1507 return getGenerator("RSA"); 1508 } 1509 1510 private KeyPairGenerator getEcGenerator() 1511 throws NoSuchAlgorithmException, NoSuchProviderException { 1512 return getGenerator("EC"); 1513 } 1514 1515 private KeyPairGenerator getGenerator(String algorithm) 1516 throws NoSuchAlgorithmException, NoSuchProviderException { 1517 return KeyPairGenerator.getInstance(algorithm, "AndroidKeyStore"); 1518 } 1519 1520 private static void assertOneOf(int actual, int... expected) { 1521 assertOneOf(null, actual, expected); 1522 } 1523 1524 private static void assertOneOf(String message, int actual, int... expected) { 1525 for (int expectedValue : expected) { 1526 if (actual == expectedValue) { 1527 return; 1528 } 1529 } 1530 fail(((message != null) ? message + ". " : "") 1531 + "Expected one of " + Arrays.asList(expected) 1532 + ", actual: <" + actual + ">"); 1533 } 1534 1535 private KeyGenParameterSpec.Builder getWorkingSpec() { 1536 return getWorkingSpec(0); 1537 } 1538 1539 private KeyGenParameterSpec.Builder getWorkingSpec(int purposes) { 1540 return new KeyGenParameterSpec.Builder(TEST_ALIAS_1, purposes); 1541 } 1542 } 1543