You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by co...@apache.org on 2017/08/11 12:15:13 UTC

[1/3] syncope git commit: Take the valid SAML Assertion from the validator response instead.

Repository: syncope
Updated Branches:
  refs/heads/master 5da5326ac -> 883911633


Take the valid SAML Assertion from the validator response instead.


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/88391163
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/88391163
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/88391163

Branch: refs/heads/master
Commit: 88391163320f5d73ca51e4c03b0edc5371ab6e1e
Parents: d8d5fe5
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Fri Aug 11 12:51:22 2017 +0100
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Fri Aug 11 13:15:07 2017 +0100

----------------------------------------------------------------------
 .../apache/syncope/core/logic/SAML2SPLogic.java | 65 ++++++++++----------
 .../core/logic/saml2/SAML2ReaderWriter.java     |  8 ++-
 2 files changed, 39 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/88391163/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
index 31ef8c4..03576ab 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
@@ -37,6 +37,7 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.commons.lang3.tuple.Triple;
 import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer;
 import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
+import org.apache.cxf.rs.security.saml.sso.SSOValidatorResponse;
 import org.apache.syncope.common.lib.AbstractBaseBean;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AttrTO;
@@ -371,8 +372,10 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
         if (idp.getConnObjectKeyItem() == null) {
             throw new IllegalArgumentException("No mapping provided for SAML 2.0 IdP '" + idp.getId() + "'");
         }
