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

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


The following commit(s) were added to refs/heads/camel-3.x by this push:
     new 8fb433790e0 CAMEL-17946 Backported changes "HTTPS for AS2 component" 
into camel-3.x (#9985)
8fb433790e0 is described below

commit 8fb433790e0d51b722301d8a3bfd504f0a68c89e
Author: Dmitry Kryukov <d...@users.noreply.github.com>
AuthorDate: Wed May 3 15:40:08 2023 +0300

    CAMEL-17946 Backported changes "HTTPS for AS2 component" into camel-3.x 
(#9985)
    
    * CAMEL-17946 Back port of SSL for AS2 component into branch camel-3.x
    
    * Recommitting mendelson keystore, Intellij Idea "optimized" it originally
---
 .../component/as2/api/AS2ClientConnection.java     |  38 +++-
 .../camel/component/as2/api/AS2ClientManager.java  |   6 +-
 .../component/as2/api/AS2ServerConnection.java     |  25 ++-
 .../camel/component/as2/api/util/AS2Utils.java     |   4 +-
 .../camel/component/as2/api/AS2MessageTest.java    |   4 +-
 components/camel-as2/camel-as2-component/pom.xml   |   8 +
 ...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        |   2 +
 .../camel/component/as2/AS2Configuration.java      |  39 ++++-
 .../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   | 195 +++++++++++++++++++++
 .../as2/MendelsonSslEndpointManualTest.java        | 128 ++++++++++++++
 .../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 -> 2757 bytes
 .../src/test/resources/mendelson/key4.cer          |  21 +++
 .../src/test/resources/test-server.properties      |  46 +++++
 28 files changed, 637 insertions(+), 31 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 9f1e8a86c8e..cb27370a092 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;
@@ -35,11 +39,16 @@ import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.config.ConnectionConfig;
+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;
@@ -68,14 +77,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");
@@ -99,7 +110,21 @@ public class AS2ClientConnection {
             }
         };
 
-        connectionPoolManager = new 
PoolingHttpClientConnectionManager(connFactory);
+        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)
@@ -126,7 +151,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..b4c34a670ab 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");
 
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/main/java/org/apache/camel/component/as2/api/util/AS2Utils.java
 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/AS2Utils.java
