This is an automated email from the ASF dual-hosted git repository.

coheigea pushed a commit to branch 3.2.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/3.2.x-fixes by this push:
     new 00fa31e  CXF-5077 - Provide a way to define a specific SSLContext to 
be used by HTTPConduit implementations
00fa31e is described below

commit 00fa31ef54423cb1d05650e16d6b813f1b968bc0
Author: Colm O hEigeartaigh <cohei...@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
    
    (cherry picked from commit 6db38f9984b9c0bf6309a3d7e26d5a9ab8055d1f)
---
 .../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

Reply via email to