套接字库的OpenSSL自定义内存BIO

套接字库的OpenSSL自定义内存BIO,openssl,Openssl,我正在使用一个模拟Berkeley sockets API的传输库来处理它(包括阻塞和非阻塞模式)。需要向我发送的数据添加TLS加密,可以考虑两种方式: 自定义BIO:找到Socket BIO的代码,所以考虑复制它,并用该库的函数替换所有berkeley Socket调用。然而,我在网上找不到很多关于自定义BIOs的信息,所以我很小心在没有得到太多帮助的情况下遇到的陷阱 记忆生物:这种方法有更多的追随者和相当多的例子。不过,大多数人警告说,带有非阻塞套接字的内存BIO比阻塞路由复杂一个数量级 关

我正在使用一个模拟Berkeley sockets API的传输库来处理它(包括阻塞和非阻塞模式)。需要向我发送的数据添加TLS加密,可以考虑两种方式:

  • 自定义BIO:找到Socket BIO的代码,所以考虑复制它,并用该库的函数替换所有berkeley Socket调用。然而,我在网上找不到很多关于自定义BIOs的信息,所以我很小心在没有得到太多帮助的情况下遇到的陷阱

  • 记忆生物:这种方法有更多的追随者和相当多的例子。不过,大多数人警告说,带有非阻塞套接字的内存BIO比阻塞路由复杂一个数量级

  • 关于内存BIO方法,我看到的源代码对我来说很有意义,但它是一个简单的echo客户端/服务器。让我非常困惑的是,当SSL\u Read/SSL\u Write返回SSL\u WANT\u Read或SSL\u WANT\u Write时该怎么做。我的理解是,在阻塞Socket BIO的情况下,您只需稍后重试调用,因为底层代码将处理这些事情

    在内存BIO+非阻塞套接字的情况下,例如,如果SSL_Read返回SSL_WANT_WRITE,这是否意味着我的代码应该从输出BIO(BIO_Read)读取并发送到套接字,并且在原始SSL_Read调用成功之前不允许任何SSL_Read/SSL_WRITE?在此期间允许SSL_写入可以吗

    编辑:我将专门使用TLS1.3,只是发现它不支持重新协商。这是否意味着一旦建立了连接,我就不必担心“在SSL上写”、“在SSL上读”、“在SSL上写”了?

    “在内存BIO+非阻塞套接字的情况下,例如,如果SSL\u Read返回SSL\u想写,这是否意味着我的代码应该从输出BIO(BIO\u Read)读取并将其发送到套接字”——是的。获取输出BIO中的所有字节并将它们写入套接字

    解释了为什么会发生这种情况:

    任何TLS/SSL I/O函数都可能导致SSL错误、想要读取和 SSL\u错误\u需要\u写入。特别是SSL_read_ex()、SSL_read(), SSL_peek_ex()或SSL_peek()可能要写入数据,而SSL_write()或 SSL_write_ex()可能要读取数据。这主要是因为TLS/SSL 握手可以在协议期间的任何时间发生(由 客户机或服务器);SSL_read_ex(),SSL_read(), SSL_peek_ex()、SSL_peek()、SSL_write_ex()和SSL_write()将处理 任何悬而未决的握手

    一旦SSL_读取以这种方式失败,我认为在将更多字节写入输入bio之前,进一步尝试SSL_读取不会成功

    同时,您可以进一步尝试SSL_写入;只需检查返回代码和SSL状态,以检查数据是否部分或完全传入


    我有一些写在上面的示例代码

    您的代码是否已经过全面的bug测试?这看起来比我预想的要简单。例如,在do_encrypt中,如果SSL_Write返回WANT_READ,则不存在处理该场景的情况,循环将立即再次重试SSL_Write。这是正确的吗?这是示例代码,不能保证没有bug或完全正确(尽管我在prod中使用它的变体已有几年了)。若SSL_写入未成功(如WANT_READ),则函数将返回select/poll循环。请参见此处,当使用非阻塞套接字时,无需执行任何操作,但可以使用select()检查所需的条件。[我只是在我的问题中添加了一个注释,基本上,我将专门使用TLS 1.3,因此我认为在建立连接后,我不需要担心WANT_WRITE&WANT_READ。相关问题:OpenSSL文档说SSL_READ将返回一个TLS记录。这是否意味着每次SSL_写入中的数据都被视为单独的记录(消息)SSL_Read将不断请求数据,直到它能够组装完整的记录(消息)?关于TLS 1.3的有趣点。根据文档,对于SSL_Read,似乎是肯定的,它“基于SSL/TLS记录……只有在完全接收到记录后,它才能被处理”。至于SSL_write,我认为单个调用可以生成多个记录。从两个不同的线程同时调用SSL_read和SSL_write可以吗?例如,如果SSL_read被阻止(阻止套接字)等待数据,另一个线程调用SSL_write可以吗?