You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2018/12/17 08:45:15 UTC

[camel] 04/05: [CAMEL-12605] Refactored AS2 Server connection to accept decryption key.

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

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

commit 9ca79898a006f9f8b24f1ba5bf7d7c5f7a10b5b7
Author: William Collins <pu...@gmail.com>
AuthorDate: Fri Dec 14 15:55:06 2018 -0500

    [CAMEL-12605] Refactored AS2 Server connection to accept decryption key.
---
 .../component/as2/api/AS2ServerConnection.java     |  18 ++--
 .../AS2MessageDispositionNotificationEntity.java   |   6 +-
 ...spositionNotificationMultipartReportEntity.java |   6 +-
 .../component/as2/api/entity/EntityParser.java     |   9 +-
 .../component/as2/api/protocol/ResponseMDN.java    |   6 +-
 .../camel/component/as2/api/util/MicUtils.java     |  10 +-
 .../camel/component/as2/api/AS2MessageTest.java    |  54 +++--------
 .../camel/component/as2/api/util/MicUtilsTest.java |   2 +-
 components/camel-as2/camel-as2-component/pom.xml   |  12 +--
 .../src/main/docs/as2-component.adoc               |   2 +-
 .../camel/component/as2/AS2Configuration.java      |  10 +-
 .../as2/internal/AS2ConnectionHelper.java          |   2 +-
 .../as2/AS2ClientManagerIntegrationTest.java       |  15 +--
 .../as2/AS2ServerManagerIntegrationTest.java       | 104 +++++++++++++++++++--
 .../as2/springboot/AS2ComponentConfiguration.java  |  10 +-
 15 files changed, 168 insertions(+), 98 deletions(-)

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 12c1132..09b1061 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
@@ -66,14 +66,15 @@ public class AS2ServerConnection {
                                      int port,
                                      AS2SignatureAlgorithm signatureAlgorithm,
                                      Certificate[] signingCertificateChain,
-                                     PrivateKey signingPrivateKey)
+                                     PrivateKey signingPrivateKey,
+                                     PrivateKey decryptingPrivateKey)
                 throws IOException {
             setName(REQUEST_LISTENER_THREAD_NAME_PREFIX + port);
             serversocket = new ServerSocket(port);
 
             // Set up HTTP protocol processor for incoming connections
             final HttpProcessor inhttpproc = initProtocolProcessor(as2Version, originServer, serverFqdn, port,
-                    signatureAlgorithm, signingCertificateChain, signingPrivateKey);
+                    signatureAlgorithm, signingCertificateChain, signingPrivateKey, decryptingPrivateKey);
 
             reqistry = new UriHttpRequestHandlerMapper();
 
