org.jboss.netty.handler.ssl

## Class SslHandler

- java.lang.Object
- - org.jboss.netty.channel.SimpleChannelUpstreamHandler
  - - org.jboss.netty.handler.codec.frame.FrameDecoder
    - - org.jboss.netty.handler.ssl.SslHandler

- All Implemented Interfaces:
    ChannelDownstreamHandler, ChannelHandler, ChannelUpstreamHandler, LifeCycleAwareChannelHandler

      public class SslHandler
      extends FrameDecoder
      implements ChannelDownstreamHandler

  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.

  ### Handshake

  If `isIssueHandshake()` is `false` (default) you will need to take care of calling `handshake()` by your own. In most situations were `SslHandler` is used in 'client mode' you want to issue a handshake once the connection was established. if `setIssueHandshake(boolean)` is set to `true` you don't need to worry about this as the `SslHandler` will take care of it.

  ### 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:

  - CVE-2009-3555
  - RFC5746
  - Phased Approach to Fixing the TLS Renegotiation Issue

  ### 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()`.

- - ### Nested Class Summary

    - ### Nested classes/interfaces inherited from interface org.jboss.netty.channel.ChannelHandler

      `ChannelHandler.Sharable`

  - ### Field Summary

    - ### Fields inherited from class org.jboss.netty.handler.codec.frame.FrameDecoder

      `cumulation, DEFAULT_MAX_COMPOSITEBUFFER_COMPONENTS`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `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

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `afterRemove(ChannelHandlerContext ctx)` Fail all pending writes which we were not able to flush out
    `void` | `beforeAdd(ChannelHandlerContext ctx)`
    `void` | `channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)` Loop over all the pending writes and fail them.
    `void` | `channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)` Calls `handshake()` once the `Channel` is connected
    `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`.
    `boolean` | `getCloseOnSSLException()`
    `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.
    `ChannelFuture` | `getSSLEngineInboundCloseFuture()` Return the `ChannelFuture` that will get notified if the inbound of the `SSLEngine` will get closed.
    `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.
    `boolean` | `isIssueHandshake()` Returns `true` if the automatic handshake is enabled
    `void` | `setCloseOnSSLException(boolean closeOnSslException)` If set to `true`, the `Channel` will automatically get closed one a `SSLException` was caught.
    `void` | `setEnableRenegotiation(boolean enableRenegotiation)` Enables or disables TLS renegotiation.
    `void` | `setIssueHandshake(boolean issueHandshake)` Enables or disables the automatic handshake once the `Channel` is connected.

    - ### Methods inherited from class org.jboss.netty.handler.codec.frame.FrameDecoder

      `actualReadableBytes, afterAdd, appendToCumulation, beforeRemove, cleanup, decodeLast, getMaxCumulationBufferCapacity, getMaxCumulationBufferComponents, internalBuffer, isUnfold, messageReceived, newCumulationBuffer, replace, setMaxCumulationBufferCapacity, setMaxCumulationBufferComponents, setUnfold, unfoldAndFireMessageReceived, updateCumulation`

    - ### Methods inherited from class org.jboss.netty.channel.SimpleChannelUpstreamHandler

      `channelBound, 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.

    - #### setIssueHandshake

          public void setIssueHandshake(boolean issueHandshake)

      Enables or disables the automatic handshake once the `Channel` is connected. The value will only have affect if its set before the `Channel` is connected.

    - #### isIssueHandshake

          public boolean isIssueHandshake()

      Returns `true` if the automatic handshake is enabled

    - #### getSSLEngineInboundCloseFuture

          public ChannelFuture getSSLEngineInboundCloseFuture()

      Return the `ChannelFuture` that will get notified if the inbound of the `SSLEngine` will get closed. This method will return the same `ChannelFuture` all the time. For more informations see the apidocs of `SSLEngine`

    - #### setCloseOnSSLException

          public void setCloseOnSSLException(boolean closeOnSslException)

      If set to `true`, the `Channel` will automatically get closed one a `SSLException` was caught. This is most times what you want, as after this its almost impossible to recover. Anyway the default is `false` to not break compatibility with older releases. This will be changed to `true` in the next major release.

    - #### getCloseOnSSLException

          public boolean getCloseOnSSLException()

    - #### 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`
      Overrides:
        `beforeAdd` in class `FrameDecoder`
      Throws:
        `Exception`

    - #### afterRemove

          public void afterRemove(ChannelHandlerContext ctx)
                           throws Exception

      Fail all pending writes which we were not able to flush out
      Specified by:
        `afterRemove` in interface `LifeCycleAwareChannelHandler`
      Overrides:
        `afterRemove` in class `FrameDecoder`
      Throws:
        `Exception`

    - #### channelConnected

          public void channelConnected(ChannelHandlerContext ctx,
                              ChannelStateEvent e)
                                throws Exception

      Calls `handshake()` once the `Channel` is connected
      Overrides:
        `channelConnected` in class `SimpleChannelUpstreamHandler`
      Throws:
        `Exception`

    - #### channelClosed

          public void channelClosed(ChannelHandlerContext ctx,
                           ChannelStateEvent e)
                             throws Exception

      Loop over all the pending writes and fail them. See #305 for more details.
      Overrides:
        `channelClosed` in class `FrameDecoder`
      Throws:
        `Exception`

Copyright © 2008-2012 The Netty Project. All Rights Reserved.