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

acosentino pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 5e8baf46787e CAMEL-23159 - Post-Quantum Cryptography (PQC) readiness: 
Add signatureSchemes support to BaseSSLContextParameters and 
SSLConfigurationProperties for PQC readiness (#21875)
5e8baf46787e is described below

commit 5e8baf46787e66c97268b78eb470620e1322c42e
Author: Andrea Cosentino <[email protected]>
AuthorDate: Mon Mar 9 16:22:54 2026 +0100

    CAMEL-23159 - Post-Quantum Cryptography (PQC) readiness: Add 
signatureSchemes support to BaseSSLContextParameters and 
SSLConfigurationProperties for PQC readiness (#21875)
    
    Add full TLS signature schemes configuration support mirroring the existing
    named groups pattern, enabling PQC signature algorithms like ML-DSA to be
    configured for TLS handshakes across all Camel components.
    
    Core API (BaseSSLContextParameters):
    - Add SignatureSchemesParameters POJO with List<String> signatureScheme
    - Add signatureSchemes and signatureSchemesFilter fields
    - Add resolveSignatureSchemes() helper for filter-based resolution
    - Wire into all 3 SSL configurers (SSLEngine, SSLSocket, SSLServerSocket)
      calling SSLParameters.setSignatureSchemes()
    - Add SignatureSchemesParametersDefinition JAXB XML binding
    - Wire into AbstractBaseSSLContextParametersFactoryBean
    
    Camel Main (SSLConfigurationProperties):
    - Add camel.ssl.signatureSchemes property (comma-separated list)
    - Add camel.ssl.signatureSchemesInclude/Exclude filter properties
    - Add mapping logic in BaseMainSupport.createSSLContextParameters()
    - Update generated configurer, metadata, and documentation
    
    Tests:
    - 3 new JSSE-level tests in SSLContextParametersTest (explicit config,
      filter, isolation)
    - 4 new Main config tests in MainSSLTest (property-based, fluent,
      filter property-based, fluent filter)
    
    Signed-off-by: Andrea Cosentino <[email protected]>
---
 .../main/camel-main-configuration-metadata.json    |   3 +
 .../apache/camel/catalog/schemas/camel-spring.xsd  |  11 ++
 .../support/jsse/BaseSSLContextParameters.java     | 202 +++++++++++++++++++++
 .../support/jsse/SignatureSchemesParameters.java   |  65 +++++++
 .../org/apache/camel/core/xml/util/jsse/jaxb.index |   1 +
 ...bstractBaseSSLContextParametersFactoryBean.java |  31 ++++
 .../jsse/SignatureSchemesParametersDefinition.java |  46 +++++
 .../support/jsse/SSLContextParametersTest.java     | 145 +++++++++++++++
 .../main/SSLConfigurationPropertiesConfigurer.java |  21 +++
 .../camel-main-configuration-metadata.json         |   3 +
 core/camel-main/src/main/docs/main.adoc            |   5 +-
 .../org/apache/camel/main/BaseMainSupport.java     |  22 +++
 .../camel/main/SSLConfigurationProperties.java     |  89 +++++++++
 .../java/org/apache/camel/main/MainSSLTest.java    | 128 +++++++++++++
 14 files changed, 771 insertions(+), 1 deletion(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
index 5e5d6ba74821..1b156fda5539 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
@@ -351,6 +351,9 @@
     { "name": "camel.ssl.secureRandomProvider", "required": false, 
"description": "To use a specific provider for creating SecureRandom. The list 
of available providers returned by java.security.Security.getProviders() or 
null to use the highest priority provider implementing the secure socket 
protocol.", "sourceType": "org.apache.camel.main.SSLConfigurationProperties", 
"type": "string", "javaType": "java.lang.String", "secret": false },
     { "name": "camel.ssl.secureSocketProtocol", "required": false, 
"description": "The protocol for the secure sockets created by the SSLContext. 
See 
https:\/\/docs.oracle.com\/en\/java\/javase\/17\/docs\/specs\/security\/standard-names.html",
 "sourceType": "org.apache.camel.main.SSLConfigurationProperties", "type": 
"string", "javaType": "java.lang.String", "defaultValue": "TLSv1.3", "secret": 
false },
     { "name": "camel.ssl.sessionTimeout", "required": false, "description": 
"Timeout in seconds to use for SSLContext. The default is 24 hours.", 
"sourceType": "org.apache.camel.main.SSLConfigurationProperties", "type": 
"integer", "javaType": "int", "defaultValue": 86400, "secret": false },
+    { "name": "camel.ssl.signatureSchemes", "required": false, "description": 
"List of TLS\/SSL signature schemes. Multiple names can be separated by comma. 
Signature schemes control which signature algorithms are available during the 
TLS handshake, including post-quantum signature algorithms such as ML-DSA.", 
"sourceType": "org.apache.camel.main.SSLConfigurationProperties", "type": 
"string", "javaType": "java.lang.String", "secret": false },
+    { "name": "camel.ssl.signatureSchemesExclude", "required": false, 
"description": "Filters TLS\/SSL signature schemes. This filter is used for 
excluding signature schemes that match the naming pattern. Multiple names can 
be separated by comma. Notice that if the signatureSchemes option has been 
configured then the include\/exclude filters are not in use.", "sourceType": 
"org.apache.camel.main.SSLConfigurationProperties", "type": "string", 
"javaType": "java.lang.String", "secret": false },
+    { "name": "camel.ssl.signatureSchemesInclude", "required": false, 
"description": "Filters TLS\/SSL signature schemes. This filter is used for 
including signature schemes that match the naming pattern. Multiple names can 
be separated by comma. Notice that if the signatureSchemes option has been 
configured then the include\/exclude filters are not in use.", "sourceType": 
"org.apache.camel.main.SSLConfigurationProperties", "type": "string", 
"javaType": "java.lang.String", "secret": false },
     { "name": "camel.ssl.trustAllCertificates", "required": false, 
"description": "Allows to trust all SSL certificates without performing 
certificate validation. This can be used in development environment but may 
expose the system to security risks. Notice that if the trustAllCertificates 
option is set to true then the trustStore\/trustStorePassword options are not 
in use.", "sourceType": "org.apache.camel.main.SSLConfigurationProperties", 
"type": "boolean", "javaType": "boolean", "def [...]
     { "name": "camel.ssl.trustStore", "required": false, "description": "The 
trust store to load. The trust store is by default loaded from classpath. If 
you must load from file system, then use file: as prefix. file:nameOfFile (to 
refer to the file system) classpath:nameOfFile (to refer to the classpath; 
default) http:uri (to load the resource using HTTP) ref:nameOfBean (to lookup 
an existing KeyStore instance from the registry, for example for testing and 
development).", "sourceType":  [...]
     { "name": "camel.ssl.trustStorePassword", "required": false, 
"description": "Sets the SSL Truststore password.", "sourceType": 
"org.apache.camel.main.SSLConfigurationProperties", "type": "string", 
"javaType": "java.lang.String", "secret": false },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
index 235f087ea21e..5b7f7fd8ba57 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
@@ -3492,6 +3492,11 @@ configuration.
       <xs:element maxOccurs="unbounded" minOccurs="0" 
name="secureSocketProtocol" nillable="true" type="xs:string"/>
     </xs:sequence>
   </xs:complexType>
+  <xs:complexType name="signatureSchemesParameters">
+    <xs:sequence>
+      <xs:element maxOccurs="unbounded" minOccurs="0" name="signatureScheme" 
nillable="true" type="xs:string"/>
+    </xs:sequence>
+  </xs:complexType>
   <xs:complexType name="output">
     <xs:complexContent>
       <xs:extension base="tns:processorDefinition">
@@ -18053,6 +18058,8 @@ converter. The default logging level is DEBUG. Default 
value: DEBUG
           <xs:element minOccurs="0" name="secureSocketProtocolsFilter" 
type="tns:filterParameters"/>
           <xs:element minOccurs="0" name="namedGroups" 
type="tns:namedGroupsParameters"/>
           <xs:element minOccurs="0" name="namedGroupsFilter" 
type="tns:filterParameters"/>
+          <xs:element minOccurs="0" name="signatureSchemes" 
type="tns:signatureSchemesParameters"/>
+          <xs:element minOccurs="0" name="signatureSchemesFilter" 
type="tns:filterParameters"/>
           <xs:element minOccurs="0" name="sniHostNames" 
type="tns:sniHostNames"/>
         </xs:all>
         <xs:attribute name="sessionTimeout" type="xs:string"/>
@@ -18069,6 +18076,8 @@ converter. The default logging level is DEBUG. Default 
value: DEBUG
           <xs:element minOccurs="0" name="secureSocketProtocolsFilter" 
type="tns:filterParameters"/>
           <xs:element minOccurs="0" name="namedGroups" 
type="tns:namedGroupsParameters"/>
           <xs:element minOccurs="0" name="namedGroupsFilter" 
type="tns:filterParameters"/>
+          <xs:element minOccurs="0" name="signatureSchemes" 
type="tns:signatureSchemesParameters"/>
+          <xs:element minOccurs="0" name="signatureSchemesFilter" 
type="tns:filterParameters"/>
           <xs:element minOccurs="0" name="keyManagers" 
type="tns:keyManagersParametersFactoryBean"/>
           <xs:element minOccurs="0" name="trustManagers" 
type="tns:trustManagersParametersFactoryBean"/>
           <xs:element minOccurs="0" name="secureRandom" 
type="tns:secureRandomParametersFactoryBean"/>
@@ -18141,6 +18150,8 @@ An optional certificate alias to use. This is useful 
when the keystore has multi
           <xs:element minOccurs="0" name="secureSocketProtocolsFilter" 
type="tns:filterParameters"/>
           <xs:element minOccurs="0" name="namedGroups" 
type="tns:namedGroupsParameters"/>
           <xs:element minOccurs="0" name="namedGroupsFilter" 
type="tns:filterParameters"/>
+          <xs:element minOccurs="0" name="signatureSchemes" 
type="tns:signatureSchemesParameters"/>
+          <xs:element minOccurs="0" name="signatureSchemesFilter" 
type="tns:filterParameters"/>
         </xs:all>
         <xs:attribute name="sessionTimeout" type="xs:string"/>
         <xs:attribute name="clientAuthentication" type="xs:string"/>
diff --git 
a/core/camel-api/src/main/java/org/apache/camel/support/jsse/BaseSSLContextParameters.java
 
b/core/camel-api/src/main/java/org/apache/camel/support/jsse/BaseSSLContextParameters.java
index 3c1a464f7d04..0356459cd8f2 100644
--- 
a/core/camel-api/src/main/java/org/apache/camel/support/jsse/BaseSSLContextParameters.java
+++ 
b/core/camel-api/src/main/java/org/apache/camel/support/jsse/BaseSSLContextParameters.java
@@ -89,6 +89,13 @@ public abstract class BaseSSLContextParameters extends 
JsseParameters {
 
     private static final String SSL_SERVER_SOCKET_NAMED_GROUP_LOG_MSG = 
createNamedGroupLogMessage("SSLServerSocket");
 
+    private static final String SSL_ENGINE_SIGNATURE_SCHEME_LOG_MSG = 
createSignatureSchemeLogMessage("SSLEngine");
+
+    private static final String SSL_SOCKET_SIGNATURE_SCHEME_LOG_MSG = 
createSignatureSchemeLogMessage("SSLSocket");
+
+    private static final String SSL_SERVER_SOCKET_SIGNATURE_SCHEME_LOG_MSG
+            = createSignatureSchemeLogMessage("SSLServerSocket");
+
     /**
      * The optional explicitly configured cipher suites for this configuration.
      */
@@ -121,6 +128,18 @@ public abstract class BaseSSLContextParameters extends 
JsseParameters {
      */
     private FilterParameters namedGroupsFilter;
 
+    /**
+     * The optional explicitly configured signature schemes for this 
configuration. Signature schemes control which
+     * signature algorithms are available during the TLS handshake, including 
post-quantum signature algorithms such as
+     * ML-DSA.
+     */
+    private SignatureSchemesParameters signatureSchemes;
+
+    /**
+     * The optional signature schemes filter configuration for this 
configuration.
+     */
+    private FilterParameters signatureSchemesFilter;
+
     /**
      * The optional {@link SSLSessionContext} timeout time for {@link 
javax.net.ssl.SSLSession}s in seconds.
      */
@@ -284,6 +303,62 @@ public abstract class BaseSSLContextParameters extends 
JsseParameters {
         this.namedGroupsFilter = namedGroupsFilter;
     }
 
+    /**
+     * Returns the optional explicitly configured signature schemes for this 
configuration. These options are used in
+     * the configuration of {@link SSLEngine}, {@link SSLSocketFactory} and 
{@link SSLServerSocketFactory} depending on
+     * the context in which they are applied.
+     * <p/>
+     * Signature schemes control which signature algorithms are available 
during the TLS handshake, including
+     * post-quantum signature algorithms such as ML-DSA.
+     * <p/>
+     * These values override any filters supplied in {@link 
#setSignatureSchemesFilter(FilterParameters)}
+     */
+    public SignatureSchemesParameters getSignatureSchemes() {
+        return signatureSchemes;
+    }
+
+    /**
+     * Sets the optional explicitly configured signature schemes for this 
configuration. These options are used in the
+     * configuration of {@link SSLEngine}, {@link SSLSocketFactory} and {@link 
SSLServerSocketFactory} depending on the
+     * context in which they are applied.
+     * <p/>
+     * Signature schemes control which signature algorithms are available 
during the TLS handshake, including
+     * post-quantum signature algorithms such as ML-DSA.
+     * <p/>
+     * These values override any filters supplied in {@link 
#setSignatureSchemesFilter(FilterParameters)}
+     *
+     * @param signatureSchemes the signature schemes configuration
+     */
+    public void setSignatureSchemes(SignatureSchemesParameters 
signatureSchemes) {
+        this.signatureSchemes = signatureSchemes;
+    }
+
+    /**
+     * Returns the optional signature schemes filter for this configuration. 
These options are used in the configuration
+     * of {@link SSLEngine}, {@link SSLSocketFactory} and {@link 
SSLServerSocketFactory} depending on the context in
+     * which they are applied.
+     * <p/>
+     * These values are ignored if {@link 
#setSignatureSchemes(SignatureSchemesParameters)} is called with a non
+     * {@code null} argument.
+     */
+    public FilterParameters getSignatureSchemesFilter() {
+        return signatureSchemesFilter;
+    }
+
+    /**
+     * Sets the optional signature schemes filter for this JSSE configuration. 
These options are used in the
+     * configuration of {@link SSLEngine}, {@link SSLSocketFactory} and {@link 
SSLServerSocketFactory} depending on the
+     * context in which they are applied.
+     * <p/>
+     * These values are ignored if {@link 
#setSignatureSchemes(SignatureSchemesParameters)} is called with a non
+     * {@code null} argument.
+     *
+     * @param signatureSchemesFilter the filter configuration
+     */
+    public void setSignatureSchemesFilter(FilterParameters 
signatureSchemesFilter) {
+        this.signatureSchemesFilter = signatureSchemesFilter;
+    }
+
     /**
      * Returns the optional {@link SSLSessionContext} timeout time for {@link 
javax.net.ssl.SSLSession}s in seconds.
      */
@@ -399,6 +474,17 @@ public abstract class BaseSSLContextParameters extends 
JsseParameters {
             enabledNamedGroupsPatterns = null;
         }
 
+        final List<String> enabledSignatureSchemes = 
this.getSignatureSchemes() == null
+                ? null : 
this.parsePropertyValues(this.getSignatureSchemes().getSignatureScheme());
+
+        final Patterns enabledSignatureSchemesPatterns;
+
+        if (this.getSignatureSchemesFilter() != null) {
+            enabledSignatureSchemesPatterns = 
this.getSignatureSchemesFilter().getPatterns();
+        } else {
+            enabledSignatureSchemesPatterns = null;
+        }
+
         //
 
         final boolean allowPassthrough = getAllowPassthrough();
@@ -466,6 +552,23 @@ public abstract class BaseSSLContextParameters extends 
JsseParameters {
                     engine.setSSLParameters(params);
                 }
 
+                String[] signatureSchemes = resolveSignatureSchemes(
+                        engine.getSSLParameters().getSignatureSchemes(),
+                        enabledSignatureSchemes, 
enabledSignatureSchemesPatterns);
+                if (signatureSchemes != null) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug(SSL_ENGINE_SIGNATURE_SCHEME_LOG_MSG,
+                                engine,
+                                enabledSignatureSchemes,
+                                enabledSignatureSchemesPatterns,
+                                
engine.getSSLParameters().getSignatureSchemes(),
+                                signatureSchemes);
+                    }
+                    SSLParameters params = engine.getSSLParameters();
+                    params.setSignatureSchemes(signatureSchemes);
+                    engine.setSSLParameters(params);
+                }
+
                 return engine;
             }
         };
@@ -592,6 +695,17 @@ public abstract class BaseSSLContextParameters extends 
JsseParameters {
             enabledNamedGroupsPatterns = null;
         }
 
+        final List<String> enabledSignatureSchemes = 
this.getSignatureSchemes() == null
+                ? null : 
this.parsePropertyValues(this.getSignatureSchemes().getSignatureScheme());
+
+        final Patterns enabledSignatureSchemesPatterns;
+
+        if (this.getSignatureSchemesFilter() != null) {
+            enabledSignatureSchemesPatterns = 
this.getSignatureSchemesFilter().getPatterns();
+        } else {
+            enabledSignatureSchemesPatterns = null;
+        }
+
         //
 
         final boolean allowPassthrough = getAllowPassthrough();
@@ -664,6 +778,23 @@ public abstract class BaseSSLContextParameters extends 
JsseParameters {
                     socket.setSSLParameters(params);
                 }
 
+                String[] signatureSchemes = resolveSignatureSchemes(
+                        socket.getSSLParameters().getSignatureSchemes(),
+                        enabledSignatureSchemes, 
enabledSignatureSchemesPatterns);
+                if (signatureSchemes != null) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug(SSL_SOCKET_SIGNATURE_SCHEME_LOG_MSG,
+                                socket,
+                                enabledSignatureSchemes,
+                                enabledSignatureSchemesPatterns,
+                                
socket.getSSLParameters().getSignatureSchemes(),
+                                signatureSchemes);
+                    }
+                    SSLParameters params = socket.getSSLParameters();
+                    params.setSignatureSchemes(signatureSchemes);
+                    socket.setSSLParameters(params);
+                }
+
                 return socket;
             }
         };
