BIO_METH_NEW(3ossl)

πŸ’– BIO_METH_NEW πŸ’–

okay bestie, welcome to BIO_METHOD land β€” the OpenSSL manual page BIO_METH_NEW(3ossl), but make it cute. πŸ¦‹

This page is your guide to: BIO_get_new_index, BIO_meth_new, BIO_meth_free, BIO_meth_get_read_ex, BIO_meth_set_read_ex, BIO_meth_get_write_ex, BIO_meth_set_write_ex, BIO_meth_get_write, BIO_meth_set_write, BIO_meth_get_read, BIO_meth_set_read, BIO_meth_get_puts, BIO_meth_set_puts, BIO_meth_get_gets, BIO_meth_set_gets, BIO_meth_get_ctrl, BIO_meth_set_ctrl, BIO_meth_get_create, BIO_meth_set_create, BIO_meth_get_destroy, BIO_meth_set_destroy, BIO_meth_get_callback_ctrl, BIO_meth_set_callback_ctrl, BIO_meth_set_sendmmsg, BIO_meth_get_sendmmsg, BIO_meth_set_recvmmsg, and BIO_meth_get_recvmmsg.

Basically: routines to build up BIO methods. You're literally constructing your own BIO type from scratch. main character energy, fr fr. πŸ‘‘


✨ SYNOPSIS ✨

First, the vibe-check include:

#include <openssl/bio.h>

int BIO_get_new_index(void);

BIO_METHOD *BIO_meth_new(int type, const char *name);

void BIO_meth_free(BIO_METHOD *biom);

int BIO_meth_set_write_ex(BIO_METHOD *biom,
                          int (*bwrite)(BIO *, const char *, size_t, size_t *));
int BIO_meth_set_write(BIO_METHOD *biom,
                       int (*write)(BIO *, const char *, int));

int BIO_meth_set_read_ex(BIO_METHOD *biom,
                         int (*bread)(BIO *, char *, size_t, size_t *));
int BIO_meth_set_read(BIO_METHOD *biom, int (*read)(BIO *, char *, int));

int BIO_meth_set_puts(BIO_METHOD *biom, int (*puts)(BIO *, const char *));
int BIO_meth_set_gets(BIO_METHOD *biom,
                      int (*gets)(BIO *, char *, int));

int BIO_meth_set_ctrl(BIO_METHOD *biom,
                      long (*ctrl)(BIO *, int, long, void *));

int BIO_meth_set_create(BIO_METHOD *biom, int (*create)(BIO *));
int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy)(BIO *));

int BIO_meth_set_callback_ctrl(BIO_METHOD *biom,
                               long (*callback_ctrl)(BIO *, int, BIO_info_cb *));

int BIO_meth_set_sendmmsg(BIO_METHOD *biom,
                          ossl_ssize_t (*f) (BIO *, BIO_MSG *, size_t,
                                             size_t, uint64_t));
int BIO_meth_set_recvmmsg(BIO_METHOD *biom,
                          ossl_ssize_t (*f) (BIO *, BIO_MSG *, size_t,
                                             size_t, uint64_t));

the following functions have been deprecated since OpenSSL 3.5 πŸ’€ (yes, the whole get squad, we're mourning them):

int (*BIO_meth_get_write_ex(const BIO_METHOD *biom))(BIO *, const char *, size_t,
                                               size_t *);
int (*BIO_meth_get_write(const BIO_METHOD *biom))(BIO *, const char *, int);

int (*BIO_meth_get_read_ex(const BIO_METHOD *biom))(BIO *, char *, size_t, size_t *);
int (*BIO_meth_get_read(const BIO_METHOD *biom))(BIO *, char *, int);

int (*BIO_meth_get_puts(const BIO_METHOD *biom))(BIO *, const char *);
int (*BIO_meth_get_gets(const BIO_METHOD *biom))(BIO *, char *, int);

long (*BIO_meth_get_ctrl(const BIO_METHOD *biom))(BIO *, int, long, void *);

int (*BIO_meth_get_create(const BIO_METHOD *bion))(BIO *);
int (*BIO_meth_get_destroy(const BIO_METHOD *biom))(BIO *);

long (*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom))(BIO *, int, BIO_info_cb *);

