org.jboss.netty.handler.ssl
Class SslHandler

java.lang.Object
  extended by org.jboss.netty.channel.SimpleChannelUpstreamHandler
      extended by org.jboss.netty.handler.codec.frame.FrameDecoder
          extended by org.jboss.netty.handler.ssl.SslHandler
All Implemented Interfaces:
ChannelDownstreamHandler, ChannelHandler, ChannelUpstreamHandler, LifeCycleAwareChannelHandler

public class SslHandler
extends FrameDecoder
implements ChannelDownstreamHandler, LifeCycleAwareChannelHandler

Adds SSL · TLS and StartTLS support to a Channel. Please refer to the "SecureChat" example in the distribution or the web site for the detailed usage.

Beginning the handshake

You must make sure not to write a message while the handshake is in progress unless you are renegotiating. You will be notified by the ChannelFuture which is returned by the handshake() method when the handshake process succeeds or fails.

Renegotiation

If enableRenegotiation is true (default) and the initial handshake has been done successfully, you can call handshake() to trigger the renegotiation.

If enableRenegotiation is false, an attempt to trigger renegotiation will result in the connection closure.

Please note that TLS renegotiation had a security issue before. If your runtime environment did not fix it, please make sure to disable TLS renegotiation by calling setEnableRenegotiation(boolean) with false. For more information, please refer to the following documents:

Closing the session

To close the SSL session, the close() method should be called to send the close_notify message to the remote peer. One exception is when you close the Channel - SslHandler intercepts the close request and send the close_notify message before the channel closure automatically. Once the SSL session is closed, it is not reusable, and consequently you should create a new SslHandler with a new SSLEngine as explained in the following section.

Restarting the session

To restart the SSL session, you must remove the existing closed SslHandler from the ChannelPipeline, insert a new SslHandler with a new SSLEngine into the pipeline, and start the handshake process as described in the first section.

Implementing StartTLS

StartTLS is the communication pattern that secures the wire in the middle of the plaintext connection. Please note that it is different from SSL · TLS, that secures the wire from the beginning of the connection. Typically, StartTLS is composed of three steps:

  1. Client sends a StartTLS request to server.
  2. Server sends a StartTLS response to client.
  3. Client begins SSL handshake.
If you implement a server, you need to:
  1. create a new SslHandler instance with startTls flag set to true,
  2. insert the SslHandler to the ChannelPipeline, and
  3. write a StartTLS response.
Please note that you must insert SslHandler before sending the StartTLS response. Otherwise the client can send begin SSL handshake before SslHandler is inserted to the ChannelPipeline, causing data corruption.

The client-side implementation is much simpler.

  1. Write a StartTLS request,
  2. wait for the StartTLS response,
  3. create a new SslHandler instance with startTls flag set to false,
  4. insert the SslHandler to the ChannelPipeline, and
  5. Initiate SSL handshake by calling handshake().

Version:
$Rev: 2369 $, $Date: 2010-10-19 13:05:28 +0900 (Tue, 19 Oct 2010) $
Author:
The Netty Project, Trustin Lee

Nested Class Summary
 
Nested classes/interfaces inherited from interface org.jboss.netty.channel.ChannelHandler
ChannelHandler.Sharable
 
Constructor Summary
SslHandler(SSLEngine engine)
          Creates a new instance.
SslHandler(SSLEngine engine, boolean startTls)
          Creates a new instance.
SslHandler(SSLEngine engine, boolean startTls, Executor delegatedTaskExecutor)
          Creates a new instance.
SslHandler(SSLEngine engine, Executor delegatedTaskExecutor)
          Creates a new instance.
SslHandler(SSLEngine engine, SslBufferPool bufferPool)
          Creates a new instance.
SslHandler(SSLEngine engine, SslBufferPool bufferPool, boolean startTls)
          Creates a new instance.
SslHandler(SSLEngine engine, SslBufferPool bufferPool, boolean startTls, Executor delegatedTaskExecutor)
          Creates a new instance.
