X509_NAME_ADD_ENTRY_BY_TXT(3ossl)

πŸ“¦
version 15.1 Β· 2 versions
, in freebsd 15.1

πŸ’– X509_NAME_ADD_ENTRY_BY_TXT(3ossl) πŸ’–

okay so bestie, listen β€” this is the 3ossl manual page for the little squad of functions that let you edit an X509_NAME: like, add fields to it, delete fields from it, whole thing. The main character is X509_NAME_add_entry_by_txt, but she brought her friends X509_NAME_add_entry_by_OBJ, X509_NAME_add_entry_by_NID, X509_NAME_add_entry, and X509_NAME_delete_entry along for the ride. It's giving "X509_NAME modification functions" and we're obsessed πŸŽ€


🌸 SYNOPSIS 🌸

like, include the header first, obviously:

#include <openssl/x509.h>

and then the whole lineup, no cap:

int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
                               const unsigned char *bytes, int len, int loc, int set);

int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type,
                               const unsigned char *bytes, int len, int loc, int set);

int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
                               const unsigned char *bytes, int len, int loc, int set);

int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, int loc, int set);

X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);

✨ DESCRIPTION ✨

so here's the tea πŸ“ X509_NAME_add_entry_by_txt(), X509_NAME_add_entry_by_OBJ(), and X509_NAME_add_entry_by_NID() all add a field to name, but they each identify that field differently β€” by a string field, by an object obj, or by a nid (a NID, bestie), respectively. Cute, right? πŸ’…

The actual field value you're adding lives in bytes, and it's len bytes long. If len is -1, the length gets calculated internally using strlen(bytes) β€” so it just figures it out itself, main character energy honestly.

The type of the field? That's determined by type, which can be either a definition of the type of bytes (like MBSTRING_ASC) or a standard ASN1 type (like V_ASN1_IA5STRING). And where does the new entry land? That's loc and set's whole job. Slay. ✨

X509_NAME_add_entry() adds a copy of the X509_NAME_ENTRY structure ne to name, at a position determined by loc and set. And because it's a copy, you still gotta free ne up after the call β€” yes, even though it's a copy, don't forget, iykyk 😭

X509_NAME_delete_entry() deletes an entry from name at position loc. It returns the deleted entry, and you have to free that up too. Free everything, always. 🫢


πŸ¦‹ NOTES πŸ¦‹

okay this part is important so pay attention bestie πŸ‘‘

Using string types like MBSTRING_ASC or MBSTRING_UTF8 for the type parameter is strongly recommended. Why? Because it lets the internal code correctly determine the type of the field and apply length checks according to the relevant standards. This whole thing happens using ASN1_STRING_set_by_NID(). Iconic.

But if you instead use an ASN1 type? No checks are performed, and the supplied data in bytes is used directly. Just raw. No vibe check. πŸ’€

Also in X509_NAME_add_entry_by_txt(), the field string represents the field name using OBJ_txt2obj(field, 0).

Now, loc and set decide where your new entry goes. For almost all applications, loc can be set to -1 and set to 0 β€” that adds a new entry to the end of name as a single valued RelativeDistinguishedName (RDN). Easy.

loc is literally the index where the new entry gets inserted: if it's -1, it's appended. That's it. That's the whole rule. 🌈

set is about how the new type gets added:

  • If it's zero, a new RDN is created.
  • If set is -1 or 1, it's added as a new set member to the previous or next RDN structure, respectively. That then becomes part of a multi-valued RDN (containing a set of AVAs).

And since multi-valued RDNs are very rarely used, set will typically be zero. Like, almost always zero. Fr fr. πŸ’…


πŸ”₯ RETURN VALUES πŸ”₯

X509_NAME_add_entry_by_txt(), X509_NAME_add_entry_by_OBJ(), X509_NAME_add_entry_by_NID() and X509_NAME_add_entry() return 1 for success, or 0 if an error occurred. One is the good number, zero is the "something went wrong" number. Got it? 🫢

X509_NAME_delete_entry() returns either the deleted X509_NAME_ENTRY structure or NULL if an error occurred. NULL means trouble, bestie. 😭


🌟 EXAMPLES 🌟

okay let's actually do the thing β€” create an X509_NAME structure that looks like this:

"C=UK, O=Disorganized Organization, CN=Joe Bloggs"

here's the code, verbatim, don't touch it:

X509_NAME *nm;

nm = X509_NAME_new();
if (nm == NULL)
    /* Some error */
if (!X509_NAME_add_entry_by_txt(nm, "C", MBSTRING_ASC,
                                "UK", -1, -1, 0))
    /* Error */
if (!X509_NAME_add_entry_by_txt(nm, "O", MBSTRING_ASC,
                                "Disorganized Organization", -1, -1, 0))
    /* Error */
if (!X509_NAME_add_entry_by_txt(nm, "CN", MBSTRING_ASC,
                                "Joe Bloggs", -1, -1, 0))
    /* Error */

see how MBSTRING_ASC, -1, -1, 0 keeps showing up? that's the recommended vibe. we love consistency. ✨


πŸ’€ BUGS πŸ’€

⚠️ warning bestie ⚠️

type can still be set to V_ASN1_APP_CHOOSE to use a different algorithm to determine field types. But listen β€” since this form does not understand multicharacter types, performs no length checks, and can result in invalid field types, its use is strongly discouraged. Like, don't. Please don't. πŸ™ˆ


πŸ‘‘ SEE ALSO πŸ‘‘

go read those too, they're part of the lore 🧚


Copyright 2002-2020 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!! this was version 3.5.6, dated 2026-04-07 β€” write it down, cite it, live laugh love. mwah πŸ’‹πŸ«Άβœ¨

πŸ“¦ where this page comes from