ossl_ssize_t (*BIO_meth_get_sendmmsg(const BIO_METHOD *biom))(BIO *,
                                                              BIO_MSG *,
                                                              size_t,
                                                              size_t,
                                                              uint64_t);
ossl_ssize_t (*BIO_meth_get_recvmmsg(const BIO_METHOD *biom))(BIO *,
                                                              BIO_MSG *,
                                                              size_t,
                                                              size_t,
                                                              uint64_t);

🌸 DESCRIPTION 🌸

So. The BIO_METHOD type is a struct used for the implementation of new BIO types, okay? It's a whole little bundle of functions that OpenSSL uses to implement the various BIO capabilities. Want the deep lore? Go read the bio(7) page. πŸ“–

πŸŽ€ making one + freeing one

BIO_meth_new() creates a new BIO_METHOD structure containing a type identifier type and a string that represents its name. You can set type to either BIO_TYPE_NONE, or via BIO_get_new_index() if you need a unique type for searching (see BIO_find_type(3)).

⚠️ heads up bestie: BIO_get_new_index() can only be used 127 times before it returns an error. That's the limit. That's it. No more. 😭

The set of standard OpenSSL-provided BIO types lives in <openssl/bio.h>. Some iconic examples: BIO_TYPE_BUFFER and BIO_TYPE_CIPHER. Filter BIOs should have a type with the "filter" bit set (BIO_TYPE_FILTER). Source/sink BIOs should have the "source/sink" bit set (BIO_TYPE_SOURCE_SINK). File descriptor based BIOs (like socket, fd, connect, accept, etc.) should additionally have the "descriptor" bit set (BIO_TYPE_DESCRIPTOR). More deets on the BIO_find_type(3) page. ✨

BIO_meth_free() destroys a BIO_METHOD structure and frees up any memory associated with it. If the argument is NULL, nothing is done β€” it just politely does nothing, no drama, we love that. 🫢

πŸ“ the write squad

BIO_meth_get_write_ex() and BIO_meth_set_write_ex() get and set the function used for writing arbitrary length data to the BIO, respectively. This function gets called when the application calls BIO_write_ex() or BIO_write(). The parameters for the function have the same meaning as for BIO_write_ex(). Older code may call BIO_meth_get_write() and BIO_meth_set_write() instead.

🚫 do NOT call both BIO_meth_set_write_ex() and BIO_meth_set_write(), and do NOT call BIO_meth_get_write() when the function was set with BIO_meth_set_write_ex(). Pick a lane bestie, it's giving chaos otherwise.

πŸ“– the read squad

BIO_meth_get_read_ex() and BIO_meth_set_read_ex() get and set the function used for reading arbitrary length data from the BIO, respectively. This function gets called when the application calls BIO_read_ex() or BIO_read(). The parameters for the function have the same meaning as for BIO_read_ex(). Older code may call BIO_meth_get_read() and BIO_meth_set_read() instead.

🚫 same rule, same energy: don't call both BIO_meth_set_read_ex() and BIO_meth_set_read(), and don't call BIO_meth_get_read() when the function was set with BIO_meth_set_read_ex().

🌈 strings & lines

BIO_meth_get_puts() and BIO_meth_set_puts() get and set the function used for writing a NULL terminated string to the BIO, respectively. This function gets called when the application calls BIO_puts(). The parameters for the function have the same meaning as for BIO_puts().

BIO_meth_get_gets() and BIO_meth_set_gets() get and set the function typically used for reading a line of data from the BIO, respectively (see the BIO_gets(3) page for more info). This function gets called when the application calls BIO_gets(). The parameters for the function have the same meaning as for BIO_gets().

