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 +