LIBRESSL-X509_STORE_CTX_SET_FLAGS(3)

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

πŸ’… X509_STORE_CTX_SET_FLAGS(3) β€” like, the whole squad of X509_STORE_CTX parameter init girlies ✨

okay so bestie, welcome to the girlies of libcrypto πŸ’– this whole page lives in the Library Functions Manual, and it's literally all about initialising the parameters on an X509_STORE_CTX. no cap, it's giving "set it up before you verify" energy and we're obsessed πŸŽ€


✨ NAME ✨

X509_STORE_CTX_set_flags, X509_STORE_CTX_set_time, X509_STORE_CTX_set_depth, X509_STORE_CTX_set_trust, X509_STORE_CTX_set_purpose, X509_STORE_CTX_get0_param, X509_STORE_CTX_set0_param, X509_STORE_CTX_set_default β€” X509_STORE_CTX parameter initialisation πŸ¦‹ (yes that's the whole friend group, they roll together)


🌸 SYNOPSIS 🌸

library β€œlibcrypto”

#include <openssl/x509_vfy.h>
void
X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags);

void
X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long dummy,
    time_t time);

void
X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);

int
X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);

int
X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);

X509_VERIFY_PARAM *
X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);

void
X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx,
    X509_VERIFY_PARAM *param);

int
X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);

πŸ’œ DESCRIPTION πŸ’œ

So these functions all operate on the X509_VERIFY_PARAM object that ctx is using 🫢. like, the whole vibe of this page is "mess with the params of this store context." The typical flow, iykyk: X509_STORE_CTX_init(3) gets called on ctx before these functions, and X509_verify_cert(3) comes after. that's the order, periodt.

  • X509_STORE_CTX_set_flags() β€” sets the internal verification parameter flags to flags. wanna know what those flags even mean? go read X509_VERIFY_PARAM_set_flags(3), she explains it πŸ’…
  • X509_STORE_CTX_set_time() β€” sets the verification time, using X509_VERIFY_PARAM_set_time(3). and the dummy argument? literally ignored. not me packing a whole unused argument in there πŸ’€
  • X509_STORE_CTX_set_depth() β€” sets the maximum verification depth via X509_VERIFY_PARAM_set_depth(3). translation: that's the max number of untrusted CA certificates that can show up in a chain. keep it reasonable bestie πŸ”₯
  • X509_STORE_CTX_set_trust() β€” sets the trust identifier, which you could also set with X509_VERIFY_PARAM_set_trust(3). but heads up: if the trust argument is 0 or invalid, or the trust identifier is already set to a non-zero value in the X509_VERIFY_PARAM object, then nothing happens. zero action. ghosted πŸ™ˆ
  • X509_STORE_CTX_set_purpose() β€” sets the purpose identifier, which you can also set with X509_VERIFY_PARAM_set_purpose(3). if the purpose argument is 0 or any failure occurs, nothing gets changed ✨

okay now for the slightly spicy part 🌢️ β€” in the following, the trust identifier contained in the X509_PURPOSE object associated with purpose is called the β€œassociated trust”. cute little nickname, we love a defined term πŸŽ€

The function fails if the purpose argument or the associated trust is invalid but not 0. otherwise, X509_STORE_CTX_set_purpose() also does the equivalent of calling X509_STORE_CTX_set_trust() with the associated trust. like it's out here doing double duty, main character energy πŸ‘‘

And β€” if the purpose identifier is already set to a non-zero value in the X509_VERIFY_PARAM object, it is not changed, even if the purpose argument is valid too. first one wins, no takebacks πŸ’…

  • X509_STORE_CTX_get0_param() β€” retrieves an internal pointer to the verification parameters associated with ctx. just a peek, not a copy, bestie πŸ‘€
  • X509_STORE_CTX_set0_param() β€” sets that internal verification parameter pointer to param. after this call, param should not be used anymore. like, she's handed off now, let her go 😭
  • X509_STORE_CTX_set_default() β€” looks up and sets the default verification method to name. it uses X509_VERIFY_PARAM_lookup(3) to find an appropriate set of parameters from name, then copies them with X509_VERIFY_PARAM_inherit(3). iconic lookup-then-inherit combo 🌈