@@ -720,6 +851,17 @@ public abstract class BaseSSLContextParameters extends 
JsseParameters {
             enabledNamedGroupsPatterns = null;
         }
 
+        final List<String> enabledSignatureSchemes = 
this.getSignatureSchemes() == null
+                ? null : 
this.parsePropertyValues(this.getSignatureSchemes().getSignatureScheme());
+
+        final Patterns enabledSignatureSchemesPatterns;
+
+        if (this.getSignatureSchemesFilter() != null) {
+            enabledSignatureSchemesPatterns = 
this.getSignatureSchemesFilter().getPatterns();
+        } else {
+            enabledSignatureSchemesPatterns = null;
+        }
+
         //
 
         final boolean allowPassthrough = getAllowPassthrough();
@@ -787,6 +929,23 @@ public abstract class BaseSSLContextParameters extends 
JsseParameters {
                     socket.setSSLParameters(params);
                 }
 
+                String[] signatureSchemes = resolveSignatureSchemes(
+                        socket.getSSLParameters().getSignatureSchemes(),
+                        enabledSignatureSchemes, 
enabledSignatureSchemesPatterns);
+                if (signatureSchemes != null) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug(SSL_SERVER_SOCKET_SIGNATURE_SCHEME_LOG_MSG,
+                                socket,
+                                enabledSignatureSchemes,
+                                enabledSignatureSchemesPatterns,
+                                
socket.getSSLParameters().getSignatureSchemes(),
+                                signatureSchemes);
+                    }
+                    SSLParameters params = socket.getSSLParameters();
+                    params.setSignatureSchemes(signatureSchemes);
+                    socket.setSSLParameters(params);
+                }
+
                 return socket;
             }
         };
