[ 
https://issues.apache.org/jira/browse/CAMEL-12605?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16595980#comment-16595980
 ] 

ASF GitHub Bot commented on CAMEL-12605:
----------------------------------------

oscerd closed pull request #2495: [CAMEL-12605] Integrated encryption logic 
into component.
URL: https://github.com/apache/camel/pull/2495
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2Algorithm.java
 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2Algorithm.java
new file mode 100644
index 00000000000..8e71f478ff2
--- /dev/null
+++ 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2Algorithm.java
@@ -0,0 +1,346 @@
+/**
+ * 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.api;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.cms.CMSAlgorithm;
+
+interface AS2AlgorithmConstants {
+    static final String DES_CBC = "DES_CBC";
+    static final String DES_EDE3_CBC = "DES_EDE3_CBC";
+    static final String RC2_CBC = "RC2_CBC";
+    static final String IDEA_CBC = "IDEA_CBC";
+    static final String CAST5_CBC = "CAST5_CBC";
+    static final String AES128_CBC = "AES128_CBC";
+    static final String AES192_CBC = "AES192_CBC";
+    static final String AES256_CBC = "AES256_CBC";
+    static final String AES128_CCM = "AES128_CCM";
+    static final String AES192_CCM = "AES192_CCM";
+    static final String AES256_CCM = "AES256_CCM";
+    static final String AES128_GCM = "AES128_GCM";
+    static final String AES192_GCM = "AES192_GCM";
+    static final String AES256_GCM = "AES256_GCM";
+    static final String CAMELLIA128_CBC = "CAMELLIA128_CBC";
+    static final String CAMELLIA192_CBC = "CAMELLIA192_CBC";
+    static final String CAMELLIA256_CBC = "CAMELLIA256_CBC";
+    static final String GOST28147_GCFB = "GOST28147_GCFB";
+    static final String SEED_CBC = "SEED_CBC";
+    static final String DES_EDE3_WRAP = "DES_EDE3_WRAP";
+    static final String AES128_WRAP = "AES128_WRAP";
+    static final String AES192_WRAP = "AES192_WRAP";
+    static final String AES256_WRAP = "AES256_WRAP";
+    static final String CAMELLIA128_WRAP = "CAMELLIA128_WRAP";
+    static final String CAMELLIA192_WRAP = "CAMELLIA192_WRAP";
+    static final String CAMELLIA256_WRAP = "CAMELLIA256_WRAP";
+    static final String SEED_WRAP = "SEED_WRAP";
+    static final String GOST28147_WRAP = "GOST28147_WRAP";
+    static final String GOST28147_CRYPTOPRO_WRAP = "GOST28147_CRYPTOPRO_WRAP";
+    static final String ECDH_SHA1KDF = "ECDH_SHA1KDF";
+    static final String ECCDH_SHA1KDF = "ECCDH_SHA1KDF";
+    static final String ECMQV_SHA1KDF = "ECMQV_SHA1KDF";
+    static final String ECDH_SHA224KDF = "ECDH_SHA224KDF";
+    static final String ECCDH_SHA224KDF = "ECCDH_SHA224KDF";
+    static final String ECMQV_SHA224KDF = "ECMQV_SHA224KDF";
+    static final String ECDH_SHA256KDF = "ECDH_SHA256KDF";
+    static final String ECCDH_SHA256KDF = "ECCDH_SHA256KDF";
+    static final String ECMQV_SHA256KDF = "ECMQV_SHA256KDF";
+    static final String ECDH_SHA384KDF = "ECDH_SHA384KDF";
+    static final String ECCDH_SHA384KDF = "ECCDH_SHA384KDF";
+    static final String ECMQV_SHA384KDF = "ECMQV_SHA384KDF";
+    static final String ECDH_SHA512KDF = "ECDH_SHA512KDF";
+    static final String ECCDH_SHA512KDF = "ECCDH_SHA512KDF";
+    static final String ECMQV_SHA512KDF = "ECMQV_SHA512KDF";
+    static final String ECDHGOST3410_2001 = "ECDHGOST3410_2001";
+    static final String ECDHGOST3410_2012_256 = "ECDHGOST3410_2012_256";
+    static final String ECDHGOST3410_2012_512 = "ECDHGOST3410_2012_512";
+    static final String SHA1 = "SHA1";
+    static final String SHA224 = "SHA224";
+    static final String SHA256 = "SHA256";
+    static final String SHA384 = "SHA384";
+    static final String SHA512 = "SHA512";
+    static final String MD5 = "MD5";
+    static final String GOST3411 = "GOST3411";
+    static final String GOST3411_2012_256 = "GOST3411_2012_256";
+    static final String GOST3411_2012_512 = "GOST3411_2012_512";
+    static final String RIPEMD128 = "RIPEMD128";
+    static final String RIPEMD160 = "RIPEMD160";
+    static final String RIPEMD256 = "RIPEMD256";
+}
+
+public enum AS2Algorithm {
+    DES_CBC(AS2AlgorithmConstants.DES_CBC, CMSAlgorithm.DES_CBC),
+    DES_EDE3_CBC(AS2AlgorithmConstants.DES_EDE3_CBC, 
CMSAlgorithm.DES_EDE3_CBC),
+    RC2_CBC(AS2AlgorithmConstants.RC2_CBC, CMSAlgorithm.RC2_CBC),
+    IDEA_CBC(AS2AlgorithmConstants.IDEA_CBC, CMSAlgorithm.IDEA_CBC),
+    CAST5_CBC(AS2AlgorithmConstants.CAST5_CBC, CMSAlgorithm.CAST5_CBC),
+    AES128_CBC(AS2AlgorithmConstants.AES128_CBC, CMSAlgorithm.AES128_CBC),
+    AES192_CBC(AS2AlgorithmConstants.AES192_CBC, CMSAlgorithm.AES192_CBC),
+    AES256_CBC(AS2AlgorithmConstants.AES256_CBC, CMSAlgorithm.AES256_CBC),
+    AES128_CCM(AS2AlgorithmConstants.AES128_CCM, CMSAlgorithm.AES128_CCM),
+    AES192_CCM(AS2AlgorithmConstants.AES192_CCM, CMSAlgorithm.AES192_CCM),
+    AES256_CCM(AS2AlgorithmConstants.AES256_CCM, CMSAlgorithm.AES256_CCM),
+    AES128_GCM(AS2AlgorithmConstants.AES128_GCM, CMSAlgorithm.AES128_GCM),
+    AES192_GCM(AS2AlgorithmConstants.AES192_GCM, CMSAlgorithm.AES192_GCM),
+    AES256_GCM(AS2AlgorithmConstants.AES256_GCM, CMSAlgorithm.AES256_GCM),
+    CAMELLIA128_CBC(AS2AlgorithmConstants.CAMELLIA128_CBC, 
CMSAlgorithm.CAMELLIA128_CBC),
+    CAMELLIA192_CBC(AS2AlgorithmConstants.CAMELLIA192_CBC, 
CMSAlgorithm.CAMELLIA192_CBC),
+    CAMELLIA256_CBC(AS2AlgorithmConstants.CAMELLIA256_CBC, 
CMSAlgorithm.CAMELLIA256_CBC),
+    GOST28147_GCFB(AS2AlgorithmConstants.GOST28147_GCFB, 
CMSAlgorithm.GOST28147_GCFB),
+    SEED_CBC(AS2AlgorithmConstants.SEED_CBC, CMSAlgorithm.SEED_CBC),
+    DES_EDE3_WRAP(AS2AlgorithmConstants.DES_EDE3_WRAP, 
CMSAlgorithm.DES_EDE3_WRAP),
+    AES128_WRAP(AS2AlgorithmConstants.AES128_WRAP, CMSAlgorithm.AES128_WRAP),
+    AES192_WRAP(AS2AlgorithmConstants.AES192_WRAP, CMSAlgorithm.AES192_WRAP),
+    AES256_WRAP(AS2AlgorithmConstants.AES256_WRAP, CMSAlgorithm.AES256_WRAP),
+    CAMELLIA128_WRAP(AS2AlgorithmConstants.CAMELLIA128_WRAP, 
CMSAlgorithm.CAMELLIA128_WRAP),
+    CAMELLIA192_WRAP(AS2AlgorithmConstants.CAMELLIA192_WRAP, 
CMSAlgorithm.CAMELLIA192_WRAP),
+    CAMELLIA256_WRAP(AS2AlgorithmConstants.CAMELLIA256_WRAP, 
CMSAlgorithm.CAMELLIA256_WRAP),
+    SEED_WRAP(AS2AlgorithmConstants.SEED_WRAP, CMSAlgorithm.SEED_WRAP),
+    GOST28147_WRAP(AS2AlgorithmConstants.GOST28147_WRAP, 
CMSAlgorithm.GOST28147_WRAP),
+    GOST28147_CRYPTOPRO_WRAP(AS2AlgorithmConstants.GOST28147_CRYPTOPRO_WRAP, 
CMSAlgorithm.GOST28147_CRYPTOPRO_WRAP),
+    ECDH_SHA1KDF(AS2AlgorithmConstants.ECDH_SHA1KDF, 
CMSAlgorithm.ECDH_SHA1KDF),
+    ECCDH_SHA1KDF(AS2AlgorithmConstants.ECCDH_SHA1KDF, 
CMSAlgorithm.ECCDH_SHA1KDF),
+    ECMQV_SHA1KDF(AS2AlgorithmConstants.ECMQV_SHA1KDF, 
CMSAlgorithm.ECMQV_SHA1KDF),
+    ECDH_SHA224KDF(AS2AlgorithmConstants.ECDH_SHA224KDF, 
CMSAlgorithm.ECDH_SHA224KDF),
+    ECCDH_SHA224KDF(AS2AlgorithmConstants.ECCDH_SHA224KDF, 
CMSAlgorithm.ECCDH_SHA224KDF),
+    ECMQV_SHA224KDF(AS2AlgorithmConstants.ECMQV_SHA224KDF, 
CMSAlgorithm.ECMQV_SHA224KDF),
+    ECDH_SHA256KDF(AS2AlgorithmConstants.ECDH_SHA256KDF, 
CMSAlgorithm.ECDH_SHA256KDF),
+    ECCDH_SHA256KDF(AS2AlgorithmConstants.ECCDH_SHA256KDF, 
CMSAlgorithm.ECCDH_SHA256KDF),
+    ECMQV_SHA256KDF(AS2AlgorithmConstants.ECMQV_SHA256KDF, 
CMSAlgorithm.ECMQV_SHA256KDF),
+    ECDH_SHA384KDF(AS2AlgorithmConstants.ECDH_SHA384KDF, 
CMSAlgorithm.ECDH_SHA384KDF),
+    ECCDH_SHA384KDF(AS2AlgorithmConstants.ECCDH_SHA384KDF, 
CMSAlgorithm.ECCDH_SHA384KDF),
+    ECMQV_SHA384KDF(AS2AlgorithmConstants.ECMQV_SHA384KDF, 
CMSAlgorithm.ECMQV_SHA384KDF),
+    ECDH_SHA512KDF(AS2AlgorithmConstants.ECDH_SHA512KDF, 
CMSAlgorithm.ECDH_SHA512KDF),
+    ECCDH_SHA512KDF(AS2AlgorithmConstants.ECCDH_SHA512KDF, 
CMSAlgorithm.ECCDH_SHA512KDF),
+    ECMQV_SHA512KDF(AS2AlgorithmConstants.ECMQV_SHA512KDF, 
CMSAlgorithm.ECMQV_SHA512KDF),
+    ECDHGOST3410_2001(AS2AlgorithmConstants.ECDHGOST3410_2001, 
CMSAlgorithm.ECDHGOST3410_2001),
+    ECDHGOST3410_2012_256(AS2AlgorithmConstants.ECDHGOST3410_2012_256, 
CMSAlgorithm.ECDHGOST3410_2012_256),
+    ECDHGOST3410_2012_512(AS2AlgorithmConstants.ECDHGOST3410_2012_512, 
CMSAlgorithm.ECDHGOST3410_2012_512),
+    SHA1(AS2AlgorithmConstants.SHA1, CMSAlgorithm.SHA1),
+    SHA224(AS2AlgorithmConstants.SHA224, CMSAlgorithm.SHA224),
+    SHA256(AS2AlgorithmConstants.SHA256, CMSAlgorithm.SHA256),
+    SHA384(AS2AlgorithmConstants.SHA384, CMSAlgorithm.SHA384),
+    SHA512(AS2AlgorithmConstants.SHA512, CMSAlgorithm.SHA512),
+    MD5(AS2AlgorithmConstants.MD5, CMSAlgorithm.MD5),
+    GOST3411(AS2AlgorithmConstants.GOST3411, CMSAlgorithm.GOST3411),
+    GOST3411_2012_256(AS2AlgorithmConstants.GOST3411_2012_256, 
CMSAlgorithm.GOST3411_2012_256),
+    GOST3411_2012_512(AS2AlgorithmConstants.GOST3411_2012_512, 
CMSAlgorithm.GOST3411_2012_512),
+    RIPEMD128(AS2AlgorithmConstants.RIPEMD128, CMSAlgorithm.RIPEMD128),
+    RIPEMD160(AS2AlgorithmConstants.RIPEMD160, CMSAlgorithm.RIPEMD160),
+    RIPEMD256(AS2AlgorithmConstants.RIPEMD256, CMSAlgorithm.RIPEMD256);
+    
+    private String algorithmName;
+    private ASN1ObjectIdentifier algorithmOID;
+    
+    private AS2Algorithm(String algorithmName, ASN1ObjectIdentifier 
algorithmOID) {
+        this.algorithmName = algorithmName;
+        this.algorithmOID = algorithmOID;
+    }
+    public String getAlgorithmName() {
+        return algorithmName;
+    }
+    public ASN1ObjectIdentifier getAlgorithmOID() {
+        return algorithmOID;
+    }
+    
+    public static AS2Algorithm getAS2Algorithm(String algorithmName) {
+        AS2Algorithm as2Algorithm;
+        switch (algorithmName) {
+        case "DES_CBC":
+            as2Algorithm = DES_CBC;
+            break;
+        case "DES_EDE3_CBC":
+            as2Algorithm = DES_EDE3_CBC;
+            break;
+        case "RC2_CBC":
+            as2Algorithm = RC2_CBC;
+            break;
+        case "IDEA_CBC":
+            as2Algorithm = IDEA_CBC;
+            break;
+        case "CAST5_CBC":
+            as2Algorithm = CAST5_CBC;
+            break;
+        case "AES128_CBC":
+            as2Algorithm = AES128_CBC;
+            break;
+        case "AES192_CBC":
+            as2Algorithm = AES192_CBC;
+            break;
+        case "AES256_CBC":
+            as2Algorithm = AES256_CBC;
+            break;
+        case "AES128_CCM":
+            as2Algorithm = AES128_CCM;
+            break;
+        case "AES192_CCM":
+            as2Algorithm = AES192_CCM;
+            break;
+        case "AES256_CCM":
+            as2Algorithm = AES256_CCM;
+            break;
+        case "AES128_GCM":
+            as2Algorithm = AES128_GCM;
+            break;
+        case "AES192_GCM":
+            as2Algorithm = AES192_GCM;
+            break;
+        case "AES256_GCM":
+            as2Algorithm = AES256_GCM;
+            break;
+        case "CAMELLIA128_CBC":
+            as2Algorithm = CAMELLIA128_CBC;
+            break;
+        case "CAMELLIA192_CBC":
+            as2Algorithm = CAMELLIA192_CBC;
+            break;
+        case "CAMELLIA256_CBC":
+            as2Algorithm = CAMELLIA256_CBC;
+            break;
+        case "GOST28147_GCFB":
+            as2Algorithm = GOST28147_GCFB;
+            break;
+        case "SEED_CBC":
+            as2Algorithm = SEED_CBC;
+            break;
+        case "DES_EDE3_WRAP":
+            as2Algorithm = DES_EDE3_WRAP;
+            break;
+        case "AES128_WRAP":
+            as2Algorithm = AES128_WRAP;
+            break;
+        case "AES192_WRAP":
+            as2Algorithm = AES192_WRAP;
+            break;
+        case "AES256_WRAP":
+            as2Algorithm = AES256_WRAP;
+            break;
+        case "CAMELLIA128_WRAP":
+            as2Algorithm = CAMELLIA128_WRAP;
+            break;
+        case "CAMELLIA192_WRAP":
+            as2Algorithm = CAMELLIA192_WRAP;
+            break;
+        case "CAMELLIA256_WRAP":
+            as2Algorithm = CAMELLIA256_WRAP;
+            break;
+        case "SEED_WRAP":
+            as2Algorithm = SEED_WRAP;
+            break;
+        case "GOST28147_WRAP":
+            as2Algorithm = GOST28147_WRAP;
+            break;
+        case "GOST28147_CRYPTOPRO_WRAP":
+            as2Algorithm = GOST28147_CRYPTOPRO_WRAP;
+            break;
+        case "ECDH_SHA1KDF":
+            as2Algorithm = ECDH_SHA1KDF;
+            break;
+        case "ECCDH_SHA1KDF":
+            as2Algorithm = ECCDH_SHA1KDF;
+            break;
+        case "ECMQV_SHA1KDF":
+            as2Algorithm = ECMQV_SHA1KDF;
+            break;
+        case "ECDH_SHA224KDF":
+            as2Algorithm = ECDH_SHA224KDF;
+            break;
+        case "ECCDH_SHA224KDF":
+            as2Algorithm = ECCDH_SHA224KDF;
+            break;
+        case "ECMQV_SHA224KDF":
+            as2Algorithm = ECMQV_SHA224KDF;
+            break;
+        case "ECDH_SHA256KDF":
+            as2Algorithm = ECDH_SHA256KDF;
+            break;
+        case "ECCDH_SHA256KDF":
+            as2Algorithm = ECCDH_SHA256KDF;
+            break;
+        case "ECMQV_SHA256KDF":
+            as2Algorithm = ECMQV_SHA256KDF;
+            break;
+        case "ECDH_SHA384KDF":
+            as2Algorithm = ECDH_SHA384KDF;
+            break;
+        case "ECCDH_SHA384KDF":
+            as2Algorithm = ECCDH_SHA384KDF;
+            break;
+        case "ECMQV_SHA384KDF":
+            as2Algorithm = ECMQV_SHA384KDF;
+            break;
+        case "ECDH_SHA512KDF":
+            as2Algorithm = ECDH_SHA512KDF;
+            break;
+        case "ECCDH_SHA512KDF":
+            as2Algorithm = ECCDH_SHA512KDF;
+            break;
+        case "ECMQV_SHA512KDF":
+            as2Algorithm = ECMQV_SHA512KDF;
+            break;
+        case "ECDHGOST3410_2001":
+            as2Algorithm = ECDHGOST3410_2001;
+            break;
+        case "ECDHGOST3410_2012_256":
+            as2Algorithm = ECDHGOST3410_2012_256;
+            break;
+        case "ECDHGOST3410_2012_512":
+            as2Algorithm = ECDHGOST3410_2012_512;
+            break;
+        case "SHA1":
+            as2Algorithm = SHA1;
+            break;
+        case "SHA224":
+            as2Algorithm = SHA224;
+            break;
+        case "SHA256":
+            as2Algorithm = SHA256;
+            break;
+        case "SHA384":
+            as2Algorithm = SHA384;
+            break;
+        case "SHA512":
+            as2Algorithm = SHA512;
+            break;
+        case "MD5":
+            as2Algorithm = MD5;
+            break;
+        case "GOST3411":
+            as2Algorithm = GOST3411;
+            break;
+        case "GOST3411_2012_256":
+            as2Algorithm = GOST3411_2012_256;
+            break;
+        case "GOST3411_2012_512":
+            as2Algorithm = GOST3411_2012_512;
+            break;
+        case "RIPEMD128":
+            as2Algorithm = RIPEMD128;
+            break;
+        case "RIPEMD160":
+            as2Algorithm = RIPEMD160;
+            break;
+        case "RIPEMD256":
+            as2Algorithm = RIPEMD256;
+            break;
+
+        default:
+            throw new IllegalArgumentException("Unsupported algorithm '" + 
algorithmName + "'");
+        }
+        return as2Algorithm;
+    }
+    
+}
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 4e22e7baf77..9c33d9a576e 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
@@ -21,8 +21,10 @@
 import java.security.cert.Certificate;
 
 import org.apache.camel.component.as2.api.entity.ApplicationEDIEntity;
+import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeEntity;
 import org.apache.camel.component.as2.api.entity.EntityParser;
 import org.apache.camel.component.as2.api.entity.MultipartSignedEntity;
+import org.apache.camel.component.as2.api.util.EncryptingUtils;
 import org.apache.camel.component.as2.api.util.EntityUtils;
 import org.apache.camel.component.as2.api.util.SigningUtils;
 import org.apache.http.HttpException;
@@ -31,6 +33,8 @@
 import org.apache.http.message.BasicHttpEntityEnclosingRequest;
 import org.apache.http.protocol.HttpCoreContext;
 import org.apache.http.util.Args;
+import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
+import org.bouncycastle.operator.OutputEncryptor;
 
 /**
  * AS2 Client Manager
@@ -134,6 +138,24 @@
      */
     public static final String SIGNING_PRIVATE_KEY = CAMEL_AS2_CLIENT_PREFIX + 
"signing-private-key";
 
+    /**
+     * The HTTP Context Attribute containing the algorithm name used to 
encrypt EDI
+     * message
+     */
+    public static final String ENCRYPTING_ALGORITHM_NAME = 
CAMEL_AS2_CLIENT_PREFIX + "encrypting-algorithm-name";
+
+    /**
+     * The HTTP Context Attribute containing the certificate used to encrypt
+     * EDI message
+     */
+    public static final String ENCRYPTING_CERTIFICATE_CHAIN = 
CAMEL_AS2_CLIENT_PREFIX + "encrypting-certificate-chain";
+
+    /**
+     * The HTTP Context Attribute containing the private key used to encrypt 
EDI
+     * message
+     */
+    public static final String ENCRYPTING_PRIVATE_KEY = 
CAMEL_AS2_CLIENT_PREFIX + "encrypting-private-key";
+
     /**
      * The HTTP Context Attribute containing the internet e-mail address of
      * sending system requesting a message disposition notification.
@@ -172,6 +194,9 @@ public AS2ClientManager(AS2ClientConnection 
as2ClientConnection) {
      * @param signingPrivateKey - the private key used to sign EDI message
      * @param dispositionNotificationTo - an RFC2822 address to request a 
receipt or <code>null</code> if no receipt requested
      * @param signedReceiptMicAlgorithms - the senders list of signing 
algorithms for signing receipt, in preferred order,  or <code>null</code> if 
requesting an unsigned receipt.
+     * @param encryptionAlgorithmName - the name of the algorithm used to 
encrypt the message or <code>null</code> if sending EDI message unencrypted
+     * @param encryptionCertificateChain - the chain of certificates used to 
encrypt the message or <code>null</code> if sending EDI message unencrypted
+     * @param encryptionPrivateKey - the private key used to encrypt EDI 
message
      * @return {@link HttpCoreContext} containing request and response used to 
send EDI message
      * @throws HttpException when things go wrong.
      */
