LIBRESSL-SSL_CTX_SET_MSG_CALLBACK(3)

πŸ“¦ version 4.4.0, in alpine 3.24, arch rolling

πŸ’… SSL_CTX_SET_MSG_CALLBACK(3) β€” like, the manual page, but make it make sense

okay bestie so this is a page from the libssl / libcrypto manuals (yes, that libssl β€” the crypto one, we stan) and it's all about installing a callback so you can eavesdrop on your own protocol messages. not in a shady way!! in a "my own code, my own TLS, I just wanna watch" way. πŸ¦‹


✨ NAME ✨

SSL_CTX_set_msg_callback, SSL_CTX_set_msg_callback_arg, SSL_set_msg_callback, SSL_set_msg_callback_arg β€” install a callback for observing protocol messages πŸ‘€βœ¨


🌸 SYNOPSIS 🌸

first, the vibe check β€” you're pulling in the library:

library β€œlibssl” libcrypto #include <openssl/ssl.h>

then the four functions, exactly as they are, no cap:

void
SSL_CTX_set_msg_callback(SSL_CTX *ctx,
    void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));

void
SSL_CTX_set_msg_callback_arg(SSL_CTX *ctx, void *arg);

void
SSL_set_msg_callback(SSL *ssl,
    void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));

void
SSL_set_msg_callback_arg(SSL *ssl, void *arg);

πŸŽ€ DESCRIPTION πŸŽ€

so SSL_CTX_set_msg_callback() and SSL_set_msg_callback() are how you define a message callback function cb that just… watches. literally all SSL/TLS protocol messages (handshake messages and friends) that get received or sent β€” it's giving security camera but make it TLS. πŸ”₯

and then SSL_CTX_set_msg_callback_arg() and SSL_set_msg_callback_arg() set the argument arg that gets handed to your callback function, and that one's yours β€” put whatever you want in it, the library is not gonna touch it, it's for arbitrary application use, periodt.

now the ctx-vs-ssl of it all:

  • SSL_CTX_set_msg_callback() and SSL_CTX_set_msg_callback_arg() set up the default settings that get copied onto new SSL objects by SSL_new(3). so it's like the blueprint energy. ✨
  • SSL_set_msg_callback() and SSL_set_msg_callback_arg() change the actual settings on a specific SSL object. main character behaviour, only affects that one.

and if you pass a NULL pointer for cb? callback disabled. done. bye. πŸ’…


πŸ’– what the callback arguments mean πŸ’–

when the SSL/TLS library calls cb for a protocol message, here's the tea on every argument:

  • write_p β€” this flag is 0 when a protocol message has been received and 1 when a protocol message has been sent. so it's the "which direction" girlie.
  • version β€” the protocol version according to which the protocol message is interpreted by the library, like TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, or DTLS1_2_VERSION. slay, versioned.
  • content_type β€” one of the ContentType values defined in the protocol spec. specifically SSL3_RT_CHANGE_CIPHER_SPEC, SSL3_RT_ALERT, SSL3_RT_HANDSHAKE, but never SSL3_RT_APPLICATION_DATA β€” because the callback only fires for protocol messages. no app data, we don't do that here. πŸ™ˆ
  • buf, len β€” buf points to a buffer holding the protocol message, which consists of len bytes. ⚠️ heads up: the buffer is no longer valid after the callback function has returned β€” so if you need it, copy it, don't keep the pointer. she's gone bestie.
  • ssl β€” the SSL object that received or sent the message. iconic.
  • arg β€” the user-defined argument you optionally defined with SSL_CTX_set_msg_callback_arg() or SSL_set_msg_callback_arg(). that's your little gift to yourself. 🎁

🧚 the fine print (read it, bestie) 🧚

protocol messages are passed to the callback function after decryption and fragment collection where applicable. so basically:

record boundaries are not visible. 😭 the callback sees reassembled, decrypted goodness, not the raw wire chunks.

and, important: if processing a received protocol message results in an error, the callback function may not be called. for example, the callback function will never see messages that are considered too large to be processed. so like, no callback is not always "no message" β€” sometimes it's just "message was too much". πŸ’€

also, bc of automatic protocol version negotiation, version is not necessarily the protocol version used by the sender of the message. iconic example: if a TLS 1.0 ClientHello message is received by an SSL 3.0-only server, version will be SSL3_VERSION. so read it as "how we interpreted it", not "what the sender was running". 🫢


🌈 SEE ALSO 🌈

go read those, iykyk πŸ’œ


πŸ‘‘ HISTORY πŸ‘‘

SSL_CTX_set_msg_callback(), SSL_CTX_set_msg_callback_arg(), SSL_set_msg_callback() and SSL_set_msg_callback_arg() first appeared in OpenSSL 0.9.7 and have been available since OpenBSD 3.2. vintage, honestly. ⭐


and that's the whole page, no skipped sections, no notes left behind. mwah. πŸ’…

okay love u bye 🫢 this page is from the Debian build, dated June 8, 2025, and honestly? it ate. πŸŒΈβœ¨πŸŽ€

πŸ“¦ where this page comes from