本文介绍了什么是OpenSSL BIO?它们如何运作? OpenSSL中如何使用BIO?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一些有关OpenSSL BIO的常规信息.对它的某种介绍.什么是OpenSSL BIO?它的总体思路是什么?我知道这是某种用于输入/输出的API.但是,例如,它与stdio或套接字API有何不同?

I need some general information about OpenSSL BIO. Some kind of introduction to it. What is OpenSSL BIO? What is its general idea? I know that it is some kind of API for input/output. But how is it different from stdio or sockets API, for example?

我知道有源,接收和过滤BIO.什么是过滤器BIO?什么是源BIO?什么是接收器BIO?

I know that there are source, sink and filter BIOs. What is a filter BIO? What is a source BIO? What is a sink BIO?

据说过滤器BIO用于处理数据.如何使用过滤器BIO处理数据?我如何通过它运行数据?我是否必须使用BIO_write函数将数据馈送到过滤器BIO并使用BIO_read函数获取经过处理的数据?

It's said that a filter BIO is used to process data. How do I process data using a filter BIO? How can I run data through it? Do I have to feed the data to the filter BIO using the BIO_write function and get processed data using the BIO_read function?

为什么在OpenSSL中根本需要BIO?使用OpenSSL编程时如何使用它们?有例子吗?

Why are BIOs needed in OpenSSL at all? How are they used when programming with OpenSSL? Any examples?

OpenSSL提供哪些BIO?您能提供一些BIO的例子并说明它们之间的区别吗?

Which BIOs does OpenSSL provide? Can you provide examples of BIOs and tell about the differences between them?

推荐答案

OpenSSL BIO是提供输入/输出相关功能的API.

OpenSSL BIO is an API that provides input/output related functionality.

第一个想法是,它不是用于某些特定类型的IO(例如,用于文件或用于网络)的API.它是用于各种类型的具有输入/输出操作能力的实体的通用API.它类似于具有纯虚函数的C ++抽象类.您仅使用单个接口,但是行为因所使用的特定BIO对象而异.例如,它可以是套接字对象或文件对象.如果将BIO_write函数与套接字对象一起使用,则数据将通过网络发送.如果对文件对象使用BIO_write函数,则数据将被写入文件.

The first idea is that it is not an API for some specific type of IO (for example, for files or for network). It is generalized API for various types of entities capable of input/output operations. It is similar to C++ abstract classes with pure virtual functions. You just use a single interface but the behavior is different depending on which specific BIO object is used. For example, it can be a socket object or a file object. If you use the BIO_write function with a socket object, the data will be sent over network. If you use the BIO_write function with a file object, the data will be written to a file.

OpenSSL BIO API背后的第二个想法是BIO对象可以堆叠在一起成为单个线性链.它允许在将数据发送到最终输出(接收器)之前或从初始输入(源)读取数据之后,通过不同的过滤器处理数据.过滤器也是BIO对象.

The second idea behind OpenSSL BIO API is that BIO objects can be stacked together into a single linear chain. It allows to process data through different filters before sending it to the final output (sink) or after reading it from the initial input (source). Filters are also BIO objects.

OpenSSL筛选器BIO是一个BIO,它获取数据,对其进行处理并将其传递给另一个BIO.

An OpenSSL filter BIO is a BIO that takes data, processes it and passes it to another BIO.

OpenSSL源BIO是一种BIO,它不会从另一个BIO接收数据,而是从其他地方(从文件,网络等)获取数据.

An OpenSSL source BIO is a BIO that doesn't take data from another BIO but takes it from somewhere else (from a file, network, etc.).

OpenSSL接收器BIO是不会将数据传递到另一个BIO而是将其传输到其他地方(文件,网络等)的BIO.

An OpenSSL sink BIO is a BIO that doesn't pass data to another BIO but transfers it to somewhere else (to a file, network, etc.).

关于源BIO和接收BIO,没有特定的源BIO,也没有特定的接收BIO,只有源-接收" BIO.作为源BIO的BIO也是宿BIO.例如,套接字BIO同时是源BIO和宿BIO.将数据写入套接字BIO时,该BIO充当接收器.从套接字BIO读取数据时,BIO将作为源.源宿BIO始终是BIO链的终结部​​分.这与通常的数据处理管道不同,在常规数据处理管道中,源是管道的开始,而接收器是管道的结束.

As regard to source and sink BIOs, there are not specifically source BIOs and there are not specifically sink BIOs, there are only "source-sink" BIOs. The BIO which is a source BIO is a sink BIO as well. For example, a socket BIO is a source BIO and a sink BIO at the same time. When data is written to a socket BIO, the BIO works as a sink. When data is read from a socket BIO, the BIO works a source. Source-sink BIOs are always the terminating section of a BIO chain. This is different from a usual data processing pipeline where the source is the start of the pipeline and the sink is the end of the pipeline.

如果使用BIO_write函数将数据放入过滤器,则仅通过在BIO上调用BIO_read函数就无法获取处理后的数据.筛选器BIO的工作方式不同.过滤器BIO可以避免将处理后的数据存储在缓冲器中.它可能只使用输入数据,进行处理,然后立即使用与将数据放入BIO相同的BIO_write函数将其传递到链中的下一个BIO.接着,下一个BIO可以在处理之后将数据写入链中的下一个BIO.如果某些BIO将数据存储在其内部缓冲区中(如果它没有足够的数据来生成下一个BIO的输出),或者该数据到达接收器,则该过程将停止.

If you put data to a filter using the BIO_write function, you can't get processed data by simply calling the BIO_read function on the BIO. Filter BIOs work in a different way. A filter BIO may avoid storing processed data in a buffer. It may just take the input data, process it and immediately pass it to the next BIO in the chain using the same BIO_write function you used to put your data to the BIO. The next BIO, in turn, may, after processing, write the data to the next BIO in the chain. The process stops if either some BIO stores the data in its internal buffer (if it doesn't have enough data to generate output for the next BIO) or if the data reaches the sink.

如果您只需要通过过滤器BIO运行数据而无需通过网络发送数据或不将其写入文件,则可以将过滤器BIO附加到OpenSSL内存BIO(即,建立以下链:filter bio <-> memory bio).内存BIO是一个源宿BIO,但它不会将数据发送到任何地方,它只是将数据存储在内存缓冲区中.将数据写入过滤器BIO后,数据将被写入存储器BIO,并将其存储在存储器缓冲区中.内存BIO具有特殊的接口,可直接从缓冲区获取数据(尽管您可以使用BIO_read来获取已写入内存BIO的数据,请参见下文).

If you need just run data through a filter BIO without sending it over network or without writing it to a file, you can attach the filter BIO to an OpenSSL memory BIO (i.e. make the following chain: filter bio <-> memory bio). A memory BIO is a source-sink BIO, but it doesn't send data to anywhere, it just stores the data in a memory buffer. After writing the data to the filter BIO, the data will be written to the memory BIO which will store it in the memory buffer. A memory BIO has special interface to get the data directly from the buffer (though you can use BIO_read to get the data that was written to a memory BIO, see below).

从过滤器中读取BIO的工作方式相反.如果您请求从过滤器BIO读取数据,则过滤器BIO可能又请求从链中的下一个BIO读取数据.如果某个BIO具有足够的缓冲数据要返回,或者该过程到达了源BIO,则该过程将停止.一次调用过滤器BIO上的BIO_read函数可能会导致多次调用过滤器BIO中的BIO_read函数,以从下一个BIO获取数据.过滤器BIO将继续调用BIO_read,直到获得足够的数据以生成处理结果为止.

Reading from a filter BIO works in an opposite way. If you request to read data from a filter BIO, the filter BIO may, in turn, request to read data from the next BIO in the chain. The process stops if either some BIO has enough buffered data to return or if the process reaches the source BIO. A single call to the BIO_read function on a filter BIO may result in multiple calls to the BIO_read function inside the filter BIO to get data from the next BIO. A filter BIO will continue to call BIO_read until it gets enough data to generate processed result.

如果链的源宿BIO以非阻塞模式工作,则情况会更加复杂.例如,使用非阻塞套接字或使用内存BIO(内存BIO本质上是非阻塞的).

The situation is more complicated if the source-sink BIO of a chain works in non-blocking mode. For example, non-blocking sockets are used or memory BIO is used (memory BIOs are non-blocking by nature).

