FileDocCategorySizeDatePackage
IIOPSSLSocketFactory.javaAPI DocGlassfish v2 API25068Wed May 23 14:45:40 BST 2007com.sun.enterprise.iiop

IIOPSSLSocketFactory

public class IIOPSSLSocketFactory extends Object implements com.sun.corba.ee.spi.transport.ORBSocketFactory, Serializable
This is socket factory used to create either plain sockets or SSL sockets based on the target's policies and the client policies.
author
Vivek Nagar
author
Shing Wai Chan

Fields Summary
private static Logger
_logger
private static final String
TLS
private static final String
SSL3
private static final String
SSL2
private static final String
SSL
private static final String
SSL_MUTUALAUTH
private static final String
PERSISTENT_SSL
private static final int
BACKLOG
private static SecureRandom
sr
private Map
portToSSLInfo
private SSLInfo
clientSslInfo
private com.sun.corba.ee.spi.orb.ORB
orb
Constructors Summary
public IIOPSSLSocketFactory()
Constructs an IIOPSSLSocketFactory


            
      
        try {
            if (Switch.getSwitch().getContainerType() == Switch.EJBWEB_CONTAINER) {
                ConfigContext configContext =
                    ApplicationServer.getServerContext().getConfigContext();
                IiopService iiopBean = ServerBeansFactory.getIiopServiceBean(configContext);

                IiopListener[] iiopListeners = iiopBean.getIiopListener();
                int listenersLength = (iiopListeners != null) ? iiopListeners.length : 0;
                for (int i = 0; i < listenersLength; i++) {
                    Ssl ssl = iiopListeners[i].getSsl();
                    SSLInfo sslInfo = null;
                    if (iiopListeners[i].isSecurityEnabled()) {
                        if (ssl != null) {
                            sslInfo = init(ssl.getCertNickname(),
                                ssl.isSsl2Enabled(), ssl.getSsl2Ciphers(),
                                ssl.isSsl3Enabled(), ssl.getSsl3TlsCiphers(),
                                ssl.isTlsEnabled());
                        } else {
                            sslInfo = getDefaultSslInfo();
                        }
                        portToSSLInfo.put(
                            new Integer(iiopListeners[i].getPort()), sslInfo);
                    }
                }

                if (iiopBean.getSslClientConfig() != null &&
                        iiopBean.getSslClientConfig().isEnabled()) {
                    Ssl outboundSsl = iiopBean.getSslClientConfig().getSsl();
                    if (outboundSsl != null) {
                        clientSslInfo = init(outboundSsl.getCertNickname(),
                            outboundSsl.isSsl2Enabled(),
                            outboundSsl.getSsl2Ciphers(),
                            outboundSsl.isSsl3Enabled(),
                            outboundSsl.getSsl3TlsCiphers(),
                            outboundSsl.isTlsEnabled());
                    }
                }
                if (clientSslInfo == null) {
                    clientSslInfo = getDefaultSslInfo();
                }
            } else {
                com.sun.enterprise.config.clientbeans.Ssl clientSsl =
                        SSLUtils.getAppclientSsl();
                if (clientSsl != null) {
                    clientSslInfo = init(clientSsl.getCertNickname(),
                        clientSsl.isSsl2Enabled(), clientSsl.getSsl2Ciphers(),
                        clientSsl.isSsl3Enabled(), clientSsl.getSsl3TlsCiphers(),
                        clientSsl.isTlsEnabled());
                } else { // include case keystore, truststore jvm option
                    clientSslInfo = getDefaultSslInfo();
                } 
            }
        } catch (Exception e) {
            _logger.log(Level.SEVERE,"iiop.init_exception",e);
            throw new IllegalStateException(e.toString());
        }
    
