This is an automated email from the ASF dual-hosted git repository. reta pushed a commit to branch 4.0.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit e2ebf8ac67d9928145f68f1e5479b8f23bf6d4aa Author: Radek Kraus <[email protected]> AuthorDate: Thu Oct 31 21:01:02 2024 +0100 [CXF-9074] Fix problem with custom SSLContext in TLSClientParameters (#2131) Fix problem in https communication, when Java HttpClient is used and custom SSLContext is registered in TLSClientParameters. (cherry picked from commit 85492df6c6c5ed18d0be3027482f84793f042efe) --- .../cxf/transport/http/HttpClientHTTPConduit.java | 1 + .../systest/https/conduit/HTTPSConduitTest.java | 84 +++++++++++++++++++++- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java index d40582d576..a59bc3e6a1 100644 --- a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java +++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java @@ -383,6 +383,7 @@ public class HttpClientHTTPConduit extends URLConnectionHTTPConduit { cb.sslContext(sslContext); } if (sslContext != null) { + cb.sslContext(sslContext); String[] supportedCiphers = org.apache.cxf.configuration.jsse.SSLUtils .getSupportedCipherSuites(sslContext); String[] cipherSuites = org.apache.cxf.configuration.jsse.SSLUtils diff --git a/systests/transports/src/test/java/org/apache/cxf/systest/https/conduit/HTTPSConduitTest.java b/systests/transports/src/test/java/org/apache/cxf/systest/https/conduit/HTTPSConduitTest.java index bcb9616c47..ae69692507 100644 --- a/systests/transports/src/test/java/org/apache/cxf/systest/https/conduit/HTTPSConduitTest.java +++ b/systests/transports/src/test/java/org/apache/cxf/systest/https/conduit/HTTPSConduitTest.java @@ -22,19 +22,29 @@ package org.apache.cxf.systest.https.conduit; import java.io.IOException; import java.io.InputStream; +import java.net.Socket; import java.net.URI; import java.net.URL; import java.security.GeneralSecurityException; import java.security.KeyStore; +import java.security.SecureRandom; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.TreeMap; +import javax.net.ssl.HostnameVerifier; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509ExtendedTrustManager; import javax.xml.namespace.QName; import org.apache.cxf.Bus; @@ -361,6 +371,78 @@ public class HTTPSConduitTest extends AbstractBusClientServerTestBase { */ @Test public void testHttpsBasicConnection() throws Exception { + // Use common/shared TLSClientParameters + testHttpsBasicConnection(tlsClientParameters); + } + + @Test + public void testHttpsBasicConnectionCustomSslContext() throws Exception { + // Use custom SSLContext registered in TLSClientParameters + SSLContext ctx = SSLContext.getInstance("TLSv1.3"); + try (InputStream keyStoreIs = ClassLoaderUtils.getResourceAsStream( + "keys/Morpit.jks", HTTPSConduitTest.class + )) { + KeyManager[] keyManagers = getKeyManagers(getKeyStore( + "JKS", keyStoreIs, "password"), "password" + ); + // I need to disable CN verification (as certificate contains Bethal as CN), + // but I cannot use TLSClientParameters.setDisableCNCheck(), because in this case + // URLCONNECTION is always used (see HttpClientHTTPConduit.setupConnection()) + // -> I must used own TrustManager without verification + TrustManager trustManager = new X509ExtendedTrustManager() { + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[] {}; + } + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) { + } + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) { + } + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) { + } + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) { + } + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) { + } + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) { + } + }; + ctx.init( + keyManagers, + new TrustManager[] {trustManager}, + SecureRandom.getInstance("SHA1PRNG") + ); + } + + // HostnameVerifier (disable host name verification) + class AllowAllHostnameVerifier implements HostnameVerifier { + @Override + public boolean verify(String host, SSLSession session) { + try { + Certificate[] certs = session.getPeerCertificates(); + return certs != null && certs[0] instanceof X509Certificate; + } catch (SSLPeerUnverifiedException e) { + return false; + } + } + } + + // TLSClientParameters (Custom SSLContext) + TLSClientParameters tlsClientParams = new TLSClientParameters(); + tlsClientParams.setSslContext(ctx); + // TLSClientParameters (disable host name verification - now needed only when URLConnection is used) + tlsClientParams.setHostnameVerifier(new AllowAllHostnameVerifier()); + + testHttpsBasicConnection(tlsClientParams); + } + + private void testHttpsBasicConnection(TLSClientParameters tlsClientParams) throws Exception { startServer("Bethal"); URL wsdl = getClass().getResource("greeting.wsdl"); @@ -392,7 +474,7 @@ public class HTTPSConduitTest extends AbstractBusClientServerTestBase { authPolicy.setPassword("password"); http.setClient(httpClientPolicy); - http.setTlsClientParameters(tlsClientParameters); + http.setTlsClientParameters(tlsClientParams); http.setAuthorization(authPolicy); configureProxy(client);
