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

acosentino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new fa87236  [CAMEL-12605] Integrated encryption logic into component.
fa87236 is described below

commit fa87236f78ea0682e64618b80f87e81acc3105f7
Author: William Collins <punkhor...@gmail.com>
AuthorDate: Tue Aug 28 11:59:25 2018 -0400

    [CAMEL-12605] Integrated encryption logic into component.
---
 .../camel/component/as2/api/AS2Algorithm.java      | 346 +++++++++++++++++++++
 .../camel/component/as2/api/AS2ClientManager.java  |  59 +++-
 .../as2/api/entity/ApplicationPkcs7MimeEntity.java |  10 -
 .../component/as2/api/util/EncryptingUtils.java    |  67 ++++
 .../camel/component/as2/api/util/SigningUtils.java |   8 +-
 .../camel/component/as2/api/AS2MessageTest.java    |  67 +++-
 .../component/as2/api/entity/EntityParserTest.java | 120 +++++++
 .../src/main/docs/as2-component.adoc               |   8 +-
 .../camel/component/as2/AS2Configuration.java      |  41 +++
 .../as2/AS2ServerManagerIntegrationTest.java       |   4 +-
 .../as2/springboot/AS2ComponentConfiguration.java  |  37 +++
 11 files changed, 739 insertions(+), 28 deletions(-)

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 0000000..8e71f47
--- /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 4e22e7b..9c33d9a 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.PrivateKey;
 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.entity.ContentType;
 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
@@ -135,6 +139,24 @@ public class AS2ClientManager {
     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 class AS2ClientManager {
      * @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 class AS2ClientManager {
                                 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 class AS2ClientManager {
         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 class AS2ClientManager {
             }
             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 class AS2ClientManager {
 
     }
 
-    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 b61b440..c1d6952 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 0000000..8e0c9b3
--- /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 ab608bb..66aabda 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 java.util.Arrays;
 
 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 @@ public final class 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 f17e7c4..65684b7 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 class AS2MessageTest {
 
         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 class AS2MessageTest {
         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 class AS2MessageTest {
         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 class AS2MessageTest {
 
         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 306d9cd..cd47c82 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.entity.BasicHttpEntity;
 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 @@ public class EntityParserTest {
 
     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 class EntityParserTest {
         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 4260d40..565e8fa 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 bcc6adc..b819c5a 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 @@ public class AS2Configuration {
     @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 class AS2Configuration {
         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 e199217..129310b 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 class AS2ServerManagerIntegrationTest extends 
AbstractAS2TestSupport {
 
         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 class AS2ServerManagerIntegrationTest extends 
AbstractAS2TestSupport {
         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 13c751a..27ddc9b 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 class AS2ComponentConfiguration
          * 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 class AS2ComponentConfiguration
                 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

Reply via email to