package org.jacorb.security.ssl.sun_jsse; /* * JacORB - a free Java ORB * * Copyright (C) 2000-2014 Gerald Brose / The JacORB Team. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; import java.security.KeyStore; import java.security.cert.CertStore; import java.security.cert.CertStoreParameters; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.PKIXBuilderParameters; import java.security.cert.X509CRL; import java.security.cert.X509CertSelector; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.net.SocketFactory; import javax.net.ssl.CertPathTrustManagerParameters; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.ManagerFactoryParameters; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import org.jacorb.config.Configuration; import org.jacorb.config.ConfigurationException; import org.jacorb.orb.ORB; import org.jacorb.orb.factory.AbstractSocketFactory; import org.jacorb.orb.listener.SSLHandshakeListener; import org.jacorb.orb.listener.SSLSessionListener; /** * a SocketFactory implementation that allows * to create sockets that support SSL. * * @author Nicolas Noffke */ public class SSLSocketFactory extends AbstractSocketFactory { private SocketFactory factory = null; private String[] cipher_suites = null; private String[] enabledProtocols = null; private TrustManager trustManager = null; private boolean trusteesFromKS = false; private int clientSupportedOptions = 0; private String keystore_location = null; private String keystore_passphrase = null; private final SSLSessionListener sslListener; private SSLRandom sslRandom; private String keystore_type = null; private String keyManagerAlgorithm = null; private String trustManagerAlgorithm = null; // Bugzilla#883: added the PKCS11 and CRL support private String keystore_provider = null; // e.g.: SunPKCS11-NSS private String truststore_type = null; private String truststore_location = null; private String truststore_passphrase = null; private String truststore_provider = null; private boolean support_crl = false; // CRL support on/off private String crl_file = null; // absolute path to the CRL file public SSLSocketFactory(ORB orb) { sslListener = orb.getTransportManager().getSocketFactoryManager().getSSLListener(); } public void configure(Configuration configuration) throws ConfigurationException { super.configure(configuration); sslRandom = new SSLRandom(); sslRandom.configure(configuration); trusteesFromKS = configuration.getAttributeAsBoolean("jacorb.security.jsse.trustees_from_ks", false); keystore_location = configuration.getAttribute("jacorb.security.keystore"); keystore_passphrase = configuration.getAttribute("jacorb.security.keystore_password"); keystore_type= configuration.getAttribute("jacorb.security.keystore_type", "JKS"); keystore_provider = configuration.getAttribute("jacorb.security.keystore_provider", null); truststore_type = configuration.getAttribute("jacorb.security.truststore_type", null); truststore_location = configuration.getAttribute("jacorb.security.truststore", null); truststore_passphrase = configuration.getAttribute("jacorb.security.truststore_password", null); truststore_provider = configuration.getAttribute("jacorb.security.truststore_provider", null); crl_file = configuration.getAttribute("jacorb.security.crl_file", null); support_crl = configuration.getAttributeAsBoolean("jacorb.security.support_crl", false); keyManagerAlgorithm = configuration.getAttribute("jacorb.security.jsse.client.key_manager_algorithm","SunX509"); trustManagerAlgorithm = configuration.getAttribute("jacorb.security.jsse.client.trust_manager_algorithm","SunX509"); clientSupportedOptions = configuration.getAttributeAsInteger("jacorb.security.ssl.client.supported_options", 0, 16); try { trustManager = (TrustManager) ((org.jacorb.config.Configuration)configuration).getAttributeAsObject ("jacorb.security.ssl.client.trust_manager"); } catch (ConfigurationException e) { if (logger.isErrorEnabled()) { logger.error("TrustManager object creation failed. Please check value of property " + "'jacorb.security.ssl.client.trust_manager'. Current value: " + configuration.getAttribute("jacorb.security.ssl.client.trust_manager", ""), e); } } if (configuration.getAttribute("jacorb.security.ssl.client.protocols", null) != null) { enabledProtocols = configuration.getAttributeAsStringsArray ("jacorb.security.ssl.server.protocols"); if (logger.isDebugEnabled()) { logger.debug("Setting user specified client enabled protocols : " + configuration.getAttribute("jacorb.security.ssl.client.protocols", "")); } } try { factory = createSocketFactory(); } catch( Exception e ) { logger.error("Unable to create SSLSocketFactory!", e); throw new ConfigurationException("Unable to create SSLSocketFactory!", e); } // Andrew T. Finnell / Change made for e-Security Inc. 2002 // We need to obtain all the cipher suites to use from the // properties file. cipher_suites = configuration.getAttributeAsStringsArray ("jacorb.security.ssl.client.cipher_suites"); } public Socket createSocket( String host, int port ) throws IOException, UnknownHostException { SSLSocket socket = (SSLSocket)factory.createSocket( host, port ); initSSLSocket(socket); return socket; } protected Socket doCreateSocket(String host, int port, int timeout) throws IOException { SSLSocket socket = (SSLSocket)factory.createSocket(); socket.connect(new InetSocketAddress(host, port), timeout); initSSLSocket(socket); return socket; } /** * common ssl socket initialization * @param socket */ private void initSSLSocket(SSLSocket socket) { // Andrew T. Finnell // We need a way to enable the cipher suites that we would like to use // We should obtain these from the properties file if ( cipher_suites != null ) { socket.setEnabledCipherSuites( cipher_suites ); } if (enabledProtocols != null) { socket.setEnabledProtocols (enabledProtocols); } socket.addHandshakeCompletedListener(new SSLHandshakeListener(logger, sslListener)); } public boolean isSSL( java.net.Socket socket ) { return (socket instanceof SSLSocket); } private SocketFactory createSocketFactory() throws IOException, java.security.GeneralSecurityException { KeyManagerFactory kmf = null; KeyStore key_store = null; if( trusteesFromKS || ( clientSupportedOptions & 0x40) != 0 ) { key_store = KeyStoreUtil.getKeyStore( keystore_location, keystore_passphrase.toCharArray(), keystore_type, keystore_provider ); //only add own credentials, if establish trust in //client is supported if( ( clientSupportedOptions & 0x40) != 0 ) { kmf = KeyManagerFactory.getInstance( keyManagerAlgorithm ); // Bugzilla #883: PKCS 11 and CRL support for SSL // Password for "WINDOWS-MY" store type doesn't need to be set if ( "WINDOWS-MY".equalsIgnoreCase( keystore_type ) ) { kmf.init( key_store, null ); } else { kmf.init( key_store, keystore_passphrase.toCharArray() ); } } } TrustManagerFactory tmf = TrustManagerFactory.getInstance( trustManagerAlgorithm ); KeyStore trust_store = null; if ( trusteesFromKS ) { trust_store = key_store; } else { if ( "PKCS11".equalsIgnoreCase( truststore_type ) ) { trust_store = KeyStore.getInstance( truststore_type, truststore_provider ); trust_store.load( null, truststore_passphrase.toCharArray() ); } else if ( "WINDOWS-ROOT".equalsIgnoreCase( truststore_type ) ) { trust_store = KeyStore.getInstance( "WINDOWS-ROOT" ); trust_store.load( null, null ); } else if (truststore_location != null && truststore_passphrase != null) { trust_store = KeyStoreUtil.getKeyStore( truststore_location, truststore_passphrase.toCharArray(), truststore_type, truststore_provider); } } if (trust_store != null) { //take trusted certificates from keystore if (logger.isInfoEnabled()) { logger.info("Loading trusted certs from keystore " + trust_store.getType() ); } } if ( trust_store != null && support_crl ) { PKIXBuilderParameters pkixParams = null; //create the selector to filter the trusted CA from others. X509CertSelector x509CertSelector = new X509CertSelector(); x509CertSelector.setCertificateValid( new Date() ); pkixParams = new PKIXBuilderParameters( trust_store, x509CertSelector ); //the CRL file InputStream crlFileStream = new FileInputStream( crl_file ); //the usage of the certificate boolean[] keyUsage = {true}; x509CertSelector.setKeyUsage( keyUsage ); CertificateFactory crlf = CertificateFactory.getInstance( "X.509" ); X509CRL x509crl = (X509CRL) crlf.generateCRL( crlFileStream ); List list = new ArrayList(); list.add( x509crl ); CertStoreParameters cparam = new CollectionCertStoreParameters( list ); CertStore cs = CertStore.getInstance( "Collection", cparam ); //Specify that revocation checking is to be enabled pkixParams.setRevocationEnabled( true ); //add the certificate store pkixParams.addCertStore( cs ); //Wrap them as trust manager parameters ManagerFactoryParameters trustParams = new CertPathTrustManagerParameters( pkixParams ); //Pass parameters to factory to be passed to CertPath implementation tmf.init( trustParams ); } else { tmf.init( trust_store ); } TrustManager[] trustManagers; if (trustManager == null) { trustManagers = tmf.getTrustManagers(); } else { if (logger.isDebugEnabled()) { logger.debug("Setting user specified TrustManager for the client: " + trustManager.getClass().getName()); } trustManagers = new TrustManager[] { trustManager }; } SSLContext ctx = SSLContext.getInstance( "TLS" ); ctx.init( (kmf == null)? null : kmf.getKeyManagers(), trustManagers, sslRandom.getSecureRandom() ); return ctx.getSocketFactory(); } }