From: markt Date: Tue, 1 Mar 2011 01:23:31 +0000 (+0000) Subject: Revert SSL renegotiation for NIO - implementation is broken X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=456000bcfbc6e60a558b1ef6ce6fc0d3c1a34a2c;p=tomcat7.0 Revert SSL renegotiation for NIO - implementation is broken Reverts r1074675 and r1075030 git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1075606 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/coyote/http11/Http11NioProcessor.java b/java/org/apache/coyote/http11/Http11NioProcessor.java index d24736a1f..daef7e7e2 100644 --- a/java/org/apache/coyote/http11/Http11NioProcessor.java +++ b/java/org/apache/coyote/http11/Http11NioProcessor.java @@ -23,8 +23,6 @@ import java.nio.channels.SelectionKey; import java.util.Locale; import java.util.concurrent.Executor; -import javax.net.ssl.SSLEngine; - import org.apache.coyote.ActionCode; import org.apache.coyote.Request; import org.apache.coyote.RequestInfo; @@ -44,9 +42,7 @@ import org.apache.tomcat.util.net.NioChannel; import org.apache.tomcat.util.net.NioEndpoint; import org.apache.tomcat.util.net.NioEndpoint.KeyAttachment; import org.apache.tomcat.util.net.SSLSupport; -import org.apache.tomcat.util.net.SecureNioChannel; import org.apache.tomcat.util.net.SocketStatus; -import org.apache.tomcat.util.net.jsse.JSSEFactory; /** @@ -629,25 +625,8 @@ public class Http11NioProcessor extends AbstractHttp11Processor { .setLimit(maxSavePostSize); inputBuffer.addActiveFilter (inputFilters[Constants.BUFFERED_FILTER]); - - SecureNioChannel sslChannel = (SecureNioChannel) socket; - SSLEngine engine = sslChannel.getSslEngine(); - if (!engine.getNeedClientAuth() && !engine.getWantClientAuth()) { - // Need to re-negotiate SSL connection - engine.setNeedClientAuth(true); - try { - sslChannel.rehandshake(); - sslSupport = (new JSSEFactory()).getSSLSupport( - engine.getSession()); - } catch (IOException ioe) { - log.warn(sm.getString("http11processor.socket.sslreneg", - ioe)); - } - } try { - // use force=false since re-negotiation is handled above - // (and it is a NO-OP for NIO anyway) - Object sslO = sslSupport.getPeerCertificateChain(false); + Object sslO = sslSupport.getPeerCertificateChain(true); if( sslO != null) { request.setAttribute (SSLSupport.CERTIFICATE_KEY, sslO); diff --git a/java/org/apache/coyote/http11/LocalStrings.properties b/java/org/apache/coyote/http11/LocalStrings.properties index 2eceb31ba..c0c27fc36 100644 --- a/java/org/apache/coyote/http11/LocalStrings.properties +++ b/java/org/apache/coyote/http11/LocalStrings.properties @@ -31,7 +31,6 @@ http11processor.request.process=Error processing request http11processor.request.finish=Error finishing request http11processor.response.finish=Error finishing response http11processor.socket.info=Exception getting socket information -http11processor.socket.sslreneg=Exception re-negotiating SSL connection http11processor.socket.ssl=Exception getting SSL attributes http11processor.socket.timeout=Error setting socket timeout diff --git a/java/org/apache/tomcat/util/net/NioChannel.java b/java/org/apache/tomcat/util/net/NioChannel.java index 1645db647..75de91e17 100644 --- a/java/org/apache/tomcat/util/net/NioChannel.java +++ b/java/org/apache/tomcat/util/net/NioChannel.java @@ -175,7 +175,7 @@ public class NioChannel implements ByteChannel{ * @return boolean * TODO Implement this org.apache.tomcat.util.net.SecureNioChannel method */ - public boolean isHandshakeComplete() { + public boolean isInitHandshakeComplete() { return true; } diff --git a/java/org/apache/tomcat/util/net/SecureNioChannel.java b/java/org/apache/tomcat/util/net/SecureNioChannel.java index 6798ad647..360cf60f1 100644 --- a/java/org/apache/tomcat/util/net/SecureNioChannel.java +++ b/java/org/apache/tomcat/util/net/SecureNioChannel.java @@ -43,8 +43,8 @@ public class SecureNioChannel extends NioChannel { protected SSLEngine sslEngine; - protected boolean handshakeComplete = false; - protected HandshakeStatus handshakeStatus; //gets set by begin handshake + protected boolean initHandshakeComplete = false; + protected HandshakeStatus initHandshakeStatus; //gets set by begin handshake protected boolean closed = false; protected boolean closing = false; @@ -82,12 +82,12 @@ public class SecureNioChannel extends NioChannel { netOutBuffer.limit(0); netInBuffer.position(0); netInBuffer.limit(0); - handshakeComplete = false; + initHandshakeComplete = false; closed = false; closing = false; //initiate handshake sslEngine.beginHandshake(); - handshakeStatus = sslEngine.getHandshakeStatus(); + initHandshakeStatus = sslEngine.getHandshakeStatus(); } @Override @@ -146,35 +146,35 @@ public class SecureNioChannel extends NioChannel { */ @Override public int handshake(boolean read, boolean write) throws IOException { - if ( handshakeComplete ) return 0; //we have done our initial handshake + if ( initHandshakeComplete ) return 0; //we have done our initial handshake if (!flush(netOutBuffer)) return SelectionKey.OP_WRITE; //we still have data to write SSLEngineResult handshake = null; - while (!handshakeComplete) { - switch ( handshakeStatus ) { + while (!initHandshakeComplete) { + switch ( initHandshakeStatus ) { case NOT_HANDSHAKING: { //should never happen throw new IOException("NOT_HANDSHAKING during handshake"); } case FINISHED: { //we are complete if we have delivered the last package - handshakeComplete = !netOutBuffer.hasRemaining(); + initHandshakeComplete = !netOutBuffer.hasRemaining(); //return 0 if we are complete, otherwise we still have data to write - return handshakeComplete?0:SelectionKey.OP_WRITE; + return initHandshakeComplete?0:SelectionKey.OP_WRITE; } case NEED_WRAP: { //perform the wrap function handshake = handshakeWrap(write); if ( handshake.getStatus() == Status.OK ){ - if (handshakeStatus == HandshakeStatus.NEED_TASK) - handshakeStatus = tasks(); + if (initHandshakeStatus == HandshakeStatus.NEED_TASK) + initHandshakeStatus = tasks(); } else { //wrap should always work with our buffers throw new IOException("Unexpected status:" + handshake.getStatus() + " during handshake WRAP."); } - if ( handshakeStatus != HandshakeStatus.NEED_UNWRAP || (!flush(netOutBuffer)) ) { + if ( initHandshakeStatus != HandshakeStatus.NEED_UNWRAP || (!flush(netOutBuffer)) ) { //should actually return OP_READ if we have NEED_UNWRAP return SelectionKey.OP_WRITE; } @@ -186,26 +186,26 @@ public class SecureNioChannel extends NioChannel { //perform the unwrap function handshake = handshakeUnwrap(read); if ( handshake.getStatus() == Status.OK ) { - if (handshakeStatus == HandshakeStatus.NEED_TASK) - handshakeStatus = tasks(); + if (initHandshakeStatus == HandshakeStatus.NEED_TASK) + initHandshakeStatus = tasks(); } else if ( handshake.getStatus() == Status.BUFFER_UNDERFLOW ){ //read more data, reregister for OP_READ return SelectionKey.OP_READ; } else { - throw new IOException("Invalid handshake status:"+handshakeStatus+" during handshake UNWRAP."); + throw new IOException("Invalid handshake status:"+initHandshakeStatus+" during handshake UNWRAP."); }//switch break; } case NEED_TASK: { - handshakeStatus = tasks(); + initHandshakeStatus = tasks(); break; } - default: throw new IllegalStateException("Invalid handshake status:"+handshakeStatus); + default: throw new IllegalStateException("Invalid handshake status:"+initHandshakeStatus); }//switch }//while //return 0 if we are complete, otherwise reregister for any activity that //would cause this method to be called again. - return handshakeComplete?0:(SelectionKey.OP_WRITE|SelectionKey.OP_READ); + return initHandshakeComplete?0:(SelectionKey.OP_WRITE|SelectionKey.OP_READ); } /** @@ -235,7 +235,7 @@ public class SecureNioChannel extends NioChannel { //prepare the results to be written netOutBuffer.flip(); //set the status - handshakeStatus = result.getHandshakeStatus(); + initHandshakeStatus = result.getHandshakeStatus(); //optimization, if we do have a writable channel, write it now if ( doWrite ) flush(netOutBuffer); return result; @@ -269,53 +269,19 @@ public class SecureNioChannel extends NioChannel { //compact the buffer, this is an optional method, wonder what would happen if we didn't netInBuffer.compact(); //read in the status - handshakeStatus = result.getHandshakeStatus(); + initHandshakeStatus = result.getHandshakeStatus(); if ( result.getStatus() == SSLEngineResult.Status.OK && result.getHandshakeStatus() == HandshakeStatus.NEED_TASK ) { //execute tasks if we need to - handshakeStatus = tasks(); + initHandshakeStatus = tasks(); } //perform another unwrap? cont = result.getStatus() == SSLEngineResult.Status.OK && - handshakeStatus == HandshakeStatus.NEED_UNWRAP; + initHandshakeStatus == HandshakeStatus.NEED_UNWRAP; }while ( cont ); return result; } - public void rehandshake() throws IOException { - int readBufLimit = getBufHandler().getReadBuffer().limit(); - try { - // Expand read buffer to maximum to allow handshaking to take place - getBufHandler().getReadBuffer().limit( - getBufHandler().getReadBuffer().capacity()); - sslEngine.getSession().invalidate(); - sslEngine.beginHandshake(); - handshakeComplete = false; - handshakeStatus = sslEngine.getHandshakeStatus(); - while (!handshakeComplete) { - handshake(true, true); - if (handshakeStatus == HandshakeStatus.NEED_UNWRAP) { - // Block until there is data to read from the client - Selector selector = null; - try { - selector = Selector.open(); - sc.register(selector, SelectionKey.OP_READ); - selector.select(); - handshakeUnwrap(true); - } finally { - if (selector != null) { - selector.close(); - } - } - } - } - } finally { - // Restore the pre-handshak value - getBufHandler().getReadBuffer().limit(readBufLimit); - } - } - - /** * Sends a SSL close message, will not physically close the connection here.
* To close the connection, you could do something like @@ -388,7 +354,7 @@ public class SecureNioChannel extends NioChannel { //are we in the middle of closing or closed? if ( closing || closed) return -1; //did we finish our handshake? - if (!handshakeComplete) throw new IllegalStateException("Handshake incomplete, you must complete handshake before reading data."); + if (!initHandshakeComplete) throw new IllegalStateException("Handshake incomplete, you must complete handshake before reading data."); //read from the network int netread = sc.read(netInBuffer); @@ -509,8 +475,8 @@ public class SecureNioChannel extends NioChannel { } @Override - public boolean isHandshakeComplete() { - return handshakeComplete; + public boolean isInitHandshakeComplete() { + return initHandshakeComplete; } @Override diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index bc388142f..e7571d66b 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -175,10 +175,6 @@ - - 49284: Add SSL re-negotiation support to the HTTP NIO - connector. (markt) - 50780: Fix memory leak in APR implementation of AJP connector introduced by the refactoring for 49884. (markt)