Package org.teiid.net.socket

Source Code of org.teiid.net.socket.SocketUtil$SSLSocketFactory

/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.  Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/

package org.teiid.net.socket;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.Properties;
import java.util.logging.Logger;

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

import org.teiid.core.util.PropertiesUtils;
import org.teiid.jdbc.JDBCPlugin;



/**
* This class provides some utility methods to create ssl sockets using the
* keystores and trust stores. these are the properties required for the making the
* ssl connection
*/
public class SocketUtil {
  private static Logger logger = Logger.getLogger(SocketUtil.class.getName());
   
    static final String TRUSTSTORE_PASSWORD = "org.teiid.ssl.trustStorePassword"; //$NON-NLS-1$
    public static final String TRUSTSTORE_FILENAME = "org.teiid.ssl.trustStore"; //$NON-NLS-1$
    static final String KEYSTORE_ALGORITHM = "org.teiid.ssl.algorithm"; //$NON-NLS-1$
    static final String PROTOCOL = "org.teiid.ssl.protocol"; //$NON-NLS-1$
    static final String KEYSTORE_TYPE = "org.teiid.ssl.keyStoreType"; //$NON-NLS-1$
    static final String KEYSTORE_PASSWORD = "org.teiid.ssl.keyStorePassword"; //$NON-NLS-1$
    static final String KEYSTORE_FILENAME = "org.teiid.ssl.keyStore"; //$NON-NLS-1$
    public static final String ALLOW_ANON = "org.teiid.ssl.allowAnon"; //$NON-NLS-1$
   
    static final String DEFAULT_KEYSTORE_TYPE = "JKS"; //$NON-NLS-1$
   
    public static final String ANON_CIPHER_SUITE = "TLS_DH_anon_WITH_AES_128_CBC_SHA"; //$NON-NLS-1$
    public static final String DEFAULT_PROTOCOL = "TLSv1"; //$NON-NLS-1$
   
    public static class SSLSocketFactory {
      private boolean isAnon;
      private boolean warned;
      private javax.net.ssl.SSLSocketFactory factory;
     
      public SSLSocketFactory(SSLContext context, boolean isAnon) {
      this.factory = context.getSocketFactory();
      this.isAnon = isAnon;
    }

    public synchronized Socket getSocket() throws IOException {
        SSLSocket result = (SSLSocket)factory.createSocket();
        result.setUseClientMode(true);
        if (isAnon && !addCipherSuite(result, ANON_CIPHER_SUITE) && !warned) {
          warned = true;
          logger.warning(JDBCPlugin.Util.getString("SocketUtil.anon_not_available")); //$NON-NLS-1$
        }
        return result;
      }
    }
   
    public static SSLSocketFactory getSSLSocketFactory(Properties props) throws IOException, GeneralSecurityException{
        String keystore = props.getProperty(KEYSTORE_FILENAME);
        String keystorePassword = props.getProperty(KEYSTORE_PASSWORD);
        String keystoreType = props.getProperty(KEYSTORE_TYPE, DEFAULT_KEYSTORE_TYPE);
        String keystoreProtocol = props.getProperty(PROTOCOL, DEFAULT_PROTOCOL);
        String keystoreAlgorithm = props.getProperty(KEYSTORE_ALGORITHM);
        String truststore = props.getProperty(TRUSTSTORE_FILENAME, keystore);
        String truststorePassword = props.getProperty(TRUSTSTORE_PASSWORD, keystorePassword);
       
        boolean anon = PropertiesUtils.getBooleanProperty(props, ALLOW_ANON, true);
       
        SSLContext result = null;
        // 1) keystore != null = 2 way SSL (can define a separate truststore too)
        // 2) truststore != null = 1 way SSL (here we can define custom properties for truststore; useful when
        //    client like a appserver have to define multiple certs without importing
        //    all the certificates into one single certificate
        // 3) else = javax properties; this is default way to define the SSL anywhere.
        if (keystore != null) {
            // 2 way SSL
            result = getClientSSLContext(keystore, keystorePassword, truststore, truststorePassword, keystoreAlgorithm, keystoreType, keystoreProtocol);
        } else  if(truststore != null) {
            // One way SSL with custom properties defined
            result = getClientSSLContext(null, null, truststore, truststorePassword, keystoreAlgorithm, keystoreType, keystoreProtocol);
        } else {
          result = SSLContext.getDefault();
        }
        return new SSLSocketFactory(result, anon);
    }
   