index 86dbd800b09..87fc0a34dfc 100644
--- 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/AS2Utils.java
+++ 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/AS2Utils.java
@@ -82,7 +82,7 @@ public final class AS2Utils {
 
     /**
      * Generates a globally unique message ID which includes 
<code>fqdn</code>: a fully qualified domain name (FQDN)
-     * 
+     *
      * @param  fqdn - the fully qualified domain name to use in message id.
      * @return      The generated message id.
      */
@@ -93,7 +93,7 @@ public final class AS2Utils {
 
     /**
      * Determines if <code>c</code> is a printable character.
-     * 
+     *
      * @param  c - the character to test
      * @return   <code>true</code> if <code>c</code> is a printable character; 
<code>false</code> otherwise.
      */
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 303b437b2f3..76c8aae6a32 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
@@ -216,7 +216,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)
@@ -1071,7 +1071,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 d566467bd89..24a6b66d7fe 100644
--- a/components/camel-as2/camel-as2-component/pom.xml
+++ b/components/camel-as2/camel-as2-component/pom.xml
@@ -39,6 +39,8 @@
         <outPackage>org.apache.camel.component.as2.internal</outPackage>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+
+        <commons-io-version>2.11.0</commons-io-version>
     </properties>
 
     <dependencies>
@@ -64,6 +66,12 @@
             <artifactId>camel-jetty</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>${commons-io-version}</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 4a5ab6f292e..0aebd04f565 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." },
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 47b6e4e8e72..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;
@@ -374,7 +382,7 @@ public class AS2Configuration {
 
     /**
      * The value of the Disposition-Notification-To header.
-     * 
+     *
      * Assigning a value to this parameter requests a message disposition 
notification (MDN) for the AS2 message.
      */
     public void setDispositionNotificationTo(String dispositionNotificationTo) 
{
@@ -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 cfb4feae095..09138825ce0 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..c88b6997e9e
--- /dev/null
+++ 
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/MendelsonCertLoader.java
@@ -0,0 +1,195 @@
+/*
+ * 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.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;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * That's a utility class for preparing Mendelson-specific certificate chain, 
private key, ssl context. It has no
+ * mention of paths to Mendelson certificate, keystore and keystore password, 
but we can't ensure that it works with any
+ * provided certificate and keystore without modifications. At least due to 
certificate chain for Mendelson consists of
+ * the only certificate.
+ */
+public class MendelsonCertLoader {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(MendelsonCertLoader.class);
+
+    private final List<Certificate> chainAsList = new ArrayList<>();
+
+    private PrivateKey privateKey;
+    private SSLContext sslContext;
+
+    public void setupSslContext(String keyStorePath, String keyStorePassword) {
+        try {
+            InputStream keyStoreAsStream = 
getClass().getClassLoader().getResourceAsStream(keyStorePath);
+            KeyStore keyStore = getKeyStore(keyStoreAsStream, 
keyStorePassword);
+            sslContext = SSLContexts.custom().setKeyStoreType("PKCS12")
+                    .loadTrustMaterial(keyStore, new TrustAllStrategy())
+                    .build();
+        } catch (KeyStoreException | IOException | KeyManagementException | 
NoSuchAlgorithmException e) {
+            LOG.error("Failed to configure SSLContext", e);
+        }
+
+        if (sslContext == null) {
+            LOG.error("failed to configure SSL context");
+        }
+    }
+
+    private KeyStore getKeyStore(InputStream inputStream, String 
keyStorePassword)
+            throws IOException, NoSuchAlgorithmException {
+        KeyStore ks;
+        try {
+            ks = KeyStore.getInstance("PKCS12");
+            ks.load(inputStream, keyStorePassword.toCharArray());
+            return ks;
+        } catch (KeyStoreException e) {
+            LOG.error("Failed to create instance of KeyStore", e);
+        } catch (CertificateException e) {
+            LOG.error("Failed to load KeyStore");
+        }
+        throw new IllegalStateException("about to return null");
+    }
+
+    public void setupCertificateChain(String certificatePath, String 
keyStorePath, String keyStorePassword) {
+
+        InputStream certificateAsStream = 
getClass().getClassLoader().getResourceAsStream(certificatePath);
+        if (certificateAsStream == null) {
+            //LOG.error("Couldn't read out client certificate as stream.");
+            throw new IllegalStateException("Couldn't read out certificate as 
stream.");
+        }
+
+        InputStream keyStoreAsStream = 
getClass().getClassLoader().getResourceAsStream(keyStorePath);
+        if (keyStoreAsStream == null) {
+            //LOG.error("Couldn't read out private key as stream.");
+            throw new IllegalStateException("Couldn't read out key storage as 
stream.");
+        }
+
+        try {
+            Certificate certificate = 
getCertificateFromStream(certificateAsStream);
+            chainAsList.add(certificate);
+
+            //private key
+            privateKey = getPrivateKeyFromPKCSStream(keyStoreAsStream, 
keyStorePassword);
+
+        } catch (IOException e) {
+            String errMsg
+                    = "Error while trying to load certificate to the key 
store. IO error when reading a byte array.  " + e;
+            LOG.error(errMsg);
+        } catch (NoSuchAlgorithmException e) {
+            String errMsg = "Error while trying to load certificate to the key 
store. Requested algorithm isn't found.  " + e;
+            LOG.error(errMsg);
+        } catch (CertificateException e) {
+            String errMsg = "Error while trying to load certificate to the key 
store. There is a certificate problem.  " + e;
+            LOG.error(errMsg);
+        } catch (InvalidKeySpecException e) {
+            String errMsg = "Can not init private key store  " + e;
+            LOG.error(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 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, 
String keyStorePassword)
+            throws IOException, NoSuchAlgorithmException, 
InvalidKeySpecException {
+        KeyStore ks = null;
+        try {
+            ks = KeyStore.getInstance("PKCS12");
+        } catch (KeyStoreException e) {
+            LOG.error("Error while getting instance of KeyStore" + e);
+        }
+        try {
+            ks.load(inputStream, keyStorePassword.toCharArray());
+        } catch (CertificateException e) {
+            LOG.error("Error while loading the certificate" + e);
+        }
+        try {
+            return (PrivateKey) ks.getKey(
+                    ks.aliases().nextElement(),
+                    keyStorePassword.toCharArray());
+        } catch (KeyStoreException e) {
+            LOG.error("Error while retrieving private key" + e);
+        } catch (UnrecoverableKeyException e) {
+            LOG.error("Error while retrieving private key" + e);
+        }
+        throw new IllegalStateException("Failed to construct a PrivateKey from 
provided InputStream");
+    }
+
+    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/MendelsonSslEndpointManualTest.java
 
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/MendelsonSslEndpointManualTest.java
new file mode 100644
index 00000000000..5382b74c9cb
--- /dev/null
+++ 
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/MendelsonSslEndpointManualTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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.component.as2;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+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. This 
class gives more info for camel-as2
+ * connectivity to a remote server compared to HTTPS connection to localhost 
server. Eventually test class will be
+ * committed with @Disabled annotation due to the test can bring dependency on 
3rd party resource.
+ */
+@Disabled("Run this test manually")
+public class MendelsonSslEndpointManualTest extends AbstractAS2ITSupport {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(MendelsonSslEndpointManualTest.class);
+    private static HostnameVerifier hostnameVerifier;
+
+    private MendelsonCertLoader mendelsonCertLoader;
+    private final Properties props = new Properties();
+
+    @BeforeAll
+    public void setupTest() {
+        InputStream is = MendelsonSslEndpointManualTest.class
+                
.getClassLoader().getResourceAsStream("test-server.properties");
+        try {
+            props.load(is);
+        } catch (IOException e) {
+            LOG.error("Failed to load properties from file 
test_server.properties");
+        }
+
+        // NoopHostnameVerifier needed since we connect to non-localhost 
remote AS2 server
+        hostnameVerifier = new NoopHostnameVerifier();
+        mendelsonCertLoader = new MendelsonCertLoader();
+        
mendelsonCertLoader.setupCertificateChain(props.getProperty("mendelson.certificate.path"),
+                props.getProperty("mendelson.keystore.path"),
+                props.getProperty("mendelson.keystore.password"));
+        
mendelsonCertLoader.setupSslContext(props.getProperty("mendelson.keystore.path"),
+                props.getProperty("mendelson.keystore.password"));
+    }
+
+    @Test
+    public void testCreateEndpointAndSendViaHTTPS() throws Exception {
+        CamelContext camelContext = new DefaultCamelContext();
+        camelContext.start();
+
+        String methodName = "send";
+        AS2ApiName as2ApiNameClient = AS2ApiName.CLIENT;
+
+        AS2Configuration endpointConfiguration = new AS2Configuration();
+        endpointConfiguration.setApiName(as2ApiNameClient);
+        endpointConfiguration.setMethodName(methodName);
+
+        
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(props.getProperty("as2.version"));
+        endpointConfiguration.setAs2To(props.getProperty("as2.as2to"));
+        endpointConfiguration.setAs2From(props.getProperty("as2.as2from"));
+        endpointConfiguration.setFrom(props.getProperty("as2.from"));
+        endpointConfiguration.setSubject(props.getProperty("as2.subject"));
+        
endpointConfiguration.setSigningAlgorithm(AS2SignatureAlgorithm.MD2WITHRSA);
+        
endpointConfiguration.setEdiMessageTransferEncoding(props.getProperty("as2.transfer.encoding"));
+        
endpointConfiguration.setAttachedFileName(props.getProperty("as2.attached.filename"));
+
+        
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=" + 
props.getProperty("as2.remote.host") +
+                                "&targetPortNumber=" + 
props.getProperty("as2.remote.port") +
+                                "&inBody=ediMessage" +
+                                "&requestUri=" + 
props.getProperty("as2.remote.uri") +
+                                "&ediMessageContentType=" + 
props.getProperty("as2.content.type") +
+                                "&signingAlgorithm=" + 
props.getProperty("as2.signing.algorithm"));
+
+        Exchange out
+                = camelContext.createProducerTemplate().request(endpoint,
+                        exchange -> 
exchange.getIn().setBody(props.getProperty("as2.edi.message")));
+        Throwable cause = out.getException();
+        Assertions.assertNull(cause);
+        LOG.debug(
+                "Sending done. If you used Mendelson settings for connection, 
" +
+                  "you can 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..71f91a97879
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/components/camel-as2/camel-as2-component/src/test/resources/test-server.properties
 
b/components/camel-as2/camel-as2-component/src/test/resources/test-server.properties
new file mode 100644
index 00000000000..aba769608da
--- /dev/null
+++ 
b/components/camel-as2/camel-as2-component/src/test/resources/test-server.properties
@@ -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.
+## ---------------------------------------------------------------------------
+
+## ---------------------------------------------------------------------------
+# This file contains connection settings for HTTPS version of Mendelson public 
resource - please see port 8444.
+# You can check your message in http://testas2.mendelson-e-c.com:8080/webas2/ 
Login guest, password guest
+# Mendelson page: http://mendelson-e-c.com/as2_testserver
+# Apache Software Foundation can't be made liable if Mendelson resource goes 
offline or changes the certificate
+# or the credentials or the terms of using.
+## ---------------------------------------------------------------------------
+
+#TODO If you want to test HTTPS connection to Mendelson public resource, 
please place 'testas2.mendelson-e-c.com'
+#TODO instead of 'TBD' in the line below
+as2.remote.host=TBD
+as2.remote.port=8444
+as2.remote.uri=/as2/HttpReceiver
+
+mendelson.certificate.path=mendelson/key4.cer
+mendelson.keystore.path=mendelson/key3.pfx
+mendelson.keystore.password=test
+
+as2.content.type=application/edifact
+as2.subject=mysubject
+as2.version=1.0
+as2.as2to=mendelsontestAS2
+as2.as2from=mycompanyAS2
+as2.from=dk2kEdi
+as2.transfer.encoding=7bit
+as2.attached.filename=from_camel.txt
+as2.signing.algorithm=SHA3_256WITHRSA
+as2.edi.message=Message from Camel AS2 3.x via HTTPS
+

Reply via email to