You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2016/02/24 18:01:50 UTC

[2/5] cxf-fediz git commit: Consolidating Crypto/Certificate loading in the IdP

Consolidating Crypto/Certificate loading in the IdP


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

Branch: refs/heads/master
Commit: f545ba0c03ca60907ca78942d31ff9afbc00d0d5
Parents: 5263f52
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Wed Feb 24 15:17:05 2016 +0000
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Wed Feb 24 15:17:05 2016 +0000

----------------------------------------------------------------------
 .../cxf/fediz/core/config/FedizContext.java     |   4 +
 .../apache/cxf/fediz/core/util/CertsUtils.java  |  30 ++++-
 .../TrustedIdpOIDCProtocolHandler.java          | 131 +++++++------------
 .../TrustedIdpSAMLProtocolHandler.java          |  48 +++----
 .../TrustedIdpWSFedProtocolHandler.java         |  23 +---
 5 files changed, 104 insertions(+), 132 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/f545ba0c/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/FedizContext.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/FedizContext.java b/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/FedizContext.java
index f94ac4a..bb352f8 100644
--- a/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/FedizContext.java
+++ b/plugins/core/src/main/java/org/apache/cxf/fediz/core/config/FedizContext.java
@@ -23,6 +23,7 @@ import java.io.Closeable;
 import java.io.File;
 import java.io.IOException;
 import java.math.BigInteger;
+import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.List;
@@ -120,6 +121,9 @@ public class FedizContext implements Closeable {
             } catch (WSSecurityException e) {
                 LOG.error("Failed to load keystore '" + tm.getName() + "'", e);
                 throw new IllegalConfigurationException("Failed to load keystore '" + tm.getName() + "'");
+            } catch (CertificateException ex) {
+                LOG.error("Failed to read keystore", ex);
+                throw new RuntimeException("Failed to read keystore");
             }
         }
         return certificateStores; 

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/f545ba0c/plugins/core/src/main/java/org/apache/cxf/fediz/core/util/CertsUtils.java
----------------------------------------------------------------------
diff --git a/plugins/core/src/main/java/org/apache/cxf/fediz/core/util/CertsUtils.java b/plugins/core/src/main/java/org/apache/cxf/fediz/core/util/CertsUtils.java
index 0737ea1..038de09 100644
--- a/plugins/core/src/main/java/org/apache/cxf/fediz/core/util/CertsUtils.java
+++ b/plugins/core/src/main/java/org/apache/cxf/fediz/core/util/CertsUtils.java
@@ -20,9 +20,11 @@
 package org.apache.cxf.fediz.core.util;
 
 import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.Properties;
@@ -32,6 +34,8 @@ import org.apache.wss4j.common.crypto.CryptoFactory;
 import org.apache.wss4j.common.crypto.CryptoType;
 import org.apache.wss4j.common.crypto.Merlin;
 import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.xml.security.exceptions.Base64DecodingException;
+import org.apache.xml.security.utils.Base64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -43,12 +47,17 @@ public final class CertsUtils {
         super();
     }
     
