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