πŸŽ›οΈ ctrl things

BIO_meth_get_ctrl() and BIO_meth_set_ctrl() get and set the function used for processing ctrl messages in the BIO, respectively. See the BIO_ctrl(3) page for more info. This function gets called when the application calls BIO_ctrl(). The parameters for the function have the same meaning as for BIO_ctrl().

πŸ‘Ά create & destroy

BIO_meth_get_create() and BIO_meth_set_create() get and set the function used for creating a new instance of the BIO, respectively. This function gets called when the application calls BIO_new() and passes in a pointer to the current BIO_METHOD. BIO_new() will allocate the memory for the new BIO, and a pointer to this newly allocated structure gets passed as a parameter to the function. If a create function is set, BIO_new() will not mark the BIO as initialised on allocation. BIO_set_init(3) must then be called either by the create function, or later, by a BIO ctrl function, once BIO initialisation is complete. iykyk. πŸ’…

BIO_meth_get_destroy() and BIO_meth_set_destroy() get and set the function used for destroying an instance of a BIO, respectively. This function gets called when the application calls BIO_free(). A pointer to the BIO to be destroyed gets passed as a parameter. The destroy function is for BIO-specific clean up. The memory for the BIO itself should not be freed by this function β€” that's not its job, don't make it do overtime. πŸ™ˆ

πŸ“ž callback ctrl

BIO_meth_get_callback_ctrl() and BIO_meth_set_callback_ctrl() get and set the function used for processing callback ctrl messages in the BIO, respectively. See the BIO_callback_ctrl(3) page for more info. This function gets called when the application calls BIO_callback_ctrl(). The parameters for the function have the same meaning as for BIO_callback_ctrl().

πŸ“¨ sendmmsg & recvmmsg

BIO_meth_get_sendmmsg(), BIO_meth_set_sendmmsg(), BIO_meth_get_recvmmsg() and BIO_meth_set_recvmmsg() get and set the functions used for handling BIO_sendmmsg() and BIO_recvmmsg() calls, respectively. See BIO_sendmmsg(3) for more info. ✨


🫢 RETURN VALUES 🫢

  • BIO_get_new_index() returns the new BIO type value, or -1 if an error occurred. 😬
  • BIO_meth_new(int type, const char *name) returns a valid BIO_METHOD or NULL if an error occurred.
  • The BIO_meth_set functions return 1 on success or 0 on error.
  • The BIO_meth_get functions return the corresponding function pointers.

πŸ’€ BUGS πŸ’€

okay so this is the important tea: 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. Nope. 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>.


πŸ‘€ SEE ALSO πŸ‘€

bio(7), BIO_find_type(3), BIO_ctrl(3), BIO_read_ex(3), BIO_new(3)


πŸ•°οΈ HISTORY πŸ•°οΈ

  • The functions BIO_meth_get_sendmmsg(), BIO_meth_set_sendmmsg(), BIO_meth_get_recvmmsg() and BIO_meth_set_recvmmsg() were added in OpenSSL 3.2. 🌱
  • All the other functions described here were added in OpenSSL 1.1.0. the OGs fr fr.
  • The functions BIO_meth_get_read_ex(), BIO_meth_get_write_ex(), BIO_meth_get_write(), BIO_meth_get_read(), BIO_meth_get_puts(), BIO_meth_get_gets(), BIO_meth_get_ctrl(), BIO_meth_get_create(), BIO_meth_get_destroy(), BIO_meth_get_callback_ctrl(), BIO_meth_get_sendmmsg() and BIO_meth_get_recvmmsg() are deprecated since OpenSSL 3.5. rip to them, they served. πŸ’

Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.


and that's the whole page bestie!! 🌈 this lil slice of the OpenSSL docs is from version 3.5.9, dated 2026-09-29 β€” go build something iconic with it. slay, stay safe, and always set your create function properly. πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from