什么是OpenSSL BIO?
OpenSSL BIO是一个提供输入/输出相关功能的API。
它的基本思想是什么?它与stdio API或sockets API有何不同?
第一个想法是,它不是某种特定类型IO(例如,文件或网络)的API。它是能够进行输入/输出操作的各种类型实体的通用API。它类似于具有纯虚函数的C++抽象类。您只需使用一个接口,但根据使用的是哪个特定的BIO对象,其行为会有所不同。例如,它可以是套接字对象或文件对象。如果你使用
BIO_write
函数使用套接字对象,数据将通过网络发送。如果你使用
写简历
函数与一个文件对象,数据将写入一个文件。
OpenSSL BIO API背后的第二个想法是,BIO对象可以堆叠成一个线性链。它允许在将数据发送到最终输出(sink)或从初始输入(source)读取数据之前,通过不同的过滤器处理数据。过滤器也是生物对象。
什么是过滤生物?什么是源生物?什么是水槽生物?
OpenSSL filter BIO是一个获取数据、处理数据并将其传递给另一个BIO的BIO。
OpenSSL源BIO不是从另一个BIO获取数据,而是从其他地方(从文件、网络等)获取数据。
OpenSSL sink BIO是一个BIO,它不会将数据传递给另一个BIO,而是将数据传输到其他地方(文件、网络等)。
至于源和汇BIOs,没有专门的源BIOs,也没有专门的汇BIOs,只有“源-汇”BIOs。源生物也是汇生物。例如,socket BIO同时是源BIO和汇BIO。当数据被写入socket BIO时,BIO作为接收器工作。当从套接字BIO读取数据时,BIO将作为源工作。源-宿BIOs始终是生物链的终止部分。这不同于通常的数据处理管道,其中源是管道的起点,汇是管道的终点。
如何通过筛选生物记录运行数据?我必须使用
写简历
函数并使用
BIO_read
功能?
如果使用
写简历
函数,仅通过调用
生物阅读
在生物上起作用。过滤BIOs以不同的方式工作。过滤器BIO可以避免将处理过的数据存储在缓冲区中。它可能只是获取输入数据,对其进行处理,然后立即使用相同的方法将其传递给链中的下一个BIO
写简历
用于将数据放入BIO的函数。下一个BIO在处理之后,可能会将数据写入链中的下一个BIO。如果某个BIO将数据存储在其内部缓冲区中(如果没有足够的数据为下一个BIO生成输出),或者如果数据到达接收器,则进程停止。
如果只需要通过筛选BIO运行数据而不通过网络发送或不将其写入文件,则可以将筛选BIO附加到OpenSSL内存BIO(即创建以下链:
filter bio <-> memory bio
). 内存BIO是源-汇BIO,但它不向任何地方发送数据,它只是将数据存储在内存缓冲区中。将数据写入过滤器BIO后,数据将写入内存BIO,内存BIO将其存储在内存缓冲区中。内存BIO有特殊的接口,可以直接从缓冲区获取数据(尽管您可以使用
生物阅读
要获取写入内存BIO的数据,请参见下文)。
从过滤生物中读取的工作方式与此相反。如果您请求从筛选器BIO读取数据,则筛选器BIO可能会反过来请求从链中的下一个BIO读取数据。如果某个BIO有足够的缓冲数据返回,或者如果进程到达源BIO,则进程停止。一个电话
生物阅读
筛选器BIO上的函数可能导致对
生物阅读
函数从下一个BIO获取数据。过滤器BIO将继续调用
生物阅读
直到它得到足够的数据来生成处理结果。
如果链的源-汇BIO以非阻塞模式工作,则情况更为复杂。例如,使用非阻塞套接字或使用内存BIO(内存BIOs本质上是非阻塞的)。
还请注意,与写入该BIO时所做的处理相比,从filter BIO中读取会使数据处理发生逆转。例如,如果您使用密码BIO,那么写入BIO将对写入的数据进行加密,但从该BIO读取将对输入数据进行解密。这样就可以形成这样的链条:
your code <-> cipher BIO <-> socket BIO
. 将未加密的数据写入密码BIO,密码BIO对其进行加密并将其发送到套接字。从密码BIO读取时,首先从套接字获取加密数据,然后对其进行解密并将未加密数据返回给您。这允许您通过网络设置加密通道。你只是用
写简历
和
生物阅读
所有的加密/解密都是由生物链自动完成的。
通常,生物链如下图所示:
/------\ /--------\ /---------\ /-------------\
| your | -- BIO_write -> | filter | -- BIO_write -> | another | -- BIO_write -> | source/sink |
| | | | | filter | | |
| code | <- BIO_read -- | BIO | <- BIO_read -- | BIO | <- BIO_read -- | BIO |
\------/ \--------/ \---------/ \-------------/
为什么OpenSSL需要BIOs?在使用OpenSSL编程时如何使用它们?有什么例子吗?
OpenSSL在操作SSL/TLS协议时使用BIOs与远程端通信。这个
SSL_set_bio
函数用于设置BIOs,以便在SSL/TLS链接的具体实例中进行通信。例如,您可以使用socket BIO通过网络连接运行SSL/TLS协议。但您也可以开发自己的BIO(是的,这是可能的),或者使用内存BIO通过自己的链接类型运行SSL/TLS协议。
您还可以将SSL/TLS链接的实例包装为BIO本身(
BIO_f_ssl
). 打电话
写简历
在SSL BIO上将导致调用
SSL_write
. 打电话
生物阅读
将导致调用
SSL_read
.
虽然SSL BIO是一个过滤BIO,但它与其他过滤BIO有点不同。打电话
写简历
在SSL BIO上可能会导致
生物阅读
和
写简历
调用链中的下一个BIO。因为
SSL写入
(用于
写简历
SSL BIO)不仅发送数据,还提供操作SSL/TLS协议,该协议可能需要双方之间的多个数据交换步骤来执行某些协商。同样的道理
生物阅读
SSL生物。这就是SSL BIOs与普通过滤器BIOs的不同之处。
还要注意,您不需要使用SSL BIO。你还可以用
SSL读取
和
SSL写入
直接的。
OpenSSL提供哪些BIOs?你能提供BIOs的例子并说明它们之间的区别吗?
以下是OpenSSL提供的源-宿BIOs示例:
-
档案简介(
BIO_s_file
). 这是一个包装纸
FILE*
反对。它用于写入和读取文件。
-
文件描述符BIO(
BIO_s_fd
). 它类似于文件BIO,但使用POSIX文件描述符而不是stdio文件。
-
插口式简历(
BIO_s_socket
). 它是POSIX套接字的包装器。它用于通过网络进行通信。
-
无效的简历(
BIO_s_null
). 它类似于
/dev/null
POSIX系统中的设备。写入此BIO只会丢弃数据,从中读取会导致EOF(文件结尾)。
-
记忆传记(
BIO_s_mem
). 它本质上是一个回环生物。从这种类型的BIO读取将返回以前写入BIO的数据。但是,也可以通过调用特定于此类型BIO的函数(每种BIO都有仅特定于此类型BIO的函数)从(或放置到)内部缓冲区中提取数据。
-
“生物”生物(
BIO_s_bio
). 这是一个像管子一样的生物。可以创建一对这样的BIOs。写入两个BIO中一个BIO的数据将被放置以读取到两个BIO中的第二个BIO。反之亦然它类似于内存BIO,但内存BIO将数据放置到自身,并将BIO放置数据管道到与其配对的BIO。
关于
生物记忆
和
比奥
可以在这里找到:
OpenSSL âBIO_s_memâ VS âBIO_s_bioâ
.
下面是过滤器BIOs的示例:
-
base64生物(
BIO_f_base64
).
写简历
通过这个BIO将数据编码为base64格式。
生物阅读
通过这个BIO解码来自base64格式的数据。
-
密码生物(
BIO_f_cipher
). 它加密/解密通过它的数据。可以使用不同的加密算法。
-
摘要计算简介(
BIO_f_md
). 它不会修改通过它传递的数据。它只计算流经它的数据摘要,而不改变数据本身可以使用不同的摘要计算算法。可以使用特殊函数检索计算出的摘要。
-
缓冲生物(
BIO_f_buffer
). 它也不会改变通过它的数据。写入此BIO的数据是缓冲的,因此并非每个写入此BIO的操作都会导致将数据写入下一个BIO。至于阅读,情况也差不多。这允许减少位于缓冲IO后面的BIOs上的IO操作数。
-
SSL简介(
生物安全
). 这种类型的生物是在上面描述的。它将SSL链接包装在里面。