TLS_CONN_VERSION(3)

πŸ“¦
version 4.4.0 Β· 2 versions
, in arch rolling

πŸ’– NAME πŸ’–

ok so bestie, this page is TLS_CONN_VERSION(3) from the Library Functions Manual, and it's literally the whole squad of functions that let you inspect an established TLS connection: tls_conn_version, tls_conn_cipher, tls_conn_cipher_strength, tls_conn_alpn_selected, tls_conn_servername, tls_conn_session_resumed, tls_peer_cert_provided, tls_peer_cert_contains_name, tls_peer_cert_chain_pem, tls_peer_cert_unverified_bundle_pem, tls_peer_cert_verified_chain_pem, tls_peer_cert_issuer, tls_peer_cert_subject, tls_peer_cert_common_name, tls_peer_cert_hash, tls_peer_cert_notbefore, and tls_peer_cert_notafter. yeah. all of them. they're a package deal πŸŽ€


✨ SYNOPSIS ✨

the library situation is libtls, plus libssl and libcrypto, and you're gonna want:

#include <tls.h>

and then, one by one, the whole lineup:

const char *
tls_conn_version(struct tls *ctx);

const char *
tls_conn_cipher(struct tls *ctx);

int
tls_conn_cipher_strength(struct tls *ctx);

const char *
tls_conn_alpn_selected(struct tls *ctx);

const char *
tls_conn_servername(struct tls *ctx);

int
tls_conn_session_resumed(struct tls *ctx);

int
tls_peer_cert_provided(struct tls *ctx);

int
tls_peer_cert_contains_name(struct tls *ctx, const char *name);

const uint8_t *
tls_peer_cert_chain_pem(struct tls *ctx, size_t *size);

const uint8_t *
tls_peer_cert_unverified_bundle_pem(struct tls *ctx, size_t *size);

const uint8_t *
tls_peer_cert_verified_chain_pem(struct tls *ctx, size_t *size);

const char *
tls_peer_cert_issuer(struct tls *ctx);

const char *
tls_peer_cert_subject(struct tls *ctx);

const char *
tls_peer_cert_common_name(struct tls *ctx);

const char *
tls_peer_cert_hash(struct tls *ctx);

time_t
tls_peer_cert_notbefore(struct tls *ctx);

time_t
tls_peer_cert_notafter(struct tls *ctx);

like, all of them take a struct tls *ctx. that's the vibe. 🫢


πŸ¦‹ DESCRIPTION πŸ¦‹

so these functions hand you info about a TLS connection, and the key thing: they will only succeed after the handshake is complete. the connection information applies to both clients and servers, unless noted otherwise. no shortcuts, no peeking early, periodt βœ‹

  • tls_conn_version() β€” returns a string for the TLS version that was negotiated with the peer connected to ctx. slay.
  • tls_conn_cipher() β€” returns a string for the cipher suite negotiated with the peer connected to ctx. iconic.
  • tls_conn_cipher_strength() β€” returns the strength, in bits, of the symmetric cipher being used with the peer connected to ctx. numbers. we love her.
  • tls_conn_alpn_selected() β€” returns a string specifying the ALPN protocol selected for use with the peer connected to ctx. and if no protocol was selected? NULL is returned. no protocol, no problem 😌
  • tls_conn_servername() β€” returns a string for the servername that the client connected to ctx requested by sending a TLS Server Name Indication extension. server only, bestie. πŸ–₯️
  • tls_conn_session_resumed() β€” tells you whether a TLS session was resumed during the handshake with the server connected to ctx. client only. πŸ”
  • tls_peer_cert_provided() β€” checks if the peer of ctx has provided a certificate.
  • tls_peer_cert_contains_name() β€” checks if the peer of a TLS ctx has provided a certificate that contains a SAN or CN matching name. yes, matching goes hard πŸ’…
  • tls_peer_cert_unverified_bundle_pem() β€” returns a pointer to memory containing the PEM-encoded, unverified bundle of certificates that was sent by the peer of ctx during the TLS handshake. note the unverified, we'll get to that drama later πŸ’€
  • tls_peer_cert_chain_pem() β€” is equivalent to tls_peer_cert_unverified_bundle_pem(). that's it. that's the whole thing. (and yes, the naming is a situation β€” see BUGS πŸ‘€)
  • tls_peer_cert_verified_chain_pem() β€” returns a pointer to memory containing the PEM-encoded certificate chain that was verified for the peer of ctx during the TLS handshake. the real one. the main character. πŸ‘‘
  • tls_peer_cert_subject() β€” returns a string for the subject of the peer certificate from ctx.
  • tls_peer_cert_issuer() β€” returns a string for the issuer of the peer certificate from ctx.
  • tls_peer_cert_common_name() β€” returns a string for the common name of the peer certificate from ctx, or the empty string if no common name is present. empty string, not NULL. important distinction, iykyk 🧚
  • tls_peer_cert_hash() β€” returns a string for a hash of the raw peer certificate from ctx, prefixed by a hash name followed by a colon. the hash currently used is SHA256, though this could change in the future. so like, don't hardcode your whole personality on it, bestie. the hash string for a certificate in file mycert.crt can be generated using the commands:
