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;
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;
/**
.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);
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;
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
*/
@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;
}
//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);
}
/**
//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;
//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.<br>
* To close the connection, you could do something like
//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);
}
@Override
- public boolean isHandshakeComplete() {
- return handshakeComplete;
+ public boolean isInitHandshakeComplete() {
+ return initHandshakeComplete;
}
@Override