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