为什么SSL_set_bio将两个指向 BIOS 的指针作为参数?(OpenSSL "BIO_s_mem" VS "BIO_s_bio" )



SSL_set_bio使用两个OpenSSL BIOs:输入BIO(rbio(和输出BIO(wbio(。第一个用于OpenSSL需要从远程端获取数据时,第二个用于OpenSSSL需要向远程端发送数据时。通常这两个BIO是相同的(它们是指向同一个BIO对象的指针(。例如,它可以是一个套接字BIO(BIO_s_socket(。当OpenSSL需要数据时,它从该套接字BIO接收数据。它使用相同的套接字BIO发送数据。因此,一个BIO对象就足够了。

当需要两个不同的BIOs时,我能想到的唯一情况是当使用内存BIO(BIO_s_mem(时。内存BIO类似于环回BIO:写入内存BIO的任何数据都将在随后的读取操作中从中读取。当应用程序在不使用OpenSSL BIOs的情况下自行实现数据传输时,需要内存BIO。应用程序使用自己的功能从远程端接收数据,然后将其放入输入内存BIO,以便OpenSSL可以获取数据。相反的过程是:OpenSSL将输出数据放入输出内存BIO中,然后应用程序使用自身的功能从输出BIO获取数据并将其发送到远程端。由于需要两个缓冲区(输入和输出(,因此单个SSL/TLS链路使用两个不同的内存BIOs。

但除此之外,还有一个名为BIO_s_bio的BIO,它具有类似管道的功能。可以创建一对这样的BIOs。写入BIO_s_bio对象对中的第一个BIO的任何数据将从该对中的第二个BIO读取。反之亦然:将数据写入第二个BIO将导致从第一个BIO读取该数据。因此可以使用BIO_s_bio而不是BIO_s_mem。将BIO_s_bio对象的单个实例传递给SSL_set_bio函数就足够了。应用程序接收数据并将其写入BIO_s_bio对中的BIO。然后,OpenSSL将从该对中的BIO获取这些数据。OpenSSL将数据写入对中的BIO,应用程序依次从其BIO获取这些数据。

SSL_set_bio是否只需要两个指向BIOs的指针来使用带有内存BIO的OpenSSL?在SSL_set_bio函数中使用两个不同的BIOs可能有帮助的其他例子吗?

如果可以使用BIO_s_bio,是否需要BIO_s_mem?使用BIO_s_mem而不是使用BIO_s_bio有什么好处吗?

通常SSL/TLS使用一个TCP套接字作为链接。在这种情况下,您可以使用以下函数将fd设置为ssl:

SSL_set_fd(ssl, tcp_socket_fd);

但是,也可能存在使用2个单向文件描述符而不是一个TCP套接字的用例。

例如,如果您想将TLS服务器实现为tcpd的子级。那么您的服务器的TCP流量文件描述符是:

输入流的STDIN_FILENO
  • 输出流的STDOUT_FILENO
  • 在这种情况下,不能使用SSL_set_fd(),您可以使用两个BIOs:

    // not tested
    BIO* in = BIO_new_fd(STDIN_FILENO, 0);
    BIO* out = BIO_new_fd(STDOUT_FILENO, 0);
    SSL_set_bio(ssl, in, out);
    

    也许使用SSL_set_rfd()SSL_set_wfd()更好。但这只是一个例子。

    最新更新