package at.gv.egiz.eaaf.core.test.http; import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.SocketTimeoutException; import java.security.Key; import java.security.KeyPair; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.Provider; import java.security.UnrecoverableKeyException; import java.security.cert.X509Certificate; import org.apache.commons.lang3.RandomStringUtils; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.entity.ContentType; import org.apache.http.impl.client.CloseableHttpClient; import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.annotation.DirtiesContext.MethodMode; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import at.gv.egiz.eaaf.core.exceptions.EaafException; import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory; import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration; import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType; import at.gv.egiz.eaaf.core.impl.data.Pair; import at.gv.egiz.eaaf.core.impl.data.Triple; import at.gv.egiz.eaaf.core.impl.http.HttpClientConfiguration; import at.gv.egiz.eaaf.core.impl.http.HttpUtils; import at.gv.egiz.eaaf.core.impl.http.IHttpClientFactory; import at.gv.egiz.eaaf.core.impl.utils.StreamUtils; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import okhttp3.HttpUrl; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import okhttp3.mockwebserver.SocketPolicy; import okhttp3.tls.HandshakeCertificates; import okhttp3.tls.HeldCertificate; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/spring/test_eaaf_pvp_not_lazy.beans.xml") @DirtiesContext(classMode = ClassMode.BEFORE_CLASS) public class HttpClientFactoryTest { @Autowired private EaafKeyStoreFactory keyStoreFactory; @Autowired private IHttpClientFactory httpClientFactory; private MockWebServer mockWebServer = null; private HttpUrl mockServerUrl; /** * Initialize full class. */ @BeforeClass public static void classInitializer() { final Logger logger = (Logger) LoggerFactory.getLogger("org.bouncycastle.jsse"); logger.setLevel(Level.TRACE); } /** * Reset test environment. */ @AfterClass public static void classReset() { System.clearProperty("javax.net.ssl.trustStoreType"); System.clearProperty("javax.net.ssl.trustStore"); System.clearProperty("javax.net.ssl.trustStorePassword"); } /** * JUnit test set-up. * */ @Before public void setup() { } /** * jUnit test shutdown. * * @throws IOException In case of an mockWebServer error */ @After public void shutdown() throws IOException { if (mockWebServer != null) { mockWebServer.shutdown(); mockWebServer = null; } } @Test public void getDefaultClient() { final CloseableHttpClient client = httpClientFactory.getHttpClient(); Assert.assertNotNull("httpClient", client); } @Test public void getDefaultClientNoRedirect() { final CloseableHttpClient client = httpClientFactory.getHttpClient(false); Assert.assertNotNull("httpClient", client); } @Test public void defaultHttpClientRetryOneTime() throws EaafException, InterruptedException, ClientProtocolException, IOException { final CloseableHttpClient client = httpClientFactory.getHttpClient(); Assert.assertNotNull("No httpClient", client); mockWebServer = new MockWebServer(); mockServerUrl = mockWebServer.url("/sp/junit"); mockWebServer.enqueue(new MockResponse() .setSocketPolicy(SocketPolicy.NO_RESPONSE) .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)); mockWebServer.enqueue(new MockResponse().setResponseCode(200) .setBody("GetData")); //request webservice final HttpUriRequest httpGet1 = new HttpGet(mockServerUrl.url().toString()); final CloseableHttpResponse httpResp1 = client.execute(httpGet1); Assert.assertEquals("http statusCode", 200, httpResp1.getStatusLine().getStatusCode()); } @Test public void getCustomClientsDefault() throws EaafException { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); Assert.assertFalse("Wrong default config - Hostnamevalidation", config.isDisableHostnameValidation()); Assert.assertFalse("Wrong default config - TLS Server-certs", config.isDisableTlsHostCertificateValidation()); final CloseableHttpClient client1 = httpClientFactory.getHttpClient(config); Assert.assertNotNull("first http client", client1); final CloseableHttpClient client2 = httpClientFactory.getHttpClient(config); Assert.assertNotNull("second http client", client2); } @Test public void getCustomClientUnknownAuthMethod() throws EaafException { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); config.setAuthMode(RandomStringUtils.randomAlphabetic(5)); final CloseableHttpClient client = httpClientFactory.getHttpClient(config); Assert.assertNotNull("httpClient", client); } @Test public void getCustomClientBasicAuth() throws EaafException, ClientProtocolException, IOException, InterruptedException { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); config.setEnablePreEmptiveHttpBasicAuth(false); config.setAuthMode("password"); config.setUsername("jUnit"); config.setPassword("password"); final CloseableHttpClient client = httpClientFactory.getHttpClient(config); Assert.assertNotNull("httpClient", client); //setup test webserver that requestes http Basic authentication mockWebServer = new MockWebServer(); mockServerUrl = mockWebServer.url("/sp/junit"); mockWebServer.enqueue(new MockResponse() .setResponseCode(HttpURLConnection.HTTP_UNAUTHORIZED) .addHeader("www-authenticate: Basic realm=\"protected area\"") .setBody("Please authenticate.")); mockWebServer.enqueue(new MockResponse().setResponseCode(200) .setBody("Successful auth!")); //request webservice final HttpUriRequest httpGet2 = new HttpGet(mockServerUrl.url().toString()); final CloseableHttpResponse httpResp2 = client.execute(httpGet2); Assert.assertEquals("http statusCode", 200, httpResp2.getStatusLine().getStatusCode()); //check request contains basic authentication after authentication was requested final RecordedRequest httpReq1 = mockWebServer.takeRequest(); final RecordedRequest httpReq2 = mockWebServer.takeRequest(); Assert.assertNull("wrong BasicAuthHeader", httpReq1.getHeader("Authorization")); Assert.assertNotNull("missing BasicAuthHeader", httpReq2.getHeader("Authorization")); assertEquals("Basic alVuaXQ6cGFzc3dvcmQ=", httpReq2.getHeader("Authorization"), "wrong authHeader"); } @Test public void getCustomClientBasicAuthWithPreEmptive() throws EaafException, ClientProtocolException, IOException, InterruptedException { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); config.setAuthMode("password"); config.setUsername("jUnit"); config.setPassword("password"); final CloseableHttpClient client = httpClientFactory.getHttpClient(config); Assert.assertNotNull("httpClient", client); //setup test webserver that requestes http Basic authentication mockWebServer = new MockWebServer(); mockServerUrl = mockWebServer.url("/sp/junit"); mockWebServer.enqueue(new MockResponse().setResponseCode(200) .setBody("Successful auth!")); //request webservice final HttpUriRequest httpGet2 = new HttpGet(mockServerUrl.url().toString()); final CloseableHttpResponse httpResp2 = client.execute(httpGet2); Assert.assertEquals("http statusCode", 200, httpResp2.getStatusLine().getStatusCode()); //check request contains basic authentication after authentication was requested final RecordedRequest httpReq1 = mockWebServer.takeRequest(); Assert.assertNotNull("missing BasicAuthHeader", httpReq1.getHeader("Authorization")); assertEquals("Basic alVuaXQ6cGFzc3dvcmQ=", httpReq1.getHeader("Authorization"), "wrong authHeader"); } @Test public void getCustomClientBasicAuthNoUsername() { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); config.setAuthMode("password"); try { httpClientFactory.getHttpClient(config); Assert.fail("Wrong config not detected"); } catch (final EaafException e) { Assert.assertEquals("Wrong errorCode", "internal.httpclient.00", e.getErrorId()); } } @Test public void httpPostRetryNotAllowed() throws EaafException, InterruptedException, ClientProtocolException, IOException { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit_retry_" + RandomStringUtils.randomAlphabetic(3)); config.setHttpErrorRetryCount(2); config.setHttpErrorRetryPost(false); final CloseableHttpClient client = httpClientFactory.getHttpClient(config); Assert.assertNotNull("No httpClient", client); mockWebServer = new MockWebServer(); mockServerUrl = mockWebServer.url("/sp/junit"); mockWebServer.enqueue(new MockResponse() .setSocketPolicy(SocketPolicy.NO_RESPONSE) .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)); mockWebServer.enqueue(new MockResponse().setResponseCode(200) .setBody("GetData")); //request webservice final HttpUriRequest httpGet1 = new HttpPost(mockServerUrl.url().toString()); try { client.execute(httpGet1); Assert.fail("HTTP POST retry not allowed"); } catch (final SocketTimeoutException e) { Assert.assertNotNull("No errorMsg", e.getMessage()); } } @Test public void httpPostRetryOneTime() throws EaafException, InterruptedException, ClientProtocolException, IOException { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit_retry_" + RandomStringUtils.randomAlphabetic(3)); config.setHttpErrorRetryCount(2); config.setHttpErrorRetryPost(true); final CloseableHttpClient client = httpClientFactory.getHttpClient(config); Assert.assertNotNull("No httpClient", client); mockWebServer = new MockWebServer(); mockServerUrl = mockWebServer.url("/sp/junit"); mockWebServer.enqueue(new MockResponse() .setSocketPolicy(SocketPolicy.NO_RESPONSE) .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)); mockWebServer.enqueue(new MockResponse().setResponseCode(200) .setBody("GetData")); //request webservice final HttpUriRequest httpGet1 = new HttpPost(mockServerUrl.url().toString()); final StatusLine httpResp1 = client.execute(httpGet1, HttpUtils.simpleStatusCodeResponseHandler()); Assert.assertEquals("http statusCode", 200, httpResp1.getStatusCode()); } @Test public void testHttpClientRetryOneTime() throws EaafException, InterruptedException, ClientProtocolException, IOException { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit_retry_" + RandomStringUtils.randomAlphabetic(3)); config.setHttpErrorRetryCount(2); final CloseableHttpClient client = httpClientFactory.getHttpClient(config); Assert.assertNotNull("No httpClient", client); mockWebServer = new MockWebServer(); mockServerUrl = mockWebServer.url("/sp/junit"); mockWebServer.enqueue(new MockResponse() .setSocketPolicy(SocketPolicy.NO_RESPONSE) .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)); String bodyData = RandomStringUtils.randomAlphanumeric(10); mockWebServer.enqueue(new MockResponse().setResponseCode(200) .setBody(bodyData)); //request webservice final HttpUriRequest httpGet1 = new HttpGet(mockServerUrl.url().toString()); final Triple httpResp1 = client.execute(httpGet1, HttpUtils.bodyStatusCodeResponseHandler()); Assert.assertEquals("http statusCode", 200, httpResp1.getFirst().getStatusCode()); Assert.assertEquals("http statusCode", bodyData, new String(StreamUtils.readStream(httpResp1.getSecond()))); } @Test public void testHttpClientRetryTwoTime() throws EaafException, InterruptedException, ClientProtocolException, IOException { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit_retry_" + RandomStringUtils.randomAlphabetic(3)); config.setHttpErrorRetryCount(2); final CloseableHttpClient client = httpClientFactory.getHttpClient(config); Assert.assertNotNull("No httpClient", client); mockWebServer = new MockWebServer(); mockServerUrl = mockWebServer.url("/sp/junit"); mockWebServer.enqueue(new MockResponse() .setSocketPolicy(SocketPolicy.NO_RESPONSE) .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)); mockWebServer.enqueue(new MockResponse() .setSocketPolicy(SocketPolicy.NO_RESPONSE) .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)); mockWebServer.enqueue(new MockResponse().setResponseCode(200) .setBody("GetData")); //request webservice final HttpUriRequest httpGet1 = new HttpGet(mockServerUrl.url().toString()); final CloseableHttpResponse httpResp1 = client.execute(httpGet1); Assert.assertEquals("http statusCode", 200, httpResp1.getStatusLine().getStatusCode()); } @Test public void testHttpClientRetryMaxReached() throws EaafException, InterruptedException, ClientProtocolException, IOException { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit_retry_" + RandomStringUtils.randomAlphabetic(3)); config.setHttpErrorRetryCount(2); final CloseableHttpClient client = httpClientFactory.getHttpClient(config); Assert.assertNotNull("No httpClient", client); mockWebServer = new MockWebServer(); mockServerUrl = mockWebServer.url("/sp/junit"); mockWebServer.enqueue(new MockResponse() .setSocketPolicy(SocketPolicy.NO_RESPONSE) .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)); mockWebServer.enqueue(new MockResponse() .setSocketPolicy(SocketPolicy.NO_RESPONSE) .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)); mockWebServer.enqueue(new MockResponse() .setSocketPolicy(SocketPolicy.NO_RESPONSE) .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)); mockWebServer.enqueue(new MockResponse().setResponseCode(200) .setBody("GetData")); //request webservice final HttpUriRequest httpGet1 = new HttpGet(mockServerUrl.url().toString()); try { client.execute(httpGet1); Assert.fail("Max retry failed"); } catch (final SocketTimeoutException e) { Assert.assertNotNull("No errorMsg", e.getMessage()); } } @Test public void testHttpClientNoRetry() throws EaafException, InterruptedException, ClientProtocolException, IOException { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit_retry_" + RandomStringUtils.randomAlphabetic(3)); config.setHttpErrorRetryCount(0); final CloseableHttpClient client = httpClientFactory.getHttpClient(config); Assert.assertNotNull("No httpClient", client); mockWebServer = new MockWebServer(); mockServerUrl = mockWebServer.url("/sp/junit"); mockWebServer.enqueue(new MockResponse() .setSocketPolicy(SocketPolicy.NO_RESPONSE) .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)); mockWebServer.enqueue(new MockResponse().setResponseCode(200) .setBody("GetData")); //request webservice final HttpUriRequest httpGet1 = new HttpGet(mockServerUrl.url().toString()); try { client.execute(httpGet1); Assert.fail("Max retry failed"); } catch (final SocketTimeoutException e) { Assert.assertNotNull("No errorMsg", e.getMessage()); } } @Test public void getCustomClientBasicAuthNoPassword() throws EaafException { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); config.setAuthMode("password"); config.setUsername(RandomStringUtils.randomAlphabetic(5)); final CloseableHttpClient client = httpClientFactory.getHttpClient(config); Assert.assertNotNull("httpClient", client); } @Test public void getCustomClientX509AuthNoKeyStoreConfig() { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); config.setAuthMode("ssl"); try { httpClientFactory.getHttpClient(config); Assert.fail("Wrong config not detected"); } catch (final EaafException e) { Assert.assertEquals("Wrong errorCode", "internal.httpclient.01", e.getErrorId()); } } @Test public void getCustomClientX509AuthNoKeyPassword() throws EaafException { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); config.setAuthMode("ssl"); config.buildKeyStoreConfig( "jks", "src/test/resources/data/junit.jks", "password", null); try { httpClientFactory.getHttpClient(config); Assert.fail("Wrong config not detected"); } catch (final EaafException e) { Assert.assertEquals("Wrong errorCode", "internal.httpclient.02", e.getErrorId()); } } @Test public void getCustomClientX509Auth() throws EaafException { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); config.setAuthMode("ssl"); config.buildKeyStoreConfig( "jks", "src/test/resources/data/junit.jks", "password", null); config.setSslKeyPassword("password"); final CloseableHttpClient client = httpClientFactory.getHttpClient(config); Assert.assertNotNull("httpClient", client); } @Test public void getCustomClientX509AuthWithAlias() throws EaafException, ClientProtocolException, IOException, KeyStoreException { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); config.setAuthMode("ssl"); config.buildKeyStoreConfig( "jks", "src/test/resources/data/junit.jks", "password", null); config.setSslKeyPassword("password"); config.setSslKeyAlias("sig"); config.setDisableTlsHostCertificateValidation(true); final CloseableHttpClient client = httpClientFactory.getHttpClient(config); Assert.assertNotNull("httpClient", client); //set-up mock-up web-server with SSL client authentication final Pair sslClientKeyStore = keyStoreFactory.buildNewKeyStore(config.getKeyStoreConfig()); final String localhost = InetAddress.getByName("localhost").getCanonicalHostName(); final HeldCertificate localhostCertificate = new HeldCertificate.Builder() .addSubjectAlternativeName(localhost) .build(); final HandshakeCertificates serverCertificates = new HandshakeCertificates.Builder() .addTrustedCertificate( (X509Certificate) sslClientKeyStore.getFirst().getCertificate(config.getSslKeyAlias())) .heldCertificate(localhostCertificate) .build(); mockWebServer = new MockWebServer(); mockWebServer.useHttps(serverCertificates.sslSocketFactory(), false); mockWebServer.requireClientAuth(); mockWebServer.enqueue(new MockResponse().setResponseCode(200) .setBody("Successful auth!")); mockServerUrl = mockWebServer.url("/sp/junit"); //perform test request final HttpUriRequest httpGet2 = new HttpGet(mockServerUrl.url().toString()); final CloseableHttpResponse httpResp2 = client.execute(httpGet2); Assert.assertEquals("http statusCode", 200, httpResp2.getStatusLine().getStatusCode()); } @Test public void getCustomClientX509AuthWrongKeyPassword() throws EaafException { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); config.setAuthMode("ssl"); config.buildKeyStoreConfig( "jks", "src/test/resources/data/junit.jks", "password", null); config.setSslKeyPassword(RandomStringUtils.randomAlphanumeric(5)); config.setSslKeyAlias("sig"); try { httpClientFactory.getHttpClient(config); Assert.fail("Wrong key password not detected"); } catch (final EaafException e) { Assert.assertEquals("Wrong errorCode", "internal.httpclient.03", e.getErrorId()); } } @Test public void getCustomClientX509AuthWithWrongAlias() throws EaafException, KeyStoreException, ClientProtocolException, IOException { final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); config.setAuthMode("ssl"); config.buildKeyStoreConfig( "jks", "src/test/resources/data/junit.jks", "password", null); config.setSslKeyPassword("password"); config.setSslKeyAlias(RandomStringUtils.randomAlphabetic(5)); config.setDisableHostnameValidation(true); config.setFollowHttpRedirects(false); config.setDisableTlsHostCertificateValidation(true); final CloseableHttpClient client = httpClientFactory.getHttpClient(config); Assert.assertNotNull("httpClient", client); //set-up mock-up web-server with SSL client authentication final Pair sslClientKeyStore = keyStoreFactory.buildNewKeyStore(config.getKeyStoreConfig()); final String localhost = InetAddress.getByName("localhost").getCanonicalHostName(); final HeldCertificate localhostCertificate = new HeldCertificate.Builder() .addSubjectAlternativeName(localhost) .build(); final HandshakeCertificates serverCertificates = new HandshakeCertificates.Builder() .addTrustedCertificate( (X509Certificate) sslClientKeyStore.getFirst().getCertificate("meta")) .addTrustedCertificate( (X509Certificate) sslClientKeyStore.getFirst().getCertificate("sig")) .heldCertificate(localhostCertificate) .build(); mockWebServer = new MockWebServer(); mockWebServer.useHttps(serverCertificates.sslSocketFactory(), false); mockWebServer.requireClientAuth(); mockWebServer.enqueue(new MockResponse().setResponseCode(200) .setBody("Successful auth!")); mockServerUrl = mockWebServer.url("/sp/junit"); //perform test request final HttpUriRequest httpGet2 = new HttpGet(mockServerUrl.url().toString()); final CloseableHttpResponse httpResp2 = client.execute(httpGet2); Assert.assertEquals("http statusCode", 200, httpResp2.getStatusLine().getStatusCode()); } @Test @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD) public void getCustomClientX509AuthWithHsmFacade() throws EaafException, ClientProtocolException, IOException, KeyStoreException { final HttpClientConfiguration clientConfig = new HttpClientConfiguration("jUnit-client"); clientConfig.setAuthMode("ssl"); clientConfig.buildKeyStoreConfig("hsmfacade", null, null, "authhandler"); clientConfig.setSslKeyAlias("authhandler-sign"); clientConfig.setDisableTlsHostCertificateValidation(true); final CloseableHttpClient client = httpClientFactory.getHttpClient(clientConfig); Assert.assertNotNull("httpClient", client); //set-up mock-up web-server with SSL client authentication final Pair sslClientKeyStore = keyStoreFactory.buildNewKeyStore(clientConfig.getKeyStoreConfig()); final X509Certificate clientRootCert = (X509Certificate) sslClientKeyStore.getFirst() .getCertificateChain(clientConfig.getSslKeyAlias())[1]; final X509Certificate clientEeCert = (X509Certificate) sslClientKeyStore.getFirst() .getCertificateChain(clientConfig.getSslKeyAlias())[0]; final String localhost = InetAddress.getByName("localhost").getCanonicalHostName(); final HeldCertificate localhostCertificate = new HeldCertificate.Builder() .addSubjectAlternativeName(localhost) .build(); final HandshakeCertificates serverCertificates = new HandshakeCertificates.Builder() .addTrustedCertificate(clientEeCert) .addTrustedCertificate(clientRootCert) .heldCertificate(localhostCertificate) .build(); mockWebServer = new MockWebServer(); mockWebServer.useHttps(serverCertificates.sslSocketFactory(), false); mockWebServer.requireClientAuth(); mockWebServer.enqueue(new MockResponse().setResponseCode(200) .setBody("Successful auth!")); mockServerUrl = mockWebServer.url("/sp/junit"); //perform test request final HttpUriRequest httpGet2 = new HttpGet(mockServerUrl.url().toString()); final CloseableHttpResponse httpResp2 = client.execute(httpGet2); Assert.assertEquals("http statusCode", 200, httpResp2.getStatusLine().getStatusCode()); } @Test @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD) public void getCustomClientX509AuthWithHsmFacadeTrustStore() throws EaafException, ClientProtocolException, IOException, KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException { final String current = new java.io.File(".").getCanonicalPath(); System.setProperty("javax.net.ssl.trustStoreType", "jks"); System.setProperty("javax.net.ssl.trustStore", current + "/src/test/resources/data/ssL_truststore.jks"); System.setProperty("javax.net.ssl.trustStorePassword", "password"); final KeyStoreConfiguration sslServerCertConfig = new KeyStoreConfiguration(); sslServerCertConfig.setKeyStoreType(KeyStoreType.JKS); sslServerCertConfig.setFriendlyName("SSL host cert"); sslServerCertConfig.setSoftKeyStoreFilePath("src/test/resources/data/ssl_host.jks"); sslServerCertConfig.setSoftKeyStorePassword("password"); Pair sslServerHostKeyStore = keyStoreFactory.buildNewKeyStore(sslServerCertConfig); final HttpClientConfiguration clientConfig = new HttpClientConfiguration("jUnit-client"); clientConfig.setAuthMode("ssl"); clientConfig.buildKeyStoreConfig("hsmfacade", null, null, "authhandler"); clientConfig.setSslKeyAlias("authhandler-sign"); clientConfig.setDisableTlsHostCertificateValidation(false); final CloseableHttpClient client = httpClientFactory.getHttpClient(clientConfig); Assert.assertNotNull("httpClient", client); //set-up mock-up web-server with SSL client authentication final Pair sslClientKeyStore = keyStoreFactory.buildNewKeyStore(clientConfig.getKeyStoreConfig()); final X509Certificate clientRootCert = (X509Certificate) sslClientKeyStore.getFirst() .getCertificateChain(clientConfig.getSslKeyAlias())[1]; final X509Certificate clientEeCert = (X509Certificate) sslClientKeyStore.getFirst() .getCertificateChain(clientConfig.getSslKeyAlias())[0]; Key sslKey = sslServerHostKeyStore.getFirst().getKey("ssl", "password".toCharArray()); X509Certificate sslCert = (X509Certificate) sslServerHostKeyStore.getFirst().getCertificate("ssl"); KeyPair keyPair = new KeyPair(sslCert.getPublicKey(), (PrivateKey) sslKey); HeldCertificate localhostCertificate = new HeldCertificate(keyPair, sslCert); final HandshakeCertificates serverCertificates = new HandshakeCertificates.Builder() .addTrustedCertificate(clientEeCert) .addTrustedCertificate(clientRootCert) .heldCertificate(localhostCertificate) .build(); mockWebServer = new MockWebServer(); mockWebServer.useHttps(serverCertificates.sslSocketFactory(), false); mockWebServer.requireClientAuth(); mockWebServer.enqueue(new MockResponse().setResponseCode(200) .setBody("Successful auth!")); mockServerUrl = mockWebServer.url("/sp/junit"); //perform test request final HttpUriRequest httpGet2 = new HttpGet(mockServerUrl.url().toString()); final CloseableHttpResponse httpResp2 = client.execute(httpGet2); Assert.assertEquals("http statusCode", 200, httpResp2.getStatusLine().getStatusCode()); } }