Package org.apache.mina.filter.ssl
Class SslFilter
- java.lang.Object
-
- org.apache.mina.core.filterchain.IoFilterAdapter
-
- org.apache.mina.filter.ssl.SslFilter
-
- All Implemented Interfaces:
IoFilter
public class SslFilter extends IoFilterAdapter
An SSL filter that encrypts and decrypts the data exchanged in the session. Adding this filter triggers SSL handshake procedure immediately by sending a SSL 'hello' message, so you don't need to callstartSsl(IoSession)manually unless you are implementing StartTLS (see below). If you don't want the handshake procedure to start immediately, please specifyfalseasautoStartparameter in the constructor.This filter uses an
SSLEnginewhich was introduced in Java 5, so Java version 5 or above is mandatory to use this filter. And please note that this filter only works for TCP/IP connections.Implementing StartTLS
You can use
DISABLE_ENCRYPTION_ONCEattribute to implement StartTLS:public void messageReceived(IoSession session, Object message) { if (message instanceof MyStartTLSRequest) { // Insert SSLFilter to get ready for handshaking session.getFilterChain().addFirst(sslFilter); // Disable encryption temporarily. // This attribute will be removed by SSLFilter // inside the Session.write() call below. session.setAttribute(SSLFilter.DISABLE_ENCRYPTION_ONCE, Boolean.TRUE); // Write StartTLSResponse which won't be encrypted. session.write(new MyStartTLSResponse(OK)); // Now DISABLE_ENCRYPTION_ONCE attribute is cleared. assert session.getAttribute(SSLFilter.DISABLE_ENCRYPTION_ONCE) == null; } }
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description (package private) static classSslFilter.EncryptedWriteRequestA private class used to store encrypted messages.static classSslFilter.SslFilterMessageA message that is sent fromSslFilterwhen the connection became secure or is not secure anymore.-
Nested classes/interfaces inherited from interface org.apache.mina.core.filterchain.IoFilter
IoFilter.NextFilter
-
-
Field Summary
Fields Modifier and Type Field Description private booleanautoStartA flag used to tell the filter to start the handshake immediatelyprivate booleanclientstatic booleanCLIENT_HANDSHAKEA flag used to determinate if the handshake should wait for the client to initiate the handshakestatic AttributeKeyDISABLE_ENCRYPTION_ONCEA session attribute key that makes next one write request bypass this filter (not encrypting the data).private java.lang.String[]enabledCipherSuitesprivate java.lang.String[]enabledProtocolsprivate java.lang.StringidentificationAlgorithmprivate static org.slf4j.LoggerLOGGERThe loggerprivate booleanneedClientAuthprivate static AttributeKeyNEXT_FILTERAn attribute containing the next filterstatic AttributeKeyPEER_ADDRESSA session attribute key that should be set to anInetSocketAddress.private static AttributeKeySSL_HANDLERstatic AttributeKeySSL_SESSIONA session attribute key that stores underlyingSSLSessionfor each session.(package private) javax.net.ssl.SSLContextsslContextThe SslContext usedstatic booleanSTART_HANDSHAKEA flag used to determinate if the handshake should start immediatelystatic AttributeKeyUSE_NOTIFICATIONA session attribute key that makes this filter to emit aIoHandler.messageReceived(IoSession, Object)event with a special message (SslEvent.SECUREDorSslEvent.UNSECURED).private booleanwantClientAuth
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description voidexceptionCaught(IoFilter.NextFilter nextFilter, IoSession session, java.lang.Throwable cause)FiltersIoHandler.exceptionCaught(IoSession,Throwable)event.voidfilterClose(IoFilter.NextFilter nextFilter, IoSession session)FiltersIoSession.closeNow()or aIoSession.closeOnFlush()method invocations.voidfilterWrite(IoFilter.NextFilter nextFilter, IoSession session, WriteRequest writeRequest)FiltersIoSession.write(Object)method invocation.java.lang.String[]getEnabledCipherSuites()java.lang.String[]getEnabledProtocols()java.lang.StringgetEndpointIdentificationAlgorithm()(package private) java.lang.StringgetSessionInfo(IoSession session)An extended toString() method for sessions.javax.net.ssl.SSLSessiongetSslSession(IoSession session)Returns the underlyingSSLSessionfor the specified session.private SslHandlergetSslSessionHandler(IoSession session)private voidhandleAppDataRead(IoFilter.NextFilter nextFilter, SslHandler sslHandler)private voidhandleSslData(IoFilter.NextFilter nextFilter, SslHandler sslHandler)private WriteFutureinitiateClosure(IoFilter.NextFilter nextFilter, IoSession session)private voidinitiateHandshake(IoFilter.NextFilter nextFilter, IoSession session)voidinitiateHandshake(IoSession session)Initiate the SSL handshake.private booleanisCloseNotify(java.lang.Object message)booleanisNeedClientAuth()booleanisSecured(IoSession session)booleanisSslStarted(IoSession session)booleanisUseClientMode()booleanisWantClientAuth()voidmessageReceived(IoFilter.NextFilter nextFilter, IoSession session, java.lang.Object message)FiltersIoHandler.messageReceived(IoSession,Object)event.voidmessageSent(IoFilter.NextFilter nextFilter, IoSession session, WriteRequest writeRequest)FiltersIoHandler.messageSent(IoSession,Object)event.voidonPostAdd(IoFilterChain parent, java.lang.String name, IoFilter.NextFilter nextFilter)Invoked after this filter is added to the specifiedparent.voidonPreAdd(IoFilterChain parent, java.lang.String name, IoFilter.NextFilter nextFilter)Executed just before the filter is added into the chain, we do : check that we don't have a SSL filter already present we update the next filter we create the SSL handler helper class and we store it into the session's AttributesvoidonPreRemove(IoFilterChain parent, java.lang.String name, IoFilter.NextFilter nextFilter)Invoked before this filter is removed from the specifiedparent.voidsessionClosed(IoFilter.NextFilter nextFilter, IoSession session)FiltersIoHandler.sessionClosed(IoSession)event.voidsetEnabledCipherSuites(java.lang.String[] cipherSuites)Sets the list of cipher suites to be enabled whenSSLEngineis initialized.voidsetEnabledProtocols(java.lang.String[] protocols)Sets the list of protocols to be enabled whenSSLEngineis initialized.voidsetEndpointIdentificationAlgorithm(java.lang.String identificationAlgorithm)Sets the endpoint identification algorithm to be used whenSSLEngineis initialized.voidsetNeedClientAuth(boolean needClientAuth)Configures the engine to require client authentication.voidsetUseClientMode(boolean clientMode)Configures the engine to use client (or server) mode when handshaking.voidsetWantClientAuth(boolean wantClientAuth)Configures the engine to request client authentication.booleanstartSsl(IoSession session)(Re)starts SSL session for the specifiedsessionif not started yet.WriteFuturestopSsl(IoSession session)Stops the SSL session by sending TLSclose_notifymessage to initiate TLS closure.-
Methods inherited from class org.apache.mina.core.filterchain.IoFilterAdapter
destroy, event, init, inputClosed, onPostRemove, sessionCreated, sessionIdle, sessionOpened, toString
-
-
-
-
Field Detail
-
LOGGER
private static final org.slf4j.Logger LOGGER
The logger
-
SSL_SESSION
public static final AttributeKey SSL_SESSION
A session attribute key that stores underlyingSSLSessionfor each session.
-
DISABLE_ENCRYPTION_ONCE
public static final AttributeKey DISABLE_ENCRYPTION_ONCE
A session attribute key that makes next one write request bypass this filter (not encrypting the data). This is a marker attribute, which means that you can put whatever as its value. (Boolean.TRUEis preferred.) The attribute is automatically removed from the session attribute map as soon asIoSession.write(Object)is invoked, and therefore should be put again if you want to make more messages bypass this filter. This is especially useful when you implement StartTLS.
-
USE_NOTIFICATION
public static final AttributeKey USE_NOTIFICATION
A session attribute key that makes this filter to emit aIoHandler.messageReceived(IoSession, Object)event with a special message (SslEvent.SECUREDorSslEvent.UNSECURED). This is a marker attribute, which means that you can put whatever as its value. (Boolean.TRUEis preferred.) By default, this filter doesn't emit any events related with SSL session flow control.
-
PEER_ADDRESS
public static final AttributeKey PEER_ADDRESS
A session attribute key that should be set to anInetSocketAddress. Setting this attribute causesSSLContext.createSSLEngine(String, int)to be called passing the hostname and port of theInetSocketAddressto get anSSLEngineinstance. If not setSSLContext.createSSLEngine()will be called.
Using this featureSSLSessionobjects may be cached and reused when in client mode.- See Also:
SSLContext.createSSLEngine(String, int)
-
NEXT_FILTER
private static final AttributeKey NEXT_FILTER
An attribute containing the next filter
-
SSL_HANDLER
private static final AttributeKey SSL_HANDLER
-
sslContext
final javax.net.ssl.SSLContext sslContext
The SslContext used
-
autoStart
private final boolean autoStart
A flag used to tell the filter to start the handshake immediately
-
START_HANDSHAKE
public static final boolean START_HANDSHAKE
A flag used to determinate if the handshake should start immediately- See Also:
- Constant Field Values
-
CLIENT_HANDSHAKE
public static final boolean CLIENT_HANDSHAKE
A flag used to determinate if the handshake should wait for the client to initiate the handshake- See Also:
- Constant Field Values
-
client
private boolean client
-
needClientAuth
private boolean needClientAuth
-
wantClientAuth
private boolean wantClientAuth
-
identificationAlgorithm
private java.lang.String identificationAlgorithm
-
enabledCipherSuites
private java.lang.String[] enabledCipherSuites
-
enabledProtocols
private java.lang.String[] enabledProtocols
-
-
Constructor Detail
-
SslFilter
public SslFilter(javax.net.ssl.SSLContext sslContext)
Creates a new SSL filter using the specifiedSSLContext. The handshake will start immediately after the filter has been added to the chain.- Parameters:
sslContext- The SSLContext to use
-
SslFilter
public SslFilter(javax.net.ssl.SSLContext sslContext, boolean autoStart)Creates a new SSL filter using the specifiedSSLContext. If theautostartflag is set totrue, the handshake will start immediately after the filter has been added to the chain.- Parameters:
sslContext- The SSLContext to useautoStart- The flag used to tell the filter to start the handshake immediately
-
-
Method Detail
-
getSslSession
public javax.net.ssl.SSLSession getSslSession(IoSession session)
Returns the underlyingSSLSessionfor the specified session.- Parameters:
session- The current session- Returns:
nullif noSSLSessionis initialized yet.
-
startSsl
public boolean startSsl(IoSession session) throws javax.net.ssl.SSLException
(Re)starts SSL session for the specifiedsessionif not started yet. Please note that SSL session is automatically started by default, and therefore you don't need to call this method unless you've used TLS closure.- Parameters:
session- The session that will be switched to SSL mode- Returns:
trueif the SSL session has been started,falseif already started.- Throws:
javax.net.ssl.SSLException- if failed to start the SSL session
-
getSessionInfo
java.lang.String getSessionInfo(IoSession session)
An extended toString() method for sessions. If the SSL handshake is not yet completed, we will print (ssl) in small caps. Once it's completed, we will use SSL capitalized.
-
isSslStarted
public boolean isSslStarted(IoSession session)
- Parameters:
session- the session we want to check- Returns:
trueif and only if the specifiedsessionis encrypted/decrypted over SSL/TLS currently. This method will start to returnfalseafter TLSclose_notifymessage is sent and any messages written after then is not going to get encrypted.
-
isSecured
public boolean isSecured(IoSession session)
- Parameters:
session- the session we want to check- Returns:
trueif and only if the conditions forisSslStarted(IoSession)are met, and the handhake has completed.
-
stopSsl
public WriteFuture stopSsl(IoSession session) throws javax.net.ssl.SSLException
Stops the SSL session by sending TLSclose_notifymessage to initiate TLS closure.- Parameters:
session- theIoSessionto initiate TLS closure- Returns:
- The Future for the initiated closure
- Throws:
javax.net.ssl.SSLException- if failed to initiate TLS closure
-
isUseClientMode
public boolean isUseClientMode()
- Returns:
trueif the engine is set to use client mode when handshaking.
-
setUseClientMode
public void setUseClientMode(boolean clientMode)
Configures the engine to use client (or server) mode when handshaking.- Parameters:
clientMode-truewhen we are in client mode,falsewhen in server mode
-
isNeedClientAuth
public boolean isNeedClientAuth()
- Returns:
trueif the engine will require client authentication. This option is only useful to engines in the server mode.
-
setNeedClientAuth
public void setNeedClientAuth(boolean needClientAuth)
Configures the engine to require client authentication. This option is only useful for engines in the server mode.- Parameters:
needClientAuth- A flag set when we need to authenticate the client
-
isWantClientAuth
public boolean isWantClientAuth()
- Returns:
trueif the engine will request client authentication. This option is only useful to engines in the server mode.
-
setWantClientAuth
public void setWantClientAuth(boolean wantClientAuth)
Configures the engine to request client authentication. This option is only useful for engines in the server mode.- Parameters:
wantClientAuth- A flag set when we want to check the client authentication
-
getEndpointIdentificationAlgorithm
public java.lang.String getEndpointIdentificationAlgorithm()
- Returns:
- the endpoint identification algorithm to be used when
SSLEngineis initialized.nullmeans 'useSSLEngine's default.'
-
setEndpointIdentificationAlgorithm
public void setEndpointIdentificationAlgorithm(java.lang.String identificationAlgorithm)
Sets the endpoint identification algorithm to be used whenSSLEngineis initialized.- Parameters:
identificationAlgorithm-nullmeans 'useSSLEngine's default.'
-
getEnabledCipherSuites
public java.lang.String[] getEnabledCipherSuites()
- Returns:
- the list of cipher suites to be enabled when
SSLEngineis initialized.nullmeans 'useSSLEngine's default.'
-
setEnabledCipherSuites
public void setEnabledCipherSuites(java.lang.String[] cipherSuites)
Sets the list of cipher suites to be enabled whenSSLEngineis initialized.- Parameters:
cipherSuites-nullmeans 'useSSLEngine's default.'
-
getEnabledProtocols
public java.lang.String[] getEnabledProtocols()
- Returns:
- the list of protocols to be enabled when
SSLEngineis initialized.nullmeans 'useSSLEngine's default.'
-
setEnabledProtocols
public void setEnabledProtocols(java.lang.String[] protocols)
Sets the list of protocols to be enabled whenSSLEngineis initialized.- Parameters:
protocols-nullmeans 'useSSLEngine's default.'
-
onPreAdd
public void onPreAdd(IoFilterChain parent, java.lang.String name, IoFilter.NextFilter nextFilter) throws javax.net.ssl.SSLException
Executed just before the filter is added into the chain, we do :- check that we don't have a SSL filter already present
- we update the next filter
- we create the SSL handler helper class
- and we store it into the session's Attributes
- Specified by:
onPreAddin interfaceIoFilter- Overrides:
onPreAddin classIoFilterAdapter- Parameters:
parent- the parent who called this methodname- the name assigned to this filternextFilter- theIoFilter.NextFilterfor this filter. You can reuse this object until this filter is removed from the chain.- Throws:
javax.net.ssl.SSLException
-
onPostAdd
public void onPostAdd(IoFilterChain parent, java.lang.String name, IoFilter.NextFilter nextFilter) throws javax.net.ssl.SSLException
Description copied from class:IoFilterAdapterInvoked after this filter is added to the specifiedparent. Please note that this method can be invoked more than once if this filter is added to more than one parents. This method is not invoked beforeIoFilter.init()is invoked.- Specified by:
onPostAddin interfaceIoFilter- Overrides:
onPostAddin classIoFilterAdapter- Parameters:
parent- the parent who called this methodname- the name assigned to this filternextFilter- theIoFilter.NextFilterfor this filter. You can reuse this object until this filter is removed from the chain.- Throws:
javax.net.ssl.SSLException
-
onPreRemove
public void onPreRemove(IoFilterChain parent, java.lang.String name, IoFilter.NextFilter nextFilter) throws javax.net.ssl.SSLException
Description copied from class:IoFilterAdapterInvoked before this filter is removed from the specifiedparent. Please note that this method can be invoked more than once if this filter is removed from more than one parents. This method is always invoked beforeIoFilter.destroy()is invoked.- Specified by:
onPreRemovein interfaceIoFilter- Overrides:
onPreRemovein classIoFilterAdapter- Parameters:
parent- the parent who called this methodname- the name assigned to this filternextFilter- theIoFilter.NextFilterfor this filter. You can reuse this object until this filter is removed from the chain.- Throws:
javax.net.ssl.SSLException
-
sessionClosed
public void sessionClosed(IoFilter.NextFilter nextFilter, IoSession session) throws javax.net.ssl.SSLException
Description copied from class:IoFilterAdapterFiltersIoHandler.sessionClosed(IoSession)event.- Specified by:
sessionClosedin interfaceIoFilter- Overrides:
sessionClosedin classIoFilterAdapter- Parameters:
nextFilter- theIoFilter.NextFilterfor this filter. You can reuse this object until this filter is removed from the chain.session- TheIoSessionwhich has received this event- Throws:
javax.net.ssl.SSLException
-
messageReceived
public void messageReceived(IoFilter.NextFilter nextFilter, IoSession session, java.lang.Object message) throws javax.net.ssl.SSLException
Description copied from class:IoFilterAdapterFiltersIoHandler.messageReceived(IoSession,Object)event.- Specified by:
messageReceivedin interfaceIoFilter- Overrides:
messageReceivedin classIoFilterAdapter- Parameters:
nextFilter- theIoFilter.NextFilterfor this filter. You can reuse this object until this filter is removed from the chain.session- TheIoSessionwhich has received this eventmessage- The received message- Throws:
javax.net.ssl.SSLException
-
messageSent
public void messageSent(IoFilter.NextFilter nextFilter, IoSession session, WriteRequest writeRequest)
Description copied from class:IoFilterAdapterFiltersIoHandler.messageSent(IoSession,Object)event.- Specified by:
messageSentin interfaceIoFilter- Overrides:
messageSentin classIoFilterAdapter- Parameters:
nextFilter- theIoFilter.NextFilterfor this filter. You can reuse this object until this filter is removed from the chain.session- TheIoSessionwhich has received this eventwriteRequest- TheWriteRequestthat contains the sent message
-
exceptionCaught
public void exceptionCaught(IoFilter.NextFilter nextFilter, IoSession session, java.lang.Throwable cause) throws java.lang.Exception
Description copied from class:IoFilterAdapterFiltersIoHandler.exceptionCaught(IoSession,Throwable)event.- Specified by:
exceptionCaughtin interfaceIoFilter- Overrides:
exceptionCaughtin classIoFilterAdapter- Parameters:
nextFilter- theIoFilter.NextFilterfor this filter. You can reuse this object until this filter is removed from the chain.session- TheIoSessionwhich has received this eventcause- The exception that cause this event to be received- Throws:
java.lang.Exception- If an error occurred while processing the event
-
isCloseNotify
private boolean isCloseNotify(java.lang.Object message)
-
filterWrite
public void filterWrite(IoFilter.NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws javax.net.ssl.SSLException
Description copied from class:IoFilterAdapterFiltersIoSession.write(Object)method invocation.- Specified by:
filterWritein interfaceIoFilter- Overrides:
filterWritein classIoFilterAdapter- Parameters:
nextFilter- theIoFilter.NextFilterfor this filter. You can reuse this object until this filter is removed from the chain.session- TheIoSessionwhich has to process this invocationwriteRequest- TheWriteRequestto process- Throws:
javax.net.ssl.SSLException
-
filterClose
public void filterClose(IoFilter.NextFilter nextFilter, IoSession session) throws javax.net.ssl.SSLException
Description copied from class:IoFilterAdapterFiltersIoSession.closeNow()or aIoSession.closeOnFlush()method invocations.- Specified by:
filterClosein interfaceIoFilter- Overrides:
filterClosein classIoFilterAdapter- Parameters:
nextFilter- theIoFilter.NextFilterfor this filter. You can reuse this object until this filter is removed from the chain.session- TheIoSessionwhich has to process this method invocation- Throws:
javax.net.ssl.SSLException
-
initiateHandshake
public void initiateHandshake(IoSession session) throws javax.net.ssl.SSLException
Initiate the SSL handshake. This can be invoked if you have set the 'autoStart' to false when creating the SslFilter instance.- Parameters:
session- The session for which the SSL handshake should be done- Throws:
javax.net.ssl.SSLException- If the handshake failed
-
initiateHandshake
private void initiateHandshake(IoFilter.NextFilter nextFilter, IoSession session) throws javax.net.ssl.SSLException
- Throws:
javax.net.ssl.SSLException
-
initiateClosure
private WriteFuture initiateClosure(IoFilter.NextFilter nextFilter, IoSession session) throws javax.net.ssl.SSLException
- Throws:
javax.net.ssl.SSLException
-
handleSslData
private void handleSslData(IoFilter.NextFilter nextFilter, SslHandler sslHandler) throws javax.net.ssl.SSLException
- Throws:
javax.net.ssl.SSLException
-
handleAppDataRead
private void handleAppDataRead(IoFilter.NextFilter nextFilter, SslHandler sslHandler)
-
getSslSessionHandler
private SslHandler getSslSessionHandler(IoSession session)
-
-