Search in sources :

Example 91 with SSLEngineResult

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

the class SslTransportLayer method read.

/**
    * Reads a sequence of bytes from this channel into the given buffer.
    *
    * @param dst The buffer into which bytes are to be transferred
    * @return The number of bytes read, possible zero or -1 if the channel has reached end-of-stream
    * @throws IOException if some other I/O error occurs
    */
@Override
public int read(ByteBuffer dst) throws IOException {
    if (closing)
        return -1;
    int read = 0;
    if (!handshakeComplete)
        return read;
    //if we have unread decrypted data in appReadBuffer read that into dst buffer.
    if (appReadBuffer.position() > 0) {
        read = readFromAppBuffer(dst);
    }
    if (dst.remaining() > 0) {
        netReadBuffer = Utils.ensureCapacity(netReadBuffer, netReadBufferSize());
        if (netReadBuffer.remaining() > 0) {
            int netread = socketChannel.read(netReadBuffer);
            if (netread == 0 && netReadBuffer.position() == 0)
                return read;
            else if (netread < 0)
                throw new EOFException("EOF during read");
        }
        do {
            netReadBuffer.flip();
            SSLEngineResult unwrapResult = sslEngine.unwrap(netReadBuffer, appReadBuffer);
            netReadBuffer.compact();
            // handle ssl renegotiation.
            if (unwrapResult.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING && unwrapResult.getStatus() == Status.OK) {
                log.trace("SSLChannel Read begin renegotiation channelId {}, appReadBuffer pos {}, netReadBuffer pos {}, netWriteBuffer pos {}", channelId, appReadBuffer.position(), netReadBuffer.position(), netWriteBuffer.position());
                renegotiate();
                break;
            }
            if (unwrapResult.getStatus() == Status.OK) {
                read += readFromAppBuffer(dst);
            } else if (unwrapResult.getStatus() == Status.BUFFER_OVERFLOW) {
                int currentApplicationBufferSize = applicationBufferSize();
                appReadBuffer = Utils.ensureCapacity(appReadBuffer, currentApplicationBufferSize);
                if (appReadBuffer.position() >= currentApplicationBufferSize) {
                    throw new IllegalStateException("Buffer overflow when available data size (" + appReadBuffer.position() + ") >= application buffer size (" + currentApplicationBufferSize + ")");
                }
                // we can break here.
                if (dst.hasRemaining())
                    read += readFromAppBuffer(dst);
                else
                    break;
            } else if (unwrapResult.getStatus() == Status.BUFFER_UNDERFLOW) {
                int currentNetReadBufferSize = netReadBufferSize();
                netReadBuffer = Utils.ensureCapacity(netReadBuffer, currentNetReadBufferSize);
                if (netReadBuffer.position() >= currentNetReadBufferSize) {
                    throw new IllegalStateException("Buffer underflow when available data size (" + netReadBuffer.position() + ") > packet buffer size (" + currentNetReadBufferSize + ")");
                }
                break;
            } else if (unwrapResult.getStatus() == Status.CLOSED) {
                // If data has been read and unwrapped, return the data. Close will be handled on the next poll.
                if (appReadBuffer.position() == 0 && read == 0)
                    throw new EOFException();
                else
                    break;
            }
        } while (netReadBuffer.position() != 0);
    }
    return read;
}
Also used : SSLEngineResult(javax.net.ssl.SSLEngineResult) EOFException(java.io.EOFException)

Example 92 with SSLEngineResult

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

the class SslTransportLayer method close.

/**
    * Sends a SSL close message and closes socketChannel.
    */
@Override
public void close() throws IOException {
    if (closing)
        return;
    closing = true;
    sslEngine.closeOutbound();
    try {
        if (isConnected()) {
            if (!flush(netWriteBuffer)) {
                throw new IOException("Remaining data in the network buffer, can't send SSL close message.");
            }
            //prep the buffer for the close message
            netWriteBuffer.clear();
            //perform the close, since we called sslEngine.closeOutbound
            SSLEngineResult wrapResult = sslEngine.wrap(emptyBuf, netWriteBuffer);
            //we should be in a close state
            if (wrapResult.getStatus() != SSLEngineResult.Status.CLOSED) {
                throw new IOException("Unexpected status returned by SSLEngine.wrap, expected CLOSED, received " + wrapResult.getStatus() + ". Will not send close message to peer.");
            }
            netWriteBuffer.flip();
            flush(netWriteBuffer);
        }
    } catch (IOException ie) {
        log.warn("Failed to send SSL Close message ", ie);
    } finally {
        try {
            socketChannel.socket().close();
            socketChannel.close();
        } finally {
            key.attach(null);
            key.cancel();
        }
    }
}
Also used : SSLEngineResult(javax.net.ssl.SSLEngineResult) IOException(java.io.IOException)

Example 93 with SSLEngineResult

use of javax.net.ssl.SSLEngineResult in project http-kit by http-kit.

the class HttpsRequest method unwrapRead.

final int unwrapRead(ByteBuffer peerAppData) throws IOException {
    // TODO, make sure peerNetData has remaining place
    int read = ((SocketChannel) key.channel()).read(peerNetData), unwrapped = 0;
    if (read > 0) {
        peerNetData.flip();
        SSLEngineResult res;
        while ((res = engine.unwrap(peerNetData, peerAppData)).getStatus() == Status.OK) {
            unwrapped += res.bytesProduced();
            if (!peerNetData.hasRemaining())
                break;
        }
        peerNetData.compact();
        switch(res.getStatus()) {
            case OK:
            case // need more data
            BUFFER_UNDERFLOW:
                return unwrapped;
            case CLOSED:
                return unwrapped > 0 ? unwrapped : -1;
            case BUFFER_OVERFLOW:
                // can't => peerAppData is 64k
                return -1;
        }
        return unwrapped;
    } else {
        return read;
    }
}
Also used : SocketChannel(java.nio.channels.SocketChannel) SSLEngineResult(javax.net.ssl.SSLEngineResult)

