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 2233a6a  [CAMEL-12605] Added support for encrypted and signed AS2 
message
2233a6a is described below

commit 2233a6a98a7fc23de6e451390c11f40c5d9d59f5
Author: William Collins <punkhor...@gmail.com>
AuthorDate: Wed Sep 26 14:27:25 2018 -0400

    [CAMEL-12605] Added support for encrypted and signed AS2 message
---
 .../camel/component/as2/api/AS2ClientManager.java  |  37 ++++---
 .../component/as2/api/entity/EntityParser.java     |   2 +-
 .../as2/api/entity/MultipartMimeEntity.java        |   4 +
 .../as2/api/entity/MultipartSignedEntity.java      |   9 +-
 .../camel/component/as2/api/AS2MessageTest.java    | 116 +++++++++++++++++----
 5 files changed, 126 insertions(+), 42 deletions(-)

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 c99f341..5865efa 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
@@ -29,8 +29,10 @@ import org.apache.camel.component.as2.api.util.EntityUtils;
 import org.apache.camel.component.as2.api.util.SigningUtils;
 import org.apache.http.HttpException;
 import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
 import org.apache.http.entity.ContentType;
 import org.apache.http.message.BasicHttpEntityEnclosingRequest;
+import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.HttpCoreContext;
 import org.apache.http.util.Args;
 import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
@@ -252,31 +254,38 @@ public class AS2ClientManager {
             throw new HttpException("Failed to create EDI message entity", e);
         }
         switch (as2MessageStructure) {
-        case PLAIN:
+        case PLAIN: {
             applicationEDIEntity.setMainBody(true);
             EntityUtils.setMessageEntity(request, applicationEDIEntity);
             break;
-        case SIGNED:
+        }
+        case SIGNED: {
             AS2SignedDataGenerator gen = createSigningGenerator(httpContext);
             // Create Multipart Signed Entity
-            try {
-                MultipartSignedEntity multipartSignedEntity = new 
MultipartSignedEntity(applicationEDIEntity, gen,
-                        AS2Charset.US_ASCII, AS2TransferEncoding.BASE64, true, 
null);
-                multipartSignedEntity.setMainBody(true);
-                EntityUtils.setMessageEntity(request, multipartSignedEntity);
-            } catch (Exception e) {
-                throw new HttpException("Failed to sign message", e);
-            }
+            MultipartSignedEntity multipartSignedEntity = new 
MultipartSignedEntity(applicationEDIEntity, gen,
+                    AS2Charset.US_ASCII, AS2TransferEncoding.BASE64, true, 
null);
+            multipartSignedEntity.setMainBody(true);
+            EntityUtils.setMessageEntity(request, multipartSignedEntity);
             break;
-        case ENCRYPTED:
+        }
+        case ENCRYPTED: {
             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.
+        }
+        case ENCRYPTED_SIGNED: {
+            AS2SignedDataGenerator signingGenrator = 
createSigningGenerator(httpContext);
+            MultipartSignedEntity multipartSignedEntity = new 
MultipartSignedEntity(applicationEDIEntity,
+                    signingGenrator, AS2Charset.US_ASCII, 
AS2TransferEncoding.BASE64, false, null);
+             
+            CMSEnvelopedDataGenerator envelopedDataGenerator = 
createEncryptingGenerator(httpContext);
+            OutputEncryptor encryptor = createEncryptor(httpContext);
+            ApplicationPkcs7MimeEntity pkcs7MimeEntity = new 
ApplicationPkcs7MimeEntity(multipartSignedEntity, envelopedDataGenerator, 
encryptor, AS2TransferEncoding.BASE64, true);
+            EntityUtils.setMessageEntity(request, pkcs7MimeEntity);
             break;
+        }
         default:
             throw new HttpException("Unknown AS2 Message Structure");
         }
@@ -292,7 +301,7 @@ public class AS2ClientManager {
         httpContext.setAttribute(HTTP_RESPONSE, response);
         return httpContext;
     }
