简体   繁体   English

ConscryptEngine 数据读取问题:无法解析 TLS 数据包 header

[英]ConscryptEngine data read issue : Unable to parse TLS packet header

Below i the code for unwrap the data packets received from sslengine:下面是解包从 sslengine 接收到的数据包的代码:

private ByteBuffer doUnwrap() throws IOException {
        if (mPeerNetData.position() == 0) {
            // The network input buffer is empty; read data from the channel before doing the unwrap
            final int count = mSocketChannel.read(mPeerNetData);
            Log.d(TAG, "bytesRead : " + count);
            if (count == -1) {
                handleEndOfStream(mSocketChannel, mSslEngine);
                return null;
            }
        }

        Log.d(TAG, "isReadPending :" + isReadPending);
        if (!isReadPending) {
            mPeerNetData.flip();
        }

        final SSLEngineResult result;
        try {
            result = mSslEngine.unwrap(mPeerNetData, mPeerAppData);
        } catch (SSLException e) {
            Log.d(TAG, "Exception while calling SSLEngine.unwrap()" + e);
            shutdown();
            return null;
        }
        mPeerNetData.compact();
        Log.d(TAG, "Result of SSLEngine.unwrap(): {}" + result.getStatus());


        final SSLEngineResult.Status status = result.getStatus();
        switch (status) {
            case OK:
                if (mPeerNetData.position() != 0) {
                    isReadPending = true;
                    mPeerAppData = ensureRemaining(mPeerAppData, mSslEngine.getSession().getApplicationBufferSize());
                    doUnwrap();
                }
                break;

            case CLOSED:
                closeConnection(mSocketChannel, mSslEngine);
                break;

            case BUFFER_UNDERFLOW:
                // The network input buffer might not have enough space, re-allocate if necessary
                // (NOTE: packet buffer size as reported by the SSL session might change dynamically)
                mPeerNetData = ensureRemaining(mPeerNetData, mSslEngine.getSession().getPacketBufferSize());

                // Read data from the channel, retry unwrap if not end-of-stream
                final int count = mSocketChannel.read(mPeerNetData);
                if (count == -1) {
                    handleEndOfStream(mSocketChannel, mSslEngine);
                    return null;
                }
                doUnwrap();
                break;

            case BUFFER_OVERFLOW:
                // The application input buffer does not have enough space, re-allocate and retry unwrap
                // (NOTE: application buffer size as reported by the SSL session might change dynamically)
                mPeerAppData = ensureRemaining(mPeerAppData, mSslEngine.getSession().getApplicationBufferSize());
                doUnwrap();
                break;

            default:
                throw new IllegalStateException("Invalid SSL status: " + status);
        }

        return mPeerAppData;
    }

mPeerNetData buffer has some data remains to read during unwrap and therefor i have enlarged the mPeerAppData buffer to hold the more data that has to be read from mPeerNetData buffer in next iteration. mPeerNetData 缓冲区在展开期间仍有一些数据要读取,因此我扩大了 mPeerAppData 缓冲区以保存在下一次迭代中必须从 mPeerNetData 缓冲区读取的更多数据。

I have debugged the flow and can verify that mPeerAppData buffer has sufficient space to hold the data and also mPeerNetData buffer has data pending to be unwrap.我已经调试了流程,可以验证 mPeerAppData 缓冲区是否有足够的空间来保存数据,并且 mPeerNetData 缓冲区有待解包的数据。

But during unwrap i am getting the error has below:但是在展开过程中,我收到以下错误:

javax.net.ssl.SSLException: Unable to parse TLS packet header
at org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:798)
at org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:738)

Please suggest how we can avoid this error?请建议我们如何避免这个错误?

After spending few days and debugging the code, i was able to know the root cause of this issue.在花了几天时间调试代码之后,我能够知道这个问题的根本原因。

Above codes start working fine after i figured out that during the below operation在我发现在以下操作期间,上面的代码开始正常工作

result = mSslEngine.unwrap(mPeerNetData, mPeerAppData);

where mPeerNetData is buffer containing the encrypted bytes read from socketChannel and mPeerAppData is a buffer holding the decrypted bytes after unwrap operation.其中mPeerNetData是包含从socketChannel读取的加密字节的缓冲区,而mPeerAppData是在unwrap操作后保存解密字节的缓冲区。

After the unwrap operation successfully decrypt a packet from mPeerNetData , there were still some bytes left and were not sufficient to perform unwrap action again.解包操作成功解密来自mPeerNetData的数据包后,仍有一些字节剩余,不足以再次执行unwrap操作。 To do further unwrap operation, we need to read more data from socketChannel again but keep in mind we should not clear the mPeerNetData instead we should add the new data to mPeerNetData which has some bytes left previously.为了进一步unwrap操作,我们需要再次从socketChannel读取更多数据,但请记住,我们不应该清除mPeerNetData ,而是应该将新数据添加到之前剩余一些字节的mPeerNetData

Those previous left bytes are must to have in buffer for success-full decryption of data because each unwrap tries to read some initial bytes from the packet.In that way during next unwrap operation the action will success-full.那些先前的左字节必须在缓冲区中才能成功完整地解密数据,因为每个展开都会尝试从数据包中读取一些初始字节。这样,在下一次展开操作期间,操作将成功完成。

Also please note that to read complete socketChannel data you should have some while loop logic to invoke this method until you read the complete data from channel.另请注意,要读取完整socketChannel数据,您应该有一些while loop逻辑来调用此方法,直到您从通道中读取完整的数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM