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

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

commit c5a7a8c3240b3dbaf585a14eee8671f2034ba277
Author: Dmitry Kryukov <d...@ya.ru>
AuthorDate: Wed Apr 26 13:34:43 2023 +0300

    CAMEL-17946 Introducing HTTPS support for AS2 component for the main and 
4.x branch
---
 .../component/as2/api/AS2ClientConnection.java     |  45 ++++-
 .../camel/component/as2/api/AS2ClientManager.java  |  10 +-
 .../component/as2/api/AS2ServerConnection.java     |  25 ++-
 .../camel/component/as2/api/AS2MessageTest.java    |   4 +-
 components/camel-as2/camel-as2-component/pom.xml   |   6 +
 ...ientManagerEndpointConfigurationConfigurer.java |  14 ++
 .../component/as2/AS2ConfigurationConfigurer.java  |  14 ++
 .../camel/component/as2/AS2EndpointConfigurer.java |  14 ++
 .../camel/component/as2/AS2EndpointUriFactory.java |   4 +-
 ...rverManagerEndpointConfigurationConfigurer.java |  14 ++
 .../org/apache/camel/component/as2/as2.json        |   4 +-
 .../camel/component/as2/AS2Configuration.java      |  37 ++++-
 .../apache/camel/component/as2/AS2Endpoint.java    |  10 ++
 .../as2/internal/AS2ConnectionHelper.java          |   5 +-
 .../camel/component/as2/AS2ClientManagerIT.java    |   2 +-
 .../camel/component/as2/AS2ServerManagerIT.java    |  74 ++++++++-
 .../as2/CreateEndpointManualIssueTest.java         |   1 -
 .../camel/component/as2/MendelsonCertLoader.java   | 183 +++++++++++++++++++++
 .../component/as2/MendelsonSslEndpointIT.java      | 132 +++++++++++++++
 .../src/test/resources/jsse/client-keystore.jks    | Bin 0 -> 2183 bytes
 .../src/test/resources/jsse/client-truststore.jks  | Bin 0 -> 921 bytes
 .../src/test/resources/jsse/localhost.p12          | Bin 0 -> 2533 bytes
 .../src/test/resources/jsse/server-keystore.jks    | Bin 0 -> 2214 bytes
 .../src/test/resources/jsse/server-truststore.jks  | Bin 0 -> 927 bytes
 .../src/test/resources/mendelson/key3.pfx          | Bin 0 -> 4983 bytes
 .../src/test/resources/mendelson/key4.cer          |  21 +++
 .../endpoint/dsl/AS2EndpointBuilderFactory.java    |  96 +++++++++++
 27 files changed, 680 insertions(+), 35 deletions(-)

diff --git 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientConnection.java
 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientConnection.java
index 2666c912b90..e3ea423a36a 100644
--- 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientConnection.java
+++ 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientConnection.java
@@ -23,6 +23,10 @@ import java.util.UUID;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+
 import org.apache.camel.component.as2.api.io.AS2BHttpClientConnection;
 import org.apache.camel.component.as2.api.protocol.RequestAS2;
 import org.apache.camel.component.as2.api.protocol.RequestMDN;
@@ -34,11 +38,16 @@ import org.apache.http.HttpException;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
 import org.apache.http.config.SocketConfig;
 import org.apache.http.conn.ConnectionKeepAliveStrategy;
 import org.apache.http.conn.HttpConnectionFactory;
 import org.apache.http.conn.ManagedHttpClientConnection;
 import org.apache.http.conn.routing.HttpRoute;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
 import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpCoreContext;
@@ -67,14 +76,16 @@ public class AS2ClientConnection {
 
     public AS2ClientConnection(String as2Version, String userAgent, String 
clientFqdn, String targetHostName,
                                Integer targetPortNumber, Duration 
socketTimeout, Duration connectionTimeout,
-                               Integer connectionPoolMaxSize, Duration 
connectionPoolTtl) throws IOException {
+                               Integer connectionPoolMaxSize, Duration 
connectionPoolTtl,
+                               SSLContext sslContext, HostnameVerifier 
hostnameVerifier) throws IOException {
 
         this.as2Version = ObjectHelper.notNull(as2Version, "as2Version");
         this.userAgent = ObjectHelper.notNull(userAgent, "userAgent");
         this.clientFqdn = ObjectHelper.notNull(clientFqdn, "clientFqdn");
         this.targetHost = new HttpHost(
                 ObjectHelper.notNull(targetHostName, "targetHostName"),
-                ObjectHelper.notNull(targetPortNumber, "targetPortNumber"));
+                ObjectHelper.notNull(targetPortNumber, "targetPortNumber"),
+                sslContext != null ? "https" : "http");
         ObjectHelper.notNull(socketTimeout, "socketTimeout");
         this.connectionTimeoutMilliseconds = (int) 
ObjectHelper.notNull(connectionTimeout, "connectionTimeout").toMillis();
         ObjectHelper.notNull(connectionPoolMaxSize, "connectionPoolMaxSize");
@@ -91,11 +102,24 @@ public class AS2ClientConnection {
                 .add(new RequestConnControl())
                 .add(new RequestExpectContinue(true)).build();
 
-        HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> 
connFactory = (route, config) -> {
-            return new AS2BHttpClientConnection(UUID.randomUUID().toString(), 
8 * 1024);
-        };
-
-        connectionPoolManager = new 
PoolingHttpClientConnectionManager(connFactory);
+        HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> 
connFactory
+                = (route, config) -> new 
AS2BHttpClientConnection(UUID.randomUUID().toString(), 8 * 1024);
+
+        if (sslContext == null) {
+            connectionPoolManager = new 
PoolingHttpClientConnectionManager(connFactory);
+        } else {
+            SSLConnectionSocketFactory sslConnectionSocketFactory;
+            if (hostnameVerifier == null) {
+                sslConnectionSocketFactory = new 
SSLConnectionSocketFactory(sslContext);
+            } else {
+                sslConnectionSocketFactory = new 
SSLConnectionSocketFactory(sslContext, hostnameVerifier);
+            }
+            Registry<ConnectionSocketFactory> socketFactoryRegistry = 
RegistryBuilder.<ConnectionSocketFactory> create()
+                    .register("http", 
PlainConnectionSocketFactory.getSocketFactory())
+                    .register("https", sslConnectionSocketFactory)
+                    .build();
+            connectionPoolManager = new 
PoolingHttpClientConnectionManager(socketFactoryRegistry, connFactory);
+        }
         connectionPoolManager.setMaxTotal(connectionPoolMaxSize);
         connectionPoolManager.setSocketConfig(targetHost,
                 SocketConfig.copy(SocketConfig.DEFAULT)
@@ -122,7 +146,12 @@ public class AS2ClientConnection {
 
         // Check if a connection can be established
         try (AS2BHttpClientConnection testConnection = new 
AS2BHttpClientConnection("test", 8 * 1024)) {
-            testConnection.bind(new Socket(targetHost.getHostName(), 
targetHost.getPort()));
+            if (sslContext == null) {
+                testConnection.bind(new Socket(targetHost.getHostName(), 
targetHost.getPort()));
+            } else {
+                SSLSocketFactory factory = sslContext.getSocketFactory();
+                
testConnection.bind(factory.createSocket(targetHost.getHostName(), 
targetHost.getPort()));
+            }
         }
 
     }
diff --git 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientManager.java
 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientManager.java
index 1b5df6d90be..ba089042eba 100644
--- 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientManager.java
+++ 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientManager.java
@@ -220,9 +220,9 @@ public class AS2ClientManager {
         ObjectHelper.notNull(ediMessage, "EDI Message");
         ObjectHelper.notNull(requestUri, "Request URI");
         ObjectHelper.notNull(subject, "Subject");
-        ObjectHelper.notNull(from, "Subject");
-        ObjectHelper.notNull(as2From, "Subject");
-        ObjectHelper.notNull(as2To, "Subject");
+        ObjectHelper.notNull(from, "From");
+        ObjectHelper.notNull(as2From, "AS2From");
+        ObjectHelper.notNull(as2To, "AS2To");
         ObjectHelper.notNull(as2MessageStructure, "AS2 Message Structure");
         ObjectHelper.notNull(ediMessageContentType, "EDI Message Content 
Type");
 
@@ -266,9 +266,9 @@ public class AS2ClientManager {
             }
             case SIGNED: {
                 // Create Multipart Signed Entity containing EDI Entity
-                AS2SignedDataGenerator signingGenrator = 
createSigningGenerator(httpContext);
+                AS2SignedDataGenerator signingGenerator = 
createSigningGenerator(httpContext);
                 MultipartSignedEntity multipartSignedEntity = new 
MultipartSignedEntity(
-                        applicationEDIEntity, signingGenrator,
+                        applicationEDIEntity, signingGenerator,
                         StandardCharsets.US_ASCII.name(), 
AS2TransferEncoding.BASE64, true, null);
 
                 // Add Multipart Signed Entity to main body of request.
diff --git 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ServerConnection.java
 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ServerConnection.java
index 1e82ac09142..c3310125e65 100644
--- 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ServerConnection.java
+++ 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ServerConnection.java
@@ -24,6 +24,9 @@ import java.net.SocketException;
 import java.security.PrivateKey;
 import java.security.cert.Certificate;
 
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocketFactory;
+
 import 
org.apache.camel.component.as2.api.entity.DispositionNotificationMultipartReportEntity;
 import org.apache.camel.component.as2.api.io.AS2BHttpServerConnection;
 import org.apache.camel.component.as2.api.protocol.ResponseMDN;
@@ -69,10 +72,17 @@ public class AS2ServerConnection {
                                      PrivateKey signingPrivateKey,
                                      PrivateKey decryptingPrivateKey,
                                      String mdnMessageTemplate,
-                                     Certificate[] 
validateSigningCertificateChain)
-                                                                               
     throws IOException {
+                                     Certificate[] 
validateSigningCertificateChain,
+                                     SSLContext sslContext)
+                                                            throws IOException 
{
             setName(REQUEST_LISTENER_THREAD_NAME_PREFIX + port);
-            serversocket = new ServerSocket(port);
+
+            if (sslContext == null) {
+                serversocket = new ServerSocket(port);
+            } else {
+                SSLServerSocketFactory factory = 
sslContext.getServerSocketFactory();
+                serversocket = factory.createServerSocket(port);
+            }
 
             // Set up HTTP protocol processor for incoming connections
             final HttpProcessor inhttpproc = initProtocolProcessor(as2Version, 
originServer, serverFqdn,
@@ -197,6 +207,7 @@ public class AS2ServerConnection {
     private PrivateKey decryptingPrivateKey;
     private String mdnMessageTemplate;
     private Certificate[] validateSigningCertificateChain;
+    private SSLContext sslContext;
 
     public AS2ServerConnection(String as2Version,
                                String originServer,
@@ -207,8 +218,9 @@ public class AS2ServerConnection {
                                PrivateKey signingPrivateKey,
                                PrivateKey decryptingPrivateKey,
                                String mdnMessageTemplate,
-                               Certificate[] validateSigningCertificateChain)
-                                                                              
throws IOException {
+                               Certificate[] validateSigningCertificateChain,
+                               SSLContext sslContext)
+                                                      throws IOException {
         this.as2Version = ObjectHelper.notNull(as2Version, "as2Version");
         this.originServer = ObjectHelper.notNull(originServer, "userAgent");
         this.serverFqdn = ObjectHelper.notNull(serverFqdn, "serverFqdn");
@@ -219,11 +231,12 @@ public class AS2ServerConnection {
         this.decryptingPrivateKey = decryptingPrivateKey;
         this.mdnMessageTemplate = mdnMessageTemplate;
         this.validateSigningCertificateChain = validateSigningCertificateChain;
+        this.sslContext = sslContext;
 
         listenerThread = new RequestListenerThread(
                 this.as2Version, this.originServer, this.serverFqdn,
                 this.serverPortNumber, this.signingAlgorithm, 
this.signingCertificateChain, this.signingPrivateKey,
-                this.decryptingPrivateKey, this.mdnMessageTemplate, 
validateSigningCertificateChain);
+                this.decryptingPrivateKey, this.mdnMessageTemplate, 
validateSigningCertificateChain, this.sslContext);
         listenerThread.setDaemon(true);
         listenerThread.start();
     }
diff --git 
a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2MessageTest.java
 
b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2MessageTest.java
index 5643af6957e..8117013839d 100644
--- 
a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2MessageTest.java
+++ 
b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2MessageTest.java
@@ -217,7 +217,7 @@ public class AS2MessageTest {
         testServer = new AS2ServerConnection(
                 AS2_VERSION, "MyServer-HTTP/1.1", SERVER_FQDN, TARGET_PORT, 
AS2SignatureAlgorithm.SHA256WITHRSA,
                 certList.toArray(new Certificate[0]), signingKP.getPrivate(), 
decryptingKP.getPrivate(), MDN_MESSAGE_TEMPLATE,
-                VALIDATE_SIGNING_CERTIFICATE_CHAIN);
+                VALIDATE_SIGNING_CERTIFICATE_CHAIN, null);
         testServer.listen("*", new HttpRequestHandler() {
             @Override
             public void handle(HttpRequest request, HttpResponse response, 
HttpContext context)
@@ -1072,7 +1072,7 @@ public class AS2MessageTest {
         AS2ClientConnection clientConnection = new AS2ClientConnection(
                 AS2_VERSION, USER_AGENT, CLIENT_FQDN,
                 TARGET_HOST, TARGET_PORT, HTTP_SOCKET_TIMEOUT, 
HTTP_CONNECTION_TIMEOUT, HTTP_CONNECTION_POOL_SIZE,
-                HTTP_CONNECTION_POOL_TTL);
+                HTTP_CONNECTION_POOL_TTL, null, null);
         return new AS2ClientManager(clientConnection);
     }
 }
diff --git a/components/camel-as2/camel-as2-component/pom.xml 
b/components/camel-as2/camel-as2-component/pom.xml
index d2ffa26888f..331487786f2 100644
--- a/components/camel-as2/camel-as2-component/pom.xml
+++ b/components/camel-as2/camel-as2-component/pom.xml
@@ -64,6 +64,12 @@
             <artifactId>camel-jetty</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.10.0</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git 
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ClientManagerEndpointConfigurationConfigurer.java
 
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ClientManagerEndpointConfigurationConfigurer.java
index 25bfcad9f8e..0406b2a86ed 100644
--- 
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ClientManagerEndpointConfigurationConfigurer.java
+++ 
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ClientManagerEndpointConfigurationConfigurer.java
@@ -37,6 +37,7 @@ public class AS2ClientManagerEndpointConfigurationConfigurer 
extends org.apache.
         map.put("EncryptingAlgorithm", 
org.apache.camel.component.as2.api.AS2EncryptionAlgorithm.class);
         map.put("EncryptingCertificateChain", 
java.security.cert.Certificate[].class);
         map.put("From", java.lang.String.class);
+        map.put("HostnameVerifier", javax.net.ssl.HostnameVerifier.class);
         map.put("HttpConnectionPoolSize", java.lang.Integer.class);
         map.put("HttpConnectionPoolTtl", java.time.Duration.class);
         map.put("HttpConnectionTimeout", java.time.Duration.class);
@@ -51,6 +52,7 @@ public class AS2ClientManagerEndpointConfigurationConfigurer 
extends org.apache.
         map.put("SigningAlgorithm", 
org.apache.camel.component.as2.api.AS2SignatureAlgorithm.class);
         map.put("SigningCertificateChain", 
java.security.cert.Certificate[].class);
         map.put("SigningPrivateKey", java.security.PrivateKey.class);
+        map.put("SslContext", javax.net.ssl.SSLContext.class);
         map.put("Subject", java.lang.String.class);
         map.put("TargetHostname", java.lang.String.class);
         map.put("TargetPortNumber", java.lang.Integer.class);
@@ -97,6 +99,8 @@ public class AS2ClientManagerEndpointConfigurationConfigurer 
extends org.apache.
         case "EncryptingCertificateChain": 
target.setEncryptingCertificateChain(property(camelContext, 
java.security.cert.Certificate[].class, value)); return true;
         case "from":
         case "From": target.setFrom(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "hostnameverifier":
+        case "HostnameVerifier": 
target.setHostnameVerifier(property(camelContext, 
javax.net.ssl.HostnameVerifier.class, value)); return true;
         case "httpconnectionpoolsize":
         case "HttpConnectionPoolSize": 
target.setHttpConnectionPoolSize(property(camelContext, 
java.lang.Integer.class, value)); return true;
         case "httpconnectionpoolttl":
@@ -125,6 +129,8 @@ public class 
AS2ClientManagerEndpointConfigurationConfigurer extends org.apache.
         case "SigningCertificateChain": 
target.setSigningCertificateChain(property(camelContext, 
java.security.cert.Certificate[].class, value)); return true;
         case "signingprivatekey":
         case "SigningPrivateKey": 
target.setSigningPrivateKey(property(camelContext, 
java.security.PrivateKey.class, value)); return true;
+        case "sslcontext":
+        case "SslContext": target.setSslContext(property(camelContext, 
javax.net.ssl.SSLContext.class, value)); return true;
         case "subject":
         case "Subject": target.setSubject(property(camelContext, 
java.lang.String.class, value)); return true;
         case "targethostname":
@@ -181,6 +187,8 @@ public class 
AS2ClientManagerEndpointConfigurationConfigurer extends org.apache.
         case "EncryptingCertificateChain": return 
java.security.cert.Certificate[].class;
         case "from":
         case "From": return java.lang.String.class;
+        case "hostnameverifier":
+        case "HostnameVerifier": return javax.net.ssl.HostnameVerifier.class;
         case "httpconnectionpoolsize":
         case "HttpConnectionPoolSize": return java.lang.Integer.class;
         case "httpconnectionpoolttl":
@@ -209,6 +217,8 @@ public class 
AS2ClientManagerEndpointConfigurationConfigurer extends org.apache.
         case "SigningCertificateChain": return 
java.security.cert.Certificate[].class;
         case "signingprivatekey":
         case "SigningPrivateKey": return java.security.PrivateKey.class;
+        case "sslcontext":
+        case "SslContext": return javax.net.ssl.SSLContext.class;
         case "subject":
         case "Subject": return java.lang.String.class;
         case "targethostname":
@@ -261,6 +271,8 @@ public class 
AS2ClientManagerEndpointConfigurationConfigurer extends org.apache.
         case "EncryptingCertificateChain": return 
target.getEncryptingCertificateChain();
         case "from":
         case "From": return target.getFrom();
+        case "hostnameverifier":
+        case "HostnameVerifier": return target.getHostnameVerifier();
         case "httpconnectionpoolsize":
         case "HttpConnectionPoolSize": return 
target.getHttpConnectionPoolSize();
         case "httpconnectionpoolttl":
@@ -289,6 +301,8 @@ public class 
AS2ClientManagerEndpointConfigurationConfigurer extends org.apache.
         case "SigningCertificateChain": return 
target.getSigningCertificateChain();
         case "signingprivatekey":
         case "SigningPrivateKey": return target.getSigningPrivateKey();
+        case "sslcontext":
+        case "SslContext": return target.getSslContext();
         case "subject":
         case "Subject": return target.getSubject();
         case "targethostname":
diff --git 
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ConfigurationConfigurer.java
 
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ConfigurationConfigurer.java
index 2924d31cacd..662a254a822 100644
--- 
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ConfigurationConfigurer.java
+++ 
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ConfigurationConfigurer.java
@@ -35,6 +35,7 @@ public class AS2ConfigurationConfigurer extends 
org.apache.camel.support.compone
         map.put("EncryptingAlgorithm", 
org.apache.camel.component.as2.api.AS2EncryptionAlgorithm.class);
         map.put("EncryptingCertificateChain", 
java.security.cert.Certificate[].class);
         map.put("From", java.lang.String.class);
+        map.put("HostnameVerifier", javax.net.ssl.HostnameVerifier.class);
         map.put("HttpConnectionPoolSize", java.lang.Integer.class);
         map.put("HttpConnectionPoolTtl", java.time.Duration.class);
         map.put("HttpConnectionTimeout", java.time.Duration.class);
@@ -49,6 +50,7 @@ public class AS2ConfigurationConfigurer extends 
org.apache.camel.support.compone
         map.put("SigningAlgorithm", 
org.apache.camel.component.as2.api.AS2SignatureAlgorithm.class);
         map.put("SigningCertificateChain", 
java.security.cert.Certificate[].class);
         map.put("SigningPrivateKey", java.security.PrivateKey.class);
+        map.put("SslContext", javax.net.ssl.SSLContext.class);
         map.put("Subject", java.lang.String.class);
         map.put("TargetHostname", java.lang.String.class);
         map.put("TargetPortNumber", java.lang.Integer.class);
@@ -91,6 +93,8 @@ public class AS2ConfigurationConfigurer extends 
org.apache.camel.support.compone
         case "EncryptingCertificateChain": 
target.setEncryptingCertificateChain(property(camelContext, 
java.security.cert.Certificate[].class, value)); return true;
         case "from":
         case "From": target.setFrom(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "hostnameverifier":
+        case "HostnameVerifier": 
target.setHostnameVerifier(property(camelContext, 
javax.net.ssl.HostnameVerifier.class, value)); return true;
         case "httpconnectionpoolsize":
         case "HttpConnectionPoolSize": 
target.setHttpConnectionPoolSize(property(camelContext, 
java.lang.Integer.class, value)); return true;
         case "httpconnectionpoolttl":
@@ -119,6 +123,8 @@ public class AS2ConfigurationConfigurer extends 
org.apache.camel.support.compone
         case "SigningCertificateChain": 
target.setSigningCertificateChain(property(camelContext, 
java.security.cert.Certificate[].class, value)); return true;
         case "signingprivatekey":
         case "SigningPrivateKey": 
target.setSigningPrivateKey(property(camelContext, 
java.security.PrivateKey.class, value)); return true;
+        case "sslcontext":
+        case "SslContext": target.setSslContext(property(camelContext, 
javax.net.ssl.SSLContext.class, value)); return true;
         case "subject":
         case "Subject": target.setSubject(property(camelContext, 
java.lang.String.class, value)); return true;
         case "targethostname":
@@ -171,6 +177,8 @@ public class AS2ConfigurationConfigurer extends 
org.apache.camel.support.compone
         case "EncryptingCertificateChain": return 
java.security.cert.Certificate[].class;
         case "from":
         case "From": return java.lang.String.class;
+        case "hostnameverifier":
+        case "HostnameVerifier": return javax.net.ssl.HostnameVerifier.class;
         case "httpconnectionpoolsize":
         case "HttpConnectionPoolSize": return java.lang.Integer.class;
         case "httpconnectionpoolttl":
@@ -199,6 +207,8 @@ public class AS2ConfigurationConfigurer extends 
org.apache.camel.support.compone
         case "SigningCertificateChain": return 
java.security.cert.Certificate[].class;
         case "signingprivatekey":
         case "SigningPrivateKey": return java.security.PrivateKey.class;
+        case "sslcontext":
+        case "SslContext": return javax.net.ssl.SSLContext.class;
         case "subject":
         case "Subject": return java.lang.String.class;
         case "targethostname":
@@ -247,6 +257,8 @@ public class AS2ConfigurationConfigurer extends 
org.apache.camel.support.compone
         case "EncryptingCertificateChain": return 
target.getEncryptingCertificateChain();
         case "from":
         case "From": return target.getFrom();
+        case "hostnameverifier":
+        case "HostnameVerifier": return target.getHostnameVerifier();
         case "httpconnectionpoolsize":
         case "HttpConnectionPoolSize": return 
target.getHttpConnectionPoolSize();
         case "httpconnectionpoolttl":
@@ -275,6 +287,8 @@ public class AS2ConfigurationConfigurer extends 
org.apache.camel.support.compone
         case "SigningCertificateChain": return 
target.getSigningCertificateChain();
         case "signingprivatekey":
         case "SigningPrivateKey": return target.getSigningPrivateKey();
+        case "sslcontext":
+        case "SslContext": return target.getSslContext();
         case "subject":
         case "Subject": return target.getSubject();
         case "targethostname":
diff --git 
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2EndpointConfigurer.java
 
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2EndpointConfigurer.java
index 6217e435990..1a2331fad37 100644
--- 
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2EndpointConfigurer.java
+++ 
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2EndpointConfigurer.java
@@ -33,6 +33,7 @@ public class AS2EndpointConfigurer extends 
PropertyConfigurerSupport implements
         map.put("ediMessageTransferEncoding", java.lang.String.class);
         map.put("ediMessageType", org.apache.http.entity.ContentType.class);
         map.put("from", java.lang.String.class);
+        map.put("hostnameVerifier", javax.net.ssl.HostnameVerifier.class);
         map.put("httpConnectionPoolSize", java.lang.Integer.class);
         map.put("httpConnectionPoolTtl", java.time.Duration.class);
         map.put("httpConnectionTimeout", java.time.Duration.class);
@@ -43,6 +44,7 @@ public class AS2EndpointConfigurer extends 
PropertyConfigurerSupport implements
         map.put("server", java.lang.String.class);
         map.put("serverFqdn", java.lang.String.class);
         map.put("serverPortNumber", java.lang.Integer.class);
+        map.put("sslContext", javax.net.ssl.SSLContext.class);
         map.put("subject", java.lang.String.class);
         map.put("targetHostname", java.lang.String.class);
         map.put("targetPortNumber", java.lang.Integer.class);
@@ -96,6 +98,8 @@ public class AS2EndpointConfigurer extends 
PropertyConfigurerSupport implements
         case "exchangepattern":
         case "exchangePattern": 
target.setExchangePattern(property(camelContext, 
org.apache.camel.ExchangePattern.class, value)); return true;
         case "from": target.getConfiguration().setFrom(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "hostnameverifier":
+        case "hostnameVerifier": 
target.getConfiguration().setHostnameVerifier(property(camelContext, 
javax.net.ssl.HostnameVerifier.class, value)); return true;
         case "httpconnectionpoolsize":
         case "httpConnectionPoolSize": 
target.getConfiguration().setHttpConnectionPoolSize(property(camelContext, 
java.lang.Integer.class, value)); return true;
         case "httpconnectionpoolttl":
@@ -125,6 +129,8 @@ public class AS2EndpointConfigurer extends 
PropertyConfigurerSupport implements
         case "signingCertificateChain": 
target.getConfiguration().setSigningCertificateChain(property(camelContext, 
java.security.cert.Certificate[].class, value)); return true;
         case "signingprivatekey":
         case "signingPrivateKey": 
target.getConfiguration().setSigningPrivateKey(property(camelContext, 
java.security.PrivateKey.class, value)); return true;
+        case "sslcontext":
+        case "sslContext": 
target.getConfiguration().setSslContext(property(camelContext, 
javax.net.ssl.SSLContext.class, value)); return true;
         case "subject": 
target.getConfiguration().setSubject(property(camelContext, 
java.lang.String.class, value)); return true;
         case "targethostname":
         case "targetHostname": 
target.getConfiguration().setTargetHostname(property(camelContext, 
java.lang.String.class, value)); return true;
@@ -177,6 +183,8 @@ public class AS2EndpointConfigurer extends 
PropertyConfigurerSupport implements
         case "exchangepattern":
         case "exchangePattern": return org.apache.camel.ExchangePattern.class;
         case "from": return java.lang.String.class;
+        case "hostnameverifier":
+        case "hostnameVerifier": return javax.net.ssl.HostnameVerifier.class;
         case "httpconnectionpoolsize":
         case "httpConnectionPoolSize": return java.lang.Integer.class;
         case "httpconnectionpoolttl":
@@ -206,6 +214,8 @@ public class AS2EndpointConfigurer extends 
PropertyConfigurerSupport implements
         case "signingCertificateChain": return 
java.security.cert.Certificate[].class;
         case "signingprivatekey":
         case "signingPrivateKey": return java.security.PrivateKey.class;
+        case "sslcontext":
+        case "sslContext": return javax.net.ssl.SSLContext.class;
         case "subject": return java.lang.String.class;
         case "targethostname":
         case "targetHostname": return java.lang.String.class;
@@ -254,6 +264,8 @@ public class AS2EndpointConfigurer extends 
PropertyConfigurerSupport implements
         case "exchangepattern":
         case "exchangePattern": return target.getExchangePattern();
         case "from": return target.getConfiguration().getFrom();
+        case "hostnameverifier":
+        case "hostnameVerifier": return 
target.getConfiguration().getHostnameVerifier();
         case "httpconnectionpoolsize":
         case "httpConnectionPoolSize": return 
target.getConfiguration().getHttpConnectionPoolSize();
         case "httpconnectionpoolttl":
@@ -283,6 +295,8 @@ public class AS2EndpointConfigurer extends 
PropertyConfigurerSupport implements
         case "signingCertificateChain": return 
target.getConfiguration().getSigningCertificateChain();
         case "signingprivatekey":
         case "signingPrivateKey": return 
target.getConfiguration().getSigningPrivateKey();
+        case "sslcontext":
+        case "sslContext": return target.getConfiguration().getSslContext();
         case "subject": return target.getConfiguration().getSubject();
         case "targethostname":
         case "targetHostname": return 
target.getConfiguration().getTargetHostname();
diff --git 
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2EndpointUriFactory.java
 
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2EndpointUriFactory.java
index 2528eb6bf04..699b07d5769 100644
--- 
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2EndpointUriFactory.java
+++ 
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2EndpointUriFactory.java
@@ -21,7 +21,7 @@ public class AS2EndpointUriFactory extends 
org.apache.camel.support.component.En
     private static final Set<String> SECRET_PROPERTY_NAMES;
     private static final Set<String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(41);
+        Set<String> props = new HashSet<>(43);
         props.add("apiName");
         props.add("as2From");
         props.add("as2MessageStructure");
@@ -41,6 +41,7 @@ public class AS2EndpointUriFactory extends 
org.apache.camel.support.component.En
         props.add("exceptionHandler");
         props.add("exchangePattern");
         props.add("from");
+        props.add("hostnameVerifier");
         props.add("httpConnectionPoolSize");
         props.add("httpConnectionPoolTtl");
         props.add("httpConnectionTimeout");
@@ -58,6 +59,7 @@ public class AS2EndpointUriFactory extends 
org.apache.camel.support.component.En
         props.add("signingAlgorithm");
         props.add("signingCertificateChain");
         props.add("signingPrivateKey");
+        props.add("sslContext");
         props.add("subject");
         props.add("targetHostname");
         props.add("targetPortNumber");
diff --git 
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ServerManagerEndpointConfigurationConfigurer.java
 
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ServerManagerEndpointConfigurationConfigurer.java
index e4ca3775905..1e992f209d7 100644
--- 
a/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ServerManagerEndpointConfigurationConfigurer.java
+++ 
b/components/camel-as2/camel-as2-component/src/generated/java/org/apache/camel/component/as2/AS2ServerManagerEndpointConfigurationConfigurer.java
@@ -35,6 +35,7 @@ public class AS2ServerManagerEndpointConfigurationConfigurer 
extends org.apache.
         map.put("EncryptingAlgorithm", 
org.apache.camel.component.as2.api.AS2EncryptionAlgorithm.class);
         map.put("EncryptingCertificateChain", 
java.security.cert.Certificate[].class);
         map.put("From", java.lang.String.class);
+        map.put("HostnameVerifier", javax.net.ssl.HostnameVerifier.class);
         map.put("HttpConnectionPoolSize", java.lang.Integer.class);
         map.put("HttpConnectionPoolTtl", java.time.Duration.class);
         map.put("HttpConnectionTimeout", java.time.Duration.class);
@@ -50,6 +51,7 @@ public class AS2ServerManagerEndpointConfigurationConfigurer 
extends org.apache.
         map.put("SigningAlgorithm", 
org.apache.camel.component.as2.api.AS2SignatureAlgorithm.class);
         map.put("SigningCertificateChain", 
java.security.cert.Certificate[].class);
         map.put("SigningPrivateKey", java.security.PrivateKey.class);
+        map.put("SslContext", javax.net.ssl.SSLContext.class);
         map.put("Subject", java.lang.String.class);
         map.put("TargetHostname", java.lang.String.class);
         map.put("TargetPortNumber", java.lang.Integer.class);
@@ -92,6 +94,8 @@ public class AS2ServerManagerEndpointConfigurationConfigurer 
extends org.apache.
         case "EncryptingCertificateChain": 
target.setEncryptingCertificateChain(property(camelContext, 
java.security.cert.Certificate[].class, value)); return true;
         case "from":
         case "From": target.setFrom(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "hostnameverifier":
+        case "HostnameVerifier": 
target.setHostnameVerifier(property(camelContext, 
javax.net.ssl.HostnameVerifier.class, value)); return true;
         case "httpconnectionpoolsize":
         case "HttpConnectionPoolSize": 
target.setHttpConnectionPoolSize(property(camelContext, 
java.lang.Integer.class, value)); return true;
         case "httpconnectionpoolttl":
@@ -122,6 +126,8 @@ public class 
AS2ServerManagerEndpointConfigurationConfigurer extends org.apache.
         case "SigningCertificateChain": 
target.setSigningCertificateChain(property(camelContext, 
java.security.cert.Certificate[].class, value)); return true;
         case "signingprivatekey":
         case "SigningPrivateKey": 
target.setSigningPrivateKey(property(camelContext, 
java.security.PrivateKey.class, value)); return true;
+        case "sslcontext":
+        case "SslContext": target.setSslContext(property(camelContext, 
javax.net.ssl.SSLContext.class, value)); return true;
         case "subject":
         case "Subject": target.setSubject(property(camelContext, 
java.lang.String.class, value)); return true;
         case "targethostname":
@@ -174,6 +180,8 @@ public class 
AS2ServerManagerEndpointConfigurationConfigurer extends org.apache.
         case "EncryptingCertificateChain": return 
java.security.cert.Certificate[].class;
         case "from":
         case "From": return java.lang.String.class;
+        case "hostnameverifier":
+        case "HostnameVerifier": return javax.net.ssl.HostnameVerifier.class;
         case "httpconnectionpoolsize":
         case "HttpConnectionPoolSize": return java.lang.Integer.class;
         case "httpconnectionpoolttl":
@@ -204,6 +212,8 @@ public class 
AS2ServerManagerEndpointConfigurationConfigurer extends org.apache.
         case "SigningCertificateChain": return 
java.security.cert.Certificate[].class;
         case "signingprivatekey":
         case "SigningPrivateKey": return java.security.PrivateKey.class;
+        case "sslcontext":
+        case "SslContext": return javax.net.ssl.SSLContext.class;
         case "subject":
         case "Subject": return java.lang.String.class;
         case "targethostname":
@@ -252,6 +262,8 @@ public class 
AS2ServerManagerEndpointConfigurationConfigurer extends org.apache.
         case "EncryptingCertificateChain": return 
target.getEncryptingCertificateChain();
         case "from":
         case "From": return target.getFrom();
+        case "hostnameverifier":
+        case "HostnameVerifier": return target.getHostnameVerifier();
         case "httpconnectionpoolsize":
         case "HttpConnectionPoolSize": return 
target.getHttpConnectionPoolSize();
         case "httpconnectionpoolttl":
@@ -282,6 +294,8 @@ public class 
AS2ServerManagerEndpointConfigurationConfigurer extends org.apache.
         case "SigningCertificateChain": return 
target.getSigningCertificateChain();
         case "signingprivatekey":
         case "SigningPrivateKey": return target.getSigningPrivateKey();
+        case "sslcontext":
+        case "SslContext": return target.getSslContext();
         case "subject":
         case "Subject": return target.getSubject();
         case "targethostname":
diff --git 
a/components/camel-as2/camel-as2-component/src/generated/resources/org/apache/camel/component/as2/as2.json
 
b/components/camel-as2/camel-as2-component/src/generated/resources/org/apache/camel/component/as2/as2.json
index c0e541a4a07..c5d81cdf3ab 100644
--- 
a/components/camel-as2/camel-as2-component/src/generated/resources/org/apache/camel/component/as2/as2.json
+++ 
b/components/camel-as2/camel-as2-component/src/generated/resources/org/apache/camel/component/as2/as2.json
@@ -43,6 +43,7 @@
     "ediMessageTransferEncoding": { "kind": "parameter", "displayName": "Edi 
Message Transfer Encoding", "group": "common", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.as2.AS2Configuration", "configurationField": 
"configuration", "description": "The transfer encoding of EDI message." },
     "ediMessageType": { "kind": "parameter", "displayName": "Edi Message 
Type", "group": "common", "label": "", "required": false, "type": "object", 
"javaType": "org.apache.http.entity.ContentType", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.as2.AS2Configuration", "configurationField": 
"configuration", "description": "The content type of EDI message. One of 
application\/edifact, application\/edi-x12, application\/edi-consent" },
     "from": { "kind": "parameter", "displayName": "From", "group": "common", 
"label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.as2.AS2Configuration", 
"configurationField": "configuration", "description": "The value of the From 
header of AS2 message." },
+    "hostnameVerifier": { "kind": "parameter", "displayName": "Hostname 
Verifier", "group": "common", "label": "", "required": false, "type": "object", 
"javaType": "javax.net.ssl.HostnameVerifier", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.as2.AS2Configuration", "configurationField": 
"configuration", "description": "Set hostname verifier for SSL session." },
     "httpConnectionPoolSize": { "kind": "parameter", "displayName": "Http 
Connection Pool Size", "group": "common", "label": "", "required": false, 
"type": "integer", "javaType": "java.lang.Integer", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "5", "configurationClass": 
"org.apache.camel.component.as2.AS2Configuration", "configurationField": 
"configuration", "description": "The maximum size of the connection pool for 
http connections (client only)" },
     "httpConnectionPoolTtl": { "kind": "parameter", "displayName": "Http 
Connection Pool Ttl", "group": "common", "label": "", "required": false, 
"type": "object", "javaType": "java.time.Duration", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "15m", 
"configurationClass": "org.apache.camel.component.as2.AS2Configuration", 
"configurationField": "configuration", "description": "The time to live for 
connections in the connection pool (client only)" },
     "httpConnectionTimeout": { "kind": "parameter", "displayName": "Http 
Connection Timeout", "group": "common", "label": "", "required": false, "type": 
"object", "javaType": "java.time.Duration", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "5s", "configurationClass": 
"org.apache.camel.component.as2.AS2Configuration", "configurationField": 
"configuration", "description": "The timeout of the http connection (client 
only)" },
@@ -53,6 +54,7 @@
     "server": { "kind": "parameter", "displayName": "Server", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "Camel AS2 Server Endpoint", "configurationClass": 
"org.apache.camel.component.as2.AS2Configuration", "configurationField": 
"configuration", "description": "The value included in the Server message 
header identifying the AS2 Server." },
     "serverFqdn": { "kind": "parameter", "displayName": "Server Fqdn", 
"group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "camel.apache.org", "configurationClass": 
"org.apache.camel.component.as2.AS2Configuration", "configurationField": 
"configuration", "description": "The Server Fully Qualified Domain Name (FQDN). 
Used in message ids sent by endpoint." },
     "serverPortNumber": { "kind": "parameter", "displayName": "Server Port 
Number", "group": "common", "label": "", "required": false, "type": "integer", 
"javaType": "java.lang.Integer", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.as2.AS2Configuration", "configurationField": 
"configuration", "description": "The port number of server." },
+    "sslContext": { "kind": "parameter", "displayName": "Ssl Context", 
"group": "common", "label": "", "required": false, "type": "object", 
"javaType": "javax.net.ssl.SSLContext", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.as2.AS2Configuration", "configurationField": 
"configuration", "description": "Set SSL context for connection to remote 
server." },
     "subject": { "kind": "parameter", "displayName": "Subject", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.as2.AS2Configuration", 
"configurationField": "configuration", "description": "The value of Subject 
header of AS2 message." },
     "targetHostname": { "kind": "parameter", "displayName": "Target Hostname", 
"group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.as2.AS2Configuration", "configurationField": 
"configuration", "description": "The host name (IP or DNS name) of target 
host." },
     "targetPortNumber": { "kind": "parameter", "displayName": "Target Port 
Number", "group": "common", "label": "", "required": false, "type": "integer", 
"javaType": "java.lang.Integer", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "80", "configurationClass": 
"org.apache.camel.component.as2.AS2Configuration", "configurationField": 
"configuration", "description": "The port number of target host. -1 indicates 
the scheme default port." },
@@ -67,7 +69,7 @@
     "signingAlgorithm": { "kind": "parameter", "displayName": "Signing 
Algorithm", "group": "security", "label": "security", "required": false, 
"type": "object", "javaType": 
"org.apache.camel.component.as2.api.AS2SignatureAlgorithm", "enum": [ 
"SHA3_224WITHRSA", "SHA3_256WITHRSA", "SHA3_384withRSA", "SHA3_512WITHRSA", 
"MD5WITHRSA", "SHA1WITHRSA", "MD2WITHRSA", "SHA224WITHRSA", "SHA256WITHRSA", 
"SHA384WITHRSA", "SHA512WITHRSA", "RIPEMD128WITHRSA", "RIPEMD160WITHRSA", 
"RIPEMD256WITHRSA", " [...]
     "signingCertificateChain": { "kind": "parameter", "displayName": "Signing 
Certificate Chain", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": "java.security.cert.Certificate[]", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.as2.AS2Configuration", "configurationField": 
"configuration", "description": "The chain of certificates used to sign EDI 
message." },
     "signingPrivateKey": { "kind": "parameter", "displayName": "Signing 
Private Key", "group": "security", "label": "security", "required": false, 
"type": "object", "javaType": "java.security.PrivateKey", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.as2.AS2Configuration", "configurationField": 
"configuration", "description": "The key used to sign the EDI message." },
-    "validateSigningCertificateChain": { "kind": "parameter", "displayName": 
"Validate Signing Certificate Chain", "group": "security", "label": "security", 
"required": false, "type": "object", "javaType": 
"java.security.cert.Certificate[]", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.as2.AS2Configuration", "configurationField": 
"configuration", "description": "Certifiates to validate the messages signature 
against. If not s [...]
+    "validateSigningCertificateChain": { "kind": "parameter", "displayName": 
"Validate Signing Certificate Chain", "group": "security", "label": "security", 
"required": false, "type": "object", "javaType": 
"java.security.cert.Certificate[]", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.as2.AS2Configuration", "configurationField": 
"configuration", "description": "Certificates to validate the message's 
signature against. If not [...]
   },
   "apis": {
     "client": { "consumerOnly": false, "producerOnly": true, "description": 
"Sends EDI Messages over HTTP", "methods": { "send": { "description": "Send 
ediMessage to trading partner", "signatures": [ 
"org.apache.http.protocol.HttpCoreContext send(String ediMessage, String 
requestUri, String subject, String from, String as2From, String as2To, 
org.apache.camel.component.as2.api.AS2MessageStructure as2MessageStructure, 
org.apache.http.entity.ContentType ediMessageContentType, String ediMess [...]
diff --git 
a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java
 
b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java
index 8159df12423..8be9214115b 100644
--- 
a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java
+++ 
b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java
@@ -20,6 +20,9 @@ import java.security.PrivateKey;
 import java.security.cert.Certificate;
 import java.time.Duration;
 
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.component.as2.api.AS2CompressionAlgorithm;
 import org.apache.camel.component.as2.api.AS2EncryptionAlgorithm;
@@ -110,6 +113,11 @@ public class AS2Configuration {
     private Duration httpConnectionPoolTtl = Duration.ofMinutes(15);
     @UriParam(label = "security")
     private Certificate[] validateSigningCertificateChain;
+    @UriParam
+    private SSLContext sslContext;
+    // If you use localhost-based AS2 server, you don't need to specify a 
hostnameVerifier
+    @UriParam
+    private HostnameVerifier hostnameVerifier;
 
     public AS2ApiName getApiName() {
         return apiName;
@@ -497,11 +505,36 @@ public class AS2Configuration {
     }
 
     /**
-     * Certifiates to validate the messages signature against. If not 
supplied, validation will not take place. Server:
-     * validates the received message. Client: not yet implemented, should 
validate the MDN
+     * Certificates to validate the message's signature against. If not 
supplied, validation will not take place.
+     * Server: validates the received message. Client: not yet implemented, 
should validate the MDN
      */
     public void setValidateSigningCertificateChain(Certificate[] 
validateSigningCertificateChain) {
         this.validateSigningCertificateChain = validateSigningCertificateChain;
     }
 
+    public SSLContext getSslContext() {
+        return sslContext;
+    }
+
+    /**
+     * Set SSL context for connection to remote server.
+     *
+     * @param sslContext
+     */
+    public void setSslContext(SSLContext sslContext) {
+        this.sslContext = sslContext;
+    }
+
+    public HostnameVerifier getHostnameVerifier() {
+        return hostnameVerifier;
+    }
+
+    /**
+     * Set hostname verifier for SSL session.
+     *
+     * @param hostnameVerifier
+     */
+    public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
+        this.hostnameVerifier = hostnameVerifier;
+    }
 }
diff --git 
a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Endpoint.java
 
b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Endpoint.java
index 09e0d30596a..42134cf3a02 100644
--- 
a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Endpoint.java
+++ 
b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Endpoint.java
@@ -22,6 +22,8 @@ import java.security.PrivateKey;
 import java.security.cert.Certificate;
 import java.util.Map;
 
+import javax.net.ssl.SSLContext;
+
 import org.apache.camel.Category;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
@@ -224,6 +226,14 @@ public class AS2Endpoint extends 
AbstractApiEndpoint<AS2ApiName, AS2Configuratio
         
configuration.setEncryptingCertificateChain(encryptingCertificateChain);
     }
 
+    public SSLContext getSslContext() {
+        return configuration.getSslContext();
+    }
+
+    public void setSslContext(SSLContext sslContext) {
+        configuration.setSslContext(sslContext);
+    }
+
     @Override
     protected ApiMethodPropertiesHelper<AS2Configuration> 
getPropertiesHelper() {
         return AS2PropertiesHelper.getHelper(getCamelContext());
diff --git 
a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/internal/AS2ConnectionHelper.java
 
b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/internal/AS2ConnectionHelper.java
index da1b01e2eb4..b99ebec65c4 100644
--- 
a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/internal/AS2ConnectionHelper.java
+++ 
b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/internal/AS2ConnectionHelper.java
@@ -55,7 +55,8 @@ public final class AS2ConnectionHelper {
                 configuration.getAs2Version(), configuration.getUserAgent(), 
configuration.getClientFqdn(),
                 configuration.getTargetHostname(), 
configuration.getTargetPortNumber(), configuration.getHttpSocketTimeout(),
                 configuration.getHttpConnectionTimeout(), 
configuration.getHttpConnectionPoolSize(),
-                configuration.getHttpConnectionPoolTtl());
+                configuration.getHttpConnectionPoolTtl(), 
configuration.getSslContext(),
+                configuration.getHostnameVerifier());
     }
 
     /**
@@ -74,7 +75,7 @@ public final class AS2ConnectionHelper {
                         configuration.getServerFqdn(), 
configuration.getServerPortNumber(), configuration.getSigningAlgorithm(),
                         configuration.getSigningCertificateChain(), 
configuration.getSigningPrivateKey(),
                         configuration.getDecryptingPrivateKey(), 
configuration.getMdnMessageTemplate(),
-                        configuration.getValidateSigningCertificateChain());
+                        configuration.getValidateSigningCertificateChain(), 
configuration.getSslContext());
                 serverConnections.put(configuration.getServerPortNumber(), 
serverConnection);
             }
             return serverConnection;
diff --git 
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIT.java
 
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIT.java
index bb3eec87c38..7736ea68f33 100644
--- 
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIT.java
+++ 
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIT.java
@@ -790,7 +790,7 @@ public class AS2ClientManagerIT extends 
AbstractAS2ITSupport {
                 AS2_VERSION, ORIGIN_SERVER_NAME,
                 SERVER_FQDN, PARTNER_TARGET_PORT, 
AS2SignatureAlgorithm.SHA256WITHRSA,
                 new Certificate[] { serverCert }, serverKP.getPrivate(), 
serverKP.getPrivate(),
-                MDN_MESSAGE_TEMPLATE, new Certificate[] { clientCert });
+                MDN_MESSAGE_TEMPLATE, new Certificate[] { clientCert }, null);
         requestHandler = new RequestHandler();
         serverConnection.listen("/", requestHandler);
     }
diff --git 
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerManagerIT.java
 
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerManagerIT.java
index 6d33a2b4a2d..2261a0f96c4 100644
--- 
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerManagerIT.java
+++ 
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerManagerIT.java
@@ -28,6 +28,8 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
+import javax.net.ssl.SSLContext;
+
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
@@ -52,6 +54,11 @@ import 
org.apache.camel.component.as2.internal.AS2ApiCollection;
 import org.apache.camel.component.as2.internal.AS2Constants;
 import org.apache.camel.component.as2.internal.AS2ServerManagerApiMethod;
 import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.support.jsse.KeyManagersParameters;
+import org.apache.camel.support.jsse.KeyStoreParameters;
+import org.apache.camel.support.jsse.SSLContextParameters;
+import org.apache.camel.support.jsse.SSLContextServerParameters;
+import org.apache.camel.support.jsse.TrustManagersParameters;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
@@ -146,6 +153,9 @@ public class AS2ServerManagerIT extends 
AbstractAS2ITSupport {
 
     private static KeyPair decryptingKP;
 
+    private static SSLContext clientSslContext;
+    private static SSLContext serverSslContext;
+
     @BeforeAll
     public static void setup() throws Exception {
         setupSigningGenerator();
@@ -156,7 +166,8 @@ public class AS2ServerManagerIT extends 
AbstractAS2ITSupport {
         AS2ClientConnection clientConnection
                 = new AS2ClientConnection(
                         AS2_VERSION, USER_AGENT, CLIENT_FQDN, TARGET_HOST, 
TARGET_PORT, HTTP_SOCKET_TIMEOUT,
-                        HTTP_CONNECTION_TIMEOUT, HTTP_CONNECTION_POOL_SIZE, 
HTTP_CONNECTION_POOL_TTL);
+                        HTTP_CONNECTION_TIMEOUT, HTTP_CONNECTION_POOL_SIZE, 
HTTP_CONNECTION_POOL_TTL, clientSslContext,
+                        null);
         AS2ClientManager clientManager = new 
AS2ClientManager(clientConnection);
 
         clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, 
AS2_NAME, AS2MessageStructure.PLAIN,
@@ -221,7 +232,8 @@ public class AS2ServerManagerIT extends 
AbstractAS2ITSupport {
         AS2ClientConnection clientConnection
                 = new AS2ClientConnection(
                         AS2_VERSION, USER_AGENT, CLIENT_FQDN, TARGET_HOST, 
TARGET_PORT, HTTP_SOCKET_TIMEOUT,
-                        HTTP_CONNECTION_TIMEOUT, HTTP_CONNECTION_POOL_SIZE, 
HTTP_CONNECTION_POOL_TTL);
+                        HTTP_CONNECTION_TIMEOUT, HTTP_CONNECTION_POOL_SIZE, 
HTTP_CONNECTION_POOL_TTL, clientSslContext,
+                        null);
         AS2ClientManager clientManager = new 
AS2ClientManager(clientConnection);
 
         clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, 
AS2_NAME, AS2MessageStructure.SIGNED,
@@ -302,7 +314,8 @@ public class AS2ServerManagerIT extends 
AbstractAS2ITSupport {
         AS2ClientConnection clientConnection
                 = new AS2ClientConnection(
                         AS2_VERSION, USER_AGENT, CLIENT_FQDN, TARGET_HOST, 
TARGET_PORT, HTTP_SOCKET_TIMEOUT,
-                        HTTP_CONNECTION_TIMEOUT, HTTP_CONNECTION_POOL_SIZE, 
HTTP_CONNECTION_POOL_TTL);
+                        HTTP_CONNECTION_TIMEOUT, HTTP_CONNECTION_POOL_SIZE, 
HTTP_CONNECTION_POOL_TTL, clientSslContext,
+                        null);
         AS2ClientManager clientManager = new 
AS2ClientManager(clientConnection);
 
         KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
@@ -394,7 +407,8 @@ public class AS2ServerManagerIT extends 
AbstractAS2ITSupport {
         AS2ClientConnection clientConnection
                 = new AS2ClientConnection(
                         AS2_VERSION, USER_AGENT, CLIENT_FQDN, TARGET_HOST, 
TARGET_PORT, HTTP_SOCKET_TIMEOUT,
-                        HTTP_CONNECTION_TIMEOUT, HTTP_CONNECTION_POOL_SIZE, 
HTTP_CONNECTION_POOL_TTL);
+                        HTTP_CONNECTION_TIMEOUT, HTTP_CONNECTION_POOL_SIZE, 
HTTP_CONNECTION_POOL_TTL, clientSslContext,
+                        null);
         AS2ClientManager clientManager = new 
AS2ClientManager(clientConnection);
 
         clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, 
AS2_NAME, AS2MessageStructure.ENCRYPTED,
@@ -464,7 +478,8 @@ public class AS2ServerManagerIT extends 
AbstractAS2ITSupport {
         AS2ClientConnection clientConnection
                 = new AS2ClientConnection(
                         AS2_VERSION, USER_AGENT, CLIENT_FQDN, TARGET_HOST, 
TARGET_PORT, HTTP_SOCKET_TIMEOUT,
-                        HTTP_CONNECTION_TIMEOUT, HTTP_CONNECTION_POOL_SIZE, 
HTTP_CONNECTION_POOL_TTL);
+                        HTTP_CONNECTION_TIMEOUT, HTTP_CONNECTION_POOL_SIZE, 
HTTP_CONNECTION_POOL_TTL, clientSslContext,
+                        null);
         AS2ClientManager clientManager = new 
AS2ClientManager(clientConnection);
 
         HttpCoreContext context = clientManager.send(EDI_MESSAGE, 
"/process_error", SUBJECT, FROM, AS2_NAME, AS2_NAME,
@@ -490,7 +505,8 @@ public class AS2ServerManagerIT extends 
AbstractAS2ITSupport {
         AS2ClientConnection clientConnection
                 = new AS2ClientConnection(
                         AS2_VERSION, USER_AGENT, CLIENT_FQDN, TARGET_HOST, 
TARGET_PORT, HTTP_SOCKET_TIMEOUT,
-                        HTTP_CONNECTION_TIMEOUT, HTTP_CONNECTION_POOL_SIZE, 
HTTP_CONNECTION_POOL_TTL);
+                        HTTP_CONNECTION_TIMEOUT, HTTP_CONNECTION_POOL_SIZE, 
HTTP_CONNECTION_POOL_TTL, clientSslContext,
+                        null);
         AS2ClientManager clientManager = new 
AS2ClientManager(clientConnection);
 
         //Testing MDN parameter defaults
@@ -572,11 +588,57 @@ public class AS2ServerManagerIT extends 
AbstractAS2ITSupport {
 
     }
 
+    public SSLContext setupClientContext(CamelContext context) throws 
Exception {
+        SSLContextParameters sslContextParameters = new SSLContextParameters();
+
+        KeyStoreParameters truststoreParameters = new KeyStoreParameters();
+        truststoreParameters.setResource("jsse/localhost.p12");
+        truststoreParameters.setPassword("changeit");
+
+        KeyManagersParameters kmp = new KeyManagersParameters();
+        kmp.setKeyPassword("changeit");
+        kmp.setKeyStore(truststoreParameters);
+
+        TrustManagersParameters clientSSLTrustManagers = new 
TrustManagersParameters();
+        clientSSLTrustManagers.setKeyStore(truststoreParameters);
+        sslContextParameters.setKeyManagers(kmp);
+        sslContextParameters.setTrustManagers(clientSSLTrustManagers);
+
+        SSLContext sslContext = sslContextParameters.createSSLContext(context);
+        return sslContext;
+    }
+
+    public SSLContext setupServerContext(CamelContext context) throws 
Exception {
+        KeyStoreParameters ksp = new KeyStoreParameters();
+        ksp.setResource("jsse/localhost.p12");
+        ksp.setPassword("changeit");
+
+        KeyManagersParameters kmp = new KeyManagersParameters();
+        kmp.setKeyPassword("changeit");
+        kmp.setKeyStore(ksp);
+
+        TrustManagersParameters tmp = new TrustManagersParameters();
+        tmp.setKeyStore(ksp);
+
+        SSLContextServerParameters scsp = new SSLContextServerParameters();
+
+        SSLContextParameters sslContextParameters = new SSLContextParameters();
+        sslContextParameters.setKeyManagers(kmp);
+        sslContextParameters.setTrustManagers(tmp);
+        sslContextParameters.setServerParameters(scsp);
+
+        SSLContext sslContext = sslContextParameters.createSSLContext(context);
+        return sslContext;
+    }
+
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
+        this.clientSslContext = setupClientContext(context);
+        this.serverSslContext = setupClientContext(context);
         AS2Component as2Component = (AS2Component) context.getComponent("as2");
         AS2Configuration configuration = as2Component.getConfiguration();
+        configuration.setSslContext(serverSslContext);
         configuration.setDecryptingPrivateKey(decryptingKP.getPrivate());
         return context;
     }
diff --git 
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/CreateEndpointManualIssueTest.java
 
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/CreateEndpointManualIssueTest.java
index c3a03a7bfa3..86c0dc13f03 100644
--- 
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/CreateEndpointManualIssueTest.java
+++ 
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/CreateEndpointManualIssueTest.java
@@ -55,7 +55,6 @@ public class CreateEndpointManualIssueTest {
         endpointConfiguration.setEdiMessageType(contentTypeEdifact);
         endpointConfiguration.setFrom("dk2kEdi");
         endpointConfiguration.setSubject("mysubject");
-        endpointConfiguration.setSubject("mysubject");
         
endpointConfiguration.setSigningAlgorithm(AS2SignatureAlgorithm.MD2WITHRSA);
         endpointConfiguration.setEdiMessageTransferEncoding("7bit");
 
diff --git 
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/MendelsonCertLoader.java
 
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/MendelsonCertLoader.java
new file mode 100644
index 00000000000..ce82de3849e
--- /dev/null
+++ 
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/MendelsonCertLoader.java
@@ -0,0 +1,183 @@
+package org.apache.camel.component.as2;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.spec.InvalidKeySpecException;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.List;
+
+import javax.net.ssl.SSLContext;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.http.conn.ssl.TrustAllStrategy;
+import org.apache.http.ssl.SSLContexts;
+
+/**
+ * That's a utility class for preparing Mendelson-specific certificate chain, 
private key, ssl context
+ */
+public class MendelsonCertLoader {
+
+    private static final String MENDELSON_CERT = "mendelson/key4.cer";
+    private static final String MENDELSON_PRIVATE_KEY = "mendelson/key3.pfx";
+
+    private final List<Certificate> chainAsList = new ArrayList<>();
+
+    private PrivateKey privateKey;
+    private SSLContext sslContext;
+
+    public void setupSslContext() {
+        try {
+            InputStream mendelsonPrivateKeyAsStream = 
getClass().getClassLoader().getResourceAsStream(MENDELSON_PRIVATE_KEY);
+            KeyStore keyStore = getKeyStore(mendelsonPrivateKeyAsStream);
+            sslContext = SSLContexts.custom().setKeyStoreType("PKCS12")
+                    .loadTrustMaterial(keyStore, new TrustAllStrategy())
+                    .build();
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+        } catch (KeyManagementException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+
+        if (sslContext == null) {
+            throw new IllegalStateException("failed to configure SSL context");
+        }
+    }
+
+    private KeyStore getKeyStore(InputStream inputStream) throws IOException, 
NoSuchAlgorithmException {
+        String password = "test";
+        KeyStore ks;
+        try {
+            ks = KeyStore.getInstance("PKCS12");
+            ks.load(inputStream, password.toCharArray());
+            return ks;
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+        } catch (CertificateException e) {
+            e.printStackTrace();
+        }
+        throw new IllegalStateException("about to return null");
+    }
+
+    public void setupCertificateChain() {
+
+        InputStream mendelsonCertAsStream = 
getClass().getClassLoader().getResourceAsStream(MENDELSON_CERT);
+        if (mendelsonCertAsStream == null) {
+            //LOG.error("Couldn't read out client certificate as stream.");
+            throw new IllegalStateException("Couldn't read out certificate as 
stream.");
+        }
+
+        InputStream mendelsonPrivateKeyAsStream = 
getClass().getClassLoader().getResourceAsStream(MENDELSON_PRIVATE_KEY);
+        if (mendelsonPrivateKeyAsStream == null) {
+            //LOG.error("Couldn't read out private key as stream.");
+            throw new IllegalStateException("Couldn't read out key storage as 
stream.");
+        }
+
+        try {
+            Certificate mendelsonCert = 
getCertificateFromStream(mendelsonCertAsStream);
+            chainAsList.add(mendelsonCert);
+
+            //private key
+            privateKey = 
getPrivateKeyFromPKCSStream(mendelsonPrivateKeyAsStream);
+
+        } catch (IOException e) {
+            String errMsg = "Error while trying to load certificate to the 
keyload. IO error when reading a byte array.  " + e;
+            System.out.println(errMsg);
+        } catch (NoSuchAlgorithmException e) {
+            String errMsg = "Error while trying to load certificate to the 
keyload. Requested algorithm isn't found.  " + e;
+            System.out.println(errMsg);
+        } catch (CertificateException e) {
+            String errMsg = "Error while trying to load certificate to the 
keyload. There is a certificate problem.  " + e;
+            System.out.println(errMsg);
+        } catch (InvalidKeySpecException e) {
+            String errMsg = "Can not init private key store  " + e;
+            System.out.println(errMsg);
+        }
+    }
+
+    public SSLContext getSslContext() {
+        return sslContext;
+    }
+
+    public Certificate[] getChain() {
+        if (chainAsList.size() > 0) {
+            Certificate[] arrayCert = new Certificate[chainAsList.size()];
+
+            for (int i = 0; i < chainAsList.size(); i++) {
+                arrayCert[i] = chainAsList.get(i);
+            }
+            return arrayCert;
+        } else {
+            return null;
+        }
+    }
+
+    public PrivateKey getPrivateKey() {
+        return privateKey;
+    }
+
+    private List<Certificate> getCertificatesFromStream(InputStream 
inputStream) throws IOException, CertificateException {
+        CertificateFactory certificateFactory = 
CertificateFactory.getInstance("X.509");
+        return (List<Certificate>) 
certificateFactory.generateCertificates(inputStream);
+    }
+
+    private Certificate getCertificateFromStream(InputStream inputStream) 
throws IOException, CertificateException {
+        CertificateFactory certificateFactory = 
CertificateFactory.getInstance("X.509");
+        return certificateFactory.generateCertificate(inputStream);
+    }
+
+    
//https://stackoverflow.com/questions/18644286/creating-privatekey-object-from-pkcs12
+    private PrivateKey getPrivateKeyFromPKCSStream(InputStream inputStream)
+            throws IOException, NoSuchAlgorithmException, 
InvalidKeySpecException {
+        String password = "test";
+        KeyStore ks = null;
+        try {
+            ks = KeyStore.getInstance("PKCS12");
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+        }
+        try {
+            ks.load(inputStream, password.toCharArray());
+        } catch (CertificateException e) {
+            e.printStackTrace();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        try {
+            return (PrivateKey) ks.getKey(
+                    ks.aliases().nextElement(),
+                    password.toCharArray());
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+        } catch (UnrecoverableKeyException e) {
+            e.printStackTrace();
+        }
+        throw new IllegalStateException("about to return null");
+    }
+
+    private byte[] getBytesFromPem(InputStream inputStream) throws IOException 
{
+        String privateKeyPEM
+                = IOUtils.toString(inputStream, 
StandardCharsets.UTF_8).replaceAll("-{5}.+-{5}", "").replaceAll("\\s", "");
+        return Base64.getDecoder().decode(privateKeyPEM);
+    }
+
+    private byte[] getBytesFromPKCS12(InputStream inputStream) throws 
IOException {
+        String privateKeyPKCS12 = IOUtils.toString(inputStream, 
StandardCharsets.UTF_8);
+        return privateKeyPKCS12.getBytes(StandardCharsets.UTF_8);
+    }
+
+}
diff --git 
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/MendelsonSslEndpointIT.java
 
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/MendelsonSslEndpointIT.java
new file mode 100644
index 00000000000..4340216eff0
--- /dev/null
+++ 
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/MendelsonSslEndpointIT.java
@@ -0,0 +1,132 @@
+package org.apache.camel.component.as2;
+
+import java.nio.charset.Charset;
+
+import javax.net.ssl.HostnameVerifier;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.as2.api.AS2EncryptionAlgorithm;
+import org.apache.camel.component.as2.api.AS2MessageStructure;
+import org.apache.camel.component.as2.api.AS2SignatureAlgorithm;
+import org.apache.camel.component.as2.internal.AS2ApiName;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Test class for testing connection to a public 3rd party AS2 server 
Mendelson. This class gives more info for
+ * camel-as2 connectivity to a remote server compared to HTTPS connection to 
localhost server. Eventually test method(s)
+ * will be committed with @Disabled annotation due to they can fail because 
the mendelson server goes offline or the
+ * certificate expires. I assume we don't want a build to fail because of such 
3rd party connectivity dependency.
+ * Mendelson page: http://mendelson-e-c.com/as2_testserver
+ */
+public class MendelsonSslEndpointIT extends AbstractAS2ITSupport {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(MendelsonSslEndpointIT.class);
+    private MendelsonCertLoader mendelsonCertLoader;
+    private static HostnameVerifier hostnameVerifier;
+
+    private static final String[] SIGNED_RECEIPT_MIC_ALGORITHMS = new String[] 
{ "sha1", "md5" };
+
+    private static final String EDI_MESSAGE = 
"UNB+UNOA:1+005435656:1+006415160:1+060515:1434+00000000000778'\n"
+                                              + 
"UNH+00000000000117+INVOIC:D:97B:UN'\n"
+                                              + "BGM+380+342459+9'\n"
+                                              + "DTM+3:20060515:102'\n"
+                                              + "RFF+ON:521052'\n"
+                                              + "NAD+BY+792820524::16++CUMMINS 
MID-RANGE ENGINE PLANT'\n"
+                                              + "NAD+SE+005435656::16++GENERAL 
WIDGET COMPANY'\n"
+                                              + "CUX+1:USD'\n"
+                                              + "LIN+1++157870:IN'\n"
+                                              + "IMD+F++:::WIDGET'\n"
+                                              + "QTY+47:1020:EA'\n"
+                                              + "ALI+US'\n"
+                                              + "MOA+203:1202.58'\n"
+                                              + "PRI+INV:1.179'\n"
+                                              + "LIN+2++157871:IN'\n"
+                                              + "IMD+F++:::Message from Camel 
AS2 via HTTPS'\n"
+                                              + "QTY+47:20:EA'\n"
+                                              + "ALI+JP'\n"
+                                              + "MOA+203:410'\n"
+                                              + "PRI+INV:20.5'\n"
+                                              + "UNS+S'\n"
+                                              + "MOA+39:2137.58'\n"
+                                              + "ALC+C+ABG'\n"
+                                              + "MOA+8:525'\n"
+                                              + "UNT+23+00000000000117'\n"
+                                              + "UNZ+1+00000000000778'\n";
+
+    @BeforeAll
+    public void setupTest() {
+        hostnameVerifier = new NoopHostnameVerifier();
+        mendelsonCertLoader = new MendelsonCertLoader();
+        mendelsonCertLoader.setupCertificateChain();
+        mendelsonCertLoader.setupSslContext();
+    }
+
+    @Disabled
+    @Test
+    public void testCreateEndpointAndSendViaHTTPS() throws Exception {
+        CamelContext camelContext = new DefaultCamelContext();
+        camelContext.start();
+
+        org.apache.http.entity.ContentType contentTypeEdifact
+                = 
org.apache.http.entity.ContentType.create("application/edifact", (Charset) 
null);
+
+        String methodName = "send";
+        AS2ApiName as2ApiNameClient = AS2ApiName.CLIENT;
+
+        AS2Configuration endpointConfiguration = new AS2Configuration();
+        endpointConfiguration.setApiName(as2ApiNameClient);
+        endpointConfiguration.setMethodName(methodName);
+        endpointConfiguration.setRequestUri("/as2/HttpReceiver");
+        
endpointConfiguration.setSignedReceiptMicAlgorithms(SIGNED_RECEIPT_MIC_ALGORITHMS);
+
+        
endpointConfiguration.setAs2MessageStructure(AS2MessageStructure.SIGNED_ENCRYPTED);
+        
endpointConfiguration.setSigningAlgorithm(AS2SignatureAlgorithm.SHA3_256WITHRSA);
+        
endpointConfiguration.setEncryptingAlgorithm(AS2EncryptionAlgorithm.DES_EDE3_CBC);
+        
endpointConfiguration.setSigningCertificateChain(mendelsonCertLoader.getChain());
+        
endpointConfiguration.setSigningPrivateKey(mendelsonCertLoader.getPrivateKey());
+        
endpointConfiguration.setEncryptingCertificateChain(mendelsonCertLoader.getChain());
+
+        endpointConfiguration.setAs2Version("1.0");
+        endpointConfiguration.setAs2To("mendelsontestAS2");
+        endpointConfiguration.setAs2From("mycompanyAS2");
+        endpointConfiguration.setEdiMessageType(contentTypeEdifact);
+        endpointConfiguration.setFrom("dk2kEdi");
+        endpointConfiguration.setSubject("mysubject");
+        
endpointConfiguration.setSigningAlgorithm(AS2SignatureAlgorithm.MD2WITHRSA);
+        endpointConfiguration.setEdiMessageTransferEncoding("7bit");
+        endpointConfiguration.setAttachedFileName("from_camel.txt");
+
+        
endpointConfiguration.setSslContext(mendelsonCertLoader.getSslContext());
+        endpointConfiguration.setHostnameVerifier(hostnameVerifier);
+
+        AS2Component as2Component = new AS2Component();
+        as2Component.setCamelContext(camelContext);
+        as2Component.setConfiguration(endpointConfiguration);
+        as2Component.start();
+
+        AS2Endpoint endpoint = (AS2Endpoint) as2Component
+                
.createEndpoint("as2://client/send?targetHostName=testas2.mendelson-e-c.com"
+                                + 
"&targetPortNumber=8444&inBody=ediMessage&requestUri=/as2/HttpReceiver" +
+                                "&ediMessageContentType=application/edifact" +
+                                "&signingAlgorithm=SHA3_256WITHRSA");
+
+        Assertions.assertEquals("mycompanyAS2", endpoint.getAs2From());
+        Assertions.assertEquals("mendelsontestAS2", endpoint.getAs2To());
+        Assertions.assertEquals("dk2kEdi", endpoint.getFrom());
+
+        Exchange out
+                = camelContext.createProducerTemplate().request(endpoint,
+                        exchange -> exchange.getIn().setBody(EDI_MESSAGE));
+        Throwable cause = out.getException();
+        Assertions.assertNull(cause);
+        LOG.debug("Sending done, check your message in 
http://testas2.mendelson-e-c.com:8080/webas2/ Login guest, password guest");
+    }
+}
diff --git 
a/components/camel-as2/camel-as2-component/src/test/resources/jsse/client-keystore.jks
 
b/components/camel-as2/camel-as2-component/src/test/resources/jsse/client-keystore.jks
new file mode 100644
index 00000000000..1ef1875460e
Binary files /dev/null and 
b/components/camel-as2/camel-as2-component/src/test/resources/jsse/client-keystore.jks
 differ
diff --git 
a/components/camel-as2/camel-as2-component/src/test/resources/jsse/client-truststore.jks
 
b/components/camel-as2/camel-as2-component/src/test/resources/jsse/client-truststore.jks
new file mode 100644
index 00000000000..b659d75b91f
Binary files /dev/null and 
b/components/camel-as2/camel-as2-component/src/test/resources/jsse/client-truststore.jks
 differ
diff --git 
a/components/camel-as2/camel-as2-component/src/test/resources/jsse/localhost.p12
 
b/components/camel-as2/camel-as2-component/src/test/resources/jsse/localhost.p12
new file mode 100644
index 00000000000..5f6a30d0690
Binary files /dev/null and 
b/components/camel-as2/camel-as2-component/src/test/resources/jsse/localhost.p12
 differ
diff --git 
a/components/camel-as2/camel-as2-component/src/test/resources/jsse/server-keystore.jks
 
b/components/camel-as2/camel-as2-component/src/test/resources/jsse/server-keystore.jks
new file mode 100644
index 00000000000..a387023b373
Binary files /dev/null and 
b/components/camel-as2/camel-as2-component/src/test/resources/jsse/server-keystore.jks
 differ
diff --git 
a/components/camel-as2/camel-as2-component/src/test/resources/jsse/server-truststore.jks
 
b/components/camel-as2/camel-as2-component/src/test/resources/jsse/server-truststore.jks
new file mode 100644
index 00000000000..c1a53ca6e70
Binary files /dev/null and 
b/components/camel-as2/camel-as2-component/src/test/resources/jsse/server-truststore.jks
 differ
diff --git 
a/components/camel-as2/camel-as2-component/src/test/resources/mendelson/key3.pfx
 
b/components/camel-as2/camel-as2-component/src/test/resources/mendelson/key3.pfx
new file mode 100644
index 00000000000..e515bfae780
Binary files /dev/null and 
b/components/camel-as2/camel-as2-component/src/test/resources/mendelson/key3.pfx
 differ
diff --git 
a/components/camel-as2/camel-as2-component/src/test/resources/mendelson/key4.cer
 
b/components/camel-as2/camel-as2-component/src/test/resources/mendelson/key4.cer
new file mode 100644
index 00000000000..0271090ef07
--- /dev/null
+++ 
b/components/camel-as2/camel-as2-component/src/test/resources/mendelson/key4.cer
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIEJTCCAw2gAwIBAgIEWipbyDANBgkqhkiG9w0BAQsFADCBujEjMCEGCSqGSIb3DQEJARYUc2Vy
+dmljZUBtZW5kZWxzb24uZGUxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcM
+BkJlcmxpbjEiMCAGA1UECgwZbWVuZGVsc29uLWUtY29tbWVyY2UgR21iSDEhMB8GA1UECwwYRG8g
+bm90IHVzZSBpbiBwcm9kdWN0aW9uMR0wGwYDVQQDDBRtZW5kZWxzb24gdGVzdCBrZXkgNDAeFw0x
+NzEyMDgwOTMwNDhaFw0yNzEyMDYwOTMwNDhaMIG6MSMwIQYJKoZIhvcNAQkBFhRzZXJ2aWNlQG1l
+bmRlbHNvbi5kZTELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVybGlu
+MSIwIAYDVQQKDBltZW5kZWxzb24tZS1jb21tZXJjZSBHbWJIMSEwHwYDVQQLDBhEbyBub3QgdXNl
+IGluIHByb2R1Y3Rpb24xHTAbBgNVBAMMFG1lbmRlbHNvbiB0ZXN0IGtleSA0MIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyeDD3FzJD3GdWoMj4pcpX7XLc5ZWJyVmt7ci+hCIyVmc4Kz5
+JIhAqQmes/EYNBf1CHBQL6yLbVPzfmDhadoXcRtVtosyG6+XvTzP8zaUQ5NcEZPkOA8S14VcvPkI
+X4I7NuU5TKkgRQ6G91tnFg3F5Ywm79qBuggxa3VPSofQpq3bJXYkaNI8vMARFyX/bDjNYFzOYCyD
+jG6Jwbwg1M69DLK6IGntku6PXGOf3X2BPMNgiZfV29sGIBKoWyx4q3p0qLXKYTPAtYP9+Uzkz+mq
+2dcH56L6rFuAMbXYGEwarbby0JsVULc3q8+anlfxrfzDJH1KYzrdYmW6bRi/dh8AWQIDAQABozEw
+LzAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3
+DQEBCwUAA4IBAQCh7+6IQjfGwsisA7xMNcPsRQC1av9T1eF2WjgmNjY0htKpK+Q2VgsAm3EgraoK
+EaUL5LaAJpQvH8iLVLdct3Qn483HVHeCiB/DE/eBrbxLVrUZqysZerWONX97BPbIBCKJAEm3Pqyi
+ej7IBY7WKy9OvCErUoH0zXsdfkuJlJXf1jS+qtEbWRGnbxwfXgH0S1uw7QU0q8EECvEb+MNrCEtD
+4Wdjq35OFKLLPcChlEgoXabGefFSAeALnIZ2CJDn8Yz+7ZvdXkBjl17z9GYnR54bBz8CUxYqJBgu
+0iE784sGpulvrJeeyrNS7EgP3odta2vn5ySjQQI8M8ubL+/cs1T7
+-----END CERTIFICATE-----
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/AS2EndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/AS2EndpointBuilderFactory.java
index 0e4765d8b13..c869b5087d2 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/AS2EndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/AS2EndpointBuilderFactory.java
@@ -849,6 +849,38 @@ public interface AS2EndpointBuilderFactory {
             doSetProperty("validateSigningCertificateChain", 
validateSigningCertificateChain);
             return this;
         }
+
+        /**
+         * Add sslContext.
+         *
+         * The option is a: &lt;code&gt;javax.net.ssl.SSLContext&lt;/code&gt;
+         * type.
+         *
+         * Group: common
+         *
+         * @param sslContext the value to set
+         * @return the dsl builder
+         */
+        default AS2EndpointConsumerBuilder sslContext(
+                javax.net.ssl.SSLContext sslContext) {
+            doSetProperty("sslContext", sslContext);
+            return this;
+        }
+        /**
+         * Add sslContext.
+         *
+         * The option will be converted to a
+         * &lt;code&gt;javax.net.ssl.SSLContext&lt;/code&gt; type.
+         *
+         * Group: common
+         *
+         * @param sslContext the value to set
+         * @return the dsl builder
+         */
+        default AS2EndpointConsumerBuilder sslContext(String sslContext) {
+            doSetProperty("sslContext", sslContext);
+            return this;
+        }
     }
 
     /**
@@ -1747,6 +1779,38 @@ public interface AS2EndpointBuilderFactory {
             doSetProperty("validateSigningCertificateChain", 
validateSigningCertificateChain);
             return this;
         }
+
+        /**
+         * Add sslContext.
+         *
+         * The option is a: &lt;code&gt;javax.net.ssl.SSLContext&lt;/code&gt;
+         * type.
+         *
+         * Group: common
+         *
+         * @param sslContext the value to set
+         * @return the dsl builder
+         */
+        default AS2EndpointProducerBuilder sslContext(
+                javax.net.ssl.SSLContext sslContext) {
+            doSetProperty("sslContext", sslContext);
+            return this;
+        }
+        /**
+         * Add sslContext.
+         *
+         * The option will be converted to a
+         * &lt;code&gt;javax.net.ssl.SSLContext&lt;/code&gt; type.
+         *
+         * Group: common
+         *
+         * @param sslContext the value to set
+         * @return the dsl builder
+         */
+        default AS2EndpointProducerBuilder sslContext(String sslContext) {
+            doSetProperty("sslContext", sslContext);
+            return this;
+        }
     }
 
     /**
@@ -2616,6 +2680,38 @@ public interface AS2EndpointBuilderFactory {
             doSetProperty("validateSigningCertificateChain", 
validateSigningCertificateChain);
             return this;
         }
+
+        /**
+         * Add sslContext.
+         *
+         * The option is a: &lt;code&gt;javax.net.ssl.SSLContext&lt;/code&gt;
+         * type.
+         *
+         * Group: common
+         *
+         * @param sslContext the value to set
+         * @return the dsl builder
+         */
+        default AS2EndpointBuilder sslContext(
+                javax.net.ssl.SSLContext sslContext) {
+            doSetProperty("sslContext", sslContext);
+            return this;
+        }
+        /**
+         * Add sslContext.
+         *
+         * The option will be converted to a
+         * &lt;code&gt;javax.net.ssl.SSLContext&lt;/code&gt; type.
+         *
+         * Group: common
+         *
+         * @param sslContext the value to set
+         * @return the dsl builder
+         */
+        default AS2EndpointBuilder sslContext(String sslContext) {
+            doSetProperty("sslContext", sslContext);
+            return this;
+        }
     }
 
     /**


Reply via email to