[prev in list] [next in list] [prev in thread] [next in thread] 

List:       mina-commits
Subject:    svn commit: r561118 - in /mina:
From:       trustin () apache ! org
Date:       2007-07-30 20:57:55
Message-ID: 20070730205755.A70BB1A981A () eris ! apache ! org
[Download RAW message or body]

Author: trustin
Date: Mon Jul 30 13:57:54 2007
New Revision: 561118

URL: http://svn.apache.org/viewvc?view=rev&rev=561118
Log:
Added a test case for SSL renegotiation.  Fixed bugs that causes SSL renegotiation \
fail.

Added:
    mina/trunk/filter-ssl/
Modified:
    mina/branches/1.0/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
  mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java
    mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java
  mina/branches/1.1/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
  mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java
    mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java
  mina/trunk/core/src/main/java/org/apache/mina/filter/ssl/SSLFilter.java
    mina/trunk/core/src/main/java/org/apache/mina/filter/ssl/SSLHandler.java
    mina/trunk/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java


Modified: mina/branches/1.0/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
                
URL: http://svn.apache.org/viewvc/mina/branches/1.0/example/src/test/java/org/apache/m \
ina/example/echoserver/ssl/SSLFilterTest.java?view=diff&rev=561118&r1=561117&r2=561118
 ==============================================================================
--- mina/branches/1.0/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java \
                (original)
+++ mina/branches/1.0/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java \
Mon Jul 30 13:57:54 2007 @@ -9,6 +9,7 @@
 import java.util.List;
 
 import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;
 
@@ -49,10 +50,9 @@
     }
 
     private void testMessageSentIsCalled(boolean useSSL) throws Exception {
-
+        SSLFilter sslFilter = null;
         if (useSSL) {
-            SSLFilter sslFilter = new SSLFilter(BogusSSLContextFactory
-                    .getInstance(true));
+            sslFilter = new SSLFilter(BogusSSLContextFactory.getInstance(true));
             acceptor.getFilterChain().addLast("sslFilter", sslFilter);
         }
         acceptor.getFilterChain().addLast(
@@ -67,11 +67,29 @@
         Socket socket = getClientSocket(useSSL);
         int bytesSent = 0;
         bytesSent += writeMessage(socket, "test-1\n");
+
+        if (useSSL) {
+            // Test renegotiation
+            SSLSocket ss = (SSLSocket) socket;
+            //ss.getSession().invalidate();
+            ss.startHandshake();
+        }
+
         bytesSent += writeMessage(socket, "test-2\n");
         byte[] response = new byte[bytesSent];
         for (int i = 0; i < response.length; i++) {
             response[i] = (byte) socket.getInputStream().read();
         }
+        
+        if (useSSL) {
+            // Read SSL close notify.
+            while (socket.getInputStream().read() >= 0) {
+                continue;
+            }
+        }
+        
+        socket.close();
+        
         long millis = System.currentTimeMillis();
         while (handler.sentMessages.size() < 2
                 && System.currentTimeMillis() < millis + 5000) {
@@ -108,6 +126,7 @@
 
         public void exceptionCaught(IoSession session, Throwable cause)
                 throws Exception {
+            cause.printStackTrace();
         }
 
         public void messageReceived(IoSession session, Object message)
@@ -118,6 +137,7 @@
         public void messageSent(IoSession session, Object message)
                 throws Exception {
             sentMessages.add(message.toString());
+            System.out.println(message);
             if (sentMessages.size() >= 2) {
                 session.close();
             }

Modified: mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java
                
URL: http://svn.apache.org/viewvc/mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java?view=diff&rev=561118&r1=561117&r2=561118
 ==============================================================================
--- mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java \
                (original)
+++ mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java \
Mon Jul 30 13:57:54 2007 @@ -131,6 +131,9 @@
 
     private static final String SSL_HANDLER = SSLFilter.class.getName()
             + ".SSLHandler";
+    
+    private static final String WAITING_FOR_LAST_CLOSE_NOTIFY = \
SSLFilter.class.getName() +            + ".WaitingForLastCloseNotify";
 
     // SSL Context
     private SSLContext sslContext;
@@ -402,6 +405,9 @@
                             }
 
                             handler.destroy();
+                            if \
(session.containsAttribute(WAITING_FOR_LAST_CLOSE_NOTIFY)) { +                        \
nextFilter.filterClose(session); +                            }
                         } else {
                             initiateClosure(nextFilter, session);
                         }
@@ -412,13 +418,13 @@
                         }
                     }
                 } catch (SSLException ssle) {
-                    if (!handler.isInitialHandshakeComplete()) {
+                    if (!handler.isHandshakeComplete()) {
                         SSLException newSSLE = new SSLHandshakeException(
-                                "Initial SSL handshake failed.");
+                                "SSL handshake failed.");
                         newSSLE.initCause(ssle);
                         ssle = newSSLE;
                     }
-
+                    
                     throw ssle;
                 }
             }
@@ -469,7 +475,7 @@
                     }
                     handler.scheduleFilterWrite(nextFilter,
                             writeRequest);
-                } else if (handler.isInitialHandshakeComplete()) {
+                } else if (handler.isHandshakeComplete()) {
                     // SSL encrypt
                     if (SessionLog.isDebugEnabled(session)) {
                         SessionLog.debug(session, " encrypt: " + buf);
@@ -528,6 +534,11 @@
             synchronized (handler) {
                 if (isSSLStarted(session)) {
                     future = initiateClosure(nextFilter, session);
+                    future.addListener(new IoFutureListener() {
+                        public void operationComplete(IoFuture future) {
+                            nextFilter.filterClose(session);
+                        }
+                    });
                 }
             }
 
@@ -535,12 +546,6 @@
         } finally {
             if (future == null) {
                 nextFilter.filterClose(session);
-            } else {
-                future.addListener(new IoFutureListener() {
-                    public void operationComplete(IoFuture future) {
-                        nextFilter.filterClose(session);
-                    }
-                });
             }
         }
     }
@@ -572,7 +577,7 @@
     private void handleSSLData(NextFilter nextFilter, SSLHandler handler)
             throws SSLException {
         // Flush any buffered write requests occurred before handshaking.
-        if (handler.isInitialHandshakeComplete()) {
+        if (handler.isHandshakeComplete()) {
             handler.flushPreHandshakeEvents();
         }
 
@@ -585,7 +590,9 @@
 
     private void handleAppDataRead(NextFilter nextFilter, SSLHandler handler) {
         IoSession session = handler.getSession();
+        handler.getAppBuffer().flip();
         if (!handler.getAppBuffer().hasRemaining()) {
+            handler.getAppBuffer().clear();
             return;
         }
 
@@ -595,6 +602,7 @@
 
         // forward read app data
         ByteBuffer readBuffer = SSLHandler.copy(handler.getAppBuffer());
+        handler.getAppBuffer().clear();
         if (SessionLog.isDebugEnabled(session)) {
             SessionLog.debug(session, " app data read: " + readBuffer + " ("
                     + readBuffer.getHexDump() + ')');

Modified: mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java
                
URL: http://svn.apache.org/viewvc/mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java?view=diff&rev=561118&r1=561117&r2=561118
 ==============================================================================
--- mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java \
                (original)
+++ mina/branches/1.0/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java \
Mon Jul 30 13:57:54 2007 @@ -89,12 +89,12 @@
     /**
      * Handshake status
      */
-    private SSLEngineResult.HandshakeStatus initialHandshakeStatus;
+    private SSLEngineResult.HandshakeStatus handshakeStatus;
 
     /**
      * Initial handshake complete?
      */
-    private boolean initialHandshakeComplete;
+    private boolean handshakeComplete;
 
     private boolean writingEncryptedData;
 
@@ -137,8 +137,8 @@
         }
 
         sslEngine.beginHandshake();
-        initialHandshakeStatus = \
                sslEngine.getHandshakeStatus();//SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
                
-        initialHandshakeComplete = false;
+        handshakeStatus = \
sslEngine.getHandshakeStatus();//SSLEngineResult.HandshakeStatus.NEED_UNWRAP; +       \
handshakeComplete = false;  
         SSLByteBufferPool.initiate(sslEngine);
 
@@ -202,10 +202,10 @@
     }
 
     /**
-     * Check if initial handshake is completed.
+     * Check if handshake is completed.
      */
-    public boolean isInitialHandshakeComplete() {
-        return initialHandshakeComplete;
+    public boolean isHandshakeComplete() {
+        return handshakeComplete;
     }
 
     public boolean isInboundDone() {
@@ -217,10 +217,10 @@
     }
 
     /**
-     * Check if there is any need to complete initial handshake.
+     * Check if there is any need to complete handshake.
      */
-    public boolean needToCompleteInitialHandshake() {
-        return (initialHandshakeStatus == SSLEngineResult.HandshakeStatus.NEED_WRAP \
&& !isInboundDone()); +    public boolean needToCompleteHandshake() {
+        return (handshakeStatus == SSLEngineResult.HandshakeStatus.NEED_WRAP && \
!isInboundDone());  }
 
     public void schedulePreHandshakeWriteRequest(NextFilter nextFilter,
@@ -292,8 +292,6 @@
             // We also expand app. buffer (twice the size of in net. buffer)
             appBuffer = SSLByteBufferPool.expandBuffer(appBuffer, inNetBuffer
                     .capacity() * 2);
-            appBuffer.position(0);
-            appBuffer.limit(0);
             if (SessionLog.isDebugEnabled(session)) {
                 SessionLog.debug(session, " expanded inNetBuffer:"
                         + inNetBuffer);
@@ -303,7 +301,7 @@
 
         // append buf to inNetBuffer
         inNetBuffer.put(buf);
-        if (!initialHandshakeComplete) {
+        if (!handshakeComplete) {
             handshake(nextFilter);
         } else {
             decrypt(nextFilter);
@@ -341,7 +339,7 @@
      * @throws SSLException on errors
      */
     public void encrypt(ByteBuffer src) throws SSLException {
-        if (!initialHandshakeComplete) {
+        if (!handshakeComplete) {
             throw new IllegalStateException();
         }
 
@@ -419,15 +417,7 @@
      */
     private void decrypt(NextFilter nextFilter) throws SSLException {
 
-        if (!initialHandshakeComplete) {
-            throw new IllegalStateException();
-        }
-
-        if (appBuffer.hasRemaining()) {
-            if (SessionLog.isDebugEnabled(session)) {
-                SessionLog.debug(session, " Error: appBuffer not empty!");
-            }
-            //still app data in buffer!?
+        if (!handshakeComplete) {
             throw new IllegalStateException();
         }
 
@@ -469,44 +459,44 @@
         }
 
         for (;;) {
-            if (initialHandshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED) \
{ +            if (handshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED) {
                 session.setAttribute(SSLFilter.SSL_SESSION, sslEngine
                         .getSession());
                 if (SessionLog.isDebugEnabled(session)) {
                     SSLSession sslSession = sslEngine.getSession();
                     SessionLog.debug(session,
-                            "  initialHandshakeStatus=FINISHED");
+                            "  handshakeStatus=FINISHED");
                     SessionLog.debug(session, "  sslSession CipherSuite used "
                             + sslSession.getCipherSuite());
                 }
-                initialHandshakeComplete = true;
+                handshakeComplete = true;
                 if (session.containsAttribute(SSLFilter.USE_NOTIFICATION)) {
                     scheduleMessageReceived(nextFilter,
                             SSLFilter.SESSION_SECURED);
                 }
                 break;
-            } else if (initialHandshakeStatus == \
SSLEngineResult.HandshakeStatus.NEED_TASK) { +            } else if (handshakeStatus \
== SSLEngineResult.HandshakeStatus.NEED_TASK) {  if \
(SessionLog.isDebugEnabled(session)) {  SessionLog.debug(session,
-                            "  initialHandshakeStatus=NEED_TASK");
+                            "  handshakeStatus=NEED_TASK");
                 }
-                initialHandshakeStatus = doTasks();
-            } else if (initialHandshakeStatus == \
SSLEngineResult.HandshakeStatus.NEED_UNWRAP) { +                handshakeStatus = \
doTasks(); +            } else if (handshakeStatus == \
SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {  // we need more data read
                 if (SessionLog.isDebugEnabled(session)) {
                     SessionLog.debug(session,
-                            "  initialHandshakeStatus=NEED_UNWRAP");
+                            "  handshakeStatus=NEED_UNWRAP");
                 }
                 SSLEngineResult.Status status = unwrapHandshake(nextFilter);
-                if ((initialHandshakeStatus != \
SSLEngineResult.HandshakeStatus.FINISHED && status == \
SSLEngineResult.Status.BUFFER_UNDERFLOW) +                if (status == \
SSLEngineResult.Status.BUFFER_UNDERFLOW  || isInboundDone()) {
                     // We need more data or the session is closed
                     break;
                 }
-            } else if (initialHandshakeStatus == \
SSLEngineResult.HandshakeStatus.NEED_WRAP) { +            } else if (handshakeStatus \
== SSLEngineResult.HandshakeStatus.NEED_WRAP) {  if \
(SessionLog.isDebugEnabled(session)) {  SessionLog.debug(session,
-                            "  initialHandshakeStatus=NEED_WRAP");
+                            "  handshakeStatus=NEED_WRAP");
                 }
                 // First make sure that the out buffer is completely empty. Since we
                 // cannot call wrap with data left on the buffer
@@ -524,11 +514,11 @@
                 }
 
                 outNetBuffer.flip();
-                initialHandshakeStatus = result.getHandshakeStatus();
+                handshakeStatus = result.getHandshakeStatus();
                 writeNetBuffer(nextFilter);
             } else {
                 throw new IllegalStateException("Invalid Handshaking State"
-                        + initialHandshakeStatus);
+                        + handshakeStatus);
             }
         }
     }
@@ -565,12 +555,12 @@
                     writeBuffer, writeFuture));
 
             // loop while more writes required to complete handshake
-            while (needToCompleteInitialHandshake()) {
+            while (needToCompleteHandshake()) {
                 try {
                     handshake(nextFilter);
                 } catch (SSLException ssle) {
                     SSLException newSSLE = new SSLHandshakeException(
-                            "Initial SSL handshake failed.");
+                            "SSL handshake failed.");
                     newSSLE.initCause(ssle);
                     throw newSSLE;
                 }
@@ -600,8 +590,6 @@
         if (SessionLog.isDebugEnabled(session)) {
             SessionLog.debug(session, " unwrap()");
         }
-        // Prepare the application buffer to receive decrypted data
-        appBuffer.clear();
 
         // Prepare the net data for reading.
         inNetBuffer.flip();
@@ -610,38 +598,28 @@
 
         // prepare to be written again
         inNetBuffer.compact();
-        // prepare app data to be read
-        appBuffer.flip();
         
         checkStatus(res);
         
-
-        if (res.getHandshakeStatus() != \
                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
-            // Renegotiation required.
-            SessionLog.debug(session, " Renegotiating...");
-            handshake(nextFilter);
-        }
+        renegotiateIfNeeded(nextFilter, res);
     }
 
     private SSLEngineResult.Status unwrapHandshake(NextFilter nextFilter) throws \
SSLException {  if (SessionLog.isDebugEnabled(session)) {
             SessionLog.debug(session, " unwrapHandshake()");
         }
-        // Prepare the application buffer to receive decrypted data
-        appBuffer.clear();
 
         // Prepare the net data for reading.
         inNetBuffer.flip();
 
         SSLEngineResult res = unwrap0();
-        initialHandshakeStatus = res.getHandshakeStatus();
+        handshakeStatus = res.getHandshakeStatus();
 
         checkStatus(res);
 
         // If handshake finished, no data was produced, and the status is still ok,
         // try to unwrap more
-        if (initialHandshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED
-                && appBuffer.position() == 0
+        if (handshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED
                 && res.getStatus() == SSLEngineResult.Status.OK
                 && inNetBuffer.hasRemaining()) {
             res = unwrap0();
@@ -649,25 +627,28 @@
             // prepare to be written again
             inNetBuffer.compact();
 
-            // prepare app data to be read
-            appBuffer.flip();
-
-            if (res.getHandshakeStatus() != \
                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
-                // Renegotiation required.
-                SessionLog.debug(session, " Renegotiating...");
-                handshake(nextFilter);
-            }
+            renegotiateIfNeeded(nextFilter, res);
         } else {
             // prepare to be written again
             inNetBuffer.compact();
-
-            // prepare app data to be read
-            appBuffer.flip();
         }
 
         return res.getStatus();
     }
 
+    private void renegotiateIfNeeded(NextFilter nextFilter, SSLEngineResult res)
+            throws SSLException {
+        if (res.getStatus() != SSLEngineResult.Status.CLOSED
+                && res.getStatus() != SSLEngineResult.Status.BUFFER_UNDERFLOW
+                && res.getHandshakeStatus() != \
SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) { +            // Renegotiation \
required. +            SessionLog.debug(session, " Renegotiating...");
+            handshakeComplete = false;
+            handshakeStatus = res.getHandshakeStatus();
+            handshake(nextFilter);
+        }
+    }
+
     private SSLEngineResult unwrap0() throws SSLException {
         SSLEngineResult res;
         do {
@@ -679,9 +660,8 @@
             if (SessionLog.isDebugEnabled(session)) {
                 SessionLog.debug(session, " Unwrap res:" + res);
             }
-
         } while (res.getStatus() == SSLEngineResult.Status.OK
-                && (initialHandshakeComplete && res.getHandshakeStatus() == \
SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING +                && \
(handshakeComplete && res.getHandshakeStatus() == \
                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING
                         || res.getHandshakeStatus() == \
SSLEngineResult.HandshakeStatus.NEED_UNWRAP));  
         return res;

Modified: mina/branches/1.1/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
                
URL: http://svn.apache.org/viewvc/mina/branches/1.1/example/src/test/java/org/apache/m \
ina/example/echoserver/ssl/SSLFilterTest.java?view=diff&rev=561118&r1=561117&r2=561118
 ==============================================================================
--- mina/branches/1.1/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java \
                (original)
+++ mina/branches/1.1/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java \
Mon Jul 30 13:57:54 2007 @@ -9,6 +9,7 @@
 import java.util.List;
 
 import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;
 
@@ -49,10 +50,9 @@
     }
 
     private void testMessageSentIsCalled(boolean useSSL) throws Exception {
-
+        SSLFilter sslFilter = null;
         if (useSSL) {
-            SSLFilter sslFilter = new SSLFilter(BogusSSLContextFactory
-                    .getInstance(true));
+            sslFilter = new SSLFilter(BogusSSLContextFactory.getInstance(true));
             acceptor.getFilterChain().addLast("sslFilter", sslFilter);
         }
         acceptor.getFilterChain().addLast(
@@ -67,11 +67,29 @@
         Socket socket = getClientSocket(useSSL);
         int bytesSent = 0;
         bytesSent += writeMessage(socket, "test-1\n");
+
+        if (useSSL) {
+            // Test renegotiation
+            SSLSocket ss = (SSLSocket) socket;
+            //ss.getSession().invalidate();
+            ss.startHandshake();
+        }
+
         bytesSent += writeMessage(socket, "test-2\n");
         byte[] response = new byte[bytesSent];
         for (int i = 0; i < response.length; i++) {
             response[i] = (byte) socket.getInputStream().read();
         }
+        
+        if (useSSL) {
+            // Read SSL close notify.
+            while (socket.getInputStream().read() >= 0) {
+                continue;
+            }
+        }
+        
+        socket.close();
+        
         long millis = System.currentTimeMillis();
         while (handler.sentMessages.size() < 2
                 && System.currentTimeMillis() < millis + 5000) {
@@ -108,6 +126,7 @@
 
         public void exceptionCaught(IoSession session, Throwable cause)
                 throws Exception {
+            cause.printStackTrace();
         }
 
         public void messageReceived(IoSession session, Object message)
@@ -118,6 +137,7 @@
         public void messageSent(IoSession session, Object message)
                 throws Exception {
             sentMessages.add(message.toString());
+            System.out.println(message);
             if (sentMessages.size() >= 2) {
                 session.close();
             }

Modified: mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java
                
URL: http://svn.apache.org/viewvc/mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java?view=diff&rev=561118&r1=561117&r2=561118
 ==============================================================================
--- mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java \
                (original)
+++ mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/SSLFilter.java \
Mon Jul 30 13:57:54 2007 @@ -131,6 +131,9 @@
 
     private static final String SSL_HANDLER = SSLFilter.class.getName()
             + ".SSLHandler";
+    
+    private static final String WAITING_FOR_LAST_CLOSE_NOTIFY = \
SSLFilter.class.getName() +            + ".WaitingForLastCloseNotify";
 
     // SSL Context
     private SSLContext sslContext;
@@ -402,6 +405,9 @@
                             }
 
                             handler.destroy();
+                            if \
(session.containsAttribute(WAITING_FOR_LAST_CLOSE_NOTIFY)) { +                        \
nextFilter.filterClose(session); +                            }
                         } else {
                             initiateClosure(nextFilter, session);
                         }
@@ -412,13 +418,13 @@
                         }
                     }
                 } catch (SSLException ssle) {
-                    if (!handler.isInitialHandshakeComplete()) {
+                    if (!handler.isHandshakeComplete()) {
                         SSLException newSSLE = new SSLHandshakeException(
-                                "Initial SSL handshake failed.");
+                                "SSL handshake failed.");
                         newSSLE.initCause(ssle);
                         ssle = newSSLE;
                     }
-
+                    
                     throw ssle;
                 }
             }
@@ -469,7 +475,7 @@
                     }
                     handler.scheduleFilterWrite(nextFilter,
                             writeRequest);
-                } else if (handler.isInitialHandshakeComplete()) {
+                } else if (handler.isHandshakeComplete()) {
                     // SSL encrypt
                     if (SessionLog.isDebugEnabled(session)) {
                         SessionLog.debug(session, " encrypt: " + buf);
@@ -528,6 +534,11 @@
             synchronized (handler) {
                 if (isSSLStarted(session)) {
                     future = initiateClosure(nextFilter, session);
+                    future.addListener(new IoFutureListener() {
+                        public void operationComplete(IoFuture future) {
+                            nextFilter.filterClose(session);
+                        }
+                    });
                 }
             }
 
@@ -535,12 +546,6 @@
         } finally {
             if (future == null) {
                 nextFilter.filterClose(session);
-            } else {
-                future.addListener(new IoFutureListener() {
-                    public void operationComplete(IoFuture future) {
-                        nextFilter.filterClose(session);
-                    }
-                });
             }
         }
     }
@@ -572,7 +577,7 @@
     private void handleSSLData(NextFilter nextFilter, SSLHandler handler)
             throws SSLException {
         // Flush any buffered write requests occurred before handshaking.
-        if (handler.isInitialHandshakeComplete()) {
+        if (handler.isHandshakeComplete()) {
             handler.flushPreHandshakeEvents();
         }
 
@@ -585,7 +590,9 @@
 
     private void handleAppDataRead(NextFilter nextFilter, SSLHandler handler) {
         IoSession session = handler.getSession();
+        handler.getAppBuffer().flip();
         if (!handler.getAppBuffer().hasRemaining()) {
+            handler.getAppBuffer().clear();
             return;
         }
 
@@ -595,6 +602,7 @@
 
         // forward read app data
         ByteBuffer readBuffer = SSLHandler.copy(handler.getAppBuffer());
+        handler.getAppBuffer().clear();
         if (SessionLog.isDebugEnabled(session)) {
             SessionLog.debug(session, " app data read: " + readBuffer + " ("
                     + readBuffer.getHexDump() + ')');

Modified: mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java
                
URL: http://svn.apache.org/viewvc/mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java?view=diff&rev=561118&r1=561117&r2=561118
 ==============================================================================
--- mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java \
                (original)
+++ mina/branches/1.1/filter-ssl/src/main/java/org/apache/mina/filter/support/SSLHandler.java \
Mon Jul 30 13:57:54 2007 @@ -88,12 +88,12 @@
     /**
      * Handshake status
      */
-    private SSLEngineResult.HandshakeStatus initialHandshakeStatus;
+    private SSLEngineResult.HandshakeStatus handshakeStatus;
 
     /**
      * Initial handshake complete?
      */
-    private boolean initialHandshakeComplete;
+    private boolean handshakeComplete;
 
     private boolean writingEncryptedData;
 
@@ -136,8 +136,8 @@
         }
 
         sslEngine.beginHandshake();
-        initialHandshakeStatus = \
                sslEngine.getHandshakeStatus();//SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
                
-        initialHandshakeComplete = false;
+        handshakeStatus = \
sslEngine.getHandshakeStatus();//SSLEngineResult.HandshakeStatus.NEED_UNWRAP; +       \
handshakeComplete = false;  
         SSLByteBufferPool.initiate(sslEngine);
 
@@ -201,10 +201,10 @@
     }
 
     /**
-     * Check if initial handshake is completed.
+     * Check if handshake is completed.
      */
-    public boolean isInitialHandshakeComplete() {
-        return initialHandshakeComplete;
+    public boolean isHandshakeComplete() {
+        return handshakeComplete;
     }
 
     public boolean isInboundDone() {
@@ -216,10 +216,10 @@
     }
 
     /**
-     * Check if there is any need to complete initial handshake.
+     * Check if there is any need to complete handshake.
      */
-    public boolean needToCompleteInitialHandshake() {
-        return (initialHandshakeStatus == SSLEngineResult.HandshakeStatus.NEED_WRAP \
&& !isInboundDone()); +    public boolean needToCompleteHandshake() {
+        return (handshakeStatus == SSLEngineResult.HandshakeStatus.NEED_WRAP && \
!isInboundDone());  }
 
     public void schedulePreHandshakeWriteRequest(NextFilter nextFilter,
@@ -291,8 +291,6 @@
             // We also expand app. buffer (twice the size of in net. buffer)
             appBuffer = SSLByteBufferPool.expandBuffer(appBuffer, inNetBuffer
                     .capacity() * 2);
-            appBuffer.position(0);
-            appBuffer.limit(0);
             if (SessionLog.isDebugEnabled(session)) {
                 SessionLog.debug(session, " expanded inNetBuffer:"
                         + inNetBuffer);
@@ -302,7 +300,7 @@
 
         // append buf to inNetBuffer
         inNetBuffer.put(buf);
-        if (!initialHandshakeComplete) {
+        if (!handshakeComplete) {
             handshake(nextFilter);
         } else {
             decrypt(nextFilter);
@@ -340,7 +338,7 @@
      * @throws SSLException on errors
      */
     public void encrypt(ByteBuffer src) throws SSLException {
-        if (!initialHandshakeComplete) {
+        if (!handshakeComplete) {
             throw new IllegalStateException();
         }
 
@@ -416,15 +414,7 @@
      */
     private void decrypt(NextFilter nextFilter) throws SSLException {
 
-        if (!initialHandshakeComplete) {
-            throw new IllegalStateException();
-        }
-
-        if (appBuffer.hasRemaining()) {
-            if (SessionLog.isDebugEnabled(session)) {
-                SessionLog.debug(session, " Error: appBuffer not empty!");
-            }
-            //still app data in buffer!?
+        if (!handshakeComplete) {
             throw new IllegalStateException();
         }
 
@@ -466,44 +456,44 @@
         }
 
         for (;;) {
-            if (initialHandshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED) \
{ +            if (handshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED) {
                 session.setAttribute(SSLFilter.SSL_SESSION, sslEngine
                         .getSession());
                 if (SessionLog.isDebugEnabled(session)) {
                     SSLSession sslSession = sslEngine.getSession();
                     SessionLog.debug(session,
-                            "  initialHandshakeStatus=FINISHED");
+                            "  handshakeStatus=FINISHED");
                     SessionLog.debug(session, "  sslSession CipherSuite used "
                             + sslSession.getCipherSuite());
                 }
-                initialHandshakeComplete = true;
+                handshakeComplete = true;
                 if (session.containsAttribute(SSLFilter.USE_NOTIFICATION)) {
                     scheduleMessageReceived(nextFilter,
                             SSLFilter.SESSION_SECURED);
                 }
                 break;
-            } else if (initialHandshakeStatus == \
SSLEngineResult.HandshakeStatus.NEED_TASK) { +            } else if (handshakeStatus \
== SSLEngineResult.HandshakeStatus.NEED_TASK) {  if \
(SessionLog.isDebugEnabled(session)) {  SessionLog.debug(session,
-                            "  initialHandshakeStatus=NEED_TASK");
+                            "  handshakeStatus=NEED_TASK");
                 }
-                initialHandshakeStatus = doTasks();
-            } else if (initialHandshakeStatus == \
SSLEngineResult.HandshakeStatus.NEED_UNWRAP) { +                handshakeStatus = \
doTasks(); +            } else if (handshakeStatus == \
SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {  // we need more data read
                 if (SessionLog.isDebugEnabled(session)) {
                     SessionLog.debug(session,
-                            "  initialHandshakeStatus=NEED_UNWRAP");
+                            "  handshakeStatus=NEED_UNWRAP");
                 }
                 SSLEngineResult.Status status = unwrapHandshake(nextFilter);
-                if ((initialHandshakeStatus != \
SSLEngineResult.HandshakeStatus.FINISHED && status == \
SSLEngineResult.Status.BUFFER_UNDERFLOW) +                if (status == \
SSLEngineResult.Status.BUFFER_UNDERFLOW  || isInboundDone()) {
                     // We need more data or the session is closed
                     break;
                 }
-            } else if (initialHandshakeStatus == \
SSLEngineResult.HandshakeStatus.NEED_WRAP) { +            } else if (handshakeStatus \
== SSLEngineResult.HandshakeStatus.NEED_WRAP) {  if \
(SessionLog.isDebugEnabled(session)) {  SessionLog.debug(session,
-                            "  initialHandshakeStatus=NEED_WRAP");
+                            "  handshakeStatus=NEED_WRAP");
                 }
                 // First make sure that the out buffer is completely empty. Since we
                 // cannot call wrap with data left on the buffer
@@ -521,11 +511,11 @@
                 }
 
                 outNetBuffer.flip();
-                initialHandshakeStatus = result.getHandshakeStatus();
+                handshakeStatus = result.getHandshakeStatus();
                 writeNetBuffer(nextFilter);
             } else {
                 throw new IllegalStateException("Invalid Handshaking State"
-                        + initialHandshakeStatus);
+                        + handshakeStatus);
             }
         }
     }
@@ -561,12 +551,12 @@
                     writeBuffer, writeFuture));
 
             // loop while more writes required to complete handshake
-            while (needToCompleteInitialHandshake()) {
+            while (needToCompleteHandshake()) {
                 try {
                     handshake(nextFilter);
                 } catch (SSLException ssle) {
                     SSLException newSSLE = new SSLHandshakeException(
-                            "Initial SSL handshake failed.");
+                            "SSL handshake failed.");
                     newSSLE.initCause(ssle);
                     throw newSSLE;
                 }
@@ -592,8 +582,6 @@
         if (SessionLog.isDebugEnabled(session)) {
             SessionLog.debug(session, " unwrap()");
         }
-        // Prepare the application buffer to receive decrypted data
-        appBuffer.clear();
 
         // Prepare the net data for reading.
         inNetBuffer.flip();
@@ -602,38 +590,28 @@
 
         // prepare to be written again
         inNetBuffer.compact();
-        // prepare app data to be read
-        appBuffer.flip();
         
         checkStatus(res);
         
-
-        if (res.getHandshakeStatus() != \
                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
-            // Renegotiation required.
-            SessionLog.debug(session, " Renegotiating...");
-            handshake(nextFilter);
-        }
+        renegotiateIfNeeded(nextFilter, res);
     }
 
     private SSLEngineResult.Status unwrapHandshake(NextFilter nextFilter) throws \
SSLException {  if (SessionLog.isDebugEnabled(session)) {
             SessionLog.debug(session, " unwrapHandshake()");
         }
-        // Prepare the application buffer to receive decrypted data
-        appBuffer.clear();
 
         // Prepare the net data for reading.
         inNetBuffer.flip();
 
         SSLEngineResult res = unwrap0();
-        initialHandshakeStatus = res.getHandshakeStatus();
+        handshakeStatus = res.getHandshakeStatus();
 
         checkStatus(res);
 
         // If handshake finished, no data was produced, and the status is still ok,
         // try to unwrap more
-        if (initialHandshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED
-                && appBuffer.position() == 0
+        if (handshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED
                 && res.getStatus() == SSLEngineResult.Status.OK
                 && inNetBuffer.hasRemaining()) {
             res = unwrap0();
@@ -641,25 +619,28 @@
             // prepare to be written again
             inNetBuffer.compact();
 
-            // prepare app data to be read
-            appBuffer.flip();
-
-            if (res.getHandshakeStatus() != \
                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
-                // Renegotiation required.
-                SessionLog.debug(session, " Renegotiating...");
-                handshake(nextFilter);
-            }
+            renegotiateIfNeeded(nextFilter, res);
         } else {
             // prepare to be written again
             inNetBuffer.compact();
-
-            // prepare app data to be read
-            appBuffer.flip();
         }
 
         return res.getStatus();
     }
 
+    private void renegotiateIfNeeded(NextFilter nextFilter, SSLEngineResult res)
+            throws SSLException {
+        if (res.getStatus() != SSLEngineResult.Status.CLOSED
+                && res.getStatus() != SSLEngineResult.Status.BUFFER_UNDERFLOW
+                && res.getHandshakeStatus() != \
SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) { +            // Renegotiation \
required. +            SessionLog.debug(session, " Renegotiating...");
+            handshakeComplete = false;
+            handshakeStatus = res.getHandshakeStatus();
+            handshake(nextFilter);
+        }
+    }
+
     private SSLEngineResult unwrap0() throws SSLException {
         SSLEngineResult res;
         do {
@@ -671,9 +652,8 @@
             if (SessionLog.isDebugEnabled(session)) {
                 SessionLog.debug(session, " Unwrap res:" + res);
             }
-
         } while (res.getStatus() == SSLEngineResult.Status.OK
-                && (initialHandshakeComplete && res.getHandshakeStatus() == \
SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING +                && \
(handshakeComplete && res.getHandshakeStatus() == \
                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING
                         || res.getHandshakeStatus() == \
SSLEngineResult.HandshakeStatus.NEED_UNWRAP));  
         return res;

Modified: mina/trunk/core/src/main/java/org/apache/mina/filter/ssl/SSLFilter.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/filter/ssl/SSLFilter.java?view=diff&rev=561118&r1=561117&r2=561118
 ==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/filter/ssl/SSLFilter.java \
                (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/filter/ssl/SSLFilter.java Mon Jul \
30 13:57:54 2007 @@ -151,6 +151,9 @@
 
     private static final String SSL_HANDLER = SSLFilter.class.getName()
             + ".SSLHandler";
+    
+    private static final String WAITING_FOR_LAST_CLOSE_NOTIFY = \
SSLFilter.class.getName() +            + ".WaitingForLastCloseNotify";
 
     // SSL Context
     private final SSLContext sslContext;
@@ -435,6 +438,9 @@
                             }
 
                             handler.destroy();
+                            if \
(session.containsAttribute(WAITING_FOR_LAST_CLOSE_NOTIFY)) { +                        \
nextFilter.filterClose(session); +                            }
                         } else {
                             initiateClosure(nextFilter, session);
                         }
@@ -445,13 +451,13 @@
                         }
                     }
                 } catch (SSLException ssle) {
-                    if (!handler.isInitialHandshakeComplete()) {
+                    if (!handler.isHandshakeComplete()) {
                         SSLException newSSLE = new SSLHandshakeException(
-                                "Initial SSL handshake failed.");
+                                "SSL handshake failed.");
                         newSSLE.initCause(ssle);
                         ssle = newSSLE;
                     }
-
+                    
                     throw ssle;
                 }
             }
@@ -503,7 +509,7 @@
                     }
                     handler.scheduleFilterWrite(nextFilter,
                             writeRequest);
-                } else if (handler.isInitialHandshakeComplete()) {
+                } else if (handler.isHandshakeComplete()) {
                     // SSL encrypt
                     if (SessionLog.isDebugEnabled(session)) {
                         SessionLog.debug(session, " encrypt: " + buf);
@@ -563,6 +569,11 @@
             synchronized (handler) {
                 if (isSSLStarted(session)) {
                     future = initiateClosure(nextFilter, session);
+                    future.addListener(new IoFutureListener() {
+                        public void operationComplete(IoFuture future) {
+                            nextFilter.filterClose(session);
+                        }
+                    });
                 }
             }
 
@@ -570,12 +581,6 @@
         } finally {
             if (future == null) {
                 nextFilter.filterClose(session);
-            } else {
-                future.addListener(new IoFutureListener() {
-                    public void operationComplete(IoFuture future) {
-                        nextFilter.filterClose(session);
-                    }
-                });
             }
         }
     }
@@ -616,7 +621,7 @@
     private void handleSSLData(NextFilter nextFilter, SSLHandler handler)
             throws SSLException {
         // Flush any buffered write requests occurred before handshaking.
-        if (handler.isInitialHandshakeComplete()) {
+        if (handler.isHandshakeComplete()) {
             handler.flushPreHandshakeEvents();
         }
 
@@ -629,7 +634,9 @@
 
     private void handleAppDataRead(NextFilter nextFilter, SSLHandler handler) {
         IoSession session = handler.getSession();
+        handler.getAppBuffer().flip();
         if (!handler.getAppBuffer().hasRemaining()) {
+            handler.getAppBuffer().clear();
             return;
         }
 
@@ -639,6 +646,7 @@
 
         // forward read app data
         ByteBuffer readBuffer = SSLHandler.copy(handler.getAppBuffer());
+        handler.getAppBuffer().clear();
         if (SessionLog.isDebugEnabled(session)) {
             SessionLog.debug(session, " app data read: " + readBuffer + " ("
                     + readBuffer.getHexDump() + ')');

Modified: mina/trunk/core/src/main/java/org/apache/mina/filter/ssl/SSLHandler.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/filter/ssl/SSLHandler.java?view=diff&rev=561118&r1=561117&r2=561118
 ==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/filter/ssl/SSLHandler.java \
                (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/filter/ssl/SSLHandler.java Mon Jul \
30 13:57:54 2007 @@ -91,12 +91,12 @@
     /**
      * Handshake status
      */
-    private SSLEngineResult.HandshakeStatus initialHandshakeStatus;
+    private SSLEngineResult.HandshakeStatus handshakeStatus;
 
     /**
      * Initial handshake complete?
      */
-    private boolean initialHandshakeComplete;
+    private boolean handshakeComplete;
 
     private boolean writingEncryptedData;
 
@@ -145,8 +145,8 @@
         }
 
         sslEngine.beginHandshake();
-        initialHandshakeStatus = \
                sslEngine.getHandshakeStatus();//SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
                
-        initialHandshakeComplete = false;
+        handshakeStatus = \
sslEngine.getHandshakeStatus();//SSLEngineResult.HandshakeStatus.NEED_UNWRAP; +       \
handshakeComplete = false;  
         SSLByteBufferUtil.initiate(sslEngine);
 
@@ -207,10 +207,10 @@
     }
 
     /**
-     * Check if initial handshake is completed.
+     * Check if handshake is completed.
      */
-    public boolean isInitialHandshakeComplete() {
-        return initialHandshakeComplete;
+    public boolean isHandshakeComplete() {
+        return handshakeComplete;
     }
 
     public boolean isInboundDone() {
@@ -222,10 +222,10 @@
     }
 
     /**
-     * Check if there is any need to complete initial handshake.
+     * Check if there is any need to complete handshake.
      */
-    public boolean needToCompleteInitialHandshake() {
-        return (initialHandshakeStatus == SSLEngineResult.HandshakeStatus.NEED_WRAP \
&& !isInboundDone()); +    public boolean needToCompleteHandshake() {
+        return (handshakeStatus == SSLEngineResult.HandshakeStatus.NEED_WRAP && \
!isInboundDone());  }
 
     public void schedulePreHandshakeWriteRequest(NextFilter nextFilter,
@@ -297,8 +297,6 @@
             // We also expand app. buffer (twice the size of in net. buffer)
             appBuffer = SSLByteBufferUtil.expandBuffer(appBuffer, inNetBuffer
                     .capacity() * 2);
-            appBuffer.position(0);
-            appBuffer.limit(0);
             if (SessionLog.isDebugEnabled(session)) {
                 SessionLog.debug(session, " expanded inNetBuffer:"
                         + inNetBuffer);
@@ -308,7 +306,7 @@
 
         // append buf to inNetBuffer
         inNetBuffer.put(buf);
-        if (!initialHandshakeComplete) {
+        if (!handshakeComplete) {
             handshake(nextFilter);
         } else {
             decrypt(nextFilter);
@@ -346,7 +344,7 @@
      * @throws SSLException on errors
      */
     public void encrypt(ByteBuffer src) throws SSLException {
-        if (!initialHandshakeComplete) {
+        if (!handshakeComplete) {
             throw new IllegalStateException();
         }
 
@@ -422,15 +420,7 @@
      */
     private void decrypt(NextFilter nextFilter) throws SSLException {
 
-        if (!initialHandshakeComplete) {
-            throw new IllegalStateException();
-        }
-
-        if (appBuffer.hasRemaining()) {
-            if (SessionLog.isDebugEnabled(session)) {
-                SessionLog.debug(session, " Error: appBuffer not empty!");
-            }
-            //still app data in buffer!?
+        if (!handshakeComplete) {
             throw new IllegalStateException();
         }
 
@@ -472,44 +462,44 @@
         }
 
         for (;;) {
-            if (initialHandshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED) \
{ +            if (handshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED) {
                 session.setAttribute(SSLFilter.SSL_SESSION, sslEngine
                         .getSession());
                 if (SessionLog.isDebugEnabled(session)) {
                     SSLSession sslSession = sslEngine.getSession();
                     SessionLog.debug(session,
-                            "  initialHandshakeStatus=FINISHED");
+                            "  handshakeStatus=FINISHED");
                     SessionLog.debug(session, "  sslSession CipherSuite used "
                             + sslSession.getCipherSuite());
                 }
-                initialHandshakeComplete = true;
+                handshakeComplete = true;
                 if (session.containsAttribute(SSLFilter.USE_NOTIFICATION)) {
                     scheduleMessageReceived(nextFilter,
                             SSLFilter.SESSION_SECURED);
                 }
                 break;
-            } else if (initialHandshakeStatus == \
SSLEngineResult.HandshakeStatus.NEED_TASK) { +            } else if (handshakeStatus \
== SSLEngineResult.HandshakeStatus.NEED_TASK) {  if \
(SessionLog.isDebugEnabled(session)) {  SessionLog.debug(session,
-                            "  initialHandshakeStatus=NEED_TASK");
+                            "  handshakeStatus=NEED_TASK");
                 }
-                initialHandshakeStatus = doTasks();
-            } else if (initialHandshakeStatus == \
SSLEngineResult.HandshakeStatus.NEED_UNWRAP) { +                handshakeStatus = \
doTasks(); +            } else if (handshakeStatus == \
SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {  // we need more data read
                 if (SessionLog.isDebugEnabled(session)) {
                     SessionLog.debug(session,
-                            "  initialHandshakeStatus=NEED_UNWRAP");
+                            "  handshakeStatus=NEED_UNWRAP");
                 }
                 SSLEngineResult.Status status = unwrapHandshake(nextFilter);
-                if ((initialHandshakeStatus != \
SSLEngineResult.HandshakeStatus.FINISHED && status == \
SSLEngineResult.Status.BUFFER_UNDERFLOW) +                if (status == \
SSLEngineResult.Status.BUFFER_UNDERFLOW  || isInboundDone()) {
                     // We need more data or the session is closed
                     break;
                 }
-            } else if (initialHandshakeStatus == \
SSLEngineResult.HandshakeStatus.NEED_WRAP) { +            } else if (handshakeStatus \
== SSLEngineResult.HandshakeStatus.NEED_WRAP) {  if \
(SessionLog.isDebugEnabled(session)) {  SessionLog.debug(session,
-                            "  initialHandshakeStatus=NEED_WRAP");
+                            "  handshakeStatus=NEED_WRAP");
                 }
                 // First make sure that the out buffer is completely empty. Since we
                 // cannot call wrap with data left on the buffer
@@ -527,11 +517,11 @@
                 }
 
                 outNetBuffer.flip();
-                initialHandshakeStatus = result.getHandshakeStatus();
+                handshakeStatus = result.getHandshakeStatus();
                 writeNetBuffer(nextFilter);
             } else {
                 throw new IllegalStateException("Invalid Handshaking State"
-                        + initialHandshakeStatus);
+                        + handshakeStatus);
             }
         }
     }
@@ -567,12 +557,12 @@
                     writeBuffer, writeFuture));
 
             // loop while more writes required to complete handshake
-            while (needToCompleteInitialHandshake()) {
+            while (needToCompleteHandshake()) {
                 try {
                     handshake(nextFilter);
                 } catch (SSLException ssle) {
                     SSLException newSSLE = new SSLHandshakeException(
-                            "Initial SSL handshake failed.");
+                            "SSL handshake failed.");
                     newSSLE.initCause(ssle);
                     throw newSSLE;
                 }
@@ -602,8 +592,6 @@
         if (SessionLog.isDebugEnabled(session)) {
             SessionLog.debug(session, " unwrap()");
         }
-        // Prepare the application buffer to receive decrypted data
-        appBuffer.clear();
 
         // Prepare the net data for reading.
         inNetBuffer.flip();
@@ -612,38 +600,28 @@
 
         // prepare to be written again
         inNetBuffer.compact();
-        // prepare app data to be read
-        appBuffer.flip();
         
         checkStatus(res);
         
-
-        if (res.getHandshakeStatus() != \
                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
-            // Renegotiation required.
-            SessionLog.debug(session, " Renegotiating...");
-            handshake(nextFilter);
-        }
+        renegotiateIfNeeded(nextFilter, res);
     }
 
     private SSLEngineResult.Status unwrapHandshake(NextFilter nextFilter) throws \
SSLException {  if (SessionLog.isDebugEnabled(session)) {
             SessionLog.debug(session, " unwrapHandshake()");
         }
-        // Prepare the application buffer to receive decrypted data
-        appBuffer.clear();
 
         // Prepare the net data for reading.
         inNetBuffer.flip();
 
         SSLEngineResult res = unwrap0();
-        initialHandshakeStatus = res.getHandshakeStatus();
+        handshakeStatus = res.getHandshakeStatus();
 
         checkStatus(res);
 
         // If handshake finished, no data was produced, and the status is still ok,
         // try to unwrap more
-        if (initialHandshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED
-                && appBuffer.position() == 0
+        if (handshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED
                 && res.getStatus() == SSLEngineResult.Status.OK
                 && inNetBuffer.hasRemaining()) {
             res = unwrap0();
@@ -651,25 +629,28 @@
             // prepare to be written again
             inNetBuffer.compact();
 
-            // prepare app data to be read
-            appBuffer.flip();
-
-            if (res.getHandshakeStatus() != \
                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
-                // Renegotiation required.
-                SessionLog.debug(session, " Renegotiating...");
-                handshake(nextFilter);
-            }
+            renegotiateIfNeeded(nextFilter, res);
         } else {
             // prepare to be written again
             inNetBuffer.compact();
-
-            // prepare app data to be read
-            appBuffer.flip();
         }
 
         return res.getStatus();
     }
 
+    private void renegotiateIfNeeded(NextFilter nextFilter, SSLEngineResult res)
+            throws SSLException {
+        if (res.getStatus() != SSLEngineResult.Status.CLOSED
+                && res.getStatus() != SSLEngineResult.Status.BUFFER_UNDERFLOW
+                && res.getHandshakeStatus() != \
SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) { +            // Renegotiation \
required. +            SessionLog.debug(session, " Renegotiating...");
+            handshakeComplete = false;
+            handshakeStatus = res.getHandshakeStatus();
+            handshake(nextFilter);
+        }
+    }
+
     private SSLEngineResult unwrap0() throws SSLException {
         SSLEngineResult res;
         do {
@@ -681,9 +662,8 @@
             if (SessionLog.isDebugEnabled(session)) {
                 SessionLog.debug(session, " Unwrap res:" + res);
             }
-
         } while (res.getStatus() == SSLEngineResult.Status.OK
-                && (initialHandshakeComplete && res.getHandshakeStatus() == \
SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING +                && \
(handshakeComplete && res.getHandshakeStatus() == \
                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING
                         || res.getHandshakeStatus() == \
SSLEngineResult.HandshakeStatus.NEED_UNWRAP));  
         return res;

Modified: mina/trunk/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java
                
URL: http://svn.apache.org/viewvc/mina/trunk/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java?view=diff&rev=561118&r1=561117&r2=561118
 ==============================================================================
--- mina/trunk/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java \
                (original)
+++ mina/trunk/example/src/test/java/org/apache/mina/example/echoserver/ssl/SSLFilterTest.java \
Mon Jul 30 13:57:54 2007 @@ -1,25 +1,27 @@
 package org.apache.mina.example.echoserver.ssl;
 
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.nio.charset.Charset;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
 import junit.framework.TestCase;
+
 import org.apache.mina.common.IoAcceptor;
 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.codec.ProtocolCodecFilter;
 import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
 import org.apache.mina.filter.ssl.SSLFilter;
 import org.apache.mina.transport.socket.nio.SocketAcceptor;
 
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.nio.charset.Charset;
-import java.security.cert.CertificateException;
-import java.util.ArrayList;
-import java.util.List;
-
 public class SSLFilterTest extends TestCase {
 
     private static final int PORT = 17887;
@@ -46,10 +48,9 @@
     }
 
     private void testMessageSentIsCalled(boolean useSSL) throws Exception {
-
+        SSLFilter sslFilter = null;
         if (useSSL) {
-            SSLFilter sslFilter = new SSLFilter(BogusSSLContextFactory
-                    .getInstance(true));
+            sslFilter = new SSLFilter(BogusSSLContextFactory.getInstance(true));
             acceptor.getFilterChain().addLast("sslFilter", sslFilter);
         }
         acceptor.getFilterChain().addLast(
@@ -67,12 +68,28 @@
         Socket socket = getClientSocket(useSSL);
         int bytesSent = 0;
         bytesSent += writeMessage(socket, "test-1\n");
-        Thread.sleep(2000);
+
+        if (useSSL) {
+            // Test renegotiation
+            SSLSocket ss = (SSLSocket) socket;
+            //ss.getSession().invalidate();
+            ss.startHandshake();
+        }
+        
         bytesSent += writeMessage(socket, "test-2\n");
+        
         int[] response = new int[bytesSent];
         for (int i = 0; i < response.length; i++) {
             response[i] = socket.getInputStream().read();
         }
+        
+        if (useSSL) {
+            // Read SSL close notify.
+            while (socket.getInputStream().read() >= 0) {
+                continue;
+            }
+        }
+        
         socket.close();
         while (acceptor.getManagedSessions().size() != 0) {
             Thread.sleep(100);
@@ -106,6 +123,7 @@
 
         public void exceptionCaught(IoSession session, Throwable cause)
                 throws Exception {
+            cause.printStackTrace();
         }
 
         public void messageReceived(IoSession session, Object message)
@@ -116,6 +134,7 @@
         public void messageSent(IoSession session, Object message)
                 throws Exception {
             sentMessages.add(message.toString());
+            System.out.println(message);
             if (sentMessages.size() >= 2) {
                 session.close();
             }


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic