blob: db43751097a5888a4184ae277d015300e14d6c05 [file] [log] [blame]
/*
* 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 java.io.IOException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.ApplicationEDIFACTEntity;
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;
import org.apache.camel.component.as2.api.entity.DispositionNotificationMultipartReportEntity;
import org.apache.camel.component.as2.api.entity.MimeEntity;
import org.apache.camel.component.as2.api.entity.MultipartSignedEntity;
import org.apache.camel.component.as2.api.entity.TextPlainEntity;
import org.apache.camel.component.as2.api.util.AS2Utils;
import org.apache.camel.component.as2.api.util.EntityUtils;
import org.apache.camel.component.as2.api.util.HttpMessageUtils;
import org.apache.camel.component.as2.api.util.MicUtils;
import org.apache.camel.component.as2.api.util.MicUtils.ReceivedContentMic;
import org.apache.camel.test.AvailablePortFinder;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.EnglishReasonPhraseCatalog;
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpCoreContext;
import org.apache.http.protocol.HttpDateGenerator;
import org.apache.http.protocol.HttpRequestHandler;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.cms.AttributeTable;
import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute;
import org.bouncycastle.asn1.smime.SMIMECapability;
import org.bouncycastle.asn1.smime.SMIMECapabilityVector;
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;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class AS2MessageTest {
public static final String EDI_MESSAGE = "UNB+UNOA:1+005435656:1+006415160:1+060515:1434+00000000000778'\n"
+ "UNH+00000000000117+INVOIC:D:97B:UN'\n"
+ "BGM+380+342459+9'\n"
+ "DTM+3:20060515:102'\n"
+ "RFF+ON:521052'\n"
+ "NAD+BY+792820524::16++CUMMINS MID-RANGE ENGINE PLANT'\n"
+ "NAD+SE+005435656::16++GENERAL WIDGET COMPANY'\n"
+ "CUX+1:USD'\n"
+ "LIN+1++157870:IN'\n"
+ "IMD+F++:::WIDGET'\n"
+ "QTY+47:1020:EA'\n"
+ "ALI+US'\n"
+ "MOA+203:1202.58'\n"
+ "PRI+INV:1.179'\n"
+ "LIN+2++157871:IN'\n"
+ "IMD+F++:::DIFFERENT WIDGET'\n"
+ "QTY+47:20:EA'\n"
+ "ALI+JP'\n"
+ "MOA+203:410'\n"
+ "PRI+INV:20.5'\n"
+ "UNS+S'\n"
+ "MOA+39:2137.58'\n"
+ "ALC+C+ABG'\n"
+ "MOA+8:525'\n"
+ "UNT+23+00000000000117'\n"
+ "UNZ+1+00000000000778'";
private static final Logger LOG = LoggerFactory.getLogger(AS2MessageTest.class);
private static final String METHOD = "POST";
private static final String TARGET_HOST = "localhost";
private static final int TARGET_PORT = AvailablePortFinder.getNextAvailable();
private static final String RECIPIENT_DELIVERY_ADDRESS = "http://localhost:" + TARGET_PORT + "/handle-receipts";
private static final String AS2_VERSION = "1.1";
private static final String USER_AGENT = "Camel AS2 Endpoint";
private static final String REQUEST_URI = "/";
private static final String AS2_NAME = "878051556";
private static final String SUBJECT = "Test Case";
private static final String FROM = "mrAS@example.org";
private static final String CLIENT_FQDN = "client.example.org";
private static final String SERVER_FQDN = "server.example.org";
private static final String REPORTING_UA = "Server Responding with MDN";
private static final String DISPOSITION_NOTIFICATION_TO = "mrAS@example.org";
private static final String DISPOSITION_NOTIFICATION_OPTIONS = "signed-receipt-protocol=optional,pkcs7-signature; signed-receipt-micalg=optional,sha1";
private static final String[] SIGNED_RECEIPT_MIC_ALGORITHMS = new String[] {"sha1", "md5"};
private static final HttpDateGenerator DATE_GENERATOR = new HttpDateGenerator();
private static AS2ServerConnection testServer;
private static KeyPair issueKP;
private static X509Certificate issueCert;
private static KeyPair signingKP;
private static X509Certificate signingCert;
private static List<X509Certificate> certList;
private AS2SignedDataGenerator gen;
@BeforeClass
public static void setUpOnce() 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";
issueKP = kpg.generateKeyPair();
issueCert = Utils.makeCertificate(issueKP, issueDN, issueKP, issueDN);
//
// certificate we sign against
//
String signingDN = "CN=William J. Collins, E=punkhornsw@gmail.com, O=Punkhorn Software, C=US";
signingKP = kpg.generateKeyPair();
signingCert = Utils.makeCertificate(signingKP, signingDN, issueKP, issueDN);
certList = new ArrayList<>();
certList.add(signingCert);
certList.add(issueCert);
KeyPair decryptingKP = signingKP;
testServer = new AS2ServerConnection(AS2_VERSION, "MyServer-HTTP/1.1", SERVER_FQDN, TARGET_PORT, AS2SignatureAlgorithm.SHA256WITHRSA,
certList.toArray(new Certificate[0]), signingKP.getPrivate(), decryptingKP.getPrivate());
testServer.listen("*", new HttpRequestHandler() {
@Override
public void handle(HttpRequest request, HttpResponse response, HttpContext context)
throws HttpException, IOException {
try {
org.apache.camel.component.as2.api.entity.EntityParser.parseAS2MessageEntity(request);
context.setAttribute(AS2ServerManager.SUBJECT, SUBJECT);
context.setAttribute(AS2ServerManager.FROM, AS2_NAME);
LOG.debug(AS2Utils.printMessage(request));
} catch (Exception e) {
throw new HttpException("Failed to parse AS2 Message Entity", e);
}
}
});
}
@AfterClass
public static void tearDownOnce() throws Exception {
testServer.close();
}
@Before
public void setUp() throws Exception {
Security.addProvider(new BouncyCastleProvider());
// Create and populate certificate store.
JcaCertStore certs = new JcaCertStore(certList);
// Create capabilities vector
SMIMECapabilityVector capabilities = new SMIMECapabilityVector();
capabilities.addCapability(SMIMECapability.dES_EDE3_CBC);
capabilities.addCapability(SMIMECapability.rC2_CBC, 128);
capabilities.addCapability(SMIMECapability.dES_CBC);
// Create signing attributes
ASN1EncodableVector attributes = new ASN1EncodableVector();
attributes.add(new SMIMEEncryptionKeyPreferenceAttribute(new IssuerAndSerialNumber(
new X500Name(signingCert.getIssuerDN().getName()), signingCert.getSerialNumber())));
attributes.add(new SMIMECapabilitiesAttribute(capabilities));
for (String signingAlgorithmName : AS2SignedDataGenerator
.getSupportedSignatureAlgorithmNamesForKey(signingKP.getPrivate())) {
try {
this.gen = new AS2SignedDataGenerator();
this.gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC")
.setSignedAttributeGenerator(new AttributeTable(attributes))
.build(signingAlgorithmName, signingKP.getPrivate(), signingCert));
this.gen.addCertificates(certs);
break;
} catch (Exception e) {
this.gen = null;
continue;
}
}
if (this.gen == null) {
throw new Exception("failed to create signing generator");
}
}
@Test
public void plainEDIMessageTest() 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.PLAIN, ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII),
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());
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.APPLICATION_EDIFACT));
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 ApplicationEDIFACTEntity);
ApplicationEDIFACTEntity ediEntity = (ApplicationEDIFACTEntity) entity;
assertTrue("Unexpected content type for entity",
ediEntity.getContentType().getValue().startsWith(AS2MediaType.APPLICATION_EDIFACT));
assertTrue("Entity not set as main body of request", ediEntity.isMainBody());
}
@Test
public void multipartSignedMessageTest() 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, AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(),
null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, 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 aes128CbcEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.AES128_CBC);
}
@Test
public void aes192CbcEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.AES192_CBC);
}
@Test
public void aes256CbcEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.AES256_CBC);
}
@Test
public void aes128CcmEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.AES128_CCM);
}
@Test
public void aes192CcmEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.AES192_CCM);
}
@Test
public void aes256CcmEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.AES256_CCM);
}
@Test
public void aes128GcmEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.AES128_GCM);
}
@Test
public void aes192GcmEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.AES192_GCM);
}
@Test
public void aes256GcmEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.AES256_GCM);
}
@Test
public void camellia128CbcEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.CAMELLIA128_CBC);
}
@Test
public void camellia192CbcEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.CAMELLIA192_CBC);
}
@Test
public void camellia256CbcEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.CAMELLIA256_CBC);
}
@Test
public void cast5CbcEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.CAST5_CBC);
}
@Test
public void desCbcEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.DES_CBC);
}
@Test
public void desEde3CbcEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.DES_EDE3_CBC);
}
@Test
public void cost28147GcfbEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.GOST28147_GCFB);
}
@Test
public void ideaCbcEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.IDEA_CBC);
}
@Test
public void rc2CbcEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.RC2_CBC);
}
@Test
public void rc4EnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.RC4);
}
@Test
public void seedCbcEnvelopedMessageTest() throws Exception {
envelopedMessageTest(AS2EncryptionAlgorithm.SEED_CBC);
}
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);
LOG.info("Key Algoritm: " + signingKP.getPrivate().getAlgorithm());
HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME,
AS2MessageStructure.ENCRYPTED,
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]));
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 ApplicationPkcs7MimeEnvelopedDataEntity);
ApplicationPkcs7MimeEnvelopedDataEntity envelopedEntity = (ApplicationPkcs7MimeEnvelopedDataEntity) 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 ApplicationEDIFACTEntity);
ApplicationEDIFACTEntity ediEntity = (ApplicationEDIFACTEntity) encryptedEntity;
assertTrue("Unexpected content type for enveloped mime part",
ediEntity.getContentType().getValue().startsWith(AS2MediaType.APPLICATION_EDIFACT));
assertFalse("Enveloped mime type set as main body of request", ediEntity.isMainBody());
assertEquals("Unexpected content for enveloped mime part", EDI_MESSAGE.replaceAll("[\n\r]", ""),
ediEntity.getEdiMessage().replaceAll("[\n\r]", ""));
}
@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.SIGNED_ENCRYPTED,
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]));
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 ApplicationPkcs7MimeEnvelopedDataEntity);
ApplicationPkcs7MimeEnvelopedDataEntity envelopedEntity = (ApplicationPkcs7MimeEnvelopedDataEntity) 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);
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, AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(),
null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null);
HttpRequest request = httpContext.getRequest();
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 multipartSignedEntity = (MultipartSignedEntity) entity;
MimeEntity signedEntity = multipartSignedEntity.getSignedDataEntity();
assertTrue("Signed entity wrong type", signedEntity instanceof ApplicationEDIEntity);
ApplicationEDIEntity ediMessageEntity = (ApplicationEDIEntity) signedEntity;
assertNotNull("Multipart signed entity does not contain EDI message entity", ediMessageEntity);
ApplicationPkcs7SignatureEntity signatureEntity = multipartSignedEntity.getSignatureEntity();
assertNotNull("Multipart signed entity does not contain signature entity", signatureEntity);
// Validate Signature
assertTrue("Signature is invalid", multipartSignedEntity.isValid());
}
@Test
public void mdnMessageTest() 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.PLAIN, ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII),
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());
assertEquals("Unexpected method value", HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
assertEquals("Unexpected method value", EnglishReasonPhraseCatalog.INSTANCE.getReason(200, null),
response.getStatusLine().getReasonPhrase());
HttpEntity responseEntity = response.getEntity();
assertNotNull("Response entity", responseEntity);
assertTrue("Unexpected response entity type", responseEntity instanceof MultipartSignedEntity);
MultipartSignedEntity responseSignedEntity = (MultipartSignedEntity) responseEntity;
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);
// Validate Signature
assertTrue("Signature is invalid", responseSignedEntity.isValid());
}
@Test
public void asynchronousMdnMessageTest() throws Exception {
AS2AsynchronousMDNManager mdnManager = new AS2AsynchronousMDNManager(AS2_VERSION, USER_AGENT, CLIENT_FQDN,
certList.toArray(new X509Certificate[0]), signingKP.getPrivate());
// Create plain edi request message to acknowledge
ApplicationEDIEntity ediEntity = EntityUtils.createEDIEntity(EDI_MESSAGE,
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), null, false);
HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", REQUEST_URI);
HttpMessageUtils.setHeaderValue(request, AS2Header.SUBJECT, SUBJECT);
String httpdate = DATE_GENERATOR.getCurrentDate();
HttpMessageUtils.setHeaderValue(request, AS2Header.DATE, httpdate);
HttpMessageUtils.setHeaderValue(request, AS2Header.AS2_TO, AS2_NAME);
HttpMessageUtils.setHeaderValue(request, AS2Header.AS2_FROM, AS2_NAME);
String originalMessageId = AS2Utils.createMessageId(SERVER_FQDN);
HttpMessageUtils.setHeaderValue(request, AS2Header.MESSAGE_ID, originalMessageId);
HttpMessageUtils.setHeaderValue(request, AS2Header.DISPOSITION_NOTIFICATION_OPTIONS,
DISPOSITION_NOTIFICATION_OPTIONS);
EntityUtils.setMessageEntity(request, ediEntity);
// Create response for MDN creation.
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
httpdate = DATE_GENERATOR.getCurrentDate();
response.setHeader(AS2Header.DATE, httpdate);
response.setHeader(AS2Header.SERVER, REPORTING_UA);
// Create a receipt for edi message
Map<String, String> extensionFields = new HashMap<>();
extensionFields.put("Original-Recipient", "rfc822;" + AS2_NAME);
AS2DispositionModifier dispositionModifier = AS2DispositionModifier.createWarning("AS2 is cool!");
String[] failureFields = new String[] {"failure-field-1"};
String[] errorFields = new String[] {"error-field-1"};
String[] warningFields = new String[] {"warning-field-1"};
DispositionNotificationMultipartReportEntity mdn = new DispositionNotificationMultipartReportEntity(request,
response, DispositionMode.AUTOMATIC_ACTION_MDN_SENT_AUTOMATICALLY, AS2DispositionType.PROCESSED,
dispositionModifier, failureFields, errorFields, warningFields, extensionFields, null, "boundary", true,
null, "Got ya message!");
// Send MDN
HttpCoreContext httpContext = mdnManager.send(mdn, RECIPIENT_DELIVERY_ADDRESS);
HttpRequest mndRequest = httpContext.getRequest();
DispositionNotificationMultipartReportEntity reportEntity = HttpMessageUtils.getEntity(mndRequest,
DispositionNotificationMultipartReportEntity.class);
assertNotNull("Request does not contain resport", reportEntity);
assertEquals("Report entity contains invalid number of parts", 2, reportEntity.getPartCount());
assertTrue("Report first part is not text entity", reportEntity.getPart(0) instanceof TextPlainEntity);
assertTrue("Report second part is not MDN entity",
reportEntity.getPart(1) instanceof AS2MessageDispositionNotificationEntity);
AS2MessageDispositionNotificationEntity mdnEntity = (AS2MessageDispositionNotificationEntity) reportEntity
.getPart(1);
assertEquals("Unexpected value for Reporting UA", REPORTING_UA, mdnEntity.getReportingUA());
assertEquals("Unexpected value for Final Recipient", AS2_NAME, mdnEntity.getFinalRecipient());
assertEquals("Unexpected value for Original Message ID", originalMessageId, mdnEntity.getOriginalMessageId());
assertEquals("Unexpected value for Disposition Mode", DispositionMode.AUTOMATIC_ACTION_MDN_SENT_AUTOMATICALLY,
mdnEntity.getDispositionMode());
assertEquals("Unexpected value for Disposition Type", AS2DispositionType.PROCESSED,
mdnEntity.getDispositionType());
assertEquals("Unexpected value for Disposition Modifier", dispositionModifier,
mdnEntity.getDispositionModifier());
assertArrayEquals("Unexpected value for Failure Fields", failureFields, mdnEntity.getFailureFields());
assertArrayEquals("Unexpected value for Error Fields", errorFields, mdnEntity.getErrorFields());
assertArrayEquals("Unexpected value for Warning Fields", warningFields, mdnEntity.getWarningFields());
assertEquals("Unexpected value for Extension Fields", extensionFields, mdnEntity.getExtensionFields());
ReceivedContentMic expectedMic = MicUtils.createReceivedContentMic(request, null);
ReceivedContentMic mdnMic = mdnEntity.getReceivedContentMic();
assertEquals("Unexpected value for Recieved Content Mic", expectedMic.getEncodedMessageDigest(),
mdnMic.getEncodedMessageDigest());
LOG.debug("\r\n" + AS2Utils.printMessage(mndRequest));
}
@Test
public void compressedMessageTest() 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.PLAIN_COMPRESSED,
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), null,
null, null, null, AS2CompressionAlgorithm.ZLIB,
DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, 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(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 ApplicationPkcs7MimeCompressedDataEntity);
ApplicationPkcs7MimeCompressedDataEntity compressedDataEntity = (ApplicationPkcs7MimeCompressedDataEntity) entity;
assertTrue("Entity not set as main body of request", compressedDataEntity.isMainBody());
// Validated compessed part.
MimeEntity compressedEntity = compressedDataEntity.getCompressedEntity(new ZlibExpanderProvider());
assertTrue("Enveloped mime part incorrect type ", compressedEntity instanceof ApplicationEDIFACTEntity);
ApplicationEDIFACTEntity ediEntity = (ApplicationEDIFACTEntity) compressedEntity;
assertTrue("Unexpected content type for compressed entity",
ediEntity.getContentType().getValue().startsWith(AS2MediaType.APPLICATION_EDIFACT));
assertFalse("Compressed entity set as main body of request", ediEntity.isMainBody());
}
@Test
public void compressedAndSignedMessageTest() 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.SIGNED_COMPRESSED,
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);
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 ApplicationPkcs7MimeCompressedDataEntity);
ApplicationPkcs7MimeCompressedDataEntity compressedDataEntity = (ApplicationPkcs7MimeCompressedDataEntity) entity;
assertTrue("Entity not set as main body of request", compressedDataEntity.isMainBody());
// Validated compressed part.
MimeEntity compressedEntity = compressedDataEntity.getCompressedEntity(new ZlibExpanderProvider());
assertTrue("Enveloped mime part incorrect type ", compressedEntity instanceof MultipartSignedEntity);
MultipartSignedEntity multipartSignedEntity = (MultipartSignedEntity) compressedEntity;
assertTrue("Unexpected content type for compressed entity",
multipartSignedEntity.getContentType().getValue().startsWith(AS2MediaType.MULTIPART_SIGNED));
assertFalse("Multipart signed entity set as main body of request", multipartSignedEntity.isMainBody());
assertTrue("Multipart signed entity 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 envelopedAndCompressedMessageTest() 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_COMPRESSED,
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]));
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 ApplicationPkcs7MimeEnvelopedDataEntity);
ApplicationPkcs7MimeEnvelopedDataEntity envelopedEntity = (ApplicationPkcs7MimeEnvelopedDataEntity) 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 ApplicationPkcs7MimeCompressedDataEntity);
ApplicationPkcs7MimeCompressedDataEntity compressedDataEntity = (ApplicationPkcs7MimeCompressedDataEntity) encryptedEntity;
assertTrue("Unexpected content type for compressed mime part",
compressedDataEntity.getContentType().getValue().startsWith(AS2MimeType.APPLICATION_PKCS7_MIME));
assertFalse("Enveloped mime type set as main body of request", compressedDataEntity.isMainBody());
// Validated compressed part.
MimeEntity compressedEntity = compressedDataEntity.getCompressedEntity(new ZlibExpanderProvider());
assertTrue("Enveloped mime part incorrect type ", compressedEntity instanceof ApplicationEDIFACTEntity);
ApplicationEDIFACTEntity ediEntity = (ApplicationEDIFACTEntity) compressedEntity;
assertTrue("Unexpected content type for compressed entity",
ediEntity.getContentType().getValue().startsWith(AS2MediaType.APPLICATION_EDIFACT));
assertFalse("Compressed entity set as main body of request", ediEntity.isMainBody());
assertEquals("Unexpected content for enveloped mime part", EDI_MESSAGE.replaceAll("[\n\r]", ""),
ediEntity.getEdiMessage().replaceAll("[\n\r]", ""));
}
@Test
public void envelopedCompressedAndSignedMessageTest() 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_COMPRESSED_SIGNED,
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]));
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 ApplicationPkcs7MimeEnvelopedDataEntity);
ApplicationPkcs7MimeEnvelopedDataEntity envelopedEntity = (ApplicationPkcs7MimeEnvelopedDataEntity) 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 ApplicationPkcs7MimeCompressedDataEntity);
ApplicationPkcs7MimeCompressedDataEntity compressedDataEntity = (ApplicationPkcs7MimeCompressedDataEntity) encryptedEntity;
assertTrue("Unexpected content type for compressed mime part",
compressedDataEntity.getContentType().getValue().startsWith(AS2MimeType.APPLICATION_PKCS7_MIME));
assertFalse("Enveloped mime type set as main body of request", compressedDataEntity.isMainBody());
// Validated compressed part.
MimeEntity compressedEntity = compressedDataEntity.getCompressedEntity(new ZlibExpanderProvider());
assertTrue("Enveloped mime part incorrect type ", compressedEntity instanceof MultipartSignedEntity);
MultipartSignedEntity multipartSignedEntity = (MultipartSignedEntity) compressedEntity;
assertTrue("Unexpected content type for compressed entity",
multipartSignedEntity.getContentType().getValue().startsWith(AS2MediaType.MULTIPART_SIGNED));
assertFalse("Multipart signed entity set as main body of request", multipartSignedEntity.isMainBody());
assertTrue("Multipart signed entity 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());
}
}