LIBRESSL-X509_STORE_CTX_SET_FLAGS(3)
π 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 toflags. wanna know what those flags even mean? go readX509_VERIFY_PARAM_set_flags(3), she explains it πX509_STORE_CTX_set_time()β sets the verification time, usingX509_VERIFY_PARAM_set_time(3). and thedummyargument? literally ignored. not me packing a whole unused argument in there πX509_STORE_CTX_set_depth()β sets the maximum verification depth viaX509_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 withX509_VERIFY_PARAM_set_trust(3). but heads up: if thetrustargument is0or invalid, or the trust identifier is already set to a non-zero value in theX509_VERIFY_PARAMobject, then nothing happens. zero action. ghosted πX509_STORE_CTX_set_purpose()β sets the purpose identifier, which you can also set withX509_VERIFY_PARAM_set_purpose(3). if thepurposeargument is0or 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 withctx. just a peek, not a copy, bestie πX509_STORE_CTX_set0_param()β sets that internal verification parameter pointer toparam. after this call,paramshould 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 toname. it usesX509_VERIFY_PARAM_lookup(3)to find an appropriate set of parameters fromname, then copies them withX509_VERIFY_PARAM_inherit(3). iconic lookup-then-inherit combo π
β RETURN VALUES β
X509_STORE_CTX_set_trust()β returns1if thetrustargument is0or valid, or0if it's invalid but not0. and fr fr, a return of1does not imply the trust identifier stored in theX509_VERIFY_PARAMobject was actually changed. like she said yes but nothing happened πX509_STORE_CTX_set_purpose()β returns1if both thepurposeargument and the associated trust are0or valid. returns0if either thepurposeargument or the associated trust is invalid but not0. same disclaimer: a1does not imply any data was changed πX509_STORE_CTX_get0_param()β returns a pointer to anX509_VERIFY_PARAMstructure, orNULLif an error occurred πX509_STORE_CTX_set_default()β returns1for success, or0if 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 atrustargument that is invalid but not0. heads up: other implementations may also return this whenX509_STORE_CTX_set_purpose()is called with apurposeargument 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"β thepurposeargument is invalid but not0.
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()andX509_STORE_CTX_set_purpose()first appeared in OpenSSL 0.9.5 and have been available since OpenBSD 2.7.X509_STORE_CTX_set_flags()andX509_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(), andX509_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 toX509_STORE_CTX_set_trust()andX509_STORE_CTX_set_purpose()is unclear unless only one of these functions is used immediately afterX509_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
- alpine 3.24: libressl-doc 4.3.1-r0 Β· custom
- arch rolling: libressl 4.4.0-1 Β· ISC AND custom:OpenSSL
- Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
- Copyright (c) 2021 Ingo Schwarze <schwarze@openbsd.org>
- Copyright (c) 2009 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