-
+    
     public AS2SignedDataGenerator createSigningGenerator(HttpCoreContext 
httpContext) throws HttpException {
 
         Certificate[] certificateChain = 
httpContext.getAttribute(SIGNING_CERTIFICATE_CHAIN, Certificate[].class);
diff --git 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/EntityParser.java
 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/EntityParser.java
index fcb2431..aaf12e8 100644
--- 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/EntityParser.java
+++ 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/EntityParser.java
@@ -171,7 +171,7 @@ public final class EntityParser {
             throw new HttpException("Failed to read start boundary for body 
part", e);
         }
 
-        if (!foundEndBoundary) {
+        if (!foundEndBoundary && boundary != null) {
             throw new HttpException("Failed to find start boundary for body 
part");
         }
 
diff --git 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/MultipartMimeEntity.java
 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/MultipartMimeEntity.java
index 2b206f3..03f5835 100644
--- 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/MultipartMimeEntity.java
+++ 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/MultipartMimeEntity.java
@@ -55,6 +55,10 @@ public abstract class MultipartMimeEntity extends MimeEntity 
{
 
     protected MultipartMimeEntity() {
     }
+    
+    public String getBoundary() {
+        return boundary;
+    }
 
     public void addPart(MimeEntity part) {
         parts.add(part);
diff --git 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/MultipartSignedEntity.java
 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/MultipartSignedEntity.java
index 6869b5f..3b0a6d2 100644
--- 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/MultipartSignedEntity.java
+++ 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/MultipartSignedEntity.java
@@ -22,10 +22,8 @@ import java.io.InputStream;
 import java.security.cert.X509Certificate;
 import java.util.Collection;
 
-import org.apache.camel.component.as2.api.AS2Header;
 import org.apache.camel.component.as2.api.AS2SignedDataGenerator;
-import org.apache.http.entity.ContentType;
-import org.apache.http.message.BasicHeader;
+import org.apache.http.HttpException;
 import org.bouncycastle.cert.X509CertificateHolder;
 import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
 import org.bouncycastle.cms.CMSProcessable;
@@ -38,10 +36,9 @@ import org.bouncycastle.util.Store;
 
 public class MultipartSignedEntity extends MultipartMimeEntity {
 
-    public MultipartSignedEntity(MimeEntity data, AS2SignedDataGenerator 
signer, String signatureCharSet, String signatureTransferEncoding, boolean 
isMainBody, String boundary) throws Exception {
+    public MultipartSignedEntity(MimeEntity data, AS2SignedDataGenerator 
signer, String signatureCharSet, String signatureTransferEncoding, boolean 
isMainBody, String boundary) throws HttpException {
         super(null, isMainBody, boundary);
-        ContentType contentType = 
signer.createMultipartSignedContentType(this.boundary);
-        this.contentType = new BasicHeader(AS2Header.CONTENT_TYPE, 
contentType.toString());
+        setContentType(signer.createMultipartSignedContentType(this.boundary));
         addPart(data);
         ApplicationPkcs7SignatureEntity signature = new 
ApplicationPkcs7SignatureEntity(data, signer, signatureCharSet, 
signatureTransferEncoding, false);
         addPart(signature);
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 d9d3338..7d181aa 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
@@ -366,105 +366,105 @@ public class AS2MessageTest {
 
     @Test
     public void aes128CbcEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.AES128_CBC);
+        envelopedMessageTest(AS2EncryptionAlgorithm.AES128_CBC);
     }
     
     @Test
     public void aes192CbcEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.AES192_CBC);
+        envelopedMessageTest(AS2EncryptionAlgorithm.AES192_CBC);
     }
     
     @Test
     public void aes256CbcEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.AES256_CBC);
+        envelopedMessageTest(AS2EncryptionAlgorithm.AES256_CBC);
     }
     
     @Test
     public void aes128CcmEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.AES128_CCM);
+        envelopedMessageTest(AS2EncryptionAlgorithm.AES128_CCM);
     }
     
     @Test
     public void aes192CcmEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.AES192_CCM);
+        envelopedMessageTest(AS2EncryptionAlgorithm.AES192_CCM);
     }
     
     @Test
     public void aes256CcmEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.AES256_CCM);
+        envelopedMessageTest(AS2EncryptionAlgorithm.AES256_CCM);
     }
     
     @Test
     public void aes128GcmEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.AES128_GCM);
+        envelopedMessageTest(AS2EncryptionAlgorithm.AES128_GCM);
     }
     
     @Test
     public void aes192GcmEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.AES192_GCM);
+        envelopedMessageTest(AS2EncryptionAlgorithm.AES192_GCM);
     }
     
     @Test
     public void aes256GcmEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.AES256_GCM);
+        envelopedMessageTest(AS2EncryptionAlgorithm.AES256_GCM);
     }
     
     @Test
     public void camellia128CbcEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.CAMELLIA128_CBC);
+        envelopedMessageTest(AS2EncryptionAlgorithm.CAMELLIA128_CBC);
     }
     
     @Test
     public void camellia192CbcEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.CAMELLIA192_CBC);
+        envelopedMessageTest(AS2EncryptionAlgorithm.CAMELLIA192_CBC);
     }
     
     @Test
     public void camellia256CbcEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.CAMELLIA256_CBC);
+        envelopedMessageTest(AS2EncryptionAlgorithm.CAMELLIA256_CBC);
     }
     
     @Test
     public void cast5CbcEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.CAST5_CBC);
+        envelopedMessageTest(AS2EncryptionAlgorithm.CAST5_CBC);
     }
     
     @Test
     public void desCbcEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.DES_CBC);
+        envelopedMessageTest(AS2EncryptionAlgorithm.DES_CBC);
     }
     
     @Test
     public void desEde3CbcEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.DES_EDE3_CBC);
+        envelopedMessageTest(AS2EncryptionAlgorithm.DES_EDE3_CBC);
     }
     
     @Test
     public void cost28147GcfbEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.GOST28147_GCFB);
