X509V3_GET_EXT_BY_NID(3ossl)

πŸ’– X509V3_GET_EXT_BY_NID πŸ’–

okay bestie, so this is a page out of the OpenSSL manual β€” specifically the 3ossl one β€” and it's literally all about the extension stack utility functions. like, every flavour of them: the generic X509v3_ girlies, the certificate X509_ ones, the X509_CRL_ ones, and the X509_REVOKED_ ones. they all do the same thing, just for different lil objects. πŸŽ€


✨ NAME ✨

here's the full roster, no one left out, we don't do that here 🫢

  • X509v3_get_ext_count
  • X509v3_get_ext
  • X509v3_get_ext_by_NID
  • X509v3_get_ext_by_OBJ
  • X509v3_get_ext_by_critical
  • X509v3_delete_ext
  • X509v3_add_ext
  • X509v3_add_extensions
  • X509_get_ext_count
  • X509_get_ext
  • X509_get_ext_by_NID
  • X509_get_ext_by_OBJ
  • X509_get_ext_by_critical
  • X509_delete_ext
  • X509_add_ext
  • X509_CRL_get_ext_count
  • X509_CRL_get_ext
  • X509_CRL_get_ext_by_NID
  • X509_CRL_get_ext_by_OBJ
  • X509_CRL_get_ext_by_critical
  • X509_CRL_delete_ext
  • X509_CRL_add_ext
  • X509_REVOKED_get_ext_count
  • X509_REVOKED_get_ext
  • X509_REVOKED_get_ext_by_NID
  • X509_REVOKED_get_ext_by_OBJ
  • X509_REVOKED_get_ext_by_critical
  • X509_REVOKED_delete_ext
  • X509_REVOKED_add_ext

β€” extension stack utility functions πŸ’…


✨ SYNOPSIS ✨

#include <openssl/x509.h>

int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);

int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
                          int nid, int lastpos);
int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
                          const ASN1_OBJECT *obj, int lastpos);
int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
                               int crit, int lastpos);
X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
                                         X509_EXTENSION *ex, int loc);
STACK_OF(X509_EXTENSION)
     *X509v3_add_extensions(STACK_OF(X509_EXTENSION) **target,
                            const STACK_OF(X509_EXTENSION) *exts);

int X509_get_ext_count(const X509 *x);
X509_EXTENSION *X509_get_ext(const X509 *x, int loc);
int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos);
int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos);
int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos);
X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);

int X509_CRL_get_ext_count(const X509_CRL *x);
X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc);
int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos);
int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj,
                            int lastpos);
int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos);
X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);

int X509_REVOKED_get_ext_count(const X509_REVOKED *x);
X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc);
int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos);
int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj,
                                int lastpos);
int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit, int lastpos);
X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);

🌸 DESCRIPTION 🌸

okay so, deep breath, it's a lot of functions but they're all the same shape, i promise. πŸ¦‹

X509v3_get_ext_count() β€” counts how many extensions are chillin' in x. that's it. that's the function.

X509v3_get_ext() β€” grabs extension number loc out of x. the index loc can be literally anything from 0 up to X509_get_ext_count(x) - 1. ⚠️ the extension it hands you back is an internal pointer, which means the application MUST NOT free it. do not touch. hands off. it's not yours. πŸ™ˆ

X509v3_get_ext_by_NID() and X509v3_get_ext_by_OBJ() β€” these two go looking for an extension matching nid or obj inside the extension STACK x. the search kicks off from the extension after lastpos, or from the very beginning if lastpos is -1. found it? you get its index back. not found? you get -1. πŸ’€

X509v3_get_ext_by_critical() β€” same energy as X509v3_get_ext_by_NID(), except it's hunting for an extension with criticality crit. a crit of zero means "find me a non-critical one". a nonzero crit means "find me a critical one". πŸ”₯

X509v3_delete_ext() β€” deletes the extension at index loc from x. the deleted extension gets returned to you and the caller must free it. if loc is an invalid index value, you get NULL back instead.

