Author: markt
Date: Thu Apr  9 15:16:42 2015
New Revision: 1672393

URL: http://svn.apache.org/r1672393
Log:
Some initial plumbing for SNI.
While Java 8 supports SNI, if you want different certs for different hosts then 
you have to manually parse the incoming TLS bytes to look for the SNI 
extension. This makes it 'interesting'. The idea at this point is to do it as 
part of the handshake. This will require moving the SSLEngine init code to 
processSNI() - that is the next step.
Fix some Java 8 Javadoc issues while I was in the area.
Modified:
    tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Channel.java
    tomcat/trunk/java/org/apache/tomcat/util/net/NioChannel.java
    tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java
    tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Channel.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Channel.java?rev=1672393&r1=1672392&r2=1672393&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Channel.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Channel.java Thu Apr  9 
15:16:42 2015
@@ -70,12 +70,21 @@ public class Nio2Channel implements Asyn
         sc.close();
     }
 
+
+    /**
+     * Close the connection.
+     *
+     * @param force Should the underlying socket be forcibly closed?
+     *
+     * @throws IOException If closing the secure channel fails.
+     */
     public void close(boolean force) throws IOException {
         if (isOpen() || force) {
             close();
         }
     }
 
+
     /**
      * Tells whether or not this channel is open.
      *

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/NioChannel.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/NioChannel.java?rev=1672393&r1=1672392&r2=1672393&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/NioChannel.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/NioChannel.java Thu Apr  9 
15:16:42 2015
@@ -92,9 +92,17 @@ public class NioChannel implements ByteC
         getIOChannel().close();
     }
 
+    /**
+     * Close the connection.
+     *
+     * @param force Should the underlying socket be forcibly closed?
+     *
+     * @throws IOException If closing the secure channel fails.
+     */
     public void close(boolean force) throws IOException {
         if (isOpen() || force ) close();
     }
+
     /**
      * Tells whether or not this channel is open.
      *

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java?rev=1672393&r1=1672392&r2=1672393&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java Thu Apr 
 9 15:16:42 2015
@@ -50,6 +50,8 @@ public class SecureNio2Channel extends N
     protected SSLEngine sslEngine;
     protected final Nio2Endpoint endpoint;
 
+    protected boolean sniComplete = false;
+
     protected boolean handshakeComplete;
     protected HandshakeStatus handshakeStatus; //gets set by handshake
 
@@ -191,7 +193,8 @@ public class SecureNio2Channel extends N
      * In the event of a positive value coming back, reregister the selection 
key for the return values interestOps.
      *
      * @return int - 0 if hand shake is complete, otherwise it returns a 
SelectionKey interestOps value
-     * @throws IOException
+     * @throws IOException If an I/O error occurs during the handshake or if 
the
+     *                     handshake fails during wrapping or unwrapping
      */
     @Override
     public int handshake() throws IOException {
@@ -199,8 +202,18 @@ public class SecureNio2Channel extends N
     }
 
     protected int handshakeInternal(boolean async) throws IOException {
-        if (handshakeComplete)
+        if (handshakeComplete) {
             return 0; //we have done our initial handshake
+        }
+
+        if (!sniComplete) {
+            int sniResult = processSNI();
+            if (sniResult == 0) {
+                sniComplete = true;
+            } else {
+                return sniResult;
+            }
+        }
 
         SSLEngineResult handshake = null;
 
@@ -290,6 +303,17 @@ public class SecureNio2Channel extends N
         return handshakeComplete ? 0 : handshakeInternal(async);
     }
 
+
+    /*
+     * Peeks at the initial network bytes to determine if the SNI extension is
+     * present and, if it is, what host name has been requested. Based on the
+     * provided host name, configure the SSLEngine for this connection.
+     */
+    private int processSNI() {
+        return 0;
+    }
+
+
     /**
      * Force a blocking handshake to take place for this key.
      * This requires that both network and application buffers have been 
emptied out prior to this call taking place, or a
@@ -452,11 +476,6 @@ public class SecureNio2Channel extends N
         closed = (!netOutBuffer.hasRemaining() && 
(handshake.getHandshakeStatus() != HandshakeStatus.NEED_WRAP));
     }
 
-    /**
-     * Force a close, can throw an IOException
-     * @param force boolean
-     * @throws IOException
-     */
     @Override
     public void close(boolean force) throws IOException {
         try {

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java?rev=1672393&r1=1672392&r2=1672393&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java Thu Apr  
9 15:16:42 2015
@@ -42,6 +42,8 @@ public class SecureNioChannel extends Ni
 
     protected SSLEngine sslEngine;
 
+    protected boolean sniComplete = false;
+
     protected boolean handshakeComplete = false;
     protected HandshakeStatus handshakeStatus; //gets set by handshake
 
@@ -88,23 +90,25 @@ public class SecureNioChannel extends Ni
 
//===========================================================================================
 //                  NIO SSL METHODS
 
//===========================================================================================
+
     /**
      * Flush the channel.
      *
      * @param block     Should a blocking write be used?
-     * @param s
-     * @param timeout
+     * @param s         The selector to use for blocking, if null then a busy
+     *                  write will be initiated
+     * @param timeout   The timeout for this write operation in milliseconds,
+     *                  -1 means no timeout
      * @return <code>true</code> if the network buffer has been flushed out and
      *         is empty else <code>false</code>
-     * @throws IOException
+     * @throws IOException If an I/O error occurs during the operation
      */
     @Override
-    public boolean flush(boolean block, Selector s, long timeout)
-            throws IOException {
+    public boolean flush(boolean block, Selector s, long timeout) throws 
IOException {
         if (!block) {
             flush(netOutBuffer);
         } else {
-            pool.write(netOutBuffer, this, s, timeout,block);
+            pool.write(netOutBuffer, this, s, timeout, block);
         }
         return !netOutBuffer.hasRemaining();
     }
@@ -134,11 +138,23 @@ public class SecureNioChannel extends Ni
      * @param read boolean - true if the underlying channel is readable
      * @param write boolean - true if the underlying channel is writable
      * @return int - 0 if hand shake is complete, otherwise it returns a 
SelectionKey interestOps value
-     * @throws IOException
+     * @throws IOException If an I/O error occurs during the handshake or if 
the
+     *                     handshake fails during wrapping or unwrapping
      */
     @Override
     public int handshake(boolean read, boolean write) throws IOException {
-        if ( handshakeComplete ) return 0; //we have done our initial handshake
+        if (handshakeComplete) {
+            return 0; //we have done our initial handshake
+        }
+
+        if (!sniComplete) {
+            int sniResult = processSNI();
+            if (sniResult == 0) {
+                sniComplete = true;
+            } else {
+                return sniResult;
+            }
+        }
 
         if (!flush(netOutBuffer)) return SelectionKey.OP_WRITE; //we still 
have data to write
 
@@ -202,6 +218,17 @@ public class SecureNioChannel extends Ni
         return 
handshakeComplete?0:(SelectionKey.OP_WRITE|SelectionKey.OP_READ);
     }
 
+
+    /*
+     * Peeks at the initial network bytes to determine if the SNI extension is
+     * present and, if it is, what host name has been requested. Based on the
+     * provided host name, configure the SSLEngine for this connection.
+     */
+    private int processSNI() {
+        return 0;
+    }
+
+
     /**
      * Force a blocking handshake to take place for this key.
      * This requires that both network and application buffers have been 
emptied out prior to this call taking place, or a
@@ -373,11 +400,7 @@ public class SecureNioChannel extends Ni
         closed = (!netOutBuffer.hasRemaining() && 
(handshake.getHandshakeStatus() != HandshakeStatus.NEED_WRAP));
     }
 
-    /**
-     * Force a close, can throw an IOException
-     * @param force boolean
-     * @throws IOException
-     */
+
     @Override
     public void close(boolean force) throws IOException {
         try {



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to