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