SAMLUtils: add unit test for SAMLUtils and method to randomly generate X509 certs
Signed-off-by: Rohit Yadav <rohit.ya...@shapeblue.com> Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/1ed532fb Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/1ed532fb Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/1ed532fb Branch: refs/heads/master Commit: 1ed532fb2011b2a6f203cfa000df5466d7924f25 Parents: 15fdc17 Author: Rohit Yadav <rohit.ya...@shapeblue.com> Authored: Mon Aug 25 17:31:01 2014 +0200 Committer: Rohit Yadav <rohit.ya...@shapeblue.com> Committed: Thu Aug 28 19:45:26 2014 +0200 ---------------------------------------------------------------------- .../apache/cloudstack/utils/auth/SAMLUtils.java | 37 ++++++++++- .../cloudstack/utils/auth/SAMLUtilsTest.java | 67 ++++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1ed532fb/utils/src/org/apache/cloudstack/utils/auth/SAMLUtils.java ---------------------------------------------------------------------- diff --git a/utils/src/org/apache/cloudstack/utils/auth/SAMLUtils.java b/utils/src/org/apache/cloudstack/utils/auth/SAMLUtils.java index 51cf507..a562d48 100644 --- a/utils/src/org/apache/cloudstack/utils/auth/SAMLUtils.java +++ b/utils/src/org/apache/cloudstack/utils/auth/SAMLUtils.java @@ -21,6 +21,8 @@ package org.apache.cloudstack.utils.auth; import com.cloud.utils.HttpUtils; import org.apache.log4j.Logger; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.x509.X509V1CertificateGenerator; import org.joda.time.DateTime; import org.opensaml.Configuration; import org.opensaml.common.SAMLVersion; @@ -57,6 +59,7 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; +import javax.security.auth.x500.X500Principal; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -66,7 +69,17 @@ import java.io.IOException; import java.io.StringWriter; import java.math.BigInteger; import java.net.URLEncoder; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.security.SecureRandom; +import java.security.Security; +import java.security.SignatureException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.Date; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; @@ -88,7 +101,7 @@ public class SAMLUtils { } public static String generateSecureRandomId() { - return new BigInteger(130, new SecureRandom()).toString(32); + return new BigInteger(160, new SecureRandom()).toString(32); } public static AuthnRequest buildAuthnRequestObject(String spId, String idpUrl, String consumerUrl) { @@ -194,4 +207,26 @@ public class SAMLUtils { return (Response) unmarshaller.unmarshall(element); } + public static X509Certificate generateRandomX509Certification() throws NoSuchAlgorithmException, NoSuchProviderException, CertificateEncodingException, SignatureException, InvalidKeyException { + Date validityBeginDate = new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000); + Date validityEndDate = new Date(System.currentTimeMillis() + 2 * 365 * 24 * 60 * 60 * 1000); + + Security.addProvider(new BouncyCastleProvider()); + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC"); + keyPairGenerator.initialize(1024, new SecureRandom()); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + + X500Principal dnName = new X500Principal("CN=John Doe"); + X509V1CertificateGenerator certGen = new X509V1CertificateGenerator(); + certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis())); + certGen.setSubjectDN(dnName); + certGen.setIssuerDN(dnName); // use the same + certGen.setNotBefore(validityBeginDate); + certGen.setNotAfter(validityEndDate); + certGen.setPublicKey(keyPair.getPublic()); + certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); + + return certGen.generate(keyPair.getPrivate(), "BC"); + } + } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1ed532fb/utils/test/org/apache/cloudstack/utils/auth/SAMLUtilsTest.java ---------------------------------------------------------------------- diff --git a/utils/test/org/apache/cloudstack/utils/auth/SAMLUtilsTest.java b/utils/test/org/apache/cloudstack/utils/auth/SAMLUtilsTest.java new file mode 100644 index 0000000..1d34ba1 --- /dev/null +++ b/utils/test/org/apache/cloudstack/utils/auth/SAMLUtilsTest.java @@ -0,0 +1,67 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package org.apache.cloudstack.utils.auth; + +import junit.framework.TestCase; +import org.junit.Test; +import org.opensaml.saml2.core.AuthnRequest; +import org.opensaml.saml2.core.LogoutRequest; +import org.opensaml.saml2.core.NameID; +import org.opensaml.saml2.core.impl.NameIDBuilder; + +public class SAMLUtilsTest extends TestCase { + + @Test + public void testSAMLId() throws Exception { + assertTrue(SAMLUtils.checkSAMLUserId(SAMLUtils.createSAMLId("someUID"))); + assertFalse(SAMLUtils.checkSAMLUserId("randomUID")); + } + + @Test + public void testGenerateSecureRandomId() throws Exception { + assertTrue(SAMLUtils.generateSecureRandomId().length() == 32); + } + + @Test + public void testBuildAuthnRequestObject() throws Exception { + String consumerUrl = "http://someurl.com"; + String idpUrl = "http://idp.domain.example"; + String spId = "cloudstack"; + AuthnRequest req = SAMLUtils.buildAuthnRequestObject(spId, idpUrl, consumerUrl); + assertEquals(req.getAssertionConsumerServiceURL(), consumerUrl); + assertEquals(req.getDestination(), idpUrl); + assertEquals(req.getIssuer().getValue(), spId); + } + + @Test + public void testBuildLogoutRequest() throws Exception { + String logoutUrl = "http://logoutUrl"; + String spId = "cloudstack"; + String sessionIndex = "12345"; + String nameIdString = "someNameID"; + NameID sessionNameId = new NameIDBuilder().buildObject(); + sessionNameId.setValue(nameIdString); + LogoutRequest req = SAMLUtils.buildLogoutRequest(logoutUrl, spId, sessionNameId, sessionIndex); + assertEquals(req.getDestination(), logoutUrl); + assertEquals(req.getIssuer().getValue(), spId); + assertEquals(req.getNameID().getValue(), nameIdString); + assertEquals(req.getSessionIndexes().get(0).getSessionIndex(), sessionIndex); + } +} \ No newline at end of file