SSLException in SslHandler; based on SecureChat example
bwagner
bwagner at mpowertrading.com
Mon Apr 13 12:56:46 EDT 2009
N.B. I forgot to mention that the exception is truly non-deterministic in behavior. It will happen even after other client connections have been established. Typically, launching the client application again will result in a successful connection. The client-side handlers are also based on the examples and are highly symmetric with the server code. I am using SecureKeyStore and SecureTrustManagerFactory from the example without any modifications.
Client ChannelPipelineFactory:
public class ClientNettyPipelineFactory implements ChannelPipelineFactory {
protected INettySocket nettySocket; // the reference to the {@link INettySocket} instance
/**
* Creates a new {@link NettyPipelineFactory}.
* @param nettySocket the reference to the {@link INettySocket} instance
*/
public ClientNettyPipelineFactory(INettySocket nettySocket) {
this.nettySocket = nettySocket;
}
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline channelPipeline = Channels.pipeline();
// Add SSL handler first to encrypt and decrypt everything. In this example, we use a bogus certificate in the server side
// and accept any invalid certificates in the client side. You will need something more complicated to identify both client
// and server in the real world.
SSLContext clientContext = SecureSslContextFactory.getClientContext();
SSLEngine sslEngine = clientContext.createSSLEngine();
sslEngine.setUseClientMode(true);
channelPipeline.addLast("ssl", new SslHandler(sslEngine));
// add object decoder/encoder
channelPipeline.addLast("decoder", new ObjectDecoder());
channelPipeline.addLast("encoder", new ObjectEncoder());
// create a new {@link ClientNettyHandler} instance for each new channel
NettyHandler nettyHandler = new ClientNettyHandler(this.nettySocket);
channelPipeline.addLast("handler", nettyHandler);
return channelPipeline;
}
}
Client SslContextFactory:
public class SecureSslContextFactory {
private static final String PROTOCOL = "TLS";
private static SSLContext CLIENT_CONTEXT = null;
private static final Object LOCK = new Object();
/**
* Creates the client SSL context.
*/
private static void createClientInstance() {
SSLContext clientContext = null;
try {
KeyManager[] keyManagers = null;
TrustManager[] trustManagers = SecureTrustManagerFactory.getTrustManagers();
SecureRandom secureRandom = null;
clientContext = SSLContext.getInstance(PROTOCOL);
clientContext.init(keyManagers, trustManagers, secureRandom);
}
catch (Exception e) {
throw new Error("Failed to initialize the client-side SSLContext", e);
}
CLIENT_CONTEXT = clientContext;
if (CLIENT_CONTEXT == null) {
throw new Error("Failed to initialize the client-side SSLContext: CLIENT_CONTEXT=" + CLIENT_CONTEXT);
}
}
/**
* Returns the singleton client-side SSL context.
* @return the singleton client-side SSL context
*/
public static SSLContext getClientContext() {
if (CLIENT_CONTEXT == null) {
synchronized (LOCK) {
if (CLIENT_CONTEXT == null) {
createClientInstance();
}
}
}
return CLIENT_CONTEXT;
}
}
Relevent code from client Netty socket handler:
public class ClientNettySocket implements INettySocket {
...
protected ExecutorService bossExecutor; // the main executor service for the Netty {@link ChannelFactory}
protected ExecutorService workerExecutor; // the auxiliary executor service for the Netty {@link ChannelFactory}
protected ChannelFactory channelFactory; // the Netty factory for creating {@link Channel} instances
protected ChannelPipelineFactory channelPipelineFactory; // the factory used to bootstrap encoders and handlers with each {@link Channel} instance
protected ClientBootstrap clientBootstrap; // the Netty factory for bootstrapping {@link Channel} instances with the encoders and handlers of {@link NettyPipelineFactory}
/**
* Creates a new {@link ClientNettySocket}.
* @param sessionSocketListener the reference to the {@link ISessionSocketListener} to send session events to
*/
public ClientNettySocket(ISessionSocketListener sessionSocketListener) {
SecureSslContextFactory.getClientContext(); // make sure the SSL context is cached
this.sessionSocketListener = sessionSocketListener;
this.sessionChannel = null;
this.bossExecutor = Executors.newCachedThreadPool();
this.workerExecutor = Executors.newCachedThreadPool();
this.channelFactory = new NioClientSocketChannelFactory(bossExecutor, workerExecutor);
this.channelPipelineFactory = new ClientNettyPipelineFactory(this);
this.clientBootstrap = new ClientBootstrap(channelFactory);
clientBootstrap.setPipelineFactory(channelPipelineFactory);
clientBootstrap.setOption("tcpNoDelay", true);
clientBootstrap.setOption("keepAlive", true);
}
...
}
--
View this message in context: http://n2.nabble.com/SSLException-in-SslHandler--based-on-SecureChat-example-tp2628574p2628633.html
Sent from the Netty User Group mailing list archive at Nabble.com.
More information about the netty-users
mailing list