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/12 14:04:57 UTC
[camel] branch master updated: [CAMEL-12605] Refactoring and fixed
issue of receipt for compressed message
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 21410db [CAMEL-12605] Refactoring and fixed issue of receipt for compressed message
21410db is described below
commit 21410db6e446757e84c0564fe798a8f05d609f0f
Author: William Collins <pu...@gmail.com>
AuthorDate: Tue Dec 11 13:16:18 2018 -0500
[CAMEL-12605] Refactoring and fixed issue of receipt for compressed message
---
.../camel/component/as2/api/AS2ClientManager.java | 18 +-
.../component/as2/api/entity/EntityParser.java | 351 ++++++++++++++-------
.../camel/component/as2/api/util/EntityUtils.java | 7 +
.../camel/component/as2/api/util/MicUtils.java | 31 +-
.../camel/component/as2/api/util/SigningUtils.java | 14 -
.../camel/component/as2/api/AS2MessageTest.java | 25 +-
.../component/as2/api/entity/EntityParserTest.java | 2 +-
components/camel-as2/camel-as2-component/pom.xml | 16 +
.../as2/AS2ClientManagerIntegrationTest.java | 116 +++++--
.../as2/AS2ServerManagerIntegrationTest.java | 4 +-
10 files changed, 384 insertions(+), 200 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 5f7ce3b..e6d8a4b 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
@@ -155,12 +155,6 @@ public class AS2ClientManager {
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 algorithm used to compress EDI
* message
*/
@@ -203,11 +197,11 @@ public class AS2ClientManager {
* @param signingAlgorithm - the algorithm used to sign the message or <code>null</code> if sending EDI message unsigned
* @param signingCertificateChain - the chain of certificates used to sign the message or <code>null</code> if sending EDI message unsigned
* @param signingPrivateKey - the private key used to sign EDI message
+ * @param compressionAlgorithm - the algorithm used to compress the message or <code>null</code> if sending EDI message uncompressed
* @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 encryptingAlgorithm - the algorithm used to encrypt the message or <code>null</code> if sending EDI message unencrypted
* @param encryptingCertificateChain - the chain of certificates used to encrypt the message or <code>null</code> if sending EDI message unencrypted
- * @param encryptingPrivateKey - 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.
*/
@@ -227,13 +221,16 @@ public class AS2ClientManager {
String dispositionNotificationTo,
String[] signedReceiptMicAlgorithms,
AS2EncryptionAlgorithm encryptingAlgorithm,
- Certificate[] encryptingCertificateChain,
- PrivateKey encryptingPrivateKey)
+ Certificate[] encryptingCertificateChain)
throws HttpException {
Args.notNull(ediMessage, "EDI Message");
- Args.notNull(as2MessageStructure, "AS2 Message Structure");
Args.notNull(requestUri, "Request URI");
+ Args.notNull(subject, "Subject");
+ Args.notNull(from, "Subject");
+ Args.notNull(as2From, "Subject");
+ Args.notNull(as2To, "Subject");
+ Args.notNull(as2MessageStructure, "AS2 Message Structure");
Args.notNull(ediMessageContentType, "EDI Message Content Type");
// Add Context attributes
@@ -254,7 +251,6 @@ public class AS2ClientManager {
httpContext.setAttribute(AS2ClientManager.SIGNED_RECEIPT_MIC_ALGORITHMS, signedReceiptMicAlgorithms);
httpContext.setAttribute(AS2ClientManager.ENCRYPTING_ALGORITHM, encryptingAlgorithm);
httpContext.setAttribute(AS2ClientManager.ENCRYPTING_CERTIFICATE_CHAIN, encryptingCertificateChain);
- httpContext.setAttribute(AS2ClientManager.ENCRYPTING_PRIVATE_KEY, encryptingPrivateKey);
BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", requestUri);
httpContext.setAttribute(HTTP_REQUEST, request);
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 f97b0ae..eb45639 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
@@ -38,6 +38,7 @@ import org.apache.camel.component.as2.api.util.EntityUtils;
import org.apache.camel.component.as2.api.util.HttpMessageUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
+import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpMessage;
import org.apache.http.NameValuePair;
@@ -58,19 +59,13 @@ import org.bouncycastle.cms.Recipient;
import org.bouncycastle.cms.RecipientInformation;
import org.bouncycastle.cms.RecipientInformationStore;
import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
+import org.bouncycastle.cms.jcajce.ZlibExpanderProvider;
import org.bouncycastle.operator.InputExpanderProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
public final class EntityParser {
- private static final Logger LOG = LoggerFactory.getLogger(EntityParser.class);
-
private static final int DEFAULT_BUFFER_SIZE = 8 * 1024;
- private static final String APPLICATION_EDI_CONTENT_TYPE_PREFIX = "application/edi";
-
-
private EntityParser() {
}
@@ -185,8 +180,6 @@ public final class EntityParser {
byte[] uncompressedContent = uncompressData(compressedData, expanderProvider);
- String uncompressedContentString = new String(uncompressedContent);
-
return parseEntity(uncompressedContent);
}
@@ -200,7 +193,6 @@ public final class EntityParser {
public static MimeEntity parseEntity(byte[] content) throws HttpException {
try {
- String contentString = new String(content);
InputStream is = new ByteArrayInputStream(content);
AS2SessionInputBuffer inbuffer = new AS2SessionInputBuffer(new HttpTransportMetricsImpl(), DEFAULT_BUFFER_SIZE);
inbuffer.bind(is);
@@ -274,55 +266,87 @@ public final class EntityParser {
throw new HttpException("Failed to decrypt data: bno recipeint information");
}
- public static void parseMultipartSignedEntity(HttpMessage message)
- throws HttpException {
- MultipartSignedEntity multipartSignedEntity = null;
+ private static void parseApplicationPkcs7MimeCompressedEntity(HttpMessage message, AS2SessionInputBuffer inBuffer, ContentType contentType, String contentTransferEncoding) throws HttpException {
+ ApplicationPkcs7MimeCompressedDataEntity applicationPkcs7MimeCompressedDataEntity = null;
+
+ Args.notNull(message, "message");
+ Args.notNull(inBuffer, "inBuffer");
+
HttpEntity entity = Args.notNull(EntityUtils.getMessageEntity(message), "message entity");
- if (entity instanceof MultipartSignedEntity) {
+ if (entity instanceof ApplicationPkcs7MimeCompressedDataEntity) {
+ // already parsed
return;
}
+
+ Args.check(entity.isStreaming(), "Message entity can not be parsed: entity is not streaming");
+
+ try {
+
+ applicationPkcs7MimeCompressedDataEntity = parseApplicationPkcs7MimeCompressedDataEntityBody(inBuffer, null, contentType, contentTransferEncoding);
+ applicationPkcs7MimeCompressedDataEntity.setMainBody(true);
+
+ EntityUtils.setMessageEntity(message, applicationPkcs7MimeCompressedDataEntity);
+
+ } catch (Exception e) {
+ throw new HttpException("Failed to parse entity content", e);
+ }
+ }
+
+ private static void parseApplicationPkcs7MimeEnvelopedEntity(HttpMessage message, AS2SessionInputBuffer inBuffer, ContentType contentType, String contentTransferEncoding) throws HttpException {
+ ApplicationPkcs7MimeEnvelopedDataEntity applicationPkcs7MimeEnvelopedDataEntity = null;
+
+ Args.notNull(message, "message");
+ Args.notNull(inBuffer, "inBuffer");
+
+ HttpEntity entity = Args.notNull(EntityUtils.getMessageEntity(message), "message entity");
- Args.check(entity.isStreaming(), "Entity is not streaming");
+ if (entity instanceof ApplicationPkcs7MimeCompressedDataEntity) {
+ // already parsed
+ return;
+ }
+
+ Args.check(entity.isStreaming(), "Message entity can not be parsed: entity is not streaming");
try {
+
+ applicationPkcs7MimeEnvelopedDataEntity = parseApplicationPkcs7MimeEnvelopedDataEntityBody(inBuffer, null, contentType, contentTransferEncoding);
+ applicationPkcs7MimeEnvelopedDataEntity.setMainBody(true);
+
+ EntityUtils.setMessageEntity(message, applicationPkcs7MimeEnvelopedDataEntity);
- // Determine and validate the Content Type
- Header contentTypeHeader = entity.getContentType();
- if (contentTypeHeader == null) {
- throw new HttpException("Content-Type header is missing");
- }
- ContentType contentType = ContentType.parse(entity.getContentType().getValue());
- if (!contentType.getMimeType().equals(AS2MimeType.MULTIPART_SIGNED)) {
- throw new HttpException("Entity has invalid MIME type '" + contentType.getMimeType() + "'");
- }
+ } catch (Exception e) {
+ throw new HttpException("Failed to parse entity content", e);
+ }
+ }
+
+ private static void parseMultipartSignedEntity(HttpMessage message, AS2SessionInputBuffer inBuffer, String boundary, String charsetName, String contentTransferEncoding)
+ throws HttpException {
+ MultipartSignedEntity multipartSignedEntity = null;
+
+ Args.notNull(message, "message");
+ Args.notNull(inBuffer, "inBuffer");
+ Args.notNull(boundary, "boundary");
+ Args.notNull(charsetName, "charsetName");
+
+ HttpEntity entity = Args.notNull(EntityUtils.getMessageEntity(message), "message entity");
- // Determine Charset
- String charsetName = AS2Charset.US_ASCII;
- Charset charset = contentType.getCharset();
- if (charset != null) {
- charsetName = charset.name();
- }
+ if (entity instanceof MultipartSignedEntity) {
+ // already parsed
+ return;
+ }
- // Determine content transfer encoding
- String contentTransferEncoding = HttpMessageUtils.getHeaderValue(message, AS2Header.CONTENT_TRANSFER_ENCODING);
+ Args.check(entity.isStreaming(), "Message entity can not be parsed: entity is not streaming");
- AS2SessionInputBuffer inbuffer = new AS2SessionInputBuffer(new HttpTransportMetricsImpl(), DEFAULT_BUFFER_SIZE);
- inbuffer.bind(entity.getContent());
+ try {
- // Get Boundary Value
- String boundary = HttpMessageUtils.getParameterValue(message, AS2Header.CONTENT_TYPE, "boundary");
- if (boundary == null) {
- throw new HttpException("Failed to retrieve 'boundary' parameter from content type header");
- }
-
// Get Micalg Value
String micalg = HttpMessageUtils.getParameterValue(message, AS2Header.CONTENT_TYPE, "micalg");
if (micalg == null) {
throw new HttpException("Failed to retrieve 'micalg' parameter from content type header");
}
- multipartSignedEntity = parseMultipartSignedEntityBody(inbuffer, boundary, micalg, charsetName, contentTransferEncoding);
+ multipartSignedEntity = parseMultipartSignedEntityBody(inBuffer, boundary, micalg, charsetName, contentTransferEncoding);
multipartSignedEntity.setMainBody(true);
EntityUtils.setMessageEntity(message, multipartSignedEntity);
@@ -334,127 +358,123 @@ public final class EntityParser {
}
}
- public static void parseApplicationEDIEntity(HttpMessage message) throws HttpException {
+ private static void parseApplicationEDIEntity(HttpMessage message, AS2SessionInputBuffer inBuffer, ContentType contentType, String contentTransferEncoding) throws HttpException {
ApplicationEDIEntity applicationEDIEntity = null;
+
+ Args.notNull(message, "message");
+ Args.notNull(inBuffer, "inBuffer");
+
HttpEntity entity = Args.notNull(EntityUtils.getMessageEntity(message), "message entity");
if (entity instanceof ApplicationEDIEntity) {
+ // already parsed
return;
}
- Args.check(entity.isStreaming(), "Entity is not streaming");
+ Args.check(entity.isStreaming(), "Message entity can not be parsed: entity is not streaming");
try {
- // Determine and validate the Content Type
- Header contentTypeHeader = entity.getContentType();
- if (contentTypeHeader == null) {
- throw new HttpException("Content-Type header is missing");
- }
- ContentType contentType = ContentType.parse(entity.getContentType().getValue());
- if (!contentType.getMimeType().startsWith(EntityParser.APPLICATION_EDI_CONTENT_TYPE_PREFIX)) {
- throw new HttpException("Entity has invalid MIME type '" + contentType.getMimeType() + "'");
- }
-
- // Determine Transfer Encoding
- Header transferEncoding = entity.getContentEncoding();
- String contentTransferEncoding = transferEncoding == null ? null : transferEncoding.getValue();
-
- AS2SessionInputBuffer inBuffer = new AS2SessionInputBuffer(new HttpTransportMetricsImpl(), 8 * 1024);
- inBuffer.bind(entity.getContent());
-
applicationEDIEntity = parseEDIEntityBody(inBuffer, null, contentType, contentTransferEncoding);
applicationEDIEntity.setMainBody(true);
EntityUtils.setMessageEntity(message, applicationEDIEntity);
- } catch (HttpException e) {
- throw e;
+
} catch (Exception e) {
throw new HttpException("Failed to parse entity content", e);
}
}
- public static void parseMessageDispositionNotificationReportEntity(HttpMessage message)
+ private static void parseMessageDispositionNotificationReportEntity(HttpMessage message, AS2SessionInputBuffer inBuffer, String boundary, String charsetName, String contentTransferEncoding)
throws HttpException {
DispositionNotificationMultipartReportEntity dispositionNotificationMultipartReportEntity = null;
+
+ Args.notNull(message, "message");
+ Args.notNull(inBuffer, "inBuffer");
+ Args.notNull(boundary, "boundary");
+ Args.notNull(charsetName, "charsetName");
HttpEntity entity = Args.notNull(EntityUtils.getMessageEntity(message), "message entity");
if (entity instanceof DispositionNotificationMultipartReportEntity) {
+ // already parsed
return;
}
- Args.check(entity.isStreaming(), "Entity is not streaming");
+ Args.check(entity.isStreaming(), "Message entity can not be parsed: entity is not streaming");
try {
- // Determine and validate the Content Type
- Header contentTypeHeader = entity.getContentType();
- if (contentTypeHeader == null) {
- throw new HttpException("Content-Type header is missing");
- }
- ContentType contentType = ContentType.parse(entity.getContentType().getValue());
- if (!contentType.getMimeType().equals(AS2MimeType.MULTIPART_REPORT)) {
- throw new HttpException("Entity has invalid MIME type '" + contentType.getMimeType() + "'");
- }
-
- // Determine Charset
- String charsetName = AS2Charset.US_ASCII;
- Charset charset = contentType.getCharset();
- if (charset != null) {
- charsetName = charset.name();
- }
-
- // Determine content transfer encoding
- String contentTransferEncoding = HttpMessageUtils.getHeaderValue(message, AS2Header.CONTENT_TRANSFER_ENCODING);
-
- AS2SessionInputBuffer inbuffer = new AS2SessionInputBuffer(new HttpTransportMetricsImpl(), 8 * 1024);
- inbuffer.bind(entity.getContent());
-
- // Get Boundary Value
- String boundary = HttpMessageUtils.getParameterValue(message, AS2Header.CONTENT_TYPE, "boundary");
- if (boundary == null) {
- throw new HttpException("Failed to retrive boundary value");
- }
-
- dispositionNotificationMultipartReportEntity = parseMultipartReportEntityBody(inbuffer, boundary, charsetName, contentTransferEncoding);
+ dispositionNotificationMultipartReportEntity = parseMultipartReportEntityBody(inBuffer, boundary, charsetName, contentTransferEncoding);
EntityUtils.setMessageEntity(message, dispositionNotificationMultipartReportEntity);
- } catch (HttpException e) {
- throw e;
} catch (Exception e) {
throw new HttpException("Failed to parse entity content", e);
}
}
+ /**
+ * Parses message's entity and replaces it with mime entity.
+ *
+ * @param message - message whose entity is parsed.
+ * @throws HttpException when things go wrong.
+ */
public static void parseAS2MessageEntity(HttpMessage message) throws HttpException {
if (EntityUtils.hasEntity(message)) {
- String contentTypeStr = HttpMessageUtils.getHeaderValue(message, AS2Header.CONTENT_TYPE);
- if (contentTypeStr != null) {
- ContentType contentType;
- try {
- contentType = ContentType.parse(contentTypeStr);
- } catch (Exception e) {
- LOG.debug("Failed to get content type of message", e);
- return;
+ HttpEntity entity = Args.notNull(EntityUtils.getMessageEntity(message), "message entity");
+
+ try {
+ // Determine Content Type of Message
+ String contentTypeStr = HttpMessageUtils.getHeaderValue(message, AS2Header.CONTENT_TYPE);
+ ContentType contentType = ContentType.parse(contentTypeStr);
+
+
+ // Determine Charset
+ String charsetName = AS2Charset.US_ASCII;
+ Charset charset = contentType.getCharset();
+ if (charset != null) {
+ charsetName = charset.name();
}
+
+ // Get any Boundary Value
+ String boundary = HttpMessageUtils.getParameterValue(message, AS2Header.CONTENT_TYPE, "boundary");
+
+ // Determine content transfer encoding
+ String contentTransferEncoding = HttpMessageUtils.getHeaderValue(message, AS2Header.CONTENT_TRANSFER_ENCODING);
+
+ AS2SessionInputBuffer inBuffer = new AS2SessionInputBuffer(new HttpTransportMetricsImpl(), 8 * 1024);
+ inBuffer.bind(entity.getContent());
+
switch (contentType.getMimeType().toLowerCase()) {
case AS2MimeType.APPLICATION_EDIFACT:
case AS2MimeType.APPLICATION_EDI_X12:
case AS2MimeType.APPLICATION_EDI_CONSENT:
- parseApplicationEDIEntity(message);
+ parseApplicationEDIEntity(message, inBuffer, contentType, contentTransferEncoding);
break;
case AS2MimeType.MULTIPART_SIGNED:
- parseMultipartSignedEntity(message);
+ parseMultipartSignedEntity(message, inBuffer, boundary, charsetName, contentTransferEncoding);
break;
case AS2MimeType.APPLICATION_PKCS7_MIME:
+ switch (contentType.getParameter("smime-type")) {
+ case "compressed-data":
+ parseApplicationPkcs7MimeCompressedEntity(message, inBuffer, contentType, contentTransferEncoding);
+ break;
+ case "enveloped-data":
+ parseApplicationPkcs7MimeEnvelopedEntity(message, inBuffer, contentType, contentTransferEncoding);
+ break;
+ default:
+ }
break;
case AS2MimeType.MULTIPART_REPORT:
- parseMessageDispositionNotificationReportEntity(message);
+ parseMessageDispositionNotificationReportEntity(message, inBuffer, boundary, charsetName, contentTransferEncoding);
break;
default:
break;
}
+ } catch (HttpException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new HttpException("Failed to parse entity content", e);
}
}
}
@@ -1043,4 +1063,121 @@ public final class EntityParser {
}
return fields;
}
+
+ public static HttpEntity extractEdiPayload(HttpEntityEnclosingRequest request, PrivateKey privateKey) throws HttpException {
+
+ String contentTypeString = HttpMessageUtils.getHeaderValue(request, AS2Header.CONTENT_TYPE);
+ if (contentTypeString == null) {
+ throw new HttpException("Failed to create MIC: content type missing from request");
+ }
+ ContentType contentType = ContentType.parse(contentTypeString);
+
+ parseAS2MessageEntity(request);
+ MimeEntity ediEntity = null;
+ switch (contentType.getMimeType().toLowerCase()) {
+ case AS2MimeType.APPLICATION_EDIFACT:
+ case AS2MimeType.APPLICATION_EDI_X12:
+ case AS2MimeType.APPLICATION_EDI_CONSENT: {
+ ediEntity = HttpMessageUtils.getEntity(request, ApplicationEDIEntity.class);
+ break;
+ }
+ case AS2MimeType.MULTIPART_SIGNED: {
+ MultipartSignedEntity multipartSignedEntity = HttpMessageUtils.getEntity(request,
+ MultipartSignedEntity.class);
+ ediEntity = multipartSignedEntity.getSignedDataEntity();
+ break;
+ }
+ case AS2MimeType.APPLICATION_PKCS7_MIME: {
+ switch(contentType.getParameter("smime-type")) {
+ case "compressed-data": {
+ ApplicationPkcs7MimeCompressedDataEntity compressedDataEntity = HttpMessageUtils.getEntity(request, ApplicationPkcs7MimeCompressedDataEntity.class);
+ ediEntity = extractEdiPayloadFromCompressedEntity(compressedDataEntity);
+ break;
+ }
+ case "enveloped-data": {
+ if (privateKey == null) {
+ throw new HttpException("Failed to get EDI message from encrypted request: private key is null");
+ }
+ ApplicationPkcs7MimeEnvelopedDataEntity envelopedDataEntity = HttpMessageUtils.getEntity(request, ApplicationPkcs7MimeEnvelopedDataEntity.class);
+ ediEntity = extractEdiPayloadFromEnvelopedEntity(envelopedDataEntity, privateKey);
+ break;
+ }
+ default:
+ throw new HttpException("Failed to create MIC: unknown " + AS2MimeType.APPLICATION_PKCS7_MIME + " smime-type: " + contentType.getParameter("smime-type"));
+ }
+ break;
+ }
+ default:
+ throw new HttpException("Failed to create MIC: invalid content type '" + contentType.getMimeType() + "' for message integrity check");
+ }
+
+ return ediEntity;
+
+ }
+
+ private static MimeEntity extractEdiPayloadFromEnvelopedEntity(ApplicationPkcs7MimeEnvelopedDataEntity envelopedDataEntity, PrivateKey privateKey) throws HttpException {
+ MimeEntity ediEntity = null;
+
+ MimeEntity entity = envelopedDataEntity.getEncryptedEntity(privateKey);
+ String contentTypeString = entity.getContentTypeValue();
+ if (contentTypeString == null) {
+ throw new HttpException("Failed to create MIC: content type missing from encrypted entity");
+ }
+ ContentType contentType = ContentType.parse(contentTypeString);
+
+ switch(contentType.getMimeType().toLowerCase()) {
+ case AS2MimeType.APPLICATION_EDIFACT:
+ case AS2MimeType.APPLICATION_EDI_X12:
+ case AS2MimeType.APPLICATION_EDI_CONSENT: {
+ ediEntity = entity;
+ break;
+ }
+ case AS2MimeType.MULTIPART_SIGNED: {
+ MultipartSignedEntity multipartSignedEntity = (MultipartSignedEntity) entity;
+ ediEntity = multipartSignedEntity.getSignedDataEntity();
+ break;
+ }
+ case AS2MimeType.APPLICATION_PKCS7_MIME: {
+ if (contentType.getParameter("mime-type").equals("compressed-data")) {
+ throw new HttpException("Failed to extract EDI payload: invalid mime type '" + contentType.getParameter("mime-type") + "' for AS2 enveloped entity");
+ }
+ ApplicationPkcs7MimeCompressedDataEntity compressedDataEntity = (ApplicationPkcs7MimeCompressedDataEntity) entity;
+ ediEntity = extractEdiPayloadFromCompressedEntity(compressedDataEntity);
+ break;
+ }
+ default:
+ throw new HttpException("Failed to extract EDI payload: invalid content type '" + contentType.getMimeType() + "' for AS2 enveloped entity");
+ }
+
+ return ediEntity;
+ }
+
+ private static MimeEntity extractEdiPayloadFromCompressedEntity(ApplicationPkcs7MimeCompressedDataEntity compressedDataEntity) throws HttpException {
+ MimeEntity ediEntity = null;
+
+ MimeEntity entity = compressedDataEntity.getCompressedEntity(new ZlibExpanderProvider());
+ String contentTypeString = entity.getContentTypeValue();
+ if (contentTypeString == null) {
+ throw new HttpException("Failed to extract EDI payload: content type missing from compressed entity");
+ }
+ ContentType contentType = ContentType.parse(contentTypeString);
+
+ switch(contentType.getMimeType().toLowerCase()) {
+ case AS2MimeType.APPLICATION_EDIFACT:
+ case AS2MimeType.APPLICATION_EDI_X12:
+ case AS2MimeType.APPLICATION_EDI_CONSENT: {
+ ediEntity = entity;
+ break;
+ }
+ case AS2MimeType.MULTIPART_SIGNED: {
+ MultipartSignedEntity multipartSignedEntity = (MultipartSignedEntity) entity;
+ ediEntity = multipartSignedEntity.getSignedDataEntity();
+ break;
+ }
+ default:
+ throw new HttpException("Failed to extract EDI payload: invalid content type '" + contentType.getMimeType() + "' for AS2 compressed entity");
+ }
+
+ return ediEntity;
+ }
}
diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/EntityUtils.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/EntityUtils.java
index 926d345..560eb1c 100644
--- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/EntityUtils.java
+++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/EntityUtils.java
@@ -32,6 +32,7 @@ import org.apache.camel.component.as2.api.entity.ApplicationEDIConsentEntity;
import org.apache.camel.component.as2.api.entity.ApplicationEDIEntity;
import org.apache.camel.component.as2.api.entity.ApplicationEDIFACTEntity;
import org.apache.camel.component.as2.api.entity.ApplicationEDIX12Entity;
+import org.apache.camel.component.as2.api.entity.MimeEntity;
import org.apache.commons.codec.binary.Base64InputStream;
import org.apache.commons.codec.binary.Base64OutputStream;
import org.apache.commons.codec.net.QuotedPrintableCodec;
@@ -242,6 +243,12 @@ public final class EntityUtils {
if (contentTypeHeader != null) {
message.setHeader(contentTypeHeader);
}
+ if (entity instanceof MimeEntity) {
+ Header contentTransferEncodingHeader = ((MimeEntity)entity).getContentTransferEncoding();
+ if (contentTransferEncodingHeader != null) {
+ message.setHeader(contentTransferEncodingHeader);
+ }
+ }
long contentLength = entity.getContentLength();
message.setHeader(AS2Header.CONTENT_LENGTH, Long.toString(contentLength));
}
diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/MicUtils.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/MicUtils.java
index 4aec7f6..8eb66b1 100644
--- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/MicUtils.java
+++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/MicUtils.java
@@ -25,6 +25,7 @@ import org.apache.camel.component.as2.api.AS2Header;
import org.apache.camel.component.as2.api.AS2MicAlgorithm;
import org.apache.camel.component.as2.api.AS2MimeType;
import org.apache.camel.component.as2.api.entity.ApplicationEDIEntity;
+import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeCompressedDataEntity;
import org.apache.camel.component.as2.api.entity.DispositionNotificationOptions;
import org.apache.camel.component.as2.api.entity.DispositionNotificationOptionsParser;
import org.apache.camel.component.as2.api.entity.EntityParser;
@@ -96,33 +97,7 @@ public final class MicUtils {
return null;
}
- String contentTypeString = HttpMessageUtils.getHeaderValue(request, AS2Header.CONTENT_TYPE);
- if (contentTypeString == null) {
- LOG.debug("can not create MIC: content type missing from request");
- return null;
- }
- ContentType contentType = ContentType.parse(contentTypeString);
-
- HttpEntity entity = null;
- switch (contentType.getMimeType().toLowerCase()) {
- case AS2MimeType.APPLICATION_EDIFACT:
- case AS2MimeType.APPLICATION_EDI_X12:
- case AS2MimeType.APPLICATION_EDI_CONSENT: {
- EntityParser.parseAS2MessageEntity(request);
- entity = HttpMessageUtils.getEntity(request, ApplicationEDIEntity.class);
- break;
- }
- case AS2MimeType.MULTIPART_SIGNED: {
- EntityParser.parseAS2MessageEntity(request);
- MultipartSignedEntity multipartSignedEntity = HttpMessageUtils.getEntity(request,
- MultipartSignedEntity.class);
- entity = multipartSignedEntity.getSignedDataEntity();
- break;
- }
- default:
- LOG.debug("can not create MIC: invalid content type '{}' for message integrity check", contentType.getMimeType());
- return null;
- }
+ HttpEntity entity = EntityParser.extractEdiPayload(request, null);
byte[] content = EntityUtils.getContent(entity);
@@ -131,7 +106,7 @@ public final class MicUtils {
try {
return new ReceivedContentMic(micAS2AlgorithmName, mic);
} catch (Exception e) {
- throw new HttpException("failed to encode MIC", e);
+ throw new HttpException("Failed to encode MIC", 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 f4b530a0..ffe26df 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
@@ -77,20 +77,6 @@ public final class SigningUtils {
} catch (Exception e) {
throw new HttpException("Failed to create signer info", e);
}
-// for (String signingAlgorithmName : AS2SignedDataGenerator.getSupportedSignatureAlgorithmNamesForKey(privateKey)) {
-// try {
-// signerInfoGenerator = new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC")
-// .setSignedAttributeGenerator(new AttributeTable(attributes))
-// .build(signingAlgorithmName, privateKey, signingCert);
-// break;
-// } catch (Exception e) {
-// signerInfoGenerator = null;
-// continue;
-// }
-// }
-// if (signerInfoGenerator == null) {
-// throw new HttpException("Failed to create signer info");
-// }
gen.addSignerInfoGenerator(signerInfoGenerator);
// Create and populate certificate store.
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 b764d62..b9d336a 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
@@ -272,7 +272,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, null, null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
+ null, null, null, null, null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null);
HttpRequest request = httpContext.getRequest();
assertEquals("Unexpected method value", METHOD, request.getRequestLine().getMethod());
@@ -316,7 +316,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, AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(),
- null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
+ null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null);
HttpRequest request = httpContext.getRequest();
assertEquals("Unexpected method value", METHOD, request.getRequestLine().getMethod());
@@ -478,7 +478,7 @@ public class AS2MessageTest {
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), null,
AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(), null,
DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, encryptionAlgorithm,
- certList.toArray(new Certificate[0]), signingKP.getPrivate());
+ certList.toArray(new Certificate[0]));
HttpRequest request = httpContext.getRequest();
assertEquals("Unexpected method value", METHOD, request.getRequestLine().getMethod());
@@ -539,7 +539,7 @@ public class AS2MessageTest {
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), null,
AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(), null,
DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, encryptionAlgorithm,
- certList.toArray(new Certificate[0]), signingKP.getPrivate());
+ certList.toArray(new Certificate[0]));
HttpRequest request = httpContext.getRequest();
assertEquals("Unexpected method value", METHOD, request.getRequestLine().getMethod());
@@ -606,7 +606,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, AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(),
- null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
+ null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null);
HttpRequest request = httpContext.getRequest();
assertTrue("Request does not contain entity", request instanceof BasicHttpEntityEnclosingRequest);
@@ -634,8 +634,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, null, null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null,
- null);
+ null, null, null, null, null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null);
HttpResponse response = httpContext.getResponse();
assertEquals("Unexpected method value", HttpVersion.HTTP_1_1, response.getStatusLine().getProtocolVersion());
@@ -751,7 +750,7 @@ public class AS2MessageTest {
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), null,
null, null, null, AS2CompressionAlgorithm.ZLIB,
DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null,
- null, null);
+ null);
HttpRequest request = httpContext.getRequest();
assertEquals("Unexpected method value", METHOD, request.getRequestLine().getMethod());
@@ -804,10 +803,10 @@ public class AS2MessageTest {
HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME,
AS2MessageStructure.SIGNED_COMPRESSED,
- ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), null,
+ ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), "base64",
AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(), AS2CompressionAlgorithm.ZLIB,
DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null,
- null, null);
+ null);
HttpRequest request = httpContext.getRequest();
assertEquals("Unexpected method value", METHOD, request.getRequestLine().getMethod());
@@ -875,10 +874,10 @@ public class AS2MessageTest {
HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME,
AS2MessageStructure.ENCRYPTED_COMPRESSED,
- ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), null,
+ ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), "base64",
null, null, null, AS2CompressionAlgorithm.ZLIB,
DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, AS2EncryptionAlgorithm.AES128_CBC,
- certList.toArray(new Certificate[0]), signingKP.getPrivate());
+ certList.toArray(new Certificate[0]));
HttpRequest request = httpContext.getRequest();
assertEquals("Unexpected method value", METHOD, request.getRequestLine().getMethod());
@@ -942,7 +941,7 @@ public class AS2MessageTest {
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), null,
AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(),
AS2CompressionAlgorithm.ZLIB, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS,
- AS2EncryptionAlgorithm.AES128_CBC, certList.toArray(new Certificate[0]), signingKP.getPrivate());
+ AS2EncryptionAlgorithm.AES128_CBC, certList.toArray(new Certificate[0]));
HttpRequest request = httpContext.getRequest();
assertEquals("Unexpected method value", METHOD, request.getRequestLine().getMethod());
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 d5b3a0d..ead2037 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
@@ -204,7 +204,7 @@ public class EntityParserTest {
entity.setContent(is);
EntityUtils.setMessageEntity(response, entity);
- EntityParser.parseMessageDispositionNotificationReportEntity(response);
+ EntityParser.parseAS2MessageEntity(response);
HttpEntity parsedEntity = EntityUtils.getMessageEntity(response);
assertNotNull("Unexpected Null message disposition notification report entity", parsedEntity);
assertTrue("Unexpected type for message disposition notification report entity", parsedEntity instanceof DispositionNotificationMultipartReportEntity);
diff --git a/components/camel-as2/camel-as2-component/pom.xml b/components/camel-as2/camel-as2-component/pom.xml
index 8903e25..d6ca3a7 100644
--- a/components/camel-as2/camel-as2-component/pom.xml
+++ b/components/camel-as2/camel-as2-component/pom.xml
@@ -156,7 +156,23 @@
<proxyClass>org.apache.camel.component.as2.api.AS2ClientManager</proxyClass>
<fromJavadoc>
<excludeMethods>createSigningGenerator</excludeMethods>
+ <excludeMethods>createEncryptingGenerator</excludeMethods>
+ <excludeMethods>createCompressorGenerator</excludeMethods>
+ <excludeMethods>createEncryptor</excludeMethods>
+ <excludeMethods>createCompressor</excludeMethods>
</fromJavadoc>
+ <nullableOptions>
+ <nullableOption>ediMessageTransferEncoding</nullableOption>
+ <nullableOption>signingAlgorithm</nullableOption>
+ <nullableOption>signingCertificateChain</nullableOption>
+ <nullableOption>signingPrivateKey</nullableOption>
+ <nullableOption>compressionAlgorithm</nullableOption>
+ <nullableOption>dispositionNotificationTo</nullableOption>
+ <nullableOption>signedReceiptMicAlgorithms</nullableOption>
+ <nullableOption>encryptingAlgorithm</nullableOption>
+ <nullableOption>encryptingCertificateChain</nullableOption>
+ <nullableOption>encryptingPrivateKey</nullableOption>
+ </nullableOptions>
</api>
<api>
<apiName>server</apiName>
diff --git a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIntegrationTest.java b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIntegrationTest.java
index 36c0386..9f83ea2 100644
--- a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIntegrationTest.java
+++ b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIntegrationTest.java
@@ -31,6 +31,7 @@ import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.as2.api.AS2AsynchronousMDNManager;
import org.apache.camel.component.as2.api.AS2Charset;
+import org.apache.camel.component.as2.api.AS2CompressionAlgorithm;
import org.apache.camel.component.as2.api.AS2Constants;
import org.apache.camel.component.as2.api.AS2EncryptionAlgorithm;
import org.apache.camel.component.as2.api.AS2Header;
@@ -45,6 +46,7 @@ import org.apache.camel.component.as2.api.entity.AS2DispositionModifier;
import org.apache.camel.component.as2.api.entity.AS2DispositionType;
import org.apache.camel.component.as2.api.entity.AS2MessageDispositionNotificationEntity;
import org.apache.camel.component.as2.api.entity.ApplicationEDIEntity;
+import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeCompressedDataEntity;
import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeEnvelopedDataEntity;
import org.apache.camel.component.as2.api.entity.ApplicationPkcs7SignatureEntity;
import org.apache.camel.component.as2.api.entity.DispositionMode;
@@ -83,6 +85,7 @@ import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder;
+import org.bouncycastle.cms.jcajce.ZlibExpanderProvider;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.AfterClass;
import org.junit.Before;
@@ -222,20 +225,8 @@ public class AS2ClientManagerIntegrationTest extends AbstractAS2TestSupport {
headers.put("CamelAS2.ediMessageContentType", ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII));
// parameter type is String
headers.put("CamelAS2.ediMessageTransferEncoding", EDI_MESSAGE_CONTENT_TRANSFER_ENCODING);
- // parameter type is java.security.cert.Certificate[]
- headers.put("CamelAS2.signingCertificateChain", null);
- // parameter type is java.security.PrivateKey
- headers.put("CamelAS2.signingPrivateKey", null);
// parameter type is String
headers.put("CamelAS2.dispositionNotificationTo", "mrAS2@example.com");
- // parameter type is String[]
- headers.put("CamelAS2.signedReceiptMicAlgorithms", null);
- // parameter type is org.apache.camel.component.as2.api.AS2EncryptionAlgorithm
- headers.put("CamelAS2.encryptingAlgorithm", null);
- // parameter type is java.security.cert.Certificate[]
- headers.put("CamelAS2.encryptingCertificateChain", null);
- // parameter type is java.security.PrivateKey
- headers.put("CamelAS2.encryptingPrivateKey", null);
final org.apache.http.protocol.HttpCoreContext result = requestBodyAndHeaders("direct://SEND", EDI_MESSAGE, headers);
@@ -302,14 +293,8 @@ public class AS2ClientManagerIntegrationTest extends AbstractAS2TestSupport {
headers.put("CamelAS2.ediMessageContentType", ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII));
// parameter type is String
headers.put("CamelAS2.ediMessageTransferEncoding", EDI_MESSAGE_CONTENT_TRANSFER_ENCODING);
- // parameter type is java.security.cert.Certificate[]
- headers.put("CamelAS2.signingCertificateChain", null);
- // parameter type is java.security.PrivateKey
- headers.put("CamelAS2.signingPrivateKey", null);
// parameter type is String
headers.put("CamelAS2.dispositionNotificationTo", "mrAS2@example.com");
- // parameter type is String[]
- headers.put("CamelAS2.signedReceiptMicAlgorithms", null);
// parameter type is org.apache.camel.component.as2.api.AS2EncryptionAlgorithm
headers.put("CamelAS2.encryptingAlgorithm", AS2EncryptionAlgorithm.AES128_CBC);
// parameter type is java.security.cert.Certificate[]
@@ -384,6 +369,8 @@ public class AS2ClientManagerIntegrationTest extends AbstractAS2TestSupport {
headers.put("CamelAS2.ediMessageContentType", ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII));
// parameter type is String
headers.put("CamelAS2.ediMessageTransferEncoding", EDI_MESSAGE_CONTENT_TRANSFER_ENCODING);
+ // parameter type is org.apache.camel.component.as2.api.AS2SignatureAlgorithm
+ headers.put("CamelAS2.signingAlgorithm", AS2SignatureAlgorithm.SHA512WITHRSA);
// parameter type is java.security.cert.Certificate[]
headers.put("CamelAS2.signingCertificateChain", certList.toArray(new Certificate[0]));
// parameter type is java.security.PrivateKey
@@ -392,12 +379,6 @@ public class AS2ClientManagerIntegrationTest extends AbstractAS2TestSupport {
headers.put("CamelAS2.dispositionNotificationTo", "mrAS2@example.com");
// parameter type is String[]
headers.put("CamelAS2.signedReceiptMicAlgorithms", SIGNED_RECEIPT_MIC_ALGORITHMS);
- // parameter type is org.apache.camel.component.as2.api.AS2EncryptionAlgorithm
- headers.put("CamelAS2.encryptingAlgorithm", null);
- // parameter type is java.security.cert.Certificate[]
- headers.put("CamelAS2.encryptingCertificateChain", null);
- // parameter type is java.security.PrivateKey
- headers.put("CamelAS2.encryptingPrivateKey", null);
final org.apache.http.protocol.HttpCoreContext result = requestBodyAndHeaders("direct://SEND", EDI_MESSAGE, headers);
@@ -461,6 +442,93 @@ public class AS2ClientManagerIntegrationTest extends AbstractAS2TestSupport {
}
@Test
+ public void compressedMessageTest() throws Exception {
+ final Map<String, Object> headers = new HashMap<>();
+ // parameter type is String
+ headers.put("CamelAS2.requestUri", REQUEST_URI);
+ // parameter type is String
+ headers.put("CamelAS2.subject", SUBJECT);
+ // parameter type is String
+ headers.put("CamelAS2.from", FROM);
+ // parameter type is String
+ headers.put("CamelAS2.as2From", AS2_NAME);
+ // parameter type is String
+ headers.put("CamelAS2.as2To", AS2_NAME);
+ // parameter type is org.apache.camel.component.as2.api.AS2MessageStructure
+ headers.put("CamelAS2.as2MessageStructure", AS2MessageStructure.PLAIN_COMPRESSED);
+ // parameter type is org.apache.http.entity.ContentType
+ headers.put("CamelAS2.ediMessageContentType", ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII));
+ // parameter type is String
+ headers.put("CamelAS2.ediMessageTransferEncoding", EDI_MESSAGE_CONTENT_TRANSFER_ENCODING);
+ // parameter type is org.apache.camel.component.as2.api.AS2CompressionAlgorithm
+ headers.put("CamelAS2.compressionAlgorithm", AS2CompressionAlgorithm.ZLIB);
+ // parameter type is String
+ headers.put("CamelAS2.dispositionNotificationTo", "mrAS2@example.com");
+ // parameter type is String[]
+ headers.put("CamelAS2.signedReceiptMicAlgorithms", SIGNED_RECEIPT_MIC_ALGORITHMS);
+
+ final org.apache.http.protocol.HttpCoreContext result = requestBodyAndHeaders("direct://SEND", EDI_MESSAGE, headers);
+
+ assertNotNull("send result", result);
+ LOG.debug("send: " + result);
+ HttpRequest request = result.getRequest();
+ assertNotNull("Request", request);
+ assertTrue("Request does not contain body", request instanceof HttpEntityEnclosingRequest);
+ HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity();
+ assertNotNull("Request body", entity);
+ assertTrue("Request body does not contain EDI entity", entity instanceof ApplicationPkcs7MimeCompressedDataEntity);
+
+ MimeEntity compressedEntity = ((ApplicationPkcs7MimeCompressedDataEntity)entity).getCompressedEntity(new ZlibExpanderProvider());
+ assertTrue("Signed entity wrong type", compressedEntity instanceof ApplicationEDIEntity);
+ ApplicationEDIEntity ediMessageEntity = (ApplicationEDIEntity) compressedEntity;
+ String ediMessage = ediMessageEntity.getEdiMessage();
+ assertEquals("EDI message is different", EDI_MESSAGE.replaceAll("[\n\r]", ""), ediMessage.replaceAll("[\n\r]", ""));
+
+ HttpResponse response = result.getResponse();
+ assertNotNull("Response", response);
+ String contentTypeHeaderValue = HttpMessageUtils.getHeaderValue(response, AS2Header.CONTENT_TYPE);
+ ContentType responseContentType = ContentType.parse(contentTypeHeaderValue);
+ assertEquals("Unexpected response type", AS2MimeType.MULTIPART_SIGNED, responseContentType.getMimeType());
+ assertEquals("Unexpected mime version", AS2Constants.MIME_VERSION, HttpMessageUtils.getHeaderValue(response, AS2Header.MIME_VERSION));
+ assertEquals("Unexpected AS2 version", EXPECTED_AS2_VERSION, HttpMessageUtils.getHeaderValue(response, AS2Header.AS2_VERSION));
+ assertEquals("Unexpected MDN subject", EXPECTED_MDN_SUBJECT, HttpMessageUtils.getHeaderValue(response, AS2Header.SUBJECT));
+ assertEquals("Unexpected MDN from", MDN_FROM, HttpMessageUtils.getHeaderValue(response, AS2Header.FROM));
+ assertEquals("Unexpected AS2 from", AS2_NAME, HttpMessageUtils.getHeaderValue(response, AS2Header.AS2_FROM));
+ assertEquals("Unexpected AS2 to", AS2_NAME, HttpMessageUtils.getHeaderValue(response, AS2Header.AS2_TO));
+ assertNotNull("Missing message id", HttpMessageUtils.getHeaderValue(response, AS2Header.MESSAGE_ID));
+
+ HttpEntity responseEntity = response.getEntity();
+ assertNotNull("Response entity", responseEntity);
+ assertTrue("Unexpected response entity type", responseEntity instanceof MultipartSignedEntity);
+ MultipartSignedEntity responseSignedEntity = (MultipartSignedEntity) responseEntity;
+ assertTrue("Signature for response entity is invalid", responseSignedEntity.isValid());
+ MimeEntity responseSignedDataEntity = responseSignedEntity.getSignedDataEntity();
+ assertTrue("Signed entity wrong type", responseSignedDataEntity instanceof DispositionNotificationMultipartReportEntity);
+ DispositionNotificationMultipartReportEntity reportEntity = (DispositionNotificationMultipartReportEntity)responseSignedDataEntity;
+ assertEquals("Unexpected number of body parts in report", 2, reportEntity.getPartCount());
+ MimeEntity firstPart = reportEntity.getPart(0);
+ assertEquals("Unexpected content type in first body part of report", ContentType.create(AS2MimeType.TEXT_PLAIN, AS2Charset.US_ASCII).toString(), firstPart.getContentTypeValue());
+ MimeEntity secondPart = reportEntity.getPart(1);
+ assertEquals("Unexpected content type in second body part of report",
+ ContentType.create(AS2MimeType.MESSAGE_DISPOSITION_NOTIFICATION, AS2Charset.US_ASCII).toString(),
+ secondPart.getContentTypeValue());
+ ApplicationPkcs7SignatureEntity signatureEntity = responseSignedEntity.getSignatureEntity();
+ assertNotNull("Signature Entity", signatureEntity);
+
+ assertTrue("", secondPart instanceof AS2MessageDispositionNotificationEntity);
+ AS2MessageDispositionNotificationEntity messageDispositionNotificationEntity = (AS2MessageDispositionNotificationEntity) secondPart;
+ assertEquals("Unexpected value for reporting UA", ORIGIN_SERVER_NAME, messageDispositionNotificationEntity.getReportingUA());
+ assertEquals("Unexpected value for final recipient", AS2_NAME, messageDispositionNotificationEntity.getFinalRecipient());
+ assertEquals("Unexpected value for original message ID", HttpMessageUtils.getHeaderValue(request, AS2Header.MESSAGE_ID), messageDispositionNotificationEntity.getOriginalMessageId());
+ assertEquals("Unexpected value for disposition mode", DispositionMode.AUTOMATIC_ACTION_MDN_SENT_AUTOMATICALLY, messageDispositionNotificationEntity.getDispositionMode());
+ assertEquals("Unexpected value for disposition type", AS2DispositionType.PROCESSED, messageDispositionNotificationEntity.getDispositionType());
+
+ ReceivedContentMic receivedContentMic = messageDispositionNotificationEntity.getReceivedContentMic();
+ ReceivedContentMic computedContentMic = MicUtils.createReceivedContentMic((HttpEntityEnclosingRequest)request);
+ assertEquals("Received content MIC does not match computed", computedContentMic.getEncodedMessageDigest(), receivedContentMic.getEncodedMessageDigest());
+ }
+
+ @Test
public void asyncMDNTest() throws Exception {
AS2AsynchronousMDNManager mdnManager = new AS2AsynchronousMDNManager(AS2_VERSION, ORIGIN_SERVER_NAME, SERVER_FQDN,
certList.toArray(new X509Certificate[0]), signingKP.getPrivate());
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 0f6b931..cb58af7 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
@@ -128,7 +128,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, null,
- null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
+ null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null);
MockEndpoint mockEndpoint = getMockEndpoint("mock:as2RcvMsgs");
mockEndpoint.expectedMinimumMessageCount(1);
@@ -186,7 +186,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, AS2SignatureAlgorithm.SHA256WITHRSA,
certList.toArray(new Certificate[0]), signingKP.getPrivate(), null, DISPOSITION_NOTIFICATION_TO,
- SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
+ SIGNED_RECEIPT_MIC_ALGORITHMS, null, null);
MockEndpoint mockEndpoint = getMockEndpoint("mock:as2RcvMsgs");
mockEndpoint.expectedMinimumMessageCount(1);