Methods Summary
private java.net.ServerSocketcreateSSLServerSocket(java.lang.String type, java.net.InetSocketAddress inetSocketAddress)
Create an SSL server socket at the specified InetSocketAddress. If the type is SSL_MUTUALAUTH then SSL client authentication is requested.


        if (inetSocketAddress == null) {
            throw new IOException(getFormatMessage(
                "iiop.invalid_sslserverport",
                new Object[] { null }));
        }
        int port = inetSocketAddress.getPort();
        Integer iport = new Integer(port);
        SSLInfo sslInfo = (SSLInfo)portToSSLInfo.get(iport);
        if (sslInfo == null) {
            throw new IOException(getFormatMessage(
                "iiop.invalid_sslserverport",
                new Object[] { iport }));
        }
        SSLServerSocketFactory ssf = sslInfo.getContext().getServerSocketFactory();   
        String[] ssl3TlsCiphers = sslInfo.getSsl3TlsCiphers();
        String[] ssl2Ciphers = sslInfo.getSsl2Ciphers();
        String[] ciphers = null;
        if (ssl3TlsCiphers != null || ssl2Ciphers != null) {
            String[] socketCiphers = ssf.getDefaultCipherSuites();
            ciphers = mergeCiphers(socketCiphers, ssl3TlsCiphers, ssl2Ciphers);
        }

	String cs[] = null;

	if(_logger.isLoggable(Level.FINE)) {
	    cs = ssf.getSupportedCipherSuites();
	    for(int i=0; i < cs.length; ++i) {
		_logger.log(Level.FINE,"Cipher Suite: " + cs[i]);
	    }
	}
	ServerSocket ss = null;
        try{
            // bugfix for 6349541
            // specify the ip address to bind to, 50 is the default used
            // by the ssf implementation when only the port is specified
            ss = ssf.createServerSocket(port, BACKLOG, inetSocketAddress.getAddress());
            if (ciphers != null) {
                ((SSLServerSocket)ss).setEnabledCipherSuites(ciphers);
            }
        } catch(IOException e) {
            _logger.log(Level.SEVERE, "iiop.createsocket_exception",
                new Object[] { type, String.valueOf(port) });
            _logger.log(Level.SEVERE, "", e);
            throw e;
        }

	try {
	    if(type.equals(SSL_MUTUALAUTH)) {
		_logger.log(Level.FINE,"Setting Mutual auth");
		((SSLServerSocket)ss).setNeedClientAuth(true);
	    }
	} catch(Exception e) {
	    _logger.log(Level.SEVERE,"iiop.cipher_exception",e);
	    throw new IOException(e.getMessage());
	}
	if(_logger.isLoggable(Level.FINE)) {
	    _logger.log(Level.FINE,"Created server socket:" + ss);
	}
	return ss;
    
private java.net.SocketcreateSSLSocket(java.lang.String host, int port)
Create an SSL socket at the specified host and port.

param
the host
param
the port
return
the socket.

            
	SSLSocket socket = null;
	SSLSocketFactory factory = null;
        try{
            // get socketfactory+sanity check
            // clientSslInfo is never null
            factory = clientSslInfo.getContext().getSocketFactory();

            if(_logger.isLoggable(Level.FINE)) {
                  _logger.log(Level.FINE,"Creating SSL Socket for host:" + host +" port:" + port);
            }
            String[] ssl3TlsCiphers = clientSslInfo.getSsl3TlsCiphers();
            String[] ssl2Ciphers = clientSslInfo.getSsl2Ciphers();
            String[] clientCiphers = null;
            if (ssl3TlsCiphers != null || ssl2Ciphers != null) {
                String[] socketCiphers = factory.getDefaultCipherSuites();
                clientCiphers = mergeCiphers(socketCiphers, ssl3TlsCiphers, ssl2Ciphers);
            }

            socket = (SSLSocket)factory.createSocket(host, port);
            if (clientCiphers != null) {
                socket.setEnabledCipherSuites(clientCiphers);
            }
        }catch(Exception e) {
            if(_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "iiop.createsocket_exception",
                new Object[] { host, String.valueOf(port) });
                _logger.log(Level.FINE, "", e);
            }
            IOException e2 = new IOException(
            "Error opening SSL socket to host="+host+" port="+port);
            e2.initCause(e);
            throw e2;
        }
        return socket;
    
public java.net.ServerSocketcreateServerSocket(java.lang.String type, java.net.InetSocketAddress inetSocketAddress)
Create a server socket on the specified InetSocketAddress based on the type of the server socket (SSL, SSL_MUTUALAUTH, PERSISTENT_SSL or CLEAR_TEXT).

param
the type of socket to create.
param
inetSocketAddress the InetSocketAddress
return
the server socket on the specified InetSocketAddress
exception
IOException if an I/O error occurs during server socket creation


	if (_logger.isLoggable(Level.FINE)) {
	    _logger.log(Level.FINE, "Creating server socket for type =" + type
                + " inetSocketAddress =" + inetSocketAddress);
	}

	if(type.equals(SSL_MUTUALAUTH) || type.equals(SSL) || 
		type.equals(PERSISTENT_SSL)) {
	    return createSSLServerSocket(type, inetSocketAddress);
	} else {
            ServerSocket serverSocket = null;
            if (orb.getORBData().acceptorSocketType().equals(
                    ORBConstants.SOCKETCHANNEL)) {
                ServerSocketChannel serverSocketChannel =
                        ServerSocketChannel.open();
                serverSocket = serverSocketChannel.socket();
            } else {
                serverSocket = new ServerSocket();
            }

	    serverSocket.bind(inetSocketAddress);
	    return serverSocket;
	}
    
public java.net.SocketcreateSocket(java.lang.String type, java.net.InetSocketAddress inetSocketAddress)
Create a client socket for the specified InetSocketAddress. Creates an SSL socket if the type specified is SSL or SSL_MUTUALAUTH.

param
type
param
inetSocketAddress
return
the socket.


	try {
	    String host = inetSocketAddress.getHostName();
	    int port = inetSocketAddress.getPort();
	    if (_logger.isLoggable(Level.FINE)) {
		_logger.log(Level.FINE, "createSocket(" + type + ", " + host + ", " +port + ")");
	    }
	    if (type.equals(SSL) || type.equals(SSL_MUTUALAUTH)) {
		return createSSLSocket(host, port);
	    } else {
                Socket socket = null;
		if (_logger.isLoggable(Level.FINE)) {
		    _logger.log(Level.FINE, "Creating CLEAR_TEXT socket for:" +port);
		}

                if (orb.getORBData().connectionSocketType().equals(
                        ORBConstants.SOCKETCHANNEL)) {
	            SocketChannel socketChannel = ORBUtility.openSocketChannel(inetSocketAddress);
	            socket = socketChannel.socket();
	        } else {
                    socket = new Socket(inetSocketAddress.getHostName(),
                        inetSocketAddress.getPort());
	        }

                // Disable Nagle's algorithm (i.e. always send immediately).
		socket.setTcpNoDelay(true);
                return socket;
	    }
	} catch ( Exception ex ) {
	    if(_logger.isLoggable(Level.FINE)) {
		_logger.log(Level.FINE,"Exception creating socket",ex);
	    }
	    throw new RuntimeException(ex);
	}
    
private com.sun.enterprise.iiop.IIOPSSLSocketFactory$SSLInfogetDefaultSslInfo()
Return a default SSLInfo object.

        return init(null, false, null, true, null, true);
    
private java.lang.String[]getEnabledCipherSuites(java.lang.String cipherSuiteStr, boolean ssl2Enabled, boolean ssl3Enabled, boolean tlsEnabled)
This API return an array of String listing the enabled cipher suites. Input is the cipherSuiteStr from xml which a space separated list ciphers with a prefix '+' indicating enabled, '-' indicating disabled. If no cipher is enabled, then it returns an empty array. If no cipher is specified, then all are enabled and it returns null.

param
cipherSuiteStr cipherSuiteStr from xml
param
ssl2Enabled
param
ssl3Enabled
param
tlsEnabled
return
an array of enabled Ciphers

        String[] cipherArr = null;
        if (cipherSuiteStr != null && cipherSuiteStr.length() > 0) {
            ArrayList cipherList = new ArrayList();
            StringTokenizer tokens = new StringTokenizer(cipherSuiteStr, ",");
            while (tokens.hasMoreTokens()) {
                String cipherAction = tokens.nextToken();
                if (cipherAction.startsWith("+")) {
                    String cipher = cipherAction.substring(1);
                    CipherInfo cipherInfo = CipherInfo.getCipherInfo(cipher);
                    if (cipherInfo != null &&
                            isValidProtocolCipher(cipherInfo, ssl2Enabled,
                                ssl3Enabled, tlsEnabled)) {
                        cipherList.add(cipherInfo.getCipherName());
                    } else {
                        throw new IllegalStateException(getFormatMessage(
                            "iiop.unknown_cipher",
                            new Object[] { cipher }));
                    }
                } else if (cipherAction.startsWith("-")) {
                    String cipher = cipherAction.substring(1);
                    CipherInfo cipherInfo = CipherInfo.getCipherInfo(cipher);
                    if (cipherInfo == null ||
                            !isValidProtocolCipher(cipherInfo, ssl2Enabled,
                                ssl3Enabled, tlsEnabled)) {
                        throw new IllegalStateException(getFormatMessage(
                            "iiop.unknown_cipher",
                            new Object[] { cipher }));
                    }
                } else if (cipherAction.trim().length() > 0) {
                    throw new IllegalStateException(getFormatMessage(
                        "iiop.invalid_cipheraction",
                        new Object[] { cipherAction }));
                }
            }

            cipherArr = (String[])cipherList.toArray(
                    new String[cipherList.size()]);
        }
        return cipherArr;
    
private java.lang.StringgetFormatMessage(java.lang.String key, java.lang.Object[] params)
This API get the format string from resource bundle of _logger.

param
key the key of the message
param
params the parameter array of Object
return
the format String for _logger

        return MessageFormat.format(
            _logger.getResourceBundle().getString(key), params);
    
private com.sun.enterprise.iiop.IIOPSSLSocketFactory$SSLInfoinit(java.lang.String alias, boolean ssl2Enabled, java.lang.String ssl2Ciphers, boolean ssl3Enabled, java.lang.String ssl3TlsCiphers, boolean tlsEnabled)
serveralias/clientalias cannot be set at the same time. this method encapsulates the common code for both the client side and server side to create a SSLContext it is called once for each serveralias and once for each clientalias

        String protocol;
        if (tlsEnabled) {
            protocol = TLS;
        } else if (ssl3Enabled) {
            protocol = SSL3;
        } else if (ssl2Enabled) {
            protocol = SSL2;
        } else { // default
            protocol = "SSL";
        }

        String[] ssl3TlsCipherArr = null;
        if (tlsEnabled || ssl3Enabled) {
            ssl3TlsCipherArr = getEnabledCipherSuites(ssl3TlsCiphers,
                    false, ssl3Enabled, tlsEnabled);
        }

        String[] ssl2CipherArr = null;
        if (ssl2Enabled) {
            ssl2CipherArr = getEnabledCipherSuites(ssl2Ciphers,
                    true, false, false);
        }

        SSLContext ctx = SSLContext.getInstance(protocol);

        if (alias != null && !SSLUtils.isTokenKeyAlias(alias)) {
            throw new IllegalStateException(getFormatMessage(
                    "iiop.cannot_find_keyalias", new Object[] { alias }));
        }
            
        KeyManager[] mgrs = SSLUtils.getKeyManagers();
        if (alias != null && mgrs != null && mgrs.length > 0) {
            KeyManager[] newMgrs = new KeyManager[mgrs.length];
            for (int i = 0; i < mgrs.length; i++) {
                if (_logger.isLoggable(Level.FINE)) {
                    StringBuffer msg = new StringBuffer("Setting J2EEKeyManager for ");
                    msg.append(" alias : "+alias);
                    _logger.log(Level.FINE, msg.toString());
                }
                newMgrs[i] = new J2EEKeyManager((X509KeyManager)mgrs[i], alias);
            }
            mgrs = newMgrs;
        }
        ctx.init(mgrs, SSLUtils.getTrustManagers(), sr);

        return new SSLInfo(ctx, ssl3TlsCipherArr, ssl2CipherArr);
    
