LIBRESSL-SSL_CTX_SET_CLIENT_CERT_CB(3)
π SSL_CTX_SET_CLIENT_CERT_CB(3) β the libssl-flavored glow-up β¨
okay so this page is from the libssl / libcrypto corner of the universe (Library Functions Manual energy, we love her), and it's all about the β¨client certificate callbackβ¨. yes bestie, the callback that decides which cert your client hands over when a server comes asking. let's get into it π
πΈ NAME πΈ
SSL_CTX_set_client_cert_cb, SSL_CTX_get_client_cert_cb β handle the client certificate callback function, aka the girl who picks which ID you show at the door π
β¨ SYNOPSIS β¨
she lives in libssl and libcrypto, and bestie you gotta bring the header:
#include <openssl/ssl.h>
void
SSL_CTX_set_client_cert_cb(SSL_CTX *ctx,
int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
int
(*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509,
EVP_PKEY **pkey);
int
(*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
π¦ DESCRIPTION π¦
So SSL_CTX_set_client_cert_cb() sets the client_cert_cb() callback β and this callback gets rung up when a server asks for a client certificate and no certificate was already set for the SSL object. it's giving "you got a sec? we need an ID" π
When client_cert_cb is NULL, no callback function is used. simple as that, no cap.
SSL_CTX_get_client_cert_cb() hands you back a pointer to whichever callback function is currently set. the "who's on duty" check π
client_cert_cb() is your application-defined callback, bestie β you write this one. here's the vibe check on what she returns:
- if it wants to set a certificate: a certificate/private key combo must be set using the
x509andpkeyarguments, and you must return1. the certificate gets installed intosslπ₯ - if no certificate should be set: return
0and no certificate will be sent π - if you return a negative value: the handshake gets suspended and the handshake function returns immediately.
SSL_get_error(3)will returnSSL_ERROR_WANT_X509_LOOKUPto tell you the handshake was suspended (iykyk). the next call to the handshake function leads toclient_cert_cb()getting called again. and it is literally the job ofclient_cert_cb()to store information about the state of the last call if it needs to continue π
okay so during a handshake (or renegotiation) a server may request a certificate from the client. and a client certificate must only be sent when the server actually did send the request. periodt π«
When a certificate has been set using the SSL_CTX_use_certificate(3) family of functions, it will be sent to the server. now here's the tea: the TLS standard requires that only a certificate is sent if it matches the list of acceptable CAs sent by the server. this constraint is violated by the default behavior of the OpenSSL library π¬. using the callback function it's possible to implement a proper selection routine, or to allow user interaction to choose the certificate to be sent. iconic, honestly β¨
If a callback function is defined and no certificate was yet defined for the SSL object, the callback function will be called. if the callback function returns a certificate, the OpenSSL library will try to load the private key and certificate data into the SSL object using the SSL_use_certificate() and SSL_use_private_key() functions. so it will permanently install the certificate and key for this SSL object β like, it will not be reset by calling SSL_clear(3) π«Ά. if the callback returns no certificate, the OpenSSL library will not send a certificate. that's it, that's the whole deal.
π SEE ALSO π
ssl(3)SSL_clear(3)SSL_CTX_add_extra_chain_cert(3)SSL_CTX_use_certificate(3)SSL_free(3)SSL_get_client_CA_list(3)
go read those too, bestie, they're all in the group chat π
π HISTORY π
SSL_CTX_set_client_cert_cb() and SSL_CTX_get_client_cert_cb() first appeared in SSLeay 0.6.6 and have been available since OpenBSD 2.4. vintage. retro. we stan a legacy function πβ
π BUGS π
ugh okay, gather round, because this is the messy part π
client_cert_cb() cannot return a complete certificate chain β it can only return one client certificate. if the chain only has a length of 2, the root CA certificate may be omitted according to the TLS standard, and thus a standard conforming answer can be sent to the server. π but for a longer chain, the client must send the complete chain (with the option to leave out the root CA certificate). this can be accomplished only by either:
- adding the intermediate CA certificates into the trusted certificate store for the
SSL_CTXobject β which results in having to add CA certificates that otherwise maybe would not be trusted π¬, or - adding the chain certificates using the
SSL_CTX_add_extra_chain_cert(3)function β which is only available for theSSL_CTXobject as a whole, and that therefore probably can only apply for one client certificate, making the concept of the callback function (to allow the choice from several certificates) questionable π
π¨ also, once theSSLobject has been used in conjunction with the callback function, the certificate will be set for theSSLobject and will not be cleared even whenSSL_clear(3)is called. it is therefore mandatory to destroy theSSLobject usingSSL_free(3)and create a new one to return to the previous state. not optional, bestie. mandatory. fr fr π
and that's the page!! π brought to you by the Debian girlies, dated June 8, 2025, filed under SSL_CTX_SET_CLIENT_CERT_CB(3) β mwah, go set some certs responsibly π§ββοΈπΈππ
π¦ 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) 2002 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