public final class

SSLEngineImpl

extends SSLEngine
java.lang.Object
   ↳ javax.net.ssl.SSLEngine
     ↳ sun.security.ssl.SSLEngineImpl

Class Overview

Implementation of an non-blocking SSLEngine. *Currently*, the SSLEngine code exists in parallel with the current SSLSocket. As such, the current implementation is using legacy code with many of the same abstractions. However, it varies in many areas, most dramatically in the IO handling. There are three main I/O threads that can be existing in parallel: wrap(), unwrap(), and beginHandshake(). We are encouraging users to not call multiple instances of wrap or unwrap, because the data could appear to flow out of the SSLEngine in a non-sequential order. We take all steps we can to at least make sure the ordering remains consistent, but once the calls returns, anything can happen. For example, thread1 and thread2 both call wrap, thread1 gets the first packet, thread2 gets the second packet, but thread2 gets control back before thread1, and sends the data. The receiving side would see an out-of-order error. Handshaking is still done the same way as SSLSocket using the normal InputStream/OutputStream abstactions. We create ClientHandshakers/ServerHandshakers, which produce/consume the handshaking data. The transfer of the data is largely handled by the HandshakeInStream/HandshakeOutStreams. Lastly, the InputRecord/OutputRecords still have the same functionality, except that they are overridden with EngineInputRecord/EngineOutputRecord, which provide SSLEngine-specific functionality. Some of the major differences are: EngineInputRecord/EngineOutputRecord/EngineWriter: In order to avoid writing whole new control flows for handshaking, and to reuse most of the same code, we kept most of the actual handshake code the same. As usual, reading handshake data may trigger output of more handshake data, so what we do is write this data to internal buffers, and wait for wrap() to be called to give that data a ride. All data is routed through EngineInputRecord/EngineOutputRecord. However, all handshake data (ct_alert/ct_change_cipher_spec/ct_handshake) are passed through to the the underlying InputRecord/OutputRecord, and the data uses the internal buffers. Application data is handled slightly different, we copy the data directly from the src to the dst buffers, and do all operations on those buffers, saving the overhead of multiple copies. In the case of an inbound record, unwrap passes the inbound ByteBuffer to the InputRecord. If the data is handshake data, the data is read into the InputRecord's internal buffer. If the data is application data, the data is decoded directly into the dst buffer. In the case of an outbound record, when the write to the "real" OutputStream's would normally take place, instead we call back up to the EngineOutputRecord's version of writeBuffer, at which time we capture the resulting output in a ByteBuffer, and send that back to the EngineWriter for internal storage. EngineWriter is responsible for "handling" all outbound data, be it handshake or app data, and for returning the data to wrap() in the proper order. ClientHandshaker/ServerHandshaker/Handshaker: Methods which relied on SSLSocket now have work on either SSLSockets or SSLEngines.

Summary

Public Methods
void beginHandshake()
Initiates handshaking (initial or renegotiation) on this SSLEngine.
synchronized void closeInbound()
Signals that no more inbound network data will be sent to this SSLEngine.
synchronized void closeOutbound()
Signals that no more outbound application data will be sent on this SSLEngine.
synchronized Runnable getDelegatedTask()
Returns a delegated Runnable task for this SSLEngine.
synchronized boolean getEnableSessionCreation()
Returns true if new connections may cause creation of new SSL sessions.
synchronized String[] getEnabledCipherSuites()
Returns the names of the SSL cipher suites which are currently enabled for use on this connection.
synchronized String[] getEnabledProtocols()
Returns the names of the protocol versions which are currently enabled for use with this SSLEngine.
SSLEngineResult.HandshakeStatus getHandshakeStatus()
Returns the current handshake status for this SSLEngine.
synchronized String getHostnameVerification()
Returns the endpoint identification algorithm of the engine.
synchronized boolean getNeedClientAuth()
Returns true if the engine will require client authentication.
synchronized SSLSession getSession()
Returns the current SSLSession for this SSLEngine

These can be long lived, and frequently correspond to an entire login session for some user.

