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