-    public static X509Certificate getX509Certificate(String filename) {
+    public static X509Certificate getX509Certificate(String filename) throws CertificateException {
         return getX509Certificate(filename,
                                   Thread.currentThread().getContextClassLoader());
     }
     
-    public static X509Certificate getX509Certificate(String filename, ClassLoader classLoader) {
+    public static X509Certificate getX509Certificate(String filename, ClassLoader classLoader) 
+        throws CertificateException {
+        if (filename == null) {
+            return null;
+        }
+        
         ClassLoader cl = classLoader;
         if (cl == null) {
             cl = Thread.currentThread().getContextClassLoader();
@@ -74,9 +83,12 @@ public final class CertsUtils {
                 LOG.error("No bytes can be read in certificate file " + filename);
                 throw new RuntimeException("No bytes can be read in certificate file " + filename);
             }
-        } catch (Exception ex) {
+        } catch (WSSecurityException ex) {
             LOG.error("Failed to read certificate file " + filename, ex);
             throw new RuntimeException("Failed to read certificate file " + filename, ex);
+        } catch (IOException ex) {
+            LOG.error("Failed to read keystore", ex);
+            throw new RuntimeException("Failed to read keystore");
         }
     }
     
@@ -113,4 +125,16 @@ public final class CertsUtils {
         }
         return issuerCerts[0];
     }
+    
+    public static X509Certificate parseCertificate(String certificate)
+        throws CertificateException, Base64DecodingException, IOException {
+        
+        //before decoding we need to get rod off the prefix and suffix
+        byte[] decoded = Base64.decode(certificate.replaceAll("-----BEGIN CERTIFICATE-----", "").
+                                        replaceAll("-----END CERTIFICATE-----", ""));
+
+        try (InputStream is = new ByteArrayInputStream(decoded)) {
+            return (X509Certificate)CertificateFactory.getInstance("X.509").generateCertificate(is);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/f545ba0c/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpOIDCProtocolHandler.java
----------------------------------------------------------------------
diff --git a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpOIDCProtocolHandler.java b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpOIDCProtocolHandler.java
index ea90193..52e007e 100644
--- a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpOIDCProtocolHandler.java
+++ b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpOIDCProtocolHandler.java
@@ -19,17 +19,15 @@
 
 package org.apache.cxf.fediz.service.idp.protocols;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLEncoder;
 import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 
@@ -65,7 +63,6 @@ import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
 import org.apache.cxf.ws.security.tokenstore.SecurityToken;
 import org.apache.wss4j.common.crypto.CertificateStore;
 import org.apache.wss4j.common.crypto.Crypto;
-import org.apache.wss4j.common.crypto.Merlin;
 import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.common.saml.SAMLCallback;
 import org.apache.wss4j.common.saml.SAMLUtil;
@@ -75,7 +72,6 @@ import org.apache.wss4j.common.saml.bean.SubjectBean;
 import org.apache.wss4j.common.saml.bean.Version;
 import org.apache.wss4j.common.saml.builder.SAML2Constants;
 import org.apache.xml.security.exceptions.Base64DecodingException;
-import org.apache.xml.security.utils.Base64;
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -179,7 +175,7 @@ public class TrustedIdpOIDCProtocolHandler implements TrustedIdpProtocolHandler
             }
             
             try {
-                X509Certificate validatingCert = getCertificate(trustedIdp);
+                X509Certificate validatingCert = getCertificate(trustedIdp.getCertificate());
                 if (validatingCert == null) {
                     LOG.warn("No X.509 Certificate configured for signature validation");
                     return null;
@@ -238,53 +234,61 @@ public class TrustedIdpOIDCProtocolHandler implements TrustedIdpProtocolHandler
         return null;
     }
     
-    
-    private X509Certificate getCertificate(TrustedIdp trustedIdp) 
-        throws CertificateException, Base64DecodingException, IOException {
-        String certificate = trustedIdp.getCertificate();
-        if (certificate != null) {
-            boolean isCertificateLocation = !certificate.startsWith("-----BEGIN CERTIFICATE");
-            if (isCertificateLocation) {
-                InputStream is = null;
-                try {
-                    is = Merlin.loadInputStream(Thread.currentThread().getContextClassLoader(), certificate);
-                
-                    CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
-                    return (X509Certificate) certFactory.generateCertificate(is);
-                } catch (WSSecurityException ex) {
-                    LOG.error("Failed to load keystore " + certificate, ex);
-                    throw new RuntimeException("Failed to load keystore " + certificate);
-                } catch (IOException ex) {
-                    LOG.error("Failed to read keystore", ex);
-                    throw new RuntimeException("Failed to read keystore");
-                } catch (CertificateException ex) {
-                    // This is ok as it could be a WSS4J properties file
-                } finally {
-                    if (is != null) {
-                        try {
-                            is.close();
-                        } catch (IOException e) {
-                            // Do nothing
-                        }
-                    }
+    private Crypto getCrypto(String certificate) throws ProcessingException {
+        if (certificate == null) {
+            return null;
+        }
+        
+        boolean isCertificateLocation = !certificate.startsWith("-----BEGIN CERTIFICATE");
+        if (isCertificateLocation) {
+            try {
+                X509Certificate cert = CertsUtils.getX509Certificate(certificate);
+                if (cert == null) {
+                    return null;
                 }
-            } else {
-                return parseCertificate(certificate);
+                return new CertificateStore(new X509Certificate[]{cert});
+            } catch (CertificateException ex) {
+                // Maybe it's a WSS4J properties file...
+                return CertsUtils.createCrypto(certificate);
             }
         } 
         
-        return null;
+        // Here the certificate is encoded in the configuration file
+        X509Certificate cert;
+        try {
+            cert = CertsUtils.parseCertificate(certificate);
+        } catch (Exception ex) {
+            LOG.error("Failed to parse trusted certificate", ex);
+            throw new ProcessingException("Failed to parse trusted certificate");
+        }
+        return new CertificateStore(Collections.singletonList(cert).toArray(new X509Certificate[0]));
     }
     
-    private X509Certificate parseCertificate(String certificate)
-        throws CertificateException, Base64DecodingException, IOException {
+    private X509Certificate getCertificate(String certificate) 
+        throws CertificateException, WSSecurityException, ProcessingException, Base64DecodingException, IOException {
+        if (certificate == null) {
+            return null;
+        }
         
-        //before decoding we need to get rod off the prefix and suffix
-        byte [] decoded = Base64.decode(certificate.replaceAll("-----BEGIN CERTIFICATE-----", "").
-                                        replaceAll("-----END CERTIFICATE-----", ""));
-
-        try (InputStream is = new ByteArrayInputStream(decoded)) {
-            return (X509Certificate)CertificateFactory.getInstance("X.509").generateCertificate(is);
+        boolean isCertificateLocation = !certificate.startsWith("-----BEGIN CERTIFICATE");
+        if (isCertificateLocation) {
+            try {
+                return CertsUtils.getX509Certificate(certificate);
+            } catch (CertificateException ex) {
+                // Maybe it's a WSS4J properties file...
+                Crypto crypto = CertsUtils.createCrypto(certificate);
+                if (crypto != null) {
+                    return CertsUtils.getX509Certificate(crypto, null);
+                }
+            }
+        } 
+        
+        // Here the certificate is encoded in the configuration file
+        try {
+            return CertsUtils.parseCertificate(certificate);
+        } catch (Exception ex) {
+            LOG.error("Failed to parse trusted certificate", ex);
+            throw new ProcessingException("Failed to parse trusted certificate");
         }
     }
     
@@ -325,41 +329,6 @@ public class TrustedIdpOIDCProtocolHandler implements TrustedIdpProtocolHandler
         return assertion;
     }
     
-    private Crypto getCrypto(String certificate) throws ProcessingException {
-        if (certificate == null) {
-            return null;
-        }
-        
-        // First see if it's a certificate file
-        InputStream is = null;
-        try {
-            is = Merlin.loadInputStream(Thread.currentThread().getContextClassLoader(), certificate);
-        
-            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
-            X509Certificate cert = (X509Certificate) certFactory.generateCertificate(is);
-            return new CertificateStore(new X509Certificate[]{cert});
-        } catch (WSSecurityException ex) {
-            LOG.error("Failed to load keystore " + certificate, ex);
-            throw new RuntimeException("Failed to load keystore " + certificate);
-        } catch (IOException ex) {
-            LOG.error("Failed to read keystore", ex);
-            throw new RuntimeException("Failed to read keystore");
-        } catch (CertificateException ex) {
-            // This is ok as it could be a WSS4J properties file
-        } finally {
-            if (is != null) {
-                try {
-                    is.close();
-                } catch (IOException e) {
-                    // Do nothing
-                }
-            }
-        }
-        
-        // Maybe it's a WSS4J properties file...
-        return CertsUtils.createCrypto(certificate);
-    }
-
     private static class SamlCallbackHandler implements CallbackHandler {
         private ConditionsBean conditionsBean;
         private SubjectBean subjectBean;

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/f545ba0c/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpSAMLProtocolHandler.java
----------------------------------------------------------------------
diff --git a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpSAMLProtocolHandler.java b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpSAMLProtocolHandler.java
index adc85d1..f128467 100644
--- a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpSAMLProtocolHandler.java
+++ b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpSAMLProtocolHandler.java
@@ -30,8 +30,8 @@ import java.net.URLEncoder;
 import java.security.PrivateKey;
 import java.security.Signature;
 import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.util.Collections;
 import java.util.Map;
 import java.util.zip.DataFormatException;
 
@@ -67,7 +67,6 @@ import org.apache.cxf.staxutils.StaxUtils;
 import org.apache.cxf.ws.security.tokenstore.SecurityToken;
 import org.apache.wss4j.common.crypto.CertificateStore;
 import org.apache.wss4j.common.crypto.Crypto;
-import org.apache.wss4j.common.crypto.Merlin;
 import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.common.saml.OpenSAMLUtil;
 import org.apache.wss4j.common.util.DOM2Writer;
@@ -308,34 +307,29 @@ public class TrustedIdpSAMLProtocolHandler implements TrustedIdpProtocolHandler
             return null;
         }
         
-        // First see if it's a certificate file
-        InputStream is = null;
-        try {
-            is = Merlin.loadInputStream(Thread.currentThread().getContextClassLoader(), certificate);
-        
-            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
-            X509Certificate cert = (X509Certificate) certFactory.generateCertificate(is);
-            return new CertificateStore(new X509Certificate[]{cert});
-        } catch (WSSecurityException ex) {
-            LOG.error("Failed to load keystore " + certificate, ex);
-            throw new RuntimeException("Failed to load keystore " + certificate);
-        } catch (IOException ex) {
-            LOG.error("Failed to read keystore", ex);
-            throw new RuntimeException("Failed to read keystore");
-        } catch (CertificateException ex) {
-            // This is ok as it could be a WSS4J properties file
-        } finally {
-            if (is != null) {
-                try {
-                    is.close();
-                } catch (IOException e) {
-                    // Do nothing
+        boolean isCertificateLocation = !certificate.startsWith("-----BEGIN CERTIFICATE");
+        if (isCertificateLocation) {
+            try {
+                X509Certificate cert = CertsUtils.getX509Certificate(certificate);
+                if (cert == null) {
+                    return null;
                 }
+                return new CertificateStore(new X509Certificate[]{cert});
+            } catch (CertificateException ex) {
+                // Maybe it's a WSS4J properties file...
+                return CertsUtils.createCrypto(certificate);
             }
-        }
+        } 
         
-        // Maybe it's a WSS4J properties file...
-        return CertsUtils.createCrypto(certificate);
+        // Here the certificate is encoded in the configuration file
+        X509Certificate cert;
+        try {
+            cert = CertsUtils.parseCertificate(certificate);
+        } catch (Exception ex) {
+            LOG.error("Failed to parse trusted certificate", ex);
+            throw new ProcessingException("Failed to parse trusted certificate");
+        }
+        return new CertificateStore(Collections.singletonList(cert).toArray(new X509Certificate[0]));
     }
     
     private org.opensaml.saml.saml2.core.Response readSAMLResponse(String samlResponse, TrustedIdp trustedIdp) {

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/f545ba0c/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpWSFedProtocolHandler.java
----------------------------------------------------------------------
diff --git a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpWSFedProtocolHandler.java b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpWSFedProtocolHandler.java
index 4ac9605..946ab61 100644
--- a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpWSFedProtocolHandler.java
+++ b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpWSFedProtocolHandler.java
@@ -19,15 +19,10 @@
 
 package org.apache.cxf.fediz.service.idp.protocols;
 
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLEncoder;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.Collections;
 
@@ -51,15 +46,14 @@ import org.apache.cxf.fediz.core.processor.FederationProcessorImpl;
 import org.apache.cxf.fediz.core.processor.FedizProcessor;
 import org.apache.cxf.fediz.core.processor.FedizRequest;
 import org.apache.cxf.fediz.core.processor.FedizResponse;
+import org.apache.cxf.fediz.core.util.CertsUtils;
 import org.apache.cxf.fediz.service.idp.domain.Idp;
 import org.apache.cxf.fediz.service.idp.domain.TrustedIdp;
 import org.apache.cxf.fediz.service.idp.spi.TrustedIdpProtocolHandler;
 import org.apache.cxf.fediz.service.idp.util.WebUtils;
 import org.apache.cxf.ws.security.tokenstore.SecurityToken;
 import org.apache.wss4j.common.crypto.CertificateStore;
-import org.apache.xml.security.exceptions.Base64DecodingException;
 import org.apache.xml.security.stax.impl.util.IDGenerator;
-import org.apache.xml.security.utils.Base64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -222,7 +216,7 @@ public class TrustedIdpWSFedProtocolHandler implements TrustedIdpProtocolHandler
             
             X509Certificate cert;
             try {
-                cert = parseCertificate(trustedIdpConfig.getCertificate());
+                cert = CertsUtils.parseCertificate(trustedIdpConfig.getCertificate());
             } catch (Exception ex) {
                 LOG.error("Failed to parse trusted certificate", ex);
                 throw new ProcessingException("Failed to parse trusted certificate");
@@ -237,17 +231,4 @@ public class TrustedIdpWSFedProtocolHandler implements TrustedIdpProtocolHandler
         return fedContext;
     }
     
-    private X509Certificate parseCertificate(String certificate)
-        throws CertificateException, Base64DecodingException, IOException {
-        
-        //before decoding we need to get rod off the prefix and suffix
-        byte [] decoded = Base64.decode(certificate.replaceAll("-----BEGIN CERTIFICATE-----", "").
-                                        replaceAll("-----END CERTIFICATE-----", ""));
-
-        try (InputStream is = new ByteArrayInputStream(decoded)) {
-            return (X509Certificate)CertificateFactory.getInstance("X.509").generateCertificate(is);
-        }
-    }
-    
-
 }