FileDocCategorySizeDatePackage
TlsProtocolFinder.javaAPI DocGlassfish v2 API8007Fri May 04 22:37:12 BST 2007com.sun.enterprise.web.portunif

TlsProtocolFinder

public class TlsProtocolFinder extends Object implements ProtocolFinder
ProtocolFinder that will first try to execute an handshake. If the handshake is succesfull, the https protocol will be assumed. If the handshake fail, the http protocol will be assumed. This object shoudn't be called by several threads simultaneously.
author
Jeanfrancois Arcand

Fields Summary
private static final int
appBBSize
Decrypted ByteBuffer default size.
private boolean
needClientAuth
Require client Authentication.
private boolean
wantClientAuth
True when requesting authentication.
Constructors Summary
public TlsProtocolFinder()

 
    
    // ---------------------------------------------------------------------- //
    
    
      
        // Try to find a secure SelectorThread.
        Enumeration<SelectorThread> selectors 
            = SelectorThread.getSelectors();                          
        SelectorThread sel;
        while (selectors.hasMoreElements()){
            sel = selectors.nextElement();
            if (sel instanceof SSLSelectorThread){
                needClientAuth = ((SSLSelectorThread)sel).isNeedClientAuth();
                wantClientAuth = ((SSLSelectorThread)sel).isWantClientAuth();  
                break;
            }
        }        
    
Methods Summary
public voidfind(com.sun.enterprise.web.portunif.util.ProtocolInfo protocolInfo)
Try to initialize an SSL|TLS handshake to determine if https

        if (protocolInfo.sslContext == null){
            return;
        }

        SelectionKey key = protocolInfo.key;    
        SocketChannel socketChannel = (SocketChannel)key.channel();

        SSLEngine sslEngine = protocolInfo.sslEngine;        
        if (protocolInfo.sslContext != null && sslEngine == null) {
            sslEngine = protocolInfo.sslContext.createSSLEngine();
            sslEngine.setUseClientMode(false);
            sslEngine.setNeedClientAuth(needClientAuth);
            sslEngine.setWantClientAuth(wantClientAuth);
        }
        
        ByteBuffer inputBB = null;
        ByteBuffer outputBB =  null;
        ByteBuffer byteBuffer =  null;  
        int inputBBSize = sslEngine.getSession().getPacketBufferSize();        
        if (protocolInfo.inputBB == null 
                || (inputBB != null && inputBBSize > inputBB.capacity())){
            inputBB = ByteBuffer.allocate(inputBBSize * 2);
            outputBB = ByteBuffer.allocate(inputBBSize * 2);
            byteBuffer = ByteBuffer.allocate(inputBBSize * 2);  

            inputBBSize = sslEngine.getSession().getApplicationBufferSize();
            if ( inputBBSize > byteBuffer.capacity() ) {
                ByteBuffer newBB = ByteBuffer.allocate(inputBBSize);
                byteBuffer.flip();
                newBB.put(byteBuffer);
                byteBuffer = newBB;
            }   

        } else {
            inputBB = protocolInfo.inputBB;
            outputBB = protocolInfo.outputBB;
            byteBuffer = protocolInfo.byteBuffer;                     
        }
        outputBB.position(0);
        outputBB.limit(0); 
        
        if ( protocolInfo.bytesRead > 0){
            inputBB.put((ByteBuffer)protocolInfo.byteBuffer.flip());
        }

        HandshakeStatus handshakeStatus = HandshakeStatus.NEED_UNWRAP;
        boolean OK = true;  
        if (protocolInfo.handshake){
            try{
                byteBuffer = SSLUtils.doHandshake(key,byteBuffer,inputBB,outputBB,
                                                  sslEngine,handshakeStatus,
                                                  SSLUtils.getReadTimeout());
                protocolInfo.handshake = false;
            } catch (EOFException ex) {
                ; // DO nothing, as the client closed the connection
            } catch (Throwable ex) {            
                // An exception means the handshake failed.
                OK = false;
                byteBuffer.put(inputBB);            
            }
        }
          
        try {
            if (OK) {  
                int byteRead = SSLUtils.doRead(key,inputBB,sslEngine,
                        SSLUtils.getReadTimeout());
                if (byteRead > -1){
                    protocolInfo.byteBuffer = 
                            SSLUtils.unwrapAll(byteBuffer,inputBB,sslEngine);
                    protocolInfo.bytesRead = byteBuffer.position();
                    
                    // Not enough bytes to decrypt the request.
                    if (protocolInfo.bytesRead == 0){
                        OK = false;
                    }                  
                } else {
                   throw new EOFException(); 
                }
            }
        } finally {
            String protocol = protocolInfo.protocol;  
            protocolInfo.inputBB = inputBB;
            protocolInfo.byteBuffer = byteBuffer;
            protocolInfo.outputBB = outputBB; 
            protocolInfo.sslEngine = sslEngine;     
            protocolInfo.isSecure = true;            
            if (!OK){
                protocolInfo.bytesRead = byteBuffer.position();
                protocolInfo.protocol = null;
                protocolInfo.isSecure = false;
            }
            protocolInfo.socketChannel = (SocketChannel)key.channel();                
        }
        return;