还请注意,与写入该BIO时所做的处理相比,从过滤器BIO进行读取确实会逆转数据处理.例如,如果您使用密码BIO,则对BIO进行写入将对已写入的数据进行加密,但是从该BIO进行读取将对输入数据进行解密.这样可以建立这样的链:your code <-> cipher BIO <-> socket BIO.您将未加密的数据写入密码BIO,该密码对其进行加密并将其发送到套接字.当您从密码BIO中读取时,它首先会从套接字获取加密的数据,然后对其解密并将未加密的数据返回给您.这使您可以通过网络设置加密通道.您只需使用BIO_writeBIO_read,所有加密/解密操作都是由BIO链自动完成的.

Also note that reading from a filter BIO does reversed data processing as compared to processing done when writing to that BIO. For example, if you use a cipher BIO, then writing to the BIO will encipher the written data, but reading from that BIO will decipher the input data. This allows to make a such chain: your code <-> cipher BIO <-> socket BIO. You write unencrypted data to the cipher BIO which encrypts it and sends it to the socket. When you read from the cipher BIO it, at first, gets encrypted data from the socket, then decrypts it and return unencrypted data to you. This allows you to set up encrypted channel through network. You just use BIO_write and BIO_read and all encryption/decryption is done automatically by the BIO chain.

通常,BIO链如下图所示:

In general a BIO chain looks like on the following diagram:

/------\                 /--------\                 /---------\                 /-------------\
| your | -- BIO_write -> | filter | -- BIO_write -> | another | -- BIO_write -> | source/sink |
|      |                 |        |                 |  filter |                 |             |
| code | <- BIO_read  -- |  BIO   | <- BIO_read  -- |   BIO   | <- BIO_read  -- |     BIO     |
\------/                 \--------/                 \---------/                 \-------------/

在运行SSL/TLS协议时,OpenSSL使用BIO与远程端进行通信. SSL_set_bio 函数用于设置BIO,以在SSL/TLS链接的具体实例中进行通信.例如,您可以使用套接字BIO通过网络连接运行SSL/TLS协议.但是您也可以开发自己的BIO(是可能的),或使用内存BIO通过自己的链接类型运行SSL/TLS协议.

OpenSSL uses BIOs for communicating with the remote side when operating SSL/TLS protocol. The SSL_set_bio function is used to set up BIOs for communicating in a concrete instance of an SSL/TLS link. You can use socket BIO, for example, to run SSL/TLS protocol via network connection. But you may also develop your own BIO (yes, it is possible) or use memory BIO to run SSL/TLS protocol via your own type of link.

您还可以将SSL/TLS链接的实例包装为BIO本身(BIO_f_ssl).在SSL BIO上调用BIO_write将导致调用SSL_write.调用BIO_read将导致调用SSL_read.

You can also wrap an instance of an SSL/TLS link as a BIO itself (BIO_f_ssl). Calling BIO_write on an SSL BIO will result in calling SSL_write. Calling BIO_read will result in calling SSL_read.

尽管SSL BIO是过滤器BIO,但与其他过滤器BIO略有不同.在SSL BIO上调用BIO_write可能会导致链中下一个BIO上同时发生BIO_readBIO_write调用.因为SSL_write(在SSL BIO的BIO_write内部使用)不仅发送数据,而且还提供可操作的SSL/TLS协议,这可能需要双方之间进行多个数据交换步骤才能进行某些协商. SSL BIO的BIO_read也是如此.这就是SSL BIO与普通过滤器BIO的不同之处.

Although SSL BIO is a filter BIO, it is a little different from other filter BIOs. Calling BIO_write on SSL BIO may result in series of both BIO_read and BIO_write calls on the next BIO in the chain. Because SSL_write (that is used inside of BIO_write of SSL BIO) not only sends data, but also provides operating SSL/TLS protocol which may require multiple data exchanging steps between sides to perform some negotiation. The same is true for BIO_read of SSL BIO. That is how SSL BIOs are different from ordinary filter BIOs.

还请注意,您不需要使用SSL BIO.您仍然可以直接使用SSL_readSSL_write.

Also note, that you are not required to use SSL BIO. You can still use SSL_read and SSL_write directly.

以下是OpenSSL提供的源库BIO的示例:

Here is examples of source-sink BIOs that OpenSSL provides:

  • 文件BIO(BIO_s_file).它是stdio的FILE*对象的包装.它用于写入和读取文件.
  • 文件描述符BIO(BIO_s_fd).它与文件BIO相似,但可用于POSIX文件描述符而不是stdio文件.
  • 插槽BIO(BIO_s_socket).它是POSIX套接字的包装.它用于通过网络进行通信.
  • 无效的BIO(BIO_s_null).它类似于POSIX系统中的/dev/null设备.写入此BIO只会丢弃数据,从中读取数据将导致EOF(文件结尾).
  • 内存BIO(BIO_s_mem).本质上,这是一个环回BIO.从这种类型的BIO读取将返回先前写入BIO的数据.但是,也可以通过调用特定于此类型BIO的函数从每种类型的BIO中提取(或放置到内部缓冲区中)数据(每种类型的BIO都有仅特定于此类型BIO的函数).
  • 生物" BIO(BIO_s_bio).它是一个类似管道的生物.可以创建一对这样的BIO.写入该对中的一个BIO的数据将被放置以读取该对中的第二个BIO.反之亦然.它类似于内存BIO,但是内存BIO将数据放置到其自身中,而管道BIO将数据放置到与之配对的BIO中.
  • A file BIO (BIO_s_file). It is a wrapper around stdio's FILE* object. It used for writing to and reading from a file.
  • A file descriptor BIO (BIO_s_fd). It is similar to file BIO but works with POSIX file descriptors instead stdio files.
  • A socket BIO (BIO_s_socket). It is a wrapper around POSIX sockets. It is used for communicating over network.
  • A null BIO (BIO_s_null). It is similar to the /dev/null device in POSIX systems. Writing to this BIO just discards data, reading from it results in EOF (end of file).
  • A memory BIO (BIO_s_mem). It is a loopback BIO in essence. Reading from this type of BIO returns the data that was previously written to the BIO. But the data can also be extracted from (or placed to) internal buffer by calling functions that are specific to this type of BIO (every type of BIO has functions that are specific only for this type of BIO).
  • A "bio" BIO (BIO_s_bio). It is a pipe-like BIO. A pair of such BIOs can be created. Data written to one BIO in the pair will be placed for reading to the second BIO in the pair. And vice versa. It is similar to memory BIO, but memory BIO places data to itself and pipe BIO places data to the BIO which it is paired with.

可以在以下位置找到有关BIO_s_memBIO_s_bio之间相似性的一些信息: OpenSSL"BIO_s_mem"与"BIO_s_bio" .

Some information about similarity between BIO_s_mem and BIO_s_bio can be found here: OpenSSL "BIO_s_mem" VS "BIO_s_bio".

这是过滤器BIO的示例:

And here is examples of filter BIOs:

  • 一个base64 BIO(BIO_f_base64).通过此BIO BIO_write将数据编码为base64格式. BIO_read通过此BIO解码base64格式的数据.
  • 密码BIO(BIO_f_cipher).它加密/解密通过它的数据.可以使用不同的密码算法.
  • 摘要计算BIO(BIO_f_md).它不会修改通过它的数据.它仅计算流经其中的数据摘要,而数据本身保持不变.可以使用不同的摘要计算算法.可以使用特殊功能来检索计算出的摘要.
  • 一个缓冲BIO(BIO_f_buffer).它也不会更改通过它的数据.写入此BIO的数据被缓冲,因此并非每次对该BIO的写入操作都会导致将数据写入下一个BIO.至于阅读,情况类似.这样可以减少位于缓冲IO后面的BIO上的IO操作数量.
  • SSL BIO(BIO_f_ssl).上面已经描述了这种类型的BIO.它将SSL链接包装在其中.
  • A base64 BIO (BIO_f_base64). BIO_write through this BIO encodes data to base64 format. BIO_read through this BIO decodes data from base64 format.
  • A cipher BIO (BIO_f_cipher). It encrypts/decrypts data passed through it. Different cryptographic algorithms can be used.
  • A digest calculation BIO (BIO_f_md). It doesn't modify data passed through it. It only calculates digest of data that flows through it, leaving the data itself unchanged. Different digest calculation algorithms can be used. The calculated digest can be retrieved using special functions.
  • A buffering BIO (BIO_f_buffer). It also doesn't change data passed through it. Data written to this BIO is buffered and therefore not every write operation to this BIO results in writing the data to the next BIO. As for reading, it is a similar situation. This allows to reduce number of IO operations on BIOs that are located behind buffering IO.
  • An SSL BIO (BIO_f_ssl). This type of BIO was described above. It wraps SSL link inside.

这篇关于什么是OpenSSL BIO?它们如何运作? OpenSSL中如何使用BIO?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-18 21:17