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: [email protected]
For additional commands, e-mail: [email protected]