You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by re...@apache.org on 2022/03/19 20:34:18 UTC
[cxf] branch 3.5.x-fixes updated: Custom certificate alias not being used when using HC5 AsyncHTTPConduit (#923)
This is an automated email from the ASF dual-hosted git repository.
reta pushed a commit to branch 3.5.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/3.5.x-fixes by this push:
new c6c02b9 Custom certificate alias not being used when using HC5 AsyncHTTPConduit (#923)
c6c02b9 is described below
commit c6c02b90786b6f97c5f600903c2517fd6db50e70
Author: Andriy Redko <dr...@gmail.com>
AuthorDate: Sat Mar 19 13:15:57 2022 -0400
Custom certificate alias not being used when using HC5 AsyncHTTPConduit (#923)
(cherry picked from commit be345311ffa68bc5138d7bc56d074534d9c5dd35)
---
.../http/asyncclient/hc5/AsyncHTTPConduit.java | 66 ++-
.../asyncclient/hc5/AsyncHTTPConduitFactory.java | 122 +++--
systests/transport-hc5/pom.xml | 10 +
.../org/apache/cxf/systest/hc5/GreeterImpl.java | 65 +++
.../hc5/https/clientauth/ClientAuthServer.java | 47 ++
.../hc5/https/clientauth/ClientAuthTest.java | 587 +++++++++++++++++++++
.../HostnameVerificationDeprecatedServer.java | 47 ++
.../HostnameVerificationDeprecatedTest.java | 320 +++++++++++
.../https/hostname/HostnameVerificationServer.java | 47 ++
.../https/hostname/HostnameVerificationTest.java | 369 +++++++++++++
.../systest/hc5/https/trust/TrustManagerTest.java | 474 +++++++++++++++++
.../cxf/systest/hc5/https/trust/TrustServer.java | 47 ++
.../hc5/https/trust/TrustServerNoSpring.java | 84 +++
.../src/test/resources/keymanagers.jks | Bin 0 -> 5385 bytes
.../hc5/https/clientauth/client-auth-chain.xml | 44 ++
.../hc5/https/clientauth/client-auth-invalid.xml | 43 ++
.../hc5/https/clientauth/client-auth-invalid2.xml | 43 ++
.../hc5/https/clientauth/client-auth-server.xml | 80 +++
.../systest/hc5/https/clientauth/client-auth.xml | 44 ++
.../hc5/https/clientauth/client-no-auth.xml | 40 ++
.../https/hostname/hostname-client-disablecn.xml | 41 ++
.../https/hostname/hostname-client-usedefault.xml | 41 ++
.../systest/hc5/https/hostname/hostname-client.xml | 41 ++
.../https/hostname/hostname-server-deprecated.xml | 95 ++++
.../systest/hc5/https/hostname/hostname-server.xml | 137 +++++
.../hc5/https/trust/client-trust-config.xml | 39 ++
.../hc5/https/trust/client-trust-empty-config.xml | 43 ++
.../hc5/https/trust/client-trust-manager-ref.xml | 42 ++
.../cxf/systest/hc5/https/trust/client-trust.xml | 35 ++
.../cxf/systest/hc5/https/trust/trust-server.xml | 72 +++
30 files changed, 3099 insertions(+), 66 deletions(-)
diff --git a/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AsyncHTTPConduit.java b/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AsyncHTTPConduit.java
index d6195c6..3802db7 100644
--- a/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AsyncHTTPConduit.java
+++ b/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AsyncHTTPConduit.java
@@ -85,7 +85,6 @@ import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.config.Registry;
-import org.apache.hc.core5.http.config.RegistryBuilder;
import org.apache.hc.core5.http.nio.ssl.BasicClientTlsStrategy;
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
import org.apache.hc.core5.http.protocol.HttpContext;
@@ -115,9 +114,11 @@ public class AsyncHTTPConduit extends URLConnectionHTTPConduit {
this.factory = factory;
}
- public synchronized CloseableHttpAsyncClient getHttpAsyncClient() throws IOException {
+ public synchronized CloseableHttpAsyncClient getHttpAsyncClient(final TlsStrategy tlsStrategy)
+ throws IOException {
+
if (client == null) {
- client = factory.createClient(this);
+ client = factory.createClient(this, tlsStrategy);
}
if (client == null) {
throw new IOException("HttpAsyncClient is null");
@@ -523,9 +524,9 @@ public class AsyncHTTPConduit extends URLConnectionHTTPConduit {
ctx.setCredentialsProvider(credsProvider);
+ TlsStrategy tlsStrategy = null;
if ("https".equals(url.getScheme())) {
try {
- RegistryBuilder<TlsStrategy> regBuilder = RegistryBuilder.<TlsStrategy>create();
// check tlsClientParameters from message header
TLSClientParameters tlsClientParameters = outMessage.get(TLSClientParameters.class);
@@ -538,31 +539,28 @@ public class AsyncHTTPConduit extends URLConnectionHTTPConduit {
final SSLContext sslcontext = getSSLContext(tlsClientParameters);
final HostnameVerifier verifier = org.apache.cxf.transport.https.SSLUtils
.getHostnameVerifier(tlsClientParameters);
- regBuilder
- .register("https",
- new BasicClientTlsStrategy(
- sslcontext,
- new SSLSessionInitializer() {
- @Override
- public void initialize(NamedEndpoint endpoint, SSLEngine engine) {
- initializeSSLEngine(sslcontext, engine);
- }
- },
- new SSLSessionVerifier() {
- @Override
- public TlsDetails verify(NamedEndpoint endpoint, SSLEngine engine)
- throws SSLException {
- final SSLSession sslsession = engine.getSession();
-
- if (!verifier.verify(endpoint.getHostName(), sslsession)) {
- throw new SSLException("Could not verify host " + endpoint.getHostName());
- }
-
- setSSLSession(sslsession);
- return new TlsDetails(sslsession, engine.getApplicationProtocol());
- }
+
+ tlsStrategy = new BasicClientTlsStrategy(sslcontext,
+ new SSLSessionInitializer() {
+ @Override
+ public void initialize(NamedEndpoint endpoint, SSLEngine engine) {
+ initializeSSLEngine(sslcontext, engine);
+ }
+ },
+ new SSLSessionVerifier() {
+ @Override
+ public TlsDetails verify(NamedEndpoint endpoint, SSLEngine engine)
+ throws SSLException {
+ final SSLSession sslsession = engine.getSession();
+
+ if (!verifier.verify(endpoint.getHostName(), sslsession)) {
+ throw new SSLException("Could not verify host " + endpoint.getHostName());
}
- )
+
+ setSSLSession(sslsession);
+ return new TlsDetails(sslsession, engine.getApplicationProtocol());
+ }
+ }
);
} catch (final GeneralSecurityException e) {
LOG.warning(e.getMessage());
@@ -580,7 +578,9 @@ public class AsyncHTTPConduit extends URLConnectionHTTPConduit {
}
connectionFuture = new BasicFuture<>(callback);
- final HttpAsyncClient c = getHttpAsyncClient();
+ // The HttpClientContext is not available in the AsyncClientConnectionOperator, so we have
+ // to provide our own TLS strategy on construction.
+ final HttpAsyncClient c = getHttpAsyncClient(tlsStrategy);
final Credentials creds = (Credentials)outMessage.getContextualProperty(Credentials.class.getName());
if (creds != null) {
credsProvider.setCredentials(new AnyAuthScope(), creds);
@@ -960,6 +960,14 @@ public class AsyncHTTPConduit extends URLConnectionHTTPConduit {
sslengine.setEnabledProtocols(p);
}
}
+
+ @Override
+ public void close() {
+ super.close();
+ if (factory != null) {
+ factory.close(this.getClient());
+ }
+ }
private String[] findProtocols(String p, String[] options) {
List<String> list = new ArrayList<>();
diff --git a/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AsyncHTTPConduitFactory.java b/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AsyncHTTPConduitFactory.java
index 1594d1a..f660288 100644
--- a/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AsyncHTTPConduitFactory.java
+++ b/rt/transports/http-hc5/src/main/java/org/apache/cxf/transport/http/asyncclient/hc5/AsyncHTTPConduitFactory.java
@@ -22,11 +22,14 @@ package org.apache.cxf.transport.http.asyncclient.hc5;
import java.io.IOException;
import java.net.URI;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
import org.apache.cxf.Bus;
import org.apache.cxf.buslifecycle.BusLifeCycleListener;
import org.apache.cxf.buslifecycle.BusLifeCycleManager;
import org.apache.cxf.common.injection.NoJSR250Annotations;
+import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.SystemPropertyAction;
import org.apache.cxf.service.model.EndpointInfo;
import org.apache.cxf.transport.http.HTTPConduit;
@@ -47,7 +50,7 @@ import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.ProtocolException;
-import org.apache.hc.core5.http.config.Registry;
+import org.apache.hc.core5.http.config.Lookup;
import org.apache.hc.core5.http.config.RegistryBuilder;
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
import org.apache.hc.core5.http.protocol.HttpContext;
@@ -63,7 +66,6 @@ import org.apache.hc.core5.util.Timeout;
*/
@NoJSR250Annotations
public class AsyncHTTPConduitFactory implements HTTPConduitFactory {
-
//TCP related properties
public static final String TCP_NODELAY = "org.apache.cxf.transport.http.async.TCP_NODELAY";
public static final String SO_KEEPALIVE = "org.apache.cxf.transport.http.async.SO_KEEPALIVE";
@@ -84,6 +86,7 @@ public class AsyncHTTPConduitFactory implements HTTPConduitFactory {
//CXF specific
public static final String USE_POLICY = "org.apache.cxf.transport.http.async.usePolicy";
+ private static final Logger LOG = LogUtils.getL7dLogger(AsyncHTTPConduitFactory.class);
public enum UseAsyncPolicy {
ALWAYS, ASYNC_ONLY, NEVER;
@@ -109,9 +112,31 @@ public class AsyncHTTPConduitFactory implements HTTPConduitFactory {
return ASYNC_ONLY;
}
};
+
+ /**
+ * See please https://issues.apache.org/jira/browse/CXF-8678 and
+ * https://issues.apache.org/jira/browse/HTTPCLIENT-2209, the context propagation
+ * is necessary to remove per-HTTPClientPolicy caching.
+ */
+ private static class AsyncClient {
+ private final PoolingAsyncClientConnectionManager connectionManager;
+ private final CloseableHttpAsyncClient client;
+
+ AsyncClient(PoolingAsyncClientConnectionManager connectionManager, CloseableHttpAsyncClient client) {
+ this.connectionManager = connectionManager;
+ this.client = client;
+ }
+
+ public CloseableHttpAsyncClient getClient() {
+ return client;
+ }
+
+ public PoolingAsyncClientConnectionManager getConnectionManager() {
+ return connectionManager;
+ }
+ }
- private volatile PoolingAsyncClientConnectionManager connectionManager;
- private volatile CloseableHttpAsyncClient client;
+ private volatile Map<HTTPClientPolicy, AsyncClient> clients = new ConcurrentHashMap<>();
private boolean isShutdown;
private UseAsyncPolicy policy;
@@ -147,19 +172,15 @@ public class AsyncHTTPConduitFactory implements HTTPConduitFactory {
}
public void update(Map<String, Object> props) {
- if (setProperties(props) && client != null) {
+ if (setProperties(props) && !clients.isEmpty()) {
restartReactor();
}
}
private void restartReactor() {
- CloseableHttpAsyncClient client2 = client;
- resetVars();
- shutdown(client2);
- }
- private synchronized void resetVars() {
- client = null;
- connectionManager = null;
+ final Map<HTTPClientPolicy, AsyncClient> clients2 = clients;
+ clients = new ConcurrentHashMap<>();
+ shutdown(clients2);
}
private boolean setProperties(Map<String, Object> s) {
@@ -178,9 +199,12 @@ public class AsyncHTTPConduitFactory implements HTTPConduitFactory {
connectionMaxIdle = getInt(s.get(CONNECTION_MAX_IDLE), connectionMaxIdle);
maxPerRoute = getInt(s.get(MAX_PER_HOST_CONNECTIONS), maxPerRoute);
- if (connectionManager != null) {
- connectionManager.setMaxTotal(maxConnections);
- connectionManager.setDefaultMaxPerRoute(maxPerRoute);
+ if (!clients.isEmpty()) {
+ for (Map.Entry<HTTPClientPolicy, AsyncClient> entry: clients.entrySet()) {
+ final PoolingAsyncClientConnectionManager connectionManager = entry.getValue().getConnectionManager();
+ connectionManager.setMaxTotal(maxConnections);
+ connectionManager.setDefaultMaxPerRoute(maxPerRoute);
+ }
}
//properties that need a restart of the reactor
@@ -254,23 +278,28 @@ public class AsyncHTTPConduitFactory implements HTTPConduitFactory {
}
public void shutdown() {
- if (client != null) {
- shutdown(client);
- connectionManager = null;
- client = null;
- }
+ shutdown(clients);
+ clients.clear();
isShutdown = true;
}
+ private static void shutdown(Map<HTTPClientPolicy, AsyncClient> clients) {
+ if (!clients.isEmpty()) {
+ for (Map.Entry<HTTPClientPolicy, AsyncClient> entry: clients.entrySet()) {
+ shutdown(entry.getValue().getClient());
+ entry.getValue().getConnectionManager().close();
+ }
+ }
+ }
+
private static void shutdown(CloseableHttpAsyncClient client) {
try {
client.close();
- } catch (IOException e1) {
- e1.printStackTrace();
+ } catch (IOException ex) {
+ LOG.warning(ex.getMessage());
}
}
-
private void addListener(Bus b) {
BusLifeCycleManager manager = b.getExtension(BusLifeCycleManager.class);
if (manager != null) {
@@ -286,11 +315,17 @@ public class AsyncHTTPConduitFactory implements HTTPConduitFactory {
}
}
- public synchronized void setupNIOClient(HTTPClientPolicy clientPolicy) {
+ public synchronized void setupNIOClient(HTTPClientPolicy clientPolicy, final TlsStrategy tlsStrategy) {
+ final AsyncClient client = clients.get(clientPolicy);
+
if (client != null) {
return;
}
-
+
+ clients.computeIfAbsent(clientPolicy, key -> createNIOClient(key, tlsStrategy));
+ }
+
+ private AsyncClient createNIOClient(HTTPClientPolicy clientPolicy, final TlsStrategy tlsStrategy) {
final IOReactorConfig config = IOReactorConfig.custom()
.setIoThreadCount(ioThreadCount)
.setSelectInterval(TimeValue.ofMilliseconds(selectInterval))
@@ -300,12 +335,13 @@ public class AsyncHTTPConduitFactory implements HTTPConduitFactory {
.setTcpNoDelay(tcpNoDelay)
.build();
- final Registry<TlsStrategy> tlsStrategy = RegistryBuilder.<TlsStrategy>create()
- .register("https", DefaultClientTlsStrategy.getSystemDefault())
+
+ final Lookup<TlsStrategy> tlsLookupStrategy = RegistryBuilder.<TlsStrategy>create()
+ .register("https", (tlsStrategy != null) ? tlsStrategy : DefaultClientTlsStrategy.getSystemDefault())
.build();
- connectionManager = new PoolingAsyncClientConnectionManager(
- tlsStrategy,
+ final PoolingAsyncClientConnectionManager connectionManager = new PoolingAsyncClientConnectionManager(
+ tlsLookupStrategy,
PoolConcurrencyPolicy.STRICT,
PoolReusePolicy.LIFO,
TimeValue.ofMilliseconds(connectionTTL),
@@ -338,25 +374,29 @@ public class AsyncHTTPConduitFactory implements HTTPConduitFactory {
adaptClientBuilder(httpAsyncClientBuilder);
- client = httpAsyncClientBuilder
- .setIOReactorConfig(config)
- .build();
+ final CloseableHttpAsyncClient client = httpAsyncClientBuilder
+ .setIOReactorConfig(config)
+ .build();
+
// Start the client thread
client.start();
//Always start the idle checker thread to validate pending requests and
//use the ConnectionMaxIdle to close the idle connection
new CloseIdleConnectionThread(connectionManager, client).start();
+
+ return new AsyncClient(connectionManager, client);
}
//provide a hook to customize the builder
protected void adaptClientBuilder(HttpAsyncClientBuilder httpAsyncClientBuilder) {
}
- public CloseableHttpAsyncClient createClient(final AsyncHTTPConduit c) throws IOException {
- if (client == null) {
- setupNIOClient(c.getClient());
- }
- return client;
+ public CloseableHttpAsyncClient createClient(final AsyncHTTPConduit c, final TlsStrategy tlsStrategy)
+ throws IOException {
+
+ return clients
+ .computeIfAbsent(c.getClient(), key -> createNIOClient(key, tlsStrategy))
+ .getClient();
}
int getMaxConnections() {
@@ -395,4 +435,12 @@ public class AsyncHTTPConduitFactory implements HTTPConduitFactory {
}
}
}
+
+ public void close(HTTPClientPolicy clientPolicy) {
+ final AsyncClient client = clients.remove(clientPolicy);
+ if (client != null) {
+ shutdown(client.getClient());
+ client.getConnectionManager().close();
+ }
+ }
}
diff --git a/systests/transport-hc5/pom.xml b/systests/transport-hc5/pom.xml
index c865c99..3ceca35 100644
--- a/systests/transport-hc5/pom.xml
+++ b/systests/transport-hc5/pom.xml
@@ -159,5 +159,15 @@
<artifactId>cglib-nodep</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-beans</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/GreeterImpl.java b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/GreeterImpl.java
new file mode 100644
index 0000000..6cbea95
--- /dev/null
+++ b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/GreeterImpl.java
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systest.hc5;
+
+import java.util.logging.Logger;
+
+import javax.jws.WebService;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.hello_world.Greeter;
+
+
+@WebService(serviceName = "SOAPService",
+ endpointInterface = "org.apache.hello_world.Greeter",
+ targetNamespace = "http://apache.org/hello_world")
+public class GreeterImpl implements Greeter {
+
+ private static final Logger LOG =
+ LogUtils.getLogger(GreeterImpl.class,
+ null,
+ GreeterImpl.class.getPackage().getName());
+ private String myName;
+
+ public GreeterImpl() {
+ this("defaultGreeter");
+ }
+
+ public GreeterImpl(String name) {
+ myName = name;
+ }
+
+ public String greetMe(String me) {
+ LOG.info("Executing operation greetMe");
+ LOG.info("Message received: " + me);
+ return "Hello " + me;
+ }
+
+
+ public String sayHi() {
+ LOG.info("Executing operation sayHi");
+ return "Bonjour from " + myName;
+ }
+
+ public void pingMe() {
+ }
+
+
+}
diff --git a/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/clientauth/ClientAuthServer.java b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/clientauth/ClientAuthServer.java
new file mode 100644
index 0000000..3761bd4
--- /dev/null
+++ b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/clientauth/ClientAuthServer.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systest.hc5.https.clientauth;
+
+import java.net.URL;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+
+public class ClientAuthServer extends AbstractBusTestServerBase {
+
+ public ClientAuthServer() {
+
+ }
+
+ protected void run() {
+ URL busFile = ClientAuthServer.class.getResource("client-auth-server.xml");
+ Bus busLocal = new SpringBusFactory().createBus(busFile);
+ BusFactory.setDefaultBus(busLocal);
+ setBus(busLocal);
+
+ try {
+ new ClientAuthServer();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/clientauth/ClientAuthTest.java b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/clientauth/ClientAuthTest.java
new file mode 100644
index 0000000..678b642
--- /dev/null
+++ b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/clientauth/ClientAuthTest.java
@@ -0,0 +1,587 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systest.hc5.https.clientauth;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.security.KeyStore;
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.xml.ws.BindingProvider;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.configuration.jsse.TLSClientParameters;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.frontend.ClientProxy;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.transport.http.HTTPConduit;
+import org.apache.cxf.transport.https.InsecureTrustManager;
+import org.apache.hello_world.Greeter;
+import org.apache.hello_world.services.SOAPService;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized.Parameters;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * A set of tests for TLS client authentication.
+ */
+@RunWith(value = org.junit.runners.Parameterized.class)
+public class ClientAuthTest extends AbstractBusClientServerTestBase {
+ static final String PORT = allocatePort(ClientAuthServer.class);
+ static final String PORT2 = allocatePort(ClientAuthServer.class, 2);
+
+ final Boolean async;
+
+ public ClientAuthTest(Boolean async) {
+ this.async = async;
+ }
+
+ @BeforeClass
+ public static void startServers() throws Exception {
+ assertTrue(
+ "Server failed to launch",
+ // run the server in the same process
+ // set this to false to fork
+ launchServer(ClientAuthServer.class, true)
+ );
+ }
+
+ @Parameters(name = "{0}")
+ public static Collection<Boolean> data() {
+
+ return Arrays.asList(new Boolean[] {Boolean.FALSE, Boolean.TRUE});
+ }
+
+ @AfterClass
+ public static void cleanup() throws Exception {
+ stopAllServers();
+ }
+
+ // Server directly trusts the client cert
+ @org.junit.Test
+ public void testDirectTrust() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = ClientAuthTest.class.getResource("client-auth.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // Server does not (directly) trust the client cert
+ @org.junit.Test
+ public void testInvalidDirectTrust() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = ClientAuthTest.class.getResource("client-auth-invalid.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ try {
+ port.greetMe("Kitty");
+ fail("Failure expected on an untrusted cert");
+ } catch (Exception ex) {
+ // expected
+ }
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // Client does not specify a KeyStore, only a TrustStore
+ @org.junit.Test
+ public void testNoClientCert() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = ClientAuthTest.class.getResource("client-no-auth.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ try {
+ port.greetMe("Kitty");
+ fail("Failure expected on no trusted cert");
+ } catch (Exception ex) {
+ // expected
+ }
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // Ignoring this test as it fails when run as part of the test class - testNoClientCert interferes with it
+ // It succeeds when run with testNoClientCert commented out
+ @org.junit.Test
+ @org.junit.Ignore
+ public void testSystemPropertiesWithEmptyKeystoreConfig() throws Exception {
+ try {
+ System.setProperty("javax.net.ssl.keyStore", "keys/Morpit.jks");
+ System.setProperty("javax.net.ssl.keyStorePassword", "password");
+ System.setProperty("javax.net.ssl.keyPassword", "password");
+ System.setProperty("javax.net.ssl.keyStoreType", "JKS");
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = ClientAuthTest.class.getResource("client-no-auth.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ } finally {
+ System.clearProperty("javax.net.ssl.keyStore");
+ System.clearProperty("javax.net.ssl.keyStorePassword");
+ System.clearProperty("javax.net.ssl.keyPassword");
+ System.clearProperty("javax.net.ssl.keyStoreType");
+ }
+ }
+
+ // Server trusts the issuer of the client cert
+ @org.junit.Test
+ public void testChainTrust() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = ClientAuthTest.class.getResource("client-auth-chain.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT2);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // Server does not trust the issuer of the client cert
+ @org.junit.Test
+ public void testInvalidChainTrust() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = ClientAuthTest.class.getResource("client-auth-invalid2.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT2);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ try {
+ port.greetMe("Kitty");
+ fail("Failure expected on no trusted cert");
+ } catch (Exception ex) {
+ // expected
+ }
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // Client does not trust the issuer of the server cert
+ @org.junit.Test
+ public void testClientInvalidCertChain() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = ClientAuthTest.class.getResource("client-auth-invalid2.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ try {
+ port.greetMe("Kitty");
+ fail("Failure expected on no trusted cert");
+ } catch (Exception ex) {
+ // expected
+ }
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // Client does not directly trust the server cert
+ @org.junit.Test
+ public void testClientInvalidDirectTrust() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = ClientAuthTest.class.getResource("client-auth-invalid.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT2);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ try {
+ port.greetMe("Kitty");
+ fail("Failure expected on no trusted cert");
+ } catch (Exception ex) {
+ // expected
+ }
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ @org.junit.Test
+ public void testSSLConnectionUsingJavaAPIs() throws Exception {
+ URL service = new URL("https://localhost:" + PORT);
+ HttpsURLConnection connection = (HttpsURLConnection) service.openConnection();
+
+ connection.setHostnameVerifier(new DisableCNCheckVerifier());
+
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+
+ KeyStore ts = KeyStore.getInstance("JKS");
+ try (InputStream trustStore =
+ ClassLoaderUtils.getResourceAsStream("keys/Truststore.jks", ClientAuthTest.class)) {
+ ts.load(trustStore, "password".toCharArray());
+ }
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ tmf.init(ts);
+
+ KeyStore ks = KeyStore.getInstance("JKS");
+ try (InputStream keyStore =
+ ClassLoaderUtils.getResourceAsStream("keys/Morpit.jks", ClientAuthTest.class)) {
+ ks.load(keyStore, "password".toCharArray());
+ }
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ kmf.init(ks, "password".toCharArray());
+
+ sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new java.security.SecureRandom());
+
+ connection.setSSLSocketFactory(sslContext.getSocketFactory());
+
+ connection.connect();
+
+ connection.disconnect();
+ }
+
+ // https://issues.apache.org/jira/browse/CXF-7763
+ @org.junit.Test
+ public void testCheckKeyManagersWithCertAlias() throws Exception {
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+
+ // Set up (shared) KeyManagers/TrustManagers
+ TrustManager[] trustManagers = InsecureTrustManager.getNoOpX509TrustManagers();
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+
+ try (InputStream inputStream = ClassLoaderUtils.getResourceAsStream("keymanagers.jks", this.getClass())) {
+ KeyStore keyStore = KeyStore.getInstance("JKS");
+ keyStore.load(inputStream, "password".toCharArray());
+
+ kmf.init(keyStore, "password".toCharArray());
+ }
+ KeyManager[] keyManagers = kmf.getKeyManagers();
+
+ // First call to PORT using Morpit
+ TLSClientParameters tlsParams = new TLSClientParameters();
+ tlsParams.setKeyManagers(keyManagers);
+ tlsParams.setCertAlias("morpit");
+ tlsParams.setTrustManagers(trustManagers);
+ tlsParams.setDisableCNCheck(true);
+
+ Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ Client client = ClientProxy.getClient(port);
+ HTTPConduit http = (HTTPConduit) client.getConduit();
+ http.setTlsClientParameters(tlsParams);
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+ ((java.io.Closeable)port).close();
+
+ // Second call to PORT2 using "alice"
+ tlsParams = new TLSClientParameters();
+ tlsParams.setKeyManagers(keyManagers);
+ tlsParams.setCertAlias("alice");
+ tlsParams.setTrustManagers(trustManagers);
+ tlsParams.setDisableCNCheck(true);
+
+ port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT2);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ client = ClientProxy.getClient(port);
+ http = (HTTPConduit) client.getConduit();
+ http.setTlsClientParameters(tlsParams);
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+ ((java.io.Closeable)port).close();
+ }
+
+ // Server directly trusts the client cert
+ @org.junit.Test
+ public void testDirectTrustUsingKeyManagers() throws Exception {
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ // Set up KeyManagers/TrustManagers
+ KeyStore ts = KeyStore.getInstance("JKS");
+ try (InputStream trustStore =
+ ClassLoaderUtils.getResourceAsStream("keys/Truststore.jks", ClientAuthTest.class)) {
+ ts.load(trustStore, "password".toCharArray());
+ }
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ tmf.init(ts);
+
+ KeyStore ks = KeyStore.getInstance("JKS");
+ try (InputStream keyStore =
+ ClassLoaderUtils.getResourceAsStream("keys/Morpit.jks", ClientAuthTest.class)) {
+ ks.load(keyStore, "password".toCharArray());
+ }
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ kmf.init(ks, "password".toCharArray());
+
+ TLSClientParameters tlsParams = new TLSClientParameters();
+ tlsParams.setKeyManagers(kmf.getKeyManagers());
+ tlsParams.setTrustManagers(tmf.getTrustManagers());
+ tlsParams.setDisableCNCheck(true);
+
+ Client client = ClientProxy.getClient(port);
+ HTTPConduit http = (HTTPConduit) client.getConduit();
+ http.setTlsClientParameters(tlsParams);
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ }
+
+ // Server directly trusts the client cert
+ @org.junit.Test
+ public void testDirectTrustUsingSSLContext() throws Exception {
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ // Set up KeyManagers/TrustManagers
+ KeyStore ts = KeyStore.getInstance("JKS");
+ try (InputStream trustStore =
+ ClassLoaderUtils.getResourceAsStream("keys/Truststore.jks", ClientAuthTest.class)) {
+ ts.load(trustStore, "password".toCharArray());
+ }
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ tmf.init(ts);
+
+ KeyStore ks = KeyStore.getInstance("JKS");
+ try (InputStream keyStore =
+ ClassLoaderUtils.getResourceAsStream("keys/Morpit.jks", ClientAuthTest.class)) {
+ ks.load(keyStore, "password".toCharArray());
+ }
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ kmf.init(ks, "password".toCharArray());
+
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new java.security.SecureRandom());
+
+ TLSClientParameters tlsParams = new TLSClientParameters();
+ tlsParams.setSslContext(sslContext);
+ tlsParams.setDisableCNCheck(true);
+
+ Client client = ClientProxy.getClient(port);
+ HTTPConduit http = (HTTPConduit) client.getConduit();
+ http.setTlsClientParameters(tlsParams);
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ // Enable Async
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ }
+
+ private static final class DisableCNCheckVerifier implements HostnameVerifier {
+
+ @Override
+ public boolean verify(String arg0, SSLSession arg1) {
+ return true;
+ }
+
+ };
+
+}
diff --git a/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/hostname/HostnameVerificationDeprecatedServer.java b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/hostname/HostnameVerificationDeprecatedServer.java
new file mode 100644
index 0000000..f75ae0d
--- /dev/null
+++ b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/hostname/HostnameVerificationDeprecatedServer.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systest.hc5.https.hostname;
+
+import java.net.URL;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+
+public class HostnameVerificationDeprecatedServer extends AbstractBusTestServerBase {
+
+ public HostnameVerificationDeprecatedServer() {
+
+ }
+
+ protected void run() {
+ URL busFile = HostnameVerificationDeprecatedServer.class.getResource("hostname-server-deprecated.xml");
+ Bus busLocal = new SpringBusFactory().createBus(busFile);
+ BusFactory.setDefaultBus(busLocal);
+ setBus(busLocal);
+
+ try {
+ new HostnameVerificationDeprecatedServer();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/hostname/HostnameVerificationDeprecatedTest.java b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/hostname/HostnameVerificationDeprecatedTest.java
new file mode 100644
index 0000000..92c983c
--- /dev/null
+++ b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/hostname/HostnameVerificationDeprecatedTest.java
@@ -0,0 +1,320 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systest.hc5.https.hostname;
+
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.xml.ws.BindingProvider;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.configuration.jsse.TLSClientParameters;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.frontend.ClientProxy;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.transport.http.HTTPConduit;
+import org.apache.hello_world.Greeter;
+import org.apache.hello_world.services.SOAPService;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized.Parameters;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * A test for hostname verification when the Java system property "java.protocol.handler.pkgs" is set to
+ * "com.sun.net.ssl.internal.www.protocol". This means that com.sun.net.ssl.HostnameVerifier is used
+ * instead of the javax version.
+ */
+@RunWith(value = org.junit.runners.Parameterized.class)
+public class HostnameVerificationDeprecatedTest extends AbstractBusClientServerTestBase {
+ static final String PORT = allocatePort(HostnameVerificationDeprecatedServer.class);
+ static final String PORT2 = allocatePort(HostnameVerificationDeprecatedServer.class, 2);
+ static final String PORT3 = allocatePort(HostnameVerificationDeprecatedServer.class, 3);
+
+ private final Boolean async;
+
+ public HostnameVerificationDeprecatedTest(Boolean async) {
+ this.async = async;
+ }
+
+ @BeforeClass
+ public static void startServers() throws Exception {
+ System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
+ assertTrue(
+ "Server failed to launch",
+ // run the server in the same process
+ // set this to false to fork
+ launchServer(HostnameVerificationDeprecatedServer.class, true)
+ );
+ }
+
+ @Parameters(name = "{0}")
+ public static Collection<Boolean> data() {
+
+ return Arrays.asList(new Boolean[] {Boolean.FALSE, Boolean.TRUE});
+ }
+
+ @AfterClass
+ public static void cleanup() throws Exception {
+ System.clearProperty("java.protocol.handler.pkgs");
+ stopAllServers();
+ }
+
+ // Here we expect an exception, as the default hostname verifier contributed by CXF will object to the
+ // fact that the server certificate does not have "CN=localhost".
+ @org.junit.Test
+ public void testLocalhostNotMatching() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = HostnameVerificationDeprecatedTest.class.getResource("hostname-client.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ try {
+ port.greetMe("Kitty");
+ fail("Failure expected on the hostname verification");
+ } catch (Exception ex) {
+ // expected
+ }
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // No Subject Alternative Name, no matching CN - but we are disabling the CN check so it should work OK
+ @org.junit.Test
+ public void testLocalhostNotMatchingDisableCN() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = HostnameVerificationTest.class.getResource("hostname-client-disablecn.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // No Subject Alternative Name, no matching CN - but we are setting the JVM default hostname verifier to
+ // allow it
+ @org.junit.Test
+ public void testNoSubjectAlternativeNameNoCNMatchDefaultVerifier() throws Exception {
+ HostnameVerifier hostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
+ try {
+ HttpsURLConnection.setDefaultHostnameVerifier(
+ new javax.net.ssl.HostnameVerifier() {
+ public boolean verify(String hostName, javax.net.ssl.SSLSession session) {
+ return true;
+ }
+
+ // Note we need this method as well or else it won't work the with the
+ // deprecated HostnameVerifier interface
+ @SuppressWarnings("unused")
+ public boolean verify(final String host, final String certHostname) {
+ return true;
+ }
+ });
+
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = HostnameVerificationTest.class.getResource("hostname-client-usedefault.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ } finally {
+ if (hostnameVerifier != null) {
+ HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
+ }
+ }
+ }
+
+ // No Subject Alternative Name, no matching CN - but we are setting the JVM default hostname verifier to
+ // allow it. It differs to the method above, that we are not using a Spring configuration file, but
+ // instead are setting a TLSClientParameters on the HTTPConduit
+ @org.junit.Test
+ public void testNoSubjectAlternativeNameNoCNMatchDefaultVerifierNoConfig() throws Exception {
+ HostnameVerifier hostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
+ try {
+ System.setProperty("javax.net.ssl.trustStore", "keys/subjalt.jks");
+ System.setProperty("javax.net.ssl.trustStorePassword", "security");
+ System.setProperty("javax.net.ssl.trustStoreType", "JKS");
+ HttpsURLConnection.setDefaultHostnameVerifier(
+ new javax.net.ssl.HostnameVerifier() {
+ public boolean verify(String hostName, javax.net.ssl.SSLSession session) {
+ return true;
+ }
+
+ // Note we need this method as well or else it won't work the with the
+ // deprecated HostnameVerifier interface
+ @SuppressWarnings("unused")
+ public boolean verify(final String host, final String certHostname) {
+ return true;
+ }
+ });
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ TLSClientParameters clientParameters = new TLSClientParameters();
+ clientParameters.setUseHttpsURLConnectionDefaultHostnameVerifier(true);
+ Client client = ClientProxy.getClient(port);
+ ((HTTPConduit)client.getConduit()).setTlsClientParameters(clientParameters);
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ } finally {
+ if (hostnameVerifier != null) {
+ HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
+ }
+ System.clearProperty("javax.net.ssl.trustStore");
+ System.clearProperty("javax.net.ssl.trustStorePassword");
+ System.clearProperty("javax.net.ssl.trustStoreType");
+ }
+ }
+
+ // No Subject Alternative Name, but the CN matches ("localhost"), so the default HostnameVerifier
+ // should work fine
+ @org.junit.Test
+ public void testNoSubjectAlternativeNameCNMatch() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = HostnameVerificationDeprecatedTest.class.getResource("hostname-client.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT2);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // No Subject Alternative Name, but the CN wildcard matches
+ @org.junit.Test
+ public void testNoSubjectAlternativeNameCNWildcardMatch() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = HostnameVerificationTest.class.getResource("hostname-client.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT3);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+}
diff --git a/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/hostname/HostnameVerificationServer.java b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/hostname/HostnameVerificationServer.java
new file mode 100644
index 0000000..ca23633
--- /dev/null
+++ b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/hostname/HostnameVerificationServer.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systest.hc5.https.hostname;
+
+import java.net.URL;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+
+public class HostnameVerificationServer extends AbstractBusTestServerBase {
+
+ public HostnameVerificationServer() {
+
+ }
+
+ protected void run() {
+ URL busFile = HostnameVerificationServer.class.getResource("hostname-server.xml");
+ Bus busLocal = new SpringBusFactory().createBus(busFile);
+ BusFactory.setDefaultBus(busLocal);
+ setBus(busLocal);
+
+ try {
+ new HostnameVerificationServer();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/hostname/HostnameVerificationTest.java b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/hostname/HostnameVerificationTest.java
new file mode 100644
index 0000000..5dbe9ba
--- /dev/null
+++ b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/hostname/HostnameVerificationTest.java
@@ -0,0 +1,369 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systest.hc5.https.hostname;
+
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.xml.ws.BindingProvider;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.configuration.jsse.TLSClientParameters;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.frontend.ClientProxy;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.transport.http.HTTPConduit;
+import org.apache.hello_world.Greeter;
+import org.apache.hello_world.services.SOAPService;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized.Parameters;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * A set of tests for hostname verification, where the hostname in question is "localhost".
+ *
+ * Keys created via something like:
+ * keytool -genkey -validity 3650 -alias subjalt -keyalg RSA -keystore subjalt.jks
+ * -dname "CN=Colm,OU=WSS4J,O=Apache,L=Dublin,ST=Leinster,C=IE" -ext SAN=DNS:localhost
+ */
+@RunWith(value = org.junit.runners.Parameterized.class)
+public class HostnameVerificationTest extends AbstractBusClientServerTestBase {
+ static final String PORT = allocatePort(HostnameVerificationServer.class);
+ static final String PORT2 = allocatePort(HostnameVerificationServer.class, 2);
+ static final String PORT3 = allocatePort(HostnameVerificationServer.class, 3);
+ static final String PORT4 = allocatePort(HostnameVerificationServer.class, 4);
+ static final String PORT5 = allocatePort(HostnameVerificationServer.class, 5);
+
+ private final Boolean async;
+
+ public HostnameVerificationTest(Boolean async) {
+ this.async = async;
+ }
+
+ @BeforeClass
+ public static void startServers() throws Exception {
+ assertTrue(
+ "Server failed to launch",
+ // run the server in the same process
+ // set this to false to fork
+ launchServer(HostnameVerificationServer.class, true)
+ );
+ }
+
+ @Parameters(name = "{0}")
+ public static Collection<Boolean> data() {
+
+ return Arrays.asList(new Boolean[] {Boolean.FALSE, Boolean.TRUE});
+ }
+
+ @AfterClass
+ public static void cleanup() throws Exception {
+ stopAllServers();
+ }
+
+ // Subject Alternative Name matches (but not the CN)
+ @org.junit.Test
+ public void testSubjectAlternativeNameMatch() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = HostnameVerificationTest.class.getResource("hostname-client.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // Subject Alternative Name does not match (but the CN does - still an error)
+ @org.junit.Test
+ public void testSubjectAlternativeNameNoMatch() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = HostnameVerificationTest.class.getResource("hostname-client.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT2);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ try {
+ port.greetMe("Kitty");
+ fail("Failure expected on a non-matching subject alternative name");
+ } catch (Exception ex) {
+ // expected
+ }
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // No Subject Alternative Name, but the CN matches
+ @org.junit.Test
+ public void testNoSubjectAlternativeNameCNMatch() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = HostnameVerificationTest.class.getResource("hostname-client.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT3);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // No Subject Alternative Name, no matching CN
+ @org.junit.Test
+ public void testNoSubjectAlternativeNameNoCNMatch() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = HostnameVerificationTest.class.getResource("hostname-client.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT4);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ try {
+ port.greetMe("Kitty");
+ fail("Failure expected with no matching Subject Alt Name or CN");
+ } catch (Exception ex) {
+ // expected
+ }
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // No Subject Alternative Name, no matching CN - but we are disabling the CN check so it should work OK
+ @org.junit.Test
+ public void testNoSubjectAlternativeNameNoCNMatchDisableCN() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = HostnameVerificationTest.class.getResource("hostname-client-disablecn.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT4);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // No Subject Alternative Name, no matching CN - but we are setting the JVM default hostname verifier to
+ // allow it
+ @org.junit.Test
+ public void testNoSubjectAlternativeNameNoCNMatchDefaultVerifier() throws Exception {
+ HostnameVerifier hostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
+ try {
+ HttpsURLConnection.setDefaultHostnameVerifier(
+ new javax.net.ssl.HostnameVerifier() {
+ public boolean verify(String hostName, javax.net.ssl.SSLSession session) {
+ return true;
+ }
+ });
+
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = HostnameVerificationTest.class.getResource("hostname-client-usedefault.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT4);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ } finally {
+ if (hostnameVerifier != null) {
+ HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
+ }
+ }
+ }
+
+ // No Subject Alternative Name, no matching CN - but we are setting the JVM default hostname verifier to
+ // allow it. It differs to the method above, that we are not using a Spring configuration file, but
+ // instead are setting a TLSClientParameters on the HTTPConduit
+ @org.junit.Test
+ public void testNoSubjectAlternativeNameNoCNMatchDefaultVerifierNoConfig() throws Exception {
+ HostnameVerifier hostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
+ try {
+ System.setProperty("javax.net.ssl.trustStore", "keys/subjalt.jks");
+ System.setProperty("javax.net.ssl.trustStorePassword", "security");
+ System.setProperty("javax.net.ssl.trustStoreType", "JKS");
+ HttpsURLConnection.setDefaultHostnameVerifier(
+ new javax.net.ssl.HostnameVerifier() {
+ public boolean verify(String hostName, javax.net.ssl.SSLSession session) {
+ return true;
+ }
+ });
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT4);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ TLSClientParameters clientParameters = new TLSClientParameters();
+ clientParameters.setUseHttpsURLConnectionDefaultHostnameVerifier(true);
+ Client client = ClientProxy.getClient(port);
+ ((HTTPConduit)client.getConduit()).setTlsClientParameters(clientParameters);
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ } finally {
+ if (hostnameVerifier != null) {
+ HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
+ }
+ System.clearProperty("javax.net.ssl.trustStore");
+ System.clearProperty("javax.net.ssl.trustStorePassword");
+ System.clearProperty("javax.net.ssl.trustStoreType");
+ }
+ }
+
+ // No Subject Alternative Name, but the CN wildcard matches
+ @org.junit.Test
+ public void testNoSubjectAlternativeNameCNWildcardMatch() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = HostnameVerificationTest.class.getResource("hostname-client.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT5);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+}
diff --git a/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/trust/TrustManagerTest.java b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/trust/TrustManagerTest.java
new file mode 100644
index 0000000..bedade5
--- /dev/null
+++ b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/trust/TrustManagerTest.java
@@ -0,0 +1,474 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systest.hc5.https.trust;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.security.KeyStore;
+import java.security.Security;
+import java.security.cert.CertificateException;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.X509CertSelector;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.net.ssl.CertPathTrustManagerParameters;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+import javax.xml.ws.BindingProvider;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.configuration.jsse.TLSClientParameters;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.frontend.ClientProxy;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.transport.http.HTTPConduit;
+import org.apache.cxf.transport.https.InsecureTrustManager;
+import org.apache.hello_world.Greeter;
+import org.apache.hello_world.services.SOAPService;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized.Parameters;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * A set of tests for specifying a TrustManager
+ */
+@RunWith(value = org.junit.runners.Parameterized.class)
+public class TrustManagerTest extends AbstractBusClientServerTestBase {
+ static final String PORT = allocatePort(TrustServer.class);
+ static final String PORT2 = allocatePort(TrustServer.class, 2);
+ static final String PORT3 = allocatePort(TrustServer.class, 3);
+
+ private final Boolean async;
+
+ public TrustManagerTest(Boolean async) {
+ this.async = async;
+ }
+
+ @BeforeClass
+ public static void startServers() throws Exception {
+ assertTrue(
+ "Server failed to launch",
+ // run the server in the same process
+ // set this to false to fork
+ launchServer(TrustServer.class, true)
+ );
+ assertTrue(
+ "Server failed to launch",
+ // run the server in the same process
+ // set this to false to fork
+ launchServer(TrustServerNoSpring.class, true)
+ );
+ }
+
+ @Parameters(name = "{0}")
+ public static Collection<Boolean> data() {
+
+ return Arrays.asList(new Boolean[] {Boolean.FALSE, Boolean.TRUE});
+ }
+
+ @AfterClass
+ public static void cleanup() throws Exception {
+ stopAllServers();
+ }
+
+ // The X509TrustManager is effectively empty here so trust verification should work
+ @org.junit.Test
+ public void testNoOpX509TrustManager() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = TrustManagerTest.class.getResource("client-trust.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ TLSClientParameters tlsParams = new TLSClientParameters();
+ tlsParams.setTrustManagers(InsecureTrustManager.getNoOpX509TrustManagers());
+ tlsParams.setDisableCNCheck(true);
+
+ Client client = ClientProxy.getClient(port);
+ HTTPConduit http = (HTTPConduit) client.getConduit();
+ http.setTlsClientParameters(tlsParams);
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // The X509TrustManager is effectively empty here so trust verification should work
+ @org.junit.Test
+ public void testNoOpX509TrustManagerTrustManagersRef() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = TrustManagerTest.class.getResource("client-trust-manager-ref.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // Here the Trust Manager checks the server cert
+ @org.junit.Test
+ public void testValidServerCertX509TrustManager() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = TrustManagerTest.class.getResource("client-trust.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ String validPrincipalName = "CN=Bethal,OU=Bethal,O=ApacheTest,L=Syracuse,C=US";
+
+ TLSClientParameters tlsParams = new TLSClientParameters();
+ X509TrustManager trustManager =
+ new ServerCertX509TrustManager(validPrincipalName);
+ TrustManager[] trustManagers = new TrustManager[1];
+ trustManagers[0] = trustManager;
+ tlsParams.setTrustManagers(trustManagers);
+ tlsParams.setDisableCNCheck(true);
+
+ Client client = ClientProxy.getClient(port);
+ HTTPConduit http = (HTTPConduit) client.getConduit();
+ http.setTlsClientParameters(tlsParams);
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ // Here we're using spring config but getting the truststore from the standard system properties
+ @org.junit.Test
+ public void testSystemPropertiesWithEmptyTLSClientParametersConfig() throws Exception {
+ try {
+ System.setProperty("javax.net.ssl.trustStore", "keys/Bethal.jks");
+ System.setProperty("javax.net.ssl.trustStorePassword", "password");
+ System.setProperty("javax.net.ssl.trustStoreType", "JKS");
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = TrustManagerTest.class.getResource("client-trust-config.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ } finally {
+ System.clearProperty("javax.net.ssl.trustStore");
+ System.clearProperty("javax.net.ssl.trustStorePassword");
+ System.clearProperty("javax.net.ssl.trustStoreType");
+ }
+ }
+
+ // Here we're using spring config but getting the truststore from the standard system properties
+ @org.junit.Test
+ public void testSystemPropertiesWithEmptyKeystoreConfig() throws Exception {
+ try {
+ System.setProperty("javax.net.ssl.trustStore", "keys/Bethal.jks");
+ System.setProperty("javax.net.ssl.trustStorePassword", "password");
+ System.setProperty("javax.net.ssl.trustStoreType", "JKS");
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = TrustManagerTest.class.getResource("client-trust-empty-config.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ } finally {
+ System.clearProperty("javax.net.ssl.trustStore");
+ System.clearProperty("javax.net.ssl.trustStorePassword");
+ System.clearProperty("javax.net.ssl.trustStoreType");
+ }
+ }
+
+ // Here the Trust Manager checks the server cert. this time we are invoking on the
+ // service that is configured in code (not by spring)
+ @org.junit.Test
+ public void testValidServerCertX509TrustManager2() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = TrustManagerTest.class.getResource("client-trust.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT3);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ String validPrincipalName = "CN=Bethal,OU=Bethal,O=ApacheTest,L=Syracuse,C=US";
+
+ TLSClientParameters tlsParams = new TLSClientParameters();
+ X509TrustManager trustManager =
+ new ServerCertX509TrustManager(validPrincipalName);
+ TrustManager[] trustManagers = new TrustManager[1];
+ trustManagers[0] = trustManager;
+ tlsParams.setTrustManagers(trustManagers);
+ tlsParams.setDisableCNCheck(true);
+
+ Client client = ClientProxy.getClient(port);
+ HTTPConduit http = (HTTPConduit) client.getConduit();
+ http.setTlsClientParameters(tlsParams);
+
+ assertEquals(port.greetMe("Kitty"), "Hello Kitty");
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ @org.junit.Test
+ public void testInvalidServerCertX509TrustManager() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = TrustManagerTest.class.getResource("client-trust.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ String invalidPrincipalName = "CN=Bethal2,OU=Bethal,O=ApacheTest,L=Syracuse,C=US";
+
+ TLSClientParameters tlsParams = new TLSClientParameters();
+ X509TrustManager trustManager =
+ new ServerCertX509TrustManager(invalidPrincipalName);
+ TrustManager[] trustManagers = new TrustManager[1];
+ trustManagers[0] = trustManager;
+ tlsParams.setTrustManagers(trustManagers);
+ tlsParams.setDisableCNCheck(true);
+
+ Client client = ClientProxy.getClient(port);
+ HTTPConduit http = (HTTPConduit) client.getConduit();
+ http.setTlsClientParameters(tlsParams);
+
+ try {
+ port.greetMe("Kitty");
+ fail("Failure expected on an invalid principal name");
+ } catch (Exception ex) {
+ // expected
+ }
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ @org.junit.Test
+ public void testOSCPOverride() throws Exception {
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = TrustManagerTest.class.getResource("client-trust.xml");
+
+ Bus bus = bf.createBus(busFile.toString());
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL url = SOAPService.WSDL_LOCATION;
+ SOAPService service = new SOAPService(url, SOAPService.SERVICE);
+ assertNotNull("Service is null", service);
+ final Greeter port = service.getHttpsPort();
+ assertNotNull("Port is null", port);
+
+ updateAddressPort(port, PORT2);
+
+ // Enable Async
+ if (async) {
+ ((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
+ }
+
+ // Read truststore
+ KeyStore ts = KeyStore.getInstance("JKS");
+ try (InputStream trustStore =
+ ClassLoaderUtils.getResourceAsStream("keys/cxfca.jks", TrustManagerTest.class)) {
+ ts.load(trustStore, "password".toCharArray());
+ }
+
+ try {
+ Security.setProperty("ocsp.enable", "true");
+
+ PKIXBuilderParameters param = new PKIXBuilderParameters(ts, new X509CertSelector());
+ param.setRevocationEnabled(true);
+
+ TrustManagerFactory tmf =
+ TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ tmf.init(new CertPathTrustManagerParameters(param));
+
+ TLSClientParameters tlsParams = new TLSClientParameters();
+ tlsParams.setTrustManagers(tmf.getTrustManagers());
+ tlsParams.setDisableCNCheck(true);
+
+ Client client = ClientProxy.getClient(port);
+ HTTPConduit http = (HTTPConduit) client.getConduit();
+ http.setTlsClientParameters(tlsParams);
+
+ try {
+ port.greetMe("Kitty");
+ fail("Failure expected on an invalid OCSP responder URL");
+ } catch (Exception ex) {
+ // expected
+ }
+
+ } finally {
+ Security.setProperty("ocsp.enable", "false");
+ }
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
+
+ public static class ServerCertX509TrustManager implements X509TrustManager {
+
+ private String requiredServerPrincipalName;
+
+ public ServerCertX509TrustManager(String principalName) {
+ requiredServerPrincipalName = principalName;
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ if (chain == null || chain.length == 0) {
+ throw new CertificateException("X509 Certificate chain is empty");
+ }
+ X509Certificate serverCert = chain[0];
+ if (requiredServerPrincipalName != null
+ && !requiredServerPrincipalName.equals(serverCert.getSubjectX500Principal().getName())) {
+ throw new CertificateException("X509 server certificate does not match requirement");
+ }
+
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ }
+
+}
diff --git a/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/trust/TrustServer.java b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/trust/TrustServer.java
new file mode 100644
index 0000000..fd0b32a
--- /dev/null
+++ b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/trust/TrustServer.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systest.hc5.https.trust;
+
+import java.net.URL;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+
+public class TrustServer extends AbstractBusTestServerBase {
+
+ public TrustServer() {
+
+ }
+
+ protected void run() {
+ URL busFile = TrustServer.class.getResource("trust-server.xml");
+ Bus busLocal = new SpringBusFactory().createBus(busFile);
+ BusFactory.setDefaultBus(busLocal);
+ setBus(busLocal);
+
+ try {
+ new TrustServer();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/trust/TrustServerNoSpring.java b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/trust/TrustServerNoSpring.java
new file mode 100644
index 0000000..c6e34a3
--- /dev/null
+++ b/systests/transport-hc5/src/test/java/org/apache/cxf/systest/hc5/https/trust/TrustServerNoSpring.java
@@ -0,0 +1,84 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systest.hc5.https.trust;
+
+import java.security.KeyStore;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.xml.ws.Endpoint;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.configuration.jsse.TLSServerParameters;
+import org.apache.cxf.configuration.security.ClientAuthentication;
+import org.apache.cxf.systest.hc5.GreeterImpl;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+import org.apache.cxf.transport.http_jetty.JettyHTTPServerEngineFactory;
+
+public class TrustServerNoSpring extends AbstractBusTestServerBase {
+
+ public TrustServerNoSpring() {
+
+ }
+
+ protected void run() {
+ Bus busLocal = BusFactory.getDefaultBus(true);
+ setBus(busLocal);
+
+ String address = "https://localhost:" + TrustManagerTest.PORT3 + "/SoapContext/HttpsPort";
+
+ try {
+ KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ keyStore.load(ClassLoaderUtils.getResourceAsStream("keys/Bethal.jks",
+ this.getClass()),
+ "password".toCharArray());
+
+ KeyManagerFactory kmf =
+ KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ kmf.init(keyStore, "password".toCharArray());
+
+ TLSServerParameters tlsParams = new TLSServerParameters();
+ tlsParams.setKeyManagers(kmf.getKeyManagers());
+
+ ClientAuthentication clientAuthentication = new ClientAuthentication();
+ clientAuthentication.setRequired(false);
+ clientAuthentication.setWant(true);
+ tlsParams.setClientAuthentication(clientAuthentication);
+
+ Map<String, TLSServerParameters> map = new HashMap<>();
+ map.put("tlsId", tlsParams);
+
+ JettyHTTPServerEngineFactory factory =
+ busLocal.getExtension(JettyHTTPServerEngineFactory.class);
+ factory.setTlsServerParametersMap(map);
+ factory.createJettyHTTPServerEngine("localhost", Integer.parseInt(TrustManagerTest.PORT3),
+ "https", "tlsId");
+
+ factory.initComplete();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+
+ Endpoint.publish(address, new GreeterImpl());
+ }
+}
diff --git a/systests/transport-hc5/src/test/resources/keymanagers.jks b/systests/transport-hc5/src/test/resources/keymanagers.jks
new file mode 100644
index 0000000..cdfbeba
Binary files /dev/null and b/systests/transport-hc5/src/test/resources/keymanagers.jks differ
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-auth-chain.xml b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-auth-chain.xml
new file mode 100644
index 0000000..857eb1a
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-auth-chain.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:p="http://cxf.apache.org/policy"
+ xmlns:sec="http://cxf.apache.org/configuration/security"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache [...]
+
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+ <http:conduit name="https://localhost:.*">
+ <http:tlsClientParameters disableCNCheck="true">
+ <sec:keyManagers keyPassword="password">
+ <sec:keyStore type="jks" password="password" resource="keys/alice.jks"/>
+ </sec:keyManagers>
+ <sec:trustManagers>
+ <sec:keyStore type="jks" password="password" resource="keys/cxfca.jks"/>
+ </sec:trustManagers>
+ </http:tlsClientParameters>
+ </http:conduit>
+</beans>
\ No newline at end of file
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-auth-invalid.xml b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-auth-invalid.xml
new file mode 100644
index 0000000..6de6bfb
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-auth-invalid.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:p="http://cxf.apache.org/policy"
+ xmlns:sec="http://cxf.apache.org/configuration/security"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache [...]
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+ <http:conduit name="https://localhost:.*">
+ <http:tlsClientParameters disableCNCheck="true">
+ <sec:keyManagers keyPassword="password">
+ <sec:keyStore type="jks" password="password" resource="keys/alice.jks"/>
+ </sec:keyManagers>
+ <sec:trustManagers>
+ <sec:keyStore type="jks" password="password" resource="keys/Truststore.jks"/>
+ </sec:trustManagers>
+ </http:tlsClientParameters>
+ </http:conduit>
+</beans>
\ No newline at end of file
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-auth-invalid2.xml b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-auth-invalid2.xml
new file mode 100644
index 0000000..1aca21e
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-auth-invalid2.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:p="http://cxf.apache.org/policy"
+ xmlns:sec="http://cxf.apache.org/configuration/security"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache [...]
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+ <http:conduit name="https://localhost:.*">
+ <http:tlsClientParameters disableCNCheck="true">
+ <sec:keyManagers keyPassword="password">
+ <sec:keyStore type="jks" password="password" resource="keys/Morpit.jks"/>
+ </sec:keyManagers>
+ <sec:trustManagers>
+ <sec:keyStore type="jks" password="password" resource="keys/cxfca.jks"/>
+ </sec:trustManagers>
+ </http:tlsClientParameters>
+ </http:conduit>
+</beans>
\ No newline at end of file
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-auth-server.xml b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-auth-server.xml
new file mode 100644
index 0000000..af5a90f
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-auth-server.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
+ xmlns:sec="http://cxf.apache.org/configuration/security"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:p="http://cxf.apache.org/policy"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache.org/policy http://cxf.apache.org/schemas/policy.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/transports/http-jetty/confi [...]
+ <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"/>
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+
+ <httpj:engine-factory id="direct-trust-tls-settings">
+ <httpj:engine port="${testutil.ports.ClientAuthServer}">
+ <httpj:tlsServerParameters>
+ <sec:keyManagers keyPassword="password">
+ <sec:keyStore type="jks" password="password" resource="keys/Bethal.jks"/>
+ </sec:keyManagers>
+ <sec:trustManagers>
+ <sec:keyStore type="jks" password="password" resource="keys/Truststore.jks"/>
+ </sec:trustManagers>
+ <sec:clientAuthentication want="true" required="true"/>
+ </httpj:tlsServerParameters>
+ </httpj:engine>
+ </httpj:engine-factory>
+
+ <jaxws:endpoint xmlns:e="http://apache.org/hello_world/services"
+ xmlns:s="http://apache.org/hello_world/services"
+ id="DirectTrustServer"
+ implementor="org.apache.cxf.systest.hc5.GreeterImpl"
+ address="https://localhost:${testutil.ports.ClientAuthServer}/SoapContext/HttpsPort"
+ serviceName="s:SOAPService"
+ endpointName="e:HttpsPort" depends-on="direct-trust-tls-settings"/>
+
+ <httpj:engine-factory id="chain-trust-tls-settings">
+ <httpj:engine port="${testutil.ports.ClientAuthServer.2}">
+ <httpj:tlsServerParameters>
+ <sec:keyManagers keyPassword="password">
+ <sec:keyStore type="jks" password="password" resource="keys/bob.jks"/>
+ </sec:keyManagers>
+ <sec:trustManagers>
+ <sec:keyStore type="jks" password="password" resource="keys/cxfca.jks"/>
+ </sec:trustManagers>
+ <sec:clientAuthentication want="true" required="true"/>
+ </httpj:tlsServerParameters>
+ </httpj:engine>
+ </httpj:engine-factory>
+
+ <jaxws:endpoint xmlns:e="http://apache.org/hello_world/services"
+ xmlns:s="http://apache.org/hello_world/services"
+ id="ChainTrustServer"
+ implementor="org.apache.cxf.systest.hc5.GreeterImpl"
+ address="https://localhost:${testutil.ports.ClientAuthServer.2}/SoapContext/HttpsPort"
+ serviceName="s:SOAPService"
+ endpointName="e:HttpsPort" depends-on="chain-trust-tls-settings"/>
+
+</beans>
\ No newline at end of file
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-auth.xml b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-auth.xml
new file mode 100644
index 0000000..a99d49e
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-auth.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:p="http://cxf.apache.org/policy"
+ xmlns:sec="http://cxf.apache.org/configuration/security"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache [...]
+
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+ <http:conduit name="https://localhost:.*">
+ <http:tlsClientParameters disableCNCheck="true">
+ <sec:keyManagers keyPassword="password">
+ <sec:keyStore type="jks" password="password" resource="keys/Morpit.jks"/>
+ </sec:keyManagers>
+ <sec:trustManagers>
+ <sec:keyStore type="jks" password="password" resource="keys/Truststore.jks"/>
+ </sec:trustManagers>
+ </http:tlsClientParameters>
+ </http:conduit>
+</beans>
\ No newline at end of file
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-no-auth.xml b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-no-auth.xml
new file mode 100644
index 0000000..05ac868
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/clientauth/client-no-auth.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:p="http://cxf.apache.org/policy"
+ xmlns:sec="http://cxf.apache.org/configuration/security"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache [...]
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+ <http:conduit name="https://localhost:.*">
+ <http:tlsClientParameters disableCNCheck="true">
+ <sec:trustManagers>
+ <sec:keyStore type="jks" password="password" resource="keys/Truststore.jks"/>
+ </sec:trustManagers>
+ </http:tlsClientParameters>
+ </http:conduit>
+</beans>
\ No newline at end of file
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/hostname/hostname-client-disablecn.xml b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/hostname/hostname-client-disablecn.xml
new file mode 100644
index 0000000..bc640e3
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/hostname/hostname-client-disablecn.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:p="http://cxf.apache.org/policy"
+ xmlns:sec="http://cxf.apache.org/configuration/security"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache [...]
+
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+ <http:conduit name="https://localhost:.*">
+ <http:tlsClientParameters disableCNCheck="true">
+ <sec:trustManagers>
+ <sec:keyStore type="jks" password="security" resource="keys/subjalt.jks"/>
+ </sec:trustManagers>
+ </http:tlsClientParameters>
+ </http:conduit>
+</beans>
\ No newline at end of file
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/hostname/hostname-client-usedefault.xml b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/hostname/hostname-client-usedefault.xml
new file mode 100644
index 0000000..97442d8
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/hostname/hostname-client-usedefault.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:p="http://cxf.apache.org/policy"
+ xmlns:sec="http://cxf.apache.org/configuration/security"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache [...]
+
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+ <http:conduit name="https://localhost:.*">
+ <http:tlsClientParameters useHttpsURLConnectionDefaultHostnameVerifier="true">
+ <sec:trustManagers>
+ <sec:keyStore type="jks" password="security" resource="keys/subjalt.jks"/>
+ </sec:trustManagers>
+ </http:tlsClientParameters>
+ </http:conduit>
+</beans>
\ No newline at end of file
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/hostname/hostname-client.xml b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/hostname/hostname-client.xml
new file mode 100644
index 0000000..2dc090f
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/hostname/hostname-client.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:p="http://cxf.apache.org/policy"
+ xmlns:sec="http://cxf.apache.org/configuration/security"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache [...]
+
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+ <http:conduit name="https://localhost:.*">
+ <http:tlsClientParameters>
+ <sec:trustManagers>
+ <sec:keyStore type="jks" password="security" resource="keys/subjalt.jks"/>
+ </sec:trustManagers>
+ </http:tlsClientParameters>
+ </http:conduit>
+</beans>
\ No newline at end of file
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/hostname/hostname-server-deprecated.xml b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/hostname/hostname-server-deprecated.xml
new file mode 100644
index 0000000..2dc2675
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/hostname/hostname-server-deprecated.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
+ xmlns:sec="http://cxf.apache.org/configuration/security"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:p="http://cxf.apache.org/policy"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache.org/policy http://cxf.apache.org/schemas/policy.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/transports/http-jetty/confi [...]
+ <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"/>
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+
+ <httpj:engine-factory id="non-localhost-match-settings">
+ <httpj:engine port="${testutil.ports.HostnameVerificationDeprecatedServer}">
+ <httpj:tlsServerParameters>
+ <sec:keyManagers keyPassword="security">
+ <sec:keyStore type="jks" password="security" resource="keys/subjalt.jks"/>
+ </sec:keyManagers>
+ <sec:clientAuthentication want="false" required="false"/>
+ <sec:certAlias>nosubjaltcnnomatch</sec:certAlias>
+ </httpj:tlsServerParameters>
+ </httpj:engine>
+ </httpj:engine-factory>
+
+ <jaxws:endpoint xmlns:e="http://apache.org/hello_world/services"
+ xmlns:s="http://apache.org/hello_world/services"
+ id="NonLocalhostMatch"
+ implementor="org.apache.cxf.systest.hc5.GreeterImpl"
+ address="https://localhost:${testutil.ports.HostnameVerificationDeprecatedServer}/SoapContext/HttpsPort"
+ serviceName="s:SOAPService"
+ endpointName="e:HttpsPort" depends-on="non-localhost-match-settings"/>
+
+ <httpj:engine-factory id="no-subject-alt-cn-match-settings">
+ <httpj:engine port="${testutil.ports.HostnameVerificationDeprecatedServer.2}">
+ <httpj:tlsServerParameters>
+ <sec:keyManagers keyPassword="security">
+ <sec:keyStore type="jks" password="security" resource="keys/subjalt.jks"/>
+ </sec:keyManagers>
+ <sec:clientAuthentication want="false" required="false"/>
+ <sec:certAlias>nosubjaltcnmatch</sec:certAlias>
+ </httpj:tlsServerParameters>
+ </httpj:engine>
+ </httpj:engine-factory>
+
+ <jaxws:endpoint xmlns:e="http://apache.org/hello_world/services"
+ xmlns:s="http://apache.org/hello_world/services"
+ id="NoSubjectAltCNMatch"
+ implementor="org.apache.cxf.systest.hc5.GreeterImpl"
+ address="https://localhost:${testutil.ports.HostnameVerificationDeprecatedServer.2}/SoapContext/HttpsPort"
+ serviceName="s:SOAPService"
+ endpointName="e:HttpsPort" depends-on="no-subject-alt-cn-match-settings"/>
+
+ <httpj:engine-factory id="no-subject-alt-cn-wildcard-match-settings">
+ <httpj:engine port="${testutil.ports.HostnameVerificationDeprecatedServer.3}">
+ <httpj:tlsServerParameters>
+ <sec:keyManagers keyPassword="security">
+ <sec:keyStore type="jks" password="security" resource="keys/subjalt.jks"/>
+ </sec:keyManagers>
+ <sec:clientAuthentication want="false" required="false"/>
+ <sec:certAlias>nosubjaltcnmatchwildcard</sec:certAlias>
+ </httpj:tlsServerParameters>
+ </httpj:engine>
+ </httpj:engine-factory>
+
+ <jaxws:endpoint xmlns:e="http://apache.org/hello_world/services"
+ xmlns:s="http://apache.org/hello_world/services"
+ id="NoSubjectAltCNWildcardMatch"
+ implementor="org.apache.cxf.systest.hc5.GreeterImpl"
+ address="https://localhost:${testutil.ports.HostnameVerificationDeprecatedServer.3}/SoapContext/HttpsPort"
+ serviceName="s:SOAPService"
+ endpointName="e:HttpsPort" depends-on="no-subject-alt-cn-wildcard-match-settings"/>
+</beans>
\ No newline at end of file
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/hostname/hostname-server.xml b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/hostname/hostname-server.xml
new file mode 100644
index 0000000..a495e9e
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/hostname/hostname-server.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
+ xmlns:sec="http://cxf.apache.org/configuration/security"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:p="http://cxf.apache.org/policy"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache.org/policy http://cxf.apache.org/schemas/policy.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/transports/http-jetty/confi [...]
+ <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"/>
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+
+ <httpj:engine-factory id="subject-alt-match-settings">
+ <httpj:engine port="${testutil.ports.HostnameVerificationServer}">
+ <httpj:tlsServerParameters>
+ <sec:keyManagers keyPassword="security">
+ <sec:keyStore type="jks" password="security" resource="keys/subjalt.jks"/>
+ </sec:keyManagers>
+ <sec:clientAuthentication want="false" required="false"/>
+ <sec:certAlias>subjaltmatch</sec:certAlias>
+ </httpj:tlsServerParameters>
+ </httpj:engine>
+ </httpj:engine-factory>
+
+ <jaxws:endpoint xmlns:e="http://apache.org/hello_world/services"
+ xmlns:s="http://apache.org/hello_world/services"
+ id="SubjectAltMatch"
+ implementor="org.apache.cxf.systest.hc5.GreeterImpl"
+ address="https://localhost:${testutil.ports.HostnameVerificationServer}/SoapContext/HttpsPort"
+ serviceName="s:SOAPService"
+ endpointName="e:HttpsPort" depends-on="subject-alt-match-settings"/>
+
+
+ <httpj:engine-factory id="subject-alt-nomatch-settings">
+ <httpj:engine port="${testutil.ports.HostnameVerificationServer.2}">
+ <httpj:tlsServerParameters>
+ <sec:keyManagers keyPassword="security">
+ <sec:keyStore type="jks" password="security" resource="keys/subjalt.jks"/>
+ </sec:keyManagers>
+ <sec:clientAuthentication want="false" required="false"/>
+ <sec:certAlias>subjaltnomatch</sec:certAlias>
+ </httpj:tlsServerParameters>
+ </httpj:engine>
+ </httpj:engine-factory>
+
+ <jaxws:endpoint xmlns:e="http://apache.org/hello_world/services"
+ xmlns:s="http://apache.org/hello_world/services"
+ id="SubjectAltNoMatch"
+ implementor="org.apache.cxf.systest.hc5.GreeterImpl"
+ address="https://localhost:${testutil.ports.HostnameVerificationServer.2}/SoapContext/HttpsPort"
+ serviceName="s:SOAPService"
+ endpointName="e:HttpsPort" depends-on="subject-alt-nomatch-settings"/>
+
+
+ <httpj:engine-factory id="no-subject-alt-cn-match-settings">
+ <httpj:engine port="${testutil.ports.HostnameVerificationServer.3}">
+ <httpj:tlsServerParameters>
+ <sec:keyManagers keyPassword="security">
+ <sec:keyStore type="jks" password="security" resource="keys/subjalt.jks"/>
+ </sec:keyManagers>
+ <sec:clientAuthentication want="false" required="false"/>
+ <sec:certAlias>nosubjaltcnmatch</sec:certAlias>
+ </httpj:tlsServerParameters>
+ </httpj:engine>
+ </httpj:engine-factory>
+
+ <jaxws:endpoint xmlns:e="http://apache.org/hello_world/services"
+ xmlns:s="http://apache.org/hello_world/services"
+ id="NoSubjectAltCNMatch"
+ implementor="org.apache.cxf.systest.hc5.GreeterImpl"
+ address="https://localhost:${testutil.ports.HostnameVerificationServer.3}/SoapContext/HttpsPort"
+ serviceName="s:SOAPService"
+ endpointName="e:HttpsPort" depends-on="no-subject-alt-cn-match-settings"/>
+
+ <httpj:engine-factory id="no-subject-alt-no-cn-match-settings">
+ <httpj:engine port="${testutil.ports.HostnameVerificationServer.4}">
+ <httpj:tlsServerParameters>
+ <sec:keyManagers keyPassword="security">
+ <sec:keyStore type="jks" password="security" resource="keys/subjalt.jks"/>
+ </sec:keyManagers>
+ <sec:clientAuthentication want="false" required="false"/>
+ <sec:certAlias>nosubjaltcnnomatch</sec:certAlias>
+ </httpj:tlsServerParameters>
+ </httpj:engine>
+ </httpj:engine-factory>
+
+ <jaxws:endpoint xmlns:e="http://apache.org/hello_world/services"
+ xmlns:s="http://apache.org/hello_world/services"
+ id="NoSubjectAltNoCNMatch"
+ implementor="org.apache.cxf.systest.hc5.GreeterImpl"
+ address="https://localhost:${testutil.ports.HostnameVerificationServer.4}/SoapContext/HttpsPort"
+ serviceName="s:SOAPService"
+ endpointName="e:HttpsPort" depends-on="no-subject-alt-no-cn-match-settings"/>
+
+ <httpj:engine-factory id="no-subject-alt-cn-wildcard-match-settings">
+ <httpj:engine port="${testutil.ports.HostnameVerificationServer.5}">
+ <httpj:tlsServerParameters>
+ <sec:keyManagers keyPassword="security">
+ <sec:keyStore type="jks" password="security" resource="keys/subjalt.jks"/>
+ </sec:keyManagers>
+ <sec:clientAuthentication want="false" required="false"/>
+ <sec:certAlias>nosubjaltcnmatchwildcard</sec:certAlias>
+ </httpj:tlsServerParameters>
+ </httpj:engine>
+ </httpj:engine-factory>
+
+ <jaxws:endpoint xmlns:e="http://apache.org/hello_world/services"
+ xmlns:s="http://apache.org/hello_world/services"
+ id="NoSubjectAltCNWildcardMatch"
+ implementor="org.apache.cxf.systest.hc5.GreeterImpl"
+ address="https://localhost:${testutil.ports.HostnameVerificationServer.5}/SoapContext/HttpsPort"
+ serviceName="s:SOAPService"
+ endpointName="e:HttpsPort" depends-on="no-subject-alt-cn-wildcard-match-settings"/>
+</beans>
\ No newline at end of file
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/trust/client-trust-config.xml b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/trust/client-trust-config.xml
new file mode 100644
index 0000000..2bab3c9
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/trust/client-trust-config.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:p="http://cxf.apache.org/policy"
+ xmlns:sec="http://cxf.apache.org/configuration/security"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache [...]
+
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+
+ <http:conduit name="https://localhost:.*">
+ <http:tlsClientParameters disableCNCheck="true" />
+ </http:conduit>
+
+</beans>
\ No newline at end of file
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/trust/client-trust-empty-config.xml b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/trust/client-trust-empty-config.xml
new file mode 100644
index 0000000..d03df98
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/trust/client-trust-empty-config.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:p="http://cxf.apache.org/policy"
+ xmlns:sec="http://cxf.apache.org/configuration/security"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache [...]
+
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+
+ <http:conduit name="https://localhost:.*">
+ <http:tlsClientParameters disableCNCheck="true">
+ <sec:trustManagers>
+ <sec:keyStore/>
+ </sec:trustManagers>
+ </http:tlsClientParameters>
+ </http:conduit>
+
+</beans>
\ No newline at end of file
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/trust/client-trust-manager-ref.xml b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/trust/client-trust-manager-ref.xml
new file mode 100644
index 0000000..47803c1
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/trust/client-trust-manager-ref.xml
@@ -0,0 +1,42 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:p="http://cxf.apache.org/policy"
+ xmlns:sec="http://cxf.apache.org/configuration/security"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache [...]
+
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+
+ <bean id="trustManagers" class="org.apache.cxf.transport.https.InsecureTrustManager" factory-method="getNoOpX509TrustManagers"/>
+
+ <http:conduit name="https://localhost:.*">
+ <http:tlsClientParameters disableCNCheck="true">
+ <sec:trustManagers ref="trustManagers" />
+ </http:tlsClientParameters>
+ </http:conduit>
+
+</beans>
\ No newline at end of file
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/trust/client-trust.xml b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/trust/client-trust.xml
new file mode 100644
index 0000000..9e1885b
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/trust/client-trust.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:p="http://cxf.apache.org/policy"
+ xmlns:sec="http://cxf.apache.org/configuration/security"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache [...]
+
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+
+</beans>
\ No newline at end of file
diff --git a/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/trust/trust-server.xml b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/trust/trust-server.xml
new file mode 100644
index 0000000..38ee8bd
--- /dev/null
+++ b/systests/transport-hc5/src/test/resources/org/apache/cxf/systest/hc5/https/trust/trust-server.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
+ xmlns:sec="http://cxf.apache.org/configuration/security"
+ xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:p="http://cxf.apache.org/policy"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache.org/policy http://cxf.apache.org/schemas/policy.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/transports/http-jetty/confi [...]
+ <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"/>
+ <cxf:bus>
+ <cxf:features>
+ <cxf:logging/>
+ </cxf:features>
+ </cxf:bus>
+
+ <httpj:engine-factory id="tls-settings">
+ <httpj:engine port="${testutil.ports.TrustServer}">
+ <httpj:tlsServerParameters>
+ <sec:keyManagers keyPassword="password">
+ <sec:keyStore type="jks" password="password" resource="keys/Bethal.jks"/>
+ </sec:keyManagers>
+ <sec:clientAuthentication want="false" required="false"/>
+ </httpj:tlsServerParameters>
+ </httpj:engine>
+ <httpj:engine port="${testutil.ports.TrustServer.2}">
+ <httpj:tlsServerParameters>
+ <sec:keyManagers keyPassword="password">
+ <sec:keyStore type="jks" password="password" resource="keys/alice.jks"/>
+ </sec:keyManagers>
+ <sec:clientAuthentication want="false" required="false"/>
+ </httpj:tlsServerParameters>
+ </httpj:engine>
+ </httpj:engine-factory>
+
+ <jaxws:endpoint xmlns:e="http://apache.org/hello_world/services"
+ xmlns:s="http://apache.org/hello_world/services"
+ id="TrustServer"
+ implementor="org.apache.cxf.systest.hc5.GreeterImpl"
+ address="https://localhost:${testutil.ports.TrustServer}/SoapContext/HttpsPort"
+ serviceName="s:SOAPService"
+ endpointName="e:HttpsPort" depends-on="tls-settings"/>
+
+ <jaxws:endpoint xmlns:e="http://apache.org/hello_world/services"
+ xmlns:s="http://apache.org/hello_world/services"
+ id="TrustServer2"
+ implementor="org.apache.cxf.systest.hc5.GreeterImpl"
+ address="https://localhost:${testutil.ports.TrustServer.2}/SoapContext/HttpsPort"
+ serviceName="s:SOAPService"
+ endpointName="e:HttpsPort" depends-on="tls-settings"/>
+
+
+</beans>
\ No newline at end of file