OpenSSL BIO Series 16 --- BIO pair (pair) type BIO

zhaozj2021-02-16  53

BIO pair (PAIR) type BIO

--- Translation according to OpenSSL DOC / CRYPTO / BIO_S_BIO.POD and its own understanding

(Author: DragonKing, Mail: wzhah@263.net, Posted on: http: //openssl.126.com of openssl professional forum)

As we have already introduced the concept of BIO pairs, in fact, Bio is also handled as a source / sink type Bio, that is, the BIO also provides a special Bio_metho method to handle BIO pairs. Various operations. BIO is defined as follows for type BIO (OpenSSL / BIO.H):

BIO_METHOD * BIO_S_BIO (VOID);

#define bio_make_bio_pair (b1, b2) (int) BIO_CTRL (B1, BIO_C_MAKE_BIO_PAIR, 0, B2)

#define bio_destroy_bio_pair (b) (int) BIO_CTRL (B, BIO_C_DESTROY_BIO_PAIR, 0, NULL)

#define bio_SHUTDOWN_WR (B) (int) BIO_CTRL (B, Bio_C_SHUTDOWN_WR, 0, NULL)

#define bio_set_write_buf_size (b, size) (int) BIO_CTRL (B, BIO_C_SET_WRITE_BUF_SIZE, SIZE, NULL)

#DEFINE BIO_GET_WRITE_BUF_SIZE (B, SIZE) (SIZE_T) BIO_CTRL (B, BIO_C_GET_WRITE_BUF_SIZE, SIZE, NULL)

INT BIO_NEW_BIO_PAIR (Bio ** Bio1, Size_t WriteBuf1, Bio ** Bio2, Size_t WriteBuf2);

#DEFINE BIO_GET_WRITE_GUArantee (b) (int) BIO_CTRL (B, BIO_C_GET_WRITE_GUAranteee, 0, NULL)

SIZE_T BIO_CTRL_GET_WRITE_GUANTEE (BIO * B);

#define bio_get_read_request (b) (int) BIO_CTRL (B, BIO_C_GET_READ_REQUEST, 0, NULL)

SIZE_T BIO_CTRL_GET_READ_REQUEST (BIO * B);

INT BIO_CTRL_RESET_READ_REQUEST (BIO * B);

It can be seen that most of these functions are macro definition functions and are based on the BIO_CTRL function.

BIO's type BIO is a pair of Source / Sink type BIO, data is usually written from one BIO buffer, read from another BIO. In fact, from the source code (BSS_BIO.C), it can be seen that the so-called BIO pair is just the two BIO terminal output (PTR members in the BIO structure) to each other, thereby forming a symmetrical structure, as follows :

BIO1-> peer-> ptr = bio2

Bio2-> peer-> ptr = bio1

Data flow direction 1 (write Bio1, read bio2): ---> Bio1 ---> Bio2 --->

Data popular 2 (write Bio2, read bio1): ---> Bio2 ---> Bio1 --->

Since there is no internal memory lock structure (LOCK) that provides internal data structure, the two BIOs of this BIO must be used under a thread. Because the BIO chain is terminated in a Source / Sink Bio, the application can be implemented by controlling a BIO of the BIO to control the data processing of the entire BIO chain. In fact, it is also equivalent to BIO to provide an entry that handles the entire BIO chain. Last time we said that BIO was saying, a typical application of BIO is to control the I / O interface of TLS / SSL in the app. In general, it is not standard in TLS / SSL in TLS / SSL. This method can be used when the transmission method is or not suitable for using a standard socket method. As mentioned earlier, the BIO needs to release two BIOs, if one of the BIOs is released, the other BIO must be released when using Bio_Free or Bio_Free_all.

When the BIO is used in two-way applications, such as TLS / SSL, be sure to perform FLUSH operations on the data in the write buffer. Of course, the BIO_pending function can also be called by another BIO in the BIO pair. If there is data in the buffer, then they read and transmit it to the underlying transmission channel. To make the request or Bio_Shold_read function call success (True), you must do this before performing any normal operations (such as SELECT).

Let's take an example for the importance of performing Flush operations:

Considering that the BIO_WRITE function transmits data in the TLS / SSL handshake process, the corresponding operation should make BIO_READ. The BIO_WRITE operation is successfully performed and writes the data into the write buffer. BIO_READ calls will fail, and Bio_Shold_Retry returns True. If the write buffer does not perform a Flush operation, the Bio_read call will never succeed because the underlying transmission channel will wait until the data is valid (but the data is in the write buffer, there is no passage channel).

[BIO_S_BIO]

This function returns a Bio_method that is defined as follows:

Static Bio_Method Methods_Biop =

{BIO_TYPE_BIO,

"BIO Pair",

Bio_Write,

BIO_READ,

Bio_puts,

NULL / * Nothing to define BIO_GETS * /,

BIO_CTRL,

BIO_NEW,

Bio_free,

NULL / * Nothing to define BIO_CALLBACK_CTRL * /

}

As can be seen from the definition, this type of BIO does not support the function of Bio_Gets.

The BIO_READ function reads data from buffer BIO. If there is no data, a retry request is issued.

The BIO_WRITE function writes data into the buffer BIO. If the buffer is full, a retry request is issued.

Bio_ctrl_pending and bio_ctrl_wpending functions can be used to view the number of data valid in the read or write buffer.

The BIO_RESET function clears the data in the write buffer.

[BIO_MAKE_BIO_PAIR]

This function connects two separate BIOs into a BIO pair.

[Bio_destroy_pair]

In contrast to the function above, it will be disassembled by two connections; if any of the BIO pairs are released, the operation will be executed automatically.

[BIO_SHUTDOWN_WR]

The function turns off one of the BIOs of the BIO, and one BIO is turned off, any write operation for the BIO will return an error. When another BIO is read data, the remaining valid data is returned, or EOF is returned. [BIO_SET_WRITE_BUF_SIZE]

This function sets the BIO buffer size. If the BIO's cache is not initialized, then the default value is used, the size is 17K, which is very large for a TLS record.

[BIO_GET_WRITE_BUF_SIZE]

This function returns the size of the write buffer.

[BIO_NEW_BIO_PAIR]

This function has made detailed introductions in the previous "Bio Series 9 - BIO", in fact, it is called BIO_NEW, BIO_MAKE_BIO_PAIR and BIO_SET_WRITE_BUF_SIZE functions to create a pair of BIO pairs. If the parameters of the two buffers are zero, then the default buffer length is used.

[BIO_GET_WRITE_GUANTEEE and BIO_CTRL_GET_WRITE_GUANTEE]

These two functions returned to the maximum length of the data that is currently writable to the BIO. If the data length written to the BIO is larger than the data returned by the function, the write data length returned by Bio_Write will be less than the required data, and if the buffer is already full, a retry request will be issued. The only difference between these two functions is a function of using a function, one is implemented using a macro definition.

[BIO_GET_READ_REQUEST and BIO_CTRL_GET_READ_REQUEST]

These two functions returned to the length of the data requested, which is usually a request to fail when the buffer data is fails because the buffer data is empty due to another BIO pair. So, this is usually used to indicate how much data should be written to make the next read operation successfully executed, which is very useful in the TLS / SSL application, because for this protocol, the read data length ratio The data length of the buffer is usually more meaningful. If you call these two functions after successful operation, you will return to 0, if you have new data writes before calling the function (whether the requirements for the data you need to read, you need to read the required data), then call the function will return 0. . It is naturally that the data returned by this function is definitely not greater than the data length returned by the BIO_GET_WRITE_GUARANTEE function.

[BIO_CTRL_RESET_READ_REQUEST]

This function is to set the BIO_GET_READ_REQUEST to be set to 0.

[Reference document]

"Bio series 9 --- BIO" creation and application "

转载请注明原文地址:https://www.9cbs.com/read-24009.html

New Post(0)