X509V3_GET_EXT_BY_NID(3ossl)

πŸ“¦ version 3.5.0, in opensuse-leap 16.0

πŸ’… X509v3_get_ext_by_NID β€” extension stack utility functions (a 3ossl moment)

okay so bestie, welcome to the OpenSSL section 3ossl page about extension stacks ✨ this whole family of functions is your go-to for poking at the extensions on a certificate, a CRL, or a CRL entry β€” and honestly once you get the vibe it's so slay.


✨ NAME ✨

Here's the whole squad (yes, all of them, no cap β€” every single one shows up on this page):

  • the X509v3_* girlies: 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
  • the X509_* crew: 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
  • the X509_CRL_* crew: 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
  • the X509_REVOKED_* crew: 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

collectively: 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 πŸ¦‹

the X509v3_* originals (main character energy πŸ‘‘)

  • X509v3_get_ext_count() β€” pulls the number of extensions in x. that's it, that's the whole job πŸ’–
  • X509v3_get_ext() β€” grabs extension loc out of x. the index loc can be any value from 0 to X509_get_ext_count(x) - 1. heads up though: the extension you get back is an internal pointer and it MUST NOT be freed by the application. not yours, don't touch πŸ™ˆ
  • X509v3_get_ext_by_NID() and X509v3_get_ext_by_OBJ() β€” hunting for an extension with nid or obj in 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. not found? -1, sorry bestie 😭
  • X509v3_get_ext_by_critical() β€” literally the same vibe as X509v3_get_ext_by_NID() except it's looking for an extension of criticality crit. a zero value for crit looks for a non-critical extension, and a nonzero value looks for a critical one. vibe check complete ✨
  • X509v3_delete_ext() β€” deletes the extension with index loc from x. the deleted extension gets returned to you and must be freed by the caller (yes, really β€” see NOTES below, it's giving counter-intuitive πŸ’€). if loc is an invalid index value, NULL comes back.
  • X509v3_add_ext() β€” inserts extension ex into STACK *x at position loc. if loc is -1, the new extension gets appended to the end (so easy πŸŽ€). a new STACK is allocated if *x is NULL. the passed extension ex is duplicated, so you still gotta free it after use πŸ‘
  • X509v3_add_extensions() β€” adds the list of extensions exts to STACK *target. if exts is NULL or an empty list, *target comes back unchanged. otherwise a new stack is allocated if *target is NULL. and here's the iconic part: an extension to be added that has the same OID as a pre-existing one replaces that earlier one. out with the old, in with the new πŸ’…

the X509_* versions (certificate edition 🌈)

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() all operate on the extensions of certificate x. literally otherwise identical to the X509v3 functions β€” same energy, different target 🫢

the X509_CRL_* versions (CRL edition πŸ”₯)

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() operate on the extensions of CRL x. again, otherwise identical to the X509v3 functions ✨

the X509_REVOKED_* versions (CRL entry edition πŸ“)

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() operate on the extensions of CRL entry x. and yeah β€” otherwise identical to the X509v3 functions πŸ’œ


πŸ’€ NOTES πŸ’€

okay so these functions are for examining stacks of extensions directly. that's their whole thing.

if your application wants to parse or encode and add an extension, bestie, use the extension encode and decode functions instead β€” think X509_add1_ext_i2d() and X509_get_ext_d2i() 🧚

for X509v3_get_ext_by_NID(), X509v3_get_ext_by_OBJ(), X509v3_get_ext_by_critical() and its variants β€” a zero index return value is not an error, because extension STACK x indices start from zero. these search functions start from the extension after the lastpos parameter, so it should initially be set to -1. ⚠️ if you set it to 0, the initial extension will not be checked. you've been warned πŸ™ˆ

X509v3_delete_ext() and its variants are a bit counter-intuitive because these functions do not free the extension they delete. they return an X509_EXTENSION object which must be explicitly freed using X509_EXTENSION_free(). like, it's literally your problem now 😭


⭐ RETURN VALUES ⭐

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

πŸ’– SEE ALSO πŸ’–


πŸ¦‹ HISTORY πŸ¦‹

X509v3_add_extensions() was added in OpenSSL 3.4. the new girl on the block πŸ’…


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 page, bestie!! 🫢 this one's from OpenSSL 3.5.0, dated 2026-09-25 β€” go read it again if you need to, iykyk βœ¨πŸ’–πŸŽ€

πŸ“¦ where this page comes from