+
+        SSOValidatorResponse validatorResponse = null;
         try {
-            saml2rw.validate(
+            validatorResponse = saml2rw.validate(
                     samlResponse,
                     idp,
                     getAssertionConsumerURL(response.getSpEntityID(), response.getUrlContext()),
@@ -390,47 +393,45 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
         responseTO.setIdp(idp.getId());
         responseTO.setSloSupported(idp.getSLOLocation(idp.getBindingType()) != null);
 
-        NameID nameID = null;
+        Assertion assertion = validatorResponse.getOpensamlAssertion();
+        NameID nameID = assertion.getSubject().getNameID();
         String keyValue = null;
-        for (Assertion assertion : samlResponse.getAssertions()) {
-            nameID = assertion.getSubject().getNameID();
-            if (StringUtils.isNotBlank(nameID.getValue())
-                    && idp.getConnObjectKeyItem().getExtAttrName().equals("NameID")) {
+        if (StringUtils.isNotBlank(nameID.getValue())
+            && idp.getConnObjectKeyItem().getExtAttrName().equals("NameID")) {
 
-                keyValue = nameID.getValue();
-            }
+            keyValue = nameID.getValue();
+        }
 
-            if (assertion.getConditions().getNotOnOrAfter() != null) {
-                responseTO.setNotOnOrAfter(assertion.getConditions().getNotOnOrAfter().toDate());
-            }
-            for (AuthnStatement authnStmt : assertion.getAuthnStatements()) {
-                responseTO.setSessionIndex(authnStmt.getSessionIndex());
+        if (assertion.getConditions().getNotOnOrAfter() != null) {
+            responseTO.setNotOnOrAfter(assertion.getConditions().getNotOnOrAfter().toDate());
+        }
+        for (AuthnStatement authnStmt : assertion.getAuthnStatements()) {
+            responseTO.setSessionIndex(authnStmt.getSessionIndex());
 
-                responseTO.setAuthInstant(authnStmt.getAuthnInstant().toDate());
-                if (authnStmt.getSessionNotOnOrAfter() != null) {
-                    responseTO.setNotOnOrAfter(authnStmt.getSessionNotOnOrAfter().toDate());
-                }
+            responseTO.setAuthInstant(authnStmt.getAuthnInstant().toDate());
+            if (authnStmt.getSessionNotOnOrAfter() != null) {
+                responseTO.setNotOnOrAfter(authnStmt.getSessionNotOnOrAfter().toDate());
             }
+        }
 
-            for (AttributeStatement attrStmt : assertion.getAttributeStatements()) {
-                for (Attribute attr : attrStmt.getAttributes()) {
-                    if (!attr.getAttributeValues().isEmpty()) {
-                        String attrName = attr.getFriendlyName() == null ? attr.getName() : attr.getFriendlyName();
-                        if (attrName.equals(idp.getConnObjectKeyItem().getExtAttrName())
-                                && attr.getAttributeValues().get(0) instanceof XSString) {
+        for (AttributeStatement attrStmt : assertion.getAttributeStatements()) {
+            for (Attribute attr : attrStmt.getAttributes()) {
+                if (!attr.getAttributeValues().isEmpty()) {
+                    String attrName = attr.getFriendlyName() == null ? attr.getName() : attr.getFriendlyName();
+                    if (attrName.equals(idp.getConnObjectKeyItem().getExtAttrName())
+                        && attr.getAttributeValues().get(0) instanceof XSString) {
 
-                            keyValue = ((XSString) attr.getAttributeValues().get(0)).getValue();
-                        }
+                        keyValue = ((XSString) attr.getAttributeValues().get(0)).getValue();
+                    }
 
-                        AttrTO attrTO = new AttrTO();
-                        attrTO.setSchema(attrName);
-                        for (XMLObject value : attr.getAttributeValues()) {
-                            if (value.getDOM() != null) {
-                                attrTO.getValues().add(value.getDOM().getTextContent());
-                            }
+                    AttrTO attrTO = new AttrTO();
+                    attrTO.setSchema(attrName);
+                    for (XMLObject value : attr.getAttributeValues()) {
+                        if (value.getDOM() != null) {
+                            attrTO.getValues().add(value.getDOM().getTextContent());
                         }
-                        responseTO.getAttrs().add(attrTO);
                     }
+                    responseTO.getAttrs().add(attrTO);
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/88391163/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
index fa48e77..3c2d547 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
@@ -44,6 +44,7 @@ import javax.xml.transform.stream.StreamResult;
 import org.apache.cxf.rs.security.saml.DeflateEncoderDecoder;
 import org.apache.cxf.rs.security.saml.sso.SAMLProtocolResponseValidator;
 import org.apache.cxf.rs.security.saml.sso.SAMLSSOResponseValidator;
+import org.apache.cxf.rs.security.saml.sso.SSOValidatorResponse;
 import org.apache.cxf.staxutils.StaxUtils;
 import org.apache.syncope.common.lib.SSOConstants;
 import org.apache.syncope.common.lib.types.SAML2BindingType;
@@ -203,7 +204,7 @@ public class SAML2ReaderWriter {
         return Base64.getEncoder().encodeToString(deflatedBytes);
     }
 
-    public void validate(
+    public SSOValidatorResponse validate(
             final Response samlResponse,
             final SAML2IdPEntity idp,
             final String assertionConsumerURL,
@@ -225,7 +226,8 @@ public class SAML2ReaderWriter {
         ssoResponseValidator.setIssuerIDP(idp.getId());
         ssoResponseValidator.setRequestId(requestId);
         ssoResponseValidator.setSpIdentifier(spEntityID);
-        ssoResponseValidator.validateSamlResponse(samlResponse, idp.getBindingType() == SAML2BindingType.POST);
+        SSOValidatorResponse validatorResponse =
+            ssoResponseValidator.validateSamlResponse(samlResponse, idp.getBindingType() == SAML2BindingType.POST);
 
         if (LOG.isDebugEnabled()) {
             try {
@@ -238,5 +240,7 @@ public class SAML2ReaderWriter {
                 LOG.error("Could not log the SAML response with decrypted assertions", e);
             }
         }
+
+        return validatorResponse;
     }
 }


[3/3] syncope git commit: SYNCOPE-1194 - Sign the SAML SSO Service Provider Metadata

Posted by co...@apache.org.
SYNCOPE-1194 - Sign the SAML SSO Service Provider Metadata


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/a22a6b55
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/a22a6b55
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/a22a6b55

Branch: refs/heads/master
Commit: a22a6b55f83846bf06bbb322e9acc234a9425ea5
Parents: 5da5326
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Fri Aug 11 11:59:08 2017 +0100
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Fri Aug 11 13:15:07 2017 +0100

----------------------------------------------------------------------
 .../apache/syncope/core/logic/SAML2SPLogic.java   |  1 +
 .../core/logic/saml2/SAML2ReaderWriter.java       |  3 +--
 .../org/apache/syncope/fit/core/SAML2ITCase.java  | 18 ++++++++++++++++++
 3 files changed, 20 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/a22a6b55/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
index 87b7eb6..31ef8c4 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
@@ -200,6 +200,7 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
             }
 
             spEntityDescriptor.getRoleDescriptors().add(spSSODescriptor);
+            saml2rw.sign(spEntityDescriptor);
 
             saml2rw.write(new OutputStreamWriter(os), spEntityDescriptor, true);
         } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a22a6b55/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
index e83af5e..fa48e77 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
@@ -152,14 +152,13 @@ public class SAML2ReaderWriter {
         return responseObject;
     }
 
-    public void sign(final RequestAbstractType request) throws SecurityException {
+    public void sign(final SignableSAMLObject signableObject) throws SecurityException {
         org.opensaml.xmlsec.signature.Signature signature = OpenSAMLUtil.buildSignature();
         signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
         signature.setSignatureAlgorithm(sigAlgo);
         signature.setSigningCredential(loader.getCredential());
         signature.setKeyInfo(keyInfoGenerator.generate(loader.getCredential()));
 
-        SignableSAMLObject signableObject = (SignableSAMLObject) request;
         signableObject.setSignature(signature);
         signableObject.releaseDOM();
         signableObject.releaseChildrenDOM(true);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a22a6b55/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
index b87db1b..93608c2 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
@@ -30,10 +30,13 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.nio.charset.StandardCharsets;
 import java.security.KeyStore;
+import java.security.cert.X509Certificate;
 import java.util.Collections;
 import java.util.Optional;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
+import javax.xml.namespace.QName;
+
 import org.apache.commons.codec.binary.Base64;
 import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.jaxrs.client.WebClient;
@@ -67,6 +70,7 @@ import org.apache.wss4j.common.util.DOM2Writer;
 import org.apache.wss4j.common.util.Loader;
 import org.apache.wss4j.dom.WSConstants;
 import org.apache.wss4j.dom.engine.WSSConfig;
+import org.apache.xml.security.signature.XMLSignature;
 import org.joda.time.DateTime;
 import org.junit.AfterClass;
 import org.junit.Assume;
@@ -74,6 +78,7 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opensaml.saml.common.xml.SAMLConstants;
 import org.opensaml.saml.saml2.core.Status;
+import org.opensaml.xmlsec.signature.support.SignatureConstants;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -142,6 +147,19 @@ public class SAML2ITCase extends AbstractITCase {
                     new InputStreamReader((InputStream) response.getEntity(), StandardCharsets.UTF_8));
             assertEquals("EntityDescriptor", responseDoc.getDocumentElement().getLocalName());
             assertEquals("urn:oasis:names:tc:SAML:2.0:metadata", responseDoc.getDocumentElement().getNamespaceURI());
+
+            // Get the signature
+            QName signatureQName = new QName(SignatureConstants.XMLSIG_NS, "Signature");
+            Element signatureElement =
+                DOMUtils.getFirstChildWithName(responseDoc.getDocumentElement(), signatureQName);
+            assertNotNull(signatureElement);
+
+            // Validate the signature
+            XMLSignature signature = new XMLSignature(signatureElement, null);
+            KeyStore keystore = KeyStore.getInstance("JKS");
+            keystore.load(Loader.getResourceAsStream("keystore"), "changeit".toCharArray());
+            assertTrue(signature.checkSignatureValue((X509Certificate)keystore.getCertificate("sp")));
+
         } catch (Exception e) {
             LOG.error("During SAML 2.0 SP metadata parsing", e);
             fail(e.getMessage());


[2/3] syncope git commit: Dynamically generate a keypair for use in the SAML signing tests

Posted by co...@apache.org.
Dynamically generate a keypair for use in the SAML signing tests


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/d8d5fe5e
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/d8d5fe5e
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/d8d5fe5e

Branch: refs/heads/master
Commit: d8d5fe5ee8c7e887f5c2fda8362aa9a0296635c9
Parents: a22a6b5
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Fri Aug 11 12:38:06 2017 +0100
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Fri Aug 11 13:15:07 2017 +0100

----------------------------------------------------------------------
 fit/core-reference/pom.xml                      |   7 ++
 .../apache/syncope/fit/core/SAML2ITCase.java    | 104 +++++++++++++++++--
 fit/core-reference/src/test/resources/fediz.xml |  14 +--
 pom.xml                                         |   2 +
 4 files changed, 108 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/d8d5fe5e/fit/core-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 5762a33..45a6214 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -176,6 +176,13 @@ under the License.
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.bouncycastle</groupId>
+      <artifactId>bcpkix-jdk15on</artifactId>
+      <version>${bouncycastle.version}</version>
+      <scope>test</scope>
+    </dependency>
+
   </dependencies>
 
   <build>

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8d5fe5e/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
index 93608c2..9ee5653 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
@@ -26,12 +26,23 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.io.File;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.math.BigInteger;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
 import java.security.KeyStore;
+import java.security.SecureRandom;
+import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
 import java.util.Collections;
+import java.util.Date;
 import java.util.Optional;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
@@ -71,6 +82,13 @@ import org.apache.wss4j.common.util.Loader;
 import org.apache.wss4j.dom.WSConstants;
 import org.apache.wss4j.dom.engine.WSSConfig;
 import org.apache.xml.security.signature.XMLSignature;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x500.style.RFC4519Style;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
 import org.joda.time.DateTime;
 import org.junit.AfterClass;
 import org.junit.Assume;
@@ -85,6 +103,8 @@ import org.w3c.dom.Element;
 public class SAML2ITCase extends AbstractITCase {
 
     private static SyncopeClient anonymous;
+    private static Path keystorePath;
+    private static Path truststorePath;
 
     @BeforeClass
     public static void setup() {
@@ -97,13 +117,17 @@ public class SAML2ITCase extends AbstractITCase {
     }
 
     @BeforeClass
-    public static void importFromIdPMetadata() {
+    public static void importFromIdPMetadata() throws Exception {
         if (!SAML2SPDetector.isSAML2SPAvailable()) {
             return;
         }
 
         assertTrue(saml2IdPService.list().isEmpty());
 
+        createKeystores();
+
+        updateMetadataWithCert();
+
         WebClient.client(saml2IdPService).
                 accept(MediaType.APPLICATION_XML_TYPE).
                 type(MediaType.APPLICATION_XML_TYPE);
@@ -123,7 +147,7 @@ public class SAML2ITCase extends AbstractITCase {
     }
 
     @AfterClass
-    public static void clearIdPs() {
+    public static void clearIdPs() throws Exception {
         if (!SAML2SPDetector.isSAML2SPAvailable()) {
             return;
         }
@@ -131,6 +155,9 @@ public class SAML2ITCase extends AbstractITCase {
         for (SAML2IdPTO idp : saml2IdPService.list()) {
             saml2IdPService.delete(idp.getKey());
         }
+
+        Files.delete(keystorePath);
+        Files.delete(truststorePath);
     }
 
     @Test
@@ -409,16 +436,81 @@ public class SAML2ITCase extends AbstractITCase {
         if (signAssertion) {
             Crypto issuerCrypto = new Merlin();
             KeyStore keyStore = KeyStore.getInstance("JKS");
-            ClassLoader loader = Loader.getClassLoader(getClass());
-            InputStream input = Merlin.loadInputStream(loader, "keystore");
-            keyStore.load(input, "changeit".toCharArray());
+            InputStream input = Files.newInputStream(keystorePath);
+            keyStore.load(input, "security".toCharArray());
             ((Merlin) issuerCrypto).setKeyStore(keyStore);
 
-            assertion.signAssertion("sp", "changeit", issuerCrypto, false);
+            assertion.signAssertion("subject", "security", issuerCrypto, false);
         }
 
         response.getAssertions().add(assertion.getSaml2());
 
         return response;
     }
+
+    private static void createKeystores() throws Exception {
+        // Create KeyPair
+        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
+        keyPairGenerator.initialize(1024, new SecureRandom());
+        KeyPair keyPair = keyPairGenerator.generateKeyPair();
+
+        Date currentDate = new Date();
+        Date expiryDate = new Date(currentDate.getTime() + 365L * 24L * 60L * 60L * 1000L);
+
+        // Create X509Certificate
+        String issuerName = "CN=Issuer";
+        String subjectName = "CN=Subject";
+        BigInteger serial = new BigInteger("123456");
+        X509v3CertificateBuilder certBuilder =
+                        new X509v3CertificateBuilder(new X500Name(RFC4519Style.INSTANCE, issuerName), serial, currentDate, expiryDate,
+                                        new X500Name(RFC4519Style.INSTANCE, subjectName),
+                                        SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded()));
+        ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSAEncryption").build(keyPair.getPrivate());
+        X509Certificate certificate = new JcaX509CertificateConverter().getCertificate(certBuilder.build(contentSigner));
+
+        // Store Private Key + Certificate in Keystore
+        KeyStore keystore = KeyStore.getInstance("JKS");
+        keystore.load(null, "security".toCharArray());
+        keystore.setKeyEntry("subject", keyPair.getPrivate(), "security".toCharArray(), new Certificate[] {certificate});
+
+        File keystoreFile = File.createTempFile("samlkeystore", ".jks");
+        try (OutputStream output = Files.newOutputStream(keystoreFile.toPath())) {
+            keystore.store(output, "security".toCharArray());
+        }
+        keystorePath = keystoreFile.toPath();
+
+        // Now store the Certificate in the truststore
+        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+        trustStore.load(null, "security".toCharArray());
+
+        trustStore.setCertificateEntry("subject", certificate);
+
+        File truststoreFile = File.createTempFile("samltruststore", ".jks");
+        try (OutputStream output = Files.newOutputStream(truststoreFile.toPath())) {
+            trustStore.store(output, "security".toCharArray());
+        }
+        truststorePath = truststoreFile.toPath();
+    }
+
+    private static void updateMetadataWithCert() throws Exception {
+        // Get encoded truststore cert
+        KeyStore keyStore = KeyStore.getInstance("JKS");
+        InputStream input = Files.newInputStream(truststorePath);
+        keyStore.load(input, "security".toCharArray());
+        X509Certificate cert = (X509Certificate)keyStore.getCertificate("subject");
+        String certEncoded = java.util.Base64.getMimeEncoder().encodeToString(cert.getEncoded());
+
+        // Replace the "cert-placeholder" string in the metadata with the actual cert
+        String basedir = System.getProperty("basedir");
+        if (basedir == null) {
+            basedir = new File(".").getCanonicalPath();
+        }
+        Path path = FileSystems.getDefault().getPath(basedir, "/src/test/resources/fediz.xml");
+        String content = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
+        content = content.replaceAll("cert-placeholder", certEncoded);
+
+        Path path2 = FileSystems.getDefault().getPath(basedir, "/target/test-classes/fediz.xml");
+        Files.write(path2, content.getBytes());
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8d5fe5e/fit/core-reference/src/test/resources/fediz.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/fediz.xml b/fit/core-reference/src/test/resources/fediz.xml
index cbc8faa..b8cbda0 100644
--- a/fit/core-reference/src/test/resources/fediz.xml
+++ b/fit/core-reference/src/test/resources/fediz.xml
@@ -23,19 +23,7 @@ under the License.
             <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                 <ds:X509Data>
                     <ds:X509Certificate>
-MIICwTCCAamgAwIBAgIEINqJ9TANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDEwZSRUFMTUEwHhcN
-MTUwNjEwMTU0NDE3WhcNMjUwNDE4MTU0NDE3WjARMQ8wDQYDVQQDEwZSRUFMTUEwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCJDSXn2lDR+JM+AsJarFG3/XGH7K+9AfAbQIz2IgB9MCpO
-KVWTUPCvuo1I+Fp5nEGreuHYLEwgIiam3o+C9tvpLgtDDaDkmXjDzkWpk8z6+im72HZ/ODF93Rqw
-jIiY5ZCzgDumFyPzdKiGwChThamidy+rd6oheSoi6qRVSMMcnwiEUmvkfFvV3izXRqeT5nGQwsin
-y9mCEiGx8jkfxP++H0RQjVjhOwzfQ7epsR7dTQNf2ZhkBR3o6wKV9QnF2IBWHZpA9EK58rWU9H6j
-G7b631rYvwsbOUF9HcZ8DI2BFh+4p18jDN/fnjNGSLr9rYOExpsIiF1cHBK7Tr7WwCmDAgMBAAGj
-ITAfMB0GA1UdDgQWBBRHy0qYoLm9jx/1L6r61NznHKun2jANBgkqhkiG9w0BAQsFAAOCAQEAR9rU
-5Sp1FsOErdvKNFqeaKl0oq6Fuz7BWcGm2kK6+1ZbWE8IOv6Vh+BlLuOe5hF7aLUbm8UIjhKsmg0M
-Ey5MBwkBZktT1qhQteMuiKgYR7CxayCxO0f125RYvvwntJa5rI7bUrzOqX29VQD1qQ/Tb+08fULT
-L7oURP+g88Ff99dn3IpO4VZxZdsbl4+KZRtqQvPAdXNYjOajJtPzS489+/DtfWJ6wPm/7YZ4did4
-1fYcrdwyEZ15L0/5i931z7sztNickm5WhO40qEVDKN6KrlV2Eyea0+933v2Pwe4resTlko9G2T5h
-dEaSbvht2Q/JOMMmT91daeto2oS8HTKhTA==
+cert-placeholder
                    </ds:X509Certificate>
                 </ds:X509Data>
             </ds:KeyInfo>

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8d5fe5e/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index fdd22f2..b3eb5e5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -356,6 +356,8 @@ under the License.
   <properties>
     <syncope.version>${project.version}</syncope.version>
 
+    <bouncycastle.version>1.57</bouncycastle.version>
+
     <connid.version>1.4.3.0</connid.version>
     <connid.soap.version>1.4.2-SNAPSHOT</connid.soap.version>
     <connid.rest.version>1.0.1</connid.rest.version>