1 package org.bouncycastle.test.est; 2 3 4 import java.io.ByteArrayOutputStream; 5 import java.io.PrintWriter; 6 import java.net.SocketException; 7 import java.security.KeyPair; 8 import java.security.KeyPairGenerator; 9 import java.security.KeyStore; 10 import java.security.PrivateKey; 11 import java.security.Provider; 12 import java.security.SecureRandom; 13 import java.security.Security; 14 import java.security.cert.Certificate; 15 import java.security.cert.TrustAnchor; 16 import java.security.cert.X509Certificate; 17 import java.security.spec.ECGenParameterSpec; 18 import java.util.ArrayList; 19 import java.util.Iterator; 20 import java.util.concurrent.TimeUnit; 21 22 import javax.crypto.Cipher; 23 import javax.crypto.spec.GCMParameterSpec; 24 import javax.crypto.spec.SecretKeySpec; 25 import javax.net.ssl.KeyManagerFactory; 26 import javax.net.ssl.SSLHandshakeException; 27 28 import junit.framework.TestCase; 29 import org.bouncycastle.asn1.ASN1EncodableVector; 30 import org.bouncycastle.asn1.x500.X500Name; 31 import org.bouncycastle.asn1.x500.X500NameBuilder; 32 import org.bouncycastle.asn1.x500.style.BCStyle; 33 import org.bouncycastle.asn1.x509.KeyPurposeId; 34 import org.bouncycastle.asn1.x509.KeyUsage; 35 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 36 import org.bouncycastle.cert.X509CertificateHolder; 37 import org.bouncycastle.est.ESTException; 38 import org.bouncycastle.est.ESTService; 39 import org.bouncycastle.est.EnrollmentResponse; 40 import org.bouncycastle.est.HttpAuth; 41 import org.bouncycastle.est.jcajce.ChannelBindingProvider; 42 import org.bouncycastle.est.jcajce.JcaHttpAuthBuilder; 43 import org.bouncycastle.est.jcajce.JcaJceUtils; 44 import org.bouncycastle.est.jcajce.JsseESTServiceBuilder; 45 import org.bouncycastle.jce.provider.BouncyCastleProvider; 46 import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider; 47 import org.bouncycastle.operator.ContentSigner; 48 import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; 49 import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; 50 import org.bouncycastle.pkcs.PKCS10CertificationRequest; 51 import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; 52 import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; 53 import org.bouncycastle.util.test.SimpleTest; 54 import org.junit.Assert; 55 import org.junit.Test; 56 57 public class TestEnroll 58 extends SimpleTest 59 { 60 getName()61 public String getName() 62 { 63 return "TestEnroll"; 64 } 65 performTest()66 public void performTest() 67 throws Exception 68 { 69 ESTTestUtils.runJUnit(TestEnroll.class); 70 } 71 72 73 // Start a server instance that uses basic auth. 74 // But disables the POP validation. startDefaultServerTLSAndBasicAuth(int delay, boolean popOn)75 private ESTServerUtils.ServerInstance startDefaultServerTLSAndBasicAuth(int delay, boolean popOn) 76 throws Exception 77 { 78 final ESTServerUtils.EstServerConfig config = new ESTServerUtils.EstServerConfig(); 79 config.serverCertPemFile = ESTServerUtils.makeRelativeToServerHome("estCA/private/estservercertandkey.pem").getCanonicalPath(); 80 config.serverKeyPemFile = ESTServerUtils.makeRelativeToServerHome("estCA/private/estservercertandkey.pem").getCanonicalPath(); 81 config.realm = "estreal"; 82 config.verbose = true; 83 config.tcpPort = 8443; 84 config.useBasicAuth = true; 85 config.useDigestAuth = false; 86 config.estTRUSTEDCerts = ESTServerUtils.makeRelativeToServerHome("trustedcerts.crt").getCanonicalPath(); 87 config.estCACERTSResp = ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt").getCanonicalPath(); 88 config.disableHTTPAuth = false; 89 config.enableCheckPOPtoTLSUID = popOn; 90 config.manualEnroll = delay; 91 92 93 // 94 // Read in openssl config, and adjust it with the correct path. 95 // 96 97 String cnf = ESTTestUtils.readToString(ESTServerUtils.makeRelativeToServerHome("/estExampleCA.cnf")); 98 cnf = cnf.replace("= ./estCA", "= " + ESTServerUtils.makeRelativeToServerHome("/estCA").getCanonicalPath()); 99 config.openSSLConfigFile = cnf; 100 101 return ESTServerUtils.startServer(config); 102 103 } 104 startDefaultServerTLSAndBasicAuthSpecial(int delay, boolean popOn)105 private ESTServerUtils.ServerInstance startDefaultServerTLSAndBasicAuthSpecial(int delay, boolean popOn) 106 throws Exception 107 { 108 final ESTServerUtils.EstServerConfig config = new ESTServerUtils.EstServerConfig(); 109 config.serverCertPemFile = ESTServerUtils.makeRelativeToServerHome("keyusage/estservercertandkey.pem").getCanonicalPath(); 110 config.serverKeyPemFile = ESTServerUtils.makeRelativeToServerHome("keyusage/estservercertandkey.pem").getCanonicalPath(); 111 config.realm = "estreal"; 112 config.verbose = true; 113 config.tcpPort = 8443; 114 config.useBasicAuth = true; 115 config.useDigestAuth = false; 116 config.estTRUSTEDCerts = ESTServerUtils.makeRelativeToServerHome("keyusage/trustedcerts.crt").getCanonicalPath(); 117 config.estCACERTSResp = ESTServerUtils.makeRelativeToServerHome("keyusage/bc_cacert.crt").getCanonicalPath(); 118 config.disableHTTPAuth = false; 119 config.enableCheckPOPtoTLSUID = popOn; 120 config.manualEnroll = delay; 121 122 123 // 124 // Read in openssl config, and adjust it with the correct path. 125 // 126 127 String cnf = ESTTestUtils.readToString(ESTServerUtils.makeRelativeToServerHome("/estExampleCA.cnf")); 128 cnf = cnf.replace("= ./estCA", "= " + ESTServerUtils.makeRelativeToServerHome("/estCA").getCanonicalPath()); 129 config.openSSLConfigFile = cnf; 130 131 return ESTServerUtils.startServer(config); 132 133 } 134 135 136 /* 137 private ESTServerUtils.ServerInstance startSpecialServer() 138 throws Exception 139 { 140 141 final ESTServerUtils.EstServerConfig config = new ESTServerUtils.EstServerConfig(); 142 config.serverCertPemFile = ESTServerUtils.makeRelativeToServerHome("keyusage/estservercertandkey.pem").getCanonicalPath(); 143 config.serverKeyPemFile = ESTServerUtils.makeRelativeToServerHome("keyusage/estservercertandkey.pem").getCanonicalPath(); 144 config.realm = "estreal"; 145 config.verbose = true; 146 config.tcpPort = 8443; 147 config.useBasicAuth = true; 148 config.estTRUSTEDCerts = ESTServerUtils.makeRelativeToServerHome("keyusage/trustedcerts.crt").getCanonicalPath(); 149 config.estCACERTSResp = ESTServerUtils.makeRelativeToServerHome("keyusage/bc_cacert.crt").getCanonicalPath(); 150 151 return ESTServerUtils.startServer(config); 152 153 } 154 155 */ 156 157 158 159 160 /** 161 * Test enrollment with digest auth. 162 * <p> 163 * NB: The digest as of 2016-Feb-03 is hard coded in the server. 164 * 165 * @return 166 * @throws Exception 167 */ startDefaultServerWithDigestAuth()168 private ESTServerUtils.ServerInstance startDefaultServerWithDigestAuth() 169 throws Exception 170 { 171 172 final ESTServerUtils.EstServerConfig config = new ESTServerUtils.EstServerConfig(); 173 config.serverCertPemFile = ESTServerUtils.makeRelativeToServerHome("estCA/private/estservercertandkey.pem").getCanonicalPath(); 174 config.serverKeyPemFile = ESTServerUtils.makeRelativeToServerHome("estCA/private/estservercertandkey.pem").getCanonicalPath(); 175 config.realm = "estrealm"; 176 config.verbose = true; 177 config.tcpPort = 8443; 178 config.useBasicAuth = false; 179 config.useDigestAuth = true; 180 config.estTRUSTEDCerts = ESTServerUtils.makeRelativeToServerHome("trustedcerts.crt").getCanonicalPath(); 181 config.estCACERTSResp = ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt").getCanonicalPath(); 182 183 // 184 // Read in openssl config, and adjust it with the correct path. 185 // 186 187 String cnf = ESTTestUtils.readToString(ESTServerUtils.makeRelativeToServerHome("/estExampleCA.cnf")); 188 cnf = cnf.replace("= ./estCA", "= " + ESTServerUtils.makeRelativeToServerHome("/estCA").getCanonicalPath()); 189 config.openSSLConfigFile = cnf; 190 191 return ESTServerUtils.startServer(config); 192 193 } 194 195 196 @Test testEnrollUsingBasicAuth()197 public void testEnrollUsingBasicAuth() 198 throws Exception 199 { 200 ESTTestUtils.ensureProvider(); 201 X509CertificateHolder[] theirCAs = null; 202 ESTServerUtils.ServerInstance serverInstance = null; 203 204 try 205 { 206 serverInstance = startDefaultServerTLSAndBasicAuth(0, false); 207 208 209 ESTService est = new JsseESTServiceBuilder( 210 "localhost:8443", JcaJceUtils.getCertPathTrustManager( 211 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificates( 212 ESTServerUtils.makeRelativeToServerHome("/estCA/multicacerts.crt") 213 )) , null) 214 ).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS").build(); 215 216 217 // 218 // Make certificate request. 219 // 220 221 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 222 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 223 kpg.initialize(ecGenSpec, new SecureRandom()); 224 KeyPair enrollmentPair = kpg.generateKeyPair(); 225 226 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 227 new X500Name("CN=Test"), 228 enrollmentPair.getPublic()); 229 230 PKCS10CertificationRequest csr = pkcs10Builder.build( 231 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 232 233 EnrollmentResponse enr = est.simpleEnroll(false, csr, 234 new JcaHttpAuthBuilder("estreal", "estuser", "estpwd".toCharArray()) 235 .setNonceGenerator(new SecureRandom()).setProvider("BC").build()); 236 X509Certificate expectedCA = ESTTestUtils.toJavaX509Certificate(ESTTestUtils.readPemCertificate( 237 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 238 )); 239 240 X509CertificateHolder enrolledAsHolder = ESTService.storeToArray(enr.getStore())[0]; 241 242 X509Certificate enrolled = ESTTestUtils.toJavaX509Certificate(enrolledAsHolder); 243 244 // Will fail if it does not verify. 245 enrolled.verify(expectedCA.getPublicKey(), "BC"); 246 247 TestCase.assertEquals(enrolledAsHolder.getSubject(), csr.getSubject()); 248 TestCase.assertEquals(enrolledAsHolder.getSubjectPublicKeyInfo(), csr.getSubjectPublicKeyInfo()); 249 250 } 251 finally 252 { 253 if (serverInstance != null) 254 { 255 serverInstance.getServer().stop_server(); 256 } 257 } 258 } 259 260 261 @Test testEnrollUsingBasicAuthWithDelay()262 public void testEnrollUsingBasicAuthWithDelay() 263 throws Exception 264 { 265 ESTTestUtils.ensureProvider(); 266 X509CertificateHolder[] theirCAs = null; 267 ESTServerUtils.ServerInstance serverInstance = null; 268 269 try 270 { 271 serverInstance = startDefaultServerTLSAndBasicAuth(5, false); 272 273 ESTService est = new JsseESTServiceBuilder( 274 "localhost:8443", JcaJceUtils.getCertPathTrustManager( 275 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 276 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 277 )), null) 278 ).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS").build(); 279 280 // 281 // Make certificate request. 282 // 283 284 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 285 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 286 kpg.initialize(ecGenSpec, new SecureRandom()); 287 KeyPair enrollmentPair = kpg.generateKeyPair(); 288 289 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 290 new X500Name("CN=Test"), 291 enrollmentPair.getPublic()); 292 293 PKCS10CertificationRequest csr = pkcs10Builder.build( 294 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 295 296 EnrollmentResponse enr = est.simpleEnroll(false, csr, new HttpAuth("estreal", "estuser", "estpwd".toCharArray(), new SecureRandom(), new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())); 297 298 299 Assert.assertFalse("Can Retry is true.", enr.canRetry()); 300 Assert.assertNull("Store is null", enr.getStore()); 301 Assert.assertFalse("Must not be completed:?", enr.isCompleted()); 302 303 System.out.println(enr.getNotBefore() - System.currentTimeMillis()); 304 Assert.assertTrue("Future time reasonable?", enr.getNotBefore() - System.currentTimeMillis() > 2000); 305 306 int max = 100; 307 while (!enr.canRetry() && --max > 0) 308 { 309 Thread.sleep(500); 310 } 311 Assert.assertTrue("Wait looped out.", max > 0); 312 313 Assert.assertTrue("Can we retry?", enr.canRetry()); 314 315 316 EnrollmentResponse entTriedAgain = est.simpleEnroll(enr); 317 318 Assert.assertTrue("Must be completed:?", entTriedAgain.isCompleted()); 319 320 X509Certificate expectedCA = ESTTestUtils.toJavaX509Certificate(ESTTestUtils.readPemCertificate( 321 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 322 )); 323 324 X509CertificateHolder enrolledAsHolder = ESTService.storeToArray(entTriedAgain.getStore())[0]; 325 326 X509Certificate enrolled = ESTTestUtils.toJavaX509Certificate(enrolledAsHolder); 327 328 // Will fail if it does not verify. 329 enrolled.verify(expectedCA.getPublicKey(), "BC"); 330 331 TestCase.assertEquals(enrolledAsHolder.getSubject(), csr.getSubject()); 332 TestCase.assertEquals(enrolledAsHolder.getSubjectPublicKeyInfo(), csr.getSubjectPublicKeyInfo()); 333 334 335 } 336 finally 337 { 338 if (serverInstance != null) 339 { 340 serverInstance.getServer().stop_server(); 341 } 342 } 343 } 344 345 346 /** 347 * Perform enrollment using digest auth. 348 * 349 * @throws Exception 350 */ 351 @Test testEnrollUsingDigestAuth()352 public void testEnrollUsingDigestAuth() 353 throws Exception 354 { 355 ESTTestUtils.ensureProvider(); 356 X509CertificateHolder[] theirCAs = null; 357 ESTServerUtils.ServerInstance serverInstance = null; 358 try 359 { 360 serverInstance = startDefaultServerWithDigestAuth(); 361 362 363 ESTService est = new JsseESTServiceBuilder( 364 "localhost:8443", JcaJceUtils.getCertPathTrustManager( 365 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 366 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 367 )), null) 368 ).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS").build(); 369 // 370 // Make certificate request. 371 // 372 373 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 374 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 375 kpg.initialize(ecGenSpec, new SecureRandom()); 376 KeyPair enrollmentPair = kpg.generateKeyPair(); 377 378 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder(new X500Name("CN=Test"), enrollmentPair.getPublic()); 379 380 PKCS10CertificationRequest csr = pkcs10Builder.build( 381 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 382 383 SecureRandom nonceRandom = new SecureRandom(); 384 EnrollmentResponse enr = est.simpleEnroll(false, csr, 385 new JcaHttpAuthBuilder("estuser", "estpwd".toCharArray()).setNonceGenerator(nonceRandom).setProvider("BC").build()); 386 X509Certificate expectedCA = ESTTestUtils.toJavaX509Certificate(ESTTestUtils.readPemCertificate( 387 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 388 )); 389 390 X509CertificateHolder enrolledAsHolder = ESTService.storeToArray(enr.getStore())[0]; 391 392 X509Certificate enrolled = ESTTestUtils.toJavaX509Certificate(enrolledAsHolder); 393 394 // Will fail if it does not verify. 395 enrolled.verify(expectedCA.getPublicKey(), "BC"); 396 397 TestCase.assertEquals(enrolledAsHolder.getSubject(), csr.getSubject()); 398 TestCase.assertEquals(enrolledAsHolder.getSubjectPublicKeyInfo(), csr.getSubjectPublicKeyInfo()); 399 } 400 finally 401 { 402 if (serverInstance != null) 403 { 404 serverInstance.getServer().stop_server(); 405 } 406 } 407 } 408 409 410 /** 411 * @return [privateKey, X509Certificate] 412 * @throws Exception 413 */ bogusCAGenerator()414 private static Object[] bogusCAGenerator() 415 throws Exception 416 { 417 // 418 // Create a self signed certificate to tend as trust anchor that will 419 // not be part of the servers path. 420 // 421 422 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 423 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 424 kpg.initialize(ecGenSpec, new SecureRandom()); 425 KeyPair originalKeyPair = kpg.generateKeyPair(); 426 427 X500NameBuilder builder = new X500NameBuilder(); 428 builder.addRDN(BCStyle.C, "AI"); 429 builder.addRDN(BCStyle.CN, "BogusCA"); 430 builder.addRDN(BCStyle.O, "BogusCA providers."); 431 builder.addRDN(BCStyle.L, "Atlantis"); 432 433 X500Name name = builder.build(); 434 435 return new Object[]{originalKeyPair.getPrivate(), ESTTestUtils.createSelfsignedCert("SHA256WITHECDSA", 436 name, 437 SubjectPublicKeyInfo.getInstance(originalKeyPair.getPublic().getEncoded()), 438 originalKeyPair.getPrivate(), 439 1 440 )}; 441 } 442 443 444 /** 445 * Test enrollment using TLS do do the client authentication. 446 * In this test we are going to use the BC API to generate a client certificate that the server will NOT accept. 447 * 448 * @throws Exception 449 */ 450 @Test testEnrollUsingBogusTLSClientAuthAndBasicAuth()451 public void testEnrollUsingBogusTLSClientAuthAndBasicAuth() 452 throws Exception 453 { 454 ESTTestUtils.ensureProvider(); 455 456 X509CertificateHolder caCert = ESTTestUtils.readPemCertificate( 457 ESTServerUtils.makeRelativeToServerHome("/extCA/cacert.crt") 458 ); 459 460 PrivateKey caPrivateKey = ESTTestUtils.readPemPrivateKey( 461 ESTServerUtils.makeRelativeToServerHome("/extCA/private/cakey.pem"), "ECDSA" 462 ); 463 464 465 Object[] bogusCA = bogusCAGenerator(); 466 467 468 // 469 // Make client certificate that the server should accept, create the key. 470 // 471 472 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 473 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 474 kpg.initialize(ecGenSpec, new SecureRandom()); 475 KeyPair originalKeyPair = kpg.generateKeyPair(); 476 477 // 478 // Subject DN 479 // 480 X500NameBuilder builder = new X500NameBuilder(); 481 builder.addRDN(BCStyle.C, "AU"); 482 builder.addRDN(BCStyle.CN, "Bunyip Bluegum"); 483 builder.addRDN(BCStyle.O, "Pudding Protectors"); 484 builder.addRDN(BCStyle.L, "Victoria"); 485 486 X500Name name = builder.build(); 487 488 KeyUsage keyUsage = new KeyUsage(KeyUsage.keyCertSign 489 | KeyUsage.digitalSignature | KeyUsage.keyEncipherment 490 | KeyUsage.dataEncipherment | KeyUsage.cRLSign); 491 492 ASN1EncodableVector purposes = new ASN1EncodableVector(); 493 purposes.add(KeyPurposeId.id_kp_serverAuth); 494 purposes.add(KeyPurposeId.id_kp_clientAuth); 495 purposes.add(KeyPurposeId.anyExtendedKeyUsage); 496 497 498 X509Certificate clientTLSCert = ESTTestUtils.createASignedCert("SHA256WITHECDSA", 499 name, 500 SubjectPublicKeyInfo.getInstance(originalKeyPair.getPublic().getEncoded()), 501 new X500Name(((X509Certificate)bogusCA[1]).getSubjectDN().getName()), 502 ((PrivateKey)bogusCA[0]), 503 1, purposes, keyUsage 504 ); 505 506 507 System.out.println(clientTLSCert.toString()); 508 509 510 // 511 // Make keystore for client JSSE client auth. 512 // 513 KeyStore clientKeyStore = KeyStore.getInstance("JKS"); 514 clientKeyStore.load(null); 515 516 char[] clientKeyStorePass = "tstpass".toCharArray(); 517 518 clientKeyStore.setKeyEntry( 519 "estuser", // This is hardcoded into the test server. 520 originalKeyPair.getPrivate(), clientKeyStorePass, 521 new Certificate[]{ 522 clientTLSCert 523 }); 524 525 clientKeyStore.store(new ByteArrayOutputStream(), clientKeyStorePass); 526 527 528 // 529 // Keypair for CSR we wish to enrole. 530 // 531 532 533 kpg.initialize(ecGenSpec); 534 KeyPair enrollmentPair = kpg.generateKeyPair(); 535 536 537 ESTTestUtils.ensureProvider(); 538 final ESTServerUtils.ServerInstance serverInstance = startDefaultServerTLSAndBasicAuth(0, false); 539 try 540 { 541 542 // 543 // Set server trust anchor so client can validate server. 544 // 545 546 TrustAnchor ta = new TrustAnchor( 547 ESTTestUtils.toJavaX509Certificate( 548 ESTTestUtils.readPemCertificate( 549 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 550 ) 551 ), null); 552 553 554 JsseESTServiceBuilder estBuilder = new JsseESTServiceBuilder( 555 "localhost:8443", JcaJceUtils.getCertPathTrustManager( 556 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 557 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 558 )), null) 559 ).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 560 561 estBuilder.withKeyManagers(JcaJceUtils.createKeyManagerFactory(KeyManagerFactory.getDefaultAlgorithm(), null, clientKeyStore, clientKeyStorePass).getKeyManagers()); 562 563 564 ESTService est = estBuilder.build(); 565 566 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 567 new X500Name("CN=Test"), 568 enrollmentPair.getPublic()); 569 570 PKCS10CertificationRequest csr = pkcs10Builder.build( 571 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 572 573 // 574 // Even though we are using TLS we still need to use an HTTP auth. 575 // 576 577 try 578 { 579 EnrollmentResponse enr = est.simpleEnroll( 580 false, 581 csr, 582 new HttpAuth("estreal", "estuser", "estpwd".toCharArray(), new SecureRandom(), new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())); 583 } 584 catch (Exception ex) 585 { 586 Assert.assertEquals("Only ESTException", ex.getClass(), ESTException.class); 587 588 // NB: My assumption is that it depends on how the server hangs up 589 // but we either get a SSL handshake exception or a Socket exception. 590 // TODO might be a race. 591 Assert.assertTrue("Either SocketException or SSLHandshakeException", (ex.getCause() instanceof SocketException || ex.getCause() instanceof SSLHandshakeException)); 592 } 593 594 595 } 596 finally 597 { 598 serverInstance.getServer().stop_server(); 599 } 600 } 601 602 603 /** 604 * Test enrollment using TLS do do the client authentication. 605 * In this test we are going to use the BC API to generate a client certificate that the server will accept. 606 * 607 * @throws Exception 608 */ 609 @Test testEnrollUsingTLSClientAuthAndBasicAuth()610 public void testEnrollUsingTLSClientAuthAndBasicAuth() 611 throws Exception 612 { 613 ESTTestUtils.ensureProvider(); 614 615 X509CertificateHolder caCert = ESTTestUtils.readPemCertificate( 616 ESTServerUtils.makeRelativeToServerHome("/extCA/cacert.crt") 617 ); 618 619 PrivateKey caPrivateKey = ESTTestUtils.readPemPrivateKey( 620 ESTServerUtils.makeRelativeToServerHome("/extCA/private/cakey.pem"), "ECDSA" 621 ); 622 623 // 624 // Make client certificate that the server should accept, create the key. 625 // 626 627 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 628 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 629 kpg.initialize(ecGenSpec, new SecureRandom()); 630 KeyPair originalKeyPair = kpg.generateKeyPair(); 631 632 // 633 // Subject DN 634 // 635 X500NameBuilder builder = new X500NameBuilder(); 636 builder.addRDN(BCStyle.C, "AU"); 637 builder.addRDN(BCStyle.CN, "Bunyip Bluegum"); 638 builder.addRDN(BCStyle.O, "Pudding Protectors"); 639 builder.addRDN(BCStyle.L, "Victoria"); 640 641 X500Name name = builder.build(); 642 643 KeyUsage keyUsage = new KeyUsage(KeyUsage.keyCertSign 644 | KeyUsage.digitalSignature | KeyUsage.keyEncipherment 645 | KeyUsage.dataEncipherment | KeyUsage.cRLSign); 646 647 ASN1EncodableVector purposes = new ASN1EncodableVector(); 648 purposes.add(KeyPurposeId.id_kp_serverAuth); 649 purposes.add(KeyPurposeId.id_kp_clientAuth); 650 purposes.add(KeyPurposeId.anyExtendedKeyUsage); 651 652 653 X509Certificate clientTLSCert = ESTTestUtils.createASignedCert("SHA256WITHECDSA", 654 name, 655 SubjectPublicKeyInfo.getInstance(originalKeyPair.getPublic().getEncoded()), 656 caCert.getSubject(), 657 caPrivateKey, 658 1, purposes, keyUsage 659 ); 660 661 662 // 663 // Make keystore for client JSSE client auth. 664 // 665 KeyStore clientKeyStore = KeyStore.getInstance("JKS"); 666 clientKeyStore.load(null); 667 668 char[] clientKeyStorePass = "tstpass".toCharArray(); 669 670 clientKeyStore.setKeyEntry( 671 "estuser", // This is hardcoded into the test server. 672 originalKeyPair.getPrivate(), clientKeyStorePass, 673 new Certificate[]{ 674 // ESTTestUtils.toJavaX509Certificate(caCert), 675 clientTLSCert 676 }); 677 678 clientKeyStore.store(new ByteArrayOutputStream(), clientKeyStorePass); 679 680 681 // 682 // Keypair for CSR we wish to enrole. 683 // 684 685 686 kpg.initialize(ecGenSpec); 687 KeyPair enrollmentPair = kpg.generateKeyPair(); 688 689 690 ESTTestUtils.ensureProvider(); 691 final ESTServerUtils.ServerInstance serverInstance = startDefaultServerTLSAndBasicAuth(0, false); 692 try 693 { 694 695 // 696 // Set server trust anchor so client can validate server. 697 // 698 699 700 TrustAnchor ta = new TrustAnchor( 701 ESTTestUtils.toJavaX509Certificate( 702 ESTTestUtils.readPemCertificate( 703 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 704 ) 705 ), null); 706 707 708 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 709 new X500Name("CN=Test"), 710 enrollmentPair.getPublic()); 711 712 PKCS10CertificationRequest csr = pkcs10Builder.build( 713 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 714 715 JsseESTServiceBuilder estServiceBuilder = new JsseESTServiceBuilder( 716 "localhost:8443", JcaJceUtils.getCertPathTrustManager( 717 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 718 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 719 )), null) 720 ).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 721 722 estServiceBuilder.withKeyManagers(JcaJceUtils.createKeyManagerFactory(KeyManagerFactory.getDefaultAlgorithm(), null, clientKeyStore, clientKeyStorePass).getKeyManagers()); 723 724 ESTService est = estServiceBuilder.build(); 725 726 727 // 728 // Even though we are using TLS we still need to use an HTTP auth. 729 // 730 731 EnrollmentResponse enr = est.simpleEnroll( 732 false, 733 csr, 734 new JcaHttpAuthBuilder("estreal", "estuser", "estpwd".toCharArray()) 735 .setNonceGenerator(new SecureRandom()).setProvider("BC").build()); 736 737 X509Certificate expectedCA = ESTTestUtils.toJavaX509Certificate(ESTTestUtils.readPemCertificate( 738 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 739 )); 740 741 X509CertificateHolder enrolledAsHolder = ESTService.storeToArray(enr.getStore())[0]; 742 743 X509Certificate enrolled = ESTTestUtils.toJavaX509Certificate(enrolledAsHolder); 744 745 // Will fail if it does not verify. 746 enrolled.verify(expectedCA.getPublicKey(), "BC"); 747 748 TestCase.assertEquals(enrolledAsHolder.getSubject(), csr.getSubject()); 749 TestCase.assertEquals(enrolledAsHolder.getSubjectPublicKeyInfo(), csr.getSubjectPublicKeyInfo()); 750 751 } 752 finally 753 { 754 serverInstance.getServer().stop_server(); 755 } 756 } 757 758 759 /** 760 * Test enrollment using TLS do do the client authentication. 761 * In this test we are going to use the BC API to generate a client certificate that the server will accept. 762 * This test uses the Bouncycastle SSL provider as it gives access to RFC5929 Channel Bindings. 763 * 764 * @throws Exception 765 */ 766 @Test() testEnrollUsingTLSClientAuthAndPOP()767 public void testEnrollUsingTLSClientAuthAndPOP() 768 throws Exception 769 { 770 771 // ESTTestUtils.ensureProvider(BouncyCastleJsseProvider.PROVIDER_NAME); 772 ESTTestUtils.ensureProvider(); 773 774 X509CertificateHolder caCert = ESTTestUtils.readPemCertificate( 775 ESTServerUtils.makeRelativeToServerHome("/extCA/cacert.crt") 776 ); 777 778 PrivateKey caPrivateKey = ESTTestUtils.readPemPrivateKey( 779 ESTServerUtils.makeRelativeToServerHome("/extCA/private/cakey.pem"), "ECDSA" 780 ); 781 782 // 783 // Make client certificate that the server should accept, create the key. 784 // 785 786 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 787 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 788 kpg.initialize(ecGenSpec, new SecureRandom()); 789 KeyPair originalKeyPair = kpg.generateKeyPair(); 790 791 // 792 // Subject DN 793 // 794 X500NameBuilder builder = new X500NameBuilder(); 795 builder.addRDN(BCStyle.C, "AU"); 796 builder.addRDN(BCStyle.CN, "Bunyip Bluegum"); 797 builder.addRDN(BCStyle.O, "Pudding Protectors"); 798 builder.addRDN(BCStyle.L, "Victoria"); 799 800 X500Name name = builder.build(); 801 802 KeyUsage keyUsage = new KeyUsage(KeyUsage.keyCertSign 803 | KeyUsage.digitalSignature | KeyUsage.keyEncipherment 804 | KeyUsage.dataEncipherment | KeyUsage.cRLSign); 805 806 ASN1EncodableVector purposes = new ASN1EncodableVector(); 807 purposes.add(KeyPurposeId.id_kp_serverAuth); 808 purposes.add(KeyPurposeId.id_kp_clientAuth); 809 purposes.add(KeyPurposeId.anyExtendedKeyUsage); 810 811 812 X509Certificate clientTLSCert = ESTTestUtils.createASignedCert("SHA256WITHECDSA", 813 name, 814 SubjectPublicKeyInfo.getInstance(originalKeyPair.getPublic().getEncoded()), 815 caCert.getSubject(), 816 caPrivateKey, 817 1, purposes, keyUsage 818 ); 819 820 821 // 822 // Make keystore for client JSSE client auth. 823 // 824 KeyStore clientKeyStore = KeyStore.getInstance("JKS"); 825 clientKeyStore.load(null); 826 827 char[] clientKeyStorePass = "tstpass".toCharArray(); 828 829 clientKeyStore.setKeyEntry( 830 "estuser", // This is hardcoded into the test server. 831 originalKeyPair.getPrivate(), clientKeyStorePass, 832 new Certificate[]{ 833 // ESTTestUtils.toJavaX509Certificate(caCert), 834 clientTLSCert 835 }); 836 837 clientKeyStore.store(new ByteArrayOutputStream(), clientKeyStorePass); 838 839 // 840 // Keypair for CSR we wish to enroll. 841 // 842 843 kpg.initialize(ecGenSpec); 844 KeyPair enrollmentPair = kpg.generateKeyPair(); 845 846 847 ESTTestUtils.ensureProvider(); 848 final ESTServerUtils.ServerInstance serverInstance = startDefaultServerTLSAndBasicAuth(0, true); 849 try 850 { 851 // 852 // Set server trust anchor so client can validate server. 853 // 854 855 TrustAnchor ta = new TrustAnchor( 856 ESTTestUtils.toJavaX509Certificate( 857 ESTTestUtils.readPemCertificate( 858 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 859 ) 860 ), null); 861 862 ChannelBindingProvider bcChannelBindingProvider = new BCChannelBindingProvider(); 863 864 865 JsseESTServiceBuilder estServiceBuilder = new JsseESTServiceBuilder("localhost:8443", JcaJceUtils.getCertPathTrustManager( 866 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 867 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 868 )), null)); 869 870 estServiceBuilder.withKeyManagers(JcaJceUtils.createKeyManagerFactory("X509", null, clientKeyStore, clientKeyStorePass).getKeyManagers()) 871 .withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 872 873 874 ESTService est = estServiceBuilder 875 .withChannelBindingProvider(bcChannelBindingProvider) 876 877 .addCipherSuites(new String[]{ 878 "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", 879 "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", 880 "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", 881 "TLS_ECDHE_RSA_WITH_NULL_SHA", 882 "TLS_RSA_WITH_AES_128_CCM", 883 "TLS_RSA_WITH_AES_256_CBC_SHA", 884 "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", 885 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", 886 "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", 887 "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", 888 // "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", 889 "TLS_ECDHE_ECDSA_WITH_AES_256_CCM", 890 "TLS_RSA_WITH_AES_256_CBC_SHA256", 891 "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", 892 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", 893 "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", 894 "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", 895 "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8", 896 "TLS_RSA_WITH_AES_256_CCM_8", 897 "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", 898 "TLS_ECDHE_ECDSA_WITH_NULL_SHA", 899 "TLS_RSA_WITH_NULL_SHA256", 900 "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", 901 "TLS_RSA_WITH_AES_128_CBC_SHA256", 902 "TLS_RSA_WITH_AES_128_GCM_SHA256", 903 "TLS_RSA_WITH_AES_256_CCM", 904 "TLS_RSA_WITH_AES_256_GCM_SHA384", 905 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", 906 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", 907 "TLS_ECDHE_ECDSA_WITH_AES_128_CCM", 908 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", 909 "TLS_DHE_RSA_WITH_AES_256_CCM_8", 910 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", 911 "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8", 912 "TLS_RSA_WITH_AES_128_CBC_SHA", 913 "TLS_DHE_RSA_WITH_AES_128_CCM_8", 914 "TLS_RSA_WITH_NULL_SHA", 915 "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", 916 "TLS_RSA_WITH_3DES_EDE_CBC_SHA", 917 "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", 918 "TLS_RSA_WITH_AES_128_CCM_8", 919 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", 920 "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", 921 "TLS_DHE_RSA_WITH_AES_256_CCM", 922 "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", 923 "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", 924 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", 925 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 926 "TLS_DHE_RSA_WITH_AES_128_CCM", 927 "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", 928 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", 929 "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", 930 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"}) 931 .build(); 932 933 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 934 new X500Name("CN=Test"), 935 enrollmentPair.getPublic()); 936 ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate()); 937 938 // 939 // Even though we are using TLS we still need to use an HTTP auth. 940 // 941 EnrollmentResponse enr = est.simpleEnrollPoP( 942 false, 943 pkcs10Builder, 944 contentSigner, 945 new JcaHttpAuthBuilder("estreal", "estuser", "estpwd".toCharArray()).setProvider("BC").setNonceGenerator(new SecureRandom()).build()); 946 947 948 X509Certificate expectedCA = ESTTestUtils.toJavaX509Certificate(ESTTestUtils.readPemCertificate( 949 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 950 )); 951 952 X509CertificateHolder enrolledAsHolder = ESTService.storeToArray(enr.getStore())[0]; 953 954 X509Certificate enrolled = ESTTestUtils.toJavaX509Certificate(enrolledAsHolder); 955 956 // Will fail if it does not verify. 957 enrolled.verify(expectedCA.getPublicKey(), "BC"); 958 959 // 960 // Other aspects of CSR testing covered elsewhere 961 // 962 963 System.out.println(ESTTestUtils.toJavaX509Certificate(enrolled)); 964 965 } 966 finally 967 { 968 serverInstance.getServer().stop_server(); 969 } 970 } 971 972 @Test() testResponseWith401AndNoAuth()973 public void testResponseWith401AndNoAuth() 974 throws Exception 975 { 976 ESTTestUtils.ensureProvider(); 977 final ByteArrayOutputStream responseData = new ByteArrayOutputStream(); 978 979 PrintWriter pw = new PrintWriter(responseData); 980 pw.print("HTTP/1.1 401 Unauthorized\n" + 981 "Status: 401 Unauthorized\n" + 982 "Content-Length: 0\n\n"); 983 pw.flush(); 984 985 986 // 987 // Test content length enforcement. 988 // Fail when content-length = read limit. 989 // 990 HttpResponder res = new HttpResponder(); 991 try 992 { 993 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 994 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 995 kpg.initialize(ecGenSpec, new SecureRandom()); 996 KeyPair enrollmentPair = kpg.generateKeyPair(); 997 998 999 TrustAnchor ta = new TrustAnchor( 1000 ESTTestUtils.toJavaX509Certificate( 1001 ESTTestUtils.readPemCertificate( 1002 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1003 ) 1004 ), null); 1005 1006 1007 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 1008 new X500Name("CN=Test"), 1009 enrollmentPair.getPublic()); 1010 1011 PKCS10CertificationRequest csr = pkcs10Builder.build( 1012 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 1013 1014 // 1015 // Even though we are using TLS we still need to use an HTTP auth. 1016 // 1017 1018 int port = res.open(responseData.toByteArray()); 1019 1020 JsseESTServiceBuilder builder = new JsseESTServiceBuilder( 1021 "localhost:" + port, JcaJceUtils.getCertPathTrustManager( 1022 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 1023 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1024 )), null)).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 1025 1026 builder.addCipherSuites(res.getSupportedCipherSuites()); 1027 1028 1029 try 1030 { 1031 EnrollmentResponse resp = builder.build().simpleEnroll(false, csr, null); 1032 Assert.fail("Must throw exception."); 1033 } 1034 catch (Exception t) 1035 { 1036 Assert.assertEquals("Must be ESTException", t.getClass(), ESTException.class); 1037 } 1038 1039 } 1040 catch (Exception ex) 1041 { 1042 ex.printStackTrace(); 1043 } 1044 finally 1045 { 1046 res.close(); 1047 } 1048 1049 res.getFinished().await(5, TimeUnit.SECONDS); 1050 1051 } 1052 1053 1054 @Test() testResponseWith400()1055 public void testResponseWith400() 1056 throws Exception 1057 { 1058 ESTTestUtils.ensureProvider(); 1059 final ByteArrayOutputStream responseData = new ByteArrayOutputStream(); 1060 1061 PrintWriter pw = new PrintWriter(responseData); 1062 pw.print("HTTP/1.1 400 Bad Request\n" + 1063 "Status: 400 Bad Request\n" + 1064 "Content-Length: 0\n\n"); 1065 pw.flush(); 1066 1067 // 1068 // Test content length enforcement. 1069 // Fail when content-length = read limit. 1070 // 1071 HttpResponder res = new HttpResponder(); 1072 try 1073 { 1074 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 1075 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 1076 kpg.initialize(ecGenSpec, new SecureRandom()); 1077 KeyPair enrollmentPair = kpg.generateKeyPair(); 1078 1079 1080 TrustAnchor ta = new TrustAnchor( 1081 ESTTestUtils.toJavaX509Certificate( 1082 ESTTestUtils.readPemCertificate( 1083 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1084 ) 1085 ), null); 1086 1087 1088 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 1089 new X500Name("CN=Test"), 1090 enrollmentPair.getPublic()); 1091 1092 PKCS10CertificationRequest csr = pkcs10Builder.build( 1093 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 1094 1095 // 1096 // Even though we are using TLS we still need to use an HTTP auth. 1097 // 1098 1099 int port = res.open(responseData.toByteArray()); 1100 1101 1102 JsseESTServiceBuilder builder = new JsseESTServiceBuilder( 1103 "localhost:" + port, JcaJceUtils.getCertPathTrustManager( 1104 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 1105 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1106 )), null)).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 1107 1108 1109 builder.addCipherSuites(res.getSupportedCipherSuites()); 1110 1111 1112 try 1113 { 1114 EnrollmentResponse resp = builder.build().simpleEnroll(false, csr, null); 1115 Assert.fail("Must throw exception."); 1116 } 1117 catch (Exception t) 1118 { 1119 Assert.assertEquals("Must be ESTException", t.getClass(), ESTException.class); 1120 Assert.assertEquals("", 400, ((ESTException)t).getStatusCode()); 1121 } 1122 1123 } 1124 catch (Exception ex) 1125 { 1126 ex.printStackTrace(); 1127 } 1128 finally 1129 { 1130 res.close(); 1131 } 1132 1133 res.getFinished().await(5, TimeUnit.SECONDS); 1134 1135 } 1136 1137 @Test() testResponseWith401BAndBadQOP()1138 public void testResponseWith401BAndBadQOP() 1139 throws Exception 1140 { 1141 ESTTestUtils.ensureProvider(); 1142 final ByteArrayOutputStream responseData = new ByteArrayOutputStream(); 1143 1144 PrintWriter pw = new PrintWriter(responseData); 1145 pw.print("HTTP/1.1 401 Unauthorized\n" + 1146 "Status: 401 Unauthorized\n" + 1147 "Content-Length: 0\n" + 1148 "WWW-Authenticate: Digest qop=\"invalid\", realm=\"estrealm\", nonce=\"1487704890\", algorithm=\"md5\"\n\n"); 1149 pw.flush(); 1150 1151 // 1152 // Test content length enforcement. 1153 // Fail when content-length = read limit. 1154 // 1155 HttpResponder res = new HttpResponder(); 1156 try 1157 { 1158 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 1159 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 1160 kpg.initialize(ecGenSpec, new SecureRandom()); 1161 KeyPair enrollmentPair = kpg.generateKeyPair(); 1162 1163 1164 TrustAnchor ta = new TrustAnchor( 1165 ESTTestUtils.toJavaX509Certificate( 1166 ESTTestUtils.readPemCertificate( 1167 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1168 ) 1169 ), null); 1170 1171 1172 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 1173 new X500Name("CN=Test"), 1174 enrollmentPair.getPublic()); 1175 1176 PKCS10CertificationRequest csr = pkcs10Builder.build( 1177 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 1178 1179 // 1180 // Even though we are using TLS we still need to use an HTTP auth. 1181 // 1182 1183 int port = res.open(responseData.toByteArray()); 1184 1185 1186 JsseESTServiceBuilder builder = new JsseESTServiceBuilder( 1187 "localhost:" + port, JcaJceUtils.getCertPathTrustManager( 1188 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 1189 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1190 )), null)).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 1191 1192 1193 builder.addCipherSuites(res.getSupportedCipherSuites()); 1194 1195 1196 try 1197 { 1198 EnrollmentResponse resp = builder.build().simpleEnroll(false, csr, 1199 new HttpAuth( 1200 "estrealm", 1201 "estuser", 1202 "estpwd".toCharArray(), 1203 new SecureRandom(), 1204 new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) 1205 ); 1206 Assert.fail("Must throw exception."); 1207 } 1208 catch (Exception t) 1209 { 1210 Assert.assertEquals("Must be ESTException", t.getClass(), ESTException.class); 1211 Assert.assertTrue("", t.getMessage().contains("QoP value unknown: '0'")); 1212 } 1213 } 1214 catch (Exception ex) 1215 { 1216 ex.printStackTrace(); 1217 } 1218 finally 1219 { 1220 res.close(); 1221 } 1222 1223 res.getFinished().await(5, TimeUnit.SECONDS); 1224 1225 } 1226 1227 @Test() testResponseWith401UknownValueInHeader()1228 public void testResponseWith401UknownValueInHeader() 1229 throws Exception 1230 { 1231 ESTTestUtils.ensureProvider(); 1232 final ByteArrayOutputStream responseData = new ByteArrayOutputStream(); 1233 1234 PrintWriter pw = new PrintWriter(responseData); 1235 pw.print("HTTP/1.1 401 Unauthorized\n" + 1236 "Status: 401 Unauthorized\n" + 1237 "Content-Length: 0\n" + 1238 "WWW-Authenticate: Digest qop=\"invalid\", realm=\"estrealm\", nonce=\"1487704890\", algorithm=\"md5\", dummy=\"value\"\n\n"); 1239 pw.flush(); 1240 1241 // 1242 // Test content length enforcement. 1243 // Fail when content-length = read limit. 1244 // 1245 HttpResponder res = new HttpResponder(); 1246 try 1247 { 1248 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 1249 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 1250 kpg.initialize(ecGenSpec, new SecureRandom()); 1251 KeyPair enrollmentPair = kpg.generateKeyPair(); 1252 1253 1254 TrustAnchor ta = new TrustAnchor( 1255 ESTTestUtils.toJavaX509Certificate( 1256 ESTTestUtils.readPemCertificate( 1257 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1258 ) 1259 ), null); 1260 1261 1262 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 1263 new X500Name("CN=Test"), 1264 enrollmentPair.getPublic()); 1265 1266 PKCS10CertificationRequest csr = pkcs10Builder.build( 1267 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 1268 1269 // 1270 // Even though we are using TLS we still need to use an HTTP auth. 1271 // 1272 1273 int port = res.open(responseData.toByteArray()); 1274 1275 1276 JsseESTServiceBuilder builder = new JsseESTServiceBuilder( 1277 "localhost:" + port, JcaJceUtils.getCertPathTrustManager( 1278 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 1279 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1280 )), null)).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 1281 1282 builder.addCipherSuites(res.getSupportedCipherSuites()); 1283 1284 1285 try 1286 { 1287 EnrollmentResponse resp = builder.build().simpleEnroll(false, csr, 1288 new HttpAuth( 1289 "estrealm", 1290 "estuser", 1291 "estpwd".toCharArray(), 1292 new SecureRandom(), 1293 new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) 1294 ); 1295 Assert.fail("Must throw exception."); 1296 } 1297 catch (Exception t) 1298 { 1299 Assert.assertEquals("Must be ESTException", t.getClass(), ESTException.class); 1300 Assert.assertTrue("", t.getMessage().contains("'dummy'")); 1301 } 1302 } 1303 catch (Exception ex) 1304 { 1305 ex.printStackTrace(); 1306 } 1307 finally 1308 { 1309 res.close(); 1310 } 1311 1312 res.getFinished().await(5, TimeUnit.SECONDS); 1313 1314 } 1315 1316 1317 @Test() testResponseWith401QpopEmpty()1318 public void testResponseWith401QpopEmpty() 1319 throws Exception 1320 { 1321 ESTTestUtils.ensureProvider(); 1322 final ByteArrayOutputStream responseData = new ByteArrayOutputStream(); 1323 1324 PrintWriter pw = new PrintWriter(responseData); 1325 pw.print("HTTP/1.1 401 Unauthorized\n" + 1326 "Status: 401 Unauthorized\n" + 1327 "Content-Length: 0\n" + 1328 "WWW-Authenticate: Digest qop=\"\", realm=\"estrealm\", nonce=\"1487704890\", algorithm=\"md5\"\n\n"); 1329 pw.flush(); 1330 1331 // 1332 // Test content length enforcement. 1333 // Fail when content-length = read limit. 1334 // 1335 HttpResponder res = new HttpResponder(); 1336 try 1337 { 1338 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 1339 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 1340 kpg.initialize(ecGenSpec, new SecureRandom()); 1341 KeyPair enrollmentPair = kpg.generateKeyPair(); 1342 1343 1344 TrustAnchor ta = new TrustAnchor( 1345 ESTTestUtils.toJavaX509Certificate( 1346 ESTTestUtils.readPemCertificate( 1347 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1348 ) 1349 ), null); 1350 1351 1352 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 1353 new X500Name("CN=Test"), 1354 enrollmentPair.getPublic()); 1355 1356 PKCS10CertificationRequest csr = pkcs10Builder.build( 1357 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 1358 1359 // 1360 // Even though we are using TLS we still need to use an HTTP auth. 1361 // 1362 1363 int port = res.open(responseData.toByteArray()); 1364 1365 1366 JsseESTServiceBuilder builder = new JsseESTServiceBuilder( 1367 "localhost:" + port, JcaJceUtils.getCertPathTrustManager( 1368 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 1369 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1370 )), null)); 1371 1372 builder.addCipherSuites(res.getSupportedCipherSuites()); 1373 builder.withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 1374 1375 1376 try 1377 { 1378 EnrollmentResponse resp = builder.build().simpleEnroll(false, csr, 1379 new HttpAuth( 1380 "estrealm", 1381 "estuser", 1382 "estpwd".toCharArray(), 1383 new SecureRandom(), 1384 new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) 1385 ); 1386 Assert.fail("Must throw exception."); 1387 } 1388 catch (Exception t) 1389 { 1390 Assert.assertEquals("Must be ESTException", t.getClass(), ESTException.class); 1391 Assert.assertTrue("", t.getMessage().contains("value is empty")); 1392 } 1393 } 1394 catch (Exception ex) 1395 { 1396 ex.printStackTrace(); 1397 } 1398 finally 1399 { 1400 res.close(); 1401 } 1402 1403 res.getFinished().await(5, TimeUnit.SECONDS); 1404 1405 } 1406 1407 1408 @Test() testResponseWith401BadMode()1409 public void testResponseWith401BadMode() 1410 throws Exception 1411 { 1412 ESTTestUtils.ensureProvider(); 1413 final ByteArrayOutputStream responseData = new ByteArrayOutputStream(); 1414 1415 PrintWriter pw = new PrintWriter(responseData); 1416 pw.print("HTTP/1.1 401 Unauthorized\n" + 1417 "Status: 401 Unauthorized\n" + 1418 "Content-Length: 0\n" + 1419 "WWW-Authenticate: Banana qop=\"\", realm=\"estrealm\", nonce=\"1487704890\", algorithm=\"md5\"\n\n"); 1420 pw.flush(); 1421 1422 // 1423 // Test content length enforcement. 1424 // Fail when content-length = read limit. 1425 // 1426 HttpResponder res = new HttpResponder(); 1427 try 1428 { 1429 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 1430 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 1431 kpg.initialize(ecGenSpec, new SecureRandom()); 1432 KeyPair enrollmentPair = kpg.generateKeyPair(); 1433 1434 1435 TrustAnchor ta = new TrustAnchor( 1436 ESTTestUtils.toJavaX509Certificate( 1437 ESTTestUtils.readPemCertificate( 1438 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1439 ) 1440 ), null); 1441 1442 1443 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 1444 new X500Name("CN=Test"), 1445 enrollmentPair.getPublic()); 1446 1447 PKCS10CertificationRequest csr = pkcs10Builder.build( 1448 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 1449 1450 // 1451 // Even though we are using TLS we still need to use an HTTP auth. 1452 // 1453 1454 int port = res.open(responseData.toByteArray()); 1455 1456 1457 JsseESTServiceBuilder builder = new JsseESTServiceBuilder( 1458 "localhost:" + port, JcaJceUtils.getCertPathTrustManager( 1459 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 1460 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1461 )), null)); 1462 1463 builder.withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 1464 1465 builder.addCipherSuites(res.getSupportedCipherSuites()); 1466 1467 1468 try 1469 { 1470 EnrollmentResponse resp = builder.build().simpleEnroll(false, csr, 1471 new HttpAuth( 1472 "estrealm", 1473 "estuser", 1474 "estpwd".toCharArray(), 1475 new SecureRandom(), 1476 new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) 1477 ); 1478 Assert.fail("Must throw exception."); 1479 } 1480 catch (Exception t) 1481 { 1482 t.printStackTrace(); 1483 Assert.assertEquals("Must be ESTException", t.getClass(), ESTException.class); 1484 Assert.assertTrue("", t.getMessage().contains("banana")); 1485 } 1486 } 1487 catch (Exception ex) 1488 { 1489 ex.printStackTrace(); 1490 } 1491 finally 1492 { 1493 res.close(); 1494 } 1495 1496 res.getFinished().await(5, TimeUnit.SECONDS); 1497 1498 } 1499 1500 1501 @Test() testResponseWith401AndNoWWWHeader()1502 public void testResponseWith401AndNoWWWHeader() 1503 throws Exception 1504 { 1505 ESTTestUtils.ensureProvider(); 1506 final ByteArrayOutputStream responseData = new ByteArrayOutputStream(); 1507 1508 PrintWriter pw = new PrintWriter(responseData); 1509 pw.print("HTTP/1.1 401 Unauthorized\n" + 1510 "Status: 401 Unauthorized\n" + 1511 "Content-Length: 0\n" + 1512 "\n"); 1513 pw.flush(); 1514 1515 // 1516 // Test content length enforcement. 1517 // Fail when content-length = read limit. 1518 // 1519 HttpResponder res = new HttpResponder(); 1520 try 1521 { 1522 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 1523 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 1524 kpg.initialize(ecGenSpec, new SecureRandom()); 1525 KeyPair enrollmentPair = kpg.generateKeyPair(); 1526 1527 1528 TrustAnchor ta = new TrustAnchor( 1529 ESTTestUtils.toJavaX509Certificate( 1530 ESTTestUtils.readPemCertificate( 1531 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1532 ) 1533 ), null); 1534 1535 1536 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 1537 new X500Name("CN=Test"), 1538 enrollmentPair.getPublic()); 1539 1540 PKCS10CertificationRequest csr = pkcs10Builder.build( 1541 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 1542 1543 // 1544 // Even though we are using TLS we still need to use an HTTP auth. 1545 // 1546 1547 int port = res.open(responseData.toByteArray()); 1548 1549 1550 JsseESTServiceBuilder builder = new JsseESTServiceBuilder( 1551 "localhost:" + port, JcaJceUtils.getCertPathTrustManager( 1552 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 1553 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1554 )), null)).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 1555 1556 1557 builder.addCipherSuites(res.getSupportedCipherSuites()); 1558 1559 1560 try 1561 { 1562 EnrollmentResponse resp = builder.build().simpleEnroll(false, csr, 1563 new HttpAuth( 1564 "estrealm", 1565 "estuser", 1566 "estpwd".toCharArray(), 1567 new SecureRandom(), 1568 new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) 1569 ); 1570 Assert.fail("Must throw exception."); 1571 } 1572 catch (Exception t) 1573 { 1574 Assert.assertEquals("Must be ESTException", t.getClass(), ESTException.class); 1575 Assert.assertTrue("", t.getMessage().contains("no WWW-Authenticate")); 1576 } 1577 } 1578 catch (Exception ex) 1579 { 1580 ex.printStackTrace(); 1581 } 1582 finally 1583 { 1584 res.close(); 1585 } 1586 1587 res.getFinished().await(5, TimeUnit.SECONDS); 1588 1589 } 1590 1591 1592 @Test() testResponseWith401AndBadAlgorithm()1593 public void testResponseWith401AndBadAlgorithm() 1594 throws Exception 1595 { 1596 ESTTestUtils.ensureProvider(); 1597 final ByteArrayOutputStream responseData = new ByteArrayOutputStream(); 1598 1599 PrintWriter pw = new PrintWriter(responseData); 1600 pw.print("HTTP/1.1 401 Unauthorized\n" + 1601 "Status: 401 Unauthorized\n" + 1602 "Content-Length: 0\n" + 1603 "WWW-Authenticate: Digest qop=\"auth\", realm=\"estrealm\", nonce=\"1487706836\", algorithm=\"token\"\n\n"); 1604 pw.flush(); 1605 1606 // 1607 // Test content length enforcement. 1608 // Fail when content-length = read limit. 1609 // 1610 HttpResponder res = new HttpResponder(); 1611 try 1612 { 1613 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 1614 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 1615 kpg.initialize(ecGenSpec, new SecureRandom()); 1616 KeyPair enrollmentPair = kpg.generateKeyPair(); 1617 1618 1619 TrustAnchor ta = new TrustAnchor( 1620 ESTTestUtils.toJavaX509Certificate( 1621 ESTTestUtils.readPemCertificate( 1622 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1623 ) 1624 ), null); 1625 1626 1627 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 1628 new X500Name("CN=Test"), 1629 enrollmentPair.getPublic()); 1630 1631 PKCS10CertificationRequest csr = pkcs10Builder.build( 1632 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 1633 1634 // 1635 // Even though we are using TLS we still need to use an HTTP auth. 1636 // 1637 1638 int port = res.open(responseData.toByteArray()); 1639 1640 1641 JsseESTServiceBuilder builder = new JsseESTServiceBuilder( 1642 "localhost:" + port, JcaJceUtils.getCertPathTrustManager( 1643 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 1644 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1645 )), null)).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 1646 1647 1648 builder.addCipherSuites(res.getSupportedCipherSuites()); 1649 1650 1651 try 1652 { 1653 EnrollmentResponse resp = builder.build().simpleEnroll(false, csr, 1654 new HttpAuth( 1655 "estrealm", 1656 "estuser", 1657 "estpwd".toCharArray(), 1658 new SecureRandom(), 1659 new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) 1660 ); 1661 Assert.fail("Must throw exception."); 1662 } 1663 catch (Exception t) 1664 { 1665 Assert.assertEquals("Must be ESTException", t.getClass(), ESTException.class); 1666 Assert.assertTrue("", t.getMessage().contains("digest algorithm unknown")); 1667 } 1668 } 1669 catch (Exception ex) 1670 { 1671 ex.printStackTrace(); 1672 } 1673 finally 1674 { 1675 res.close(); 1676 } 1677 1678 res.getFinished().await(5, TimeUnit.SECONDS); 1679 1680 } 1681 1682 1683 @Test() testResponseWith401AndEmptyAlgorithm()1684 public void testResponseWith401AndEmptyAlgorithm() 1685 throws Exception 1686 { 1687 ESTTestUtils.ensureProvider(); 1688 final ByteArrayOutputStream responseData = new ByteArrayOutputStream(); 1689 1690 PrintWriter pw = new PrintWriter(responseData); 1691 pw.print("HTTP/1.1 401 Unauthorized\n" + 1692 "Status: 401 Unauthorized\n" + 1693 "Content-Length: 0\n" + 1694 "WWW-Authenticate: Digest qop=\"auth\", realm=\"estrealm\", nonce=\"1487706836\", algorithm=\"\"\n\n"); 1695 pw.flush(); 1696 1697 // 1698 // Test content length enforcement. 1699 // Fail when content-length = read limit. 1700 // 1701 HttpResponder res = new HttpResponder(); 1702 try 1703 { 1704 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 1705 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 1706 kpg.initialize(ecGenSpec, new SecureRandom()); 1707 KeyPair enrollmentPair = kpg.generateKeyPair(); 1708 1709 1710 TrustAnchor ta = new TrustAnchor( 1711 ESTTestUtils.toJavaX509Certificate( 1712 ESTTestUtils.readPemCertificate( 1713 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1714 ) 1715 ), null); 1716 1717 1718 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 1719 new X500Name("CN=Test"), 1720 enrollmentPair.getPublic()); 1721 1722 PKCS10CertificationRequest csr = pkcs10Builder.build( 1723 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 1724 1725 // 1726 // Even though we are using TLS we still need to use an HTTP auth. 1727 // 1728 1729 int port = res.open(responseData.toByteArray()); 1730 1731 1732 JsseESTServiceBuilder builder = new JsseESTServiceBuilder( 1733 "localhost:" + port, JcaJceUtils.getCertPathTrustManager( 1734 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 1735 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1736 )), null)).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 1737 1738 1739 builder.addCipherSuites(res.getSupportedCipherSuites()); 1740 1741 1742 try 1743 { 1744 EnrollmentResponse resp = builder.build().simpleEnroll(false, csr, 1745 new HttpAuth( 1746 "estrealm", 1747 "estuser", 1748 "estpwd".toCharArray(), 1749 new SecureRandom(), 1750 new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) 1751 ); 1752 Assert.fail("Must throw exception."); 1753 } 1754 catch (Exception t) 1755 { 1756 Assert.assertEquals("Must be ESTException", t.getClass(), ESTException.class); 1757 Assert.assertTrue("", t.getMessage().contains("no algorithm defined")); 1758 } 1759 } 1760 catch (Exception ex) 1761 { 1762 ex.printStackTrace(); 1763 } 1764 finally 1765 { 1766 res.close(); 1767 } 1768 1769 res.getFinished().await(5, TimeUnit.SECONDS); 1770 1771 } 1772 1773 1774 1775 1776 1777 @Test() testResponseWith401NullNonce()1778 public void testResponseWith401NullNonce() 1779 throws Exception 1780 { 1781 ESTTestUtils.ensureProvider(); 1782 final ByteArrayOutputStream responseData = new ByteArrayOutputStream(); 1783 1784 PrintWriter pw = new PrintWriter(responseData); 1785 pw.print("HTTP/1.1 401 Unauthorized\n" + 1786 "Status: 401 Unauthorized\n" + 1787 "Content-Length: 0\n" + 1788 "WWW-Authenticate: Digest qop=\"auth\", realm=\"estrealm\", nonce=\n\n"); 1789 pw.flush(); 1790 1791 // 1792 // Test content length enforcement. 1793 // Fail when content-length = read limit. 1794 // 1795 HttpResponder res = new HttpResponder(); 1796 try 1797 { 1798 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 1799 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 1800 kpg.initialize(ecGenSpec, new SecureRandom()); 1801 KeyPair enrollmentPair = kpg.generateKeyPair(); 1802 1803 1804 TrustAnchor ta = new TrustAnchor( 1805 ESTTestUtils.toJavaX509Certificate( 1806 ESTTestUtils.readPemCertificate( 1807 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1808 ) 1809 ), null); 1810 1811 1812 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 1813 new X500Name("CN=Test"), 1814 enrollmentPair.getPublic()); 1815 1816 PKCS10CertificationRequest csr = pkcs10Builder.build( 1817 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 1818 1819 // 1820 // Even though we are using TLS we still need to use an HTTP auth. 1821 // 1822 1823 int port = res.open(responseData.toByteArray()); 1824 1825 1826 JsseESTServiceBuilder builder = new JsseESTServiceBuilder( 1827 "localhost:" + port, JcaJceUtils.getCertPathTrustManager( 1828 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 1829 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1830 )), null)).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 1831 1832 builder.addCipherSuites(res.getSupportedCipherSuites()); 1833 1834 1835 try 1836 { 1837 EnrollmentResponse resp = builder.build().simpleEnroll(false, csr, 1838 new HttpAuth( 1839 "estrealm", 1840 "estuser", 1841 "estpwd".toCharArray(), 1842 new SecureRandom(), 1843 new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) 1844 ); 1845 Assert.fail("Must throw exception."); 1846 } 1847 catch (Exception t) 1848 { 1849 Assert.assertEquals("Must be ESTException", t.getClass(), ESTException.class); 1850 Assert.assertTrue("", t.getMessage().contains("Expecting start quote")); 1851 } 1852 } 1853 catch (Exception ex) 1854 { 1855 ex.printStackTrace(); 1856 } 1857 finally 1858 { 1859 res.close(); 1860 } 1861 1862 res.getFinished().await(5, TimeUnit.SECONDS); 1863 1864 } 1865 1866 1867 @Test() testResponseWith401NullRealm()1868 public void testResponseWith401NullRealm() 1869 throws Exception 1870 { 1871 ESTTestUtils.ensureProvider(); 1872 final ByteArrayOutputStream responseData = new ByteArrayOutputStream(); 1873 1874 PrintWriter pw = new PrintWriter(responseData); 1875 pw.print("HTTP/1.1 401 Unauthorized\n" + 1876 "Status: 401 Unauthorized\n" + 1877 "Content-Length: 0\n" + 1878 "WWW-Authenticate: Digest qop=\"auth\", realm=, nonce=\"1234\"\n\n"); 1879 pw.flush(); 1880 1881 // 1882 // Test content length enforcement. 1883 // Fail when content-length = read limit. 1884 // 1885 HttpResponder res = new HttpResponder(); 1886 try 1887 { 1888 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 1889 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 1890 kpg.initialize(ecGenSpec, new SecureRandom()); 1891 KeyPair enrollmentPair = kpg.generateKeyPair(); 1892 1893 1894 TrustAnchor ta = new TrustAnchor( 1895 ESTTestUtils.toJavaX509Certificate( 1896 ESTTestUtils.readPemCertificate( 1897 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1898 ) 1899 ), null); 1900 1901 1902 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 1903 new X500Name("CN=Test"), 1904 enrollmentPair.getPublic()); 1905 1906 PKCS10CertificationRequest csr = pkcs10Builder.build( 1907 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 1908 1909 // 1910 // Even though we are using TLS we still need to use an HTTP auth. 1911 // 1912 1913 int port = res.open(responseData.toByteArray()); 1914 1915 JsseESTServiceBuilder builder = new JsseESTServiceBuilder( 1916 "localhost:" + port, JcaJceUtils.getCertPathTrustManager( 1917 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 1918 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1919 )), null)).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 1920 1921 builder.addCipherSuites(res.getSupportedCipherSuites()); 1922 1923 1924 try 1925 { 1926 EnrollmentResponse resp = builder.build().simpleEnroll(false, csr, 1927 new HttpAuth( 1928 "estrealm", 1929 "estuser", 1930 "estpwd".toCharArray(), 1931 new SecureRandom(), 1932 new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) 1933 ); 1934 Assert.fail("Must throw exception."); 1935 } 1936 catch (Exception t) 1937 { 1938 Assert.assertEquals("Must be ESTException", t.getClass(), ESTException.class); 1939 Assert.assertTrue("", t.getMessage().contains("Expecting start quote")); 1940 } 1941 } 1942 catch (Exception ex) 1943 { 1944 ex.printStackTrace(); 1945 } 1946 finally 1947 { 1948 res.close(); 1949 } 1950 1951 res.getFinished().await(5, TimeUnit.SECONDS); 1952 1953 } 1954 1955 1956 @Test() testResponseWith401NullQop()1957 public void testResponseWith401NullQop() 1958 throws Exception 1959 { 1960 ESTTestUtils.ensureProvider(); 1961 final ByteArrayOutputStream responseData = new ByteArrayOutputStream(); 1962 1963 PrintWriter pw = new PrintWriter(responseData); 1964 pw.print("HTTP/1.1 401 Unauthorized\n" + 1965 "Status: 401 Unauthorized\n" + 1966 "Content-Length: 0\n" + 1967 "WWW-Authenticate: Digest realm=\"estrealm\", nonce=\"1487778654\", qop=\n\n"); 1968 pw.flush(); 1969 1970 // 1971 // Test content length enforcement. 1972 // Fail when content-length = read limit. 1973 // 1974 HttpResponder res = new HttpResponder(); 1975 try 1976 { 1977 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 1978 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 1979 kpg.initialize(ecGenSpec, new SecureRandom()); 1980 KeyPair enrollmentPair = kpg.generateKeyPair(); 1981 1982 1983 TrustAnchor ta = new TrustAnchor( 1984 ESTTestUtils.toJavaX509Certificate( 1985 ESTTestUtils.readPemCertificate( 1986 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 1987 ) 1988 ), null); 1989 1990 1991 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 1992 new X500Name("CN=Test"), 1993 enrollmentPair.getPublic()); 1994 1995 PKCS10CertificationRequest csr = pkcs10Builder.build( 1996 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 1997 1998 // 1999 // Even though we are using TLS we still need to use an HTTP auth. 2000 // 2001 2002 int port = res.open(responseData.toByteArray()); 2003 2004 2005 JsseESTServiceBuilder builder = new JsseESTServiceBuilder( 2006 "localhost:" + port, JcaJceUtils.getCertPathTrustManager( 2007 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 2008 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 2009 )), null)).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 2010 2011 2012 builder.addCipherSuites(res.getSupportedCipherSuites()); 2013 2014 2015 try 2016 { 2017 EnrollmentResponse resp = builder.build().simpleEnroll(false, csr, 2018 new HttpAuth( 2019 "estrealm", 2020 "estuser", 2021 "estpwd".toCharArray(), 2022 new SecureRandom(), 2023 new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) 2024 ); 2025 Assert.fail("Must throw exception."); 2026 } 2027 catch (Exception t) 2028 { 2029 Assert.assertEquals("Must be ESTException", t.getClass(), ESTException.class); 2030 Assert.assertTrue("", t.getMessage().contains("Expecting start quote")); 2031 } 2032 } 2033 catch (Exception ex) 2034 { 2035 ex.printStackTrace(); 2036 } 2037 finally 2038 { 2039 res.close(); 2040 } 2041 2042 res.getFinished().await(5, TimeUnit.SECONDS); 2043 2044 } 2045 2046 2047 @Test() testResponseWith202NoRetryHeader()2048 public void testResponseWith202NoRetryHeader() 2049 throws Exception 2050 { 2051 ESTTestUtils.ensureProvider(); 2052 final ByteArrayOutputStream responseData = new ByteArrayOutputStream(); 2053 2054 PrintWriter pw = new PrintWriter(responseData); 2055 pw.print("HTTP/1.1 202 Accepted\n" + 2056 "Status: 202 Accepted\n" + 2057 "Content-Length: 0\n\n"); 2058 pw.flush(); 2059 2060 // 2061 // Test content length enforcement. 2062 // Fail when content-length = read limit. 2063 // 2064 HttpResponder res = new HttpResponder(); 2065 try 2066 { 2067 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 2068 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 2069 kpg.initialize(ecGenSpec, new SecureRandom()); 2070 KeyPair enrollmentPair = kpg.generateKeyPair(); 2071 2072 2073 TrustAnchor ta = new TrustAnchor( 2074 ESTTestUtils.toJavaX509Certificate( 2075 ESTTestUtils.readPemCertificate( 2076 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 2077 ) 2078 ), null); 2079 2080 2081 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 2082 new X500Name("CN=Test"), 2083 enrollmentPair.getPublic()); 2084 2085 PKCS10CertificationRequest csr = pkcs10Builder.build( 2086 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 2087 2088 // 2089 // Even though we are using TLS we still need to use an HTTP auth. 2090 // 2091 2092 int port = res.open(responseData.toByteArray()); 2093 2094 2095 JsseESTServiceBuilder builder = new JsseESTServiceBuilder( 2096 "localhost:" + port, JcaJceUtils.getCertPathTrustManager( 2097 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 2098 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 2099 )), null)).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 2100 2101 builder.addCipherSuites(res.getSupportedCipherSuites()); 2102 2103 2104 try 2105 { 2106 EnrollmentResponse resp = builder.build().simpleEnroll(false, csr, 2107 new HttpAuth( 2108 "estrealm", 2109 "estuser", 2110 "estpwd".toCharArray(), 2111 new SecureRandom(), 2112 new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) 2113 ); 2114 Assert.fail("Must throw exception."); 2115 } 2116 catch (Exception t) 2117 { 2118 Assert.assertEquals("Must be ESTException", t.getClass(), ESTException.class); 2119 Assert.assertTrue("", t.getMessage().contains("not Retry-After header")); 2120 } 2121 } 2122 catch (Exception ex) 2123 { 2124 ex.printStackTrace(); 2125 } 2126 finally 2127 { 2128 res.close(); 2129 } 2130 2131 res.getFinished().await(5, TimeUnit.SECONDS); 2132 2133 } 2134 2135 2136 @Test() testWithLabel()2137 public void testWithLabel() 2138 throws Exception 2139 { 2140 ESTTestUtils.ensureProvider(); 2141 final ByteArrayOutputStream responseData = new ByteArrayOutputStream(); 2142 2143 PrintWriter pw = new PrintWriter(responseData); 2144 pw.print("HTTP/1.1 202 Accepted\n" + 2145 "Status: 202 Accepted\n" + 2146 "Content-Length: 0\n\n"); 2147 pw.flush(); 2148 2149 // 2150 // Test content length enforcement. 2151 // Fail when content-length = read limit. 2152 // 2153 2154 ArrayList<String> lines = new ArrayList<String>(); 2155 2156 HttpResponder res = new HttpResponder(lines); 2157 try 2158 { 2159 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 2160 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 2161 kpg.initialize(ecGenSpec, new SecureRandom()); 2162 KeyPair enrollmentPair = kpg.generateKeyPair(); 2163 2164 2165 TrustAnchor ta = new TrustAnchor( 2166 ESTTestUtils.toJavaX509Certificate( 2167 ESTTestUtils.readPemCertificate( 2168 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 2169 ) 2170 ), null); 2171 2172 2173 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 2174 new X500Name("CN=Test"), 2175 enrollmentPair.getPublic()); 2176 2177 PKCS10CertificationRequest csr = pkcs10Builder.build( 2178 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 2179 2180 // 2181 // Even though we are using TLS we still need to use an HTTP auth. 2182 // 2183 2184 int port = res.open(responseData.toByteArray()); 2185 2186 2187 JsseESTServiceBuilder builder = new JsseESTServiceBuilder( 2188 "localhost:" + port , JcaJceUtils.getCertPathTrustManager( 2189 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificate( 2190 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 2191 )), null)).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS"); 2192 2193 builder.addCipherSuites(res.getSupportedCipherSuites()); 2194 builder.withLabel("the_label"); 2195 2196 /* 2197 We are only checking the use of the label. 2198 */ 2199 2200 2201 try 2202 { 2203 EnrollmentResponse resp = builder.build().simpleEnroll(false, csr, 2204 new HttpAuth( 2205 "estrealm", 2206 "estuser", 2207 "estpwd".toCharArray(), 2208 new SecureRandom(), 2209 new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) 2210 ); 2211 Assert.fail("Must throw exception."); 2212 } 2213 catch (Exception t) 2214 { 2215 // // Not tested here, tested elsewhere. 2216 } 2217 2218 Assert.assertTrue(lines.get(0).contains("/.well-known/est/the_label/simpleenroll")); 2219 2220 2221 } 2222 catch (Exception ex) 2223 { 2224 ex.printStackTrace(); 2225 } 2226 finally 2227 { 2228 res.close(); 2229 } 2230 2231 res.getFinished().await(5, TimeUnit.SECONDS); 2232 2233 } 2234 2235 2236 @Test testEnrollUsingBasicAuthWrongUsage()2237 public void testEnrollUsingBasicAuthWrongUsage() 2238 throws Exception 2239 { 2240 ESTTestUtils.ensureProvider(); 2241 X509CertificateHolder[] theirCAs = null; 2242 ESTServerUtils.ServerInstance serverInstance = null; 2243 2244 try 2245 { 2246 serverInstance = startDefaultServerTLSAndBasicAuthSpecial(0, false); 2247 2248 2249 ESTService est = new JsseESTServiceBuilder( 2250 "localhost:8443", JcaJceUtils.getCertPathTrustManager( 2251 ESTTestUtils.toTrustAnchor(ESTTestUtils.readPemCertificates( 2252 ESTServerUtils.makeRelativeToServerHome("/estCA/multicacerts.crt") 2253 )), null) 2254 ).withProvider(BouncyCastleJsseProvider.PROVIDER_NAME).withTLSVersion("TLS").build(); 2255 2256 2257 // 2258 // Make certificate request. 2259 // 2260 2261 ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1"); 2262 KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 2263 kpg.initialize(ecGenSpec, new SecureRandom()); 2264 KeyPair enrollmentPair = kpg.generateKeyPair(); 2265 2266 PKCS10CertificationRequestBuilder pkcs10Builder = new JcaPKCS10CertificationRequestBuilder( 2267 new X500Name("CN=Test"), 2268 enrollmentPair.getPublic()); 2269 2270 PKCS10CertificationRequest csr = pkcs10Builder.build( 2271 new JcaContentSignerBuilder("SHA256WITHECDSA").setProvider("BC").build(enrollmentPair.getPrivate())); 2272 2273 EnrollmentResponse enr = est.simpleEnroll(false, csr, 2274 new JcaHttpAuthBuilder("estreal", "estuser", "estpwd".toCharArray()) 2275 .setNonceGenerator(new SecureRandom()).setProvider("BC").build()); 2276 X509Certificate expectedCA = ESTTestUtils.toJavaX509Certificate(ESTTestUtils.readPemCertificate( 2277 ESTServerUtils.makeRelativeToServerHome("/estCA/cacert.crt") 2278 )); 2279 2280 X509CertificateHolder enrolledAsHolder = ESTService.storeToArray(enr.getStore())[0]; 2281 2282 X509Certificate enrolled = ESTTestUtils.toJavaX509Certificate(enrolledAsHolder); 2283 2284 // Will fail if it does not verify. 2285 enrolled.verify(expectedCA.getPublicKey(), "BC"); 2286 2287 2288 } catch (Throwable t) { 2289 // 2290 // Non-ideal for testing but the TLS library emits errors that can not accidentally be printed to 2291 // a web page and aid an attacker. 2292 // 2293 Assert.assertTrue(t.getMessage().toLowerCase().contains("certificate_unknown")); 2294 } 2295 finally 2296 { 2297 if (serverInstance != null) 2298 { 2299 serverInstance.getServer().stop_server(); 2300 } 2301 } 2302 } 2303 2304 2305 main(String[] args)2306 public static void main(String[] args) 2307 throws Exception 2308 { 2309 2310 //// Cipher c = Cipher.getInstance("AES/GCM/NoPadding"); 2311 //// 2312 //// c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(new byte[16], "AES"), new GCMParameterSpec(32, new byte[16])); 2313 // Security.addProvider(new BouncyCastleProvider()); 2314 // for (Iterator it = Security.getProvider("BC").getServices().iterator(); it.hasNext();) 2315 // { 2316 // Provider.Service s = (Provider.Service)it.next(); 2317 // 2318 // if (s.getAlgorithm().equals("AES")) 2319 // { 2320 // System.err.println(s.getAttribute("SupportedKeyFormats")); 2321 // } 2322 // } 2323 2324 ESTTestUtils.ensureProvider(); 2325 runTest(new TestEnroll()); 2326 } 2327 2328 } 2329