Search in sources :

Example 71 with SSLEngineResult

use of javax.net.ssl.SSLEngineResult in project ignite by apache.

the class GridNioSslHandler method closeOutbound.

/**
 * Writes close_notify message to the network output buffer.
 *
 * @throws SSLException If wrap failed or SSL engine does not get closed
 * after wrap.
 * @return {@code True} if <tt>close_notify</tt> message was encoded, {@code false} if outbound
 *      stream was already closed.
 */
boolean closeOutbound() throws SSLException {
    assert isHeldByCurrentThread();
    if (!sslEngine.isOutboundDone()) {
        sslEngine.closeOutbound();
        outNetBuf.clear();
        SSLEngineResult res = sslEngine.wrap(handshakeBuf, outNetBuf);
        if (res.getStatus() != CLOSED)
            throw new SSLException("Incorrect SSL engine status after closeOutbound call [status=" + res.getStatus() + ", handshakeStatus=" + res.getHandshakeStatus() + ", ses=" + ses + ']');
        outNetBuf.flip();
        return true;
    }
    return false;
}
Also used : SSLEngineResult(javax.net.ssl.SSLEngineResult) SSLException(javax.net.ssl.SSLException)

Example 72 with SSLEngineResult

use of javax.net.ssl.SSLEngineResult in project baseio by generallycloud.

the class SslHandler method wrap.

public ByteBuf wrap(SocketChannel channel, ByteBuf src) throws IOException {
    SSLEngine engine = channel.getSSLEngine();
    ByteBuf dst = getTempDst(engine);
    ByteBuf out = null;
    try {
        for (; ; ) {
            dst.clear();
            SSLEngineResult result = engine.wrap(src.nioBuffer(), dst.nioBuffer());
            Status status = result.getStatus();
            HandshakeStatus handshakeStatus = result.getHandshakeStatus();
            synchByteBuf(result, src, dst);
            if (status == Status.CLOSED) {
                return gc(channel, dst.flip());
            }
            if (handshakeStatus != HandshakeStatus.NOT_HANDSHAKING) {
                if (handshakeStatus == HandshakeStatus.NEED_UNWRAP) {
                    if (out != null) {
                        out.read(dst.flip());
                        return out.flip();
                    }
                    return gc(channel, dst.flip());
                } else if (handshakeStatus == HandshakeStatus.NEED_WRAP) {
                    if (out == null) {
                        out = allocate(channel, 256);
                    }
                    out.read(dst.flip());
                    continue;
                } else if (handshakeStatus == HandshakeStatus.FINISHED) {
                    channel.finishHandshake(null);
                    out.read(dst.flip());
                    return out.flip();
                } else if (handshakeStatus == HandshakeStatus.NEED_TASK) {
                    runDelegatedTasks(engine);
                    continue;
                }
            }
            if (src.hasRemaining()) {
                if (out == null) {
                    int outLength = ((src.limit() / src.position()) + 1) * (dst.position() - src.position()) + src.limit();
                    out = allocate(channel, outLength);
                }
                out.read(dst.flip());
                continue;
            }
            if (out != null) {
                out.read(dst.flip());
                return out.flip();
            }
            return gc(channel, dst.flip());
        }
    } catch (Throwable e) {
        ReleaseUtil.release(out);
        if (e instanceof IOException) {
            throw (IOException) e;
        }
        throw new IOException(e);
    }
}
Also used : HandshakeStatus(javax.net.ssl.SSLEngineResult.HandshakeStatus) Status(javax.net.ssl.SSLEngineResult.Status) SSLEngineResult(javax.net.ssl.SSLEngineResult) SSLEngine(javax.net.ssl.SSLEngine) IOException(java.io.IOException) ByteBuf(com.generallycloud.baseio.buffer.ByteBuf) EmptyByteBuf(com.generallycloud.baseio.buffer.EmptyByteBuf) HandshakeStatus(javax.net.ssl.SSLEngineResult.HandshakeStatus)

Example 73 with SSLEngineResult

use of javax.net.ssl.SSLEngineResult in project baseio by generallycloud.

the class SslHandler method unwrap.

