You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2018/09/11 11:49:43 UTC
[cxf] branch master updated: CXF-5077 - Provide a way to define a
specific SSLContext to be used by HTTPConduit implementations
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/master by this push:
new 6db38f9 CXF-5077 - Provide a way to define a specific SSLContext to be used by HTTPConduit implementations
6db38f9 is described below
commit 6db38f9984b9c0bf6309a3d7e26d5a9ab8055d1f
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Tue Sep 11 11:34:15 2018 +0100
CXF-5077 - Provide a way to define a specific SSLContext to be used by HTTPConduit implementations
---
.../configuration/jsse/TLSClientParameters.java | 20 +++++
.../http/asyncclient/AsyncHTTPConduit.java | 38 +++++----
.../transport/https/HttpsURLConnectionFactory.java | 18 ++--
.../systest/https/clientauth/ClientAuthTest.java | 98 ++++++++++++++++++++++
4 files changed, 151 insertions(+), 23 deletions(-)
diff --git a/core/src/main/java/org/apache/cxf/configuration/jsse/TLSClientParameters.java b/core/src/main/java/org/apache/cxf/configuration/jsse/TLSClientParameters.java
index 51b85b6..6f4b0f4 100644
--- a/core/src/main/java/org/apache/cxf/configuration/jsse/TLSClientParameters.java
+++ b/core/src/main/java/org/apache/cxf/configuration/jsse/TLSClientParameters.java
@@ -21,6 +21,7 @@ package org.apache.cxf.configuration.jsse;
import java.util.List;
import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
/**
@@ -35,6 +36,7 @@ public class TLSClientParameters extends TLSParameterBase {
private boolean useHttpsURLConnectionDefaultSslSocketFactory;
private boolean useHttpsURLConnectionDefaultHostnameVerifier;
private HostnameVerifier hostnameVerifier;
+ private SSLContext sslContext;
/**
* Set custom HostnameVerifier
@@ -147,6 +149,9 @@ public class TLSClientParameters extends TLSParameterBase {
if (sslSocketFactory != null) {
hash = hash * 41 + System.identityHashCode(sslSocketFactory);
}
+ if (sslContext != null) {
+ hash = hash * 41 + System.identityHashCode(sslContext);
+ }
hash = hash(hash, useHttpsURLConnectionDefaultSslSocketFactory);
hash = hash(hash, useHttpsURLConnectionDefaultHostnameVerifier);
hash = hash(hash, sslCacheTimeout);
@@ -193,6 +198,7 @@ public class TLSClientParameters extends TLSParameterBase {
TLSClientParameters that = (TLSClientParameters)o;
boolean eq = disableCNCheck == that.disableCNCheck;
eq &= sslSocketFactory == that.sslSocketFactory;
+ eq &= sslContext == that.sslContext;
eq &= useHttpsURLConnectionDefaultSslSocketFactory == that.useHttpsURLConnectionDefaultSslSocketFactory;
eq &= useHttpsURLConnectionDefaultHostnameVerifier == that.useHttpsURLConnectionDefaultHostnameVerifier;
eq &= sslCacheTimeout == that.sslCacheTimeout;
@@ -258,4 +264,18 @@ public class TLSClientParameters extends TLSParameterBase {
}
return false;
}
+
+ /**
+ * Get the SSLContext parameter to use (if it has been set)
+ */
+ public SSLContext getSslContext() {
+ return sslContext;
+ }
+
+ /**
+ * Set an SSLContext parameter to use to create https connections
+ */
+ public void setSslContext(SSLContext sslContext) {
+ this.sslContext = sslContext;
+ }
}
diff --git a/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduit.java b/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduit.java
index 9c55b60..7df19ce 100755
--- a/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduit.java
+++ b/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduit.java
@@ -880,25 +880,31 @@ public class AsyncHTTPConduit extends URLConnectionHTTPConduit {
return sslContext;
}
- String provider = tlsClientParameters.getJsseProvider();
+ SSLContext ctx = null;
+ if (tlsClientParameters.getSslContext() != null) {
+ ctx = tlsClientParameters.getSslContext();
+ } else {
+ String provider = tlsClientParameters.getJsseProvider();
- String protocol = tlsClientParameters.getSecureSocketProtocol() != null ? tlsClientParameters
- .getSecureSocketProtocol() : "TLS";
+ String protocol = tlsClientParameters.getSecureSocketProtocol() != null ? tlsClientParameters
+ .getSecureSocketProtocol() : "TLS";
- SSLContext ctx = provider == null ? SSLContext.getInstance(protocol) : SSLContext
- .getInstance(protocol, provider);
- ctx.getClientSessionContext().setSessionTimeout(tlsClientParameters.getSslCacheTimeout());
+ ctx = provider == null ? SSLContext.getInstance(protocol) : SSLContext
+ .getInstance(protocol, provider);
+ ctx.getClientSessionContext().setSessionTimeout(tlsClientParameters.getSslCacheTimeout());
- KeyManager[] keyManagers = tlsClientParameters.getKeyManagers();
- KeyManager[] configuredKeyManagers = org.apache.cxf.transport.https.SSLUtils.configureKeyManagersWithCertAlias(
- tlsClientParameters, keyManagers);
+ KeyManager[] keyManagers = tlsClientParameters.getKeyManagers();
+ KeyManager[] configuredKeyManagers =
+ org.apache.cxf.transport.https.SSLUtils.configureKeyManagersWithCertAlias(
+ tlsClientParameters, keyManagers);
- TrustManager[] trustManagers = tlsClientParameters.getTrustManagers();
- if (trustManagers == null) {
- trustManagers = org.apache.cxf.configuration.jsse.SSLUtils.getDefaultTrustStoreManagers(LOG);
- }
+ TrustManager[] trustManagers = tlsClientParameters.getTrustManagers();
+ if (trustManagers == null) {
+ trustManagers = org.apache.cxf.configuration.jsse.SSLUtils.getDefaultTrustStoreManagers(LOG);
+ }
- ctx.init(configuredKeyManagers, trustManagers, tlsClientParameters.getSecureRandom());
+ ctx.init(configuredKeyManagers, trustManagers, tlsClientParameters.getSecureRandom());
+ }
sslContext = ctx;
lastTlsHash = hash;
@@ -923,9 +929,9 @@ public class AsyncHTTPConduit extends URLConnectionHTTPConduit {
sslengine.setEnabledCipherSuites(cipherSuites);
String protocol = tlsClientParameters.getSecureSocketProtocol() != null ? tlsClientParameters
- .getSecureSocketProtocol() : "TLS";
+ .getSecureSocketProtocol() : sslcontext.getProtocol();
- String p[] = findProtocols(protocol, sslengine.getSupportedProtocols());
+ String[] p = findProtocols(protocol, sslengine.getSupportedProtocols());
if (p != null) {
sslengine.setEnabledProtocols(p);
}
diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/https/HttpsURLConnectionFactory.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/https/HttpsURLConnectionFactory.java
index cced865..5b51b30 100644
--- a/rt/transports/http/src/main/java/org/apache/cxf/transport/https/HttpsURLConnectionFactory.java
+++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/https/HttpsURLConnectionFactory.java
@@ -138,11 +138,15 @@ public class HttpsURLConnectionFactory {
socketFactory = tlsClientParameters.getSSLSocketFactory();
} else if (socketFactory == null) {
- // ssl socket factory not yet instantiated, create a new one with tlsClientParameters's Trust
- // Managers, Key Managers, etc
- SSLContext ctx =
- org.apache.cxf.transport.https.SSLUtils.getSSLContext(tlsClientParameters);
+ SSLContext ctx = null;
+ if (tlsClientParameters.getSslContext() != null) {
+ // Use the SSLContext which was set
+ ctx = tlsClientParameters.getSslContext();
+ } else {
+ // Create socketfactory with tlsClientParameters's Trust Managers, Key Managers, etc
+ ctx = org.apache.cxf.transport.https.SSLUtils.getSSLContext(tlsClientParameters);
+ }
String[] cipherSuites =
SSLUtils.getCiphersuitesToInclude(tlsClientParameters.getCipherSuites(),
@@ -150,10 +154,10 @@ public class HttpsURLConnectionFactory {
ctx.getSocketFactory().getDefaultCipherSuites(),
SSLUtils.getSupportedCipherSuites(ctx),
LOG);
- // The SSLSocketFactoryWrapper enables certain cipher suites
- // from the policy.
+
+ // The SSLSocketFactoryWrapper enables certain cipher suites from the policy.
String protocol = tlsClientParameters.getSecureSocketProtocol() != null ? tlsClientParameters
- .getSecureSocketProtocol() : "TLS";
+ .getSecureSocketProtocol() : ctx.getProtocol();
socketFactory = new SSLSocketFactoryWrapper(ctx.getSocketFactory(), cipherSuites,
protocol);
//recalc the hashcode since some of the above MAY have changed the tlsClientParameters
diff --git a/systests/transports/src/test/java/org/apache/cxf/systest/https/clientauth/ClientAuthTest.java b/systests/transports/src/test/java/org/apache/cxf/systest/https/clientauth/ClientAuthTest.java
index 0160a69..11a7d23 100644
--- a/systests/transports/src/test/java/org/apache/cxf/systest/https/clientauth/ClientAuthTest.java
+++ b/systests/transports/src/test/java/org/apache/cxf/systest/https/clientauth/ClientAuthTest.java
@@ -35,6 +35,7 @@ import javax.net.ssl.SSLSession;
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;
@@ -412,6 +413,103 @@ public class ClientAuthTest extends AbstractBusClientServerTestBase {
}
}
+ // 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);
+
+ // 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("PKIX");
+ 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("PKIX");
+ 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);
+
+ // 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("PKIX");
+ 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("PKIX");
+ 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