SslHandler(SSLEngine engine, SslBufferPool bufferPool, Executor delegatedTaskExecutor)
          Creates a new instance.
 
Method Summary
 void afterAdd(ChannelHandlerContext ctx)
           
 void afterRemove(ChannelHandlerContext ctx)
           
 void beforeAdd(ChannelHandlerContext ctx)
           
 void beforeRemove(ChannelHandlerContext ctx)
           
 void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e)
          Invoked when a Channel was disconnected from its remote peer.
 ChannelFuture close()
          Sends an SSL close_notify message to the specified channel and destroys the underlying SSLEngine.
 ChannelFuture close(Channel channel)
          Deprecated. Use close() instead.
protected  Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer)
          Decodes the received packets so far into a frame.
 void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
          Invoked when an exception was raised by an I/O thread or a ChannelHandler.
static SslBufferPool getDefaultBufferPool()
          Returns the default SslBufferPool used when no pool is specified in the constructor.
 SSLEngine getEngine()
          Returns the SSLEngine which is used by this handler.
 void handleDownstream(ChannelHandlerContext context, ChannelEvent evt)
          Handles the specified downstream event.
 ChannelFuture handshake()
          Starts an SSL / TLS handshake for the specified channel.
 ChannelFuture handshake(Channel channel)
          Deprecated. Use handshake() instead.
 boolean isEnableRenegotiation()
          Returns true if and only if TLS renegotiation is enabled.
 void setEnableRenegotiation(boolean enableRenegotiation)
          Enables or disables TLS renegotiation.
 
Methods inherited from class org.jboss.netty.handler.codec.frame.FrameDecoder
channelClosed, decodeLast, messageReceived
 
Methods inherited from class org.jboss.netty.channel.SimpleChannelUpstreamHandler
channelBound, channelConnected, channelInterestChanged, channelOpen, channelUnbound, childChannelClosed, childChannelOpen, handleUpstream, writeComplete
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

SslHandler

public SslHandler(SSLEngine engine)
Creates a new instance.

Parameters:
engine - the SSLEngine this handler will use

SslHandler

public SslHandler(SSLEngine engine,
                  SslBufferPool bufferPool)
Creates a new instance.

Parameters:
engine - the SSLEngine this handler will use
bufferPool - the SslBufferPool where this handler will acquire the buffers required by the SSLEngine

SslHandler

public SslHandler(SSLEngine engine,
                  boolean startTls)
Creates a new instance.

Parameters:
engine - the SSLEngine this handler will use
startTls - true if the first write request shouldn't be encrypted by the SSLEngine

SslHandler

public SslHandler(SSLEngine engine,
                  SslBufferPool bufferPool,
                  boolean startTls)
Creates a new instance.

Parameters:
engine - the SSLEngine this handler will use
bufferPool - the SslBufferPool where this handler will acquire the buffers required by the SSLEngine
startTls - true if the first write request shouldn't be encrypted by the SSLEngine

SslHandler

public SslHandler(SSLEngine engine,
                  Executor delegatedTaskExecutor)
Creates a new instance.

Parameters:
engine - the SSLEngine this handler will use
delegatedTaskExecutor - the Executor which will execute the delegated task that SSLEngine.getDelegatedTask() will return

SslHandler

public SslHandler(SSLEngine engine,
                  SslBufferPool bufferPool,
                  Executor delegatedTaskExecutor)
Creates a new instance.

Parameters:
engine - the SSLEngine this handler will use
bufferPool - the SslBufferPool where this handler will acquire the buffers required by the SSLEngine
delegatedTaskExecutor - the Executor which will execute the delegated task that SSLEngine.getDelegatedTask() will return

SslHandler

public SslHandler(SSLEngine engine,
                  boolean startTls,
                  Executor delegatedTaskExecutor)
Creates a new instance.

Parameters:
engine - the SSLEngine this handler will use
startTls - true if the first write request shouldn't be encrypted by the SSLEngine
delegatedTaskExecutor - the Executor which will execute the delegated task that SSLEngine.getDelegatedTask() will return

SslHandler

