Recent OpenSSL 3.5.0 has deprecated certain BIO_meth_get_*() functions, but its replacements are not provided. Below is a C++ code fragment in my project:-
BIO_METHOD *_bio = BIO_meth_new(BIO_TYPE_SOCKET, "mysslsocket");
BIO_METHOD *tbio = _bio->Bio(); //Bio() method just returns _bio object
const BIO_METHOD *biom = BIO_s_socket();
BIO_meth_set_gets(tbio, BIO_meth_get_gets(biom));
BIO_meth_set_puts(tbio, BIO_meth_get_puts(biom));
BIO_meth_set_ctrl(tbio, BIO_meth_get_ctrl(biom));
BIO_meth_set_create(tbio, BIO_meth_get_create(biom));
BIO_meth_set_destroy(tbio, BIO_meth_get_destroy(biom));
BIO_meth_set_callback_ctrl(tbio, BIO_meth_get_callback_ctrl(biom));
auto wbio = BIO_new(tbio);
As BIO_meth_get_*() functions are deprecated, can someone please suggest how to rewrite above code in OpenSSL 3.5.0 version compliant?
These functions were deprecated because they are considered unsafe.
The man page has this to say about it:
It is not safe to use
BIO_meth_get_
functions to reuse the BIO implementation of BIOs implemented by OpenSSL itself with application-implemented BIOs. Instead either the applications ought to implement these functions themselves or they should implement a filter BIO.For more details please see https://github.com/openssl/openssl/issues/26047.
The suggested alternative to is to use a filter BIO instead. The issue linked to above from the man page has more details about why this is unsafe and also describes an alternative approach:
If the application is meaningfully calling into the base
BIO
, OpenSSL already has a notion of filterBIO
s. A good solution would be to either make a filterBIO
and explicitly defer toBIO_next
, or just encapsulate aBIO
in your customBIO
's data yourself. This would make closely align with how OOP subclassing actually works.
There is a description of filter BIOs on this man page:
A filter BIO takes data from one BIO and passes it through to another, or the application. The data may be left unmodified (for example a message digest BIO) or translated (for example an encryption BIO). The effect of a filter BIO may change according to the I/O operation it is performing: for example an encryption BIO will encrypt data if it is being written to and decrypt data if it is being read from.
BIOs can be joined together to form a chain (a single BIO is a chain with one component). A chain normally consists of one source/sink BIO and one or more filter BIOs. Data read from or written to the first BIO then traverses the chain to the end (normally a source/sink BIO).
For inspiration you might look at this implementation of a filter BIO from within the OpenSSL test suite: