1

I am using an SSLEngine over Java NIO unblocking server sockets to handle connections. I am able to successfully handshake the clients and pass small record sets to the server. However when I try to transfer a file to the server text/binary I am getting the following error:

javax.net.ssl.SSLException: Unsupported record version Unknown-0.0
  at sun.security.ssl.InputRecord.checkRecordVersion(InputRecord.java:552)
  at sun.security.ssl.EngineInputRecord.bytesInCompletePacket(EngineInputRecord.java:113)
  at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:862)
  at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:775)
  at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
  at ncp.io.network.tls.TLSWrapper.unwrap(TLSWrapper.java:170)
  at ncp.io.network.tls.TLSIO.decodeData(TLSIO.java:110)
  at ncp.io.network.tls.TLSIO.handleRead(TLSIO.java:71)
  at ncp.io.network.SocketThread.run(SocketThread.java:137)

I am however unable to find out the reason for this error.

Below is my code snippet

@Override
public int handleRead(ByteBuffer temp) {

    int read = opsManager.handleRead(temp);

    if (read > 0) {

        try {
            tlsDecodeBuffer = decodeData(temp);

            try {
                temp.clear();
                temp.put(tlsDecodeBuffer);
            }catch (BufferOverflowException e){
                temp = ByteBuffer.allocateDirect(tlsDecodeBuffer.remaining());
                temp.put(tlsDecodeBuffer);
            }

            temp.flip();
            temp.rewind();

            if(tlsDecodeBuffer.hasRemaining())
                tlsDecodeBuffer.compact();
            else
                tlsDecodeBuffer.clear();

        }catch (SSLException e){
            // Error occurs here: 
            e.printStackTrace();
            log.warning("Insecure connection attempted/ SSL failure for:" + e.getMessage());
            opsManager.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }

        return read;
    } else {
        return -1;
    }
}

private ByteBuffer decodeData(ByteBuffer input) throws IOException {
    ncp.io.network.tls.TLSStatus stat = null;
    boolean continueLoop = true;

    do {

        tlsDecodeBuffer = wrapper.unwrap(input, tlsDecodeBuffer);

        switch (wrapper.getStatus()) {
            case NEED_WRITE:
                writeBuff(ByteBuffer.allocate(0));
                break;

            case UNDERFLOW:
                if (tlsDecodeBuffer.capacity() == tlsDecodeBuffer.remaining()) {
                    throw new BufferUnderflowException();
                } else {
                    input.compact();
                    continueLoop = false;
                }

                break;
            case CLOSED:
                if (log.isLoggable(Level.FINER)) {
                    log.finer("TLS Socket closed..." + toString());
                }

                throw new EOFException("Socket has been closed.");
            default:
                break;
        }

        stat = wrapper.getStatus();

    } while (continueLoop && ((stat == TLSStatus.NEED_READ) || (stat == TLSStatus.OK))
            && input.hasRemaining());

    if (continueLoop) {
        if (input.hasRemaining()) {
            input.rewind();
        } else {
            input.clear();
        }
    }

    tlsDecodeBuffer.flip();
    return tlsDecodeBuffer;
}
4

1 回答 1

0

你的代码没有意义。

  1. 当你进入BufferOverflowExceptionunwrap(),你需要通过清空目标缓冲区flip()/get()/compact().

  2. 当您进入BufferOverflowExceptionwrap(),您需要通过连接到网络的flip()/write()/compact(),地方清空目标缓冲区。write()

    在这两种情况下,分配新缓冲区等都没有任何意义。

  3. rewind()afterflip()在任何情况下都没有意义。

这里有很多关于如何SSLEngine正确使用的帖子和答案。我建议你仔细阅读它们。

于 2015-01-16T08:49:50.107 回答