    /**
     * create socket factory for the client socket. 
     * @throws GeneralSecurityException
     */
    static SSLContext getClientSSLContext(String keystore,
                                            String password,
                                            String truststore,
                                            String truststorePassword,
                                            String algorithm,
                                            String keystoreType,
                                            String protocol) throws IOException, GeneralSecurityException {
        return getSSLContext(keystore, password, truststore, truststorePassword, algorithm, keystoreType, protocol);
    }
   
    public static boolean addCipherSuite(SSLSocket engine, String cipherSuite) {
        if (!Arrays.asList(engine.getSupportedCipherSuites()).contains(cipherSuite)) {
          return false;
        }

        String[] suites = engine.getEnabledCipherSuites();

        String[] newSuites = new String[suites.length + 1];
        System.arraycopy(suites, 0, newSuites, 0, suites.length);
       
        newSuites[suites.length] = cipherSuite;
       
        engine.setEnabledCipherSuites(newSuites);
        return true;
    }

    public static SSLContext getAnonSSLContext() throws IOException, GeneralSecurityException {
        return getSSLContext(null, null, null, null, null, null, DEFAULT_PROTOCOL);
    }
   
    public static SSLContext getSSLContext(String keystore,
                                            String password,
                                            String truststore,
                                            String truststorePassword,
                                            String algorithm,
                                            String keystoreType,
                                            String protocol) throws IOException, GeneralSecurityException {
       
      if (algorithm == null) {
        algorithm = KeyManagerFactory.getDefaultAlgorithm();
      }
        // Configure the Keystore Manager
        KeyManager[] keyManagers = null;
        if (keystore != null) {
            KeyStore ks = loadKeyStore(keystore, password, keystoreType);
            if (ks != null) {
                KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
                kmf.init(ks, password.toCharArray());
                keyManagers = kmf.getKeyManagers();
            }
        }
       
        // Configure the Trust Store Manager
        TrustManager[] trustManagers = null;
        if (truststore != null) {
            KeyStore ks = loadKeyStore(truststore, truststorePassword, keystoreType);
            if (ks != null) {
                TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
                tmf.init(ks);
                trustManagers = tmf.getTrustManagers();
            }
        }

        // Configure the SSL
        SSLContext sslc = SSLContext.getInstance(protocol);
        sslc.init(keyManagers, trustManagers, null);
        return sslc;
    }
   
    /**
     * Load any defined keystore file, by first looking in the classpath
     * then looking in the file system path.
     *  
     * @param name - name of the keystore
     * @param password - password to load the keystore
     * @param type - type of the keystore
     * @return loaded keystore
     */
    public static KeyStore loadKeyStore(String name, String password, String type) throws IOException, NoSuchAlgorithmException, CertificateException, KeyStoreException {
       
        // Check in the classpath
        InputStream stream = SocketUtil.class.getClassLoader().getResourceAsStream(name);
        if (stream == null) {
            try {
                stream = new FileInputStream(name);
            } catch (FileNotFoundException e) {
                IOException exception = new IOException(JDBCPlugin.Util.getString("SocketHelper.keystore_not_found", name)); //$NON-NLS-1$
                exception.initCause(e);
                throw exception;
            }
        }
               
        KeyStore ks = KeyStore.getInstance(type);       
        try {
          ks.load(stream, password != null ? password.toCharArray() : null);
        } finally {
        stream.close();
        }
        return ks;
    }

}
TOP

Related Classes of org.teiid.net.socket.SocketUtil$SSLSocketFactory

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.