Class SslConnection
- java.lang.Object
-
- org.eclipse.jetty.io.AbstractConnection
-
- org.eclipse.jetty.io.ssl.SslConnection
-
- All Implemented Interfaces:
java.io.Closeable
,java.lang.AutoCloseable
,Connection
,Connection.UpgradeTo
public class SslConnection extends AbstractConnection implements Connection.UpgradeTo
A Connection that acts as an interceptor between an EndPoint providing SSL encrypted data and another consumer of an EndPoint (typically anConnection
like HttpConnection) that wants unencrypted data.The connector uses an
EndPoint
(typically SocketChannelEndPoint) as it's source/sink of encrypted data. It then provides an endpoint viagetDecryptedEndPoint()
to expose a source/sink of unencrypted data to another connection (eg HttpConnection).The design of this class is based on a clear separation between the passive methods, which do not block nor schedule any asynchronous callbacks, and active methods that do schedule asynchronous callbacks.
The passive methods are
SslConnection.DecryptedEndPoint.fill(ByteBuffer)
andSslConnection.DecryptedEndPoint.flush(ByteBuffer...)
. They make best effort attempts to progress the connection using only calls to the encryptedEndPoint.fill(ByteBuffer)
andEndPoint.flush(ByteBuffer...)
methods. They will never block nor schedule any readInterest or write callbacks. If a fill/flush cannot progress either because of network congestion or waiting for an SSL handshake message, then the fill/flush will simply return with zero bytes filled/flushed. Specifically, if a flush cannot proceed because it needs to receive a handshake message, then the flush will attempt to fill bytes from the encrypted endpoint, but if insufficient bytes are read it will NOT callEndPoint.fillInterested(Callback)
.It is only the active methods :
AbstractEndPoint.fillInterested(Callback)
andAbstractEndPoint.write(Callback, ByteBuffer...)
that may schedule callbacks by calling the encryptedEndPoint.fillInterested(Callback)
andEndPoint.write(Callback, ByteBuffer...)
methods. For normal data handling, the decrypted fillInterest method will result in an encrypted fillInterest and a decrypted write will result in an encrypted write. However, due to SSL handshaking requirements, it is also possible for a decrypted fill to call the encrypted write and for the decrypted flush to call the encrypted fillInterested methods.MOST IMPORTANTLY, the encrypted callbacks from the active methods (#onFillable() and WriteFlusher#completeWrite()) do no filling or flushing themselves. Instead they simple make the callbacks to the decrypted callbacks, so that the passive encrypted fill/flush will be called again and make another best effort attempt to progress the connection.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description class
SslConnection.DecryptedEndPoint
private static class
SslConnection.FillState
private static class
SslConnection.FlushState
private static class
SslConnection.HandshakeState
private class
SslConnection.RunnableTask
-
Nested classes/interfaces inherited from interface org.eclipse.jetty.io.Connection
Connection.Listener, Connection.UpgradeFrom, Connection.UpgradeTo
-
-
Field Summary
Fields Modifier and Type Field Description private ByteBufferPool
_bufferPool
private boolean
_closedOutbound
private boolean
_decryptedDirectBuffers
private SslConnection.DecryptedEndPoint
_decryptedEndPoint
private java.nio.ByteBuffer
_decryptedInput
private boolean
_encryptedDirectBuffers
private java.nio.ByteBuffer
_encryptedInput
private java.nio.ByteBuffer
_encryptedOutput
private SslConnection.FillState
_fillState
private SslConnection.FlushState
_flushState
private java.util.concurrent.atomic.AtomicReference<SslConnection.HandshakeState>
_handshake
private boolean
_renegotiationAllowed
private int
_renegotiationLimit
private boolean
_requireCloseMessage
private java.lang.Runnable
_runFillable
private javax.net.ssl.SSLEngine
_sslEngine
private Callback
_sslReadCallback
private boolean
_underflown
private java.util.List<SslHandshakeListener>
handshakeListeners
private static Logger
LOG
private static java.lang.String
TLS_1_3
-
Constructor Summary
Constructors Constructor Description SslConnection(ByteBufferPool byteBufferPool, java.util.concurrent.Executor executor, EndPoint endPoint, javax.net.ssl.SSLEngine sslEngine)
SslConnection(ByteBufferPool byteBufferPool, java.util.concurrent.Executor executor, EndPoint endPoint, javax.net.ssl.SSLEngine sslEngine, boolean useDirectBuffersForEncryption, boolean useDirectBuffersForDecryption)
-
Method Summary
All Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description private void
acquireEncryptedInput()
private void
acquireEncryptedOutput()
void
addHandshakeListener(SslHandshakeListener listener)
void
close()
Performs a logical close of this connection.private int
getApplicationBufferSize()
private int
getBufferSize(java.util.function.ToIntFunction<javax.net.ssl.SSLSession> bufferSizeFn)
SslConnection.DecryptedEndPoint
getDecryptedEndPoint()
private int
getPacketBufferSize()
int
getRenegotiationLimit()
javax.net.ssl.SSLEngine
getSSLEngine()
boolean
isAllowMissingCloseMessage()
Deprecated.use invertedisRequireCloseMessage()
insteadprivate boolean
isHandshakeComplete()
private boolean
isHandshakeInitial()
private boolean
isHandshakeSucceeded()
boolean
isRenegotiationAllowed()
boolean
isRequireCloseMessage()
protected int
networkFill(java.nio.ByteBuffer input)
protected boolean
networkFlush(java.nio.ByteBuffer output)
protected SslConnection.DecryptedEndPoint
newDecryptedEndPoint()
void
onClose()
Callback method invoked when this connection is closed.void
onFillable()
Callback method invoked when the endpoint is ready to be read.void
onFillInterestedFailed(java.lang.Throwable cause)
Callback method invoked when the endpoint failed to be ready to be read.boolean
onIdleExpired()
Callback method invoked upon an idle timeout event.void
onOpen()
Callback method invoked when this connection is opened.void
onUpgradeTo(java.nio.ByteBuffer buffer)
Invoked during anupgrade
to receive a buffer containing bytes that have not been consumed by the upgrade-from connection, and that must be consumed by this connection.protected void
releaseDecryptedInputBuffer()
private void
releaseEncryptedInputBuffer()
private void
releaseEncryptedOutputBuffer()
boolean
removeHandshakeListener(SslHandshakeListener listener)
void
setAllowMissingCloseMessage(boolean allowMissingCloseMessage)
Deprecated.use invertedsetRequireCloseMessage(boolean)
insteadvoid
setRenegotiationAllowed(boolean renegotiationAllowed)
void
setRenegotiationLimit(int renegotiationLimit)
void
setRequireCloseMessage(boolean requireCloseMessage)
Sets whether it is required that a peer send the TLSclose_notify
message to indicate the will to close the connection, otherwise it may be interpreted as a truncation attack.java.lang.String
toConnectionString()
protected javax.net.ssl.SSLEngineResult
unwrap(javax.net.ssl.SSLEngine sslEngine, java.nio.ByteBuffer input, java.nio.ByteBuffer output)
protected javax.net.ssl.SSLEngineResult
wrap(javax.net.ssl.SSLEngine sslEngine, java.nio.ByteBuffer[] input, java.nio.ByteBuffer output)
-
Methods inherited from class org.eclipse.jetty.io.AbstractConnection
addListener, failedCallback, fillInterested, getBytesIn, getBytesOut, getCreatedTimeStamp, getEndPoint, getExecutor, getInputBufferSize, getMessagesIn, getMessagesOut, isFillInterested, onReadTimeout, removeListener, setInputBufferSize, toString, tryFillInterested, tryFillInterested
-
-
-
-
Field Detail
-
LOG
private static final Logger LOG
-
TLS_1_3
private static final java.lang.String TLS_1_3
- See Also:
- Constant Field Values
-
handshakeListeners
private final java.util.List<SslHandshakeListener> handshakeListeners
-
_bufferPool
private final ByteBufferPool _bufferPool
-
_sslEngine
private final javax.net.ssl.SSLEngine _sslEngine
-
_decryptedEndPoint
private final SslConnection.DecryptedEndPoint _decryptedEndPoint
-
_decryptedInput
private java.nio.ByteBuffer _decryptedInput
-
_encryptedInput
private java.nio.ByteBuffer _encryptedInput
-
_encryptedOutput
private java.nio.ByteBuffer _encryptedOutput
-
_encryptedDirectBuffers
private final boolean _encryptedDirectBuffers
-
_decryptedDirectBuffers
private final boolean _decryptedDirectBuffers
-
_renegotiationAllowed
private boolean _renegotiationAllowed
-
_renegotiationLimit
private int _renegotiationLimit
-
_closedOutbound
private boolean _closedOutbound
-
_requireCloseMessage
private boolean _requireCloseMessage
-
_flushState
private SslConnection.FlushState _flushState
-
_fillState
private SslConnection.FillState _fillState
-
_handshake
private java.util.concurrent.atomic.AtomicReference<SslConnection.HandshakeState> _handshake
-
_underflown
private boolean _underflown
-
_runFillable
private final java.lang.Runnable _runFillable
-
_sslReadCallback
private final Callback _sslReadCallback
-
-
Constructor Detail
-
SslConnection
public SslConnection(ByteBufferPool byteBufferPool, java.util.concurrent.Executor executor, EndPoint endPoint, javax.net.ssl.SSLEngine sslEngine)
-
SslConnection
public SslConnection(ByteBufferPool byteBufferPool, java.util.concurrent.Executor executor, EndPoint endPoint, javax.net.ssl.SSLEngine sslEngine, boolean useDirectBuffersForEncryption, boolean useDirectBuffersForDecryption)
-
-
Method Detail
-
addHandshakeListener
public void addHandshakeListener(SslHandshakeListener listener)
-
removeHandshakeListener
public boolean removeHandshakeListener(SslHandshakeListener listener)
-
newDecryptedEndPoint
protected SslConnection.DecryptedEndPoint newDecryptedEndPoint()
-
getSSLEngine
public javax.net.ssl.SSLEngine getSSLEngine()
-
getDecryptedEndPoint
public SslConnection.DecryptedEndPoint getDecryptedEndPoint()
-
isRenegotiationAllowed
public boolean isRenegotiationAllowed()
-
setRenegotiationAllowed
public void setRenegotiationAllowed(boolean renegotiationAllowed)
-
getRenegotiationLimit
public int getRenegotiationLimit()
- Returns:
- The number of renegotiations allowed for this connection. When the limit is 0 renegotiation will be denied. If the limit is less than 0 then no limit is applied.
-
setRenegotiationLimit
public void setRenegotiationLimit(int renegotiationLimit)
- Parameters:
renegotiationLimit
- The number of renegotiations allowed for this connection. When the limit is 0 renegotiation will be denied. If the limit is less than 0 then no limit is applied. Default -1.
-
isAllowMissingCloseMessage
@Deprecated public boolean isAllowMissingCloseMessage()
Deprecated.use invertedisRequireCloseMessage()
instead- Returns:
- whether is not required that peers send the TLS
close_notify
message
-
setAllowMissingCloseMessage
@Deprecated public void setAllowMissingCloseMessage(boolean allowMissingCloseMessage)
Deprecated.use invertedsetRequireCloseMessage(boolean)
instead- Parameters:
allowMissingCloseMessage
- whether is not required that peers send the TLSclose_notify
message
-
isRequireCloseMessage
public boolean isRequireCloseMessage()
- Returns:
- whether peers must send the TLS
close_notify
message
-
setRequireCloseMessage
public void setRequireCloseMessage(boolean requireCloseMessage)
Sets whether it is required that a peer send the TLS
close_notify
message to indicate the will to close the connection, otherwise it may be interpreted as a truncation attack.This option is only useful on clients, since typically servers cannot accept connection-delimited content that may be truncated.
- Parameters:
requireCloseMessage
- whether peers must send the TLSclose_notify
message
-
isHandshakeInitial
private boolean isHandshakeInitial()
-
isHandshakeSucceeded
private boolean isHandshakeSucceeded()
-
isHandshakeComplete
private boolean isHandshakeComplete()
-
getApplicationBufferSize
private int getApplicationBufferSize()
-
getPacketBufferSize
private int getPacketBufferSize()
-
getBufferSize
private int getBufferSize(java.util.function.ToIntFunction<javax.net.ssl.SSLSession> bufferSizeFn)
-
acquireEncryptedInput
private void acquireEncryptedInput()
-
acquireEncryptedOutput
private void acquireEncryptedOutput()
-
onUpgradeTo
public void onUpgradeTo(java.nio.ByteBuffer buffer)
Description copied from interface:Connection.UpgradeTo
Invoked during an
upgrade
to receive a buffer containing bytes that have not been consumed by the upgrade-from connection, and that must be consumed by this connection.- Specified by:
onUpgradeTo
in interfaceConnection.UpgradeTo
- Parameters:
buffer
- a non-null buffer of unconsumed bytes received from the upgrade-from connection. The buffer does not belong to any pool and should be discarded after having consumed its bytes.
-
onOpen
public void onOpen()
Description copied from interface:Connection
Callback method invoked when this connection is opened.
Creators of the connection implementation are responsible for calling this method.
- Specified by:
onOpen
in interfaceConnection
- Overrides:
onOpen
in classAbstractConnection
-
onClose
public void onClose()
Description copied from interface:Connection
Callback method invoked when this connection is closed.
Creators of the connection implementation are responsible for calling this method.
- Specified by:
onClose
in interfaceConnection
- Overrides:
onClose
in classAbstractConnection
-
close
public void close()
Description copied from interface:Connection
Performs a logical close of this connection.
For simple connections, this may just mean to delegate the close to the associated
EndPoint
but, for example, SSL connections should write the SSL close message before closing the associatedEndPoint
.- Specified by:
close
in interfacejava.lang.AutoCloseable
- Specified by:
close
in interfacejava.io.Closeable
- Specified by:
close
in interfaceConnection
- Overrides:
close
in classAbstractConnection
-
onIdleExpired
public boolean onIdleExpired()
Description copied from interface:Connection
Callback method invoked upon an idle timeout event.
Implementations of this method may return true to indicate that the idle timeout handling should proceed normally, typically failing the EndPoint and causing it to be closed.
When false is returned, the handling of the idle timeout event is halted immediately and the EndPoint left in the state it was before the idle timeout event.
- Specified by:
onIdleExpired
in interfaceConnection
- Overrides:
onIdleExpired
in classAbstractConnection
- Returns:
- true to let the EndPoint handle the idle timeout, false to tell the EndPoint to halt the handling of the idle timeout.
-
onFillable
public void onFillable()
Description copied from class:AbstractConnection
Callback method invoked when the endpoint is ready to be read.
- Specified by:
onFillable
in classAbstractConnection
- See Also:
AbstractConnection.fillInterested()
-
onFillInterestedFailed
public void onFillInterestedFailed(java.lang.Throwable cause)
Description copied from class:AbstractConnection
Callback method invoked when the endpoint failed to be ready to be read.
- Overrides:
onFillInterestedFailed
in classAbstractConnection
- Parameters:
cause
- the exception that caused the failure
-
wrap
protected javax.net.ssl.SSLEngineResult wrap(javax.net.ssl.SSLEngine sslEngine, java.nio.ByteBuffer[] input, java.nio.ByteBuffer output) throws javax.net.ssl.SSLException
- Throws:
javax.net.ssl.SSLException
-
unwrap
protected javax.net.ssl.SSLEngineResult unwrap(javax.net.ssl.SSLEngine sslEngine, java.nio.ByteBuffer input, java.nio.ByteBuffer output) throws javax.net.ssl.SSLException
- Throws:
javax.net.ssl.SSLException
-
toConnectionString
public java.lang.String toConnectionString()
- Overrides:
toConnectionString
in classAbstractConnection
-
releaseEncryptedInputBuffer
private void releaseEncryptedInputBuffer()
-
releaseDecryptedInputBuffer
protected void releaseDecryptedInputBuffer()
-
releaseEncryptedOutputBuffer
private void releaseEncryptedOutputBuffer()
-
networkFill
protected int networkFill(java.nio.ByteBuffer input) throws java.io.IOException
- Throws:
java.io.IOException
-
networkFlush
protected boolean networkFlush(java.nio.ByteBuffer output) throws java.io.IOException
- Throws:
java.io.IOException
-
-