Example usage for javax.net.ssl SSLEngineResult getHandshakeStatus

List of usage examples for javax.net.ssl SSLEngineResult getHandshakeStatus

Introduction

In this page you can find the example usage for javax.net.ssl SSLEngineResult getHandshakeStatus.

Prototype

public final HandshakeStatus getHandshakeStatus() 

Source Link

Document

Gets the handshake status of this SSLEngine operation.

Usage

From source file:co.elastic.tealess.SSLChecker.java

private void checkHandshake(SSLReport sslReport, SocketChannel socket) {
    final InetSocketAddress address = sslReport.getAddress();
    final String name = sslReport.getHostname();
    IOObserver ioObserver = new IOObserver();
    ObservingSSLEngine sslEngine = new ObservingSSLEngine(ctx.createSSLEngine(name, address.getPort()),
            ioObserver);/*  ww  w . ja v  a2  s  .  c o m*/
    sslReport.setIOObserver(ioObserver);
    sslEngine.setUseClientMode(true);

    try {
        sslEngine.beginHandshake();
    } catch (SSLException e) {
        sslReport.setFailed(e);
        Throwable cause = Blame.get(e);
        logger.warn("beginHandshake failed: [{}] {}", cause.getClass(), cause.getMessage());
    }

    // TODO: Is this enough bytes?
    int size = sslEngine.getSession().getApplicationBufferSize() * 2;
    ByteBuffer localText = ByteBuffer.allocate(size);
    ByteBuffer localWire = ByteBuffer.allocate(size);
    ByteBuffer peerText = ByteBuffer.allocate(size);
    ByteBuffer peerWire = ByteBuffer.allocate(size);

    // TODO: I wonder... do we need to send any data at all?
    localText.put("SSL TEST. HELLO.".getBytes());
    localText.flip();

    SSLEngineResult result;
    logger.info("Starting SSL handshake [{}] ", address);
    try {
        SSLEngineResult.HandshakeStatus state;
        state = sslEngine.getHandshakeStatus();
        while (state != FINISHED) {
            // XXX: Use a Selector to wait for data.
            //logger.trace("State: {} [{}]", state, address);
            switch (state) {
            case NEED_TASK:
                sslEngine.getDelegatedTask().run();
                state = sslEngine.getHandshakeStatus();
                break;
            case NEED_WRAP:
                localWire.clear();
                result = sslEngine.wrap(localText, localWire);
                state = result.getHandshakeStatus();
                localWire.flip();
                while (localWire.hasRemaining()) {
                    socket.write(localWire);
                    //logger.trace("Sent {} bytes [{}]", bytes, address);
                }
                localWire.compact();
                break;
            case NEED_UNWRAP:
                // Try reading until we get data.
                Selector selector = Selector.open();
                while (peerWire.position() == 0) {
                    socket.read(peerWire);
                    try {
                        Thread.currentThread().sleep(5);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("Read " + peerWire.position() + " bytes");
                peerWire.flip();
                result = sslEngine.unwrap(peerWire, peerText);
                state = result.getHandshakeStatus();
                peerWire.compact();
                break;
            }
        }
    } catch (IOException e) {
        sslReport.setFailed(e);
        sslReport.setSSLSession(sslEngine.getHandshakeSession());
        sslReport.setPeerCertificateDetails(peerCertificateDetails);
        logger.warn("beginHandshake failed", e);
        return;
    }

    logger.info("handshake completed [{}]", address);

    // Handshake OK!
    sslReport.setSSLSession(sslEngine.getSession());
}

From source file:org.apache.hadoop.ipc.RpcSSLEngineAbstr.java

@Override
public boolean doHandshake() throws IOException {
    LOG.debug("Starting TLS handshake with peer " + getRemoteHost());

    SSLEngineResult result;
    SSLEngineResult.HandshakeStatus handshakeStatus;

    ByteBuffer serverAppBuffer = ByteBuffer.allocate(sslEngine.getSession().getApplicationBufferSize());
    ByteBuffer clientAppBuffer = ByteBuffer.allocate(sslEngine.getSession().getApplicationBufferSize());
    serverNetBuffer.clear();//from w  ww  .  j  a v a2 s  . co m
    clientNetBuffer.clear();

    TimeWatch timer = TimeWatch.start();

    handshakeStatus = sslEngine.getHandshakeStatus();
    while (handshakeStatus != SSLEngineResult.HandshakeStatus.FINISHED
            && handshakeStatus != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
        if (timer.elapsedIn(TimeUnit.MILLISECONDS) > handshakeTimeoutMS) {
            if (LOG.isWarnEnabled()) {
                String remoteHost = getRemoteHost();
                LOG.warn("Connection with " + remoteHost + " has been handshaking for too long. Closing the "
                        + "connection!");
            }
            throw new SSLException("TLS handshake time-out. Handshaking for more than " + handshakeTimeoutMS
                    + " milliseconds!");
        }
        switch (handshakeStatus) {
        case NEED_UNWRAP:
            int inBytes = socketChannel.read(clientNetBuffer);
            if (inBytes > 0) {
                timer.reset();
            } else if (inBytes < 0) {
                if (sslEngine.isInboundDone() && sslEngine.isOutboundDone()) {
                    return false;
                }
                try {
                    sslEngine.closeInbound();
                } catch (SSLException ex) {
                    LOG.warn(ex, ex);
                    throw ex;
                }
                sslEngine.closeOutbound();
                handshakeStatus = sslEngine.getHandshakeStatus();
                break;
            }
            clientNetBuffer.flip();
            try {
                result = sslEngine.unwrap(clientNetBuffer, clientAppBuffer);
                clientNetBuffer.compact();
                handshakeStatus = result.getHandshakeStatus();
            } catch (SSLException ex) {
                LOG.warn(ex, ex);
                sslEngine.closeOutbound();
                throw ex;
            }
            switch (result.getStatus()) {
            case OK:
                break;
            case BUFFER_OVERFLOW:
                // clientAppBuffer is not large enough
                clientAppBuffer = enlargeApplicationBuffer(clientAppBuffer);
                break;
            case BUFFER_UNDERFLOW:
                // Not enough input data to unwrap or the input buffer is too small
                clientNetBuffer = handleBufferUnderflow(clientNetBuffer);
                break;
            case CLOSED:
                if (sslEngine.isOutboundDone()) {
                    return false;
                } else {
                    sslEngine.closeOutbound();
                    handshakeStatus = sslEngine.getHandshakeStatus();
                    break;
                }
            default:
                throw new IllegalStateException("Invalid SSL status: " + result.getStatus());
            }
            break;
        case NEED_WRAP:
            serverNetBuffer.clear();
            try {
                result = sslEngine.wrap(serverAppBuffer, serverNetBuffer);
                handshakeStatus = result.getHandshakeStatus();
            } catch (SSLException ex) {
                LOG.warn(ex, ex);
                sslEngine.closeOutbound();
                throw ex;
            }
            switch (result.getStatus()) {
            case OK:
                serverNetBuffer.flip();
                while (serverNetBuffer.hasRemaining()) {
                    socketChannel.write(serverNetBuffer);
                }
                timer.reset();
                break;
            case BUFFER_OVERFLOW:
                serverNetBuffer = enlargePacketBuffer(serverNetBuffer);
                break;
            case BUFFER_UNDERFLOW:
                throw new SSLException("Buffer overflow occurred after a wrap.");
            case CLOSED:
                try {
                    serverNetBuffer.flip();
                    while (serverNetBuffer.hasRemaining()) {
                        socketChannel.write(serverNetBuffer);
                    }
                    timer.reset();
                    clientNetBuffer.clear();
                } catch (Exception ex) {
                    LOG.warn(ex, ex);
                    throw ex;
                }
                break;
            default:
                throw new IllegalStateException("Invalid SSL status: " + result.getStatus());
            }
            break;
        case NEED_TASK:
            Runnable task;
            while ((task = sslEngine.getDelegatedTask()) != null) {
                exec.execute(task);
            }
            handshakeStatus = sslEngine.getHandshakeStatus();
            break;
        case FINISHED:
            break;
        case NOT_HANDSHAKING:
            break;
        default:
            throw new IllegalStateException("Invalid SSL status: " + handshakeStatus);
        }
    }

    return true;
}

From source file:org.globus.gsi.gssapi.GlobusGSSContextImpl.java

private ByteBuffer sslDataWrap(ByteBuffer inBBuff, ByteBuffer outBBuff) throws GSSException {
    try {// w  w w .j  a  va 2s .  c  o m

        if (sslEngine.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
            throw new Exception("SSLEngine handshaking needed! " + "HandshakeStatus: "
                    + sslEngine.getHandshakeStatus().toString());
        }
        int iter = 0;
        do {
            logger.debug("PROCESSING DATA (WRAP) " + ++iter + ": " + inBBuff.remaining());
            SSLEngineResult result = sslEngine.wrap(inBBuff, outBBuff);
            if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
                runDelegatedTasks(sslEngine);
                continue;
            }
            if (result.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW) {
                // just increase it to the size needed.
                int pktSize = sslEngine.getSession().getPacketBufferSize();
                ByteBuffer b = ByteBuffer.allocate(pktSize + outBBuff.position());
                outBBuff.flip();
                b.put(outBBuff);
                outBBuff = b;
                continue;
            } else if (result.getStatus() == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
                throw new GlobusGSSException(GSSException.FAILURE, new Exception("Unexpected BUFFER_UNDERFLOW;"
                        + " Handshaking status: " + sslEngine.getHandshakeStatus()));
            }
            if (result.getStatus() != SSLEngineResult.Status.OK) {
                throw new GlobusGSSException(GSSException.FAILURE, GlobusGSSException.TOKEN_FAIL,
                        result.getStatus().toString());
            }
        } while (inBBuff.hasRemaining());

        return outBBuff;
    } catch (Exception e) {
        throw new GlobusGSSException(GSSException.FAILURE, e);
    }
}

From source file:org.globus.gsi.gssapi.GlobusGSSContextImpl.java

private ByteBuffer sslDataUnwrap(ByteBuffer inBBuff, ByteBuffer outBBuff) throws GSSException {
    try {/*from   w  ww  .j  ava2 s .  c o m*/
        int iter = 0;
        if (sslEngine.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
            throw new Exception("SSLEngine handshaking needed! " + "HandshakeStatus: "
                    + sslEngine.getHandshakeStatus().toString());
        }
        do {
            logger.debug("PROCESSING DATA (UNWRAP) " + ++iter + ": " + inBBuff.remaining());
            SSLEngineResult result = sslEngine.unwrap(inBBuff, outBBuff);
            if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
                runDelegatedTasks(sslEngine);
                continue;
            }
            if (result.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW) {
                // increase it to the size needed.
                int appSize = sslEngine.getSession().getApplicationBufferSize();
                ByteBuffer b = ByteBuffer.allocate(appSize + outBBuff.position());
                outBBuff.flip();
                b.put(outBBuff);
                outBBuff = b;
                continue;
            } else if (result.getStatus() == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
                // More data needed from peer
                break;
            } else if (result.getStatus() == SSLEngineResult.Status.CLOSED) {
                throw new ClosedGSSException();
            }

            if (result.getStatus() != SSLEngineResult.Status.OK) {
                throw new GlobusGSSException(GSSException.FAILURE, GlobusGSSException.TOKEN_FAIL,
                        result.getStatus().toString());
            }
        } while (inBBuff.hasRemaining());
        return outBBuff;
    } catch (IllegalArgumentException e) {
        throw new GlobusGSSException(GSSException.DEFECTIVE_TOKEN, e);
    } catch (SSLException e) {
        if (e.toString().endsWith("bad record MAC"))
            throw new GlobusGSSException(GSSException.BAD_MIC, e);
        else if (e.toString().endsWith("ciphertext sanity check failed"))
            throw new GlobusGSSException(GSSException.DEFECTIVE_TOKEN, e);
        else
            throw new GlobusGSSException(GSSException.FAILURE, e);
    } catch (GSSException e) {
        throw e;
    } catch (Exception e) {
        throw new GlobusGSSException(GSSException.FAILURE, e);
    }
}

