Package org.objectweb.celtix.bus.transports.https

Source Code of org.objectweb.celtix.bus.transports.https.JettySslClientConfigurer

package org.objectweb.celtix.bus.transports.https;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URLConnection;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

import org.objectweb.celtix.bus.configuration.security.SSLClientPolicy;
import org.objectweb.celtix.common.logging.LogUtils;
import org.objectweb.celtix.configuration.Configuration;



public final class JettySslClientConfigurer {
    private static final long serialVersionUID = 1L;
    private static final Logger LOG = LogUtils.getL7dLogger(JettySslClientConfigurer.class);
    private static final String DEFAUL_KEYSTORE_TYPE = "PKCS12";
    private static final String DEFAUL_TRUST_STORE_TYPE = "JKS";
    private static final String DEFAULT_SECURE_SOCKET_PROTOCOL = "TLSv1";
    private static final String CERTIFICATE_FACTORY_TYPE    = "X.509";
    private static final String PKCS12_TYPE = "PKCS12";
   
    SSLClientPolicy sslPolicy;
   
    private String keyStoreLocation;
    private String keyStorePassword;
    private String keyPassword;
    private String keyStoreType = DEFAUL_KEYSTORE_TYPE;
    private String[] cipherSuites;
    private String trustStoreLocation;
    private String trustStoreType = DEFAUL_TRUST_STORE_TYPE;
    private String keystoreKeyManagerFactoryAlgorithm;
    private String trustStoreKeyManagerFactoryAlgorithm;
    private HttpsURLConnection httpsConnection;
    private String secureSocketProtocol;
    private Configuration config;
   
    public JettySslClientConfigurer(SSLClientPolicy sslPolicyParam,
                                       URLConnection connection,
                                       Configuration configurationParam) {
       
        this.sslPolicy = sslPolicyParam;
        this.httpsConnection = (HttpsURLConnection)connection;
       
        config = configurationParam;
       
    }
   
    public void configure() {
        setupSecurityConfigurer();
        setupKeystore();
        setupKeystoreType();
        setupKeystorePassword();
        setupKeyPassword();
        setupKeystoreAlgorithm();
        setupTrustStoreAlgorithm();
        setupCiphersuites();
        setupTrustStore();
        setupTrustStoreType();
        setupSecureSocketProtocol();
        setupSessionCaching();
        setupSessionCacheKey();
        setupMaxChainLength();
        setupCertValidator();
        setupProxyHost();
        setupProxyPort();
       
        if (keyStoreType.equalsIgnoreCase(PKCS12_TYPE)) {
            setupSSLContextPKCS12();
        } else {
            setupSSLContext();
        }

    }
   
