This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push: new 8f734d7 [CAMEL-12605] Updated signature algorithms supported and refactored API. 8f734d7 is described below commit 8f734d70504575cf8d12a35f10cedc582b4c7477 Author: William Collins <punkhor...@gmail.com> AuthorDate: Tue Oct 16 14:45:07 2018 -0400 [CAMEL-12605] Updated signature algorithms supported and refactored API. --- .../camel/component/as2/api/AS2ClientManager.java | 16 ++- .../component/as2/api/AS2ServerConnection.java | 26 +++- .../component/as2/api/AS2SignatureAlgorithm.java | 153 +++++++++++++++++++++ .../component/as2/api/protocol/ResponseMDN.java | 7 +- .../camel/component/as2/api/util/SigningUtils.java | 37 +++-- .../camel/component/as2/api/AS2MessageTest.java | 14 +- .../src/main/docs/as2-component.adoc | 2 +- .../camel/component/as2/AS2Configuration.java | 13 +- .../as2/internal/AS2ConnectionHelper.java | 2 +- .../as2/AS2ClientManagerIntegrationTest.java | 3 +- .../as2/AS2ServerManagerIntegrationTest.java | 7 +- .../as2/springboot/AS2ComponentConfiguration.java | 13 +- 12 files changed, 241 insertions(+), 52 deletions(-) diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientManager.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientManager.java index 5865efa..ecd1f7a 100644 --- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientManager.java +++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ClientManager.java @@ -29,10 +29,8 @@ import org.apache.camel.component.as2.api.util.EntityUtils; import org.apache.camel.component.as2.api.util.SigningUtils; import org.apache.http.HttpException; import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; import org.apache.http.entity.ContentType; import org.apache.http.message.BasicHttpEntityEnclosingRequest; -import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HttpCoreContext; import org.apache.http.util.Args; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; @@ -123,10 +121,10 @@ public class AS2ClientManager { public static final String AS2_TO = CAMEL_AS2_CLIENT_PREFIX + "as2-to"; /** - * The HTTP Context Attribute containing the algorithm name used to sign EDI + * The HTTP Context Attribute containing the algorithm used to sign EDI * message */ - public static final String SIGNING_ALGORITHM_NAME = CAMEL_AS2_CLIENT_PREFIX + "signing-algorithm-name"; + public static final String SIGNING_ALGORITHM = CAMEL_AS2_CLIENT_PREFIX + "signing-algorithm"; /** * The HTTP Context Attribute containing the certificate chain used to sign @@ -192,6 +190,7 @@ public class AS2ClientManager { * @param as2MessageStructure - the structure of AS2 to send; see {@link AS2MessageStructure} * @param ediMessageContentType - the content typw of EDI message * @param ediMessageTransferEncoding - the transfer encoding used to transport EDI message + * @param signingAlgorithm - the algorithm used to sign the message or <code>null</code> if sending EDI message unsigned * @param signingCertificateChain - the chain of certificates used to sign the message or <code>null</code> if sending EDI message unsigned * @param signingPrivateKey - the private key used to sign EDI message * @param dispositionNotificationTo - an RFC2822 address to request a receipt or <code>null</code> if no receipt requested @@ -211,6 +210,7 @@ public class AS2ClientManager { AS2MessageStructure as2MessageStructure, ContentType ediMessageContentType, String ediMessageTransferEncoding, + AS2SignatureAlgorithm signingAlgorithm, Certificate[] signingCertificateChain, PrivateKey signingPrivateKey, String dispositionNotificationTo, @@ -235,6 +235,7 @@ public class AS2ClientManager { httpContext.setAttribute(AS2ClientManager.AS2_MESSAGE_STRUCTURE, as2MessageStructure); httpContext.setAttribute(AS2ClientManager.EDI_MESSAGE_CONTENT_TYPE, ediMessageContentType); httpContext.setAttribute(AS2ClientManager.EDI_MESSAGE_TRANSFER_ENCODING, ediMessageTransferEncoding); + httpContext.setAttribute(AS2ClientManager.SIGNING_ALGORITHM, signingAlgorithm); httpContext.setAttribute(AS2ClientManager.SIGNING_CERTIFICATE_CHAIN, signingCertificateChain); httpContext.setAttribute(AS2ClientManager.SIGNING_PRIVATE_KEY, signingPrivateKey); httpContext.setAttribute(AS2ClientManager.DISPOSITION_NOTIFICATION_TO, dispositionNotificationTo); @@ -303,6 +304,11 @@ public class AS2ClientManager { } public AS2SignedDataGenerator createSigningGenerator(HttpCoreContext httpContext) throws HttpException { + + AS2SignatureAlgorithm signatureAlgorithm = httpContext.getAttribute(SIGNING_ALGORITHM, AS2SignatureAlgorithm.class); + if (signatureAlgorithm == null) { + throw new HttpException("Signing algorithm missing"); + } Certificate[] certificateChain = httpContext.getAttribute(SIGNING_CERTIFICATE_CHAIN, Certificate[].class); if (certificateChain == null) { @@ -314,7 +320,7 @@ public class AS2ClientManager { throw new HttpException("Signing private key missing"); } - return SigningUtils.createSigningGenerator(certificateChain, privateKey); + return SigningUtils.createSigningGenerator(signatureAlgorithm, certificateChain, privateKey); } diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ServerConnection.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ServerConnection.java index dfd01f0..12c1132 100644 --- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ServerConnection.java +++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ServerConnection.java @@ -60,19 +60,27 @@ public class AS2ServerConnection { private final HttpService httpService; private UriHttpRequestHandlerMapper reqistry; - public RequestListenerThread(String as2Version, String originServer, String serverFqdn, int port, Certificate[] signingCertificateChain, PrivateKey signingPrivateKey) throws IOException { + public RequestListenerThread(String as2Version, + String originServer, + String serverFqdn, + int port, + AS2SignatureAlgorithm signatureAlgorithm, + Certificate[] signingCertificateChain, + PrivateKey signingPrivateKey) + throws IOException { setName(REQUEST_LISTENER_THREAD_NAME_PREFIX + port); serversocket = new ServerSocket(port); // Set up HTTP protocol processor for incoming connections - final HttpProcessor inhttpproc = initProtocolProcessor(as2Version, originServer, serverFqdn, port, signingCertificateChain, signingPrivateKey); + final HttpProcessor inhttpproc = initProtocolProcessor(as2Version, originServer, serverFqdn, port, + signatureAlgorithm, signingCertificateChain, signingPrivateKey); reqistry = new UriHttpRequestHandlerMapper(); // Set up the HTTP service httpService = new HttpService(inhttpproc, reqistry); } - + @Override public void run() { LOG.info("Listening on port {}", this.serversocket.getLocalPort()); @@ -171,6 +179,7 @@ public class AS2ServerConnection { private String originServer; private String serverFqdn; private Integer serverPortNumber; + private AS2SignatureAlgorithm signingAlgorithm; private Certificate[] signingCertificateChain; private PrivateKey signingPrivateKey; @@ -178,6 +187,7 @@ public class AS2ServerConnection { String originServer, String serverFqdn, Integer serverPortNumber, + AS2SignatureAlgorithm signingAlgorithm, Certificate[] signingCertificateChain, PrivateKey signingPrivateKey) throws IOException { @@ -185,10 +195,12 @@ public class AS2ServerConnection { this.originServer = Args.notNull(originServer, "userAgent"); this.serverFqdn = Args.notNull(serverFqdn, "serverFqdn"); this.serverPortNumber = Args.notNull(serverPortNumber, "serverPortNumber"); + this.signingAlgorithm = signingAlgorithm; this.signingCertificateChain = signingCertificateChain; this.signingPrivateKey = signingPrivateKey; - listenerThread = new RequestListenerThread(this.as2Version, this.originServer, this.serverFqdn, this.serverPortNumber, this.signingCertificateChain, this.signingPrivateKey); + listenerThread = new RequestListenerThread(this.as2Version, this.originServer, this.serverFqdn, + this.serverPortNumber, this.signingAlgorithm, this.signingCertificateChain, this.signingPrivateKey); listenerThread.setDaemon(true); listenerThread.start(); } @@ -226,11 +238,13 @@ public class AS2ServerConnection { String originServer, String serverFqdn, int port, + AS2SignatureAlgorithm signatureAlgorithm, Certificate[] signingCertificateChain, PrivateKey signingPrivateKey) { return HttpProcessorBuilder.create().add(new ResponseContent(true)).add(new ResponseServer(originServer)) - .add(new ResponseDate()).add(new ResponseConnControl()) - .add(new ResponseMDN(as2Version, serverFqdn, signingCertificateChain, signingPrivateKey)).build(); + .add(new ResponseDate()).add(new ResponseConnControl()).add(new ResponseMDN(as2Version, serverFqdn, + signatureAlgorithm, signingCertificateChain, signingPrivateKey)) + .build(); } } diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2SignatureAlgorithm.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2SignatureAlgorithm.java new file mode 100644 index 0000000..587634b --- /dev/null +++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2SignatureAlgorithm.java @@ -0,0 +1,153 @@ +/** + * 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.ASN1Integer; +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; +import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; + +interface AS2SignatureAlgorithmParams { + + static AlgorithmIdentifier SHA1ALGID = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); + static RSASSAPSSparams SHA1ALGPARAMS = new RSASSAPSSparams(SHA1ALGID, + new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, SHA1ALGID), new ASN1Integer(20), new ASN1Integer(1)); + + static AlgorithmIdentifier SHA224ALGID = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE); + static RSASSAPSSparams SHA224ALGPARAMS = new RSASSAPSSparams(SHA224ALGID, + new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, SHA224ALGID), new ASN1Integer(28), new ASN1Integer(1)); + + static AlgorithmIdentifier SHA256ALGID = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE); + static RSASSAPSSparams SHA256ALGPARAMS = new RSASSAPSSparams(SHA256ALGID, + new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, SHA256ALGID), new ASN1Integer(32), new ASN1Integer(1)); + + static AlgorithmIdentifier SHA384ALGID = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE); + static RSASSAPSSparams SHA384ALGPARAMS = new RSASSAPSSparams(SHA384ALGID, + new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, SHA384ALGID), new ASN1Integer(48), new ASN1Integer(1)); + + static AlgorithmIdentifier SHA512ALGID = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, DERNull.INSTANCE); + static RSASSAPSSparams SHA512ALGPARAMS = new RSASSAPSSparams(SHA512ALGID, + new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, SHA512ALGID), new ASN1Integer(64), new ASN1Integer(1)); + + static AlgorithmIdentifier SHA3_224ALGID = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_224, DERNull.INSTANCE); + static RSASSAPSSparams SHA3_224ALGPARAMS = new RSASSAPSSparams(SHA3_224ALGID, + new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, SHA3_224ALGID), new ASN1Integer(28), new ASN1Integer(1)); + + static AlgorithmIdentifier SHA3_256ALGID = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_256, DERNull.INSTANCE); + static RSASSAPSSparams SHA3_256ALGPARAMS = new RSASSAPSSparams(SHA3_256ALGID, + new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, SHA3_256ALGID), new ASN1Integer(32), new ASN1Integer(1)); + + static AlgorithmIdentifier SHA3_384ALGID = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_384, DERNull.INSTANCE); + static RSASSAPSSparams SHA3_384ALGPARAMS = new RSASSAPSSparams(SHA3_384ALGID, + new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, SHA3_384ALGID), new ASN1Integer(48), new ASN1Integer(1)); + + static AlgorithmIdentifier SHA3_512ALGID = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_512, DERNull.INSTANCE); + static RSASSAPSSparams SHA3_512ALGPARAMS = new RSASSAPSSparams(SHA3_512ALGID, + new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, SHA3_512ALGID), new ASN1Integer(64), new ASN1Integer(1)); + +} + + +public enum AS2SignatureAlgorithm { + + SHA3_224WITHRSA(new AlgorithmIdentifier(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224), "SHA3-224", "RSA"), + SHA3_256WITHRSA(new AlgorithmIdentifier(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256), "SHA3-256", "RSA"), + SHA3_384withRSA(new AlgorithmIdentifier(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384), "SHA3-384", "RSA"), + SHA3_512WITHRSA(new AlgorithmIdentifier(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512), "SHA3-512", "RSA"), + MD5WITHRSA(new AlgorithmIdentifier(OIWObjectIdentifiers.md5WithRSA), "MD5", "RSA"), + SHA1WITHRSA(new AlgorithmIdentifier(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224), "SHA1", "RSA"), + MD2WITHRSA(new AlgorithmIdentifier(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224), "MD2", "RSA"), + SHA224WITHRSA(new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption), "SHA224", "RSA"), + SHA256WITHRSA(new AlgorithmIdentifier(PKCSObjectIdentifiers.sha256WithRSAEncryption), "SHA256", "RSA"), + SHA384WITHRSA(new AlgorithmIdentifier(PKCSObjectIdentifiers.sha384WithRSAEncryption), "SHA384", "RSA"), + SHA512WITHRSA(new AlgorithmIdentifier(PKCSObjectIdentifiers.sha512WithRSAEncryption), "SHA512", "RSA"), + RIPEMD128WITHRSA(new AlgorithmIdentifier(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128), "RIPEMD128", "RSA"), + RIPEMD160WITHRSA(new AlgorithmIdentifier(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160), "RIPEMD160", "RSA"), + RIPEMD256WITHRSA(new AlgorithmIdentifier(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256), "RIPEMD256", "RSA"), + + SHA224WITHDSA(new AlgorithmIdentifier(NISTObjectIdentifiers.dsa_with_sha224), "SHA224", "DSA"), + SHA256WITHDSA(new AlgorithmIdentifier(NISTObjectIdentifiers.dsa_with_sha256), "SHA256", "DSA"), + SHA384WITHDSA(new AlgorithmIdentifier(NISTObjectIdentifiers.dsa_with_sha384), "SHA384", "DSA"), + SHA512WITHDSA(new AlgorithmIdentifier(NISTObjectIdentifiers.dsa_with_sha512), "SHA512", "DSA"), + SHA3_224WITHDSA(new AlgorithmIdentifier(NISTObjectIdentifiers.id_dsa_with_sha3_224), "SHA3-224", "DSA"), + SHA3_256WITHDSA(new AlgorithmIdentifier(NISTObjectIdentifiers.id_dsa_with_sha3_256), "SHA3-256", "DSA"), + SHA3_384WITHDSA(new AlgorithmIdentifier(NISTObjectIdentifiers.id_dsa_with_sha3_384), "SHA3-384", "DSA"), + SHA3_512WITHDSA(new AlgorithmIdentifier(NISTObjectIdentifiers.id_dsa_with_sha3_512), "SHA3-512", "DSA"), + SHA1WITHDSA(new AlgorithmIdentifier(OIWObjectIdentifiers.dsaWithSHA1), "SHA1", "DSA"), + + SHA3_224WITHECDSA(new AlgorithmIdentifier(NISTObjectIdentifiers.id_ecdsa_with_sha3_224), "SHA3-224", "ECDSA"), + SHA3_256WITHECDSA(new AlgorithmIdentifier(NISTObjectIdentifiers.id_ecdsa_with_sha3_256), "SHA3-256", "ECDSA"), + SHA3_384WITHECDSA(new AlgorithmIdentifier(NISTObjectIdentifiers.id_ecdsa_with_sha3_384), "SHA3-384", "ECDSA"), + SHA3_512WITHECDSA(new AlgorithmIdentifier(NISTObjectIdentifiers.id_ecdsa_with_sha3_512), "SHA3-512", "ECDSA"), + SHA1WITHECDSA(new AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA1), "SHA1", "ECDSA"), + SHA224WITHECDSA(new AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA224), "SHA224", "ECDSA"), + SHA256WITHECDSA(new AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA256), "SHA256", "ECDSA"), + SHA384WITHECDSA(new AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA384), "SHA384", "ECDSA"), + SHA512WITHECDSA(new AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA512), "SHA512", "ECDSA"), + + SHA1WITHPLAIN_ECDSA(new AlgorithmIdentifier(BSIObjectIdentifiers.ecdsa_plain_SHA1), "SHA1", "ECDSA"), + SHA224WITHPLAIN_ECDSA(new AlgorithmIdentifier(BSIObjectIdentifiers.ecdsa_plain_SHA224), "SHA224", "ECDSA"), + SHA256WITHPLAIN_ECDSA(new AlgorithmIdentifier(BSIObjectIdentifiers.ecdsa_plain_SHA256), "SHA256", "ECDSA"), + SHA384WITHPLAIN_ECDSA(new AlgorithmIdentifier(BSIObjectIdentifiers.ecdsa_plain_SHA384), "SHA384", "ECDSA"), + SHA512WITHPLAIN_ECDSA(new AlgorithmIdentifier(BSIObjectIdentifiers.ecdsa_plain_SHA512), "SHA512", "ECDSA"), + RIPEMD160WITHPLAIN_ECDSA(new AlgorithmIdentifier(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160), "RIPEMD160", "ECDSA"), + + SHA1WITHRSAANDMGF1(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, AS2SignatureAlgorithmParams.SHA1ALGPARAMS), "SHA1", "RSA"), + SHA224WITHRSAANDMGF1(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, AS2SignatureAlgorithmParams.SHA224ALGPARAMS), "SHA224", "RSA"), + SHA256WITHRSAANDMGF1(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, AS2SignatureAlgorithmParams.SHA256ALGPARAMS), "SHA256", "RSA"), + SHA384WITHRSAANDMGF1(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, AS2SignatureAlgorithmParams.SHA384ALGPARAMS), "SHA384", "RSA"), + SHA512WITHRSAANDMGF1(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, AS2SignatureAlgorithmParams.SHA512ALGPARAMS), "SHA512", "RSA"), + SHA3_224WITHRSAANDMGF1(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_224, AS2SignatureAlgorithmParams.SHA3_224ALGPARAMS), "SHA3_224", "RSA"), + SHA3_256WITHRSAANDMGF1(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_256, AS2SignatureAlgorithmParams.SHA3_256ALGPARAMS), "SHA3_256", "RSA"), + SHA3_384WITHRSAANDMGF1(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_384, AS2SignatureAlgorithmParams.SHA3_384ALGPARAMS), "SHA3_384", "RSA"), + SHA3_512WITHRSAANDMGF1(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_512, AS2SignatureAlgorithmParams.SHA3_512ALGPARAMS), "SHA3_512", "RSA"); + + private final AlgorithmIdentifier signatureAlgorithm; + private final String digestAlgorithmName; + private final String encryptionAlgorithmName; + + AS2SignatureAlgorithm(AlgorithmIdentifier signatureAlgorithm, + String digestAlgorithmName, + String encryptionAlgorithmName) { + this.signatureAlgorithm = signatureAlgorithm; + this.digestAlgorithmName = digestAlgorithmName; + this.encryptionAlgorithmName = encryptionAlgorithmName; + } + + public AlgorithmIdentifier getSignatureAlgorithm() { + return signatureAlgorithm; + } + + public String getSignatureAlgorithmName() { + return name().replace("_", "-"); + } + + public String getDigestAlgorithmName() { + return digestAlgorithmName; + } + + public String getEncryptionAlgorithmName() { + return encryptionAlgorithmName; + } + +} diff --git a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/protocol/ResponseMDN.java b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/protocol/ResponseMDN.java index 6a6e24e..14a4109 100644 --- a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/protocol/ResponseMDN.java +++ b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/protocol/ResponseMDN.java @@ -25,6 +25,7 @@ import org.apache.camel.component.as2.api.AS2Charset; import org.apache.camel.component.as2.api.AS2Constants; import org.apache.camel.component.as2.api.AS2Header; import org.apache.camel.component.as2.api.AS2ServerManager; +import org.apache.camel.component.as2.api.AS2SignatureAlgorithm; import org.apache.camel.component.as2.api.AS2SignedDataGenerator; import org.apache.camel.component.as2.api.AS2TransferEncoding; import org.apache.camel.component.as2.api.InvalidAS2NameException; @@ -55,12 +56,14 @@ public class ResponseMDN implements HttpResponseInterceptor { private final String as2Version; private final String serverFQDN; + private AS2SignatureAlgorithm signingAlgorithm; private Certificate[] signingCertificateChain; private PrivateKey signingPrivateKey; - public ResponseMDN(String as2Version, String serverFQDN, Certificate[] signingCertificateChain, PrivateKey signingPrivateKey) { + public ResponseMDN(String as2Version, String serverFQDN, AS2SignatureAlgorithm signingAlgorithm, Certificate[] signingCertificateChain, PrivateKey signingPrivateKey) { this.as2Version = as2Version; this.serverFQDN = serverFQDN; + this.signingAlgorithm = signingAlgorithm; this.signingCertificateChain = signingCertificateChain; this.signingPrivateKey = signingPrivateKey; } @@ -161,7 +164,7 @@ public class ResponseMDN implements HttpResponseInterceptor { AS2SignedDataGenerator gen = null; if (dispositionNotificationOptions.getSignedReceiptProtocol() != null && signingCertificateChain != null && signingPrivateKey != null) { - gen = SigningUtils.createSigningGenerator(signingCertificateChain, signingPrivateKey); + gen = SigningUtils.createSigningGenerator(signingAlgorithm, signingCertificateChain, signingPrivateKey); } if (gen != null) { 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 66aabda..f4b530a0 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 @@ -22,6 +22,7 @@ import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.Arrays; +import org.apache.camel.component.as2.api.AS2SignatureAlgorithm; import org.apache.camel.component.as2.api.AS2SignedDataGenerator; import org.apache.http.HttpException; import org.apache.http.util.Args; @@ -43,7 +44,7 @@ public final class SigningUtils { private SigningUtils() { } - public static AS2SignedDataGenerator createSigningGenerator(Certificate[] certificateChain, PrivateKey privateKey) throws HttpException { + public static AS2SignedDataGenerator createSigningGenerator(AS2SignatureAlgorithm signingAlgorithm, Certificate[] certificateChain, PrivateKey privateKey) throws HttpException { Args.notNull(certificateChain, "certificateChain"); if (certificateChain.length == 0 || !(certificateChain[0] instanceof X509Certificate)) { throw new IllegalArgumentException("Invalid certificate chain"); @@ -68,20 +69,28 @@ public final class SigningUtils { attributes.add(new SMIMECapabilitiesAttribute(capabilities)); SignerInfoGenerator signerInfoGenerator = null; - for (String signingAlgorithmName : AS2SignedDataGenerator.getSupportedSignatureAlgorithmNamesForKey(privateKey)) { - try { - signerInfoGenerator = new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC") - .setSignedAttributeGenerator(new AttributeTable(attributes)) - .build(signingAlgorithmName, privateKey, signingCert); - break; - } catch (Exception e) { - signerInfoGenerator = null; - continue; - } - } - if (signerInfoGenerator == null) { - throw new HttpException("Failed to create signer info"); + try { + signerInfoGenerator = new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC") + .setSignedAttributeGenerator(new AttributeTable(attributes)) + .build(signingAlgorithm.getSignatureAlgorithmName(), privateKey, signingCert); + + } catch (Exception e) { + throw new HttpException("Failed to create signer info", e); } +// for (String signingAlgorithmName : AS2SignedDataGenerator.getSupportedSignatureAlgorithmNamesForKey(privateKey)) { +// try { +// signerInfoGenerator = new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC") +// .setSignedAttributeGenerator(new AttributeTable(attributes)) +// .build(signingAlgorithmName, privateKey, signingCert); +// break; +// } catch (Exception e) { +// signerInfoGenerator = null; +// continue; +// } +// } +// if (signerInfoGenerator == null) { +// throw new HttpException("Failed to create signer info"); +// } gen.addSignerInfoGenerator(signerInfoGenerator); // Create and populate certificate store. diff --git a/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2MessageTest.java b/components/camel-as2/camel-as2-api/src/test/java/org/apache/camel/component/as2/api/AS2MessageTest.java index 7d181aa..3cdd384 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 @@ -198,7 +198,7 @@ public class AS2MessageTest { certList.add(signingCert); certList.add(issueCert); - testServer = new AS2ServerConnection(AS2_VERSION, "MyServer-HTTP/1.1", SERVER_FQDN, TARGET_PORT, + testServer = new AS2ServerConnection(AS2_VERSION, "MyServer-HTTP/1.1", SERVER_FQDN, TARGET_PORT, AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate()); testServer.listen("*", new HttpRequestHandler() { @Override @@ -270,7 +270,7 @@ public class AS2MessageTest { HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME, AS2MessageStructure.PLAIN, ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), - null, null, null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null); + null, 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()); @@ -313,7 +313,7 @@ public class AS2MessageTest { HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME, AS2MessageStructure.SIGNED, ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), - null, certList.toArray(new Certificate[0]), signingKP.getPrivate(), DISPOSITION_NOTIFICATION_TO, + null, AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(), DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null); HttpRequest request = httpContext.getRequest(); @@ -473,7 +473,7 @@ public class AS2MessageTest { 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, certList.toArray(new Certificate[0]), signingKP.getPrivate(), DISPOSITION_NOTIFICATION_TO, + null, AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(), DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, encryptionAlgorithm, certList.toArray(new Certificate[0]), signingKP.getPrivate()); @@ -533,7 +533,7 @@ public class AS2MessageTest { HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME, AS2MessageStructure.ENCRYPTED_SIGNED, ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), - null, certList.toArray(new Certificate[0]), signingKP.getPrivate(), DISPOSITION_NOTIFICATION_TO, + null, AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(), DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, encryptionAlgorithm, certList.toArray(new Certificate[0]), signingKP.getPrivate()); @@ -601,7 +601,7 @@ public class AS2MessageTest { HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME, AS2MessageStructure.SIGNED, ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), - null, certList.toArray(new Certificate[0]), signingKP.getPrivate(), DISPOSITION_NOTIFICATION_TO, + null, AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(), DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null); HttpRequest request = httpContext.getRequest(); @@ -630,7 +630,7 @@ public class AS2MessageTest { HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME, AS2MessageStructure.PLAIN, ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), - null, null, null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null); + null, 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-component/src/main/docs/as2-component.adoc b/components/camel-as2/camel-as2-component/src/main/docs/as2-component.adoc index 34ef813..fd01c5e 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 @@ -95,7 +95,7 @@ with the following path and query parameters: | *serverFqdn* (common) | The Server Fully Qualified Domain Name (FQDN). Used in message ids sent by endpoint. | camel.apache.org | String | *serverPortNumber* (common) | The port number of server. | | Integer | *signedReceiptMicAlgorithms* (common) | The list of algorithms, in order of preference, requested to generate a message integrity check (MIC) returned in message dispostion notification (MDN) | | String[] -| *signingAlgorithmName* (common) | The name of algorithm used to sign EDI message. | | String +| *signingAlgorithm* (common) | The algorithm used to sign EDI message. | | AS2SignatureAlgorithm | *signingCertificateChain* (common) | The chain of certificates used to sign EDI message. | | Certificate[] | *signingPrivateKey* (common) | The key used to sign the EDI message. | | PrivateKey | *subject* (common) | The value of Subject header of AS2 message. | | String 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 73bc0fe..bd5a347 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 @@ -22,6 +22,7 @@ import java.security.cert.Certificate; import org.apache.camel.RuntimeCamelException; import org.apache.camel.component.as2.api.AS2EncryptionAlgorithm; import org.apache.camel.component.as2.api.AS2MessageStructure; +import org.apache.camel.component.as2.api.AS2SignatureAlgorithm; import org.apache.camel.component.as2.internal.AS2ApiName; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriParam; @@ -92,7 +93,7 @@ public class AS2Configuration { private String as2To; @UriParam - private String signingAlgorithmName; + private AS2SignatureAlgorithm signingAlgorithm; @UriParam private Certificate[] signingCertificateChain; @@ -354,15 +355,15 @@ public class AS2Configuration { this.as2To = as2To; } - public String getSigningAlgorithmName() { - return signingAlgorithmName; + public AS2SignatureAlgorithm getSigningAlgorithm() { + return signingAlgorithm; } /** - * The name of algorithm used to sign EDI message. + * The algorithm used to sign EDI message. */ - public void setSigningAlgorithmName(String signingAlgorithmName) { - this.signingAlgorithmName = signingAlgorithmName; + public void setSigningAlgorithm(AS2SignatureAlgorithm signingAlgorithm) { + this.signingAlgorithm = signingAlgorithm; } public Certificate[] getSigningCertificateChain() { diff --git a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/internal/AS2ConnectionHelper.java b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/internal/AS2ConnectionHelper.java index ad9ee1b..bc1fff5 100644 --- a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/internal/AS2ConnectionHelper.java +++ b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/internal/AS2ConnectionHelper.java @@ -63,7 +63,7 @@ public final class AS2ConnectionHelper { AS2ServerConnection serverConnection = serverConnections.get(configuration.getServerPortNumber()); if (serverConnection == null) { serverConnection = new AS2ServerConnection(configuration.getAs2Version(), configuration.getServer(), - configuration.getServerFqdn(), configuration.getServerPortNumber(), + configuration.getServerFqdn(), configuration.getServerPortNumber(), configuration.getSigningAlgorithm(), configuration.getSigningCertificateChain(), configuration.getSigningPrivateKey()); serverConnections.put(configuration.getServerPortNumber(), serverConnection); } diff --git a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIntegrationTest.java b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIntegrationTest.java index 58ad275..ca14bf6 100644 --- a/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIntegrationTest.java +++ b/components/camel-as2/camel-as2-component/src/test/java/org/apache/camel/component/as2/AS2ClientManagerIntegrationTest.java @@ -39,6 +39,7 @@ import org.apache.camel.component.as2.api.AS2MessageStructure; import org.apache.camel.component.as2.api.AS2MimeType; import org.apache.camel.component.as2.api.AS2ServerConnection; import org.apache.camel.component.as2.api.AS2ServerManager; +import org.apache.camel.component.as2.api.AS2SignatureAlgorithm; import org.apache.camel.component.as2.api.AS2SignedDataGenerator; import org.apache.camel.component.as2.api.entity.AS2DispositionModifier; import org.apache.camel.component.as2.api.entity.AS2DispositionType; @@ -579,7 +580,7 @@ public class AS2ClientManagerIntegrationTest extends AbstractAS2TestSupport { private static void receiveTestMessages() throws IOException { serverConnection = new AS2ServerConnection(AS2_VERSION, ORIGIN_SERVER_NAME, - SERVER_FQDN, PARTNER_TARGET_PORT, serverCertList.toArray(new Certificate[0]), serverSigningKP.getPrivate()); + SERVER_FQDN, PARTNER_TARGET_PORT, AS2SignatureAlgorithm.SHA256WITHRSA, serverCertList.toArray(new Certificate[0]), serverSigningKP.getPrivate()); serverConnection.listen("/", new RequestHandler()); } 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 129310b..9cb635f 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 @@ -35,6 +35,7 @@ import org.apache.camel.component.as2.api.AS2ClientManager; import org.apache.camel.component.as2.api.AS2Header; import org.apache.camel.component.as2.api.AS2MediaType; import org.apache.camel.component.as2.api.AS2MessageStructure; +import org.apache.camel.component.as2.api.AS2SignatureAlgorithm; import org.apache.camel.component.as2.api.AS2SignedDataGenerator; import org.apache.camel.component.as2.api.entity.ApplicationEDIFACTEntity; import org.apache.camel.component.as2.api.entity.ApplicationPkcs7SignatureEntity; @@ -126,7 +127,7 @@ public class AS2ServerManagerIntegrationTest extends AbstractAS2TestSupport { AS2ClientManager clientManager = new AS2ClientManager(clientConnection); 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, + ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), null, null, null, null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null); MockEndpoint mockEndpoint = getMockEndpoint("mock:as2RcvMsgs"); @@ -183,7 +184,7 @@ public class AS2ServerManagerIntegrationTest extends AbstractAS2TestSupport { AS2ClientManager clientManager = new AS2ClientManager(clientConnection); clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME, AS2MessageStructure.SIGNED, - ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), null, + ContentType.create(AS2MediaType.APPLICATION_EDIFACT, AS2Charset.US_ASCII), null, AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(), DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, null); @@ -264,7 +265,7 @@ public class AS2ServerManagerIntegrationTest extends AbstractAS2TestSupport { attributes.add(new SMIMEEncryptionKeyPreferenceAttribute(new IssuerAndSerialNumber(new X500Name(signingCert.getIssuerDN().getName()), signingCert.getSerialNumber()))); attributes.add(new SMIMECapabilitiesAttribute(capabilities)); - gen = SigningUtils.createSigningGenerator(certList.toArray(new X509Certificate[0]), signingKP.getPrivate()); + gen = SigningUtils.createSigningGenerator(AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new X509Certificate[0]), signingKP.getPrivate()); gen.addCertificates(certs); } 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 0f65e1b..d5d84d5 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 @@ -21,6 +21,7 @@ import java.security.cert.Certificate; import javax.annotation.Generated; import org.apache.camel.component.as2.api.AS2EncryptionAlgorithm; import org.apache.camel.component.as2.api.AS2MessageStructure; +import org.apache.camel.component.as2.api.AS2SignatureAlgorithm; import org.apache.camel.component.as2.internal.AS2ApiName; import org.apache.camel.spring.boot.ComponentConfigurationPropertiesCommon; import org.apache.http.entity.ContentType; @@ -154,9 +155,9 @@ public class AS2ComponentConfiguration */ private String as2To; /** - * The name of algorithm used to sign EDI message. + * The algorithm used to sign EDI message. */ - private String signingAlgorithmName; + private AS2SignatureAlgorithm signingAlgorithm; /** * The chain of certificates used to sign EDI message. */ @@ -336,12 +337,12 @@ public class AS2ComponentConfiguration this.as2To = as2To; } - public String getSigningAlgorithmName() { - return signingAlgorithmName; + public AS2SignatureAlgorithm getSigningAlgorithm() { + return signingAlgorithm; } - public void setSigningAlgorithmName(String signingAlgorithmName) { - this.signingAlgorithmName = signingAlgorithmName; + public void setSigningAlgorithm(AS2SignatureAlgorithm signingAlgorithm) { + this.signingAlgorithm = signingAlgorithm; } public Certificate[] getSigningCertificateChain() {