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