syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject [2/5] syncope git commit: Dynamically generate a keypair for use in the SAML signing tests
Date Fri, 11 Aug 2017 12:39:53 GMT
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/1d8b6c62
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/1d8b6c62
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/1d8b6c62

Branch: refs/heads/2_0_X
Commit: 1d8b6c62110564b57eb615b405346f1c978ee65e
Parents: 919584f
Author: Colm O hEigeartaigh <coheigea@apache.org>
Authored: Fri Aug 11 12:38:06 2017 +0100
Committer: Colm O hEigeartaigh <coheigea@apache.org>
Committed: Fri Aug 11 13:16:06 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/1d8b6c62/fit/core-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index de491a3..d28eb06 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/1d8b6c62/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 e8a5add..4ae8c8f 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 javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.xml.namespace.QName;
@@ -72,6 +83,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;
@@ -86,6 +104,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() {
@@ -98,13 +118,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);
@@ -124,7 +148,7 @@ public class SAML2ITCase extends AbstractITCase {
     }
 
     @AfterClass
-    public static void clearIdPs() {
+    public static void clearIdPs() throws Exception {
         if (!SAML2SPDetector.isSAML2SPAvailable()) {
             return;
         }
@@ -132,6 +156,9 @@ public class SAML2ITCase extends AbstractITCase {
         for (SAML2IdPTO idp : saml2IdPService.list()) {
             saml2IdPService.delete(idp.getKey());
         }
+
+        Files.delete(keystorePath);
+        Files.delete(truststorePath);
     }
 
     @Test
@@ -411,16 +438,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/1d8b6c62/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/1d8b6c62/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index e29b8a4..004a8b5 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.1</connid.soap.version>
     <connid.rest.version>1.0.1</connid.rest.version>


Mime
View raw message