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(