public ByteBuf unwrap(SocketChannel channel, ByteBuf src) throws IOException {
    SSLEngine sslEngine = channel.getSSLEngine();
    ByteBuf dst = getTempDst(sslEngine);
    for (; ; ) {
        dst.clear();
        SSLEngineResult result = sslEngine.unwrap(src.nioBuffer(), dst.nioBuffer());
        HandshakeStatus handshakeStatus = result.getHandshakeStatus();
        synchByteBuf(result, src, dst);
        if (handshakeStatus != HandshakeStatus.NOT_HANDSHAKING) {
            if (handshakeStatus == HandshakeStatus.NEED_WRAP) {
                channel.doFlush(forgeFuture.duplicate());
                return null;
            } else if (handshakeStatus == HandshakeStatus.NEED_TASK) {
                runDelegatedTasks(sslEngine);
                continue;
            } else if (handshakeStatus == HandshakeStatus.FINISHED) {
                channel.finishHandshake(null);
                return null;
            } else if (handshakeStatus == HandshakeStatus.NEED_UNWRAP) {
                return null;
            }
        }
        return dst.flip();
    }
}
Also used : SSLEngineResult(javax.net.ssl.SSLEngineResult) SSLEngine(javax.net.ssl.SSLEngine) ByteBuf(com.generallycloud.baseio.buffer.ByteBuf) EmptyByteBuf(com.generallycloud.baseio.buffer.EmptyByteBuf) HandshakeStatus(javax.net.ssl.SSLEngineResult.HandshakeStatus)

Example 74 with SSLEngineResult

use of javax.net.ssl.SSLEngineResult in project jersey by jersey.

the class SslFilter method doHandshakeStep.

private boolean doHandshakeStep(ByteBuffer networkData) {
    /* Buffer used to store application data read during this handshake step.
        Application data can be interleaved with handshake messages only during re-handshake.
        We don't use applicationInputBuffer, because we might want to store more than one packet */
    LazyBuffer inputBuffer = new LazyBuffer();
    boolean handshakeFinished = false;
    synchronized (this) {
        if (SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING.equals(sslEngine.getHandshakeStatus())) {
            // we stopped handshaking while waiting for the lock
            return true;
        }
        try {
            /* we don't use networkOutputBuffer, because there might be a write operation still in progress ->
                we don't want to corrupt the buffer it is using */
            LazyBuffer outputBuffer = new LazyBuffer();
            boolean stepFinished = false;
            while (!stepFinished) {
                SSLEngineResult.HandshakeStatus hs = sslEngine.getHandshakeStatus();
                switch(hs) {
                    case NOT_HANDSHAKING:
                        {
                            throw new IllegalStateException("Trying to handshake, but SSL engine not in HANDSHAKING state." + "SSL filter state: \n" + getDebugState());
                        }
                    case FINISHED:
                        {
                            /* According to SSLEngine javadoc FINISHED status can be returned only in SSLEngineResult,
                            but just to make sure we don't end up in an infinite loop when presented with an SSLEngine
                            implementation that does not respect this:*/
                            stepFinished = true;
                            handshakeFinished = true;
                            break;
                        }
                    // needs to write data to the network
                    case NEED_WRAP:
                        {
                            ByteBuffer byteBuffer = outputBuffer.get();
                            SSLEngineResult result = sslEngine.wrap(emptyBuffer, byteBuffer);
                            if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED) {
                                stepFinished = true;
                                handshakeFinished = true;
                            }
                            switch(result.getStatus()) {
                                case BUFFER_OVERFLOW:
                                    {
                                        outputBuffer.resize();
                                        break;
                                    }
                                case BUFFER_UNDERFLOW:
                                    {
                                        /* This basically says that there is not enough data to create an SSL packet. Javadoc suggests
                                    that BUFFER_UNDERFLOW can occur only after unwrap(), but to be 100% sure we handle all
                                    possible error states: */
                                        throw new IllegalStateException("SSL engine underflow with the following SSL filter " + "state: \n" + getDebugState());
                                    }
                                case CLOSED:
                                    {
                                        stepFinished = true;
                                        state = State.CLOSED;
                                        break;
                                    }
                            }
                            break;
                        }
                    case NEED_UNWRAP:
                        {
                            SSLEngineResult result = sslEngine.unwrap(networkData, applicationInputBuffer);
                            applicationInputBuffer.flip();
                            if (applicationInputBuffer.hasRemaining()) {
                                // data can flow during re-handshake
                                inputBuffer.append(applicationInputBuffer);
                            }
                            applicationInputBuffer.compact();
                            if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED) {
                                stepFinished = true;
                                handshakeFinished = true;
                            }
                            switch(result.getStatus()) {
                                case BUFFER_OVERFLOW:
                                    {
                                        /* This means that the content of the ssl packet (max 16kB) did not fit into
                                    applicationInputBuffer, but we make sure to set applicationInputBuffer > max 16kB
                                    when initializing this filter. This indicates a bug. */
                                        throw new IllegalStateException("SSL packet does not fit into the network buffer: " + getDebugState());
                                    }
                                case BUFFER_UNDERFLOW:
                                    {
                                        // indicate that we won't get more from this buffer
                                        stepFinished = true;
                                        break;
                                    }
                                case CLOSED:
                                    {
                                        stepFinished = true;
                                        state = State.CLOSED;
                                        break;
                                    }
                            }
                            break;
                        }
                    // needs to execute long running task (for instance validating certificates)
                    case NEED_TASK:
                        {
                            Runnable delegatedTask;
                            while ((delegatedTask = sslEngine.getDelegatedTask()) != null) {
                                delegatedTask.run();
                            }
                            break;
                        }
                }
            }
            // now write the stored wrap() results
            if (outputBuffer.isAllocated()) {
                ByteBuffer buffer = outputBuffer.get();
                buffer.flip();
                writeQueue.write(buffer, null);
            }
        } catch (Exception e) {
            handleSslError(e);
        }
    }
    /* Handle any read data.
        We have to execute upstreamFilter.onRead after releasing the lock. See the synchronization note on top.
        Only one read operation can be in progress at a time, so even though we have released the lock, no other
        SSlEngine#unwrap can be performed until this method returns. So there is no chance of the read data
        being mixed up */
    if (inputBuffer.isAllocated()) {
        ByteBuffer buffer = inputBuffer.get();
        upstreamFilter.onRead(buffer);
    }
    if (handshakeFinished) {
        handleHandshakeFinished();
        // indicate that there still might be usable data in the input buffer
        return true;
    }
    /* if we are here, it means that we are waiting for more data -> indicate that there is nothing usable in the
        input buffer left */
    return false;
}
Also used : SSLEngineResult(javax.net.ssl.SSLEngineResult) ByteBuffer(java.nio.ByteBuffer) SSLException(javax.net.ssl.SSLException)

Example 75 with SSLEngineResult

use of javax.net.ssl.SSLEngineResult in project jersey by jersey.

the class SslFilter method handleRead.

private boolean handleRead(ByteBuffer networkData) {
    try {
        applicationInputBuffer.clear();
        SSLEngineResult result = sslEngine.unwrap(networkData, applicationInputBuffer);
        switch(result.getStatus()) {
            case BUFFER_OVERFLOW:
                {
                    /* This means that the content of the ssl packet (max 16kB) did not fit into
                       applicationInputBuffer, but we make sure to set applicationInputBuffer > max 16kB
                       when initializing this filter. This indicates a bug.*/
                    throw new IllegalStateException("Contents of a SSL packet did not fit into buffer: " + applicationInputBuffer + "\n" + getDebugState());
                }
            case BUFFER_UNDERFLOW:
                {
                    // the ssl packet is not full, return and indicate that we won't get more from this buffer
                    return false;
                }
            case CLOSED:
            case OK:
                {
                    if (result.bytesProduced() > 0) {
                        applicationInputBuffer.flip();
                        upstreamFilter.onRead(applicationInputBuffer);
                        applicationInputBuffer.compact();
                    }
                    if (sslEngine.isInboundDone()) {
                        // signal that there is nothing useful left in this buffer
                        return false;
                    }
                    // we started re-handshaking
                    if (result.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING && // make sure we don't confuse re-handshake with closing handshake
                    !sslEngine.isOutboundDone()) {
                        state = State.REHANDSHAKING;
                        return doHandshakeStep(networkData);
                    }
                    break;
                }
        }
    } catch (SSLException e) {
        handleSslError(e);
    }
    return true;
}
Also used : SSLEngineResult(javax.net.ssl.SSLEngineResult) SSLException(javax.net.ssl.SSLException)

Aggregations

SSLEngineResult (javax.net.ssl.SSLEngineResult)139 ByteBuffer (java.nio.ByteBuffer)53 IOException (java.io.IOException)32 SSLException (javax.net.ssl.SSLException)32 SSLEngine (javax.net.ssl.SSLEngine)25 Test (org.junit.Test)13 ReadOnlyBufferException (java.nio.ReadOnlyBufferException)12 SelfSignedCertificate (io.netty.handler.ssl.util.SelfSignedCertificate)10 HandshakeStatus (javax.net.ssl.SSLEngineResult.HandshakeStatus)9 EOFException (java.io.EOFException)7 ByteBuf (io.netty.buffer.ByteBuf)6 SSLSession (javax.net.ssl.SSLSession)6 WritePendingException (java.nio.channels.WritePendingException)5 KeyManagementException (java.security.KeyManagementException)5 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)5 ExecutionException (java.util.concurrent.ExecutionException)5 TimeoutException (java.util.concurrent.TimeoutException)5 Status (javax.net.ssl.SSLEngineResult.Status)5 CompositeByteBuf (io.netty.buffer.CompositeByteBuf)4 BufferUnderflowException (java.nio.BufferUnderflowException)3