String[] getSupportedCipherSuites()
Returns the names of the cipher suites which could be enabled for use on an SSL connection.
String[] getSupportedProtocols()
Returns the protocols that are supported by this implementation.
synchronized boolean getUseClientMode()
Returns true if the engine is set to use client mode when handshaking.
synchronized boolean getWantClientAuth()
Returns true if the engine will request client authentication.
synchronized boolean isInboundDone()
Returns the network inbound data closure state
boolean isOutboundDone()
Returns the outbound application data closure state
synchronized void setEnableSessionCreation(boolean flag)
Controls whether new connections may cause creation of new SSL sessions.
synchronized void setEnabledCipherSuites(String[] suites)
Controls which particular cipher suites are enabled for use on this connection.
synchronized void setEnabledProtocols(String[] protocols)
Controls which protocols are enabled for use on this connection.
synchronized void setNeedClientAuth(boolean flag)
Sets the flag controlling whether a server mode engine *REQUIRES* SSL client authentication.
synchronized void setUseClientMode(boolean flag)
Sets the flag controlling whether the engine is in SSL client or server mode.
synchronized void setWantClientAuth(boolean flag)
Sets the flag controlling whether a server mode engine *REQUESTS* SSL client authentication.
String toString()
Returns a printable representation of this end of the connection.
synchronized boolean trySetHostnameVerification(String identificationAlgorithm)
Try to configure the endpoint identification algorithm of the engine.
SSLEngineResult unwrap(ByteBuffer netData, ByteBuffer[] appData, int offset, int length)
Unwraps a buffer.
SSLEngineResult wrap(ByteBuffer[] appData, int offset, int length, ByteBuffer netData)
Wraps a buffer.
[Expand]
Inherited Methods
From class javax.net.ssl.SSLEngine
From class java.lang.Object

Public Methods

public void beginHandshake ()

Initiates handshaking (initial or renegotiation) on this SSLEngine.

This method is not needed for the initial handshake, as the wrap() and unwrap() methods will implicitly call this method if handshaking has not already begun.

Note that the peer may also request a session renegotiation with this SSLEngine by sending the appropriate session renegotiate handshake message.

Unlike the SSLSocket#startHandshake() method, this method does not block until handshaking is completed.

To force a complete SSL/TLS session renegotiation, the current session should be invalidated prior to calling this method.

Some protocols may not support multiple handshakes on an existing engine and may throw an SSLException.

Throws
SSLException

public synchronized void closeInbound ()

Signals that no more inbound network data will be sent to this SSLEngine.

If the application initiated the closing process by calling closeOutbound(), under some circumstances it is not required that the initiator wait for the peer's corresponding close message. (See section 7.2.1 of the TLS specification (RFC 2246) for more information on waiting for closure alerts.) In such cases, this method need not be called.

But if the application did not initiate the closure process, or if the circumstances above do not apply, this method should be called whenever the end of the SSL/TLS data stream is reached. This ensures closure of the inbound side, and checks that the peer followed the SSL/TLS close procedure properly, thus detecting possible truncation attacks.

This method is idempotent: if the inbound side has already been closed, this method does not do anything.

wrap() should be called to flush any remaining handshake data.

Throws
SSLException

public synchronized void closeOutbound ()

Signals that no more outbound application data will be sent on this SSLEngine.

This method is idempotent: if the outbound side has already been closed, this method does not do anything.

wrap(ByteBuffer, ByteBuffer) should be called to flush any remaining handshake data.

public synchronized Runnable getDelegatedTask ()

Returns a delegated Runnable task for this SSLEngine.

Returns
  • a delegated Runnable task, or null if none are available.

public synchronized boolean getEnableSessionCreation ()

Returns true if new connections may cause creation of new SSL sessions.

Returns
  • true indicates that sessions may be created; this is the default. false indicates that an existing session must be resumed

public synchronized String[] getEnabledCipherSuites ()

Returns the names of the SSL cipher suites which are currently enabled for use on this connection. When an SSL engine is first created, all enabled cipher suites (a) protect data confidentiality, by traffic encryption, and (b) can mutually authenticate both clients and servers. Thus, in some environments, this value might be empty.

Returns
  • an array of cipher suite names

public synchronized String[] getEnabledProtocols ()

Returns the names of the protocol versions which are currently enabled for use with this SSLEngine.

Returns
  • an array of protocols

public SSLEngineResult.HandshakeStatus getHandshakeStatus ()

Returns the current handshake status for this SSLEngine.

Returns
  • the current SSLEngineResult.HandshakeStatus.

public synchronized String getHostnameVerification ()

Returns the endpoint identification algorithm of the engine.

public synchronized boolean getNeedClientAuth ()

Returns true if the engine will require client authentication. This option is only useful to engines in the server mode.

Returns
  • true if client authentication is required, or false if no client authentication is desired.

public synchronized SSLSession getSession ()

Returns the current SSLSession for this SSLEngine

These can be long lived, and frequently correspond to an entire login session for some user.

Returns
  • the SSLSession for this SSLEngine

public String[] getSupportedCipherSuites ()

Returns the names of the cipher suites which could be enabled for use on an SSL connection. Normally, only a subset of these will actually be enabled by default, since this list may include cipher suites which do not support the mutual authentication of servers and clients, or which do not protect data confidentiality. Servers may also need certain kinds of certificates to use certain cipher suites.

Returns
  • an array of cipher suite names

public String[] getSupportedProtocols ()

Returns the protocols that are supported by this implementation. A subset of the supported protocols may be enabled for this connection@ returns an array of protocol names.

Returns
  • an array of protocols supported

public synchronized boolean getUseClientMode ()

Returns true if the engine is set to use client mode when handshaking.

Returns
  • true if the engine should do handshaking in "client" mode

public synchronized boolean getWantClientAuth ()

Returns true if the engine will request client authentication. This option is only useful for engines in the server mode.

Returns
  • true if client authentication is requested, or false if no client authentication is desired.

public synchronized boolean isInboundDone ()

Returns the network inbound data closure state

Returns
  • true if the SSLEngine will not consume anymore network data (and by implication, will not produce any more application data.)

public boolean isOutboundDone ()

Returns the outbound application data closure state

Returns
  • true if the SSLEngine will not produce any more network data

public synchronized void setEnableSessionCreation (boolean flag)

Controls whether new connections may cause creation of new SSL sessions. As long as handshaking has not started, we can change whether we enable session creations. Otherwise, we will need to wait for the next handshake.

Parameters
flag true indicates that sessions may be created; this is the default. false indicates that an existing session must be resumed

public synchronized void setEnabledCipherSuites (String[] suites)

Controls which particular cipher suites are enabled for use on this connection. The cipher suites must have been listed by getCipherSuites() as being supported. Even if a suite has been enabled, it might never be used if no peer supports it or the requisite certificates (and private keys) are not available.

Parameters
suites Names of all the cipher suites to enable.

public synchronized void setEnabledProtocols (String[] protocols)

Controls which protocols are enabled for use on this connection. The protocols must have been listed by getSupportedProtocols() as being supported.

Parameters
protocols protocols to enable.
Throws
IllegalArgumentException when one of the protocols named by the parameter is not supported.

public synchronized void setNeedClientAuth (boolean flag)

Sets the flag controlling whether a server mode engine *REQUIRES* SSL client authentication. As long as handshaking has not started, we can change whether client authentication is needed. Otherwise, we will need to wait for the next handshake.

Parameters
flag set to true if client authentication is required, or false if no client authentication is desired.

public synchronized void setUseClientMode (boolean flag)

Sets the flag controlling whether the engine is in SSL client or server mode. Must be called before any SSL traffic has started.

Parameters
flag true if the engine should start its handshaking in "client" mode

public synchronized void setWantClientAuth (boolean flag)

Sets the flag controlling whether a server mode engine *REQUESTS* SSL client authentication. As long as handshaking has not started, we can change whether client authentication is requested. Otherwise, we will need to wait for the next handshake.

Parameters
flag set to true if client authentication is requested, or false if no client authentication is desired.

public String toString ()

Returns a printable representation of this end of the connection.

Returns
  • a string representation of the object.

public synchronized boolean trySetHostnameVerification (String identificationAlgorithm)

Try to configure the endpoint identification algorithm of the engine.

Parameters
identificationAlgorithm the algorithm used to check the endpoint identity.
Returns
  • true if the identification algorithm configuration success.

public SSLEngineResult unwrap (ByteBuffer netData, ByteBuffer[] appData, int offset, int length)

Unwraps a buffer. Does a variety of checks before grabbing the unwrapLock, which blocks multiple unwraps from occuring.

Parameters
netData a ByteBuffer containing inbound network data.
appData an array of ByteBuffers to hold inbound application data.
offset The offset within the buffer array of the first buffer from which bytes are to be transferred; it must be non-negative and no larger than dsts.length.
length The maximum number of buffers to be accessed; it must be non-negative and no larger than dsts.length - offset.
Returns
  • an SSLEngineResult describing the result of this operation.
Throws
SSLException

public SSLEngineResult wrap (ByteBuffer[] appData, int offset, int length, ByteBuffer netData)

Wraps a buffer. Does a variety of checks before grabbing the wrapLock, which blocks multiple wraps from occuring.

Parameters
appData an array of ByteBuffers containing the outbound application data
offset The offset within the buffer array of the first buffer from which bytes are to be retrieved; it must be non-negative and no larger than srcs.length
length The maximum number of buffers to be accessed; it must be non-negative and no larger than srcs.length - offset
netData a ByteBuffer to hold outbound network data
Returns
  • an SSLEngineResult describing the result of this operation.
Throws
SSLException