【问题标题】:ConscryptEngine data read issue : Unable to parse TLS packet headerConscryptEngine 数据读取问题:无法解析 TLS 数据包标头
【发布时间】:2020-08-10 09:30:01
【问题描述】:

下面是解包从 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 缓冲区在展开期间仍有一些数据需要读取,因此我扩大了 mPeerAppData 缓冲区以容纳更多数据,这些数据必须在下一次迭代中从 mPeerNetData 缓冲区读取。

我已经调试了流程并且可以验证 mPeerAppData 缓冲区有足够的空间来保存数据,而且 mPeerNetData 缓冲区有待解包的数据。

但在展开过程中,我收到以下错误:

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)

请建议我们如何避免这个错误?

【问题讨论】:

标签: android socketchannel tcpsocket sslengine openssl-engine


【解决方案1】:

花了几天时间调试代码,我才知道这个问题的根本原因。

在下面的操作中我发现上面的代码开始正常工作

result = mSslEngine.unwrap(mPeerNetData, mPeerAppData);

其中mPeerNetData 是包含从socketChannel 读取的加密字节的缓冲区,mPeerAppData 是在unwrap 操作之后保存解密字节的缓冲区。

解包操作成功解密来自mPeerNetData 的数据包后,仍有一些字节剩余,不足以再次执行unwrap 操作。要进一步进行unwrap 操作,我们需要再次从socketChannel 读取更多数据,但请记住,我们不应该清除mPeerNetData,而是应该将新数据添加到mPeerNetData,它之前还剩下一些字节。

之前的左字节必须在缓冲区中才能成功解密数据,因为每次展开都会尝试从数据包中读取一些初始字节。这样,在下一次展开操作期间,操作将成功完成。

另外请注意,要读取完整的socketChannel 数据,您应该有一些while loop 逻辑来调用此方法,直到您从通道读取完整数据。

【讨论】:

  • 嗨,Ashok,你能解释一下你是如何解决这个问题的吗?
猜你喜欢
  • 2021-07-25
  • 1970-01-01
  • 2018-04-18
  • 2021-04-15
  • 2019-10-17
  • 1970-01-01
  • 1970-01-01
  • 2020-08-01
  • 1970-01-01
相关资源
最近更新 更多