org.glassfish.enterprise.iiop.impl.IIOPSSLSocketFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-micro Show documentation
Show all versions of payara-micro Show documentation
Micro Distribution of the Payara Project
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Portions Copyright [2016] [Payara Foundation]
package org.glassfish.enterprise.iiop.impl;
import com.sun.corba.ee.impl.misc.ORBUtility;
import com.sun.corba.ee.spi.transport.Acceptor;
import java.util.Hashtable;
import java.util.Map;
import java.util.logging.Logger;
import javax.net.ssl.SSLContext;
import com.sun.corba.ee.spi.orb.ORB;
import com.sun.corba.ee.spi.misc.ORBConstants;
import com.sun.corba.ee.spi.transport.ORBSocketFactory;
import com.sun.enterprise.config.serverbeans.Config;
import org.glassfish.orb.admin.config.IiopListener;
import org.glassfish.orb.admin.config.IiopService;
import org.glassfish.grizzly.config.dom.Ssl;
import com.sun.logging.LogDomains;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.logging.Level;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import org.glassfish.api.admin.ProcessEnvironment;
import org.glassfish.api.admin.ProcessEnvironment.ProcessType;
import org.glassfish.internal.api.Globals;
import org.glassfish.security.common.CipherInfo;
import org.glassfish.enterprise.iiop.api.IIOPSSLUtil;
import com.sun.enterprise.security.integration.AppClientSSL;
import org.glassfish.api.admin.ServerEnvironment;
/**
* 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
*/
public class IIOPSSLSocketFactory implements ORBSocketFactory
{
private static final Logger _logger = LogDomains.getLogger(
IIOPSSLSocketFactory.class, LogDomains.CORBA_LOGGER);
private static final String TLS = "TLS";
private static final String TLS11 = "TLS11";
private static final String TLS12 = "TLS12";
private static final String SSL3 = "SSLv3";
private static final String SSL2 = "SSLv2";
private static final String SSL = "SSL";
private static final String SSL_MUTUALAUTH = "SSL_MUTUALAUTH";
private static final String PERSISTENT_SSL = "PERSISTENT_SSL";
private static final int BACKLOG = 50;
private static final String SO_KEEPALIVE = "fish.payara.SOKeepAlive";
//private static SecureRandom sr = null;
/* this is stored for the Server side of SSL Connections.
* Note: There will be only a port per iiop listener and a corresponding
* ctx for that port
*/
/*
* @todo provide an interface to the admin, so that whenever a iiop-listener
* is added / removed, we modify the hashtable,
*/
private Map portToSSLInfo = new Hashtable();
/* this is stored for the client side of SSL Connections.
* Note: There will be only 1 ctx for the client side, as we will reuse the
* ctx for all SSL connections
*/
private SSLInfo clientSslInfo = null;
private ORB orb;
/**
* Constructs an IIOPSSLSocketFactory
*/
public IIOPSSLSocketFactory() {
try {
ProcessEnvironment penv = null;
ProcessType processType = null;
boolean notServerOrACC = Globals.getDefaultHabitat() == null ? true : false;
if (!notServerOrACC) {
penv = Globals.get(ProcessEnvironment.class);
processType = penv.getProcessType();
}
//if (Switch.getSwitch().getContainerType() == Switch.EJBWEB_CONTAINER) {
if((processType != null) && (processType.isServer())) {
//this is the EJB container
Config conf = Globals.getDefaultHabitat().getService(Config.class,
ServerEnvironment.DEFAULT_INSTANCE_NAME);
IiopService iiopBean =conf.getExtensionByType(IiopService.class);
List iiopListeners = iiopBean.getIiopListener();
for (IiopListener listener : iiopListeners) {
Ssl ssl = listener.getSsl();
SSLInfo sslInfo = null;
boolean securityEnabled = Boolean.valueOf(listener.getSecurityEnabled());
if (securityEnabled) {
if (ssl != null) {
boolean ssl2Enabled = Boolean.valueOf(ssl.getSsl2Enabled());
boolean tlsEnabled = Boolean.valueOf(ssl.getTlsEnabled());
boolean tlsEnabled11 = Boolean.valueOf(ssl.getTls11Enabled());
boolean tlsEnabled12 = Boolean.valueOf(ssl.getTls12Enabled());
boolean ssl3Enabled = Boolean.valueOf(ssl.getSsl3Enabled());
sslInfo = init(ssl.getCertNickname(),
ssl2Enabled, ssl.getSsl2Ciphers(),
ssl3Enabled, ssl.getSsl3TlsCiphers(),
tlsEnabled, tlsEnabled11, tlsEnabled12);
} else {
sslInfo = getDefaultSslInfo();
}
portToSSLInfo.put(
new Integer(listener.getPort()), sslInfo);
}
}
if (iiopBean.getSslClientConfig() != null &&
/*iiopBean.getSslClientConfig().isEnabled()*/
iiopBean.getSslClientConfig().getSsl() != null) {
Ssl outboundSsl = iiopBean.getSslClientConfig().getSsl();
if (outboundSsl != null) {
boolean ssl2Enabled = Boolean.valueOf(outboundSsl.getSsl2Enabled());
boolean ssl3Enabled = Boolean.valueOf(outboundSsl.getSsl3Enabled());
boolean tlsEnabled = Boolean.valueOf(outboundSsl.getTlsEnabled());
boolean tlsEnabled11 = Boolean.valueOf(outboundSsl.getTls11Enabled());
boolean tlsEnabled12 = Boolean.valueOf(outboundSsl.getTls12Enabled());
clientSslInfo = init(outboundSsl.getCertNickname(),
ssl2Enabled,
outboundSsl.getSsl2Ciphers(),
ssl3Enabled,
outboundSsl.getSsl3TlsCiphers(),
tlsEnabled, tlsEnabled11, tlsEnabled12);
}
}
if (clientSslInfo == null) {
clientSslInfo = getDefaultSslInfo();
}
} else {
if ((processType != null) && (processType == ProcessType.ACC)) {
IIOPSSLUtil sslUtil = Globals.getDefaultHabitat().getService(IIOPSSLUtil.class);
AppClientSSL clientSsl = (AppClientSSL)sslUtil.getAppClientSSL();
if (clientSsl != null) {
clientSslInfo = init(clientSsl.getCertNickname(),
clientSsl.getSsl2Enabled(), clientSsl.getSsl2Ciphers(),
clientSsl.getSsl3Enabled(), clientSsl.getSsl3TlsCiphers(),
clientSsl.getTlsEnabled(),clientSsl.getTls11Enabled(),clientSsl.getTls12Enabled());
} else { // include case keystore, truststore jvm option
clientSslInfo = getDefaultSslInfo();
}
} else {
clientSslInfo = getDefaultSslInfo();
}
}
} catch (Exception e) {
_logger.log(Level.SEVERE,"iiop.init_exception",e);
throw new IllegalStateException(e);
}
}
/**
* Return a default SSLInfo object.
*/
private SSLInfo getDefaultSslInfo() throws Exception {
return init(null, false, null, true, null, true, true , true);
}
/**
* 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
*/
private SSLInfo init(String alias,
boolean ssl2Enabled, String ssl2Ciphers,
boolean ssl3Enabled, String ssl3TlsCiphers,
boolean tlsEnabled, boolean tlsEnabled11,boolean tlsEnabled12) throws Exception {
String protocol;
if (tlsEnabled) {
protocol = TLS;
} else if (tlsEnabled11){
protocol = TLS11;
} else if (tlsEnabled12){
protocol = TLS12;
}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, tlsEnabled11, tlsEnabled12);
}
String[] ssl2CipherArr = null;
if (ssl2Enabled) {
ssl2CipherArr = getEnabledCipherSuites(ssl2Ciphers,
true, false, false, false, false);
}
SSLContext ctx = SSLContext.getInstance(protocol);
if (Globals.getDefaultHabitat() != null) {
IIOPSSLUtil sslUtil = Globals.getDefaultHabitat().getService(IIOPSSLUtil.class);
KeyManager[] mgrs = sslUtil.getKeyManagers(alias);
ctx.init(mgrs, sslUtil.getTrustManagers(), sslUtil.getInitializedSecureRandom());
} else {
//do nothing
//ctx.init(mgrs, sslUtil.getTrustManagers(), sslUtil.getInitializedSecureRandom());
}
return new SSLInfo(ctx, ssl3TlsCipherArr, ssl2CipherArr);
}
//----- implements com.sun.corba.ee.spi.transport.ORBSocketFactory -----
public void setORB(ORB orb) {
this.orb = orb;
}
/**
* 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 type 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
*/
public ServerSocket createServerSocket(String type,
InetSocketAddress inetSocketAddress) throws IOException {
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;
}
}
/**
* 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.
*/
public Socket createSocket(String type, InetSocketAddress inetSocketAddress)
throws IOException {
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());
}
// PAYARA-408
// Check if SO_KEEPALIVE property set
if (Boolean.getBoolean("fish.payara.SOKeepAlive")) {
if (_logger.isLoggable(Level.FINER)) {
_logger.log(Level.FINER, "Enabling SO_KEEPALIVE");
}
socket.setKeepAlive(true);
}
// 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);
}
}
public void setAcceptedSocketOptions(Acceptor acceptor,
ServerSocket serverSocket, Socket socket) {
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, "setAcceptedSocketOptions: " + acceptor
+ " " + serverSocket + " " + socket);
}
// Disable Nagle's algorithm (i.e., always send immediately).
try {
socket.setTcpNoDelay(true);
} catch (SocketException ex) {
throw new RuntimeException(ex);
}
}
//----- END implements com.sun.corba.ee.spi.transport.ORBSocketFactory -----
/**
* Create an SSL server socket at the specified InetSocketAddress. If the type
* is SSL_MUTUALAUTH then SSL client authentication is requested.
*/
private ServerSocket createSSLServerSocket(String type,
InetSocketAddress inetSocketAddress) throws IOException {
if (inetSocketAddress == null) {
throw new IOException(getFormatMessage(
"iiop.invalid_sslserverport",
new Object[] { null }));
}
int port = inetSocketAddress.getPort();
Integer iport = Integer.valueOf(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;
}
/**
* Create an SSL socket at the specified host and port.
* @param host
* @param port
* @return the socket.
*/
private Socket createSSLSocket(String host, int port)
throws IOException {
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);
}
// PAYARA-408
// Check if SO_KEEPALIVE property set
if (Boolean.getBoolean("fish.payara.SOKeepAlive")) {
if (_logger.isLoggable(Level.FINER)) {
_logger.log(Level.FINER, "Enabling SO_KEEPALIVE");
}
socket.setKeepAlive(true);
}
} 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;
}
/**
* 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
*/
private String[] getEnabledCipherSuites(String cipherSuiteStr,
boolean ssl2Enabled, boolean ssl3Enabled, boolean tlsEnabled, boolean tlsEnabled11, boolean tlsEnabled12) {
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, tlsEnabled11, tlsEnabled12)) {
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, tlsEnabled11, tlsEnabled12)) {
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;
}
/**
* Return an array of merged ciphers.
* @param enableCiphers ciphers enabled by socket factory
* @param ssl3TlsCiphers
* @param ssl2Ciphers
*/
private String[] mergeCiphers(String[] enableCiphers,
String[] ssl3TlsCiphers, String[] 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()]);
}
/**
* Check whether given cipherInfo belongs to given protocol.
* @param cipherInfo
* @param ssl2Enabled
* @param ssl3Enabled
* @param tlsEnabled
*/
private boolean isValidProtocolCipher(CipherInfo cipherInfo,
boolean ssl2Enabled, boolean ssl3Enabled, boolean tlsEnabled, boolean tlsEnabled11, boolean tlsEnabled12) {
return (tlsEnabled && cipherInfo.isTLS() ||
tlsEnabled11 && cipherInfo.isTLS() ||
tlsEnabled12 && cipherInfo.isTLS() ||
ssl3Enabled && cipherInfo.isSSL3() ||
ssl2Enabled && cipherInfo.isSSL2());
}
/**
* 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
*/
private String getFormatMessage(String key, Object[] params) {
return MessageFormat.format(
_logger.getResourceBundle().getString(key), params);
}
class SSLInfo {
private SSLContext ctx;
private String[] ssl3TlsCiphers = null;
private String[] ssl2Ciphers = null;
SSLInfo(SSLContext ctx, String[] ssl3TlsCiphers, String[] ssl2Ciphers) {
this.ctx = ctx;
this.ssl3TlsCiphers = ssl3TlsCiphers;
this.ssl2Ciphers = ssl2Ciphers;
}
SSLContext getContext() {
return ctx;
}
String[] getSsl3TlsCiphers() {
return ssl3TlsCiphers;
}
String[] getSsl2Ciphers() {
return ssl2Ciphers;
}
}
}