    private boolean setupSSLContext() {
       
        //TODO for performance reasons we should cache the KeymanagerFactory and TrustManagerFactory
        if ((keyStorePassword != null) && (keyPassword != null) && (!keyStorePassword.equals(keyPassword))) {
            LogUtils.log(LOG, Level.WARNING, "KEY_PASSWORD_NOT_SAME_KEYSTORE_PASSWORD");
        }
        try {
            SSLContext sslctx = SSLContext.getInstance(secureSocketProtocol);

            KeyManagerFactory kmf =
                KeyManagerFactory.getInstance(keystoreKeyManagerFactoryAlgorithm)
            KeyStore ks = KeyStore.getInstance(keyStoreType);
            FileInputStream fis = new FileInputStream(keyStoreLocation);
            DataInputStream dis = new DataInputStream(fis);
            byte[] bytes = new byte[dis.available()];
            dis.readFully(bytes);
            ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
           
            KeyManager[] keystoreManagers = null;
            if (keyStorePassword != null) {
                try {
                    ks.load(bin, keyStorePassword.toCharArray());
                    kmf.init(ks, keyStorePassword.toCharArray());
                    keystoreManagers = kmf.getKeyManagers();
                    LogUtils.log(LOG, Level.INFO, "LOADED_KEYSTORE", new Object[]{keyStoreLocation});
                } catch (Exception e) {
                    LogUtils.log(LOG, Level.WARNING, "FAILED_TO_LOAD_KEYSTORE",
                                 new Object[]{keyStoreLocation, e.getMessage()});
               
            }
            if ((keyStorePassword == null) && (keyStoreLocation != null)) {
                LogUtils.log(LOG, Level.WARNING, "FAILED_TO_LOAD_KEYSTORE_NULL_PASSWORD",
                             new Object[]{keyStoreLocation});
            }
           
            // ************************* Load Trusted CA file *************************
           
            TrustManager[] trustStoreManagers = null;
            KeyStore trustedCertStore = KeyStore.getInstance(trustStoreType);
           
            trustedCertStore.load(new FileInputStream(trustStoreLocation), null);
            TrustManagerFactory tmf  =
                TrustManagerFactory.getInstance(trustStoreKeyManagerFactoryAlgorithm);
            try {
                tmf.init(trustedCertStore);
                trustStoreManagers = tmf.getTrustManagers();
                LogUtils.log(LOG, Level.INFO, "LOADED_TRUST_STORE", new Object[]{trustStoreLocation});
            } catch (Exception e) {
                LogUtils.log(LOG, Level.WARNING, "FAILED_TO_LOAD_TRUST_STORE",
                             new Object[]{trustStoreLocation, e.getMessage()});
            }
            sslctx.init(keystoreManagers, trustStoreManagers, null);
           
            httpsConnection.setSSLSocketFactory(new SSLSocketFactoryWrapper(sslctx.getSocketFactory(),
                                                                            cipherSuites));
           
           
           
        } catch (Exception e) {
            LogUtils.log(LOG, Level.SEVERE, "SSL_CONTEXT_INIT_FAILURE", new Object[]{e.getMessage()});
            return false;
        }  
        return true;
    }
   
   
    private boolean setupSSLContextPKCS12() {
       
        //TODO for performance reasons we should cache the KeymanagerFactory and TrustManagerFactory
        if ((keyStorePassword != null) && (keyPassword != null) && (!keyStorePassword.equals(keyPassword))) {
            LogUtils.log(LOG, Level.WARNING, "KEY_PASSWORD_NOT_SAME_KEYSTORE_PASSWORD");
        }
        try {
            SSLContext sslctx = SSLContext.getInstance(secureSocketProtocol);
            KeyManagerFactory kmf =
                KeyManagerFactory.getInstance(keystoreKeyManagerFactoryAlgorithm)
            KeyStore ks = KeyStore.getInstance(keyStoreType);
            KeyManager[] keystoreManagers = null;
           
           
            byte[] sslCert = loadClientCredential(keyStoreLocation);
           
            if (sslCert != null && sslCert.length > 0 && keyStorePassword != null) {
                ByteArrayInputStream bin = new ByteArrayInputStream(sslCert);
                try {
                    ks.load(bin, keyStorePassword.toCharArray());
                    kmf.init(ks, keyStorePassword.toCharArray());
                    keystoreManagers = kmf.getKeyManagers();
                    LogUtils.log(LOG, Level.INFO, "LOADED_KEYSTORE", new Object[]{keyStoreLocation});
                } catch (Exception e) {
                    LogUtils.log(LOG, Level.WARNING, "FAILED_TO_LOAD_KEYSTORE",
                                                     new Object[]{keyStoreLocation, e.getMessage()});
                }
            } 
            if ((keyStorePassword == null) && (keyStoreLocation != null)) {
                LogUtils.log(LOG, Level.WARNING, "FAILED_TO_LOAD_KEYSTORE_NULL_PASSWORD",
                             new Object[]{keyStoreLocation});
            }
           
            // ************************* Load Trusted CA file *************************
            //TODO could support multiple trust cas
            TrustManager[] trustStoreManagers = new TrustManager[1];
            
            KeyStore trustedCertStore = KeyStore.getInstance(trustStoreType);
            trustedCertStore.load(null, "".toCharArray());
            CertificateFactory cf = CertificateFactory.getInstance(CERTIFICATE_FACTORY_TYPE);
            byte[] caCert = loadCACert(trustStoreLocation);
            try {
                if (caCert != null) {
                    ByteArrayInputStream cabin = new ByteArrayInputStream(caCert);
                    X509Certificate cert = (X509Certificate)cf.generateCertificate(cabin);
                    trustedCertStore.setCertificateEntry(cert.getIssuerDN().toString(), cert);
                    cabin.close();
                }
            } catch (Exception e) {
                LogUtils.log(LOG, Level.WARNING, "FAILED_TO_LOAD_TRUST_STORE",
                             new Object[]{trustStoreLocation, e.getMessage()});
            }
            TrustManagerFactory tmf  =
                TrustManagerFactory.getInstance(trustStoreKeyManagerFactoryAlgorithm);

            tmf.init(trustedCertStore);
            LogUtils.log(LOG, Level.INFO, "LOADED_TRUST_STORE", new Object[]{trustStoreLocation});
           
            trustStoreManagers = tmf.getTrustManagers();

            sslctx.init(keystoreManagers, trustStoreManagers, null)
            httpsConnection.setSSLSocketFactory(new SSLSocketFactoryWrapper(sslctx.getSocketFactory(),
                                                                            cipherSuites));
           
        } catch (Exception e) {
            LogUtils.log(LOG, Level.SEVERE, "SSL_CONTEXT_INIT_FAILURE", new Object[]{e.getMessage()});
            return false;
        }  
        return true;
    }
   

   
    private static byte[] loadClientCredential(String fileName) throws IOException {
        if (fileName == null) {
            return null;
        }
        FileInputStream in = new FileInputStream(fileName);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buf = new byte[512];
        int i = in.read(buf);
        while (i  > 0) {
            out.write(buf, 0, i);
            i = in.read(buf);
        }
        in.close();
        return out.toByteArray();
    }
   


    private static byte[] loadCACert(String fileName) throws IOException {
        if (fileName == null) {
            return null;
        }
        FileInputStream in = new FileInputStream(fileName);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buf = new byte[512];
        int i = in.read(buf);
       
        while (i > 0) {
            out.write(buf, 0, i);
            i = in.read(buf);
        }
        in.close();
        return out.toByteArray();
    }

   
    public void setupKeystore() {
        if (sslPolicy.isSetKeystore()) {
            keyStoreLocation = sslPolicy.getKeystore();
            LogUtils.log(LOG, Level.INFO, "KEY_STORE_SET", new Object[]{keyStoreLocation});
            return;
        }
        keyStoreLocation = System.getProperty("javax.net.ssl.keyStore");
        if (keyStoreLocation != null) {
            LogUtils.log(LOG, Level.INFO, "KEY_STORE_SYSTEM_PROPERTY_SET", new Object[]{keyStoreLocation});
            return;
        }

        keyStoreLocation = System.getProperty("user.home") + "/.keystore";
        LogUtils.log(LOG, Level.INFO, "KEY_STORE_NOT_SET", new Object[]{keyStoreLocation});

    }
   
    public void setupKeystoreType() {
        if (!sslPolicy.isSetKeystoreType()) {
            LogUtils.log(LOG, Level.INFO, "KEY_STORE_TYPE_NOT_SET", new Object[]{DEFAUL_KEYSTORE_TYPE});
            return;
        }
        keyStoreType = sslPolicy.getKeystoreType();
        LogUtils.log(LOG, Level.INFO, "KEY_STORE_TYPE_SET", new Object[]{keyStoreType});
   
   
    public void setupKeystorePassword() {
        if (sslPolicy.isSetKeystorePassword()) {
            LogUtils.log(LOG, Level.INFO, "KEY_STORE_PASSWORD_SET");
            keyStorePassword = sslPolicy.getKeystorePassword();
            return;
        }
        keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword");
        if (keyStorePassword != null) {
            LogUtils.log(LOG, Level.INFO, "KEY_STORE_PASSWORD_SYSTEM_PROPERTY_SET");
            return;
        }
        LogUtils.log(LOG, Level.INFO, "KEY_STORE_PASSWORD_NOT_SET");

    }
   
    public void setupKeyPassword() {
        if (sslPolicy.isSetKeyPassword()) {
            LogUtils.log(LOG, Level.INFO, "KEY_PASSWORD_SET");
            keyPassword = sslPolicy.getKeyPassword();
            return;
        }
        keyPassword = System.getProperty("javax.net.ssl.keyStorePassword");
        if (keyPassword != null) {
            LogUtils.log(LOG, Level.INFO, "KEY_PASSWORD_SYSTEM_PROPERTY_SET");
            return;
        }

        LogUtils.log(LOG, Level.INFO, "KEY_PASSWORD_NOT_SET");
    }
  
   
   
    public void setupKeystoreAlgorithm() {
        if (sslPolicy.isSetKeystoreAlgorithm()) {
            keystoreKeyManagerFactoryAlgorithm = sslPolicy.getKeystoreAlgorithm();
            LogUtils.log(LOG, Level.INFO,
                         "KEY_STORE_ALGORITHM_SET",
                         new Object[] {keystoreKeyManagerFactoryAlgorithm});
            return;
        }
        keystoreKeyManagerFactoryAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
        LogUtils.log(LOG, Level.INFO,
                     "KEY_STORE_ALGORITHM_NOT_SET",
                     new Object[] {keystoreKeyManagerFactoryAlgorithm});
    }
   
    public void setupTrustStoreAlgorithm() {
        if (sslPolicy.isSetKeystoreAlgorithm()) {
            trustStoreKeyManagerFactoryAlgorithm = sslPolicy.getTrustStoreAlgorithm();
            LogUtils.log(LOG, Level.INFO,
                         "TRUST_STORE_ALGORITHM_SET",
                         new Object[] {trustStoreKeyManagerFactoryAlgorithm});
            return;
        }
        trustStoreKeyManagerFactoryAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        LogUtils.log(LOG, Level.INFO,
                     "TRUST_STORE_ALGORITHM_NOT_SET",
                     new Object[] {trustStoreKeyManagerFactoryAlgorithm});
    }   
   
    public void setupCiphersuites() {
        if (sslPolicy.isSetCiphersuites()) {
           
            List<String> cipherSuitesList = sslPolicy.getCiphersuites();
            int numCipherSuites = cipherSuitesList.size();
            cipherSuites = new String[numCipherSuites];
            String ciphsStr = null;
            for (int i = 0; i < numCipherSuites; i++) {
                cipherSuites[i] = cipherSuitesList.get(i);
                if (ciphsStr == null) {
                    ciphsStr = cipherSuites[i];
                } else {
                    ciphsStr += ", " + cipherSuites[i];
                }
            }
            LogUtils.log(LOG, Level.INFO, "CIPHERSUITE_SET", new Object[]{ciphsStr});
            return;
        }
        LogUtils.log(LOG, Level.INFO, "CIPHERSUITE_NOT_SET");
    }        
   
    public void setupTrustStore() {
        if (sslPolicy.isSetTrustStore()) {
            trustStoreLocation = sslPolicy.getTrustStore();
            LogUtils.log(LOG, Level.INFO, "TRUST_STORE_SET", new Object[]{trustStoreLocation});
            return;
        }
       
        trustStoreLocation = System.getProperty("javax.net.ssl.trustStore");
        if (trustStoreLocation != null) {
            LogUtils.log(LOG, Level.INFO, "TRUST_STORE_SYSTEM_PROPERTY_SET",
                         new Object[]{trustStoreLocation});
            return;
        }

        trustStoreLocation = System.getProperty("java.home") + "/lib/security/cacerts";
        LogUtils.log(LOG, Level.INFO, "TRUST_STORE_NOT_SET", new Object[]{trustStoreLocation});
       
    }
   
    public void setupTrustStoreType() {
        if (!sslPolicy.isSetTrustStoreType()) {
            LogUtils.log(LOG, Level.INFO, "TRUST_STORE_TYPE_NOT_SET", new Object[]{DEFAUL_TRUST_STORE_TYPE});
            //Can default to JKS so return
            return;
        }
        trustStoreType = sslPolicy.getTrustStoreType();
        LogUtils.log(LOG, Level.INFO, "TRUST_STORE_TYPE_SET", new Object[]{trustStoreType});
    }

   
    public void setupSecureSocketProtocol() {
        if (!sslPolicy.isSetSecureSocketProtocol()) {
            LogUtils.log(LOG, Level.INFO, "SECURE_SOCKET_PROTOCOL_NOT_SET");
            secureSocketProtocol = DEFAULT_SECURE_SOCKET_PROTOCOL;
            return;
        }
        secureSocketProtocol = sslPolicy.getSecureSocketProtocol();
        LogUtils.log(LOG, Level.INFO, "SECURE_SOCKET_PROTOCOL_SET", new Object[] {secureSocketProtocol});
    }
   
    public boolean setupSessionCaching() {
        if (sslPolicy.isSetSessionCaching()) {
            LogUtils.log(LOG, Level.WARNING, "UNSUPPORTED_SSL_CLIENT_POLICY_DATA",
                         new Object[]{"SessionCaching"});
        }
        return true;
   
   
    public boolean setupSessionCacheKey() {
        if (sslPolicy.isSetSessionCacheKey()) {
            LogUtils.log(LOG, Level.WARNING, "UNSUPPORTED_SSL_CLIENT_POLICY_DATA",
                         new Object[]{"SessionCacheKey"});
        }
        return true;
   
   
    public boolean setupMaxChainLength() {
        if (sslPolicy.isSetMaxChainLength()) {
            LogUtils.log(LOG, Level.WARNING, "UNSUPPORTED_SSL_CLIENT_POLICY_DATA",
                         new Object[]{"MaxChainLength"});
        }
        return true;
   
   
    public boolean setupCertValidator() {
        if (sslPolicy.isSetCertValidator()) {
            LogUtils.log(LOG, Level.WARNING, "UNSUPPORTED_SSL_CLIENT_POLICY_DATA",
                         new Object[]{"CertValidator"});
        }
        return true;
    }     
   
    public boolean setupProxyHost() {
        if (sslPolicy.isSetProxyHost()) {
            LogUtils.log(LOG, Level.WARNING, "UNSUPPORTED_SSL_CLIENT_POLICY_DATA",
                         new Object[]{"ProxyHost"});
        }
        return true;
    }

    public boolean setupProxyPort() {
        if (sslPolicy.isSetProxyPort()) {
            LogUtils.log(LOG, Level.WARNING, "UNSUPPORTED_SSL_CLIENT_POLICY_DATA",
                         new Object[]{"ProxyPort"});
        }
        return true;
    }
   
   
    public void setupSecurityConfigurer() {
        String systemProperty = "celtix.security.configurer.celtix."
            + config.getId() + ".http-client";
        String securityConfigurerName =
            System.getProperty(systemProperty);
      
        if ((securityConfigurerName == null)
            || (securityConfigurerName.equals(""))) {
            return;
        }
        LogUtils.log(LOG, Level.WARNING, "UNOFFICIAL_SECURITY_CONFIGURER");
       
        try {
            Class clazz = Class.forName(securityConfigurerName);
            Method configure = clazz.getDeclaredMethod("configure", SSLClientPolicy.class);
            Object[] params = new Object[]{sslPolicy};
            Object configurer = clazz.newInstance();
            configure.invoke(configurer, params);
            LogUtils.log(LOG, Level.INFO, "SUCCESS_INVOKING_SECURITY_CONFIGURER",
                         new Object[]{securityConfigurerName});
        } catch (Exception e) {
            LogUtils.log(LOG, Level.SEVERE, "ERROR_INVOKING_SECURITY_CONFIGURER",
                         new Object[]{securityConfigurerName, e.getMessage()});
        }
    }
   
    protected HttpsURLConnection getHttpsConnection() {
        return httpsConnection;
    }
   
   
    /*
     *  For development and testing only
     */
   
   
    protected boolean testAllDataHasSetupMethod() {
        Method[] sslPolicyMethods = sslPolicy.getClass().getDeclaredMethods();
        Class[] classArgs = null;

        for (int i = 0; i < sslPolicyMethods.length; i++) {
            String sslPolicyMethodName = sslPolicyMethods[i].getName();
            if (sslPolicyMethodName.startsWith("isSet")) {
                String dataName =
                    sslPolicyMethodName.substring("isSet".length(), sslPolicyMethodName.length());
                String thisMethodName = "setup" + dataName;
                try {
                    this.getClass().getMethod(thisMethodName, classArgs);
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
               
            }
        }
        return true;
    }
   
    protected void addLogHandler(Handler handler) {
        LOG.addHandler(handler);
    }
   
}
TOP

Related Classes of org.objectweb.celtix.bus.transports.https.JettySslClientConfigurer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.