@@ -187,7 +212,10 @@ public HttpCoreContext send(String ediMessage,
                                 Certificate[] signingCertificateChain,
                                 PrivateKey signingPrivateKey,
                                 String dispositionNotificationTo,
-                                String[] signedReceiptMicAlgorithms)
+                                String[] signedReceiptMicAlgorithms,
+                                String encryptionAlgorithmName,
+                                Certificate[] encryptionCertificateChain,
+                                PrivateKey encryptionPrivateKey)
             throws HttpException {
 
         Args.notNull(ediMessage, "EDI Message");
@@ -209,6 +237,9 @@ public HttpCoreContext send(String ediMessage,
         httpContext.setAttribute(AS2ClientManager.SIGNING_PRIVATE_KEY, 
signingPrivateKey);
         httpContext.setAttribute(AS2ClientManager.DISPOSITION_NOTIFICATION_TO, 
dispositionNotificationTo);
         
httpContext.setAttribute(AS2ClientManager.SIGNED_RECEIPT_MIC_ALGORITHMS, 
signedReceiptMicAlgorithms);
+        httpContext.setAttribute(AS2ClientManager.ENCRYPTING_ALGORITHM_NAME, 
encryptionAlgorithmName);
+        
httpContext.setAttribute(AS2ClientManager.ENCRYPTING_CERTIFICATE_CHAIN, 
encryptionCertificateChain);
+        httpContext.setAttribute(AS2ClientManager.ENCRYPTING_PRIVATE_KEY, 
encryptionPrivateKey);
 
         BasicHttpEntityEnclosingRequest request = new 
BasicHttpEntityEnclosingRequest("POST", requestUri);
         httpContext.setAttribute(HTTP_REQUEST, request);
@@ -238,7 +269,10 @@ public HttpCoreContext send(String ediMessage,
             }
             break;
         case ENCRYPTED:
-            // TODO : Add code here to add application/pkcs7-mime entity when 
encryption facility available.
+            CMSEnvelopedDataGenerator envelopedDataGenerator = 
createEncryptingGenerator(httpContext);
+            OutputEncryptor encryptor = createEncryptor(httpContext);
+            ApplicationPkcs7MimeEntity pkcs7MimeEntity = new 
ApplicationPkcs7MimeEntity(applicationEDIEntity, envelopedDataGenerator, 
encryptor, AS2TransferEncoding.BASE64, true);
+            EntityUtils.setMessageEntity(request, pkcs7MimeEntity);
             break;
         case ENCRYPTED_SIGNED:
             // TODO : Add code here to add application/pkcs7-mime entity when 
encryption facility available.
@@ -275,20 +309,25 @@ public AS2SignedDataGenerator 
createSigningGenerator(HttpCoreContext httpContext
 
     }
 
-    public AS2SignedDataGenerator createEncryptingGenerator(HttpCoreContext 
httpContext) throws HttpException {
+    public CMSEnvelopedDataGenerator createEncryptingGenerator(HttpCoreContext 
httpContext) throws HttpException {
 
-        Certificate[] certificateChain = 
httpContext.getAttribute(SIGNING_CERTIFICATE_CHAIN, Certificate[].class);
+        Certificate[] certificateChain = 
httpContext.getAttribute(ENCRYPTING_CERTIFICATE_CHAIN, Certificate[].class);
         if (certificateChain == null) {
-            throw new HttpException("Signing certificate chain missing");
+            throw new HttpException("Encrypting certificate chain missing");
         }
 
-        PrivateKey privateKey = httpContext.getAttribute(SIGNING_PRIVATE_KEY, 
PrivateKey.class);
-        if (privateKey == null) {
-            throw new HttpException("Signing private key missing");
-        }
+        return EncryptingUtils.createEnvelopDataGenerator(certificateChain);
 
-        return SigningUtils.createSigningGenerator(certificateChain, 
privateKey);
+    }
+    
+    public OutputEncryptor createEncryptor(HttpCoreContext httpContext) throws 
HttpException {
+        
+        String algorithmName = 
httpContext.getAttribute(ENCRYPTING_ALGORITHM_NAME, String.class);
+        if (algorithmName == null) {
+            throw new HttpException("Encrypting algorithm name missing");
+        }
 
+        return EncryptingUtils.createEncryptor(algorithmName);
     }
 
 }
diff --git 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationPkcs7MimeEntity.java
 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationPkcs7MimeEntity.java
index b61b440244b..c1d6952f413 100644
--- 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationPkcs7MimeEntity.java
+++ 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationPkcs7MimeEntity.java
@@ -16,35 +16,25 @@
  */
 package org.apache.camel.component.as2.api.entity;
 
-import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.OutputStream;
 import java.security.PrivateKey;
-import java.util.Collection;
-import java.util.Iterator;
 
 import org.apache.camel.component.as2.api.AS2Charset;
 import org.apache.camel.component.as2.api.AS2Header;
 import org.apache.camel.component.as2.api.CanonicalOutputStream;
-import org.apache.camel.component.as2.api.io.AS2SessionInputBuffer;
 import org.apache.camel.component.as2.api.util.EntityUtils;
 import org.apache.http.Header;
 import org.apache.http.HeaderIterator;
 import org.apache.http.HttpException;
 import org.apache.http.entity.ContentType;
-import org.apache.http.impl.io.HttpTransportMetricsImpl;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.util.Args;
 import org.bouncycastle.cms.CMSEnvelopedData;
 import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
 import org.bouncycastle.cms.CMSProcessableByteArray;
 import org.bouncycastle.cms.CMSTypedData;
-import org.bouncycastle.cms.Recipient;
-import org.bouncycastle.cms.RecipientInformation;
-import org.bouncycastle.cms.RecipientInformationStore;
-import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
 import org.bouncycastle.operator.OutputEncryptor;
 
 public class ApplicationPkcs7MimeEntity extends MimeEntity {
diff --git 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/EncryptingUtils.java
 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/EncryptingUtils.java
new file mode 100644
index 00000000000..8e0c9b3a347
--- /dev/null
+++ 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/EncryptingUtils.java
@@ -0,0 +1,67 @@
+/**
+ * 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.api.util;
+
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.apache.camel.component.as2.api.AS2Algorithm;
+import org.apache.http.HttpException;
+import org.apache.http.util.Args;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
+import org.bouncycastle.cms.CMSException;
+import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
+import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
+import org.bouncycastle.operator.OutputEncryptor;
+
+public final class EncryptingUtils {
+
+    private EncryptingUtils() {
+    }
+    
+    public static CMSEnvelopedDataGenerator 
createEnvelopDataGenerator(Certificate[] encryptionCertificateChain) throws 
HttpException {
+        Args.notNull(encryptionCertificateChain, "encryptionCertificateChain");
+        if (encryptionCertificateChain.length == 0 || 
!(encryptionCertificateChain[0] instanceof X509Certificate)) {
+            throw new IllegalArgumentException("Invalid certificate chain");
+        }
+        
+        try {
+            X509Certificate encryptionCertificate = (X509Certificate) 
encryptionCertificateChain[0];
+            
+            CMSEnvelopedDataGenerator cmsEnvelopeDataGenerator = new 
CMSEnvelopedDataGenerator();
+            
+            JceKeyTransRecipientInfoGenerator recipientInfoGenerator = new 
JceKeyTransRecipientInfoGenerator(encryptionCertificate);
+            
cmsEnvelopeDataGenerator.addRecipientInfoGenerator(recipientInfoGenerator);
+
+            return cmsEnvelopeDataGenerator;
+        } catch (CertificateEncodingException e) {
+            throw new HttpException("Failed to create envelope data 
generator", e);
+        }
+    }
+    
+    public static OutputEncryptor createEncryptor(String 
encryptionAlgorithmName) throws HttpException {
+        Args.notNull(encryptionAlgorithmName, "encryptionAlgorithmName");
+        try {
+            ASN1ObjectIdentifier algorithmOID = 
AS2Algorithm.getAS2Algorithm(encryptionAlgorithmName).getAlgorithmOID();
+            return new JceCMSContentEncryptorBuilder(algorithmOID).build();
+        } catch (CMSException e) {
+            throw new HttpException("Failed to create encryptor ", e);
+        }
+    }
+}
diff --git 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/SigningUtils.java
 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/SigningUtils.java
index ab608bb27c9..66aabda4cf8 100644
--- 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/SigningUtils.java
+++ 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/SigningUtils.java
@@ -24,6 +24,7 @@
 
 import org.apache.camel.component.as2.api.AS2SignedDataGenerator;
 import org.apache.http.HttpException;
+import org.apache.http.util.Args;
 import org.bouncycastle.asn1.ASN1EncodableVector;
 import org.bouncycastle.asn1.cms.AttributeTable;
 import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
@@ -43,7 +44,12 @@ private SigningUtils() {
     }
 
     public static AS2SignedDataGenerator createSigningGenerator(Certificate[] 
certificateChain, PrivateKey privateKey) throws HttpException {
-
+        Args.notNull(certificateChain, "certificateChain");
+        if (certificateChain.length == 0 || !(certificateChain[0] instanceof 
X509Certificate)) {
+            throw new IllegalArgumentException("Invalid certificate chain");
+        }
+        Args.notNull(privateKey, "privateKey");
+        
         AS2SignedDataGenerator gen = new AS2SignedDataGenerator();
 
         // Get first certificate in chain for signing
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 f17e7c45826..65684b77bff 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
@@ -270,7 +270,7 @@ public void plainEDIMessageTest() throws Exception {
 
         HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE, 
REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME,
                 AS2MessageStructure.PLAIN, 
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII),
-                null, null, null, DISPOSITION_NOTIFICATION_TO, 
SIGNED_RECEIPT_MIC_ALGORITHMS);
+                null, null, null, DISPOSITION_NOTIFICATION_TO, 
SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
 
         HttpRequest request = httpContext.getRequest();
         assertEquals("Unexpected method value", METHOD, 
request.getRequestLine().getMethod());
@@ -314,7 +314,66 @@ public void multipartSignedMessageTest() throws Exception {
         HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE, 
REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME,
                 AS2MessageStructure.SIGNED, 
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII),
                 null, certList.toArray(new Certificate[0]), 
signingKP.getPrivate(), DISPOSITION_NOTIFICATION_TO,
-                SIGNED_RECEIPT_MIC_ALGORITHMS);
+                SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
+
+        HttpRequest request = httpContext.getRequest();
+        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(AS2MediaType.MULTIPART_SIGNED));
+
+        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 
MultipartSignedEntity);
+        MultipartSignedEntity signedEntity = (MultipartSignedEntity) entity;
+        assertTrue("Entity not set as main body of request", 
signedEntity.isMainBody());
+        assertTrue("Request contains invalid number of mime parts", 
signedEntity.getPartCount() == 2);
+
+        // Validated first mime part.
+        assertTrue("First mime part incorrect type ", signedEntity.getPart(0) 
instanceof ApplicationEDIFACTEntity);
+        ApplicationEDIFACTEntity ediEntity = (ApplicationEDIFACTEntity) 
signedEntity.getPart(0);
+        assertTrue("Unexpected content type for first mime part",
+                
ediEntity.getContentType().getValue().startsWith(AS2MediaType.APPLICATION_EDIFACT));
+        assertFalse("First mime type set as main body of request", 
ediEntity.isMainBody());
+
+        // Validate second mime part.
+        assertTrue("Second mime part incorrect type ",
+                signedEntity.getPart(1) instanceof 
ApplicationPkcs7SignatureEntity);
+        ApplicationPkcs7SignatureEntity signatureEntity = 
(ApplicationPkcs7SignatureEntity) signedEntity.getPart(1);
+        assertTrue("Unexpected content type for second mime part",
+                
signatureEntity.getContentType().getValue().startsWith(AS2MediaType.APPLICATION_PKCS7_SIGNATURE));
+        assertFalse("First mime type set as main body of request", 
signatureEntity.isMainBody());
+
+    }
+
+//    @Test
+    public void envelopeddMessageTest() throws Exception {
+        AS2ClientConnection clientConnection = new 
AS2ClientConnection(AS2_VERSION, USER_AGENT, CLIENT_FQDN,
+                TARGET_HOST, TARGET_PORT);
+        AS2ClientManager clientManager = new 
AS2ClientManager(clientConnection);
+
+        HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE, 
REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME,
+                AS2MessageStructure.SIGNED, 
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII),
+                null, certList.toArray(new Certificate[0]), 
signingKP.getPrivate(), DISPOSITION_NOTIFICATION_TO,
+                SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
 
         HttpRequest request = httpContext.getRequest();
         assertEquals("Unexpected method value", METHOD, 
request.getRequestLine().getMethod());
@@ -373,7 +432,7 @@ public void signatureVerificationTest() throws Exception {
         HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE, 
REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME,
                 AS2MessageStructure.SIGNED, 
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII),
                 null, certList.toArray(new Certificate[0]), 
signingKP.getPrivate(), DISPOSITION_NOTIFICATION_TO,
-                SIGNED_RECEIPT_MIC_ALGORITHMS);
+                SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
 
         HttpRequest request = httpContext.getRequest();
         assertTrue("Request does not contain entity", request instanceof 
BasicHttpEntityEnclosingRequest);
@@ -401,7 +460,7 @@ public void mdnMessageTest() throws Exception {
 
         HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE, 
REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME,
                 AS2MessageStructure.PLAIN, 
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII),
-                null, null, null, DISPOSITION_NOTIFICATION_TO, 
SIGNED_RECEIPT_MIC_ALGORITHMS);
+                null, null, null, DISPOSITION_NOTIFICATION_TO, 
SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
 
         HttpResponse response = httpContext.getResponse();
         assertEquals("Unexpected method value", HttpVersion.HTTP_1_1, 
response.getStatusLine().getProtocolVersion());
diff --git 
a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/entity/EntityParserTest.java
 
b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/entity/EntityParserTest.java
index 306d9cdcfc4..cd47c82d9e0 100644
--- 
a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/entity/EntityParserTest.java
+++ 
b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/entity/EntityParserTest.java
@@ -17,7 +17,20 @@
 package org.apache.camel.component.as2.api.entity;
 
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
 
 import org.apache.camel.component.as2.api.AS2Header;
 import org.apache.camel.component.as2.api.io.AS2SessionInputBuffer;
@@ -31,6 +44,23 @@
 import org.apache.http.impl.EnglishReasonPhraseCatalog;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
 import org.apache.http.message.BasicHttpResponse;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.bc.BcX509ExtensionUtils;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
+import org.bouncycastle.cms.CMSAlgorithm;
+import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
+import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
+import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.OutputEncryptor;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -150,6 +180,11 @@
 
     private static final int DEFAULT_BUFFER_SIZE = 8 * 1024;
 
+    //
+    // certificate serial number seed.
+    //
+    int  serialNo = 1;
+
     @Before
     public void setUp() throws Exception {
     }
@@ -237,4 +272,89 @@ public void parseMessageDispositionNotificationBodyTest() 
throws Exception {
         assertEquals("Unexpected Digest Algorithm ID", 
EXPECTED_DIGEST_ALGORITHM_ID, 
messageDispositionNotificationEntity.getReceivedContentMic().getDigestAlgorithmId());
     }
 
+    @Test
+    public void parseEnvelopedBodyTest() 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 issuerCertificate = makeCertificate(issueKP, issueDN, 
issueKP, issueDN);
+
+        //
+        // certificate we encrypt against
+        //
+        String encryptDN = "CN=William J. Collins, E=punkhor...@gmail.com, 
O=Punkhorn Software, C=US";
+        KeyPair encryptKP = kpg.generateKeyPair();
+        X509Certificate encryptionCertificate = makeCertificate(encryptKP, 
encryptDN, issueKP, issueDN);
+
+        List<X509Certificate> certList = new ArrayList<>();
+
+        certList.add(encryptionCertificate);
+        certList.add(issuerCertificate);
+        
+        //
+        // Create generator
+        //
+        CMSEnvelopedDataGenerator cmsEnvelopeDataGenerator = new 
CMSEnvelopedDataGenerator();
+        
+        JceKeyTransRecipientInfoGenerator recipientInfoGenerator = new 
JceKeyTransRecipientInfoGenerator(encryptionCertificate);
+        
cmsEnvelopeDataGenerator.addRecipientInfoGenerator(recipientInfoGenerator);
+
+        //
+        // Create encryptor
+        //
+        OutputEncryptor contentEncryptor = new 
JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CCM).build();
+        
+        //
+        // Build Enveloped Entity
+        //
+        TextPlainEntity textEntity = new TextPlainEntity("This is a super 
secret messatge!", "US-ASCII", "7bit", false);
+        ApplicationPkcs7MimeEntity applicationPkcs7MimeEntity = new 
ApplicationPkcs7MimeEntity(textEntity, cmsEnvelopeDataGenerator, 
contentEncryptor, "binary", true);
+        
+        MimeEntity decryptedMimeEntity = 
applicationPkcs7MimeEntity.getEncryptedEntity(encryptKP.getPrivate());
+        assertEquals("Decrypted entity has unexpected content type", 
"text/plain; charset=US-ASCII", decryptedMimeEntity.getContentTypeValue());
+        assertEquals("Decrypted entity has unexpected content", "This is a 
super secret messatge!", ((TextPlainEntity)decryptedMimeEntity).getText());
+    }
+
+    /**
+     * create a basic X509 certificate from the given keys
+     */
+    private X509Certificate makeCertificate(KeyPair subKP, String subDN, 
KeyPair issKP, String issDN)
+            throws GeneralSecurityException, IOException, 
OperatorCreationException {
+        PublicKey subPub = subKP.getPublic();
+        PrivateKey issPriv = issKP.getPrivate();
+        PublicKey issPub = issKP.getPublic();
+
+        X509v3CertificateBuilder v3CertGen = new 
JcaX509v3CertificateBuilder(new X500Name(issDN),
+                BigInteger.valueOf(serialNo++), new 
Date(System.currentTimeMillis()),
+                new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 
100)), new X500Name(subDN), subPub);
+
+        v3CertGen.addExtension(Extension.subjectKeyIdentifier, false, 
createSubjectKeyId(subPub));
+
+        v3CertGen.addExtension(Extension.authorityKeyIdentifier, false, 
createAuthorityKeyId(issPub));
+
+        return new 
JcaX509CertificateConverter().setProvider("BC").getCertificate(
+                v3CertGen.build(new 
JcaContentSignerBuilder("MD5withRSA").setProvider("BC").build(issPriv)));
+    }
+
+    private AuthorityKeyIdentifier createAuthorityKeyId(PublicKey pub) throws 
IOException {
+        SubjectPublicKeyInfo info = 
SubjectPublicKeyInfo.getInstance(pub.getEncoded());
+
+        BcX509ExtensionUtils utils = new BcX509ExtensionUtils();
+        return utils.createAuthorityKeyIdentifier(info);
+    }
+
+    static SubjectKeyIdentifier createSubjectKeyId(PublicKey pub) throws 
IOException {
+        SubjectPublicKeyInfo info = 
SubjectPublicKeyInfo.getInstance(pub.getEncoded());
+
+        return new BcX509ExtensionUtils().createSubjectKeyIdentifier(info);
+    }
 }
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 4260d4032ee..565e8fa5326 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
@@ -70,7 +70,7 @@ with the following path and query parameters:
 |===
 
 