@@ -962,6 +1121,41 @@ public abstract class BaseSSLContextParameters extends 
JsseParameters {
         return filteredNamedGroups.toArray(new String[0]);
     }
 
+    /**
+     * Resolves the signature schemes to configure based on explicit values or 
filter patterns. Returns {@code null} if
+     * no signature schemes configuration is needed (both parameters are 
{@code null}).
+     *
+     * @param  currentSignatureSchemes         the currently available 
signature schemes from the SSL object
+     * @param  enabledSignatureSchemes         the optional explicit signature 
schemes list
+     * @param  enabledSignatureSchemesPatterns the optional filter patterns
+     *
+     * @return                                 the filtered signature schemes 
array, or {@code null} if no configuration
+     *                                         is needed
+     */
+    private String[] resolveSignatureSchemes(
+            String[] currentSignatureSchemes, List<String> 
enabledSignatureSchemes,
+            Patterns enabledSignatureSchemesPatterns) {
+
+        if (enabledSignatureSchemes == null && enabledSignatureSchemesPatterns 
== null) {
+            return null;
+        }
+
+        if (currentSignatureSchemes == null) {
+            currentSignatureSchemes = new String[0];
+        }
+
+        Collection<String> filteredSignatureSchemes;
+        if (enabledSignatureSchemes != null) {
+            filteredSignatureSchemes = new 
ArrayList<>(enabledSignatureSchemes);
+        } else {
+            filteredSignatureSchemes = this.filter(
+                    null, Arrays.asList(currentSignatureSchemes),
+                    enabledSignatureSchemesPatterns.getIncludes(), 
enabledSignatureSchemesPatterns.getExcludes());
+        }
+
+        return filteredSignatureSchemes.toArray(new String[0]);
+    }
+
     /**
      * Configures a {@code T} based on the related configuration options.
      */
@@ -1308,4 +1502,12 @@ public abstract class BaseSSLContextParameters extends 
JsseParameters {
                + "\t available named groups [{}]," + LS
                + "\t Resulting enabled named groups are [{}].";
     }
+
+    private static String createSignatureSchemeLogMessage(String entityName) {
+        return "Configuring " + entityName + " [{}] with " + LS
+               + "\t explicitly set signature schemes [{}]," + LS
+               + "\t signature scheme patterns [{}]," + LS
+               + "\t available signature schemes [{}]," + LS
+               + "\t Resulting enabled signature schemes are [{}].";
+    }
 }
diff --git 
a/core/camel-api/src/main/java/org/apache/camel/support/jsse/SignatureSchemesParameters.java
 