private booleanisValidProtocolCipher(com.sun.enterprise.security.CipherInfo cipherInfo, boolean ssl2Enabled, boolean ssl3Enabled, boolean tlsEnabled)
Check whether given cipherInfo belongs to given protocol.

param
cipherInfo
param
ssl2Enabled
param
ssl3Enabled
param
tlsEnabled

        return (tlsEnabled && cipherInfo.isTLS() ||
                ssl3Enabled && cipherInfo.isSSL3() ||
                ssl2Enabled && cipherInfo.isSSL2());
    
private java.lang.String[]mergeCiphers(java.lang.String[] enableCiphers, java.lang.String[] ssl3TlsCiphers, java.lang.String[] ssl2Ciphers)
Return an array of merged ciphers.

param
enableCiphers ciphers enabled by socket factory
param
ssl3TlsCiphers
param
ssl2Ciphers

        if (ssl3TlsCiphers == null && ssl2Ciphers == null) {
            return null;
        }

        int eSize = (enableCiphers != null)? enableCiphers.length : 0;

        if (_logger.isLoggable(Level.FINE)) {
            StringBuffer buf = new StringBuffer("Default socket ciphers: ");
            for (int i = 0; i < eSize; i++) {
                buf.append(enableCiphers[i] + ", ");
            }
            _logger.log(Level.FINE, buf.toString());
        }

        ArrayList cList = new ArrayList();
        if (ssl3TlsCiphers != null) {
            for (int i = 0; i < ssl3TlsCiphers.length; i++) {
                cList.add(ssl3TlsCiphers[i]);
            }
        } else {
            for (int i = 0; i < eSize; i++) {
                String cipher = enableCiphers[i];
                CipherInfo cInfo = CipherInfo.getCipherInfo(cipher);
                if (cInfo != null && (cInfo.isTLS() || cInfo.isSSL3())) {
                    cList.add(cipher);
                }
            }
        }
        
        if (ssl2Ciphers != null) {
            for (int i = 0; i < ssl2Ciphers.length; i++) {
                cList.add(ssl2Ciphers[i]);
            }
        } else {
            for (int i = 0; i < eSize; i++) {
                String cipher = enableCiphers[i];
                CipherInfo cInfo = CipherInfo.getCipherInfo(cipher);
                if (cInfo != null && cInfo.isSSL2()) {
                    cList.add(cipher);
                }
            }
        }

        if (_logger.isLoggable(Level.FINE)) {
            _logger.log(Level.FINE, "Merged socket ciphers: " + cList);
        }

        return (String[])cList.toArray(new String[cList.size()]);
    
public voidsetAcceptedSocketOptions(com.sun.corba.ee.pept.transport.Acceptor acceptor, java.net.ServerSocket serverSocket, java.net.Socket socket)


	if (_logger.isLoggable(Level.FINE)) {
	    _logger.log(Level.FINE, "setAcceptedSocketOptions: " + acceptor
                    + " " + serverSocket + " " + socket);
	}
        // Disable Nagle's algorithm (i.e., always send immediately).
        socket.setTcpNoDelay(true);
    
public voidsetORB(com.sun.corba.ee.spi.orb.ORB orb)

        this.orb = orb;