⭐ RETURN VALUES ⭐

  • X509_STORE_CTX_set_trust() β€” returns 1 if the trust argument is 0 or valid, or 0 if it's invalid but not 0. and fr fr, a return of 1 does not imply the trust identifier stored in the X509_VERIFY_PARAM object was actually changed. like she said yes but nothing happened πŸ’€
  • X509_STORE_CTX_set_purpose() β€” returns 1 if both the purpose argument and the associated trust are 0 or valid. returns 0 if either the purpose argument or the associated trust is invalid but not 0. same disclaimer: a 1 does not imply any data was changed πŸ™ˆ
  • X509_STORE_CTX_get0_param() β€” returns a pointer to an X509_VERIFY_PARAM structure, or NULL if an error occurred 😭
  • X509_STORE_CTX_set_default() β€” returns 1 for success, or 0 if an error occurred ✨

πŸ”₯ ERRORS πŸ”₯

these diagnostics can be retrieved with ERR_get_error(3), ERR_GET_REASON(3), and ERR_reason_error_string(3). get you a girl who reads her error strings πŸ’…

  • X509_R_UNKNOWN_TRUST_ID "unknown trust id" β€” X509_STORE_CTX_set_trust() was called with a trust argument that is invalid but not 0. heads up: other implementations may also return this when X509_STORE_CTX_set_purpose() is called with a purpose argument that has an invalid associated trust. so it's not just a you problem, it's a portability thing πŸ¦‹
  • X509_R_UNKNOWN_PURPOSE_ID "unknown purpose id" β€” the purpose argument is invalid but not 0.

and the other functions? no diagnostics. they simply don't do drama πŸŽ€


πŸ¦‹ SEE ALSO πŸ¦‹

X509_STORE_CTX_get_error(3), X509_STORE_CTX_new(3), X509_STORE_CTX_set_verify(3), X509_STORE_CTX_set_verify_cb(3), X509_STORE_new(3), X509_STORE_set1_param(3), X509_STORE_set_verify_cb(3), X509_verify_cert(3), X509_VERIFY_PARAM_new(3), X509_VERIFY_PARAM_set_flags(3)

go read the whole friend group, they're all slay ✨


πŸ‘‘ HISTORY πŸ‘‘

okay history lesson, grab a snack πŸ“

  • X509_STORE_CTX_set_depth() first appeared in OpenSSL 0.9.3 and has been available since OpenBSD 2.4.
  • X509_STORE_CTX_set_trust() and X509_STORE_CTX_set_purpose() first appeared in OpenSSL 0.9.5 and have been available since OpenBSD 2.7.
  • X509_STORE_CTX_set_flags() and X509_STORE_CTX_set_time() first appeared in OpenSSL 0.9.6 and have been available since OpenBSD 2.9.
  • X509_STORE_CTX_get0_param(), X509_STORE_CTX_set0_param(), and X509_STORE_CTX_set_default() first appeared in OpenSSL 0.9.8 and have been available since OpenBSD 4.5.

legends only, no cap πŸ’œ


πŸ’€ CAVEATS πŸ’€

bestie, listen to me for a sec πŸ™

The precise effect of a successful call to X509_STORE_CTX_set_trust() and X509_STORE_CTX_set_purpose() is unclear unless only one of these functions is used immediately after X509_STORE_CTX_init(3).

like... unclear. that's the actual word. so it's therefore recommended to use X509_STORE_CTX_get0_param(), X509_VERIFY_PARAM_set_trust(3), and X509_VERIFY_PARAM_set_purpose(3) instead. do that. trust me on this one πŸ’…βœ¨


and that's the whole page, bestie 🫢 this one's from the Debian build of the manual, dated June 8, 2025, and yes the page file itself is literally named X509_STORE_CTX_SET_FLAGS(3) β€” we stan a title that doubles as the filename 🌸 go forth and initialise your params correctly πŸ’–

πŸ“¦ where this page comes from