LIBRESSL-X509_NAME_GET_INDEX_BY_NID(3)
π X509_NAME_GET_INDEX_BY_NID(3)
okay so bestie, this is the X509_NAME_GET_INDEX_BY_NID(3) page from the Library Functions Manual β it's giving "how do I actually dig through an X509_NAME" energy, and honestly? iconic. let's get into it π
β¨ NAME β¨
X509_NAME_get_index_by_NID, X509_NAME_get_index_by_OBJ, X509_NAME_entry_count, X509_NAME_get_entry, X509_NAME_get_text_by_NID, X509_NAME_get_text_by_OBJ β these are the X509_NAME lookup and enumeration functions. yes, all six of them, one big friend group π«Ά
πΈ SYNOPSIS πΈ
library "libcrypto" and you gotta include this:
#include <openssl/x509.h>
then the whole squad:
int
X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, int lastpos);
int
X509_NAME_get_index_by_OBJ(const X509_NAME *name,
const ASN1_OBJECT *obj, int lastpos);
int
X509_NAME_entry_count(const X509_NAME *name);
X509_NAME_ENTRY *
X509_NAME_get_entry(const X509_NAME *name, int loc);
int
X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len);
int
X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
char *buf, int len);
π¦ DESCRIPTION π¦
these functions let you examine an X509_NAME structure. and what even is that? it's the same as the ASN.1 Name type defined in RFC 2459 (and like, elsewhere too) β the one used for certificate subject and issuer names. so yeah, main character of every cert ever π
X509_NAME_get_index_by_NID() and X509_NAME_get_index_by_OBJ() retrieve the next index matching nid or obj after lastpos. pro tip: lastpos should initially be set to -1. that's the starting line, gorl π
X509_NAME_get_entry() retrieves the X509_NAME_ENTRY from name corresponding to index loc. acceptable values for loc run from 0 to X509_NAME_entry_count(name) - 1. so like, zero-indexed, obviously.
X509_NAME_get_text_by_NID() and X509_NAME_get_text_by_OBJ() retrieve the bytes encoded as UTF-8 from the first entry in name which matches nid or obj.
- if
bufisNULL, nothing is written, but the return value is calculated as usual (iykyk, it's a size-check vibe) - if
bufis notNULL, no more thanlenbytes will be written, and the text written tobufwill be NUL terminated β¨
and here's the part where you gotta pay attention π β if len is not large enough to hold the NUL byte terminated UTF-8 encoding of the text, or if the UTF-8 encoding of the text would contain a NUL byte, no data will be written and the call will return failure. no cap, it just bails.
all the relevant NID_* and OBJ_* codes can be found in the <openssl/objects.h> header file. go look, they're all right there π
π¨ apps that could pass invalid NIDs toX509_NAME_get_index_by_NID()should check for the return value of-2. alternatively, the NID validity can be determined first by checking thatOBJ_nid2obj(nid)is notNULL. literally just vibe check your nid first.
π₯ RETURN VALUES π₯
X509_NAME_get_index_by_NID()β returns the index of the next matching entry,-1if not found, or-2if theniddoes not correspond to a valid OID. that-2is the "your nid is fake" signal πX509_NAME_get_index_by_OBJ()β returns the index of the next matching entry or-1if not found.X509_NAME_entry_count()β returns the total number of entries inname.X509_NAME_get_entry()β returns an internal pointer which must not be freed by the caller, orNULLif the index is invalid. do not free it, bestie, it's not yours πX509_NAME_get_text_by_NID()andX509_NAME_get_text_by_OBJ()β return the length of the output UTF-8 string written, not counting the terminating NUL, or-1in the case of an error or no match being found.
and in some cases of failure of X509_NAME_get_index_by_NID() and X509_NAME_get_text_by_NID(), the reason can be determined with ERR_get_error(3). detective mode π
π EXAMPLES π
process all entries β the classic full-lore run-through:
int i;
X509_NAME_ENTRY *e;
for (i = 0; i < X509_NAME_entry_count(nm); i++) {
e = X509_NAME_get_entry(nm, i);
/* Do something with e */
}
process all commonName entries β the "only the ones I care about" arc:
int lastpos = -1;
X509_NAME_ENTRY *e;
for (;;) {
lastpos = X509_NAME_get_index_by_NID(nm, NID_commonName, lastpos);
if (lastpos == -1)
break;
e = X509_NAME_get_entry(nm, lastpos);
/* Do something with e */
}
see how lastpos starts at -1? told you π
π§ SEE ALSO π§
d2i_X509_NAME(3), X509_NAME_ENTRY_get_object(3), X509_NAME_new(3)
β HISTORY β
these functions first appeared in SSLeay 0.8.0 and have been available since OpenBSD 2.4. vintage. lowkey legendary π
π CAVEATS π
okay so real talk:
X509_NAME_get_text_by_NID() and X509_NAME_get_text_by_OBJ() are legacy functions which have various limitations which make them of minimal use in practice. not me calling them flops but like... they kinda are π¬
- they can only find the first matching entry
- and they will copy the contents of the field verbatim
which can be highly confusing if the target is a multicharacter string type like a BMPString or a UTF8String. like, you get raw bytes, not always what you expected. rude.
for a more general solution, use X509_NAME_get_index_by_NID() or X509_NAME_get_index_by_OBJ(), followed by X509_NAME_get_entry() on any matching indices, and then the various X509_NAME_ENTRY utility functions on the result. that's the upgrade path, bestie β take it πΈ
kisses, this page is from Debian, dated June 8, 2025 β and it's the X509_NAME_GET_INDEX_BY_NID(3) girlies' official group chat. go read your certs properly, periodt π
β¨
π¦ 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) 2002, 2006, 2014, 2015, 2016 The OpenSSL Project
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms