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

gnodet pushed a commit to branch camel-4.22.x
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/camel-4.22.x by this push:
     new 196de70405a0 [backport camel-4.22.x] CAMEL-25103: camel-vertx - Client 
authentication, cipher suites and protocols of SSLContextParameters are not 
applied (#27029)
196de70405a0 is described below

commit 196de70405a0076ac918aae76212ece7857ddf6b
Author: Guillaume Nodet <[email protected]>
AuthorDate: Tue Sep 29 08:32:24 2026 +0200

    [backport camel-4.22.x] CAMEL-25103: camel-vertx - Client authentication, 
cipher suites and protocols of SSLContextParameters are not applied (#27029)
---
 .../http/vertx/VertxPlatformHttpEngineTest.java    | 94 ++++++++++++++++++++++
 .../camel/component/vertx/common/VertxHelper.java  | 42 +++++++++-
 2 files changed, 134 insertions(+), 2 deletions(-)

diff --git 
a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
 
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
index d81479098864..2629d6c5bc19 100644
--- 
a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
+++ 
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
@@ -43,6 +43,7 @@ import 
io.vertx.ext.auth.authentication.AuthenticationProvider;
 import io.vertx.ext.auth.properties.PropertyFileAuthentication;
 import io.vertx.ext.web.handler.BasicAuthHandler;
 import org.apache.camel.CamelContext;
+import org.apache.camel.CamelExecutionException;
 import org.apache.camel.Message;
 import org.apache.camel.attachment.AttachmentMessage;
 import org.apache.camel.builder.RouteBuilder;
@@ -55,6 +56,7 @@ import org.apache.camel.model.rest.RestBindingMode;
 import org.apache.camel.model.rest.RestParamType;
 import org.apache.camel.spi.EmbeddedHttpService;
 import org.apache.camel.spi.RestConfiguration;
+import org.apache.camel.support.jsse.CipherSuitesParameters;
 import org.apache.camel.support.jsse.KeyManagersParameters;
 import org.apache.camel.support.jsse.KeyStoreParameters;
 import org.apache.camel.support.jsse.SSLContextParameters;
@@ -69,6 +71,7 @@ import org.junit.jupiter.api.extension.RegisterExtension;
 import static io.restassured.RestAssured.get;
 import static io.restassured.RestAssured.given;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.emptyOrNullString;
 import static org.hamcrest.Matchers.emptyString;
@@ -359,6 +362,97 @@ public class VertxPlatformHttpEngineTest {
         }
     }
 
+    @Test
+    public void testEngineSSLClientAuthenticationRequired() throws Exception {
+        final CamelContext context
+                = createCamelContextForTest(configuration -> 
configuration.setSslContextParameters(serverSSLParameters));
+
+        try {
+            // the client trusts the server but has no certificate
+            KeyStoreParameters truststoreParameters = new KeyStoreParameters();
+            truststoreParameters.setResource("jsse/truststore.jks");
+            truststoreParameters.setPassword("storepass");
+            TrustManagersParameters trustManagers = new 
TrustManagersParameters();
+            trustManagers.setKeyStore(truststoreParameters);
+            SSLContextParameters noCertificate = new SSLContextParameters();
+            noCertificate.setTrustManagers(trustManagers);
+            context.getRegistry().bind("noCertificate", noCertificate);
+
+            context.addRoutes(new RouteBuilder() {
+                @Override
+                public void configure() {
+                    from("platform-http:/")
+                            .transform().body(String.class, b -> 
b.toUpperCase());
+                }
+            });
+
+            context.start();
+
+            // client authentication is required
+            assertThatThrownBy(() -> context.createFluentProducerTemplate()
+                    
.toF("https://localhost:%d?sslContextParameters=#noCertificate";, 
RestAssured.port)
+                    .withBody("test")
+                    .request(String.class))
+                    .isInstanceOf(CamelExecutionException.class);
+        } finally {
+            context.stop();
+        }
+    }
+
+    @Test
+    public void testEngineSSLCipherSuites() throws Exception {
+        KeyStoreParameters keystoreParameters = new KeyStoreParameters();
+        keystoreParameters.setResource("jsse/service.jks");
+        keystoreParameters.setPassword("security");
+        KeyManagersParameters keyManagers = new KeyManagersParameters();
+        keyManagers.setKeyPassword("security");
+        keyManagers.setKeyStore(keystoreParameters);
+        KeyStoreParameters truststoreParameters = new KeyStoreParameters();
+        truststoreParameters.setResource("jsse/truststore.jks");
+        truststoreParameters.setPassword("storepass");
+        TrustManagersParameters trustManagers = new TrustManagersParameters();
+        trustManagers.setKeyStore(truststoreParameters);
+
+        // the server only allows one cipher suite
+        SSLContextParameters server = new SSLContextParameters();
+        server.setKeyManagers(keyManagers);
+        server.setTrustManagers(trustManagers);
+        CipherSuitesParameters serverSuites = new CipherSuitesParameters();
+        serverSuites.setCipherSuite(List.of("TLS_AES_256_GCM_SHA384"));
+        server.setCipherSuites(serverSuites);
+
+        // and the client only another cipher suite
+        SSLContextParameters client = new SSLContextParameters();
+        client.setKeyManagers(keyManagers);
+        client.setTrustManagers(trustManagers);
+        CipherSuitesParameters clientSuites = new CipherSuitesParameters();
+        clientSuites.setCipherSuite(List.of("TLS_AES_128_GCM_SHA256"));
+        client.setCipherSuites(clientSuites);
+
+        final CamelContext context = createCamelContextForTest(configuration 
-> configuration.setSslContextParameters(server));
+
+        try {
+            context.getRegistry().bind("client", client);
+            context.addRoutes(new RouteBuilder() {
+                @Override
+                public void configure() {
+                    from("platform-http:/")
+                            .transform().body(String.class, b -> 
b.toUpperCase());
+                }
+            });
+
+            context.start();
+
+            assertThatThrownBy(() -> context.createFluentProducerTemplate()
+                    .toF("https://localhost:%d?sslContextParameters=#client";, 
RestAssured.port)
+                    .withBody("test")
+                    .request(String.class))
+                    .isInstanceOf(CamelExecutionException.class);
+        } finally {
+            context.stop();
+        }
+    }
+
     @Test
     public void testEngineGlobalSSL() throws Exception {
         final CamelContext context
diff --git 
a/components/camel-vertx/camel-vertx-common/src/main/java/org/apache/camel/component/vertx/common/VertxHelper.java
 
b/components/camel-vertx/camel-vertx-common/src/main/java/org/apache/camel/component/vertx/common/VertxHelper.java
index 298a3a3f894a..20a1387785e3 100644
--- 
a/components/camel-vertx/camel-vertx-common/src/main/java/org/apache/camel/component/vertx/common/VertxHelper.java
+++ 
b/components/camel-vertx/camel-vertx-common/src/main/java/org/apache/camel/component/vertx/common/VertxHelper.java
@@ -17,13 +17,20 @@
 package org.apache.camel.component.vertx.common;
 
 import java.security.KeyStore;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Locale;
 
 import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLEngine;
 import javax.net.ssl.TrustManagerFactory;
 
+import io.vertx.core.http.ClientAuth;
+import io.vertx.core.net.NetServerOptions;
 import io.vertx.core.net.TCPSSLOptions;
 import io.vertx.core.net.TrustOptions;
 import org.apache.camel.CamelContext;
+import org.apache.camel.support.jsse.ClientAuthentication;
 import org.apache.camel.support.jsse.KeyManagersParameters;
 import org.apache.camel.support.jsse.SSLContextParameters;
 import org.apache.camel.support.jsse.TrustAllTrustManager;
@@ -36,8 +43,8 @@ public final class VertxHelper {
     }
 
     /**
-     * Configures key store and trust store options for the given 
TCPSSLOptions from the configuration specified on
-     * SSLContextParameters
+     * Configures key store and trust store options, the client authentication 
(of a server) and the cipher suites and
+     * protocols for the given TCPSSLOptions from the configuration specified 
on SSLContextParameters
      *
      * @param camelContext         the CamelContext
      * @param sslContextParameters the SSL configuration to use for the 
KeyManagerFactory & TrustManagerFactory
@@ -76,6 +83,37 @@ public final class VertxHelper {
             
tcpsslOptions.setTrustOptions(TrustOptions.wrap(TrustAllTrustManager.INSTANCE));
         }
 
+        // client authentication of a server
+        if (tcpsslOptions instanceof NetServerOptions serverOptions
+                && sslContextParameters.getServerParameters() != null
+                && 
sslContextParameters.getServerParameters().getClientAuthentication() != null) {
+            String value = camelContext.resolvePropertyPlaceholders(
+                    
sslContextParameters.getServerParameters().getClientAuthentication());
+            ClientAuthentication clientAuthentication = 
ClientAuthentication.valueOf(value.toUpperCase(Locale.ENGLISH));
+            serverOptions.setClientAuth(switch (clientAuthentication) {
+                case REQUIRE -> ClientAuth.REQUIRED;
+                case WANT -> ClientAuth.REQUEST;
+                case NONE -> ClientAuth.NONE;
+            });
+        }
+
+        // the cipher suites and protocols (when configured) as computed by 
the SSLContextParameters
+        // (such as from the include and exclude filters)
+        boolean cipherSuites = sslContextParameters.getCipherSuites() != null
+                || sslContextParameters.getCipherSuitesFilter() != null;
+        boolean protocols = sslContextParameters.getSecureSocketProtocols() != 
null
+                || sslContextParameters.getSecureSocketProtocolsFilter() != 
null;
+        if (cipherSuites || protocols) {
+            SSLEngine engine = 
sslContextParameters.createSSLContext(camelContext).createSSLEngine();
+            if (cipherSuites) {
+                for (String suite : engine.getEnabledCipherSuites()) {
+                    tcpsslOptions.addEnabledCipherSuite(suite);
+                }
+            }
+            if (protocols) {
+                tcpsslOptions.setEnabledSecureTransportProtocols(new 
LinkedHashSet<>(List.of(engine.getEnabledProtocols())));
+            }
+        }
     }
 
     private static KeyManagerFactory createKeyManagerFactory(

Reply via email to