Example 94 with SSLEngineResult

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

the class SslHandler method wrap.

private SSLEngineResult wrap(ByteBufAllocator alloc, SSLEngine engine, ByteBuf in, ByteBuf out) throws SSLException {
    ByteBuf newDirectIn = null;
    try {
        int readerIndex = in.readerIndex();
        int readableBytes = in.readableBytes();
        // We will call SslEngine.wrap(ByteBuffer[], ByteBuffer) to allow efficient handling of
        // CompositeByteBuf without force an extra memory copy when CompositeByteBuffer.nioBuffer() is called.
        final ByteBuffer[] in0;
        if (in.isDirect() || !engineType.wantsDirectBuffer) {
            // which is better then walking the composed ByteBuf in most cases.
            if (!(in instanceof CompositeByteBuf) && in.nioBufferCount() == 1) {
                in0 = singleBuffer;
                // We know its only backed by 1 ByteBuffer so use internalNioBuffer to keep object allocation
                // to a minimum.
                in0[0] = in.internalNioBuffer(readerIndex, readableBytes);
            } else {
                in0 = in.nioBuffers();
            }
        } else {
            // We could even go further here and check if its a CompositeByteBuf and if so try to decompose it and
            // only replace the ByteBuffer that are not direct. At the moment we just will replace the whole
            // CompositeByteBuf to keep the complexity to a minimum
            newDirectIn = alloc.directBuffer(readableBytes);
            newDirectIn.writeBytes(in, readerIndex, readableBytes);
            in0 = singleBuffer;
            in0[0] = newDirectIn.internalNioBuffer(newDirectIn.readerIndex(), readableBytes);
        }
        for (; ; ) {
            ByteBuffer out0 = out.nioBuffer(out.writerIndex(), out.writableBytes());
            SSLEngineResult result = engine.wrap(in0, out0);
            in.skipBytes(result.bytesConsumed());
            out.writerIndex(out.writerIndex() + result.bytesProduced());
            switch(result.getStatus()) {
                case BUFFER_OVERFLOW:
                    out.ensureWritable(maxPacketBufferSize);
                    break;
                default:
                    return result;
            }
        }
    } finally {
        // Null out to allow GC of ByteBuffer
        singleBuffer[0] = null;
        if (newDirectIn != null) {
            newDirectIn.release();
        }
    }
}
Also used : CompositeByteBuf(io.netty.buffer.CompositeByteBuf) SSLEngineResult(javax.net.ssl.SSLEngineResult) CompositeByteBuf(io.netty.buffer.CompositeByteBuf) ByteBuf(io.netty.buffer.ByteBuf) ByteBuffer(java.nio.ByteBuffer)

Example 95 with SSLEngineResult

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

the class SslHandler method wrap.

// This method will not call setHandshakeFailure(...) !
private void wrap(ChannelHandlerContext ctx, boolean inUnwrap) throws SSLException {
    ByteBuf out = null;
    ChannelPromise promise = null;
    ByteBufAllocator alloc = ctx.alloc();
    boolean needUnwrap = false;
    try {
        // See https://github.com/netty/netty/issues/5860
        while (!ctx.isRemoved()) {
            Object msg = pendingUnencryptedWrites.current();
            if (msg == null) {
                break;
            }
            ByteBuf buf = (ByteBuf) msg;
            if (out == null) {
                out = allocateOutNetBuf(ctx, buf.readableBytes(), buf.nioBufferCount());
            }
            SSLEngineResult result = wrap(alloc, engine, buf, out);
            if (result.getStatus() == Status.CLOSED) {
                // SSLEngine has been closed already.
                // Any further write attempts should be denied.
                pendingUnencryptedWrites.removeAndFailAll(SSLENGINE_CLOSED);
                return;
            } else {
                if (!buf.isReadable()) {
                    promise = pendingUnencryptedWrites.remove();
                } else {
                    promise = null;
                }
                switch(result.getHandshakeStatus()) {
                    case NEED_TASK:
                        runDelegatedTasks();
                        break;
                    case FINISHED:
                        setHandshakeSuccess();
                    // deliberate fall-through
                    case NOT_HANDSHAKING:
                        setHandshakeSuccessIfStillHandshaking();
                    // deliberate fall-through
                    case NEED_WRAP:
                        finishWrap(ctx, out, promise, inUnwrap, false);
                        promise = null;
                        out = null;
                        break;
                    case NEED_UNWRAP:
                        needUnwrap = true;
                        return;
                    default:
                        throw new IllegalStateException("Unknown handshake status: " + result.getHandshakeStatus());
                }
            }
        }
    } finally {
        finishWrap(ctx, out, promise, inUnwrap, needUnwrap);
    }
}
Also used : ByteBufAllocator(io.netty.buffer.ByteBufAllocator) SSLEngineResult(javax.net.ssl.SSLEngineResult) ChannelPromise(io.netty.channel.ChannelPromise) CompositeByteBuf(io.netty.buffer.CompositeByteBuf) ByteBuf(io.netty.buffer.ByteBuf)

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