b/core/camel-api/src/main/java/org/apache/camel/support/jsse/SignatureSchemesParameters.java
new file mode 100644
index 000000000000..bb13c65825b3
--- /dev/null
+++ 
b/core/camel-api/src/main/java/org/apache/camel/support/jsse/SignatureSchemesParameters.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.support.jsse;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a list of TLS/SSL signature schemes for use in TLS handshakes. 
Signature schemes control which signature
+ * algorithms are available during the TLS handshake, including post-quantum 
signature algorithms such as ML-DSA.
+ */
+public class SignatureSchemesParameters {
+    private List<String> signatureScheme;
+
+    /**
+     * Returns a live reference to the list of signature scheme names.
+     *
+     * @return a reference to the list, never {@code null}
+     */
+    public List<String> getSignatureScheme() {
+        if (this.signatureScheme == null) {
+            this.signatureScheme = new ArrayList<>();
+        }
+        return this.signatureScheme;
+    }
+
+    public void addSignatureScheme(String scheme) {
+        if (this.signatureScheme == null) {
+            this.signatureScheme = new ArrayList<>();
+        }
+        this.signatureScheme.add(scheme.trim());
+    }
+
+    /**
+     * Sets the signature schemes. It creates a copy of the given list.
+     *
+     * @param signatureScheme signature schemes
+     */
+    public void setSignatureScheme(List<String> signatureScheme) {
+        this.signatureScheme = signatureScheme == null ? null : new 
ArrayList<>(signatureScheme);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("SignatureSchemesParameters[signatureScheme=");
+        builder.append(getSignatureScheme());
+        builder.append("]");
+        return builder.toString();
+    }
+}
diff --git 
a/core/camel-core-xml/src/generated/resources/org/apache/camel/core/xml/util/jsse/jaxb.index
 
b/core/camel-core-xml/src/generated/resources/org/apache/camel/core/xml/util/jsse/jaxb.index
index ecefb19403b1..3fd51d5143a2 100644
--- 
a/core/camel-core-xml/src/generated/resources/org/apache/camel/core/xml/util/jsse/jaxb.index
+++ 
b/core/camel-core-xml/src/generated/resources/org/apache/camel/core/xml/util/jsse/jaxb.index
@@ -4,3 +4,4 @@ FilterParametersDefinition
 NamedGroupsParametersDefinition
 SNIHostNamesDefinition
 SecureSocketProtocolsParametersDefinition
+SignatureSchemesParametersDefinition
diff --git 
a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/AbstractBaseSSLContextParametersFactoryBean.java
 
b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/AbstractBaseSSLContextParametersFactoryBean.java
index ff0d4d944dc9..25cea709bf5b 100644
--- 
a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/AbstractBaseSSLContextParametersFactoryBean.java
+++ 
b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/AbstractBaseSSLContextParametersFactoryBean.java
@@ -25,6 +25,7 @@ import org.apache.camel.support.jsse.CipherSuitesParameters;
 import org.apache.camel.support.jsse.FilterParameters;
 import org.apache.camel.support.jsse.NamedGroupsParameters;
 import org.apache.camel.support.jsse.SecureSocketProtocolsParameters;
+import org.apache.camel.support.jsse.SignatureSchemesParameters;
 
 @XmlTransient
 public abstract class AbstractBaseSSLContextParametersFactoryBean<T extends 
BaseSSLContextParameters>
@@ -42,6 +43,10 @@ public abstract class 
AbstractBaseSSLContextParametersFactoryBean<T extends Base
 
     private FilterParametersDefinition namedGroupsFilter;
 
+    private SignatureSchemesParametersDefinition signatureSchemes;
+
+    private FilterParametersDefinition signatureSchemesFilter;
+
     @XmlAttribute
     @Metadata(description = "The optional SSLSessionContext timeout time for 
javax.net.ssl.SSLSession in seconds.")
     private String sessionTimeout;
@@ -98,6 +103,16 @@ public abstract class 
AbstractBaseSSLContextParametersFactoryBean<T extends Base
             
newInstance.setNamedGroupsFilter(createFilterParameters(namedGroupsFilter));
         }
 
+        if (signatureSchemes != null) {
+            SignatureSchemesParameters signatureSchemesInstance = new 
SignatureSchemesParameters();
+            
signatureSchemesInstance.setSignatureScheme(signatureSchemes.getSignatureScheme());
+            newInstance.setSignatureSchemes(signatureSchemesInstance);
+        }
+
+        if (signatureSchemesFilter != null) {
+            
newInstance.setSignatureSchemesFilter(createFilterParameters(signatureSchemesFilter));
+        }
+
         if (sessionTimeout != null) {
             newInstance.setSessionTimeout(sessionTimeout);
         }
@@ -162,6 +177,22 @@ public abstract class 
AbstractBaseSSLContextParametersFactoryBean<T extends Base
         this.namedGroupsFilter = namedGroupsFilter;
     }
 
+    public SignatureSchemesParametersDefinition getSignatureSchemes() {
+        return signatureSchemes;
+    }
+
+    public void setSignatureSchemes(SignatureSchemesParametersDefinition 
signatureSchemes) {
+        this.signatureSchemes = signatureSchemes;
+    }
+
+    public FilterParametersDefinition getSignatureSchemesFilter() {
+        return signatureSchemesFilter;
+    }
+
+    public void setSignatureSchemesFilter(FilterParametersDefinition 
signatureSchemesFilter) {
+        this.signatureSchemesFilter = signatureSchemesFilter;
+    }
+
     public String getSessionTimeout() {
         return sessionTimeout;
     }
diff --git 
a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/SignatureSchemesParametersDefinition.java
 
b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/SignatureSchemesParametersDefinition.java
new file mode 100644
index 000000000000..9ccb7a46321c
--- /dev/null
+++ 
b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/SignatureSchemesParametersDefinition.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.core.xml.util.jsse;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlType;
+
+import org.apache.camel.spi.Metadata;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "signatureSchemesParameters", propOrder = { "signatureScheme" 
})
+public class SignatureSchemesParametersDefinition {
+
+    @Metadata(description = "List of TLS/SSL signature schemes")
+    private List<String> signatureScheme;
+
+    /**
+     * Returns a live reference to the list of signature scheme names.
+     *
+     * @return a reference to the list, never {@code null}
+     */
+    public List<String> getSignatureScheme() {
+        if (this.signatureScheme == null) {
+            this.signatureScheme = new ArrayList<>();
+        }
+        return this.signatureScheme;
+    }
+}
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/support/jsse/SSLContextParametersTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/support/jsse/SSLContextParametersTest.java
index 0ad671cf15a3..903e69c5d6a5 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/support/jsse/SSLContextParametersTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/support/jsse/SSLContextParametersTest.java
@@ -900,6 +900,151 @@ public class SSLContextParametersTest extends 
AbstractJsseParametersTest {
         assertEquals("x25519", engine.getSSLParameters().getNamedGroups()[0]);
     }
 
