X509_PURPOSE_SET(3)
π X509_PURPOSE_SET(3) π
okay so bestie, this is the X509_PURPOSE_SET(3) page from the Library Functions Manual, and it's all about the libcrypto life. The squad is purpose objects, indices, and identifiers β and the way this page ate? It's giving certificate-purpose realness, and we're obsessed. π«Ά No cap.
β¨ NAME β¨
X509_PURPOSE_set, X509_PURPOSE_get_by_id, X509_PURPOSE_add, X509_PURPOSE_get_count, X509_PURPOSE_cleanup, X509_PURPOSE_get0, X509_PURPOSE_get_by_sname, X509_PURPOSE_get_id, X509_PURPOSE_get0_name, X509_PURPOSE_get0_sname, X509_PURPOSE_get_trust β purpose objects, indices, and identifiers. That's the whole cast. π
π¦ SYNOPSIS π¦
Library is libcrypto, and you're gonna need this include:
library βlibcryptoβ #include <openssl/x509v3.h>
Here's the function lineup, literally all of it:
int
X509_PURPOSE_set(int *id_out, int id_in);
int
X509_PURPOSE_get_by_id(int identifier);
int
X509_PURPOSE_add(int identifier, int trust, int flags,
int (*check_purpose)(const X509_PURPOSE *, const X509 *, int),
const char *name, const char *sname, void *usr_data);
int
X509_PURPOSE_get_count(void);
void
X509_PURPOSE_cleanup(void);
X509_PURPOSE *
X509_PURPOSE_get0(int index);
int
X509_PURPOSE_get_by_sname(const char *sname);
int
X509_PURPOSE_get_id(const X509_PURPOSE *object);
char *
X509_PURPOSE_get0_name(const X509_PURPOSE *object);
char *
X509_PURPOSE_get0_sname(const X509_PURPOSE *object);
int
X509_PURPOSE_get_trust(const X509_PURPOSE *object);
π DESCRIPTION π
The purposes that an X.509 certificate is intended to be used for can be identified in three equivalent ways. Not one, not two β three. π
- Purpose identifiers β positive integer constants. Standard purpose identifiers lie in the range from
X509_PURPOSE_MINtoX509_PURPOSE_MAX, inclusive, and are listed in theX509_check_purpose(3)manual page. User-defined purpose identifiers are larger thanX509_PURPOSE_MAX. π - Purpose indices β non-negative integer constants, but they differ from the purpose identifiers for the same purpose. Standard purpose indices are smaller than
X509_PURPOSE_MAX. User-defined purpose indices are larger than or equal toX509_PURPOSE_MAX. π - Purpose objects of the type
X509_PURPOSE. Standard purpose objects are available in static storage. User-defined purpose objects can be created withX509_PURPOSE_add(). π¦
Application programmers cannot choose the way to identify purposes that they like best; depending on the circumstances, all three ways are needed. Be warned that the naming of most functions is misleading. π
Most API functions documented outside the present manual page use purpose identifiers rather than purpose indices. iykyk. π
π― Using purpose identifiers π―
X509_PURPOSE_set()β validates the purpose identifierid_in. If it's valid, it gets copied to*id_out. Otherwise,*id_outremains unchanged. No sneaky overwrite. πX509_PURPOSE_get_by_id()β converts the purpose identifier to the corresponding purpose index. To find the corresponding purpose object, pass the result toX509_PURPOSE_get0(). πX509_PURPOSE_add()β defines a purpose with the given identifier, or modifies its properties if it already exists. The purpose identifier, the trust identifier, the flags, thecheck_purposefunction, the name, the short namesname, and theusr_datapointer are copied into theX509_PURPOSEobject. When modifying an existing purpose object, previous values of fields are overwritten and previousnameandsnamestrings are freed if they were dynamically allocated. When creating a new purpose object, it is added to the global array of user-defined purpose objects. π οΈ
Now the flags tea, because this is where it gets spicy. X509_PURPOSE_DYNAMIC and X509_PURPOSE_DYNAMIC_NAME are always ignored in the flags argument. X509_PURPOSE_DYNAMIC is automatically set if the object was created by the user. It is never set for standard objects, not even if they were modified by the user. X509_PURPOSE_DYNAMIC_NAME is automatically set if the object was created or modified by the user. It is only unset for unmodified standard objects. The library does not appear to define any other flags, so the flags argument is probably useless unless users define their own flags and use them in the check_purpose function. π
The third and final argument of the check_purpose function is the ca argument documented in X509_check_purpose(3). π«Ά
X509_PURPOSE_get_count() returns the total number of purposes currently defined, including both standard and user-defined purposes. If no user-defined purposes exist, the returned value is X509_PURPOSE_MAX. π
X509_PURPOSE_cleanup() deletes all user-defined purpose objects and invalidates their purpose identifiers and purpose indices. If any of the standard purpose objects were modified by the user, those changes are not reverted. π§Ή
π’ Using purpose indices π’
X509_PURPOSE_get0()β converts the purpose index to a pointer to the corresponding purpose object. To find the corresponding purpose identifier, pass the result toX509_PURPOSE_get_id(). πͺX509_PURPOSE_get_by_sname()β returns the lowest index of a purpose with the given short name. Lowkey the lowest. π
π§ Using purpose objects π§
X509_PURPOSE_get_id()β converts a pointer to a purpose object to the corresponding purpose identifier. To find the corresponding purpose index, pass the result toX509_PURPOSE_get_by_id(). πX509_PURPOSE_get0_name(),X509_PURPOSE_get0_sname(), andX509_PURPOSE_get_trust()β retrieve the name, short name, and trust identifier from the object, respectively. π
π RETURN VALUES π
X509_PURPOSE_set()β returns1ifid_inis valid or0otherwise. βX509_PURPOSE_get_by_id()andX509_PURPOSE_get_by_sname()β return the corresponding purpose index or-1if no matching purpose is found. πX509_PURPOSE_add()β returns1for success or0for failure. π―X509_PURPOSE_get_count()β returns the total number of purposes currently defined. πX509_PURPOSE_get0()β returns a standard or user-defined purpose object orNULLif the index is invalid. π«₯X509_PURPOSE_get_id()β always returns a valid purpose identifier. π―X509_PURPOSE_get0_name()andX509_PURPOSE_get0_sname()β return pointers to storage owned by the object. ποΈX509_PURPOSE_get_trust()β returns the trust identifier associated with the object. π€
π ERRORS π
The following diagnostics can be retrieved with ERR_get_error(3), ERR_GET_REASON(3), and ERR_reason_error_string(3): π¨
X509V3_R_INVALID_PURPOSE"invalid purpose"βX509_PURPOSE_set()was called with an invalidid_inargument. πX509V3_R_INVALID_NULL_ARGUMENT"invalid null argument"βX509_PURPOSE_add()was called with anameorsnameargument ofNULL. π«ERR_R_MALLOC_FAILURE"malloc failure"βX509_PURPOSE_add()failed to allocate memory. π
The other functions provide no diagnostics. π€
πΈ SEE ALSO πΈ
X509_check_purpose(3), X509_new(3), X509_STORE_set_purpose(3), X509_VERIFY_PARAM_set_purpose(3). Go read those next, bestie. π
π HISTORY π
X509_PURPOSE_set() first appeared in OpenSSL 0.9.7 and has been available since OpenBSD 3.2. π°οΈ
The other functions first appeared in OpenSSL 0.9.5 and have been available since OpenBSD 2.7. π¦
β οΈ CAVEATS β οΈ
The difference between purpose identifiers and purpose indices provides an ideal breeding ground for off-by-one bugs. ππͺ So keep your indices and identifiers straight, bestie. Not me warning you twice. π
π«Ά Debian, June 8, 2025 β that's the footer, bestie. X509_PURPOSE_SET(3) out. π
π¦ 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) 2021 Ingo Schwarze <schwarze@openbsd.org>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms