You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bh...@apache.org on 2015/01/12 12:20:08 UTC

git commit: updated refs/heads/master to aaf6a34

Repository: cloudstack
Updated Branches:
  refs/heads/master 173710d5b -> aaf6a34c5


CLOUDSTACK-8035: Generate and store X509Cert and reuse this for SAML

The fix generates X509Certificate if missing from DB and uses that for eternity.
SAML SP metadata remains same since it's using the same X509 certificate and
it remains same after restarts. The certificate is serialized, base64 encoded
and stored in the keystore table under a specific name. For reading, it's
retrieved, base64 decoded and deserialized.

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>
(cherry picked from commit 43587143811b222ca131b0e1237f9e99cd94694d)
Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


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

Branch: refs/heads/master
Commit: aaf6a34c54a88e92b03696c91f4fcc1ddc472559
Parents: 173710d
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Mon Jan 12 16:44:23 2015 +0530
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Mon Jan 12 16:49:49 2015 +0530

----------------------------------------------------------------------
 .../cloudstack/saml/SAML2AuthManagerImpl.java   | 39 ++++++++++++++++----
 .../apache/cloudstack/utils/auth/SAMLUtils.java |  3 +-
 2 files changed, 34 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aaf6a34c/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java
index 3178f31..f175081 100644
--- a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java
+++ b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java
@@ -27,6 +27,7 @@ import org.apache.cloudstack.framework.security.keystore.KeystoreDao;
 import org.apache.cloudstack.framework.security.keystore.KeystoreVO;
 import org.apache.cloudstack.utils.auth.SAMLUtils;
 import org.apache.log4j.Logger;
+import org.apache.commons.codec.binary.Base64;
 import org.opensaml.DefaultBootstrap;
 import org.opensaml.common.xml.SAMLConstants;
 import org.opensaml.saml2.metadata.EntityDescriptor;
@@ -45,6 +46,12 @@ import org.springframework.stereotype.Component;
 import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.xml.stream.FactoryConfigurationError;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
 import java.security.InvalidKeyException;
 import java.security.KeyPair;
 import java.security.NoSuchAlgorithmException;
@@ -94,12 +101,12 @@ public class SAML2AuthManagerImpl extends AdapterBase implements SAML2AuthManage
     }
 
     private boolean setup() {
-        KeystoreVO keyStoreVO = _ksDao.findByName(SAMLUtils.CERTIFICATE_NAME);
+        KeystoreVO keyStoreVO = _ksDao.findByName(SAMLUtils.SAMLSP_KEYPAIR);
         if (keyStoreVO == null) {
             try {
                 KeyPair keyPair = SAMLUtils.generateRandomKeyPair();
-                _ksDao.save(SAMLUtils.CERTIFICATE_NAME, SAMLUtils.savePrivateKey(keyPair.getPrivate()), SAMLUtils.savePublicKey(keyPair.getPublic()), "saml-sp");
-                keyStoreVO = _ksDao.findByName(SAMLUtils.CERTIFICATE_NAME);
+                _ksDao.save(SAMLUtils.SAMLSP_KEYPAIR, SAMLUtils.savePrivateKey(keyPair.getPrivate()), SAMLUtils.savePublicKey(keyPair.getPublic()), "samlsp-keypair");
+                keyStoreVO = _ksDao.findByName(SAMLUtils.SAMLSP_KEYPAIR);
             } catch (NoSuchProviderException | NoSuchAlgorithmException e) {
                 s_logger.error("Unable to create and save SAML keypair");
             }
@@ -110,10 +117,28 @@ public class SAML2AuthManagerImpl extends AdapterBase implements SAML2AuthManage
             PublicKey publicKey = SAMLUtils.loadPublicKey(keyStoreVO.getKey());
             if (privateKey != null && publicKey != null) {
                 spKeyPair = new KeyPair(publicKey, privateKey);
-                try {
-                    spX509Key = SAMLUtils.generateRandomX509Certificate(spKeyPair);
-                } catch (NoSuchAlgorithmException | NoSuchProviderException | CertificateEncodingException | SignatureException | InvalidKeyException e) {
-                    s_logger.error("SAML Plugin won't be able to use X509 signed authentication");
+                KeystoreVO x509VO = _ksDao.findByName(SAMLUtils.SAMLSP_X509CERT);
+                if (x509VO == null) {
+                    try {
+                        spX509Key = SAMLUtils.generateRandomX509Certificate(spKeyPair);
+                        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                        ObjectOutput out = new ObjectOutputStream(bos);
+                        out.writeObject(spX509Key);
+                        out.flush();
+                        _ksDao.save(SAMLUtils.SAMLSP_X509CERT, Base64.encodeBase64String(bos.toByteArray()), "", "samlsp-x509cert");
+                        bos.close();
+                    } catch (NoSuchAlgorithmException | NoSuchProviderException | CertificateEncodingException | SignatureException | InvalidKeyException | IOException e) {
+                        s_logger.error("SAML Plugin won't be able to use X509 signed authentication");
+                    }
+                } else {
+                    try {
+                        ByteArrayInputStream bi = new ByteArrayInputStream(Base64.decodeBase64(x509VO.getCertificate()));
+                        ObjectInputStream si = new ObjectInputStream(bi);
+                        spX509Key = (X509Certificate) si.readObject();
+                        bi.close();
+                    } catch (IOException | ClassNotFoundException ignored) {
+                        s_logger.error("SAML Plugin won't be able to use X509 signed authentication. Failed to load X509 Certificate from Database.");
+                    }
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aaf6a34c/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 dbd2d6f..bb4af3a 100644
--- a/utils/src/org/apache/cloudstack/utils/auth/SAMLUtils.java
+++ b/utils/src/org/apache/cloudstack/utils/auth/SAMLUtils.java
@@ -100,7 +100,8 @@ public class SAMLUtils {
     public static final String SAML_NS = "SAML-";
     public static final String SAML_NAMEID = "SAML_NAMEID";
     public static final String SAML_SESSION = "SAML_SESSION";
-    public static final String CERTIFICATE_NAME = "SAMLSP_CERTIFICATE";
+    public static final String SAMLSP_KEYPAIR = "SAMLSP_KEYPAIR";
+    public static final String SAMLSP_X509CERT = "SAMLSP_X509CERT";
 
     public static String createSAMLId(String uid) {
         if (uid == null)  {