Example usage for javax.net.ssl SSLEngineResult getStatus

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

Introduction

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

Prototype

public final Status getStatus() 

Source Link

Document

Gets the return value of this SSLEngine operation.

Usage

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   www.j  a  v  a2s  .  c om*/
    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.apache.hadoop.ipc.ServerRpcSSLEngineImpl.java

@Override
public int write(WritableByteChannel channel, ByteBuffer buffer) throws IOException {
    serverAppBuffer.clear();//from w w  w. j  a va2  s .  c  om
    if (serverAppBuffer.capacity() < buffer.capacity()) {
        LOG.debug("ServerAppBuffer capacity: " + serverAppBuffer.capacity() + " Buffer size: "
                + buffer.capacity());
        serverAppBuffer = ByteBuffer.allocate(Math.min(buffer.capacity(), MAX_BUFFER_SIZE));
    }
    serverAppBuffer.put(buffer);
    serverAppBuffer.flip();

    int bytesWritten = 0;
    while (serverAppBuffer.hasRemaining()) {
        serverNetBuffer.clear();
        SSLEngineResult result = sslEngine.wrap(serverAppBuffer, serverNetBuffer);
        switch (result.getStatus()) {
        case OK:
            serverNetBuffer.flip();
            while (serverNetBuffer.hasRemaining()) {
                bytesWritten += channel.write(serverNetBuffer);
            }
            //return bytesWritten;
            break;
        case BUFFER_OVERFLOW:
            serverNetBuffer = enlargePacketBuffer(serverNetBuffer);
            break;
        case BUFFER_UNDERFLOW:
            throw new SSLException("Buffer underflow should not happen after wrap");
        case CLOSED:
            sslEngine.closeOutbound();
            doHandshake();
            return -1;
        default:
            throw new IllegalStateException("Invalid SSL state: " + result.getStatus());
        }
    }
    return bytesWritten;
}

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

@Override
public int read(ReadableByteChannel channel, ByteBuffer buffer, Server.Connection connection)
        throws IOException {
    int netRead = channel.read(clientNetBuffer);
    if (netRead == -1) {
        return -1;
    }/*w w  w  .ja v  a 2  s .  c  o  m*/

    int read = 0;
    SSLEngineResult unwrapResult;
    do {
        clientNetBuffer.flip();
        unwrapResult = sslEngine.unwrap(clientNetBuffer, clientAppBuffer);
        clientNetBuffer.compact();

        if (unwrapResult.getStatus().equals(SSLEngineResult.Status.OK)) {
            read += unwrapResult.bytesProduced();
            clientAppBuffer.flip();

            while (clientAppBuffer.hasRemaining()) {
                byte currentByte = clientAppBuffer.get();
                try {
                    buffer.put(currentByte);
                } catch (BufferOverflowException ex) {
                    if (buffer.capacity() < maxUnWrappedDataLength) {
                        buffer = enlargeUnwrappedBuffer(buffer, currentByte);
                        connection.setSslUnwrappedBuffer(buffer);
                    } else {
                        LOG.error("Buffer overflow clientAppBuffer position: " + clientAppBuffer.position()
                                + " but buffer capacity " + buffer.capacity(), ex);
                        throw ex;
                    }
                }
            }
            clientAppBuffer.compact();
        } else if (unwrapResult.getStatus().equals(SSLEngineResult.Status.BUFFER_UNDERFLOW)) {
            read += unwrapResult.bytesProduced();
            break;
        } else if (unwrapResult.getStatus().equals(SSLEngineResult.Status.BUFFER_OVERFLOW)) {
            clientAppBuffer = enlargeApplicationBuffer(clientAppBuffer);
        } else if (unwrapResult.getStatus().equals(SSLEngineResult.Status.CLOSED)) {
            sslEngine.closeOutbound();
            doHandshake();
            read = -1;
            break;
        } else {
            throw new IOException("SSLEngine UNWRAP invalid status: " + unwrapResult.getStatus());
        }
    } while (clientNetBuffer.position() != 0);

    return read;
}

From source file:org.apache.hc.client5.http.impl.auth.CredSspScheme.java

private void wrap(final ByteBuffer src, final ByteBuffer dst) throws AuthenticationException {
    final SSLEngine sslEngine = getSSLEngine();
    try {//from  w w w  .  j  a  v  a2 s. c  o m
        final SSLEngineResult engineResult = sslEngine.wrap(src, dst);
        if (engineResult.getStatus() != Status.OK) {
            throw new AuthenticationException("SSL Engine error status: " + engineResult.getStatus());
        }
    } catch (final SSLException e) {
        throw new AuthenticationException("SSL Engine wrap error: " + e.getMessage(), e);
    }
}

From source file:org.apache.hc.client5.http.impl.auth.CredSspScheme.java

private void unwrap(final ByteBuffer src, final ByteBuffer dst) throws MalformedChallengeException {

    try {//ww  w  .j av a 2  s. co m
        final SSLEngineResult engineResult = sslEngine.unwrap(src, dst);
        if (engineResult.getStatus() != Status.OK) {
            throw new MalformedChallengeException("SSL Engine error status: " + engineResult.getStatus());
        }

        if (sslEngine.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
            final Runnable task = sslEngine.getDelegatedTask();
            task.run();
        }

    } catch (final SSLException e) {
        throw new MalformedChallengeException("SSL Engine unwrap error: " + e.getMessage(), e);
    }
}

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

private ByteBuffer sslDataWrap(ByteBuffer inBBuff, ByteBuffer outBBuff) throws GSSException {
    try {//from  ww w  .java  2 s.  com

        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  ww w .  j  av a2 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 {//  ww  w.  j  a  va 2 s. co  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);
    }
}