--- /dev/null
+.\" $OpenBSD: OBJ_NAME_add.3,v 1.1 2021/12/17 17:56:14 schwarze Exp $
+.\"
+.\" Copyright (c) 2021 Ingo Schwarze <schwarze@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: December 17 2021 $
+.Dt OBJ_NAME_ADD 3
+.Os
+.Sh NAME
+.Nm OBJ_NAME_add ,
+.Nm OBJ_NAME_remove ,
+.Nm OBJ_NAME_get ,
+.Nm OBJ_NAME_new_index ,
+.Nm OBJ_NAME_init ,
+.Nm OBJ_NAME_cleanup ,
+.Nm OBJ_NAME_do_all ,
+.Nm OBJ_NAME_do_all_sorted
+.Nd global associative array
+.Sh SYNOPSIS
+.In openssl/objects.h
+.Ft int
+.Fo OBJ_NAME_add
+.Fa "const char *name"
+.Fa "int type"
+.Fa "const char *data"
+.Fc
+.Ft int
+.Fo OBJ_NAME_remove
+.Fa "const char *name"
+.Fa "int type"
+.Fc
+.Ft const char *
+.Fo OBJ_NAME_get
+.Fa "const char *name"
+.Fa "int type"
+.Fc
+.Ft int
+.Fo OBJ_NAME_new_index
+.Fa "unsigned long (*hash_func)(const char *name)"
+.Fa "int (*cmp_func)(const char *name1, const char *name2)"
+.Fa "void (*free_func)(const char *name, int type, const char *value)"
+.Fc
+.Ft int
+.Fn OBJ_NAME_init void
+.Ft void
+.Fn OBJ_NAME_cleanup "int type"
+.Bd -literal
+typedef struct {
+ int type;
+ int alias;
+ const char *name;
+ const char *data;
+} OBJ_NAME;
+.Ed
+.Pp
+.Ft void
+.Fo OBJ_NAME_do_all
+.Fa "int type"
+.Fa "void (*fn)(const OBJ_NAME *pair, void *arg)"
+.Fa "void *arg"
+.Fc
+.Ft void
+.Fo OBJ_NAME_do_all_sorted
+.Fa "int type"
+.Fa "void (*fn)(const OBJ_NAME *pair, void *arg)"
+.Fa "void *arg"
+.Fc
+.Sh DESCRIPTION
+These functions implement a single, static associative array
+with the following properties:
+.Bl -bullet
+.It
+The keys are ordered pairs consisting of a NUL-terminated string
+.Pq called the Fa name
+and an
+.Vt int
+number
+.Pq called the Fa type .
+Two types are predefined and used internally by the library:
+.Dv OBJ_NAME_TYPE_MD_METH
+and
+.Dv OBJ_NAME_TYPE_CIPHER_METH .
+Two additional types are predefined but not used internally:
+.Dv OBJ_NAME_TYPE_PKEY_METH
+and
+.Dv OBJ_NAME_TYPE_COMP_METH .
+All predefined types are greater than
+.Dv OBJ_NAME_TYPE_UNDEF
+and smaller than
+.Dv OBJ_NAME_TYPE_NUM .
+.It
+The values are pointers.
+Formally, they are of the type
+.Vt const char * ,
+but in practice, pointers of other types, for example
+.Vt EVP_CIPHER *
+or
+.Vt EVP_MD * ,
+are often stored as values
+and cast back to the correct type on retrieval.
+.It
+The array supports type-specific aliases for names.
+.El
+.Pp
+.Fn OBJ_NAME_add
+removes the key-value pair or alias with the key
+.Pq Fa name , type
+in the same way as
+.Fn OBJ_NAME_remove
+and inserts a key-value pair with the specified
+.Fa name ,
+.Fa type ,
+and
+.Fa value .
+If the bit
+.Dv OBJ_NAME_ALIAS
+is set in the
+.Fa type
+argument, that bit is cleared before using the
+.Fa type
+and the key
+.Pq Fa name , type
+becomes an alias for the key
+.Pq Fa value , type
+instead of setting a value.
+It is not checked whether the key
+.Pq Fa value , type
+already exists.
+Consequently, it is possible to define an alias
+before setting the associated value.
+.Pp
+.Fn OBJ_NAME_remove
+removes the key-value pair or alias with the key
+.Pq Fa name , type
+from the array, it it exists.
+Otherwise, it has no effect.
+If the bit
+.Dv OBJ_NAME_ALIAS
+is set in the
+.Fa type
+argument, it is ignored and cleared before using the
+.Fa type .
+If the
+.Fa type
+is an application-defined type added with
+.Fn OBJ_NAME_new_index
+and the
+.Fa free_func
+associated with the
+.Fa type
+is not a
+.Dv NULL
+pointer, it is called with the
+.Fa name ,
+.Fa type ,
+and
+.Fa value
+of the key-value pair being removed or with the
+.Fa name ,
+.Fa type ,
+and alias target name of the alias being removed.
+In typical usage, this function might free the
+.Fa name ,
+and it might free the
+.Fa value
+in a type-specific way.
+.Pp
+.Fn OBJ_NAME_get
+looks up the key
+.Pq Fa name , type ,
+recursively resolving up to ten aliases if needed.
+If the bit
+.Dv OBJ_NAME_ALIAS
+is set in the
+.Fa type
+argument, it is cleared before using the
+.Fa type ,
+processing of aliases is disabled, and if
+.Pq Fa name , type
+is an alias, the target name of the alias is returned instead of a value.
+.Pp
+.Fn OBJ_NAME_new_index
+assigns the smallest unassigned positive integer number
+to represent a new, application-defined
+.Fa type .
+The three function pointers will be used, respectively,
+to hash a name for this type, to compare two names for this type,
+and to free the contents of a key-value pair holding the given
+.Fa name ,
+.Fa type ,
+and
+.Fa value .
+If the
+.Fa hash_func
+argument is a
+.Dv NULL
+pointer,
+.Xr lh_strhash 3
+is used instead.
+If the
+.Fa cmp_func
+argument is a
+.Dv NULL
+pointer,
+.Xr strcmp 3
+is used instead.
+If the
+.Fa free_func
+argument is a
+.Dv NULL
+pointer, the
+.Fa name
+and
+.Fa value
+pointers contained in the key-value pair are not freed,
+only the structure representing the pair itself is.
+This default behaviour is also used for the built-in types.
+.Pp
+.Fn OBJ_NAME_init
+initializes the array.
+After initialization, the array is empty.
+Calling
+.Fn OBJ_NAME_init
+when the array is already initialized has no effect.
+Application programs do not need to call this function because
+.Fn OBJ_NAME_add
+and
+.Fn OBJ_NAME_get
+automatically call it whenever needed.
+.Pp
+.Fn OBJ_NAME_cleanup
+removes all key-value pairs and aliases of the given
+.Fa type
+from the array by calling
+.Fn OBJ_NAME_remove
+on every such pair and alias.
+If the
+.Fa type
+argument is negative, it removes all key-value pairs and aliases
+of any type and also reverses all effects of
+.Fn OBJ_NAME_new_index
+and
+.Fn OBJ_NAME_init ,
+in particular resetting the list of types to the predefined types
+and releasing all memory reserved by these functions.
+.Pp
+The
+.Vt OBJ_NAME
+structure represents one key-value pair or one alias with the key
+.Pq Fa name , type .
+If the
+.Fa alias
+field is 0, the
+.Fa data
+field contains the value; otherwise, it contains the alias target name.
+.Pp
+.Fn OBJ_NAME_do_all
+calls
+.Fa fn
+on every
+.Fa pair
+and alias in the array that has the given
+.Fa type ,
+also passing the
+.Fa arg
+pointer.
+.Fn OBJ_NAME_do_all_sorted
+is similar except that it processes the pairs and aliases
+in lexicographic order of their names as determined by
+.Xr strcmp 3 ,
+ignoring any
+.Fa cmp_func
+that may be defined for the
+.Fa type .
+.Sh RETURN VALUES
+.Fn OBJ_NAME_add
+and
+.Fn OBJ_NAME_init
+return 1 on success or 0 if memory allocation fails.
+.Pp
+.Fn OBJ_NAME_remove
+returns 1 if one key-value pair or alias was removed or 0 otherwise.
+.Pp
+.Fn OBJ_NAME_get
+returns the
+.Fa value
+associated with the key
+.Pq Fa name , type
+or
+.Dv NULL
+if
+.Fa name
+is
+.Dv NULL ,
+if the array does not contain a value for this key,
+or if more than ten aliases are encountered before finding a value.
+.Pp
+.Fn OBJ_NAME_new_index
+returns a positive integer greater than or equal to
+.Dv OBJ_NAME_TYPE_NUM
+representing the new type or 0 if memory allocation fails.
+.Sh SEE ALSO
+.Xr EVP_cleanup 3 ,
+.Xr EVP_get_cipherbyname 3 ,
+.Xr EVP_get_digestbyname 3 ,
+.Xr lh_new 3 ,
+.Xr OBJ_create 3 ,
+.Xr OBJ_nid2obj 3
+.Sh BUGS
+Calling
+.Fn OBJ_NAME_get
+with the bit
+.Dv OBJ_NAME_ALIAS
+is not very useful because there is no way to tell
+whether the returned pointer points to a value or to a name,
+short of calling the function again without setting the bit
+and comparing the two returned pointers.
+.Pp
+The
+.Fa free_func
+has no way to tell whether its
+.Fa value
+argument is indeed of the given
+.Fa type
+or whether it is merely the target name of an alias.
+Consequently, to use values of a type
+that requires more cleanup than merely calling
+.Xr free 3
+on it, instances of the type need to begin with a magic number or string
+that cannot occur at the beginning of a name.
+.Pp
+.Fn OBJ_NAME_do_all_sorted
+is unable to report errors.
+If memory allocations fails, it does nothing at all
+without telling the caller about the problem.