+    @Test
+    public void testSignatureSchemes() throws Exception {
+        SSLContext controlContext = SSLContext.getInstance("TLSv1.3");
+        controlContext.init(null, null, null);
+        SSLEngine controlEngine = controlContext.createSSLEngine();
+        String[] controlSignatureSchemes = 
controlEngine.getSSLParameters().getSignatureSchemes();
+
+        // default - no signature schemes configured, should keep defaults
+        SSLContextParameters scp = new SSLContextParameters();
+        SSLContext context = scp.createSSLContext(null);
+
+        SSLEngine engine = context.createSSLEngine();
+        SSLSocket socket = (SSLSocket) 
context.getSocketFactory().createSocket();
+        SSLServerSocket serverSocket = (SSLServerSocket) 
context.getServerSocketFactory().createServerSocket();
+
+        assertArrayEquals(controlSignatureSchemes, 
engine.getSSLParameters().getSignatureSchemes());
+        assertArrayEquals(controlSignatureSchemes, 
socket.getSSLParameters().getSignatureSchemes());
+        assertArrayEquals(controlSignatureSchemes, 
serverSocket.getSSLParameters().getSignatureSchemes());
+
+        // empty ssp - sets empty list
+        SignatureSchemesParameters ssp = new SignatureSchemesParameters();
+        scp.setSignatureSchemes(ssp);
+        context = scp.createSSLContext(null);
+        engine = context.createSSLEngine();
+        socket = (SSLSocket) context.getSocketFactory().createSocket();
+        serverSocket = (SSLServerSocket) 
context.getServerSocketFactory().createServerSocket();
+
+        assertEquals(0, 
engine.getSSLParameters().getSignatureSchemes().length);
+        assertEquals(0, 
socket.getSSLParameters().getSignatureSchemes().length);
+        assertEquals(0, 
serverSocket.getSSLParameters().getSignatureSchemes().length);
+
+        // explicit signature scheme
+        
ssp.setSignatureScheme(Collections.singletonList("rsa_pss_rsae_sha256"));
+        context = scp.createSSLContext(null);
+        engine = context.createSSLEngine();
+        socket = (SSLSocket) context.getSocketFactory().createSocket();
+        serverSocket = (SSLServerSocket) 
context.getServerSocketFactory().createServerSocket();
+
+        assertEquals(1, 
engine.getSSLParameters().getSignatureSchemes().length);
+        assertEquals("rsa_pss_rsae_sha256", 
engine.getSSLParameters().getSignatureSchemes()[0]);
+        assertEquals(1, 
socket.getSSLParameters().getSignatureSchemes().length);
+        assertEquals("rsa_pss_rsae_sha256", 
socket.getSSLParameters().getSignatureSchemes()[0]);
+        assertEquals(1, 
serverSocket.getSSLParameters().getSignatureSchemes().length);
+        assertEquals("rsa_pss_rsae_sha256", 
serverSocket.getSSLParameters().getSignatureSchemes()[0]);
+
+        // explicit signature schemes override filter
+        FilterParameters filter = new FilterParameters();
+        filter.getInclude().add(".*");
+        scp.setSignatureSchemesFilter(filter);
+        context = scp.createSSLContext(null);
+        engine = context.createSSLEngine();
+        socket = (SSLSocket) context.getSocketFactory().createSocket();
+        serverSocket = (SSLServerSocket) 
context.getServerSocketFactory().createServerSocket();
+
+        assertEquals(1, 
engine.getSSLParameters().getSignatureSchemes().length);
+        assertEquals("rsa_pss_rsae_sha256", 
engine.getSSLParameters().getSignatureSchemes()[0]);
+        assertEquals(1, 
socket.getSSLParameters().getSignatureSchemes().length);
+        assertEquals("rsa_pss_rsae_sha256", 
socket.getSSLParameters().getSignatureSchemes()[0]);
+        assertEquals(1, 
serverSocket.getSSLParameters().getSignatureSchemes().length);
+        assertEquals("rsa_pss_rsae_sha256", 
serverSocket.getSSLParameters().getSignatureSchemes()[0]);
+    }
+
+    @Test
+    public void testSignatureSchemesFilter() throws Exception {
+        // Note: SSLParameters.getSignatureSchemes() returns null by default 
(unlike getNamedGroups()),
+        // so filters operate on explicitly provided schemes rather than JDK 
defaults.
+
+        // default - no filter, keeps defaults (null)
+        SSLContextParameters scp = new SSLContextParameters();
+        SSLContext context = scp.createSSLContext(null);
+
+        SSLEngine engine = context.createSSLEngine();
+        SSLSocket socket = (SSLSocket) 
context.getSocketFactory().createSocket();
+        SSLServerSocket serverSocket = (SSLServerSocket) 
context.getServerSocketFactory().createServerSocket();
+
+        assertNull(engine.getSSLParameters().getSignatureSchemes());
+        assertNull(socket.getSSLParameters().getSignatureSchemes());
+        assertNull(serverSocket.getSSLParameters().getSignatureSchemes());
+
+        // empty filter - no includes means no schemes match (empty array)
+        FilterParameters filter = new FilterParameters();
+        scp.setSignatureSchemesFilter(filter);
+        context = scp.createSSLContext(null);
+        engine = context.createSSLEngine();
+        socket = (SSLSocket) context.getSocketFactory().createSocket();
+        serverSocket = (SSLServerSocket) 
context.getServerSocketFactory().createServerSocket();
+
+        assertEquals(0, 
engine.getSSLParameters().getSignatureSchemes().length);
+        assertEquals(0, 
socket.getSSLParameters().getSignatureSchemes().length);
+        assertEquals(0, 
serverSocket.getSSLParameters().getSignatureSchemes().length);
+
+        // explicit schemes override filter - filter ignored when schemes are 
set
+        SignatureSchemesParameters ssp = new SignatureSchemesParameters();
+        List<String> allSchemes = new LinkedList<>();
+        allSchemes.add("ecdsa_secp256r1_sha256");
+        allSchemes.add("ecdsa_secp384r1_sha384");
+        allSchemes.add("rsa_pss_rsae_sha256");
+        allSchemes.add("ed25519");
+        ssp.setSignatureScheme(allSchemes);
+        scp.setSignatureSchemes(ssp);
+
+        filter.getInclude().add("ecdsa_.*");
+        context = scp.createSSLContext(null);
+        engine = context.createSSLEngine();
+
+        // explicit schemes take precedence over filter
+        assertEquals(4, 
engine.getSSLParameters().getSignatureSchemes().length);
+
+        // clear explicit schemes, keep filter - now filter applies to empty 
JDK defaults
+        scp.setSignatureSchemes(null);
+        filter.getInclude().clear();
+        filter.getInclude().add(".*");
+        context = scp.createSSLContext(null);
+        engine = context.createSSLEngine();
+        socket = (SSLSocket) context.getSocketFactory().createSocket();
+        serverSocket = (SSLServerSocket) 
context.getServerSocketFactory().createServerSocket();
+
+        // JDK defaults are null → filtering null gives empty array
+        assertEquals(0, 
engine.getSSLParameters().getSignatureSchemes().length);
+        assertEquals(0, 
socket.getSSLParameters().getSignatureSchemes().length);
+        assertEquals(0, 
serverSocket.getSSLParameters().getSignatureSchemes().length);
+    }
+
+    @Test
+    public void testSignatureSchemesDoNotAffectOtherSettings() throws 
Exception {
+        SSLContext controlContext = SSLContext.getInstance("TLSv1.3");
+        controlContext.init(null, null, null);
+        SSLEngine controlEngine = controlContext.createSSLEngine();
+
+        // setting signature schemes should not change cipher suites, 
protocols, or named groups
+        SSLContextParameters scp = new SSLContextParameters();
+        SignatureSchemesParameters ssp = new SignatureSchemesParameters();
+        
ssp.setSignatureScheme(Collections.singletonList("rsa_pss_rsae_sha256"));
+        scp.setSignatureSchemes(ssp);
+
+        SSLContext context = scp.createSSLContext(null);
+        SSLEngine engine = context.createSSLEngine();
+
+        assertArrayEquals(controlEngine.getEnabledCipherSuites(), 
engine.getEnabledCipherSuites());
+        assertArrayEquals(controlEngine.getEnabledProtocols(), 
engine.getEnabledProtocols());
+        assertArrayEquals(controlEngine.getSSLParameters().getNamedGroups(), 
engine.getSSLParameters().getNamedGroups());
+        assertEquals(1, 
engine.getSSLParameters().getSignatureSchemes().length);
+        assertEquals("rsa_pss_rsae_sha256", 
engine.getSSLParameters().getSignatureSchemes()[0]);
+    }
+
     @Test
     public void testSessionTimeout() throws Exception {
         SSLContextParameters scp = new SSLContextParameters();
diff --git 
a/core/camel-main/src/generated/java/org/apache/camel/main/SSLConfigurationPropertiesConfigurer.java
 
b/core/camel-main/src/generated/java/org/apache/camel/main/SSLConfigurationPropertiesConfigurer.java
index bd5547568b98..375dd286459a 100644
--- 
a/core/camel-main/src/generated/java/org/apache/camel/main/SSLConfigurationPropertiesConfigurer.java
+++ 
b/core/camel-main/src/generated/java/org/apache/camel/main/SSLConfigurationPropertiesConfigurer.java
@@ -42,6 +42,9 @@ public class SSLConfigurationPropertiesConfigurer extends 
org.apache.camel.suppo
         map.put("SecureRandomProvider", java.lang.String.class);
         map.put("SecureSocketProtocol", java.lang.String.class);
         map.put("SessionTimeout", int.class);
+        map.put("SignatureSchemes", java.lang.String.class);
+        map.put("SignatureSchemesExclude", java.lang.String.class);
+        map.put("SignatureSchemesInclude", java.lang.String.class);
         map.put("TrustAllCertificates", boolean.class);
         map.put("TrustStore", java.lang.String.class);
         map.put("TrustStorePassword", java.lang.String.class);
@@ -90,6 +93,12 @@ public class SSLConfigurationPropertiesConfigurer extends 
org.apache.camel.suppo
         case "secureSocketProtocol": 
target.setSecureSocketProtocol(property(camelContext, java.lang.String.class, 
value)); return true;
         case "sessiontimeout":
         case "sessionTimeout": target.setSessionTimeout(property(camelContext, 
int.class, value)); return true;
+        case "signatureschemes":
+        case "signatureSchemes": 
target.setSignatureSchemes(property(camelContext, java.lang.String.class, 
value)); return true;
+        case "signatureschemesexclude":
+        case "signatureSchemesExclude": 
target.setSignatureSchemesExclude(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "signatureschemesinclude":
+        case "signatureSchemesInclude": 
target.setSignatureSchemesInclude(property(camelContext, 
java.lang.String.class, value)); return true;
         case "trustallcertificates":
         case "trustAllCertificates": 
target.setTrustAllCertificates(property(camelContext, boolean.class, value)); 
return true;
         case "truststore":
@@ -146,6 +155,12 @@ public class SSLConfigurationPropertiesConfigurer extends 
org.apache.camel.suppo
         case "secureSocketProtocol": return java.lang.String.class;
         case "sessiontimeout":
         case "sessionTimeout": return int.class;
+        case "signatureschemes":
+        case "signatureSchemes": return java.lang.String.class;
+        case "signatureschemesexclude":
+        case "signatureSchemesExclude": return java.lang.String.class;
+        case "signatureschemesinclude":
+        case "signatureSchemesInclude": return java.lang.String.class;
         case "trustallcertificates":
         case "trustAllCertificates": return boolean.class;
         case "truststore":
@@ -198,6 +213,12 @@ public class SSLConfigurationPropertiesConfigurer extends 
org.apache.camel.suppo
         case "secureSocketProtocol": return target.getSecureSocketProtocol();
         case "sessiontimeout":
         case "sessionTimeout": return target.getSessionTimeout();
+        case "signatureschemes":
+        case "signatureSchemes": return target.getSignatureSchemes();
+        case "signatureschemesexclude":
+        case "signatureSchemesExclude": return 
target.getSignatureSchemesExclude();
+        case "signatureschemesinclude":
+        case "signatureSchemesInclude": return 
target.getSignatureSchemesInclude();
         case "trustallcertificates":
         case "trustAllCertificates": return target.isTrustAllCertificates();
         case "truststore":
diff --git 
a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
 
b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index 5e5d6ba74821..1b156fda5539 100644
--- 
a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ 
b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -351,6 +351,9 @@
     { "name": "camel.ssl.secureRandomProvider", "required": false, 
"description": "To use a specific provider for creating SecureRandom. The list 
of available providers returned by java.security.Security.getProviders() or 
null to use the highest priority provider implementing the secure socket 
protocol.", "sourceType": "org.apache.camel.main.SSLConfigurationProperties", 
"type": "string", "javaType": "java.lang.String", "secret": false },
     { "name": "camel.ssl.secureSocketProtocol", "required": false, 
"description": "The protocol for the secure sockets created by the SSLContext. 
See 
https:\/\/docs.oracle.com\/en\/java\/javase\/17\/docs\/specs\/security\/standard-names.html",
 "sourceType": "org.apache.camel.main.SSLConfigurationProperties", "type": 
"string", "javaType": "java.lang.String", "defaultValue": "TLSv1.3", "secret": 
false },
     { "name": "camel.ssl.sessionTimeout", "required": false, "description": 
"Timeout in seconds to use for SSLContext. The default is 24 hours.", 
"sourceType": "org.apache.camel.main.SSLConfigurationProperties", "type": 
"integer", "javaType": "int", "defaultValue": 86400, "secret": false },
+    { "name": "camel.ssl.signatureSchemes", "required": false, "description": 
"List of TLS\/SSL signature schemes. Multiple names can be separated by comma. 
Signature schemes control which signature algorithms are available during the 
TLS handshake, including post-quantum signature algorithms such as ML-DSA.", 
"sourceType": "org.apache.camel.main.SSLConfigurationProperties", "type": 
"string", "javaType": "java.lang.String", "secret": false },
+    { "name": "camel.ssl.signatureSchemesExclude", "required": false, 
"description": "Filters TLS\/SSL signature schemes. This filter is used for 
excluding signature schemes that match the naming pattern. Multiple names can 
be separated by comma. Notice that if the signatureSchemes option has been 
configured then the include\/exclude filters are not in use.", "sourceType": 
"org.apache.camel.main.SSLConfigurationProperties", "type": "string", 
"javaType": "java.lang.String", "secret": false },
+    { "name": "camel.ssl.signatureSchemesInclude", "required": false, 
"description": "Filters TLS\/SSL signature schemes. This filter is used for 
including signature schemes that match the naming pattern. Multiple names can 
be separated by comma. Notice that if the signatureSchemes option has been 
configured then the include\/exclude filters are not in use.", "sourceType": 
"org.apache.camel.main.SSLConfigurationProperties", "type": "string", 
"javaType": "java.lang.String", "secret": false },
     { "name": "camel.ssl.trustAllCertificates", "required": false, 
"description": "Allows to trust all SSL certificates without performing 
certificate validation. This can be used in development environment but may 
expose the system to security risks. Notice that if the trustAllCertificates 
option is set to true then the trustStore\/trustStorePassword options are not 
in use.", "sourceType": "org.apache.camel.main.SSLConfigurationProperties", 
"type": "boolean", "javaType": "boolean", "def [...]
     { "name": "camel.ssl.trustStore", "required": false, "description": "The 
trust store to load. The trust store is by default loaded from classpath. If 
you must load from file system, then use file: as prefix. file:nameOfFile (to 
refer to the file system) classpath:nameOfFile (to refer to the classpath; 
default) http:uri (to load the resource using HTTP) ref:nameOfBean (to lookup 
an existing KeyStore instance from the registry, for example for testing and 
development).", "sourceType":  [...]
     { "name": "camel.ssl.trustStorePassword", "required": false, 
"description": "Sets the SSL Truststore password.", "sourceType": 
"org.apache.camel.main.SSLConfigurationProperties", "type": "string", 
"javaType": "java.lang.String", "secret": false },
diff --git a/core/camel-main/src/main/docs/main.adoc 
b/core/camel-main/src/main/docs/main.adoc
index 9d52d82ad48b..eb81817ede0f 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -299,7 +299,7 @@ The camel.trace supports 14 options, which are listed below.
 
 
 === Camel SSL configurations
-The camel.ssl supports 23 options, which are listed below.
+The camel.ssl supports 26 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
@@ -324,6 +324,9 @@ The camel.ssl supports 23 options, which are listed below.
 | *camel.ssl.secureRandomProvider* | To use a specific provider for creating 
SecureRandom. The list of available providers returned by 
java.security.Security.getProviders() or null to use the highest priority 
provider implementing the secure socket protocol. |  | String
 | *camel.ssl.secureSocketProtocol* | The protocol for the secure sockets 
created by the SSLContext. See 
\https://docs.oracle.com/en/java/javase/17/docs/specs/security/standard-names.html
 | TLSv1.3 | String
 | *camel.ssl.sessionTimeout* | Timeout in seconds to use for SSLContext. The 
default is 24 hours. | 86400 | int
+| *camel.ssl.signatureSchemes* | List of TLS/SSL signature schemes. Multiple 
names can be separated by comma. Signature schemes control which signature 
algorithms are available during the TLS handshake, including post-quantum 
signature algorithms such as ML-DSA. |  | String
+| *camel.ssl.signatureSchemes{zwsp}Exclude* | Filters TLS/SSL signature 
schemes. This filter is used for excluding signature schemes that match the 
naming pattern. Multiple names can be separated by comma. Notice that if the 
signatureSchemes option has been configured then the include/exclude filters 
are not in use. |  | String
+| *camel.ssl.signatureSchemes{zwsp}Include* | Filters TLS/SSL signature 
schemes. This filter is used for including signature schemes that match the 
naming pattern. Multiple names can be separated by comma. Notice that if the 
signatureSchemes option has been configured then the include/exclude filters 
are not in use. |  | String
 | *camel.ssl.trustAllCertificates* | Allows to trust all SSL certificates 
without performing certificate validation. This can be used in development 
environment but may expose the system to security risks. Notice that if the 
trustAllCertificates option is set to true then the 
trustStore/trustStorePassword options are not in use. | false | boolean
 | *camel.ssl.trustStore* | The trust store to load. The trust store is by 
default loaded from classpath. If you must load from file system, then use 
file: as prefix. file:nameOfFile (to refer to the file system) 
classpath:nameOfFile (to refer to the classpath; default) http:uri (to load the 
resource using HTTP) ref:nameOfBean (to lookup an existing KeyStore instance 
from the registry, for example for testing and development). |  | String
 | *camel.ssl.trustStorePassword* | Sets the SSL Truststore password. |  | 
String
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java 
b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
index 05b3ec116032..e73e1565752c 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
@@ -101,6 +101,7 @@ import org.apache.camel.support.jsse.NamedGroupsParameters;
 import org.apache.camel.support.jsse.SSLContextParameters;
 import org.apache.camel.support.jsse.SSLContextServerParameters;
 import org.apache.camel.support.jsse.SecureRandomParameters;
+import org.apache.camel.support.jsse.SignatureSchemesParameters;
 import org.apache.camel.support.jsse.TrustAllTrustManager;
 import org.apache.camel.support.jsse.TrustManagersParameters;
 import org.apache.camel.support.scan.PackageScanHelper;
@@ -2220,6 +2221,27 @@ public abstract class BaseMainSupport extends 
BaseService {
             }
             sslContextParameters.setNamedGroupsFilter(fp);
         }
+        if (sslConfig.getSignatureSchemes() != null) {
+            SignatureSchemesParameters ssp = new SignatureSchemesParameters();
+            for (String s : sslConfig.getSignatureSchemes().split(",")) {
+                ssp.addSignatureScheme(s);
+            }
+            sslContextParameters.setSignatureSchemes(ssp);
+        }
+        if (sslConfig.getSignatureSchemesInclude() != null || 
sslConfig.getSignatureSchemesExclude() != null) {
+            FilterParameters fp = new FilterParameters();
+            if (sslConfig.getSignatureSchemesInclude() != null) {
+                for (String s : 
sslConfig.getSignatureSchemesInclude().split(",")) {
+                    fp.addInclude(s);
+                }
+            }
+            if (sslConfig.getSignatureSchemesExclude() != null) {
+                for (String s : 
sslConfig.getSignatureSchemesExclude().split(",")) {
+                    fp.addExclude(s);
+                }
+            }
+            sslContextParameters.setSignatureSchemesFilter(fp);
+        }
         sslContextParameters.setKeyManagers(kmp);
         sslContextParameters.setTrustManagers(tmp);
         sslContextParameters.setServerParameters(scsp);
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/SSLConfigurationProperties.java
 
b/core/camel-main/src/main/java/org/apache/camel/main/SSLConfigurationProperties.java
index 4d6395d14120..77b84bd3b5a7 100644
--- 
a/core/camel-main/src/main/java/org/apache/camel/main/SSLConfigurationProperties.java
+++ 
b/core/camel-main/src/main/java/org/apache/camel/main/SSLConfigurationProperties.java
@@ -50,6 +50,12 @@ public class SSLConfigurationProperties implements 
BootstrapCloseable {
     private String namedGroupsInclude;
     @Metadata(label = "advanced")
     private String namedGroupsExclude;
+    @Metadata(label = "advanced")
+    private String signatureSchemes;
+    @Metadata(label = "advanced")
+    private String signatureSchemesInclude;
+    @Metadata(label = "advanced")
+    private String signatureSchemesExclude;
     @Metadata
     private String keyStore;
     @Metadata(label = "advanced")
@@ -237,6 +243,52 @@ public class SSLConfigurationProperties implements 
BootstrapCloseable {
         this.namedGroupsExclude = namedGroupsExclude;
     }
 
+    public String getSignatureSchemes() {
+        return signatureSchemes;
+    }
+
+    /**
+     * List of TLS/SSL signature schemes. Multiple names can be separated by 
comma.
+     * <p>
+     * Signature schemes control which signature algorithms are available 
during the TLS handshake, including
+     * post-quantum signature algorithms such as ML-DSA.
+     */
+    public void setSignatureSchemes(String signatureSchemes) {
+        this.signatureSchemes = signatureSchemes;
+    }
+
+    public String getSignatureSchemesInclude() {
+        return signatureSchemesInclude;
+    }
+
+    /**
+     * Filters TLS/SSL signature schemes.
+     * <p>
+     * This filter is used for including signature schemes that match the 
naming pattern. Multiple names can be
+     * separated by comma.
+     * <p>
+     * Notice that if the signatureSchemes option has been configured then the 
include/exclude filters are not in use.
+     */
+    public void setSignatureSchemesInclude(String signatureSchemesInclude) {
+        this.signatureSchemesInclude = signatureSchemesInclude;
+    }
+
+    public String getSignatureSchemesExclude() {
+        return signatureSchemesExclude;
+    }
+
+    /**
+     * Filters TLS/SSL signature schemes.
+     * <p>
+     * This filter is used for excluding signature schemes that match the 
naming pattern. Multiple names can be
+     * separated by comma.
+     * <p>
+     * Notice that if the signatureSchemes option has been configured then the 
include/exclude filters are not in use.
+     */
+    public void setSignatureSchemesExclude(String signatureSchemesExclude) {
+        this.signatureSchemesExclude = signatureSchemesExclude;
+    }
+
     public String getKeyStore() {
         return keyStore;
     }
@@ -514,6 +566,43 @@ public class SSLConfigurationProperties implements 
BootstrapCloseable {
         return this;
     }
 
+    /**
+     * List of TLS/SSL signature schemes. Multiple names can be separated by 
comma.
+     * <p>
+     * Signature schemes control which signature algorithms are available 
during the TLS handshake, including
+     * post-quantum signature algorithms such as ML-DSA.
+     */
+    public SSLConfigurationProperties withSignatureSchemes(String 
signatureSchemes) {
+        this.signatureSchemes = signatureSchemes;
+        return this;
+    }
+
+    /**
+     * Filters TLS/SSL signature schemes.
+     * <p>
+     * This filter is used for including signature schemes that match the 
naming pattern. Multiple names can be
+     * separated by comma.
+     * <p>
+     * Notice that if the signatureSchemes option has been configured then the 
include/exclude filters are not in use.
+     */
+    public SSLConfigurationProperties withSignatureSchemesInclude(String 
signatureSchemesInclude) {
+        this.signatureSchemesInclude = signatureSchemesInclude;
+        return this;
+    }
+
+    /**
+     * Filters TLS/SSL signature schemes.
+     * <p>
+     * This filter is used for excluding signature schemes that match the 
naming pattern. Multiple names can be
+     * separated by comma.
+     * <p>
+     * Notice that if the signatureSchemes option has been configured then the 
include/exclude filters are not in use.
+     */
+    public SSLConfigurationProperties withSignatureSchemesExclude(String 
signatureSchemesExclude) {
+        this.signatureSchemesExclude = signatureSchemesExclude;
+        return this;
+    }
+
     /**
      * The keystore to load.
      *
diff --git 
a/core/camel-main/src/test/java/org/apache/camel/main/MainSSLTest.java 
b/core/camel-main/src/test/java/org/apache/camel/main/MainSSLTest.java
index 50353a31899a..21f22e7f1cb6 100644
--- a/core/camel-main/src/test/java/org/apache/camel/main/MainSSLTest.java
+++ b/core/camel-main/src/test/java/org/apache/camel/main/MainSSLTest.java
@@ -26,6 +26,7 @@ import org.apache.camel.support.jsse.KeyStoreParameters;
 import org.apache.camel.support.jsse.NamedGroupsParameters;
 import org.apache.camel.support.jsse.SSLContextParameters;
 import org.apache.camel.support.jsse.SSLContextServerParameters;
+import org.apache.camel.support.jsse.SignatureSchemesParameters;
 import org.apache.camel.support.jsse.TrustAllTrustManager;
 import org.apache.camel.support.jsse.TrustManagersParameters;
 import org.junit.jupiter.api.Assertions;
@@ -290,4 +291,131 @@ public class MainSSLTest {
 
         main.stop();
     }
+
+    @Test
+    public void testMainSSLSignatureSchemes() {
+        Main main = new Main();
+
+        main.addInitialProperty("camel.ssl.enabled", "true");
+        main.addInitialProperty("camel.ssl.keyStore", "server.jks");
+        main.addInitialProperty("camel.ssl.keystorePassword", "security");
+        main.addInitialProperty("camel.ssl.signatureSchemes", 
"ed25519,rsa_pss_rsae_sha256,ecdsa_secp256r1_sha256");
+
+        main.start();
+
+        CamelContext context = main.getCamelContext();
+        assertNotNull(context);
+
+        SSLContextParameters sslParams = context.getSSLContextParameters();
+        assertNotNull(sslParams);
+
+        SignatureSchemesParameters ssp = sslParams.getSignatureSchemes();
+        assertNotNull(ssp);
+
+        List<String> schemes = ssp.getSignatureScheme();
+        Assertions.assertEquals(3, schemes.size());
+        Assertions.assertEquals("ed25519", schemes.get(0));
+        Assertions.assertEquals("rsa_pss_rsae_sha256", schemes.get(1));
+        Assertions.assertEquals("ecdsa_secp256r1_sha256", schemes.get(2));
+
+        assertNull(sslParams.getSignatureSchemesFilter());
+
+        main.stop();
+    }
+
+    @Test
+    public void testMainSSLSignatureSchemesFluent() {
+        Main main = new Main();
+
+        main.configure().sslConfig()
+                .withEnabled(true)
+                .withKeyStore("server.jks")
+                .withKeystorePassword("security")
+                .withSignatureSchemes("ed25519,rsa_pss_rsae_sha256");
+
+        main.start();
+
+        CamelContext context = main.getCamelContext();
+        assertNotNull(context);
+
+        SSLContextParameters sslParams = context.getSSLContextParameters();
+        assertNotNull(sslParams);
+
+        SignatureSchemesParameters ssp = sslParams.getSignatureSchemes();
+        assertNotNull(ssp);
+
+        List<String> schemes = ssp.getSignatureScheme();
+        Assertions.assertEquals(2, schemes.size());
+        Assertions.assertEquals("ed25519", schemes.get(0));
+        Assertions.assertEquals("rsa_pss_rsae_sha256", schemes.get(1));
+
+        main.stop();
+    }
+
+    @Test
+    public void testMainSSLSignatureSchemesFilter() {
+        Main main = new Main();
+
+        main.addInitialProperty("camel.ssl.enabled", "true");
+        main.addInitialProperty("camel.ssl.keyStore", "server.jks");
+        main.addInitialProperty("camel.ssl.keystorePassword", "security");
+        main.addInitialProperty("camel.ssl.signatureSchemesInclude", 
"ecdsa_.*,ed.*");
+        main.addInitialProperty("camel.ssl.signatureSchemesExclude", "ed448");
+
+        main.start();
+
+        CamelContext context = main.getCamelContext();
+        assertNotNull(context);
+
+        SSLContextParameters sslParams = context.getSSLContextParameters();
+        assertNotNull(sslParams);
+
+        assertNull(sslParams.getSignatureSchemes());
+
+        FilterParameters fp = sslParams.getSignatureSchemesFilter();
+        assertNotNull(fp);
+
+        List<String> includes = fp.getInclude();
+        Assertions.assertEquals(2, includes.size());
+        Assertions.assertEquals("ecdsa_.*", includes.get(0));
+        Assertions.assertEquals("ed.*", includes.get(1));
+
+        List<String> excludes = fp.getExclude();
+        Assertions.assertEquals(1, excludes.size());
+        Assertions.assertEquals("ed448", excludes.get(0));
+
+        main.stop();
+    }
+
+    @Test
+    public void testMainSSLSignatureSchemesFilterFluent() {
+        Main main = new Main();
+
+        main.configure().sslConfig()
+                .withEnabled(true)
+                .withKeyStore("server.jks")
+                .withKeystorePassword("security")
+                .withSignatureSchemesInclude("ecdsa_.*")
+                .withSignatureSchemesExclude("ed448");
+
+        main.start();
+
+        CamelContext context = main.getCamelContext();
+        assertNotNull(context);
+
+        SSLContextParameters sslParams = context.getSSLContextParameters();
+        assertNotNull(sslParams);
+
+        assertNull(sslParams.getSignatureSchemes());
+
+        FilterParameters fp = sslParams.getSignatureSchemesFilter();
+        assertNotNull(fp);
+
+        Assertions.assertEquals(1, fp.getInclude().size());
+        Assertions.assertEquals("ecdsa_.*", fp.getInclude().get(0));
+        Assertions.assertEquals(1, fp.getExclude().size());
+        Assertions.assertEquals("ed448", fp.getExclude().get(0));
+
+        main.stop();
+    }
 }

Reply via email to