public SslHandler(SSLEngine engine,
                  SslBufferPool bufferPool,
                  boolean startTls,
                  Executor delegatedTaskExecutor)
Creates a new instance.

Parameters:
engine - the SSLEngine this handler will use
bufferPool - the SslBufferPool where this handler will acquire the buffers required by the SSLEngine
startTls - true if the first write request shouldn't be encrypted by the SSLEngine
delegatedTaskExecutor - the Executor which will execute the delegated task that SSLEngine.getDelegatedTask() will return
Method Detail

getDefaultBufferPool

public static SslBufferPool getDefaultBufferPool()
Returns the default SslBufferPool used when no pool is specified in the constructor.


getEngine

public SSLEngine getEngine()
Returns the SSLEngine which is used by this handler.


handshake

public ChannelFuture handshake()
Starts an SSL / TLS handshake for the specified channel.

Returns:
a ChannelFuture which is notified when the handshake succeeds or fails.

handshake

@Deprecated
public ChannelFuture handshake(Channel channel)
Deprecated. Use handshake() instead.


close

public ChannelFuture close()
Sends an SSL close_notify message to the specified channel and destroys the underlying SSLEngine.


close

@Deprecated
public ChannelFuture close(Channel channel)
Deprecated. Use close() instead.


isEnableRenegotiation

public boolean isEnableRenegotiation()
Returns true if and only if TLS renegotiation is enabled.


setEnableRenegotiation

public void setEnableRenegotiation(boolean enableRenegotiation)
Enables or disables TLS renegotiation.


handleDownstream

public void handleDownstream(ChannelHandlerContext context,
                             ChannelEvent evt)
                      throws Exception
Description copied from interface: ChannelDownstreamHandler
Handles the specified downstream event.

Specified by:
handleDownstream in interface ChannelDownstreamHandler
Parameters:
context - the context object for this handler
evt - the downstream event to process or intercept
Throws:
Exception

channelDisconnected

public void channelDisconnected(ChannelHandlerContext ctx,
                                ChannelStateEvent e)
                         throws Exception
Description copied from class: SimpleChannelUpstreamHandler
Invoked when a Channel was disconnected from its remote peer.

Overrides:
channelDisconnected in class FrameDecoder
Throws:
Exception

exceptionCaught

public void exceptionCaught(ChannelHandlerContext ctx,
                            ExceptionEvent e)
                     throws Exception
Description copied from class: SimpleChannelUpstreamHandler
Invoked when an exception was raised by an I/O thread or a ChannelHandler.

Overrides:
exceptionCaught in class FrameDecoder
Throws:
Exception

decode

protected Object decode(ChannelHandlerContext ctx,
                        Channel channel,
                        ChannelBuffer buffer)
                 throws Exception
Description copied from class: FrameDecoder
Decodes the received packets so far into a frame.

Specified by:
decode in class FrameDecoder
Parameters:
ctx - the context of this handler
channel - the current channel
buffer - the cumulative buffer of received packets so far. Note that the buffer might be empty, which means you should not make an assumption that the buffer contains at least one byte in your decoder implementation.
Returns:
the decoded frame if a full frame was received and decoded. null if there's not enough data in the buffer to decode a frame.
Throws:
Exception

beforeAdd

public void beforeAdd(ChannelHandlerContext ctx)
               throws Exception
Specified by:
beforeAdd in interface LifeCycleAwareChannelHandler
Throws:
Exception

afterAdd

public void afterAdd(ChannelHandlerContext ctx)
              throws Exception
Specified by:
afterAdd in interface LifeCycleAwareChannelHandler
Throws:
Exception

beforeRemove

public void beforeRemove(ChannelHandlerContext ctx)
                  throws Exception
Specified by:
beforeRemove in interface LifeCycleAwareChannelHandler
Throws:
Exception

afterRemove

public void afterRemove(ChannelHandlerContext ctx)
                 throws Exception
Specified by:
afterRemove in interface LifeCycleAwareChannelHandler
Throws:
Exception


Copyright © 2008-2011 JBoss, a division of Red Hat, Inc.. All Rights Reserved.