-==== Query Parameters (27 parameters):
+==== Query Parameters (30 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -84,6 +84,9 @@ with the following path and query parameters:
 | *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
+| *encryptingAlgorithmName* (common) | The name of algorithm used to encrypt 
EDI message. |  | String
+| *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
@@ -135,6 +138,9 @@ The component supports 25 options, which are listed below.
 | *camel.component.as2.configuration.signing-algorithm-name* | The name of 
algorithm used to sign EDI message. |  | String
 | *camel.component.as2.configuration.signing-certificate-chain* | The chain of 
certificates used to sign EDI message. |  | Certificate[]
 | *camel.component.as2.configuration.signing-private-key* | The key used to 
sign the EDI message. |  | PrivateKey
+| *camel.component.as2.configuration.encrypting-algorithm-name* | The name of 
algorithm used to encrypt EDI message. |  | String
+| *camel.component.as2.configuration.encrypting-certificate-chain* | The chain 
of certificates used to encrypt EDI message. |  | Certificate[]
+| *camel.component.as2.configuration.encrypting-private-key* | The key used to 
encrypt the EDI message. |  | PrivateKey
 | *camel.component.as2.configuration.subject* | The value of Subject header of 
AS2 message. |  | String
 | *camel.component.as2.configuration.target-hostname* | The host name (IP or 
DNS name) of target host. |  | String
 | *camel.component.as2.configuration.target-port-number* | The port number of 
target host. -1 indicates the scheme default port. |  | Integer
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 bcc6adcc091..b819c5a2041 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
@@ -105,6 +105,15 @@
     @UriParam
     private String[] signedReceiptMicAlgorithms;
 
+    @UriParam
+    private String encryptingAlgorithmName;
+
+    @UriParam
+    private Certificate[] encryptingCertificateChain;
+
+    @UriParam
+    private PrivateKey encryptingPrivateKey;
+
     public AS2ApiName getApiName() {
         return apiName;
     }
@@ -404,4 +413,36 @@ public void setSignedReceiptMicAlgorithms(String[] 
signedReceiptMicAlgorithms) {
         this.signedReceiptMicAlgorithms = signedReceiptMicAlgorithms;
     }
 
+    public String getEncryptingingAlgorithmName() {
+        return signingAlgorithmName;
+    }
+
+    /**
+     * The name of algorithm used to encrypt EDI message.
+     */
+    public void setEncryptingAlgorithmName(String signingAlgorithmName) {
+        this.encryptingAlgorithmName = signingAlgorithmName;
+    }
+
+    public Certificate[] getEncryptingCertificateChain() {
+        return encryptingCertificateChain;
+    }
+
+    /**
+     * The chain of certificates used to encrypt EDI message.
+     */
+    public void setEncryptingCertificateChain(Certificate[] 
signingCertificateChain) {
+        this.encryptingCertificateChain = signingCertificateChain;
+    }
+
+    public PrivateKey getEncryptingPrivateKey() {
+        return encryptingPrivateKey;
+    }
+
+    /**
+     * The key used to encrypt the EDI message.
+     */
+    public void setEncryptingPrivateKey(PrivateKey signingPrivateKey) {
+        this.encryptingPrivateKey = signingPrivateKey;
+    }
 }
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 e199217e04b..129310b2877 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
@@ -127,7 +127,7 @@ public void receivePlainEDIMessageTest() throws Exception {
 
         clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, 
AS2_NAME, AS2MessageStructure.PLAIN,
                 ContentType.create(AS2MediaType.APPLICATION_EDIFACT, 
AS2Charset.US_ASCII), null, null, null,
-                DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS);
+                DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, 
null, null, null);
 
         MockEndpoint mockEndpoint = getMockEndpoint("mock:as2RcvMsgs");
         mockEndpoint.expectedMinimumMessageCount(1);
