You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2018/12/05 11:32:07 UTC
[camel] 01/15: [CAMEL-12605] Added support for compression
This is an automated email from the ASF dual-hosted git repository.
acosentino pushed a commit to branch sandbox/camel-3.x
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 73ec6892b72a56d4823eba08b2a884b3ef7a4d5d
Author: William Collins <pu...@gmail.com>
AuthorDate: Mon Nov 26 16:03:27 2018 -0500
[CAMEL-12605] Added support for compression
---
... ApplicationPkcs7MimeCompressedDataEntity.java} | 57 +++++++-------
.../as2/api/entity/ApplicationPkcs7MimeEntity.java | 2 +-
.../component/as2/api/entity/EntityParser.java | 87 ++++++++++++++-------
.../as2/api/entity/CompressedEntityTest.java | 89 ++++++++++++++++++++++
4 files changed, 176 insertions(+), 59 deletions(-)
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/ApplicationPkcs7MimeCompressedDataEntity.java
similarity index 64%
copy from components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationPkcs7MimeEntity.java
copy to components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationPkcs7MimeCompressedDataEntity.java
index c1d6952..7a88761 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/ApplicationPkcs7MimeCompressedDataEntity.java
@@ -19,7 +19,6 @@ package org.apache.camel.component.as2.api.entity;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
-import java.security.PrivateKey;
import org.apache.camel.component.as2.api.AS2Charset;
import org.apache.camel.component.as2.api.AS2Header;
@@ -31,42 +30,43 @@ import org.apache.http.HttpException;
import org.apache.http.entity.ContentType;
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.CMSCompressedData;
+import org.bouncycastle.cms.CMSCompressedDataGenerator;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSTypedData;
-import org.bouncycastle.operator.OutputEncryptor;
+import org.bouncycastle.operator.InputExpanderProvider;
+import org.bouncycastle.operator.OutputCompressor;
-public class ApplicationPkcs7MimeEntity extends MimeEntity {
+public class ApplicationPkcs7MimeCompressedDataEntity extends MimeEntity {
- private static final String CONTENT_DISPOSITION = "attachment; filename=\"smime.p7m\"";
+ private static final String CONTENT_DISPOSITION = "attachment; filename=\"smime.p7z\"";
- private byte[] encryptedData;
+ private byte[] compressedData;
- public ApplicationPkcs7MimeEntity(MimeEntity entity2Encrypt,
- CMSEnvelopedDataGenerator dataGenerator,
- OutputEncryptor encryptor,
- String encryptedContentTransferEncoding,
- boolean isMainBody)
+ public ApplicationPkcs7MimeCompressedDataEntity(MimeEntity entity2Encrypt,
+ CMSCompressedDataGenerator dataGenerator,
+ OutputCompressor compressor,
+ String compressedContentTransferEncoding,
+ boolean isMainBody)
throws HttpException {
- setContentType(ContentType.create("application/pkcs7-mime", new BasicNameValuePair("smime-type", "enveloped-data"),
- new BasicNameValuePair("name", "smime.p7m")));
- setContentTransferEncoding(encryptedContentTransferEncoding);
+ setContentType(ContentType.create("application/pkcs7-mime", new BasicNameValuePair("smime-type", "compressed-data"),
+ new BasicNameValuePair("name", "smime.p7z")));
+ setContentTransferEncoding(compressedContentTransferEncoding);
addHeader(AS2Header.CONTENT_DISPOSITION, CONTENT_DISPOSITION);
setMainBody(isMainBody);
try {
- this.encryptedData = createEncryptedData(entity2Encrypt, dataGenerator, encryptor);
+ this.compressedData = createCompressedData(entity2Encrypt, dataGenerator, compressor);
} catch (Exception e) {
throw new HttpException("Failed to create encrypted data");
}
}
- public ApplicationPkcs7MimeEntity(byte[] encryptedData, String encryptedContentTransferEncoding, boolean isMainBody) {
- this.encryptedData = Args.notNull(encryptedData, "encryptedData");
+ public ApplicationPkcs7MimeCompressedDataEntity(byte[] compressedData, String compressedContentTransferEncoding, boolean isMainBody) {
+ this.compressedData = Args.notNull(compressedData, "encryptedData");
- setContentType(ContentType.create("application/pkcs7-mime", new BasicNameValuePair("smime-type", "enveloped-datat"),
- new BasicNameValuePair("name", "smime.p7m")));
- setContentTransferEncoding(encryptedContentTransferEncoding);
+ setContentType(ContentType.create("application/pkcs7-mime", new BasicNameValuePair("smime-type", "compressed-datat"),
+ new BasicNameValuePair("name", "smime.p7z")));
+ setContentTransferEncoding(compressedContentTransferEncoding);
addHeader(AS2Header.CONTENT_DISPOSITION, CONTENT_DISPOSITION);
setMainBody(isMainBody);
}
@@ -94,27 +94,24 @@ public class ApplicationPkcs7MimeEntity extends MimeEntity {
String transferEncoding = getContentTransferEncoding() == null ? null : getContentTransferEncoding().getValue();
try (OutputStream transferEncodedStream = EntityUtils.encode(ncos, transferEncoding)) {
- transferEncodedStream.write(encryptedData);
+ transferEncodedStream.write(compressedData);
} catch (Exception e) {
throw new IOException("Failed to write to output stream", e);
}
}
- public MimeEntity getEncryptedEntity(PrivateKey privateKey) {
-
- return EntityParser.parseEnvelopedEntity(encryptedData, privateKey);
-
-
+ public MimeEntity getCompressedEntity(InputExpanderProvider expanderProvider) throws HttpException {
+ return EntityParser.parseCompressedEntity(compressedData, expanderProvider);
}
- private byte[] createEncryptedData(MimeEntity entity2Encrypt, CMSEnvelopedDataGenerator envelopedDataGenerator, OutputEncryptor encryptor) throws Exception {
+ private byte[] createCompressedData(MimeEntity entity2Encrypt, CMSCompressedDataGenerator compressedDataGenerator, OutputCompressor compressor) throws Exception {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
entity2Encrypt.writeTo(bos);
bos.flush();
CMSTypedData contentData = new CMSProcessableByteArray(bos.toByteArray());
- CMSEnvelopedData envelopedData = envelopedDataGenerator.generate(contentData, encryptor);
- return envelopedData.getEncoded();
+ CMSCompressedData compressedData = compressedDataGenerator.generate(contentData, compressor);
+ return compressedData.getEncoded();
} catch (Exception e) {
throw new Exception("", e);
}
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 c1d6952..5487055 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
@@ -100,7 +100,7 @@ public class ApplicationPkcs7MimeEntity extends MimeEntity {
}
}
- public MimeEntity getEncryptedEntity(PrivateKey privateKey) {
+ public MimeEntity getEncryptedEntity(PrivateKey privateKey) throws HttpException {
return EntityParser.parseEnvelopedEntity(encryptedData, privateKey);
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 aaf12e8..4d8a2b2 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
@@ -51,11 +51,14 @@ import org.apache.http.message.LineParser;
import org.apache.http.message.ParserCursor;
import org.apache.http.util.Args;
import org.apache.http.util.CharArrayBuffer;
+import org.bouncycastle.cms.CMSCompressedData;
import org.bouncycastle.cms.CMSEnvelopedData;
+import org.bouncycastle.cms.CMSException;
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.InputExpanderProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -177,12 +180,26 @@ public final class EntityParser {
}
- public static MimeEntity parseEnvelopedEntity(byte[] envelopedContent, PrivateKey privateKey) {
+ public static MimeEntity parseCompressedEntity(byte[] compressedData, InputExpanderProvider expanderProvider)
+ throws HttpException {
+
+ byte[] uncompressedContent = uncompressData(compressedData, expanderProvider);
+
+ return parseEntity(uncompressedContent);
+ }
+
+ public static MimeEntity parseEnvelopedEntity(byte[] envelopedContent, PrivateKey privateKey) throws HttpException {
+
+ byte[] decryptedContent = decryptData(envelopedContent, privateKey);
+
+ return parseEntity(decryptedContent);
+ }
+
+ public static MimeEntity parseEntity(byte[] content) throws HttpException {
try {
- byte[] decryptedContent = decryptData(envelopedContent, privateKey);
- InputStream is = new ByteArrayInputStream(decryptedContent);
+ InputStream is = new ByteArrayInputStream(content);
AS2SessionInputBuffer inbuffer = new AS2SessionInputBuffer(new HttpTransportMetricsImpl(), DEFAULT_BUFFER_SIZE);
inbuffer.bind(is);
@@ -191,54 +208,68 @@ public final class EntityParser {
new ArrayList<CharArrayBuffer>());
// Get Content-Type and Content-Transfer-Encoding
- ContentType envelopedEntityContentType = null;
- String envelopedEntityContentTransferEncoding = null;
+ ContentType entityContentType = null;
+ String entityContentTransferEncoding = null;
for (Header header : headers) {
switch (header.getName()) {
case AS2Header.CONTENT_TYPE:
- envelopedEntityContentType = ContentType.parse(header.getValue());
+ entityContentType = ContentType.parse(header.getValue());
break;
case AS2Header.CONTENT_TRANSFER_ENCODING:
- envelopedEntityContentTransferEncoding = header.getValue();
+ entityContentTransferEncoding = header.getValue();
break;
default:
continue;
}
}
- if (envelopedEntityContentType == null) {
+ if (entityContentType == null) {
throw new HttpException("Failed to find Content-Type header in enveloped entity");
}
- MimeEntity entity = parseEntityBody(inbuffer, null, envelopedEntityContentType, envelopedEntityContentTransferEncoding, headers);
+ MimeEntity entity = parseEntityBody(inbuffer, null, entityContentType, entityContentTransferEncoding, headers);
entity.removeAllHeaders();
entity.setHeaders(headers);
return entity;
} catch (Exception e) {
- return null;
+ throw new HttpException("Failed to parse entity", e);
}
}
- public static byte[] decryptData(byte[] encryptedData, PrivateKey privateKey) throws Exception {
- // Create enveloped data from encrypted data
- CMSEnvelopedData cmsEnvelopedData = new CMSEnvelopedData(encryptedData);
-
- // Extract recipient information form enveloped data.
- RecipientInformationStore recipientsInformationStore = cmsEnvelopedData.getRecipientInfos();
- Collection<RecipientInformation> recipients = recipientsInformationStore.getRecipients();
- Iterator<RecipientInformation> it = recipients.iterator();
-
- // Decrypt if enveloped data contains recipient information
- if (it.hasNext()) {
- // Create recipient from private key.
- Recipient recipient = new JceKeyTransEnvelopedRecipient(privateKey);
-
- // Extract decrypted data from recipient information
- RecipientInformation recipientInfo = it.next();
- return recipientInfo.getContent(recipient);
+ public static byte[] uncompressData(byte[] compressedData, InputExpanderProvider expanderProvider)
+ throws HttpException {
+ try {
+ CMSCompressedData cmsCompressedData = new CMSCompressedData(compressedData);
+ return cmsCompressedData.getContent(expanderProvider);
+ } catch (CMSException e) {
+ throw new HttpException("Failed to decompress data", e);
+ }
+ }
+
+ public static byte[] decryptData(byte[] encryptedData, PrivateKey privateKey) throws HttpException {
+ try {
+ // Create enveloped data from encrypted data
+ CMSEnvelopedData cmsEnvelopedData = new CMSEnvelopedData(encryptedData);
+
+ // Extract recipient information form enveloped data.
+ RecipientInformationStore recipientsInformationStore = cmsEnvelopedData.getRecipientInfos();
+ Collection<RecipientInformation> recipients = recipientsInformationStore.getRecipients();
+ Iterator<RecipientInformation> it = recipients.iterator();
+
+ // Decrypt if enveloped data contains recipient information
+ if (it.hasNext()) {
+ // Create recipient from private key.
+ Recipient recipient = new JceKeyTransEnvelopedRecipient(privateKey);
+
+ // Extract decrypted data from recipient information
+ RecipientInformation recipientInfo = it.next();
+ return recipientInfo.getContent(recipient);
+ }
+ } catch (CMSException e) {
+ throw new HttpException("Failed to decrypt data", e);
}
- return null;
+ throw new HttpException("Failed to decrypt data: bno recipeint information");
}
public static void parseMultipartSignedEntity(HttpMessage message)
diff --git a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/entity/CompressedEntityTest.java b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/entity/CompressedEntityTest.java
new file mode 100644
index 0000000..dc549e9
--- /dev/null
+++ b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/entity/CompressedEntityTest.java
@@ -0,0 +1,89 @@
+/**
+ * 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.entity;
+
+import org.bouncycastle.cms.CMSCompressedDataGenerator;
+import org.bouncycastle.cms.jcajce.ZlibCompressor;
+import org.bouncycastle.cms.jcajce.ZlibExpanderProvider;
+import org.bouncycastle.operator.OutputCompressor;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class CompressedEntityTest {
+
+ public static final String TEXT_PLAIN_CONTENT =
+ "MDN for -\r\n"
+ + " Message ID: <200207310834482A70BF63@\\\"~~foo~~\\\">\r\n"
+ + " From: \"\\\" as2Name \\\"\"\r\n"
+ + " To: \"0123456780000\""
+ + " Received on: 2002-07-31 at 09:34:14 (EDT)\r\n"
+ + " Status: processed\r\n"
+ + " Comment: This is not a guarantee that the message has\r\n"
+ + " been completely processed or &understood by the receiving\r\n"
+ + " translator\r\n"
+ + "\r\n";
+
+ public static final String TEXT_PLAIN_CONTENT_CHARSET_NAME = "US-ASCII";
+
+ public static final String TEXT_PLAIN_CONTENT_TRANSFER_ENCODING = "7bit";
+
+ public static final String EXPECTED_TEXT_PLAIN_CONTENT =
+ "MDN for -\r\n"
+ + " Message ID: <200207310834482A70BF63@\\\"~~foo~~\\\">\r\n"
+ + " From: \"\\\" as2Name \\\"\"\r\n"
+ + " To: \"0123456780000\""
+ + " Received on: 2002-07-31 at 09:34:14 (EDT)\r\n"
+ + " Status: processed\r\n"
+ + " Comment: This is not a guarantee that the message has\r\n"
+ + " been completely processed or &understood by the receiving\r\n"
+ + " translator\r\n"
+ + "\r\n";
+
+
+ public static final String APPLICATION_PKCS7_MIME_COMPRESSED_TRANSFER_ENCODING = "base64";
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void createCompressedEntityTest() throws Exception {
+ TextPlainEntity textPlainEntity = new TextPlainEntity(TEXT_PLAIN_CONTENT, TEXT_PLAIN_CONTENT_CHARSET_NAME,
+ TEXT_PLAIN_CONTENT_TRANSFER_ENCODING, false);
+
+ CMSCompressedDataGenerator cGen = new CMSCompressedDataGenerator();
+
+ OutputCompressor compressor = new ZlibCompressor();
+
+ ApplicationPkcs7MimeCompressedDataEntity compressedEntity = new ApplicationPkcs7MimeCompressedDataEntity(
+ textPlainEntity, cGen, compressor, APPLICATION_PKCS7_MIME_COMPRESSED_TRANSFER_ENCODING, false);
+
+ MimeEntity decompressedEntity = compressedEntity.getCompressedEntity(new ZlibExpanderProvider());
+ assertTrue("", decompressedEntity instanceof TextPlainEntity);
+ TextPlainEntity decompressedTextPlainEntity = (TextPlainEntity) decompressedEntity;
+ assertEquals("", EXPECTED_TEXT_PLAIN_CONTENT, decompressedTextPlainEntity.getText());
+ }
+
+}