X509v3_add_ext() β€” inserts extension ex into STACK *x at position loc. if loc is -1, the new extension just gets appended to the end. if *x is NULL, a whole new STACK gets allocated for you. note: the extension ex you passed in is duplicated, so you still gotta free it after use. ✨

X509v3_add_extensions() β€” adds the list of extensions exts onto STACK *target. if exts is NULL or an empty list, *target comes back unchanged, no drama. otherwise, if *target is NULL, a new stack gets allocated. and here's the fun part: if an extension you're adding has the same OID as one that's already there, it replaces the earlier one. iconique. πŸ‘‘

X509_get_ext_count(), X509_get_ext(), X509_get_ext_by_NID(), X509_get_ext_by_OBJ(), X509_get_ext_by_critical(), X509_delete_ext() and X509_add_ext() β€” these operate on the extensions of certificate x. otherwise? identical to the X509v3 functions. same girls, different fit. πŸ’…

X509_CRL_get_ext_count(), X509_CRL_get_ext(), X509_CRL_get_ext_by_NID(), X509_CRL_get_ext_by_OBJ(), X509_CRL_get_ext_by_critical(), X509_CRL_delete_ext() and X509_CRL_add_ext() β€” these operate on the extensions of CRL x. otherwise identical to the X509v3 functions. πŸŽ€

X509_REVOKED_get_ext_count(), X509_REVOKED_get_ext(), X509_REVOKED_get_ext_by_NID(), X509_REVOKED_get_ext_by_OBJ(), X509_REVOKED_get_ext_by_critical(), X509_REVOKED_delete_ext() and X509_REVOKED_add_ext() β€” these operate on the extensions of CRL entry x. and yes, otherwise identical to the X509v3 functions. we love a consistent family. 🫢


πŸ“ NOTES πŸ“

these functions are for examining stacks of extensions directly. if your app actually wants to parse, encode and add an extension, use the extension encode and decode functions instead β€” like X509_add1_ext_i2d() and X509_get_ext_d2i(). that's the move. ✨

for X509v3_get_ext_by_NID(), X509v3_get_ext_by_OBJ(), X509v3_get_ext_by_critical() and all their variants: a return value of index zero is not an error, because extension STACK x indices start from zero. these search functions start from the extension after the lastpos parameter, so you should initially set it to -1. πŸ‘€ if you set it to zero, that first extension will not get checked. beware. 😭

X509v3_delete_ext() and its variants are a bit counter-intuitive because these functions do not free the extension they delete. they hand you back an X509_EXTENSION object which you must explicitly free using X509_EXTENSION_free(). the way that it deletes but doesn't free… yeah. just free it yourself bestie. πŸ’€

πŸ’« RETURN VALUES πŸ’«

  • X509v3_get_ext_count() β€” returns the extension count, or 0 for failure.
  • X509v3_get_ext(), X509v3_delete_ext() and X509_delete_ext() β€” return an X509_EXTENSION structure, or NULL if an error occurs.
  • X509v3_get_ext_by_OBJ() and X509v3_get_ext_by_critical() β€” return the extension index, or -1 if an error occurs.
  • X509v3_get_ext_by_NID() β€” returns the extension index, or negative values if an error occurs.
  • X509v3_add_ext() β€” returns a STACK of extensions, or NULL on error.
  • X509v3_add_extensions() β€” returns a STACK of extensions, or NULL on error, or if *target is NULL and exts is NULL or an empty list.
  • X509_add_ext() β€” returns 1 on success and 0 on error.

πŸ‘€ SEE ALSO πŸ‘€

X509V3_get_d2i(3)


πŸ•°οΈ HISTORY πŸ•°οΈ

X509v3_add_extensions() was added in OpenSSL 3.4. she's new here but she's already serving. πŸ’…


Copyright 2015-2024 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.


and that's the whole page bestie, you ate it up fr fr πŸ“βœ¨ this was 3.5.9, dated 2026-09-29, straight from the OpenSSL X509V3_GET_EXT_BY_NID(3ossl) manual β€” go forth and manage your extension stacks responsibly, mwah πŸ’–πŸ¦‹πŸŽ€

πŸ“¦ where this page comes from