@@ -185,7 +185,7 @@ public void receiveMultipartSignedMessageTest() throws 
Exception {
         clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, 
AS2_NAME, AS2MessageStructure.SIGNED,
                 ContentType.create(AS2MediaType.APPLICATION_EDIFACT, 
AS2Charset.US_ASCII), null,
                 certList.toArray(new Certificate[0]), signingKP.getPrivate(), 
DISPOSITION_NOTIFICATION_TO,
-                SIGNED_RECEIPT_MIC_ALGORITHMS);
+                SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
 
         MockEndpoint mockEndpoint = getMockEndpoint("mock:as2RcvMsgs");
         mockEndpoint.expectedMinimumMessageCount(1);
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 13c751ab70b..27ddc9ba898 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
@@ -176,6 +176,18 @@ public void setResolvePropertyPlaceholders(
          * notification (MDN)
          */
         private String[] signedReceiptMicAlgorithms;
+        /**
+         * The name of algorithm used to encrypt EDI message.
+         */
+        private String encryptingAlgorithmName;
+        /**
+         * The chain of certificates used to encrypt EDI message.
+         */
+        private Certificate[] encryptingCertificateChain;
+        /**
+         * The key used to encrypt the EDI message.
+         */
+        private PrivateKey encryptingPrivateKey;
 
         public AS2ApiName getApiName() {
             return apiName;
@@ -365,5 +377,30 @@ public void setSignedReceiptMicAlgorithms(
                 String[] signedReceiptMicAlgorithms) {
             this.signedReceiptMicAlgorithms = signedReceiptMicAlgorithms;
         }
+
+        public String getEncryptingAlgorithmName() {
+            return encryptingAlgorithmName;
+        }
+
+        public void setEncryptingAlgorithmName(String encryptingAlgorithmName) 
{
+            this.encryptingAlgorithmName = encryptingAlgorithmName;
+        }
+
+        public Certificate[] getEncryptingCertificateChain() {
+            return encryptingCertificateChain;
+        }
+
+        public void setEncryptingCertificateChain(
+                Certificate[] encryptingCertificateChain) {
+            this.encryptingCertificateChain = encryptingCertificateChain;
+        }
+
+        public PrivateKey getEncryptingPrivateKey() {
+            return encryptingPrivateKey;
+        }
+
+        public void setEncryptingPrivateKey(PrivateKey encryptingPrivateKey) {
+            this.encryptingPrivateKey = encryptingPrivateKey;
+        }
     }
 }
\ No newline at end of file


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


> Enhance the AS2 Component to send and receive encrypted AS2 messages
> --------------------------------------------------------------------
>
>                 Key: CAMEL-12605
>                 URL: https://issues.apache.org/jira/browse/CAMEL-12605
>             Project: Camel
>          Issue Type: Improvement
>    Affects Versions: 2.23.0
>            Reporter: William Collins
>            Assignee: William Collins
>            Priority: Major
>
> Enhance the AS2 Component to support encrypted AS2 messages per RFC4130



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to