BIO_PUSH(3)
π
BIO_PUSH(3) β Library Functions Manual β BIO_push, BIO_pop, BIO_set_next manipulate BIO chains π
π NAME π
BIO_push, BIO_pop, BIO_set_next β manipulate BIO chains
πΈ SYNOPSIS πΈ
library βlibcryptoβ #include <openssl/bio.h>
BIO *
BIO_push(BIO *b, BIO *new_tail);
BIO *
BIO_pop(BIO *b);
void
BIO_set_next(BIO *b, BIO *new_tail);
β¨ DESCRIPTION β¨
okay bestie, so BIOs can be joined together into chains. A chain normally has one or more filter BIOs plus one source/sink BIO at the end. Data read from or written to the first BIO traverses the chain all the way to the end. itβs giving linked-list main character energy, fr fr.
Every BIO is a member of exactly one chain. Itβs either at the beginning of its chain, or thereβs exactly one preceding BIO. Itβs either at the end of its chain, or thereβs exactly one following BIO. If thereβs neither a preceding nor a following BIO, you can regard it as a chain with one member. Every chain has exactly one beginning and exactly one end. periodt.
BIO_push() appends the chain starting at new_tail to the end of the chain that contains b. Unless b is NULL, it then calls BIO_ctrl(3) on b with an argument of BIO_CTRL_PUSH. If b or new_tail is NULL, nothing is appended.
In LibreSSL, if new_tail is not at the beginning of its chain, the head of that chain up to but not including new_tail is cut off and becomes a separate chain. For portability, it is best to make sure that new_tail is at the beginning of its chain before calling BIO_push().
BIO_pop() removes the BIO b from its chain. Despite the word βpopβ in the function name, b can be at the beginning, in the middle, or at the end of its chain. Before removal, BIO_ctrl(3) is called on b with an argument of BIO_CTRL_POP. The removed BIO b becomes the only member of its own chain and can thus be freed or attached to a different chain. If b is NULL, no action occurs.
BIO_set_next() appends the chain starting with new_tail to the chain ending with b.
In LibreSSL, if new_tail is not at the beginning of its chain, the head of that chain up to but not including new_tail is cut off and becomes a separate chain, and if b is not at the end of its chain, the tail of that chain starting after b is cut off and becomes a separate chain.
For portability, it is best to make sure that b is at the end of its chain and that new_tail is at the beginning of its chain before calling BIO_set_next() and to avoid calling BIO_pop() on new_tail afterwards. iykyk π«Ά
In LibreSSL, the only built-in BIO type for which BIO_ctrl(3) calls with an argument of BIO_CTRL_PUSH or BIO_CTRL_POP have any effect is BIO_f_ssl(3).
π RETURN VALUES π
BIO_push()returnsbifbis notNULL; otherwise it returnsnew_tail.BIO_pop()returns the BIO that followedbin its chain, orNULLifbisNULLor was at the end of its chain.
π¦ EXAMPLES π¦
For these examples, suppose md1 and md2 are digest BIOs, b64 is a Base64 BIO, and f is a file BIO β see BIO_f_md(3), BIO_f_base64(3), and BIO_s_file(3), respectively.
If the call
BIO_push(b64, f);
is made, then the new chain will be b64-f. After making the calls
BIO_push(md2, b64);
BIO_push(md1, md2);
the new chain is md1-md2-b64-f. Data written to md1 will be digested by md1 and md2, Base64-encoded, and written to f.
It should be noted that reading causes data to pass in the reverse direction. That is, data is read from f, Base64-decoded, and digested by md1 and md2. If this call is made:
BIO_pop(md2);
The call will return b64 and the new chain will be md1-b64-f; data can be written to md1 as before. slay, chain secured π
π SEE ALSO π
π§ HISTORY π§
BIO_push() first appeared in SSLeay 0.6.0. BIO_pop() first appeared in SSLeay 0.6.4. Both functions have been available since OpenBSD 2.4.
BIO_set_next() first appeared in OpenSSL 1.1.0 and has been available since OpenBSD 7.1.
β οΈ CAVEATS β οΈ
Creating a cyclic chain results in undefined behavior. For example, infinite recursion or infinite loops may ensue. not cute, bestie β do not do this π
If it is unknown whether b and new_tail are already members of the same chain and whether joining them would create a cycle, the calling code can use the following safe idiom:
BIO *btest;
for (btest = new_tail; btest != NULL; btest = BIO_next(btest))
if (btest == b)
/* Bail out because this would create a cycle. */
BIO_push(b, new_tail); /* This is now safe. */
The same idiom can be used with BIO_set_next() instead of BIO_push().
Often, the safe idiom is not needed because it is already known that b and new_tail are not members of the same chain, for example when b or new_tail was created right before.
xoxo, this was the Debian edition stamped June 8, 2025 β and yes bestie, itβs still BIO_PUSH(3) energy ππ
π¦ where this page comes from
- alpine 3.24: libressl-doc 4.3.1-r0 Β· custom
- arch rolling: libressl 4.4.0-1 Β· ISC AND custom:OpenSSL
- Copyright (c) 2022 Ingo Schwarze <schwarze@openbsd.org>
- Copyright (c) 2000, 2014 The OpenSSL Project. All rights reserved
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms