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 <[email protected]>
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
+