如何使用OpenSSL BIO?结合 BIO_s_socket 和 BIO_f_ssl

问题描述 投票:0回答:1

我正在编写一个简单的应用程序来使用 OpenSSL 连接到服务器。最初的想法是编写一个自定义的 BIO 方法来通过 linux 的 SO_TIMESTAMPING 获取有关硬件套接字时间戳的信息,但与此同时,我意识到我在如何构建正确的 BIO 方面遗漏了一些东西,所以我从刮擦。

最基本的想法:让我们使用 BIO 连接到套接字并使用 BIO 来执行加密操作,以便重新创建 SSL_write 和 SSL_read 的基本行为。 实例化 BIO 方法并将其绑定到 SSL 的代码如下:

BIO *default_sck_bio = BIO_new(BIO_s_socket());
BIO *default_ssl_bio = BIO_new(BIO_f_ssl());
BIO *sock_bio = BIO_new(BIO_s_socket());
BIO *ssl_bio = BIO_new(BIO_f_ssl());
BIO_push(default_sck_bio, default_ssl_bio);
SSL_set_bio(ssl, default_sck_bio, default_sck_bio);

通过这种方式,我希望 SSL_read 在底层执行基于 BIO 的 recv(),然后执行 SSL 加密,而对于 SSL_write,执行 SSL 加密,然后执行基于 BIO 的 send()。但是,我的 SSL_connect 不断生成 SSL_ERROR_SSL 并显示错误消息:

error:10000078:BIO routines::uninitialized
。我是不是错过了什么?

解决了这个问题后,我的初衷是编写一个自定义的 BIO 方法,但接下来的问题突然出现在我的脑海中:如何从读/写 BIO 回调内部调用 SSL 加密函数(我通过

BIO_meth_set_read设置) 
)?

c openssl
1个回答
0
投票

经过几天的谷歌搜索,我终于明白了 BIO 是如何工作的。

首先,与加密相关的编码/解码是在调用

SSL_read
SSL_write
时在后台管理的。

在问题的基本示例中,不需要

BIO *ssl_bio
。要获得问题中的功能,代码可以更改为:

BIO *default_sck_bio = BIO_new(BIO_s_socket());
BIO *sock_bio = BIO_new(BIO_s_socket());
SSL_set_bio(ssl, default_sck_bio, default_sck_bio);

下图让我们更好地理解流程(感谢 darrenjs 的要点):

  +------+                                    +-----+

  |......|--> read(fd) --> BIO_write(rbio) -->|.....|--> SSL_read(ssl)  --> IN

  |......|                                    |.....|

  |.sock.|                                    |.SSL.|

  |......|                                    |.....|

  |......|<-- write(fd) <-- BIO_read(wbio) <--|.....|<-- SSL_write(ssl) <-- OUT

  +------+                                    +-----+

          |                                  |       |                     |

          |<-------------------------------->|       |<------------------->|

          |         encrypted bytes          |       |  unencrypted bytes  |

总之,要回答“如何从读/写 BIO 回调内部调用 SSL 加密函数(我通过

BIO_meth_set_read
设置)?”的问题:一旦您通过使用
BIO_meth_set_read
设置的读取方法访问数据,数据已经被加密。同样,写入回调中访问的数据也将尚未被解密。

使用自定义BIO方法仍然存在问题,我写的客户端仍然返回错误。看看这个评论,看起来这是一个与openssl 3.0相关的问题。

© www.soinside.com 2019 - 2024. All rights reserved.