[
https://issues.apache.org/jira/browse/CAMEL-12605?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16595980#comment-16595980
]
ASF GitHub Bot commented on CAMEL-12605:
----------------------------------------
oscerd closed pull request #2495: [CAMEL-12605] Integrated encryption logic
into component.
URL: https://github.com/apache/camel/pull/2495
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2Algorithm.java
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2Algorithm.java
new file mode 100644
index 00000000000..8e71f478ff2
--- /dev/null
+++
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2Algorithm.java
@@ -0,0 +1,346 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.as2.api;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.cms.CMSAlgorithm;
+
+interface AS2AlgorithmConstants {
+ static final String DES_CBC = "DES_CBC";
+ static final String DES_EDE3_CBC = "DES_EDE3_CBC";
+ static final String RC2_CBC = "RC2_CBC";
+ static final String IDEA_CBC = "IDEA_CBC";
+ static final String CAST5_CBC = "CAST5_CBC";
+ static final String AES128_CBC = "AES128_CBC";
+ static final String AES192_CBC = "AES192_CBC";
+ static final String AES256_CBC = "AES256_CBC";
+ static final String AES128_CCM = "AES128_CCM";
+ static final String AES192_CCM = "AES192_CCM";
+ static final String AES256_CCM = "AES256_CCM";
+ static final String AES128_GCM = "AES128_GCM";
+ static final String AES192_GCM = "AES192_GCM";
+ static final String AES256_GCM = "AES256_GCM";
+ static final String CAMELLIA128_CBC = "CAMELLIA128_CBC";
+ static final String CAMELLIA192_CBC = "CAMELLIA192_CBC";
+ static final String CAMELLIA256_CBC = "CAMELLIA256_CBC";
+ static final String GOST28147_GCFB = "GOST28147_GCFB";
+ static final String SEED_CBC = "SEED_CBC";
+ static final String DES_EDE3_WRAP = "DES_EDE3_WRAP";
+ static final String AES128_WRAP = "AES128_WRAP";
+ static final String AES192_WRAP = "AES192_WRAP";
+ static final String AES256_WRAP = "AES256_WRAP";
+ static final String CAMELLIA128_WRAP = "CAMELLIA128_WRAP";
+ static final String CAMELLIA192_WRAP = "CAMELLIA192_WRAP";
+ static final String CAMELLIA256_WRAP = "CAMELLIA256_WRAP";
+ static final String SEED_WRAP = "SEED_WRAP";
+ static final String GOST28147_WRAP = "GOST28147_WRAP";
+ static final String GOST28147_CRYPTOPRO_WRAP = "GOST28147_CRYPTOPRO_WRAP";
+ static final String ECDH_SHA1KDF = "ECDH_SHA1KDF";
+ static final String ECCDH_SHA1KDF = "ECCDH_SHA1KDF";
+ static final String ECMQV_SHA1KDF = "ECMQV_SHA1KDF";
+ static final String ECDH_SHA224KDF = "ECDH_SHA224KDF";
+ static final String ECCDH_SHA224KDF = "ECCDH_SHA224KDF";
+ static final String ECMQV_SHA224KDF = "ECMQV_SHA224KDF";
+ static final String ECDH_SHA256KDF = "ECDH_SHA256KDF";
+ static final String ECCDH_SHA256KDF = "ECCDH_SHA256KDF";
+ static final String ECMQV_SHA256KDF = "ECMQV_SHA256KDF";
+ static final String ECDH_SHA384KDF = "ECDH_SHA384KDF";
+ static final String ECCDH_SHA384KDF = "ECCDH_SHA384KDF";
+ static final String ECMQV_SHA384KDF = "ECMQV_SHA384KDF";
+ static final String ECDH_SHA512KDF = "ECDH_SHA512KDF";
+ static final String ECCDH_SHA512KDF = "ECCDH_SHA512KDF";
+ static final String ECMQV_SHA512KDF = "ECMQV_SHA512KDF";
+ static final String ECDHGOST3410_2001 = "ECDHGOST3410_2001";
+ static final String ECDHGOST3410_2012_256 = "ECDHGOST3410_2012_256";
+ static final String ECDHGOST3410_2012_512 = "ECDHGOST3410_2012_512";
+ static final String SHA1 = "SHA1";
+ static final String SHA224 = "SHA224";
+ static final String SHA256 = "SHA256";
+ static final String SHA384 = "SHA384";
+ static final String SHA512 = "SHA512";
+ static final String MD5 = "MD5";
+ static final String GOST3411 = "GOST3411";
+ static final String GOST3411_2012_256 = "GOST3411_2012_256";
+ static final String GOST3411_2012_512 = "GOST3411_2012_512";
+ static final String RIPEMD128 = "RIPEMD128";
+ static final String RIPEMD160 = "RIPEMD160";
+ static final String RIPEMD256 = "RIPEMD256";
+}
+
+public enum AS2Algorithm {
+ DES_CBC(AS2AlgorithmConstants.DES_CBC, CMSAlgorithm.DES_CBC),
+ DES_EDE3_CBC(AS2AlgorithmConstants.DES_EDE3_CBC,
CMSAlgorithm.DES_EDE3_CBC),
+ RC2_CBC(AS2AlgorithmConstants.RC2_CBC, CMSAlgorithm.RC2_CBC),
+ IDEA_CBC(AS2AlgorithmConstants.IDEA_CBC, CMSAlgorithm.IDEA_CBC),
+ CAST5_CBC(AS2AlgorithmConstants.CAST5_CBC, CMSAlgorithm.CAST5_CBC),
+ AES128_CBC(AS2AlgorithmConstants.AES128_CBC, CMSAlgorithm.AES128_CBC),
+ AES192_CBC(AS2AlgorithmConstants.AES192_CBC, CMSAlgorithm.AES192_CBC),
+ AES256_CBC(AS2AlgorithmConstants.AES256_CBC, CMSAlgorithm.AES256_CBC),
+ AES128_CCM(AS2AlgorithmConstants.AES128_CCM, CMSAlgorithm.AES128_CCM),
+ AES192_CCM(AS2AlgorithmConstants.AES192_CCM, CMSAlgorithm.AES192_CCM),
+ AES256_CCM(AS2AlgorithmConstants.AES256_CCM, CMSAlgorithm.AES256_CCM),
+ AES128_GCM(AS2AlgorithmConstants.AES128_GCM, CMSAlgorithm.AES128_GCM),
+ AES192_GCM(AS2AlgorithmConstants.AES192_GCM, CMSAlgorithm.AES192_GCM),
+ AES256_GCM(AS2AlgorithmConstants.AES256_GCM, CMSAlgorithm.AES256_GCM),
+ CAMELLIA128_CBC(AS2AlgorithmConstants.CAMELLIA128_CBC,
CMSAlgorithm.CAMELLIA128_CBC),
+ CAMELLIA192_CBC(AS2AlgorithmConstants.CAMELLIA192_CBC,
CMSAlgorithm.CAMELLIA192_CBC),
+ CAMELLIA256_CBC(AS2AlgorithmConstants.CAMELLIA256_CBC,
CMSAlgorithm.CAMELLIA256_CBC),
+ GOST28147_GCFB(AS2AlgorithmConstants.GOST28147_GCFB,
CMSAlgorithm.GOST28147_GCFB),
+ SEED_CBC(AS2AlgorithmConstants.SEED_CBC, CMSAlgorithm.SEED_CBC),
+ DES_EDE3_WRAP(AS2AlgorithmConstants.DES_EDE3_WRAP,
CMSAlgorithm.DES_EDE3_WRAP),
+ AES128_WRAP(AS2AlgorithmConstants.AES128_WRAP, CMSAlgorithm.AES128_WRAP),
+ AES192_WRAP(AS2AlgorithmConstants.AES192_WRAP, CMSAlgorithm.AES192_WRAP),
+ AES256_WRAP(AS2AlgorithmConstants.AES256_WRAP, CMSAlgorithm.AES256_WRAP),
+ CAMELLIA128_WRAP(AS2AlgorithmConstants.CAMELLIA128_WRAP,
CMSAlgorithm.CAMELLIA128_WRAP),
+ CAMELLIA192_WRAP(AS2AlgorithmConstants.CAMELLIA192_WRAP,
CMSAlgorithm.CAMELLIA192_WRAP),
+ CAMELLIA256_WRAP(AS2AlgorithmConstants.CAMELLIA256_WRAP,
CMSAlgorithm.CAMELLIA256_WRAP),
+ SEED_WRAP(AS2AlgorithmConstants.SEED_WRAP, CMSAlgorithm.SEED_WRAP),
+ GOST28147_WRAP(AS2AlgorithmConstants.GOST28147_WRAP,
CMSAlgorithm.GOST28147_WRAP),
+ GOST28147_CRYPTOPRO_WRAP(AS2AlgorithmConstants.GOST28147_CRYPTOPRO_WRAP,
CMSAlgorithm.GOST28147_CRYPTOPRO_WRAP),
+ ECDH_SHA1KDF(AS2AlgorithmConstants.ECDH_SHA1KDF,
CMSAlgorithm.ECDH_SHA1KDF),
+ ECCDH_SHA1KDF(AS2AlgorithmConstants.ECCDH_SHA1KDF,
CMSAlgorithm.ECCDH_SHA1KDF),
+ ECMQV_SHA1KDF(AS2AlgorithmConstants.ECMQV_SHA1KDF,
CMSAlgorithm.ECMQV_SHA1KDF),
+ ECDH_SHA224KDF(AS2AlgorithmConstants.ECDH_SHA224KDF,
CMSAlgorithm.ECDH_SHA224KDF),
+ ECCDH_SHA224KDF(AS2AlgorithmConstants.ECCDH_SHA224KDF,
CMSAlgorithm.ECCDH_SHA224KDF),
+ ECMQV_SHA224KDF(AS2AlgorithmConstants.ECMQV_SHA224KDF,
CMSAlgorithm.ECMQV_SHA224KDF),
+ ECDH_SHA256KDF(AS2AlgorithmConstants.ECDH_SHA256KDF,
CMSAlgorithm.ECDH_SHA256KDF),
+ ECCDH_SHA256KDF(AS2AlgorithmConstants.ECCDH_SHA256KDF,
CMSAlgorithm.ECCDH_SHA256KDF),
+ ECMQV_SHA256KDF(AS2AlgorithmConstants.ECMQV_SHA256KDF,
CMSAlgorithm.ECMQV_SHA256KDF),
+ ECDH_SHA384KDF(AS2AlgorithmConstants.ECDH_SHA384KDF,
CMSAlgorithm.ECDH_SHA384KDF),
+ ECCDH_SHA384KDF(AS2AlgorithmConstants.ECCDH_SHA384KDF,
CMSAlgorithm.ECCDH_SHA384KDF),
+ ECMQV_SHA384KDF(AS2AlgorithmConstants.ECMQV_SHA384KDF,
CMSAlgorithm.ECMQV_SHA384KDF),
+ ECDH_SHA512KDF(AS2AlgorithmConstants.ECDH_SHA512KDF,
CMSAlgorithm.ECDH_SHA512KDF),
+ ECCDH_SHA512KDF(AS2AlgorithmConstants.ECCDH_SHA512KDF,
CMSAlgorithm.ECCDH_SHA512KDF),
+ ECMQV_SHA512KDF(AS2AlgorithmConstants.ECMQV_SHA512KDF,
CMSAlgorithm.ECMQV_SHA512KDF),
+ ECDHGOST3410_2001(AS2AlgorithmConstants.ECDHGOST3410_2001,
CMSAlgorithm.ECDHGOST3410_2001),
+ ECDHGOST3410_2012_256(AS2AlgorithmConstants.ECDHGOST3410_2012_256,
CMSAlgorithm.ECDHGOST3410_2012_256),
+ ECDHGOST3410_2012_512(AS2AlgorithmConstants.ECDHGOST3410_2012_512,
CMSAlgorithm.ECDHGOST3410_2012_512),
+ SHA1(AS2AlgorithmConstants.SHA1, CMSAlgorithm.SHA1),
+ SHA224(AS2AlgorithmConstants.SHA224, CMSAlgorithm.SHA224),
+ SHA256(AS2AlgorithmConstants.SHA256, CMSAlgorithm.SHA256),
+ SHA384(AS2AlgorithmConstants.SHA384, CMSAlgorithm.SHA384),
+ SHA512(AS2AlgorithmConstants.SHA512, CMSAlgorithm.SHA512),
+ MD5(AS2AlgorithmConstants.MD5, CMSAlgorithm.MD5),
+ GOST3411(AS2AlgorithmConstants.GOST3411, CMSAlgorithm.GOST3411),
+ GOST3411_2012_256(AS2AlgorithmConstants.GOST3411_2012_256,
CMSAlgorithm.GOST3411_2012_256),
+ GOST3411_2012_512(AS2AlgorithmConstants.GOST3411_2012_512,
CMSAlgorithm.GOST3411_2012_512),
+ RIPEMD128(AS2AlgorithmConstants.RIPEMD128, CMSAlgorithm.RIPEMD128),
+ RIPEMD160(AS2AlgorithmConstants.RIPEMD160, CMSAlgorithm.RIPEMD160),
+ RIPEMD256(AS2AlgorithmConstants.RIPEMD256, CMSAlgorithm.RIPEMD256);
+
+ private String algorithmName;
+ private ASN1ObjectIdentifier algorithmOID;
+
+ private AS2Algorithm(String algorithmName, ASN1ObjectIdentifier
algorithmOID) {
+ this.algorithmName = algorithmName;
+ this.algorithmOID = algorithmOID;
+ }
+ public String getAlgorithmName() {
+ return algorithmName;
+ }
+ public ASN1ObjectIdentifier getAlgorithmOID() {
+ return algorithmOID;
+ }
+
+ public static AS2Algorithm getAS2Algorithm(String algorithmName) {
+ AS2Algorithm as2Algorithm;
+ switch (algorithmName) {
+ case "DES_CBC":
+ as2Algorithm = DES_CBC;
+ break;
+ case "DES_EDE3_CBC":
+ as2Algorithm = DES_EDE3_CBC;
+ break;
+ case "RC2_CBC":
+ as2Algorithm = RC2_CBC;
+ break;
+ case "IDEA_CBC":
+ as2Algorithm = IDEA_CBC;
+ break;
+ case "CAST5_CBC":
+ as2Algorithm = CAST5_CBC;
+ break;
+ case "AES128_CBC":
+ as2Algorithm = AES128_CBC;
+ break;
+ case "AES192_CBC":
+ as2Algorithm = AES192_CBC;
+ break;
+ case "AES256_CBC":
+ as2Algorithm = AES256_CBC;
+ break;
+ case "AES128_CCM":
+ as2Algorithm = AES128_CCM;
+ break;
+ case "AES192_CCM":
+ as2Algorithm = AES192_CCM;
+ break;
+ case "AES256_CCM":
+ as2Algorithm = AES256_CCM;
+ break;
+ case "AES128_GCM":
+ as2Algorithm = AES128_GCM;
+ break;
+ case "AES192_GCM":
+ as2Algorithm = AES192_GCM;
+ break;
+ case "AES256_GCM":
+ as2Algorithm = AES256_GCM;
+ break;
+ case "CAMELLIA128_CBC":
+ as2Algorithm = CAMELLIA128_CBC;
+ break;
+ case "CAMELLIA192_CBC":
+ as2Algorithm = CAMELLIA192_CBC;
+ break;
+ case "CAMELLIA256_CBC":
+ as2Algorithm = CAMELLIA256_CBC;
+ break;
+ case "GOST28147_GCFB":
+ as2Algorithm = GOST28147_GCFB;
+ break;
+ case "SEED_CBC":
+ as2Algorithm = SEED_CBC;
+ break;
+ case "DES_EDE3_WRAP":
+ as2Algorithm = DES_EDE3_WRAP;
+ break;
+ case "AES128_WRAP":
+ as2Algorithm = AES128_WRAP;
+ break;
+ case "AES192_WRAP":
+ as2Algorithm = AES192_WRAP;
+ break;
+ case "AES256_WRAP":
+ as2Algorithm = AES256_WRAP;
+ break;
+ case "CAMELLIA128_WRAP":
+ as2Algorithm = CAMELLIA128_WRAP;
+ break;
+ case "CAMELLIA192_WRAP":
+ as2Algorithm = CAMELLIA192_WRAP;
+ break;
+ case "CAMELLIA256_WRAP":
+ as2Algorithm = CAMELLIA256_WRAP;
+ break;
+ case "SEED_WRAP":
+ as2Algorithm = SEED_WRAP;
+ break;
+ case "GOST28147_WRAP":
+ as2Algorithm = GOST28147_WRAP;
+ break;
+ case "GOST28147_CRYPTOPRO_WRAP":
+ as2Algorithm = GOST28147_CRYPTOPRO_WRAP;
+ break;
+ case "ECDH_SHA1KDF":
+ as2Algorithm = ECDH_SHA1KDF;
+ break;
+ case "ECCDH_SHA1KDF":
+ as2Algorithm = ECCDH_SHA1KDF;
+ break;
+ case "ECMQV_SHA1KDF":
+ as2Algorithm = ECMQV_SHA1KDF;
+ break;
+ case "ECDH_SHA224KDF":
+ as2Algorithm = ECDH_SHA224KDF;
+ break;
+ case "ECCDH_SHA224KDF":
+ as2Algorithm = ECCDH_SHA224KDF;
+ break;
+ case "ECMQV_SHA224KDF":
+ as2Algorithm = ECMQV_SHA224KDF;
+ break;
+ case "ECDH_SHA256KDF":
+ as2Algorithm = ECDH_SHA256KDF;
+ break;
+ case "ECCDH_SHA256KDF":
+ as2Algorithm = ECCDH_SHA256KDF;
+ break;
+ case "ECMQV_SHA256KDF":
+ as2Algorithm = ECMQV_SHA256KDF;
+ break;
+ case "ECDH_SHA384KDF":
+ as2Algorithm = ECDH_SHA384KDF;
+ break;
+ case "ECCDH_SHA384KDF":
+ as2Algorithm = ECCDH_SHA384KDF;
+ break;
+ case "ECMQV_SHA384KDF":
+ as2Algorithm = ECMQV_SHA384KDF;
+ break;
+ case "ECDH_SHA512KDF":
+ as2Algorithm = ECDH_SHA512KDF;
+ break;
+ case "ECCDH_SHA512KDF":
+ as2Algorithm = ECCDH_SHA512KDF;
+ break;
+ case "ECMQV_SHA512KDF":
+ as2Algorithm = ECMQV_SHA512KDF;
+ break;
+ case "ECDHGOST3410_2001":
+ as2Algorithm = ECDHGOST3410_2001;
+ break;
+ case "ECDHGOST3410_2012_256":
+ as2Algorithm = ECDHGOST3410_2012_256;
+ break;
+ case "ECDHGOST3410_2012_512":
+ as2Algorithm = ECDHGOST3410_2012_512;
+ break;
+ case "SHA1":
+ as2Algorithm = SHA1;
+ break;
+ case "SHA224":
+ as2Algorithm = SHA224;
+ break;
+ case "SHA256":
+ as2Algorithm = SHA256;
+ break;
+ case "SHA384":
+ as2Algorithm = SHA384;
+ break;
+ case "SHA512":
+ as2Algorithm = SHA512;
+ break;
+ case "MD5":
+ as2Algorithm = MD5;
+ break;
+ case "GOST3411":
+ as2Algorithm = GOST3411;
+ break;
+ case "GOST3411_2012_256":
+ as2Algorithm = GOST3411_2012_256;
+ break;
+ case "GOST3411_2012_512":
+ as2Algorithm = GOST3411_2012_512;
+ break;
+ case "RIPEMD128":
+ as2Algorithm = RIPEMD128;
+ break;
+ case "RIPEMD160":
+ as2Algorithm = RIPEMD160;
+ break;
+ case "RIPEMD256":
+ as2Algorithm = RIPEMD256;
+ break;
+
+ default:
+ throw new IllegalArgumentException("Unsupported algorithm '" +
algorithmName + "'");
+ }
+ return as2Algorithm;
+ }
+
+}
diff --git
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientManager.java
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientManager.java
index 4e22e7baf77..9c33d9a576e 100644
---
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientManager.java
+++
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientManager.java
@@ -21,8 +21,10 @@
import java.security.cert.Certificate;
import org.apache.camel.component.as2.api.entity.ApplicationEDIEntity;
+import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeEntity;
import org.apache.camel.component.as2.api.entity.EntityParser;
import org.apache.camel.component.as2.api.entity.MultipartSignedEntity;
+import org.apache.camel.component.as2.api.util.EncryptingUtils;
import org.apache.camel.component.as2.api.util.EntityUtils;
import org.apache.camel.component.as2.api.util.SigningUtils;
import org.apache.http.HttpException;
@@ -31,6 +33,8 @@
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
import org.apache.http.protocol.HttpCoreContext;
import org.apache.http.util.Args;
+import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
+import org.bouncycastle.operator.OutputEncryptor;
/**
* AS2 Client Manager
@@ -134,6 +138,24 @@
*/
public static final String SIGNING_PRIVATE_KEY = CAMEL_AS2_CLIENT_PREFIX +
"signing-private-key";
+ /**
+ * The HTTP Context Attribute containing the algorithm name used to
encrypt EDI
+ * message
+ */
+ public static final String ENCRYPTING_ALGORITHM_NAME =
CAMEL_AS2_CLIENT_PREFIX + "encrypting-algorithm-name";
+
+ /**
+ * The HTTP Context Attribute containing the certificate used to encrypt
+ * EDI message
+ */
+ public static final String ENCRYPTING_CERTIFICATE_CHAIN =
CAMEL_AS2_CLIENT_PREFIX + "encrypting-certificate-chain";
+
+ /**
+ * The HTTP Context Attribute containing the private key used to encrypt
EDI
+ * message
+ */
+ public static final String ENCRYPTING_PRIVATE_KEY =
CAMEL_AS2_CLIENT_PREFIX + "encrypting-private-key";
+
/**
* The HTTP Context Attribute containing the internet e-mail address of
* sending system requesting a message disposition notification.
@@ -172,6 +194,9 @@ public AS2ClientManager(AS2ClientConnection
as2ClientConnection) {
* @param signingPrivateKey - the private key used to sign EDI message
* @param dispositionNotificationTo - an RFC2822 address to request a
receipt or <code>null</code> if no receipt requested
* @param signedReceiptMicAlgorithms - the senders list of signing
algorithms for signing receipt, in preferred order, or <code>null</code> if
requesting an unsigned receipt.
+ * @param encryptionAlgorithmName - the name of the algorithm used to
encrypt the message or <code>null</code> if sending EDI message unencrypted
+ * @param encryptionCertificateChain - the chain of certificates used to
encrypt the message or <code>null</code> if sending EDI message unencrypted
+ * @param encryptionPrivateKey - the private key used to encrypt EDI
message
* @return {@link HttpCoreContext} containing request and response used to
send EDI message
* @throws HttpException when things go wrong.
*/
@@ -187,7 +212,10 @@ public HttpCoreContext send(String ediMessage,
Certificate[] signingCertificateChain,
PrivateKey signingPrivateKey,
String dispositionNotificationTo,
- String[] signedReceiptMicAlgorithms)
+ String[] signedReceiptMicAlgorithms,
+ String encryptionAlgorithmName,
+ Certificate[] encryptionCertificateChain,
+ PrivateKey encryptionPrivateKey)
throws HttpException {
Args.notNull(ediMessage, "EDI Message");
@@ -209,6 +237,9 @@ public HttpCoreContext send(String ediMessage,
httpContext.setAttribute(AS2ClientManager.SIGNING_PRIVATE_KEY,
signingPrivateKey);
httpContext.setAttribute(AS2ClientManager.DISPOSITION_NOTIFICATION_TO,
dispositionNotificationTo);
httpContext.setAttribute(AS2ClientManager.SIGNED_RECEIPT_MIC_ALGORITHMS,
signedReceiptMicAlgorithms);
+ httpContext.setAttribute(AS2ClientManager.ENCRYPTING_ALGORITHM_NAME,
encryptionAlgorithmName);
+
httpContext.setAttribute(AS2ClientManager.ENCRYPTING_CERTIFICATE_CHAIN,
encryptionCertificateChain);
+ httpContext.setAttribute(AS2ClientManager.ENCRYPTING_PRIVATE_KEY,
encryptionPrivateKey);
BasicHttpEntityEnclosingRequest request = new
BasicHttpEntityEnclosingRequest("POST", requestUri);
httpContext.setAttribute(HTTP_REQUEST, request);
@@ -238,7 +269,10 @@ public HttpCoreContext send(String ediMessage,
}
break;
case ENCRYPTED:
- // TODO : Add code here to add application/pkcs7-mime entity when
encryption facility available.
+ CMSEnvelopedDataGenerator envelopedDataGenerator =
createEncryptingGenerator(httpContext);
+ OutputEncryptor encryptor = createEncryptor(httpContext);
+ ApplicationPkcs7MimeEntity pkcs7MimeEntity = new
ApplicationPkcs7MimeEntity(applicationEDIEntity, envelopedDataGenerator,
encryptor, AS2TransferEncoding.BASE64, true);
+ EntityUtils.setMessageEntity(request, pkcs7MimeEntity);
break;
case ENCRYPTED_SIGNED:
// TODO : Add code here to add application/pkcs7-mime entity when
encryption facility available.
@@ -275,20 +309,25 @@ public AS2SignedDataGenerator
createSigningGenerator(HttpCoreContext httpContext
}
- public AS2SignedDataGenerator createEncryptingGenerator(HttpCoreContext
httpContext) throws HttpException {
+ public CMSEnvelopedDataGenerator createEncryptingGenerator(HttpCoreContext
httpContext) throws HttpException {
- Certificate[] certificateChain =
httpContext.getAttribute(SIGNING_CERTIFICATE_CHAIN, Certificate[].class);
+ Certificate[] certificateChain =
httpContext.getAttribute(ENCRYPTING_CERTIFICATE_CHAIN, Certificate[].class);
if (certificateChain == null) {
- throw new HttpException("Signing certificate chain missing");
+ throw new HttpException("Encrypting certificate chain missing");
}
- PrivateKey privateKey = httpContext.getAttribute(SIGNING_PRIVATE_KEY,
PrivateKey.class);
- if (privateKey == null) {
- throw new HttpException("Signing private key missing");
- }
+ return EncryptingUtils.createEnvelopDataGenerator(certificateChain);
- return SigningUtils.createSigningGenerator(certificateChain,
privateKey);
+ }
+
+ public OutputEncryptor createEncryptor(HttpCoreContext httpContext) throws
HttpException {
+
+ String algorithmName =
httpContext.getAttribute(ENCRYPTING_ALGORITHM_NAME, String.class);
+ if (algorithmName == null) {
+ throw new HttpException("Encrypting algorithm name missing");
+ }
+ return EncryptingUtils.createEncryptor(algorithmName);
}
}
diff --git
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationPkcs7MimeEntity.java
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationPkcs7MimeEntity.java
index b61b440244b..c1d6952f413 100644
---
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationPkcs7MimeEntity.java
+++
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/entity/ApplicationPkcs7MimeEntity.java
@@ -16,35 +16,25 @@
*/
package org.apache.camel.component.as2.api.entity;
-import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.security.PrivateKey;
-import java.util.Collection;
-import java.util.Iterator;
import org.apache.camel.component.as2.api.AS2Charset;
import org.apache.camel.component.as2.api.AS2Header;
import org.apache.camel.component.as2.api.CanonicalOutputStream;
-import org.apache.camel.component.as2.api.io.AS2SessionInputBuffer;
import org.apache.camel.component.as2.api.util.EntityUtils;
import org.apache.http.Header;
import org.apache.http.HeaderIterator;
import org.apache.http.HttpException;
import org.apache.http.entity.ContentType;
-import org.apache.http.impl.io.HttpTransportMetricsImpl;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.Args;
import org.bouncycastle.cms.CMSEnvelopedData;
import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSTypedData;
-import org.bouncycastle.cms.Recipient;
-import org.bouncycastle.cms.RecipientInformation;
-import org.bouncycastle.cms.RecipientInformationStore;
-import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
import org.bouncycastle.operator.OutputEncryptor;
public class ApplicationPkcs7MimeEntity extends MimeEntity {
diff --git
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/EncryptingUtils.java
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/EncryptingUtils.java
new file mode 100644
index 00000000000..8e0c9b3a347
--- /dev/null
+++
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/EncryptingUtils.java
@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.as2.api.util;
+
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.apache.camel.component.as2.api.AS2Algorithm;
+import org.apache.http.HttpException;
+import org.apache.http.util.Args;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
+import org.bouncycastle.cms.CMSException;
+import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
+import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
+import org.bouncycastle.operator.OutputEncryptor;
+
+public final class EncryptingUtils {
+
+ private EncryptingUtils() {
+ }
+
+ public static CMSEnvelopedDataGenerator
createEnvelopDataGenerator(Certificate[] encryptionCertificateChain) throws
HttpException {
+ Args.notNull(encryptionCertificateChain, "encryptionCertificateChain");
+ if (encryptionCertificateChain.length == 0 ||
!(encryptionCertificateChain[0] instanceof X509Certificate)) {
+ throw new IllegalArgumentException("Invalid certificate chain");
+ }
+
+ try {
+ X509Certificate encryptionCertificate = (X509Certificate)
encryptionCertificateChain[0];
+
+ CMSEnvelopedDataGenerator cmsEnvelopeDataGenerator = new
CMSEnvelopedDataGenerator();
+
+ JceKeyTransRecipientInfoGenerator recipientInfoGenerator = new
JceKeyTransRecipientInfoGenerator(encryptionCertificate);
+
cmsEnvelopeDataGenerator.addRecipientInfoGenerator(recipientInfoGenerator);
+
+ return cmsEnvelopeDataGenerator;
+ } catch (CertificateEncodingException e) {
+ throw new HttpException("Failed to create envelope data
generator", e);
+ }
+ }
+
+ public static OutputEncryptor createEncryptor(String
encryptionAlgorithmName) throws HttpException {
+ Args.notNull(encryptionAlgorithmName, "encryptionAlgorithmName");
+ try {
+ ASN1ObjectIdentifier algorithmOID =
AS2Algorithm.getAS2Algorithm(encryptionAlgorithmName).getAlgorithmOID();
+ return new JceCMSContentEncryptorBuilder(algorithmOID).build();
+ } catch (CMSException e) {
+ throw new HttpException("Failed to create encryptor ", e);
+ }
+ }
+}
diff --git
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/SigningUtils.java
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/SigningUtils.java
index ab608bb27c9..66aabda4cf8 100644
---
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/SigningUtils.java
+++
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/util/SigningUtils.java
@@ -24,6 +24,7 @@
import org.apache.camel.component.as2.api.AS2SignedDataGenerator;
import org.apache.http.HttpException;
+import org.apache.http.util.Args;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.cms.AttributeTable;
import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
@@ -43,7 +44,12 @@ private SigningUtils() {
}
public static AS2SignedDataGenerator createSigningGenerator(Certificate[]
certificateChain, PrivateKey privateKey) throws HttpException {
-
+ Args.notNull(certificateChain, "certificateChain");
+ if (certificateChain.length == 0 || !(certificateChain[0] instanceof
X509Certificate)) {
+ throw new IllegalArgumentException("Invalid certificate chain");
+ }
+ Args.notNull(privateKey, "privateKey");
+
AS2SignedDataGenerator gen = new AS2SignedDataGenerator();
// Get first certificate in chain for signing
diff --git
a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2MessageTest.java
b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2MessageTest.java
index f17e7c45826..65684b77bff 100644
---
a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2MessageTest.java
+++
b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2MessageTest.java
@@ -270,7 +270,7 @@ public void plainEDIMessageTest() throws Exception {
HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE,
REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME,
AS2MessageStructure.PLAIN,
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII),
- null, null, null, DISPOSITION_NOTIFICATION_TO,
SIGNED_RECEIPT_MIC_ALGORITHMS);
+ null, null, null, DISPOSITION_NOTIFICATION_TO,
SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
HttpRequest request = httpContext.getRequest();
assertEquals("Unexpected method value", METHOD,
request.getRequestLine().getMethod());
@@ -314,7 +314,66 @@ public void multipartSignedMessageTest() throws Exception {
HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE,
REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME,
AS2MessageStructure.SIGNED,
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII),
null, certList.toArray(new Certificate[0]),
signingKP.getPrivate(), DISPOSITION_NOTIFICATION_TO,
- SIGNED_RECEIPT_MIC_ALGORITHMS);
+ SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
+
+ HttpRequest request = httpContext.getRequest();
+ assertEquals("Unexpected method value", METHOD,
request.getRequestLine().getMethod());
+ assertEquals("Unexpected request URI value", REQUEST_URI,
request.getRequestLine().getUri());
+ assertEquals("Unexpected HTTP version value", HttpVersion.HTTP_1_1,
+ request.getRequestLine().getProtocolVersion());
+
+ assertEquals("Unexpected subject value", SUBJECT,
request.getFirstHeader(AS2Header.SUBJECT).getValue());
+ assertEquals("Unexpected from value", FROM,
request.getFirstHeader(AS2Header.FROM).getValue());
+ assertEquals("Unexpected AS2 version value", AS2_VERSION,
+ request.getFirstHeader(AS2Header.AS2_VERSION).getValue());
+ assertEquals("Unexpected AS2 from value", AS2_NAME,
request.getFirstHeader(AS2Header.AS2_FROM).getValue());
+ assertEquals("Unexpected AS2 to value", AS2_NAME,
request.getFirstHeader(AS2Header.AS2_TO).getValue());
+ assertTrue("Unexpected message id value",
+
request.getFirstHeader(AS2Header.MESSAGE_ID).getValue().endsWith(CLIENT_FQDN +
">"));
+ assertEquals("Unexpected target host value", TARGET_HOST + ":" +
TARGET_PORT,
+ request.getFirstHeader(AS2Header.TARGET_HOST).getValue());
+ assertEquals("Unexpected user agent value", USER_AGENT,
+ request.getFirstHeader(AS2Header.USER_AGENT).getValue());
+ assertNotNull("Date value missing",
request.getFirstHeader(AS2Header.DATE));
+ assertNotNull("Content length value missing",
request.getFirstHeader(AS2Header.CONTENT_LENGTH));
+ assertTrue("Unexpected content type for message",
+
request.getFirstHeader(AS2Header.CONTENT_TYPE).getValue().startsWith(AS2MediaType.MULTIPART_SIGNED));
+
+ assertTrue("Request does not contain entity", request instanceof
BasicHttpEntityEnclosingRequest);
+ HttpEntity entity = ((BasicHttpEntityEnclosingRequest)
request).getEntity();
+ assertNotNull("Request does not contain entity", entity);
+ assertTrue("Unexpected request entity type", entity instanceof
MultipartSignedEntity);
+ MultipartSignedEntity signedEntity = (MultipartSignedEntity) entity;
+ assertTrue("Entity not set as main body of request",
signedEntity.isMainBody());
+ assertTrue("Request contains invalid number of mime parts",
signedEntity.getPartCount() == 2);
+
+ // Validated first mime part.
+ assertTrue("First mime part incorrect type ", signedEntity.getPart(0)
instanceof ApplicationEDIFACTEntity);
+ ApplicationEDIFACTEntity ediEntity = (ApplicationEDIFACTEntity)
signedEntity.getPart(0);
+ assertTrue("Unexpected content type for first mime part",
+
ediEntity.getContentType().getValue().startsWith(AS2MediaType.APPLICATION_EDIFACT));
+ assertFalse("First mime type set as main body of request",
ediEntity.isMainBody());
+
+ // Validate second mime part.
+ assertTrue("Second mime part incorrect type ",
+ signedEntity.getPart(1) instanceof
ApplicationPkcs7SignatureEntity);
+ ApplicationPkcs7SignatureEntity signatureEntity =
(ApplicationPkcs7SignatureEntity) signedEntity.getPart(1);
+ assertTrue("Unexpected content type for second mime part",
+
signatureEntity.getContentType().getValue().startsWith(AS2MediaType.APPLICATION_PKCS7_SIGNATURE));
+ assertFalse("First mime type set as main body of request",
signatureEntity.isMainBody());
+
+ }
+
+// @Test
+ public void envelopeddMessageTest() throws Exception {
+ AS2ClientConnection clientConnection = new
AS2ClientConnection(AS2_VERSION, USER_AGENT, CLIENT_FQDN,
+ TARGET_HOST, TARGET_PORT);
+ AS2ClientManager clientManager = new
AS2ClientManager(clientConnection);
+
+ HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE,
REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME,
+ AS2MessageStructure.SIGNED,
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII),
+ null, certList.toArray(new Certificate[0]),
signingKP.getPrivate(), DISPOSITION_NOTIFICATION_TO,
+ SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
HttpRequest request = httpContext.getRequest();
assertEquals("Unexpected method value", METHOD,
request.getRequestLine().getMethod());
@@ -373,7 +432,7 @@ public void signatureVerificationTest() throws Exception {
HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE,
REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME,
AS2MessageStructure.SIGNED,
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII),
null, certList.toArray(new Certificate[0]),
signingKP.getPrivate(), DISPOSITION_NOTIFICATION_TO,
- SIGNED_RECEIPT_MIC_ALGORITHMS);
+ SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
HttpRequest request = httpContext.getRequest();
assertTrue("Request does not contain entity", request instanceof
BasicHttpEntityEnclosingRequest);
@@ -401,7 +460,7 @@ public void mdnMessageTest() throws Exception {
HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE,
REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME,
AS2MessageStructure.PLAIN,
ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII),
- null, null, null, DISPOSITION_NOTIFICATION_TO,
SIGNED_RECEIPT_MIC_ALGORITHMS);
+ null, null, null, DISPOSITION_NOTIFICATION_TO,
SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
HttpResponse response = httpContext.getResponse();
assertEquals("Unexpected method value", HttpVersion.HTTP_1_1,
response.getStatusLine().getProtocolVersion());
diff --git
a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/entity/EntityParserTest.java
b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/entity/EntityParserTest.java
index 306d9cdcfc4..cd47c82d9e0 100644
---
a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/entity/EntityParserTest.java
+++
b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/entity/EntityParserTest.java
@@ -17,7 +17,20 @@
package org.apache.camel.component.as2.api.entity;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
import org.apache.camel.component.as2.api.AS2Header;
import org.apache.camel.component.as2.api.io.AS2SessionInputBuffer;
@@ -31,6 +44,23 @@
import org.apache.http.impl.EnglishReasonPhraseCatalog;
import org.apache.http.impl.io.HttpTransportMetricsImpl;
import org.apache.http.message.BasicHttpResponse;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.bc.BcX509ExtensionUtils;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
+import org.bouncycastle.cms.CMSAlgorithm;
+import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
+import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
+import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.OutputEncryptor;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -150,6 +180,11 @@
private static final int DEFAULT_BUFFER_SIZE = 8 * 1024;
+ //
+ // certificate serial number seed.
+ //
+ int serialNo = 1;
+
@Before
public void setUp() throws Exception {
}
@@ -237,4 +272,89 @@ public void parseMessageDispositionNotificationBodyTest()
throws Exception {
assertEquals("Unexpected Digest Algorithm ID",
EXPECTED_DIGEST_ALGORITHM_ID,
messageDispositionNotificationEntity.getReceivedContentMic().getDigestAlgorithmId());
}
+ @Test
+ public void parseEnvelopedBodyTest() throws Exception {
+
+ Security.addProvider(new BouncyCastleProvider());
+
+ //
+ // set up our certificates
+ //
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
+
+ kpg.initialize(1024, new SecureRandom());
+
+ String issueDN = "O=Punkhorn Software, C=US";
+ KeyPair issueKP = kpg.generateKeyPair();
+ X509Certificate issuerCertificate = makeCertificate(issueKP, issueDN,
issueKP, issueDN);
+
+ //
+ // certificate we encrypt against
+ //
+ String encryptDN = "CN=William J. Collins, [email protected],
O=Punkhorn Software, C=US";
+ KeyPair encryptKP = kpg.generateKeyPair();
+ X509Certificate encryptionCertificate = makeCertificate(encryptKP,
encryptDN, issueKP, issueDN);
+
+ List<X509Certificate> certList = new ArrayList<>();
+
+ certList.add(encryptionCertificate);
+ certList.add(issuerCertificate);
+
+ //
+ // Create generator
+ //
+ CMSEnvelopedDataGenerator cmsEnvelopeDataGenerator = new
CMSEnvelopedDataGenerator();
+
+ JceKeyTransRecipientInfoGenerator recipientInfoGenerator = new
JceKeyTransRecipientInfoGenerator(encryptionCertificate);
+
cmsEnvelopeDataGenerator.addRecipientInfoGenerator(recipientInfoGenerator);
+
+ //
+ // Create encryptor
+ //
+ OutputEncryptor contentEncryptor = new
JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CCM).build();
+
+ //
+ // Build Enveloped Entity
+ //
+ TextPlainEntity textEntity = new TextPlainEntity("This is a super
secret messatge!", "US-ASCII", "7bit", false);
+ ApplicationPkcs7MimeEntity applicationPkcs7MimeEntity = new
ApplicationPkcs7MimeEntity(textEntity, cmsEnvelopeDataGenerator,
contentEncryptor, "binary", true);
+
+ MimeEntity decryptedMimeEntity =
applicationPkcs7MimeEntity.getEncryptedEntity(encryptKP.getPrivate());
+ assertEquals("Decrypted entity has unexpected content type",
"text/plain; charset=US-ASCII", decryptedMimeEntity.getContentTypeValue());
+ assertEquals("Decrypted entity has unexpected content", "This is a
super secret messatge!", ((TextPlainEntity)decryptedMimeEntity).getText());
+ }
+
+ /**
+ * create a basic X509 certificate from the given keys
+ */
+ private X509Certificate makeCertificate(KeyPair subKP, String subDN,
KeyPair issKP, String issDN)
+ throws GeneralSecurityException, IOException,
OperatorCreationException {
+ PublicKey subPub = subKP.getPublic();
+ PrivateKey issPriv = issKP.getPrivate();
+ PublicKey issPub = issKP.getPublic();
+
+ X509v3CertificateBuilder v3CertGen = new
JcaX509v3CertificateBuilder(new X500Name(issDN),
+ BigInteger.valueOf(serialNo++), new
Date(System.currentTimeMillis()),
+ new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 *
100)), new X500Name(subDN), subPub);
+
+ v3CertGen.addExtension(Extension.subjectKeyIdentifier, false,
createSubjectKeyId(subPub));
+
+ v3CertGen.addExtension(Extension.authorityKeyIdentifier, false,
createAuthorityKeyId(issPub));
+
+ return new
JcaX509CertificateConverter().setProvider("BC").getCertificate(
+ v3CertGen.build(new
JcaContentSignerBuilder("MD5withRSA").setProvider("BC").build(issPriv)));
+ }
+
+ private AuthorityKeyIdentifier createAuthorityKeyId(PublicKey pub) throws
IOException {
+ SubjectPublicKeyInfo info =
SubjectPublicKeyInfo.getInstance(pub.getEncoded());
+
+ BcX509ExtensionUtils utils = new BcX509ExtensionUtils();
+ return utils.createAuthorityKeyIdentifier(info);
+ }
+
+ static SubjectKeyIdentifier createSubjectKeyId(PublicKey pub) throws
IOException {
+ SubjectPublicKeyInfo info =
SubjectPublicKeyInfo.getInstance(pub.getEncoded());
+
+ return new BcX509ExtensionUtils().createSubjectKeyIdentifier(info);
+ }
}
diff --git
a/components/camel-as2/camel-as2-component/src/main/docs/as2-component.adoc
b/components/camel-as2/camel-as2-component/src/main/docs/as2-component.adoc
index 4260d4032ee..565e8fa5326 100644
--- a/components/camel-as2/camel-as2-component/src/main/docs/as2-component.adoc
+++ b/components/camel-as2/camel-as2-component/src/main/docs/as2-component.adoc
@@ -70,7 +70,7 @@ with the following path and query parameters:
|===
-==== Query Parameters (27 parameters):
+==== Query Parameters (30 parameters):
[width="100%",cols="2,5,^1,2",options="header"]
@@ -84,6 +84,9 @@ with the following path and query parameters:
| *dispositionNotificationTo* (common) | The value of the
Disposition-Notification-To header. Assigning a value to this parameter
requests a message disposition notification (MDN) for the AS2 message. | |
String
| *ediMessageTransferEncoding* (common) | The transfer encoding of EDI
message. | | String
| *ediMessageType* (common) | The content type of EDI message. One of
application/edifact, application/edi-x12, application/edi-consent | |
ContentType
+| *encryptingAlgorithmName* (common) | The name of algorithm used to encrypt
EDI message. | | String
+| *encryptingCertificateChain* (common) | The chain of certificates used to
encrypt EDI message. | | Certificate[]
+| *encryptingPrivateKey* (common) | The key used to encrypt the EDI message. |
| PrivateKey
| *from* (common) | The value of the From header of AS2 message. | | String
| *inBody* (common) | Sets the name of a parameter to be passed in the
exchange In Body | | String
| *methodName* (common) | *Required* What sub operation to use for the
selected operation | | String
@@ -135,6 +138,9 @@ The component supports 25 options, which are listed below.
| *camel.component.as2.configuration.signing-algorithm-name* | The name of
algorithm used to sign EDI message. | | String
| *camel.component.as2.configuration.signing-certificate-chain* | The chain of
certificates used to sign EDI message. | | Certificate[]
| *camel.component.as2.configuration.signing-private-key* | The key used to
sign the EDI message. | | PrivateKey
+| *camel.component.as2.configuration.encrypting-algorithm-name* | The name of
algorithm used to encrypt EDI message. | | String
+| *camel.component.as2.configuration.encrypting-certificate-chain* | The chain
of certificates used to encrypt EDI message. | | Certificate[]
+| *camel.component.as2.configuration.encrypting-private-key* | The key used to
encrypt the EDI message. | | PrivateKey
| *camel.component.as2.configuration.subject* | The value of Subject header of
AS2 message. | | String
| *camel.component.as2.configuration.target-hostname* | The host name (IP or
DNS name) of target host. | | String
| *camel.component.as2.configuration.target-port-number* | The port number of
target host. -1 indicates the scheme default port. | | Integer
diff --git
a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java
b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java
index bcc6adcc091..b819c5a2041 100644
---
a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java
+++
b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Configuration.java
@@ -105,6 +105,15 @@
@UriParam
private String[] signedReceiptMicAlgorithms;
+ @UriParam
+ private String encryptingAlgorithmName;
+
+ @UriParam
+ private Certificate[] encryptingCertificateChain;
+
+ @UriParam
+ private PrivateKey encryptingPrivateKey;
+
public AS2ApiName getApiName() {
return apiName;
}
@@ -404,4 +413,36 @@ public void setSignedReceiptMicAlgorithms(String[]
signedReceiptMicAlgorithms) {
this.signedReceiptMicAlgorithms = signedReceiptMicAlgorithms;
}
+ public String getEncryptingingAlgorithmName() {
+ return signingAlgorithmName;
+ }
+
+ /**
+ * The name of algorithm used to encrypt EDI message.
+ */
+ public void setEncryptingAlgorithmName(String signingAlgorithmName) {
+ this.encryptingAlgorithmName = signingAlgorithmName;
+ }
+
+ public Certificate[] getEncryptingCertificateChain() {
+ return encryptingCertificateChain;
+ }
+
+ /**
+ * The chain of certificates used to encrypt EDI message.
+ */
+ public void setEncryptingCertificateChain(Certificate[]
signingCertificateChain) {
+ this.encryptingCertificateChain = signingCertificateChain;
+ }
+
+ public PrivateKey getEncryptingPrivateKey() {
+ return encryptingPrivateKey;
+ }
+
+ /**
+ * The key used to encrypt the EDI message.
+ */
+ public void setEncryptingPrivateKey(PrivateKey signingPrivateKey) {
+ this.encryptingPrivateKey = signingPrivateKey;
+ }
}
diff --git
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerManagerIntegrationTest.java
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerManagerIntegrationTest.java
index e199217e04b..129310b2877 100644
---
a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerManagerIntegrationTest.java
+++
b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ServerManagerIntegrationTest.java
@@ -127,7 +127,7 @@ public void receivePlainEDIMessageTest() throws Exception {
clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME,
AS2_NAME, AS2MessageStructure.PLAIN,
ContentType.create(AS2MediaType.APPLICATION_EDIFACT,
AS2Charset.US_ASCII), null, null, null,
- DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS);
+ DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS,
null, null, null);
MockEndpoint mockEndpoint = getMockEndpoint("mock:as2RcvMsgs");
mockEndpoint.expectedMinimumMessageCount(1);
@@ -185,7 +185,7 @@ public void receiveMultipartSignedMessageTest() throws
Exception {
clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME,
AS2_NAME, AS2MessageStructure.SIGNED,
ContentType.create(AS2MediaType.APPLICATION_EDIFACT,
AS2Charset.US_ASCII), null,
certList.toArray(new Certificate[0]), signingKP.getPrivate(),
DISPOSITION_NOTIFICATION_TO,
- SIGNED_RECEIPT_MIC_ALGORITHMS);
+ SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null);
MockEndpoint mockEndpoint = getMockEndpoint("mock:as2RcvMsgs");
mockEndpoint.expectedMinimumMessageCount(1);
diff --git
a/platforms/spring-boot/components-starter/camel-as2-starter/src/main/java/org/apache/camel/component/as2/springboot/AS2ComponentConfiguration.java
b/platforms/spring-boot/components-starter/camel-as2-starter/src/main/java/org/apache/camel/component/as2/springboot/AS2ComponentConfiguration.java
index 13c751ab70b..27ddc9ba898 100644
---
a/platforms/spring-boot/components-starter/camel-as2-starter/src/main/java/org/apache/camel/component/as2/springboot/AS2ComponentConfiguration.java
+++
b/platforms/spring-boot/components-starter/camel-as2-starter/src/main/java/org/apache/camel/component/as2/springboot/AS2ComponentConfiguration.java
@@ -176,6 +176,18 @@ public void setResolvePropertyPlaceholders(
* notification (MDN)
*/
private String[] signedReceiptMicAlgorithms;
+ /**
+ * The name of algorithm used to encrypt EDI message.
+ */
+ private String encryptingAlgorithmName;
+ /**
+ * The chain of certificates used to encrypt EDI message.
+ */
+ private Certificate[] encryptingCertificateChain;
+ /**
+ * The key used to encrypt the EDI message.
+ */
+ private PrivateKey encryptingPrivateKey;
public AS2ApiName getApiName() {
return apiName;
@@ -365,5 +377,30 @@ public void setSignedReceiptMicAlgorithms(
String[] signedReceiptMicAlgorithms) {
this.signedReceiptMicAlgorithms = signedReceiptMicAlgorithms;
}
+
+ public String getEncryptingAlgorithmName() {
+ return encryptingAlgorithmName;
+ }
+
+ public void setEncryptingAlgorithmName(String encryptingAlgorithmName)
{
+ this.encryptingAlgorithmName = encryptingAlgorithmName;
+ }
+
+ public Certificate[] getEncryptingCertificateChain() {
+ return encryptingCertificateChain;
+ }
+
+ public void setEncryptingCertificateChain(
+ Certificate[] encryptingCertificateChain) {
+ this.encryptingCertificateChain = encryptingCertificateChain;
+ }
+
+ public PrivateKey getEncryptingPrivateKey() {
+ return encryptingPrivateKey;
+ }
+
+ public void setEncryptingPrivateKey(PrivateKey encryptingPrivateKey) {
+ this.encryptingPrivateKey = encryptingPrivateKey;
+ }
}
}
\ No newline at end of file
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
> Enhance the AS2 Component to send and receive encrypted AS2 messages
> --------------------------------------------------------------------
>
> Key: CAMEL-12605
> URL: https://issues.apache.org/jira/browse/CAMEL-12605
> Project: Camel
> Issue Type: Improvement
> Affects Versions: 2.23.0
> Reporter: William Collins
> Assignee: William Collins
> Priority: Major
>
> Enhance the AS2 Component to support encrypted AS2 messages per RFC4130
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)