h=$(openssl x509 -outform der -in mycert.crt | sha256)
printf "SHA256:${h}\n"

look at that. chef's kiss ✨

  • tls_peer_cert_notbefore() β€” returns the time corresponding to the start of the validity period of the peer certificate from ctx. ⏰
  • tls_peer_cert_notafter() β€” returns the time corresponding to the end of the validity period of the peer certificate from ctx. ⏳

🌈 RETURN VALUES 🌈

okay so here's what you actually get back:

  • tls_conn_session_resumed() returns 1 if a TLS session was resumed, or 0 if it was not.
  • tls_peer_cert_provided() and tls_peer_cert_contains_name() return 1 if the check succeeds, or 0 if it does not.
  • tls_peer_cert_notbefore() and tls_peer_cert_notafter() return a time in epoch-seconds on success, or -1 on error.
  • the functions that return a pointer return NULL on error or an out of memory condition. yes, both. keep that in mind 🫠

🌸 SEE ALSO 🌸

go read these next, bestie, they're all connected:


⭐ HISTORY ⭐

the lore drop, chronological order:

  • tls_conn_version(), tls_conn_cipher(), tls_peer_cert_provided(), tls_peer_cert_contains_name(), tls_peer_cert_issuer(), tls_peer_cert_subject(), tls_peer_cert_hash(), tls_peer_cert_notbefore(), and tls_peer_cert_notafter() appeared in OpenBSD 5.9.
  • tls_conn_servername() and tls_conn_alpn_selected() appeared in OpenBSD 6.1.
  • tls_conn_session_resumed() appeared in OpenBSD 6.3.
  • tls_conn_cipher_strength() appeared in OpenBSD 6.7.
  • tls_peer_cert_common_name() appeared in OpenBSD 7.7.
  • tls_peer_cert_unverified_bundle_pem() and tls_peer_cert_verified_chain_pem() appeared in OpenBSD 8.0.

a whole glow-up timeline fr fr πŸ’…


πŸŽ€ AUTHORS πŸŽ€

the legends themselves:

  • Bob Beck <beck@openbsd.org>
  • Joel Sing <jsing@openbsd.org>

thank you for your service πŸ«‘πŸ’–


πŸ’€ BUGS πŸ’€

ok so tls_peer_cert_chain_pem() is poorly named: it returns the unverified bundle of certificates sent by the peer, not the chain that was verified during the handshake. so the name is lowkey lying to you 😭

it will be deprecated in a future release in favour of tls_peer_cert_unverified_bundle_pem() and tls_peer_cert_verified_chain_pem(). so like, migrate when you can, bestie.

and that's the whole page ✨ this gem comes to you from Debian, dated September 20, 2026, and it's TLS_CONN_VERSION(3) all the way down. mwah πŸ’‹

πŸ“¦ where this page comes from
  • arch rolling: libressl 4.4.0-1 Β· ISC AND custom:OpenSSL
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms