From 5dbe8b3314a093a895dafe28a6efd3f97332ae43 Mon Sep 17 00:00:00 2001 From: Pawel GUTOWSKI <Pawel.GUTOWSKI@ext.ec.europa.eu> Date: Wed, 10 Jan 2018 19:30:39 +0100 Subject: [PATCH] EDELIVERY-2302 Refactored first 2 out of 3 deprecated classes --- .../europa/ec/smp/api/GeneratedCodeTest.java | 48 ++++++ .../ec/cipa/smp/server/security/Signer.java | 101 ----------- .../cipa/smp/server/util/IdentifierUtils.java | 60 ------- .../cipa/smp/server/util/SignatureFilter.java | 114 ------------- .../smp/services/ServiceMetadataService.java | 3 +- .../smp/services/ServiceMetadataSigner.java | 161 ++++++++++++++++++ .../ec/cipa/smp/server/util/CommonUtil.java | 96 ----------- .../smp/server/util/DefaultHttpHeader.java | 87 ---------- .../smp/server/util/IdentifierUtilsTest.java | 58 ------- .../cipa/smp/server/util/SMPDBUtilsTest.java | 70 -------- .../services/ServiceMetadataSignerTest.java} | 28 ++- .../edelivery/smp/config/SmpWebAppConfig.java | 1 - .../smp/validation/ServiceGroupValidator.java | 5 +- 13 files changed, 232 insertions(+), 600 deletions(-) delete mode 100644 smp-server-library/src/main/java/eu/europa/ec/cipa/smp/server/security/Signer.java delete mode 100644 smp-server-library/src/main/java/eu/europa/ec/cipa/smp/server/util/IdentifierUtils.java delete mode 100644 smp-server-library/src/main/java/eu/europa/ec/cipa/smp/server/util/SignatureFilter.java create mode 100644 smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataSigner.java delete mode 100644 smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/util/CommonUtil.java delete mode 100644 smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/util/DefaultHttpHeader.java delete mode 100644 smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/util/IdentifierUtilsTest.java delete mode 100644 smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/util/SMPDBUtilsTest.java rename smp-server-library/src/test/java/eu/europa/ec/{cipa/smp/server/security/SignerTest.java => edelivery/smp/services/ServiceMetadataSignerTest.java} (72%) diff --git a/smp-api/src/test/java/eu/europa/ec/smp/api/GeneratedCodeTest.java b/smp-api/src/test/java/eu/europa/ec/smp/api/GeneratedCodeTest.java index d9039e75e..55da9a45b 100644 --- a/smp-api/src/test/java/eu/europa/ec/smp/api/GeneratedCodeTest.java +++ b/smp-api/src/test/java/eu/europa/ec/smp/api/GeneratedCodeTest.java @@ -92,4 +92,52 @@ public class GeneratedCodeTest { return (ServiceGroup) serviceGroup; } + @Test + public void testGeneratedServiceGroupEqualsReturnsTrue(){ + ParticipantIdentifierType id1 = new ParticipantIdentifierType(VALUE, SCHEME); + ParticipantIdentifierType id2 = new ParticipantIdentifierType(VALUE, SCHEME); + + assertTrue(id1.equals(id2)); + } + + @Test + public void testGeneratedServiceGroupEqualsIsCaseSensitive(){ + ParticipantIdentifierType id1 = new ParticipantIdentifierType("Value", "Scheme"); + ParticipantIdentifierType id2 = new ParticipantIdentifierType("value", "scheme"); + + assertFalse(id1.equals(id2)); + } + + @Test + public void testGeneratedServiceGroupEquaHandlesEmptyScheme(){ + ParticipantIdentifierType id1 = new ParticipantIdentifierType(VALUE, null); + ParticipantIdentifierType id2 = new ParticipantIdentifierType(VALUE, null); + + assertTrue(id1.equals(id2)); + } + + @Test + public void testGeneratedDocumentIdEqualsReturnsTrue(){ + DocumentIdentifier id1 = new DocumentIdentifier(VALUE, SCHEME); + DocumentIdentifier id2 = new DocumentIdentifier(VALUE, SCHEME); + + assertTrue(id1.equals(id2)); + } + + @Test + public void testGeneratedDocumentIdEqualsIsCaseSensitive(){ + DocumentIdentifier id1 = new DocumentIdentifier("Value", "Scheme"); + DocumentIdentifier id2 = new DocumentIdentifier("value", "scheme"); + + assertFalse(id1.equals(id2)); + } + + @Test + public void testGeneratedDocumentIdEqualsHandlesEmptyScheme(){ + DocumentIdentifier id1 = new DocumentIdentifier(VALUE, null); + DocumentIdentifier id2 = new DocumentIdentifier(VALUE, null); + + assertTrue(id1.equals(id2)); + } + } diff --git a/smp-server-library/src/main/java/eu/europa/ec/cipa/smp/server/security/Signer.java b/smp-server-library/src/main/java/eu/europa/ec/cipa/smp/server/security/Signer.java deleted file mode 100644 index 5ac10c7f9..000000000 --- a/smp-server-library/src/main/java/eu/europa/ec/cipa/smp/server/security/Signer.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2017 European Commission | CEF eDelivery - * - * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * - * You may obtain a copy of the Licence attached in file: LICENCE-EUPL-v1.2.pdf - * - * Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and limitations under the Licence. - */ - -package eu.europa.ec.cipa.smp.server.security; - -import org.w3c.dom.Element; - -import javax.annotation.Nonnull; -import javax.xml.crypto.MarshalException; -import javax.xml.crypto.dsig.*; -import javax.xml.crypto.dsig.dom.DOMSignContext; -import javax.xml.crypto.dsig.keyinfo.KeyInfo; -import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory; -import javax.xml.crypto.dsig.keyinfo.X509Data; -import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec; -import javax.xml.crypto.dsig.spec.TransformParameterSpec; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidParameterException; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class Signer { - - private final PrivateKey privateKey; - private final X509Certificate certificate; - - public Signer(@Nonnull final PrivateKey privateKey, - @Nonnull final X509Certificate certificate) { - this.privateKey = privateKey; - this.certificate = certificate; - - if (this.privateKey == null) { - throw new InvalidParameterException("Private key must be not null."); - } - - if (this.certificate == null) { - throw new InvalidParameterException("Certificate must be not null."); - } - } - - public void signXML(final Element aElementToSign) throws NoSuchAlgorithmException, - InvalidAlgorithmParameterException, - MarshalException, - XMLSignatureException { - // Create a DOM XMLSignatureFactory that will be used to - // generate the enveloped signature. - final XMLSignatureFactory aSignatureFactory = XMLSignatureFactory.getInstance("DOM"); - - // Create a Reference to the enveloped document (in this case, - // you are signing the whole document, so a URI of "" signifies - // that, and also specify the SHA1 digest algorithm and - // the ENVELOPED Transform) - final Reference aReference = aSignatureFactory.newReference("", - aSignatureFactory.newDigestMethod(DigestMethod.SHA256, - null), - Collections.singletonList(aSignatureFactory.newTransform(Transform.ENVELOPED, - (TransformParameterSpec) null)), - null, - null); - - // Create the SignedInfo. - final String RSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; - final SignedInfo aSingedInfo = aSignatureFactory.newSignedInfo(aSignatureFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, - (C14NMethodParameterSpec) null), - aSignatureFactory.newSignatureMethod(RSA_SHA256, - null), - Collections.singletonList(aReference)); - - // Create the KeyInfo containing the X509Data. - final KeyInfoFactory aKeyInfoFactory = aSignatureFactory.getKeyInfoFactory(); - final List<Object> aX509Content = new ArrayList<Object>(); - aX509Content.add(certificate.getSubjectX500Principal().getName()); - aX509Content.add(certificate); - final X509Data aX509Data = aKeyInfoFactory.newX509Data(aX509Content); - final KeyInfo aKeyInfo = aKeyInfoFactory.newKeyInfo(Collections.singletonList(aX509Data)); - - // Create a DOMSignContext and specify the RSA PrivateKey and - // location of the resulting XMLSignature's parent element. - final DOMSignContext dsc = new DOMSignContext(privateKey, aElementToSign); - - // Create the XMLSignature, but don't sign it yet. - final XMLSignature signature = aSignatureFactory.newXMLSignature(aSingedInfo, aKeyInfo); - - // Marshal, generate, and sign the enveloped signature. - signature.sign(dsc); - } -} diff --git a/smp-server-library/src/main/java/eu/europa/ec/cipa/smp/server/util/IdentifierUtils.java b/smp-server-library/src/main/java/eu/europa/ec/cipa/smp/server/util/IdentifierUtils.java deleted file mode 100644 index e7047769a..000000000 --- a/smp-server-library/src/main/java/eu/europa/ec/cipa/smp/server/util/IdentifierUtils.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2017 European Commission | CEF eDelivery - * - * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * - * You may obtain a copy of the Licence attached in file: LICENCE-EUPL-v1.2.pdf - * - * Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and limitations under the Licence. - */ -package eu.europa.ec.cipa.smp.server.util; - -import org.oasis_open.docs.bdxr.ns.smp._2016._05.ParticipantIdentifierType; - -import javax.annotation.Nonnull; -import javax.annotation.concurrent.Immutable; - -/** - * This class contains several identifier related utility methods. - * - * @author PEPPOL.AT, BRZ, Philip Helger - */ -@Immutable -@Deprecated -public final class IdentifierUtils { - - /** - * According to the specification, two participant identifiers are equal if - * their parts are equal case insensitive. - * - * @param aIdentifier1 - * First identifier to compare. May not be null. - * @param aIdentifier2 - * Second identifier to compare. May not be null. - * @return <code>true</code> if the identifiers are equal, <code>false</code> - * otherwise. - */ - public static boolean areIdentifiersEqual (@Nonnull final ParticipantIdentifierType aIdentifier1, - @Nonnull final ParticipantIdentifierType aIdentifier2) { - - if(aIdentifier1==null || aIdentifier2==null){ - throw new IllegalArgumentException("Null identifiers are not allowed"); - } - // Identifiers are equal, if both scheme and value match case insensitive! - return stringEquals(aIdentifier1.getScheme(), aIdentifier2.getScheme ()) && - stringEquals(aIdentifier1.getValue (), aIdentifier2.getValue ()); - - } - - - private static boolean stringEquals(String a, String b){ - return a==null ? b==null : a.equalsIgnoreCase(b); - } - - - - -} diff --git a/smp-server-library/src/main/java/eu/europa/ec/cipa/smp/server/util/SignatureFilter.java b/smp-server-library/src/main/java/eu/europa/ec/cipa/smp/server/util/SignatureFilter.java deleted file mode 100644 index d89519a55..000000000 --- a/smp-server-library/src/main/java/eu/europa/ec/cipa/smp/server/util/SignatureFilter.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2017 European Commission | CEF eDelivery - * - * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * - * You may obtain a copy of the Licence attached in file: LICENCE-EUPL-v1.2.pdf - * - * Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and limitations under the Licence. - */ -package eu.europa.ec.cipa.smp.server.util; - -import eu.europa.ec.cipa.smp.server.security.Signer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import org.w3c.dom.Document; - -import javax.annotation.PostConstruct; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.security.KeyStore; -import java.security.cert.X509Certificate; - -/** - * This class adds a XML DSIG to successful GET's for SignedServiceMetadata - * objects. - * - * @author PEPPOL.AT, BRZ, Philip Helger - */ -@Deprecated // TODO: This is no longer a filter, refactor this garbage. -@Component -public final class SignatureFilter { - - private static final Logger s_aLogger = LoggerFactory.getLogger(SignatureFilter.class); - - @Value("${xmldsig.keystore.classpath}") - private String xmldsigKeystoreClasspath; - - @Value("${xmldsig.keystore.password}") - private String xmldsigKeystorePassword; - - @Value("${xmldsig.keystore.key.alias}") - private String xmldsigKeystoreKeyAlias; - - @Value("${xmldsig.keystore.key.password}") - private String xmldsigKeystoreKeyPassword; - - private KeyStore.PrivateKeyEntry m_aKeyEntry; - - private X509Certificate m_aCert; - - private Signer signer; - - @PostConstruct - public void init() { - // Load the KeyStore and get the signing key and certificate. - try { - InputStream keystoreInputStream; - try { - keystoreInputStream = new FileInputStream(xmldsigKeystoreClasspath); - } catch (FileNotFoundException e){ - s_aLogger.warn("Could not file keystore file, trying loading from classpath: " + xmldsigKeystoreClasspath); - keystoreInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(xmldsigKeystoreClasspath); - } - KeyStore keyStore = KeyStore.getInstance("JKS"); - keyStore.load(keystoreInputStream, xmldsigKeystorePassword.toCharArray()); - final KeyStore.Entry aEntry = keyStore.getEntry(xmldsigKeystoreKeyAlias, - new KeyStore.PasswordProtection(xmldsigKeystoreKeyPassword.toCharArray())); - if (aEntry == null) { - // Alias not found - throw new IllegalStateException("Failed to find key store alias '" + - xmldsigKeystoreKeyAlias + - "' in keystore with password '" + - xmldsigKeystoreKeyPassword + - "'. Does the alias exist? Is the password correct?"); - } - if (!(aEntry instanceof KeyStore.PrivateKeyEntry)) { - // Not a private key - throw new IllegalStateException("The keystore alias '" + - xmldsigKeystoreKeyAlias + - "' was found in keystore with password '" + - xmldsigKeystorePassword + - "' but it is not a private key! The internal type is " + - aEntry.getClass().getName()); - } - m_aKeyEntry = (KeyStore.PrivateKeyEntry) aEntry; - m_aCert = (X509Certificate) m_aKeyEntry.getCertificate(); - s_aLogger.info("Signature filter initialized with keystore '" + - xmldsigKeystoreClasspath + - "' and alias '" + - xmldsigKeystoreKeyAlias + - "'"); - - signer = new Signer(m_aKeyEntry.getPrivateKey(), m_aCert); - } catch (final Throwable t) { - s_aLogger.error("Error in constructor of SignatureFilter", t); - throw new IllegalStateException("Error in constructor of SignatureFilter", t); - } - } - - public void sign(Document serviceMetadataDoc) { - try { - signer.signXML(serviceMetadataDoc.getDocumentElement()); - } catch (Exception e) { - throw new RuntimeException("Could not sign serviceMetadata response", e); - } - } - -} \ No newline at end of file diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataService.java index e6b2ede00..8bcddb2bc 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataService.java @@ -15,7 +15,6 @@ package eu.europa.ec.edelivery.smp.services; import eu.europa.ec.edelivery.smp.conversion.CaseSensitivityNormalizer; import eu.europa.ec.edelivery.smp.conversion.ServiceGroupConverter; -import eu.europa.ec.cipa.smp.server.util.SignatureFilter; import eu.europa.ec.edelivery.smp.data.dao.ServiceGroupDao; import eu.europa.ec.edelivery.smp.data.dao.ServiceMetadataDao; import eu.europa.ec.edelivery.smp.data.model.DBServiceGroup; @@ -52,7 +51,7 @@ public class ServiceMetadataService { private ServiceGroupDao serviceGroupDao; @Autowired - private SignatureFilter signatureFilter; + private ServiceMetadataSigner signatureFilter; public Document getServiceMetadataDocument(ParticipantIdentifierType serviceGroupId, DocumentIdentifier documentId) { ParticipantIdentifierType normalizedServiceGroupId = caseSensitivityNormalizer.normalize(serviceGroupId); diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataSigner.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataSigner.java new file mode 100644 index 000000000..7b2e76b78 --- /dev/null +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataSigner.java @@ -0,0 +1,161 @@ +/* + * Copyright 2018 European Commission | CEF eDelivery + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * + * You may obtain a copy of the Licence attached in file: LICENCE-EUPL-v1.2.pdf + * + * Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and limitations under the Licence. + */ +package eu.europa.ec.edelivery.smp.services; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.w3c.dom.Document; + +import javax.annotation.PostConstruct; +import javax.xml.crypto.dsig.*; +import javax.xml.crypto.dsig.dom.DOMSignContext; +import javax.xml.crypto.dsig.keyinfo.KeyInfo; +import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory; +import javax.xml.crypto.dsig.keyinfo.X509Data; +import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec; +import javax.xml.crypto.dsig.spec.TransformParameterSpec; +import java.io.FileInputStream; +import java.io.InputStream; +import java.security.InvalidAlgorithmParameterException; +import java.security.Key; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static javax.xml.crypto.dsig.CanonicalizationMethod.INCLUSIVE; +import static javax.xml.crypto.dsig.DigestMethod.SHA256; +import static javax.xml.crypto.dsig.Transform.ENVELOPED; + +@Component +public final class ServiceMetadataSigner { + + private static final Logger log = LoggerFactory.getLogger(ServiceMetadataSigner.class); + + private static final String RSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; + + // Initialized in constructor + // Could not be initialized statically, factory methods declare throwing checked exceptions + private List TRANSFORM_ENVELOPED; + private DigestMethod DIGEST_METHOD_SHA_256; + private CanonicalizationMethod C14N_METHOD_INCLUSIVE; + private SignatureMethod SIGNATURE_METHOD_RSA_SHA256; + + + @Value("${xmldsig.keystore.classpath}") + private String keystoreFilePath; + + @Value("${xmldsig.keystore.password}") + private String keystorePassword; + + @Value("${xmldsig.keystore.key.alias}") + private String xmldsigKeystoreKeyAlias; + + @Value("${xmldsig.keystore.key.password}") + private String xmldsigKeystoreKeyPassword; + + + private Key signingKey; + + private X509Certificate signingCertificate; + + + public ServiceMetadataSigner() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException { + XMLSignatureFactory domSigFactory = getDomSigFactory(); + DIGEST_METHOD_SHA_256 = domSigFactory.newDigestMethod(SHA256, null); + + Transform transformEnveloped = domSigFactory.newTransform(ENVELOPED, (TransformParameterSpec) null); + TRANSFORM_ENVELOPED = Collections.singletonList(transformEnveloped); + + C14N_METHOD_INCLUSIVE = domSigFactory.newCanonicalizationMethod(INCLUSIVE, (C14NMethodParameterSpec) null); + + SIGNATURE_METHOD_RSA_SHA256 = domSigFactory.newSignatureMethod(RSA_SHA256, null); + } + + private static XMLSignatureFactory getDomSigFactory() { + // Only static methods of this factory are thread-safe + // We cannot re-use the same instance in every place + return XMLSignatureFactory.getInstance("DOM"); + } + + @PostConstruct + public void init() { + // Load the KeyStore and get the signing key and certificate. + try { + KeyStore keyStore = KeyStore.getInstance("JKS"); + InputStream keystoreInputStream = new FileInputStream(keystoreFilePath); + keyStore.load(keystoreInputStream, keystorePassword.toCharArray()); + + signingKey = keyStore.getKey(xmldsigKeystoreKeyAlias, xmldsigKeystoreKeyPassword.toCharArray()); + signingCertificate = (X509Certificate) keyStore.getCertificate(xmldsigKeystoreKeyAlias); + + log.info("Successfully loaded signing key and certificate: " + signingCertificate.getSubjectDN().getName()); + } catch (final Exception e) { + throw new IllegalStateException("Could not load signing certificate with private key from keystore file: " + keystoreFilePath, e); + } + } + + public void sign(Document serviceMetadataDoc) { + + try { + XMLSignatureFactory domSigFactory = getDomSigFactory(); + + // Create a Reference to the ENVELOPED document + // URI "" means that the whole document is signed + Reference reference = domSigFactory.newReference("", DIGEST_METHOD_SHA_256, TRANSFORM_ENVELOPED, null, null); + + SignedInfo singedInfo = domSigFactory.newSignedInfo(C14N_METHOD_INCLUSIVE, + SIGNATURE_METHOD_RSA_SHA256, + Collections.singletonList(reference)); + + KeyInfo keyInfo = createKeyInfo(); + + DOMSignContext domSignContext = new DOMSignContext(signingKey, serviceMetadataDoc.getDocumentElement()); + + // Create the XMLSignature, but don't sign it yet + XMLSignature signature = domSigFactory.newXMLSignature(singedInfo, keyInfo); + + // Marshal, generate, and sign the enveloped signature + signature.sign(domSignContext); + } catch (Exception e) { + throw new RuntimeException("Could not sign serviceMetadata response", e); + } + } + + private KeyInfo createKeyInfo() { + KeyInfoFactory keyInfoFactory = getDomSigFactory().getKeyInfoFactory(); + List content = new ArrayList(); + content.add(signingCertificate.getSubjectX500Principal().getName()); + content.add(signingCertificate); + X509Data x509Data = keyInfoFactory.newX509Data(content); + return keyInfoFactory.newKeyInfo(Collections.singletonList(x509Data)); + } + + public void setKeystoreFilePath(String keystoreFilePath) { + this.keystoreFilePath = keystoreFilePath; + } + public void setKeystorePassword(String keystorePassword) { + this.keystorePassword = keystorePassword; + } + public void setXmldsigKeystoreKeyAlias(String xmldsigKeystoreKeyAlias) { + this.xmldsigKeystoreKeyAlias = xmldsigKeystoreKeyAlias; + } + public void setXmldsigKeystoreKeyPassword(String xmldsigKeystoreKeyPassword) { + this.xmldsigKeystoreKeyPassword = xmldsigKeystoreKeyPassword; + } + +} \ No newline at end of file diff --git a/smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/util/CommonUtil.java b/smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/util/CommonUtil.java deleted file mode 100644 index 4e2c3f6ac..000000000 --- a/smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/util/CommonUtil.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2017 European Commission | CEF eDelivery - * - * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * - * You may obtain a copy of the Licence attached in file: LICENCE-EUPL-v1.2.pdf - * - * Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and limitations under the Licence. - */ - -package eu.europa.ec.cipa.smp.server.util; - -import org.apache.commons.lang3.StringUtils; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.*; -import org.bouncycastle.cert.X509v3CertificateBuilder; -import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; -import org.bouncycastle.operator.ContentSigner; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; - -import java.io.FileInputStream; -import java.math.BigInteger; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.KeyStore; -import java.security.cert.X509Certificate; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; - -/** - * Created by rodrfla on 29/11/2016. - */ -public class CommonUtil { - - public static Date convertStringToDate(String dateStr) throws ParseException { - SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd"); - return formatter.parse(dateStr); - } - - public static X509Certificate createCertificateForX509(String serialNumber, String issuer, String subject, Date startDate, Date expiryDate) throws Exception { - KeyStore keyStore = KeyStore.getInstance("JKS"); - keyStore.load(new FileInputStream(Thread.currentThread().getContextClassLoader().getResource("keystore.jks").getFile()), "test".toCharArray()); - - KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); - keyGen.initialize(1024); - KeyPair key = keyGen.generateKeyPair(); - X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(new X500Name(issuer), new BigInteger(serialNumber, 16), startDate, expiryDate, new X500Name(subject), SubjectPublicKeyInfo.getInstance(key.getPublic().getEncoded())); - - //CRL Distribution Points - DistributionPointName distPointOne = new DistributionPointName(new GeneralNames( - new GeneralName(GeneralName.uniformResourceIdentifier, Thread.currentThread().getContextClassLoader().getResource("test.crl").toString()))); - - DistributionPoint[] distPoints = new DistributionPoint[]{new DistributionPoint(distPointOne, null, null)}; - certBuilder.addExtension(Extension.cRLDistributionPoints, false, new CRLDistPoint(distPoints)); - - ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider("BC").build(key.getPrivate()); - return new JcaX509CertificateConverter().setProvider("BC").getCertificate(certBuilder.build(sigGen)); - } - - - public static String createHeaderCertificateForBlueCoat() throws Exception { - return createHeaderCertificateForBlueCoat(null,false); - } - - public static String createHeaderCertificateForBlueCoat(String tSubject, boolean isPolicyParamIncluded) throws Exception { - String serial = "123ABCD"; - // different order for the issuer certificate with extra spaces - String issuer = "CN=PEPPOL SERVICE METADATA PUBLISHER TEST CA, C=DK, O=NATIONAL IT AND TELECOM AGENCY, OU=FOR TEST PURPOSES ONLY"; - String subject = "O=DG-DIGIT,C=BE,CN=SMP_123456789"; - if (!StringUtils.isEmpty(tSubject)) { - subject = tSubject; - } - DateFormat df = new SimpleDateFormat("MMM d hh:mm:ss yyyy zzz", Locale.US); - Date validFrom = df.parse("Jun 01 10:37:53 2015 CEST"); - Date validTo = df.parse("Jun 01 10:37:53 2035 CEST"); - if (!isPolicyParamIncluded) { - return createHeaderCertificateForBlueCoat(serial, issuer, subject, validFrom, validTo); - } - return createHeaderCertificateForBlueCoatWithPolicyOids(serial, issuer, subject, validFrom, validTo, "&policy_oids=5.0.6.0.4.1.0000.66.99"); - } - - public static String createHeaderCertificateForBlueCoat(String serialNumber, String issuer, String subject, Date startDate, Date expiryDate) throws Exception { - DateFormat df = new SimpleDateFormat("MMM d hh:mm:ss yyyy zzz", Locale.US); - return "serial=" + serialNumber + "&subject=" + subject + "&validFrom=" + df.format(startDate) + "&validTo=" + df.format(expiryDate) + "&issuer=" + issuer; - } - - public static String createHeaderCertificateForBlueCoatWithPolicyOids(String serialNumber, String issuer, String subject, Date startDate, Date expiryDate, String policy_oids) throws Exception { - return createHeaderCertificateForBlueCoat(serialNumber, issuer, subject, startDate, expiryDate) + policy_oids; - } -} diff --git a/smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/util/DefaultHttpHeader.java b/smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/util/DefaultHttpHeader.java deleted file mode 100644 index 3d024f4a1..000000000 --- a/smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/util/DefaultHttpHeader.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2017 European Commission | CEF eDelivery - * - * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * - * You may obtain a copy of the Licence attached in file: LICENCE-EUPL-v1.2.pdf - * - * Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and limitations under the Licence. - */ - -package eu.europa.ec.cipa.smp.server.util; - -import javax.ws.rs.core.Cookie; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import java.util.*; -/** - * Created by rodrfla on 13/01/2017. - */ -public class DefaultHttpHeader implements HttpHeaders { - - private Map<String, List<String>> headerMap; - private List<String> requestHeaders; - - { - headerMap = new HashMap<>(); - requestHeaders = new ArrayList<>(); - } - - public void addRequestHeader(String headerParameter, List<String> values) { - headerMap.put(headerParameter, values); - } - - @Override - public List<String> getRequestHeader(String headerParameter) { - return headerMap.get(headerParameter); - } - - @Override - public String getHeaderString(String name) { - return null; - } - - @Override - public MultivaluedMap<String, String> getRequestHeaders() { - return null; - } - - @Override - public List<MediaType> getAcceptableMediaTypes() { - return null; - } - - @Override - public List<Locale> getAcceptableLanguages() { - return null; - } - - @Override - public MediaType getMediaType() { - return null; - } - - @Override - public Locale getLanguage() { - return null; - } - - @Override - public Map<String, Cookie> getCookies() { - return null; - } - - @Override - public Date getDate() { - return null; - } - - @Override - public int getLength() { - return 0; - } -} diff --git a/smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/util/IdentifierUtilsTest.java b/smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/util/IdentifierUtilsTest.java deleted file mode 100644 index 90ac8130c..000000000 --- a/smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/util/IdentifierUtilsTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2017 European Commission | CEF eDelivery - * - * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * - * You may obtain a copy of the Licence attached in file: LICENCE-EUPL-v1.2.pdf - * - * Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and limitations under the Licence. - */ -package eu.europa.ec.cipa.smp.server.util; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import eu.europa.ec.edelivery.smp.data.model.CommonColumnsLengths; -import org.junit.Test; -import org.oasis_open.docs.bdxr.ns.smp._2016._05.DocumentIdentifier; -import org.oasis_open.docs.bdxr.ns.smp._2016._05.ParticipantIdentifierType; - -import static org.junit.Assert.*; - -/** - * Test class for class {@link IdentifierUtils}. - * - * @author PEPPOL.AT, BRZ, Philip Helger - */ -public final class IdentifierUtilsTest { - - @Test - public void testAreIdentifiersEqualPariticpantIdentifier () { - final ParticipantIdentifierType aPI1 = new ParticipantIdentifierType(null, "0088:123abc"); - - final ParticipantIdentifierType aPI3a = new ParticipantIdentifierType("iso6523-actorid-upis","0088:123456"); - final ParticipantIdentifierType aPI3b = new ParticipantIdentifierType ("my-actorid-scheme", "0088:12345"); - assertTrue (IdentifierUtils.areIdentifiersEqual (aPI1, aPI1)); - assertFalse (IdentifierUtils.areIdentifiersEqual (aPI1, aPI3a)); - assertFalse (IdentifierUtils.areIdentifiersEqual (aPI1, aPI3b)); - assertFalse (IdentifierUtils.areIdentifiersEqual (aPI3a, aPI3b)); - - try { - IdentifierUtils.areIdentifiersEqual (aPI1, null); - fail ("null parameter not allowed"); - } - catch (final IllegalArgumentException ex) { - // expected - } - - try { - IdentifierUtils.areIdentifiersEqual (null, aPI1); - fail ("null parameter not allowed"); - } - catch (final IllegalArgumentException ex) { - // expected - } - } - -} diff --git a/smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/util/SMPDBUtilsTest.java b/smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/util/SMPDBUtilsTest.java deleted file mode 100644 index fcbb30287..000000000 --- a/smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/util/SMPDBUtilsTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2017 European Commission | CEF eDelivery - * - * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * - * You may obtain a copy of the Licence attached in file: LICENCE-EUPL-v1.2.pdf - * - * Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and limitations under the Licence. - */ -package eu.europa.ec.cipa.smp.server.util; - -import org.junit.Test; -import org.oasis_open.docs.bdxr.ns.smp._2016._05.ExtensionType; -import org.w3c.dom.Element; - -import java.util.Arrays; - -import static org.junit.Assert.*; - -/** - * @author PEPPOL.AT, BRZ, Philip Helger - */ -public class SMPDBUtilsTest {/* - @Test - public void getRFC1421CompliantStringWithoutCarriageReturnCharacters () { - assertNull (SMPDBUtils.getRFC1421CompliantStringWithoutCarriageReturnCharacters(null)); - assertEquals ("", SMPDBUtils.getRFC1421CompliantStringWithoutCarriageReturnCharacters("")); - - // for up to 64 chars it makes no difference - for (int i = 0; i <= 64; ++i) { - final char [] aChars = new char [i]; - Arrays.fill (aChars, 'a'); - final String sText = new String (aChars); - assertEquals (sText, SMPDBUtils.getRFC1421CompliantStringWithoutCarriageReturnCharacters(sText)); - } - - final String sLong = "123456789012345678901234567890123456789012345678901234567890abcd" - + "123456789012345678901234567890123456789012345678901234567890abcd" - + "xyz"; - final String sFormatted = SMPDBUtils.getRFC1421CompliantStringWithoutCarriageReturnCharacters(sLong); - assertEquals ("123456789012345678901234567890123456789012345678901234567890abcd\n" - + "123456789012345678901234567890123456789012345678901234567890abcd\n" - + "xyz", sFormatted); - } - - @Test - public void testConvertFromString () { - // Use elements - final String sXML = "<any xmlns=\"urn:foo\"><child>text1</child><child2 /></any>"; - final ExtensionType aExtension = SMPDBUtils.getAsExtensionSafe(sXML); - assertNotNull (aExtension); - assertNotNull (aExtension.getAny ()); - assertTrue (aExtension.getAny () instanceof Element); - - assertNull (SMPDBUtils.getAsExtensionSafe((String) null)); - assertNull (SMPDBUtils.getAsExtensionSafe("")); - - // Convert back to String - final String sXML2 = SMPDBUtils.convert(aExtension); - assertEquals (sXML, sXML2); - - // Cannot convert non-element - ExtensionType extension = SMPDBUtils.getAsExtensionSafe("Plain text"); - assertNull(extension); - } - */ -} diff --git a/smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/security/SignerTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataSignerTest.java similarity index 72% rename from smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/security/SignerTest.java rename to smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataSignerTest.java index 8e15d06e2..1a881667f 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/cipa/smp/server/security/SignerTest.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceMetadataSignerTest.java @@ -1,7 +1,7 @@ /* - * Copyright 2017 European Commission | CEF eDelivery + * Copyright 2018 European Commission | CEF eDelivery * - * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence"); + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * * You may obtain a copy of the Licence attached in file: LICENCE-EUPL-v1.2.pdf @@ -11,25 +11,36 @@ * See the Licence for the specific language governing permissions and limitations under the Licence. */ -package eu.europa.ec.cipa.smp.server.security; +package eu.europa.ec.edelivery.smp.services; +import eu.europa.ec.cipa.smp.server.security.SignatureUtil; +import eu.europa.ec.edelivery.smp.services.ServiceMetadataSigner; import org.junit.Test; import org.w3c.dom.Document; import org.w3c.dom.Element; -import java.security.cert.X509Certificate; - import static eu.europa.ec.cipa.smp.server.util.XmlTestUtils.loadDocument; /** * Created by rodrfla on 20/02/2017. */ -public class SignerTest { + +public class ServiceMetadataSignerTest { + + private final static String KEYSTORE_PATH = Thread.currentThread().getContextClassLoader().getResource("signature_keys.jks").getFile(); + private static final String KEYSTORE_PASS = "mock"; + private static final String KEY_ALIAS = "smp_mock"; private Document loadAndSignDocumentForDefault() throws Exception { + ServiceMetadataSigner signer = new ServiceMetadataSigner(); + signer.setKeystoreFilePath(KEYSTORE_PATH); + signer.setKeystorePassword(KEYSTORE_PASS); + signer.setXmldsigKeystoreKeyAlias(KEY_ALIAS); + signer.setXmldsigKeystoreKeyPassword(KEYSTORE_PASS); + signer.init(); + Document documentToSign = loadDocument("/input/SignedServiceMetadata_withoutSignature.xml"); - Signer signatureSigner = new Signer(SignatureUtil.loadPrivateKey(), (X509Certificate) SignatureUtil.loadCertificate()); - signatureSigner.signXML(documentToSign.getDocumentElement()); + signer.sign(documentToSign); return documentToSign; } @@ -76,4 +87,5 @@ public class SignerTest { SignatureUtil.validateSignature(adminSignature); } + } diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SmpWebAppConfig.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SmpWebAppConfig.java index 0d4176545..4d1ab0ef7 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SmpWebAppConfig.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SmpWebAppConfig.java @@ -13,7 +13,6 @@ package eu.europa.ec.edelivery.smp.config; -import eu.europa.ec.cipa.smp.server.util.SignatureFilter; import eu.europa.ec.edelivery.smp.error.ErrorMappingControllerAdvice; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/validation/ServiceGroupValidator.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/validation/ServiceGroupValidator.java index 1b6e13661..3b0e28d7a 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/validation/ServiceGroupValidator.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/validation/ServiceGroupValidator.java @@ -13,7 +13,6 @@ package eu.europa.ec.edelivery.smp.validation; -import eu.europa.ec.cipa.smp.server.util.IdentifierUtils; import eu.europa.ec.edelivery.smp.error.exceptions.BadRequestException; import eu.europa.ec.smp.api.Identifiers; import org.oasis_open.docs.bdxr.ns.smp._2016._05.ParticipantIdentifierType; @@ -46,8 +45,8 @@ public class ServiceGroupValidator { public void validate(String serviceGroupId, ServiceGroup serviceGroup) { - final ParticipantIdentifierType aServiceGroupID = Identifiers.asParticipantId(serviceGroupId); - if (!IdentifierUtils.areIdentifiersEqual(aServiceGroupID, serviceGroup.getParticipantIdentifier())) { + final ParticipantIdentifierType participantId = Identifiers.asParticipantId(serviceGroupId); + if (!participantId.equals(serviceGroup.getParticipantIdentifier())) { // Business identifier must equal path throw new BadRequestException(WRONG_FIELD, "Service Group Ids don't match between URL parameter and XML body"); } -- GitLab