@@ -163,6 +164,7 @@ public class AS2ServerConnection {
             } catch (final IOException ex) {
                 LOG.error("I/O error: {}", ex.getMessage());
             } catch (final HttpException ex) {
+                ex.printStackTrace();
                 LOG.error("Unrecoverable HTTP protocol violation: {}", ex.getMessage());
             } finally {
                 try {
@@ -182,6 +184,7 @@ public class AS2ServerConnection {
     private AS2SignatureAlgorithm signingAlgorithm;
     private Certificate[] signingCertificateChain;
     private PrivateKey signingPrivateKey;
+    private PrivateKey decryptingPrivateKey;
 
     public AS2ServerConnection(String as2Version,
                                String originServer,
@@ -189,7 +192,8 @@ public class AS2ServerConnection {
                                Integer serverPortNumber,
                                AS2SignatureAlgorithm signingAlgorithm,
                                Certificate[] signingCertificateChain,
-                               PrivateKey signingPrivateKey)
+                               PrivateKey signingPrivateKey,
+                               PrivateKey decryptingPrivateKey)
             throws IOException {
         this.as2Version = Args.notNull(as2Version, "as2Version");
         this.originServer = Args.notNull(originServer, "userAgent");
@@ -198,9 +202,10 @@ public class AS2ServerConnection {
         this.signingAlgorithm = signingAlgorithm;
         this.signingCertificateChain = signingCertificateChain;
         this.signingPrivateKey = signingPrivateKey;
+        this.decryptingPrivateKey = decryptingPrivateKey;
 
         listenerThread = new RequestListenerThread(this.as2Version, this.originServer, this.serverFqdn,
-                this.serverPortNumber, this.signingAlgorithm, this.signingCertificateChain, this.signingPrivateKey);
+                this.serverPortNumber, this.signingAlgorithm, this.signingCertificateChain, this.signingPrivateKey, this.decryptingPrivateKey);
         listenerThread.setDaemon(true);
         listenerThread.start();
     }
@@ -240,10 +245,11 @@ public class AS2ServerConnection {
                                                   int port,
                                                   AS2SignatureAlgorithm signatureAlgorithm,
                                                   Certificate[] signingCertificateChain,
-                                                  PrivateKey signingPrivateKey) {
+                                                  PrivateKey signingPrivateKey,
+                                                  PrivateKey decryptingPrivateKey) {
         return HttpProcessorBuilder.create().add(new ResponseContent(true)).add(new ResponseServer(originServer))
                 .add(new ResponseDate()).add(new ResponseConnControl()).add(new ResponseMDN(as2Version, serverFqdn,
-                        signatureAlgorithm, signingCertificateChain, signingPrivateKey))
+                        signatureAlgorithm, signingCertificateChain, signingPrivateKey, decryptingPrivateKey))
                 .build();
     }
 
diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/AS2MessageDispositionNotificationEntity.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/AS2MessageDispositionNotificationEntity.java
index 71e323c..f6eb364 100644
--- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/AS2MessageDispositionNotificationEntity.java
+++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/AS2MessageDispositionNotificationEntity.java
@@ -18,6 +18,7 @@ package org.apache.camel.component.as2.api.entity;
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.security.PrivateKey;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -76,7 +77,8 @@ public class AS2MessageDispositionNotificationEntity extends MimeEntity {
                                                    String[] warningFields,
                                                    Map<String, String> extensionFields,
                                                    String charset,
-                                                   boolean isMainBody) throws HttpException {
+                                                   boolean isMainBody,
+                                                   PrivateKey decryptingPrivateKey) throws HttpException {
         setMainBody(isMainBody);
         setContentType(ContentType.create(AS2MimeType.MESSAGE_DISPOSITION_NOTIFICATION, charset));
 
@@ -87,7 +89,7 @@ public class AS2MessageDispositionNotificationEntity extends MimeEntity {
 
         this.originalMessageId  = HttpMessageUtils.getHeaderValue(request, AS2Header.MESSAGE_ID);
 
-        this.receivedContentMic = MicUtils.createReceivedContentMic(request);
+        this.receivedContentMic = MicUtils.createReceivedContentMic(request, decryptingPrivateKey);
 
         this.reportingUA = HttpMessageUtils.getHeaderValue(response, AS2Header.SERVER);
 
diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/DispositionNotificationMultipartReportEntity.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/DispositionNotificationMultipartReportEntity.java
index 4706ae6..fd68a3e 100644
--- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/DispositionNotificationMultipartReportEntity.java
+++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/DispositionNotificationMultipartReportEntity.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.component.as2.api.entity;
 
+import java.security.PrivateKey;
 import java.util.Map;
 
 import org.apache.camel.component.as2.api.AS2Charset;
@@ -49,7 +50,8 @@ public class DispositionNotificationMultipartReportEntity extends MultipartRepor
                                                         Map<String, String> extensionFields,
                                                         String charset,
                                                         String boundary,
-                                                        boolean isMainBody)
+                                                        boolean isMainBody,
+                                                        PrivateKey decryptingPrivateKey)
             throws HttpException {
         super(charset, isMainBody, boundary);
         removeHeaders(AS2Header.CONTENT_TYPE);
@@ -58,7 +60,7 @@ public class DispositionNotificationMultipartReportEntity extends MultipartRepor
         addPart(buildPlainTextReport(request, response, dispositionMode, dispositionType, dispositionModifier,
                 failureFields, errorFields, warningFields, extensionFields));
         addPart(new AS2MessageDispositionNotificationEntity(request, response, dispositionMode, dispositionType,
-                dispositionModifier, failureFields, errorFields, warningFields, extensionFields, charset, false));
+                dispositionModifier, failureFields, errorFields, warningFields, extensionFields, charset, false, decryptingPrivateKey));
     }
 
     public String getMainMessageContentType() {
diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/EntityParser.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/EntityParser.java
index eb45639..9652f5e9 100644
--- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/EntityParser.java
+++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/EntityParser.java
@@ -422,6 +422,11 @@ public final class EntityParser {
     public static void parseAS2MessageEntity(HttpMessage message) throws HttpException {
         if (EntityUtils.hasEntity(message)) {
             HttpEntity entity = Args.notNull(EntityUtils.getMessageEntity(message), "message entity");
+            
+            if (entity instanceof MimeEntity) {
+                // already parsed
+                return;
+            }
 
             try {
                 // Determine Content Type of Message
@@ -1138,8 +1143,8 @@ public final class EntityParser {
             break;
         }
         case AS2MimeType.APPLICATION_PKCS7_MIME: {
-            if (contentType.getParameter("mime-type").equals("compressed-data")) {
-                throw new HttpException("Failed to extract EDI payload: invalid mime type '" + contentType.getParameter("mime-type") + "' for AS2 enveloped entity");
+            if (!"compressed-data".equals(contentType.getParameter("smime-type"))) {
+                throw new HttpException("Failed to extract EDI payload: invalid mime type '" + contentType.getParameter("smime-type") + "' for AS2 enveloped entity");
             }
             ApplicationPkcs7MimeCompressedDataEntity compressedDataEntity = (ApplicationPkcs7MimeCompressedDataEntity) entity;
             ediEntity = extractEdiPayloadFromCompressedEntity(compressedDataEntity);
diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/protocol/ResponseMDN.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/protocol/ResponseMDN.java
index 14a4109..eacb22c 100644
--- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/protocol/ResponseMDN.java
+++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/protocol/ResponseMDN.java
@@ -59,13 +59,15 @@ public class ResponseMDN implements HttpResponseInterceptor {
     private AS2SignatureAlgorithm signingAlgorithm;
     private Certificate[] signingCertificateChain;
     private PrivateKey signingPrivateKey;
+    private PrivateKey decryptingPrivateKey;
 
-    public ResponseMDN(String as2Version, String serverFQDN, AS2SignatureAlgorithm signingAlgorithm, Certificate[] signingCertificateChain, PrivateKey signingPrivateKey) {
+    public ResponseMDN(String as2Version, String serverFQDN, AS2SignatureAlgorithm signingAlgorithm, Certificate[] signingCertificateChain, PrivateKey signingPrivateKey, PrivateKey decryptingPrivateKey) {
         this.as2Version = as2Version;
         this.serverFQDN = serverFQDN;
         this.signingAlgorithm = signingAlgorithm;
         this.signingCertificateChain = signingCertificateChain;
         this.signingPrivateKey = signingPrivateKey;
+        this.decryptingPrivateKey = decryptingPrivateKey;
     }
 
     @Override
@@ -100,7 +102,7 @@ public class ResponseMDN implements HttpResponseInterceptor {
         String boundary = EntityUtils.createBoundaryValue();
         DispositionNotificationMultipartReportEntity multipartReportEntity = new DispositionNotificationMultipartReportEntity(
                 request, response, DispositionMode.AUTOMATIC_ACTION_MDN_SENT_AUTOMATICALLY,
-                AS2DispositionType.PROCESSED, null, null, null, null, null, AS2Charset.US_ASCII, boundary, true);
+                AS2DispositionType.PROCESSED, null, null, null, null, null, AS2Charset.US_ASCII, boundary, true, decryptingPrivateKey);
 
         DispositionNotificationOptions dispositionNotificationOptions = DispositionNotificationOptionsParser
                 .parseDispositionNotificationOptions(
diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/MicUtils.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/MicUtils.java
index 8eb66b1..c3da303 100644
--- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/MicUtils.java
+++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/MicUtils.java
@@ -19,21 +19,17 @@ package org.apache.camel.component.as2.api.util;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
 
 import org.apache.camel.component.as2.api.AS2Charset;
 import org.apache.camel.component.as2.api.AS2Header;
 import org.apache.camel.component.as2.api.AS2MicAlgorithm;
-import org.apache.camel.component.as2.api.AS2MimeType;
-import org.apache.camel.component.as2.api.entity.ApplicationEDIEntity;
-import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeCompressedDataEntity;
 import org.apache.camel.component.as2.api.entity.DispositionNotificationOptions;
 import org.apache.camel.component.as2.api.entity.DispositionNotificationOptionsParser;
 import org.apache.camel.component.as2.api.entity.EntityParser;
-import org.apache.camel.component.as2.api.entity.MultipartSignedEntity;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpException;
-import org.apache.http.entity.ContentType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -83,7 +79,7 @@ public final class MicUtils {
         }
     }
 
-    public static ReceivedContentMic createReceivedContentMic(HttpEntityEnclosingRequest request) throws HttpException {
+    public static ReceivedContentMic createReceivedContentMic(HttpEntityEnclosingRequest request, PrivateKey decryptingPrivateKey) throws HttpException {
 
         String dispositionNotificationOptionsString =  HttpMessageUtils.getHeaderValue(request, AS2Header.DISPOSITION_NOTIFICATION_OPTIONS);
         if (dispositionNotificationOptionsString == null) {
@@ -97,7 +93,7 @@ public final class MicUtils {
             return null;
         }
 
-        HttpEntity entity = EntityParser.extractEdiPayload(request, null);
+        HttpEntity entity = EntityParser.extractEdiPayload(request, decryptingPrivateKey);
 
         byte[] content = EntityUtils.getContent(entity);
 
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 b9d336a..b8369f5 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
@@ -140,14 +140,17 @@ public class AS2MessageTest {
 
     private AS2SignedDataGenerator gen;
 
-    private KeyPair issueKP;
-    private X509Certificate issueCert;
+    private static KeyPair issueKP;
+    private static X509Certificate issueCert;
 
-    private KeyPair signingKP;
-    private X509Certificate signingCert;
-    private List<X509Certificate> certList;
+    private static KeyPair signingKP;
+    private static X509Certificate signingCert;
+    private static List<X509Certificate> certList;
+    
+    @BeforeClass
+    public static void setUpOnce() throws Exception {
+        Security.addProvider(new BouncyCastleProvider());
 
-    private void setupKeysAndCertificates() throws Exception {
         //
         // set up our certificates
         //
@@ -170,38 +173,11 @@ public class AS2MessageTest {
 
         certList.add(signingCert);
         certList.add(issueCert);
-
-    }
-
-    @BeforeClass
-    public static void setUpOnce() throws Exception {
-        Security.addProvider(new BouncyCastleProvider());
-
-        //
-        // set up our certificates
-        //
-        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
-
-        kpg.initialize(1024, new SecureRandom());
-
-        String issueDN = "O=Punkhorn Software, C=US";
-        KeyPair issueKP = kpg.generateKeyPair();
-        X509Certificate issueCert = Utils.makeCertificate(issueKP, issueDN, issueKP, issueDN);
-
-        //
-        // certificate we sign against
-        //
-        String signingDN = "CN=William J. Collins, E=punkhornsw@gmail.com, O=Punkhorn Software, C=US";
-        KeyPair signingKP = kpg.generateKeyPair();
-        X509Certificate signingCert = Utils.makeCertificate(signingKP, signingDN, issueKP, issueDN);
-
-        List<X509Certificate> certList = new ArrayList<>();
-
-        certList.add(signingCert);
-        certList.add(issueCert);
+        
+        KeyPair decryptingKP = signingKP;
 
         testServer = new AS2ServerConnection(AS2_VERSION, "MyServer-HTTP/1.1", SERVER_FQDN, TARGET_PORT, AS2SignatureAlgorithm.SHA256WITHRSA,
-                certList.toArray(new Certificate[0]), signingKP.getPrivate());
+                certList.toArray(new Certificate[0]), signingKP.getPrivate(), decryptingKP.getPrivate());
         testServer.listen("*", new HttpRequestHandler() {
             @Override
             public void handle(HttpRequest request, HttpResponse response, HttpContext context)
@@ -227,8 +203,6 @@ public class AS2MessageTest {
     public void setUp() throws Exception {
         Security.addProvider(new BouncyCastleProvider());
 
-        setupKeysAndCertificates();
-
         // Create and populate certificate store.
         JcaCertStore certs = new JcaCertStore(certList);
 
@@ -703,7 +677,7 @@ public class AS2MessageTest {
         DispositionNotificationMultipartReportEntity mdn = new DispositionNotificationMultipartReportEntity(request,
                 response, DispositionMode.AUTOMATIC_ACTION_MDN_SENT_AUTOMATICALLY, AS2DispositionType.PROCESSED,
                 dispositionModifier, failureFields, errorFields, warningFields, extensionFields, null, "boundary",
-                true);
+                true, null);
 
         // Send MDN
         HttpCoreContext httpContext = mdnManager.send(mdn, RECIPIENT_DELIVERY_ADDRESS);
@@ -730,7 +704,7 @@ public class AS2MessageTest {
         assertArrayEquals("Unexpected value for Error Fields", errorFields, mdnEntity.getErrorFields());
         assertArrayEquals("Unexpected value for Warning Fields", warningFields, mdnEntity.getWarningFields());
         assertEquals("Unexpected value for Extension Fields", extensionFields, mdnEntity.getExtensionFields());
-        ReceivedContentMic expectedMic = MicUtils.createReceivedContentMic(request);
+        ReceivedContentMic expectedMic = MicUtils.createReceivedContentMic(request, null);
         ReceivedContentMic mdnMic = mdnEntity.getReceivedContentMic();
         assertEquals("Unexpected value for Recieved Content Mic", expectedMic.getEncodedMessageDigest(),
                 mdnMic.getEncodedMessageDigest());
diff --git a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/util/MicUtilsTest.java b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/util/MicUtilsTest.java
index 5cbaba7..e14c511 100644
--- a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/util/MicUtilsTest.java
+++ b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/util/MicUtilsTest.java
@@ -99,7 +99,7 @@ public class MicUtilsTest {
         basicEntity.setContentType(CONTENT_TYPE_VALUE);
         request.setEntity(basicEntity);
 
-        ReceivedContentMic receivedContentMic = MicUtils.createReceivedContentMic(request);
+        ReceivedContentMic receivedContentMic = MicUtils.createReceivedContentMic(request, null);
         assertNotNull("Failed to create Received Content MIC");
         LOG.debug("Digest Algorithm: " + receivedContentMic.getDigestAlgorithmId());
         assertEquals("Unexpected digest algorithm value", EXPECTED_MESSAGE_DIGEST_ALGORITHM, receivedContentMic.getDigestAlgorithmId());
diff --git a/components/camel-as2/camel-as2-component/pom.xml b/components/camel-as2/camel-as2-component/pom.xml
index 86c2c5e..37af503 100644
--- a/components/camel-as2/camel-as2-component/pom.xml
+++ b/components/camel-as2/camel-as2-component/pom.xml
@@ -155,11 +155,7 @@
                     <apiName>client</apiName>
                     <proxyClass>org.apache.camel.component.as2.api.AS2ClientManager</proxyClass>
                     <fromJavadoc>
-                      <excludeMethods>createSigningGenerator</excludeMethods>
-                      <excludeMethods>createEncryptingGenerator</excludeMethods>
-                      <excludeMethods>createCompressorGenerator</excludeMethods>
-                      <excludeMethods>createEncryptor</excludeMethods>
-                      <excludeMethods>createCompressor</excludeMethods>
+                      <excludeMethods>createSigningGenerator|createEncryptingGenerator|createCompressorGenerator|createEncryptor|createCompressor</excludeMethods>
                     </fromJavadoc>
                     <nullableOptions>
                         <nullableOption>ediMessageTransferEncoding</nullableOption>
@@ -171,7 +167,6 @@
                         <nullableOption>signedReceiptMicAlgorithms</nullableOption>
                         <nullableOption>encryptingAlgorithm</nullableOption>
                         <nullableOption>encryptingCertificateChain</nullableOption>
-                        <nullableOption>encryptingPrivateKey</nullableOption>
                     </nullableOptions>
                 </api>
                 <api>
@@ -181,7 +176,10 @@
                       <excludeMethods>stopListening|handleMDNResponse</excludeMethods>
 	                </fromJavadoc>
                     <excludeConfigNames>handler</excludeConfigNames>
-                </api>
+<!--                     <nullableOptions>
+                        <nullableOption>decryptingPrivateKey</nullableOption>
+                    </nullableOptions>
+ -->                </api>
               </apis>
               <!-- Specify global values for all APIs here, these are overridden at API level
               <substitutions/>
diff --git a/components/camel-as2/camel-as2-component/src/main/docs/as2-component.adoc b/components/camel-as2/camel-as2-component/src/main/docs/as2-component.adoc
index 0c1180c..7ff1595 100644
--- a/components/camel-as2/camel-as2-component/src/main/docs/as2-component.adoc
+++ b/components/camel-as2/camel-as2-component/src/main/docs/as2-component.adoc
@@ -82,12 +82,12 @@ with the following path and query parameters:
 | *as2Version* (common) | The version of the AS2 protocol. | 1.1 | String
 | *clientFqdn* (common) | The Client Fully Qualified Domain Name (FQDN). Used in message ids sent by endpoint. | camel.apache.org | String
 | *compressionAlgorithm* (common) | The algorithm used to compress EDI message. |  | AS2Compression Algorithm
+| *decryptingPrivateKey* (common) | The key used to encrypt the EDI message. |  | PrivateKey
 | *dispositionNotificationTo* (common) | The value of the Disposition-Notification-To header. Assigning a value to this parameter requests a message disposition notification (MDN) for the AS2 message. |  | String
 | *ediMessageTransferEncoding* (common) | The transfer encoding of EDI message. |  | String
 | *ediMessageType* (common) | The content type of EDI message. One of application/edifact, application/edi-x12, application/edi-consent |  | ContentType
 | *encryptingAlgorithm* (common) | The algorithm used to encrypt EDI message. |  | AS2EncryptionAlgorithm
 | *encryptingCertificateChain* (common) | The chain of certificates used to encrypt EDI message. |  | Certificate[]
-| *encryptingPrivateKey* (common) | The key used to encrypt the EDI message. |  | PrivateKey
 | *from* (common) | The value of the From header of AS2 message. |  | String
 | *inBody* (common) | Sets the name of a parameter to be passed in the exchange In Body |  | String
 | *methodName* (common) | *Required* What sub operation to use for the selected operation |  | String
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 c92b50e..57ac5ba 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
@@ -118,7 +118,7 @@ public class AS2Configuration {
     private Certificate[] encryptingCertificateChain;
 
     @UriParam
-    private PrivateKey encryptingPrivateKey;
+    private PrivateKey decryptingPrivateKey;
 
     public AS2ApiName getApiName() {
         return apiName;
@@ -452,14 +452,14 @@ public class AS2Configuration {
         this.encryptingCertificateChain = signingCertificateChain;
     }
 
-    public PrivateKey getEncryptingPrivateKey() {
-        return encryptingPrivateKey;
+    public PrivateKey getDecryptingPrivateKey() {
+        return decryptingPrivateKey;
     }
 
     /**
      * The key used to encrypt the EDI message.
      */
-    public void setEncryptingPrivateKey(PrivateKey signingPrivateKey) {
-        this.encryptingPrivateKey = signingPrivateKey;
+    public void setDecryptingPrivateKey(PrivateKey signingPrivateKey) {
+        this.decryptingPrivateKey = signingPrivateKey;
     }
 }
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 bc1fff5..908eef7 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
@@ -64,7 +64,7 @@ public final class AS2ConnectionHelper {
             if (serverConnection == null) {
                 serverConnection = new AS2ServerConnection(configuration.getAs2Version(), configuration.getServer(),
                         configuration.getServerFqdn(), configuration.getServerPortNumber(), configuration.getSigningAlgorithm(),
-                        configuration.getSigningCertificateChain(), configuration.getSigningPrivateKey());
+                        configuration.getSigningCertificateChain(), configuration.getSigningPrivateKey(), configuration.getDecryptingPrivateKey());
                 serverConnections.put(configuration.getServerPortNumber(), serverConnection);
             }
             return serverConnection;
diff --git a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIntegrationTest.java b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIntegrationTest.java
index 9f83ea2..a52747f 100644
--- a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIntegrationTest.java
+++ b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIntegrationTest.java
@@ -161,6 +161,7 @@ public class AS2ClientManagerIntegrationTest extends AbstractAS2TestSupport {
     private X509Certificate issueCert;
 
     private KeyPair signingKP;
+    private KeyPair decryptingKP;
     private X509Certificate signingCert;
     private List<X509Certificate> certList;
     private AS2SignedDataGenerator gen;
@@ -299,8 +300,6 @@ public class AS2ClientManagerIntegrationTest extends AbstractAS2TestSupport {
         headers.put("CamelAS2.encryptingAlgorithm", AS2EncryptionAlgorithm.AES128_CBC);
         // parameter type is java.security.cert.Certificate[]
         headers.put("CamelAS2.encryptingCertificateChain", certList);
-        // parameter type is java.security.PrivateKey
-        headers.put("CamelAS2.encryptingPrivateKey", signingKP.getPrivate());
 
         final org.apache.http.protocol.HttpCoreContext result = requestBodyAndHeaders("direct://SEND", EDI_MESSAGE, headers);
 
@@ -312,7 +311,7 @@ public class AS2ClientManagerIntegrationTest extends AbstractAS2TestSupport {
         HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity();
         assertNotNull("Request body", entity);
         assertTrue("Request body does not contain ApplicationPkcs7Mime entity", entity instanceof ApplicationPkcs7MimeEnvelopedDataEntity);
-        MimeEntity envelopeEntity = ((ApplicationPkcs7MimeEnvelopedDataEntity)entity).getEncryptedEntity(signingKP.getPrivate());
+        MimeEntity envelopeEntity = ((ApplicationPkcs7MimeEnvelopedDataEntity)entity).getEncryptedEntity(decryptingKP.getPrivate());
         assertTrue("Enveloped entity is not an EDI entity", envelopeEntity instanceof ApplicationEDIEntity);
         String ediMessage = ((ApplicationEDIEntity)envelopeEntity).getEdiMessage();
         assertEquals("EDI message is different", EDI_MESSAGE.replaceAll("[\n\r]", ""), ediMessage.replaceAll("[\n\r]", ""));
@@ -437,7 +436,7 @@ public class AS2ClientManagerIntegrationTest extends AbstractAS2TestSupport {
         assertEquals("Unexpected value for disposition type", AS2DispositionType.PROCESSED, messageDispositionNotificationEntity.getDispositionType());
         
         ReceivedContentMic receivedContentMic = messageDispositionNotificationEntity.getReceivedContentMic();
-        ReceivedContentMic computedContentMic = MicUtils.createReceivedContentMic((HttpEntityEnclosingRequest)request);
+        ReceivedContentMic computedContentMic = MicUtils.createReceivedContentMic((HttpEntityEnclosingRequest)request, decryptingKP.getPrivate());
         assertEquals("Received content MIC does not match computed", computedContentMic.getEncodedMessageDigest(), receivedContentMic.getEncodedMessageDigest());
     }
 
@@ -524,7 +523,7 @@ public class AS2ClientManagerIntegrationTest extends AbstractAS2TestSupport {
         assertEquals("Unexpected value for disposition type", AS2DispositionType.PROCESSED, messageDispositionNotificationEntity.getDispositionType());
         
         ReceivedContentMic receivedContentMic = messageDispositionNotificationEntity.getReceivedContentMic();
-        ReceivedContentMic computedContentMic = MicUtils.createReceivedContentMic((HttpEntityEnclosingRequest)request);
+        ReceivedContentMic computedContentMic = MicUtils.createReceivedContentMic((HttpEntityEnclosingRequest)request, decryptingKP.getPrivate());
         assertEquals("Received content MIC does not match computed", computedContentMic.getEncodedMessageDigest(), receivedContentMic.getEncodedMessageDigest());
     }
 
@@ -564,7 +563,7 @@ public class AS2ClientManagerIntegrationTest extends AbstractAS2TestSupport {
         DispositionNotificationMultipartReportEntity mdn = new DispositionNotificationMultipartReportEntity(request,
                 response, DispositionMode.AUTOMATIC_ACTION_MDN_SENT_AUTOMATICALLY, AS2DispositionType.PROCESSED,
                 dispositionModifier, failureFields, errorFields, warningFields, extensionFields, null, "boundary",
-                true);
+                true, serverSigningKP.getPrivate());
 
         // Send MDN
         @SuppressWarnings("unused")
@@ -648,7 +647,7 @@ public class AS2ClientManagerIntegrationTest extends AbstractAS2TestSupport {
 
     private static void receiveTestMessages() throws IOException {
         serverConnection = new AS2ServerConnection(AS2_VERSION, ORIGIN_SERVER_NAME,
-                SERVER_FQDN, PARTNER_TARGET_PORT, AS2SignatureAlgorithm.SHA256WITHRSA, serverCertList.toArray(new Certificate[0]), serverSigningKP.getPrivate());
+                SERVER_FQDN, PARTNER_TARGET_PORT, AS2SignatureAlgorithm.SHA256WITHRSA, serverCertList.toArray(new Certificate[0]), serverSigningKP.getPrivate(), serverSigningKP.getPrivate());
         serverConnection.listen("/", new RequestHandler());
     }
 
@@ -678,5 +677,7 @@ public class AS2ClientManagerIntegrationTest extends AbstractAS2TestSupport {
         certList.add(signingCert);
         certList.add(issueCert);
 
+        // keys used to encrypt/decrypt
+        decryptingKP = signingKP;
     }
 }
diff --git a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerManagerIntegrationTest.java b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerManagerIntegrationTest.java
index cb58af7..34b598b 100644
--- a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerManagerIntegrationTest.java
+++ b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerManagerIntegrationTest.java
@@ -26,19 +26,24 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.as2.api.AS2Charset;
 import org.apache.camel.component.as2.api.AS2ClientConnection;
 import org.apache.camel.component.as2.api.AS2ClientManager;
+import org.apache.camel.component.as2.api.AS2EncryptionAlgorithm;
 import org.apache.camel.component.as2.api.AS2Header;
 import org.apache.camel.component.as2.api.AS2MediaType;
 import org.apache.camel.component.as2.api.AS2MessageStructure;
+import org.apache.camel.component.as2.api.AS2MimeType;
 import org.apache.camel.component.as2.api.AS2SignatureAlgorithm;
 import org.apache.camel.component.as2.api.AS2SignedDataGenerator;
 import org.apache.camel.component.as2.api.entity.ApplicationEDIFACTEntity;
+import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeEnvelopedDataEntity;
 import org.apache.camel.component.as2.api.entity.ApplicationPkcs7SignatureEntity;
+import org.apache.camel.component.as2.api.entity.MimeEntity;
 import org.apache.camel.component.as2.api.entity.MultipartSignedEntity;
 import org.apache.camel.component.as2.api.util.SigningUtils;
 import org.apache.camel.component.as2.internal.AS2ApiCollection;
@@ -60,6 +65,7 @@ import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute;
 import org.bouncycastle.asn1.x500.X500Name;
 import org.bouncycastle.cert.jcajce.JcaCertStore;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -112,14 +118,21 @@ public class AS2ServerManagerIntegrationTest extends AbstractAS2TestSupport {
             + "UNT+23+00000000000117'\n"
             + "UNZ+1+00000000000778'";
 
-    private AS2SignedDataGenerator gen;
+    private static AS2SignedDataGenerator gen;
 
-    private KeyPair issueKP;
-    private X509Certificate issueCert;
+    private static KeyPair issueKP;
+    private static X509Certificate issueCert;
 
-    private KeyPair signingKP;
-    private X509Certificate signingCert;
-    private List<X509Certificate> certList;
+    private static KeyPair signingKP;
+    private static X509Certificate signingCert;
+    private static List<X509Certificate> certList;
+    
+    private static KeyPair decryptingKP;
+    
+    @BeforeClass
+    public static void  setup() throws Exception {
+        setupSigningGenerator();
+    }
 
     @Test
     public void receivePlainEDIMessageTest() throws Exception {
@@ -178,7 +191,6 @@ public class AS2ServerManagerIntegrationTest extends AbstractAS2TestSupport {
 
     @Test
     public void receiveMultipartSignedMessageTest() throws Exception {
-        setupSigningGenerator();
 
         AS2ClientConnection clientConnection = new AS2ClientConnection(AS2_VERSION, USER_AGENT, CLIENT_FQDN, TARGET_HOST, TARGET_PORT);
         AS2ClientManager clientManager = new AS2ClientManager(clientConnection);
@@ -245,8 +257,70 @@ public class AS2ServerManagerIntegrationTest extends AbstractAS2TestSupport {
         // Validate Signature
         assertTrue("Signature is invalid", signedEntity.isValid());
     }
+    
+    @Test
+    public void receiveEnvelopedMessageTest() throws Exception {
+        AS2ClientConnection clientConnection = new AS2ClientConnection(AS2_VERSION, USER_AGENT, CLIENT_FQDN, TARGET_HOST, TARGET_PORT);
+        AS2ClientManager clientManager = new AS2ClientManager(clientConnection);
+
+        clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME, AS2MessageStructure.ENCRYPTED,
+                ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), null, null, null, null,
+                null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, AS2EncryptionAlgorithm.AES128_CBC, certList.toArray(new Certificate[0]));
 
-    private void setupSigningGenerator() throws Exception {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:as2RcvMsgs");
+        mockEndpoint.expectedMinimumMessageCount(1);
+        mockEndpoint.setResultWaitTime(TimeUnit.MILLISECONDS.convert(30,  TimeUnit.SECONDS));
+        mockEndpoint.assertIsSatisfied();
+
+        final List<Exchange> exchanges = mockEndpoint.getExchanges();
+        assertNotNull("listen result", exchanges);
+        assertFalse("listen result", exchanges.isEmpty());
+        LOG.debug("poll result: " + exchanges);
+
+        Exchange exchange = exchanges.get(0);
+        Message message = exchange.getIn();
+        assertNotNull("exchange message", message);
+        BasicHttpContext context = message.getBody(BasicHttpContext.class);
+        assertNotNull("context", context);
+        HttpCoreContext coreContext = HttpCoreContext.adapt(context);
+        HttpRequest request = coreContext.getRequest();
+        assertNotNull("request", request);
+        assertEquals("Unexpected method value", METHOD, request.getRequestLine().getMethod());
+        assertEquals("Unexpected request URI value", REQUEST_URI, request.getRequestLine().getUri());
+        assertEquals("Unexpected HTTP version value", HttpVersion.HTTP_1_1, request.getRequestLine().getProtocolVersion());
+        assertEquals("Unexpected subject value", SUBJECT, request.getFirstHeader(AS2Header.SUBJECT).getValue());
+        assertEquals("Unexpected from value", FROM, request.getFirstHeader(AS2Header.FROM).getValue());
+        assertEquals("Unexpected AS2 version value", AS2_VERSION, request.getFirstHeader(AS2Header.AS2_VERSION).getValue());
+        assertEquals("Unexpected AS2 from value", AS2_NAME, request.getFirstHeader(AS2Header.AS2_FROM).getValue());
+        assertEquals("Unexpected AS2 to value", AS2_NAME, request.getFirstHeader(AS2Header.AS2_TO).getValue());
+        assertTrue("Unexpected message id value", request.getFirstHeader(AS2Header.MESSAGE_ID).getValue().endsWith(CLIENT_FQDN + ">"));
+        assertEquals("Unexpected target host value", TARGET_HOST + ":" + TARGET_PORT, request.getFirstHeader(AS2Header.TARGET_HOST).getValue());
+        assertEquals("Unexpected user agent value", USER_AGENT, request.getFirstHeader(AS2Header.USER_AGENT).getValue());
+        assertNotNull("Date value missing", request.getFirstHeader(AS2Header.DATE));
+        assertNotNull("Content length value missing", request.getFirstHeader(AS2Header.CONTENT_LENGTH));
+        assertTrue("Unexpected content type for message", request.getFirstHeader(AS2Header.CONTENT_TYPE).getValue().startsWith(AS2MimeType.APPLICATION_PKCS7_MIME));
+
+
+        assertTrue("Request does not contain entity", request instanceof BasicHttpEntityEnclosingRequest);
+        HttpEntity entity = ((BasicHttpEntityEnclosingRequest) request).getEntity();
+        assertNotNull("Request does not contain entity", entity);
+        assertTrue("Unexpected request entity type", entity instanceof ApplicationPkcs7MimeEnvelopedDataEntity);
+        ApplicationPkcs7MimeEnvelopedDataEntity envelopedEntity = (ApplicationPkcs7MimeEnvelopedDataEntity) entity;
+        assertTrue("Entity not set as main body of request", envelopedEntity.isMainBody());
+
+        // Validated enveloped part.
+        MimeEntity encryptedEntity = envelopedEntity.getEncryptedEntity(signingKP.getPrivate());
+        assertTrue("Enveloped mime part incorrect type ", encryptedEntity instanceof ApplicationEDIFACTEntity);
+        ApplicationEDIFACTEntity ediEntity = (ApplicationEDIFACTEntity) encryptedEntity;
+        assertTrue("Unexpected content type for enveloped mime part",
+                ediEntity.getContentType().getValue().startsWith(AS2MediaType.APPLICATION_EDIFACT));
+        assertFalse("Enveloped mime type set as main body of request", ediEntity.isMainBody());
+        assertEquals("Unexpected content for enveloped mime part", EDI_MESSAGE.replaceAll("[\n\r]", ""),
+                ediEntity.getEdiMessage().replaceAll("[\n\r]", ""));
+
+    }
+
+    private static void setupSigningGenerator() throws Exception {
         Security.addProvider(new BouncyCastleProvider());
 
         setupKeysAndCertificates();
@@ -270,7 +344,7 @@ public class AS2ServerManagerIntegrationTest extends AbstractAS2TestSupport {
 
     }
 
-    private void setupKeysAndCertificates() throws Exception {
+    private static void setupKeysAndCertificates() throws Exception {
         //
         // set up our certificates
         //
@@ -295,9 +369,19 @@ public class AS2ServerManagerIntegrationTest extends AbstractAS2TestSupport {
 
         certList.add(signingCert);
         certList.add(issueCert);
+        
+        decryptingKP = signingKP;
 
     }
-
+    
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = super.createCamelContext();
+        AS2Component as2Component = (AS2Component) context.getComponent("as2");
+        AS2Configuration configuration = as2Component.getConfiguration();
+        configuration.setDecryptingPrivateKey(decryptingKP.getPrivate());
+        return context;
+    }
 
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
diff --git a/platforms/spring-boot/components-starter/camel-as2-starter/src/main/java/org/apache/camel/component/as2/springboot/AS2ComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-as2-starter/src/main/java/org/apache/camel/component/as2/springboot/AS2ComponentConfiguration.java
index eda444f..6b66ad7 100644
--- a/platforms/spring-boot/components-starter/camel-as2-starter/src/main/java/org/apache/camel/component/as2/springboot/AS2ComponentConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-as2-starter/src/main/java/org/apache/camel/component/as2/springboot/AS2ComponentConfiguration.java
@@ -194,7 +194,7 @@ public class AS2ComponentConfiguration
         /**
          * The key used to encrypt the EDI message.
          */
-        private PrivateKey encryptingPrivateKey;
+        private PrivateKey decryptingPrivateKey;
 
         public AS2ApiName getApiName() {
             return apiName;
@@ -412,12 +412,12 @@ public class AS2ComponentConfiguration
             this.encryptingCertificateChain = encryptingCertificateChain;
         }
 
-        public PrivateKey getEncryptingPrivateKey() {
-            return encryptingPrivateKey;
+        public PrivateKey getDecryptingPrivateKey() {
+            return decryptingPrivateKey;
         }
 
-        public void setEncryptingPrivateKey(PrivateKey encryptingPrivateKey) {
-            this.encryptingPrivateKey = encryptingPrivateKey;
+        public void setDecryptingPrivateKey(PrivateKey decryptingPrivateKey) {
+            this.decryptingPrivateKey = decryptingPrivateKey;
         }
     }
 }
\ No newline at end of file