+        envelopedMessageTest(AS2EncryptionAlgorithm.GOST28147_GCFB);
     }
     
     @Test
     public void ideaCbcEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.IDEA_CBC);
+        envelopedMessageTest(AS2EncryptionAlgorithm.IDEA_CBC);
     }
     
     @Test
     public void rc2CbcEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.RC2_CBC);
+        envelopedMessageTest(AS2EncryptionAlgorithm.RC2_CBC);
     }
     
     @Test
     public void rc4EnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.RC4);
+        envelopedMessageTest(AS2EncryptionAlgorithm.RC4);
     }
     
     @Test
     public void seedCbcEnvelopedMessageTest() throws Exception {
-        envelopeddMessageTest(AS2EncryptionAlgorithm.SEED_CBC);
+        envelopedMessageTest(AS2EncryptionAlgorithm.SEED_CBC);
     }
 
-    public void envelopeddMessageTest(AS2EncryptionAlgorithm 
encryptionAlgorithm) throws Exception {
+    public void envelopedMessageTest(AS2EncryptionAlgorithm 
encryptionAlgorithm) throws Exception {
         AS2ClientConnection clientConnection = new 
AS2ClientConnection(AS2_VERSION, USER_AGENT, CLIENT_FQDN,
                 TARGET_HOST, TARGET_PORT);
         AS2ClientManager clientManager = new 
AS2ClientManager(clientConnection);
@@ -520,6 +520,80 @@ public class AS2MessageTest {
     }
 
     @Test
+    public void aes128CbcEnvelopedAndSignedMessageTest() throws Exception {
+        envelopedAndSignedMessageTest(AS2EncryptionAlgorithm.AES128_CBC);
+    }
+    
+    public void envelopedAndSignedMessageTest(AS2EncryptionAlgorithm 
encryptionAlgorithm) throws Exception {
+        AS2ClientConnection clientConnection = new 
AS2ClientConnection(AS2_VERSION, USER_AGENT, CLIENT_FQDN,
+                TARGET_HOST, TARGET_PORT);
+        AS2ClientManager clientManager = new 
AS2ClientManager(clientConnection);
+        
+        LOG.info("Key Algoritm: " + signingKP.getPrivate().getAlgorithm());
+
+        HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE, 
REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME,
+                AS2MessageStructure.ENCRYPTED_SIGNED, 
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII),
+                null, certList.toArray(new Certificate[0]), 
signingKP.getPrivate(), DISPOSITION_NOTIFICATION_TO,
+                SIGNED_RECEIPT_MIC_ALGORITHMS, encryptionAlgorithm, 
certList.toArray(new Certificate[0]),
+                signingKP.getPrivate());
+
+        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(AS2MimeType.APPLICATION_PKCS7_MIME));
+
+        assertTrue("Request does not contain entity", request instanceof 
BasicHttpEntityEnclosingRequest);
+        HttpEntity entity = ((BasicHttpEntityEnclosingRequest) 
request).getEntity();
+        assertNotNull("Request does not contain entity", entity);
+        assertTrue("Unexpected request entity type", entity instanceof 
ApplicationPkcs7MimeEntity);
+        ApplicationPkcs7MimeEntity envelopedEntity = 
(ApplicationPkcs7MimeEntity) entity;
+        assertTrue("Entity not set as main body of request", 
envelopedEntity.isMainBody());
+
+        // Validated enveloped part.
+        MimeEntity encryptedEntity = 
envelopedEntity.getEncryptedEntity(signingKP.getPrivate());
+        assertTrue("Enveloped mime part incorrect type ", encryptedEntity 
instanceof MultipartSignedEntity);
+        MultipartSignedEntity multipartSignedEntity = (MultipartSignedEntity) 
encryptedEntity;
+        assertTrue("Unexpected content type for enveloped mime part",
+                
multipartSignedEntity.getContentType().getValue().startsWith(AS2MediaType.MULTIPART_SIGNED));
+        assertFalse("Enveloped mime type set as main body of request", 
multipartSignedEntity.isMainBody());
+        assertTrue("Request contains invalid number of mime parts", 
multipartSignedEntity.getPartCount() == 2);
+
+        // Validated first mime part.
+        assertTrue("First mime part incorrect type ", 
multipartSignedEntity.getPart(0) instanceof ApplicationEDIFACTEntity);
+        ApplicationEDIFACTEntity ediEntity = (ApplicationEDIFACTEntity) 
multipartSignedEntity.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 ",
+                multipartSignedEntity.getPart(1) instanceof 
ApplicationPkcs7SignatureEntity);
+        ApplicationPkcs7SignatureEntity signatureEntity = 
(ApplicationPkcs7SignatureEntity) multipartSignedEntity.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 signatureVerificationTest() throws Exception {
         AS2ClientConnection clientConnection = new 
AS2ClientConnection(AS2_VERSION, USER_AGENT, CLIENT_FQDN,
                 TARGET_HOST, TARGET_PORT);

Reply via email to