This class performs SSL handshaking,
encryption and decryption, but does not send or receive messages over
the network. This leaves the network transport mechanism up to the
user of this class, and enables SSL communication using the
nonblocking I/O mechanisms of the
java.nio package. The price of this flexibility is
that your code must follow a relatively complex protocol to use an
SSLEngine correctly.
Create an SSLEngine with
SSLContext.createSSLEngine(
). Next, configure it with the
various setter methods to specify authentication requirements,
encryption algorithms, etc. After creating and configuring an engine,
you use it to encrypt outbound data from one
ByteBuffer to another with wrap(
) and to decrypt inbound data from
one byte buffer to another with unwrap( ). (Note
that the wrap( ) and unwrap( )
methods also come in gathering and scattering variants.) Both methods
return an SSLEngineResult.
The initial call or calls to wrap( ) produce
outbound handshaking data without consuming any of the source bytes
in the buffer you provide. Initial calls to unwrap(
) may consume inbound handshaking data without producing
any result bytes. Monitor the
SSLEngineResult.HandshakeStatus value to ensure
that handshaking is proceeding as needed. When handshaking is
complete, you can call getSession( ) to obtain the
SSLSession object that describes session details
negotiated during handshaking. Remember that either peer of an SSL
connection may request a new handshake at any time; this means that
you must monitor the HandshakeStatus after every
wrap( ) or unwrap( ) call in
case a new handshake has been requested. You can request a new
handshake yourself with beginHandshake( ).
As part of the handshaking protocol, the SSLEngine
typically needs to use the KeyManager or
trustManager of the originating
SSLContext object. Rather than blocking a
wrap( ) or unwrap( ) method
while these operations are performed, it instead returns an
SSLResult.HandshakeStatus, indicating that a task
needs to be performed. When this happens, you must call
geTDelegatedTask(
) repeatedly, calling the run(
) methods of the Runnable objects it
returns until it returns null to indicate that all
necessary tasks have been completed. (If it returns more than one
Runnable, it is safe to run them in parallel (with
a java.util.concurrent.ExecutorCompletionService,
for example). Once all such tasks have been run, the original call to
wrap( ) or unwrap( ) should be
repeated.
When you are done sending outbound data, call closeOutbound(
), and then call wrap( ) one
or more times to flush any remaining data from the engine. Call
wrap( ) until the returned
SSLEngineResult.Status indicates that the
connection has closed. Similarly, if you are done reading inbound
data, call closeInbound(
)
and final calls to unwrap( ) until the connection
is closed.
It is safe for one thread to call wrap( ) while
another thread is calling unwrap( ). It is not
safe, however, for either method to be called by two threads at once.
public abstract class SSLEngine {
// Protected Constructors
protected SSLEngine( );
protected SSLEngine(String peerHost, int peerPort);
// Public Instance Methods
public abstract void beginHandshake( ) throws SSLException;
public abstract void closeInbound( ) throws SSLException;
public abstract void closeOutbound( );
public abstract Runnable getDelegatedTask( );
public abstract String[ ] getEnabledCipherSuites( );
public abstract String[ ] getEnabledProtocols( );
public abstract boolean getEnableSessionCreation( );
public abstract SSLEngineResult.HandshakeStatus getHandshakeStatus( );
public abstract boolean getNeedClientAuth( );
public String getPeerHost( );
public int getPeerPort( );
public abstract SSLSession getSession( );
public abstract String[ ] getSupportedCipherSuites( );
public abstract String[ ] getSupportedProtocols( );
public abstract boolean getUseClientMode( );
public abstract boolean getWantClientAuth( );
public abstract boolean isInboundDone( );
public abstract boolean isOutboundDone( );
public abstract void setEnabledCipherSuites(String[ ] suites);
public abstract void setEnabledProtocols(String[ ] protocols);
public abstract void setEnableSessionCreation(boolean flag);
public abstract void setNeedClientAuth(boolean need);
public abstract void setUseClientMode(boolean mode);
public abstract void setWantClientAuth(boolean want);
public SSLEngineResult unwrap(java.nio.ByteBuffer src, java.nio.
ByteBuffer dst) throws SSLException;
public SSLEngineResult unwrap(java.nio.ByteBuffer src, java.nio.
ByteBuffer[ ] dsts) throws SSLException;
public abstract SSLEngineResult unwrap(java.nio.ByteBuffer src,
java.nio.ByteBuffer[ ] dsts, int offset,
int length) throws SSLException;
public SSLEngineResult wrap(java.nio.ByteBuffer[ ] srcs, java.nio.
ByteBuffer dst) throws SSLException;
public SSLEngineResult wrap(java.nio.ByteBuffer src, java.nio.
ByteBuffer dst) throws SSLException;
public abstract SSLEngineResult wrap(java.nio.ByteBuffer[ ] srcs,
int offset, int length,
java.nio.ByteBuffer dst) throws SSLException;
}