From source file:org.globus.gsi.gssapi.GlobusGSSContextImpl.java

private ByteBuffer sslProcessHandshake(ByteBuffer inBBuff, ByteBuffer outBBuff) throws GSSException {
    // Loopon until we need more from peer or we are done with handshaking.
    try {/*from   w  w w  .  j  a  va2 s.  c  o m*/
        done: do {
            while (sslEngine.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_WRAP) {
                SSLEngineResult result = sslEngine.wrap(inBBuff, outBBuff);
                if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
                    runDelegatedTasks(sslEngine);
                    continue;
                }
                if (result.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW) {
                    // increase it to the size needed.
                    int pktSize = sslEngine.getSession().getPacketBufferSize();
                    ByteBuffer b = ByteBuffer.allocate(pktSize + outBBuff.position());
                    outBBuff.flip();
                    b.put(outBBuff);
                    outBBuff = b;
                    continue;
                } else if (result.getStatus() == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
                    throw new GlobusGSSException(GSSException.FAILURE,
                            new Exception("Unexpected BUFFER_UNDERFLOW;" + " Handshaking status: "
                                    + sslEngine.getHandshakeStatus()));
                }
                if (result.getStatus() != SSLEngineResult.Status.OK) {
                    throw new GlobusGSSException(GSSException.FAILURE, GlobusGSSException.TOKEN_FAIL,
                            result.getStatus().toString());
                }
            }

            int iter = 0;
            while (sslEngine.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {
                logger.debug("PROCESSING " + ++iter + ": " + inBBuff.remaining());
                SSLEngineResult result = sslEngine.unwrap(inBBuff, outBBuff);
                if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
                    runDelegatedTasks(sslEngine);
                    continue;
                }
                if (result.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW) {
                    // increase it to the size needed.
                    int appSize = sslEngine.getSession().getApplicationBufferSize();
                    ByteBuffer b = ByteBuffer.allocate(appSize + outBBuff.position());
                    outBBuff.flip();
                    b.put(outBBuff);
                    outBBuff = b;
                    continue;
                } else if (result.getStatus() == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
                    // More data needed from peer
                    // break out of outer loop
                    break done;
                }
                if (result.getStatus() != SSLEngineResult.Status.OK) {
                    throw new GlobusGSSException(GSSException.FAILURE, GlobusGSSException.TOKEN_FAIL,
                            result.getStatus().toString());
                }
            }
        } while (sslEngine.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING);

        return outBBuff;
    } catch (Exception e) {
        throw new GlobusGSSException(GSSException.FAILURE, e);
    }
}