mina-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Wolter Eldering <wol...@eldering.net>
Subject Re: SSLFilter and SSL session reuse
Date Sun, 10 Dec 2006 21:13:21 GMT
Hi Trustin,

Whether SSL sessions are reused/resumed depends both on the client  
and server.
SSLSessions are cached in the SSLContext, by default the cache size  
is unlimited and the session timeout is 86400 seconds (24 hours).

The ctx.createSSLEngine(hostname,port) is only useful in clientMode,  
in serverMode a session will only be resumed if a client asks for it  
by sending the session-id in the clientHello.

The following patches to the SSLFilter make it possible to specify a  
hint for the SSLEngine when in clientMode:

--- SSLFilter.java      (revision 485164)
+++ SSLFilter.java      (working copy)
@@ -119,6 +119,12 @@
      private static final String NEXT_FILTER =  
SSLFilter.class.getName() + ".NextFilter";
      private static final String SSL_HANDLER =  
SSLFilter.class.getName() + ".SSLHandler";
+    /**
+     * A session attribute key that stores a hint for the {@link  
SSLContext#createSSLEngine(java.lang.String, int)}
+     * for its internal session reuse strategy. A {@link  
java.net.InetSocketAddress} object should be stored in the attribute.
+     */
+       public static final String SSL_SESSION_HINT =  
SSLFilter.class.getName() + ".SSLSessionHint";
+
      // SSL Context
      private SSLContext sslContext;


--- SSLHandler.java     (revision 485164)
+++ SSLHandler.java     (working copy)
@@ -19,6 +19,7 @@
   */
package org.apache.mina.filter.support;
+import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.Queue;
@@ -111,7 +112,15 @@
              return;
          }
-        sslEngine = ctx.createSSLEngine();
+        if( parent.isUseClientMode() && session.containsAttribute 
(SSLFilter.SSL_SESSION_HINT))
+        {
+            InetSocketAddress hint = (InetSocketAddress)  
session.getAttribute(SSLFilter.SSL_SESSION_HINT);
+            sslEngine = ctx.createSSLEngine(hint.getHostName(),  
hint.getPort());
+        }
+        else
+        {
+            sslEngine = ctx.createSSLEngine();
+        }
          sslEngine.setUseClientMode( parent.isUseClientMode() );
          if ( parent.isWantClientAuth() )


I have chosen an attribute instead of session.getRemoteAddress() to  
allow connection through proxies.

Here is a small test class, use "- 
Djavax.net.debug=sslctx,session,sessioncache" to see when sessions  
are created and reused.

Another thing i noticed is that when I do a IoSession.close() an  
"javax.net.ssl.SSLException: Inbound closed before receiving peer's  
close_notify: possible truncation attack?" occurs.
This will invalidate the SSLSession and prevent it from being reused.
If I remove the SSLFilter before I close the IoSession it all works  
fine.

package org.apache.mina.example.echoserver;

import java.net.InetSocketAddress;
import java.security.GeneralSecurityException;

import org.apache.mina.common.ConnectFuture;
import org.apache.mina.common.DefaultIoFilterChainBuilder;
import org.apache.mina.common.IoFilterAdapter;
import org.apache.mina.common.IoFilterChain;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
import org.apache.mina.example.echoserver.ssl.BogusSSLContextFactory;
import org.apache.mina.filter.SSLFilter;
import org.apache.mina.transport.socket.nio.SocketConnector;

public class SSLTest {

	public static void main(String[] args) throws  
GeneralSecurityException {
		
		SocketConnector connector = new SocketConnector();
		DefaultIoFilterChainBuilder chain = connector.getFilterChain();
		SSLFilter sslFilter = new SSLFilter 
(BogusSSLContextFactory.getInstance(false));
		sslFilter.setUseClientMode(true);
		chain.addLast("SSLFilter", sslFilter);
		
		// this workaround set the SSL_SESSION_HINT before the SSLFilter is  
added to the session
		// when the SSLFilter is added to the session manually a simple  
session.setAttribute() before adding the filter will work.
		chain.addFirst("Hint", new IoFilterAdapter() {
			@Override
			public void onPostAdd(IoFilterChain parent, String name,  
NextFilter nextFilter) throws Exception {
				parent.getSession().setAttribute(SSLFilter.SSL_SESSION_HINT, new  
InetSocketAddress("bogus.com", 8080));
			} });
		
		// keep the connector happy
		connector.setHandler( new IoHandlerAdapter() );

		// connect to the server 5 times
		for (int i=0; i < 5; i++) {
			ConnectFuture f = connector.connect(new InetSocketAddress(args[0],  
Integer.parseInt(args[1])));
			f.join();
			if (f.isConnected()) {
				IoSession s = f.getSession();
				
				// wait for a while
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
				}
				
				// shutdown connection
				
				s.getFilterChain().remove("SSLFilter"); // removing SSLFilter  
from the session prevents:
													  // javax.net.ssl.SSLException: Inbound closed before  
receiving peer's close_notify: possible truncation attack?
													  // when this exception occurs the SSL session will be  
invalidated
				s.close();
			}
		}
		
	}

}



Op 10-dec-2006, om 4:08 heeft Trustin Lee het volgende geschreven:

> Hi Wolter,
>
> On 12/10/06, Wolter Eldering <woltere@mac.com> wrote:
>>
>> Hi James,
>>
>> You are right, it has little use for a server.
>> But if you are using the SSLFilter in client mode, the SSLEngine must
>> be able to select a session(id) to send in the SSL ClientHello
>> otherwise sessions will never be reused.
>> In serverMode a session will only be resumed if a client asks for it
>> by sending a sessionid in the ClientHello.
>>
>> I'm using the SSLFilter in client mode in combination with client
>> authentication where the certificates are stored on a smartcard, for
>> every SSL session I create a sign operation is required on the
>> smartcard which is quite slow.
>
>
> Actually, I am not used to this kind of 'session reuse' situation.   
> Does
> just specitying hostname and port number make the SSLContext  
> reused?  Is
> SSLContext instance cached somewhere in a LRU cache?  If it is that  
> simple,
> can we just replace the ctx.createSSLEngine() to ctx.createSSLEngine 
> (hostname,
> port)?  Wouldn't there be any possibility of memory leak?
>
> Probably several lines of patch might worth much more than  
> explaining the
> whole stuff.  :D
>
> Thanks for the feed back,
> Trustin
> -- 
> what we call human nature is actually human habit
> --
> http://gleamynode.net/
> --
> PGP key fingerprints:
> * E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
> * B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6


Mime
View raw message