OPENSSL_SK_NEW(3)
π OPENSSL_SK_NEW(3) β bestie edition
okay so this is from the libcrypto library, and it's the whole OpenSSL "stack" situation β variable-sized arrays of void pointers. buckle up π
β¨ SYNOPSIS β¨
library βlibcryptoβ #include <openssl/stack.h>
_STACK *
sk_new_null(void);
_STACK *
sk_new(int (*compfunc)(const void *, const void *));
old_function_pointer
sk_set_cmp_func(_STACK *stack,
int (*compfunc)(const void *, const void *));
_STACK *
sk_dup(_STACK *stack);
void
sk_free(_STACK *stack);
void
sk_pop_free(_STACK *stack, void (*freefunc)(void *));
int
sk_num(const _STACK *stack);
void *
sk_value(const _STACK *stack, int index);
int
sk_find(_STACK *stack, void *wanted);
void
sk_sort(_STACK *stack);
int
sk_is_sorted(const _STACK *stack);
int
sk_push(_STACK *stack, void *new_item);
int
sk_unshift(_STACK *stack, void *new_item);
int
sk_insert(_STACK *stack, void *new_item, int index);
void *
sk_set(_STACK *stack, int index, void *new_item);
void *
sk_pop(_STACK *stack);
void *
sk_shift(_STACK *stack);
void *
sk_delete(_STACK *stack, int index);
void *
sk_delete_ptr(_STACK *stack, void *wanted);
void
sk_zero(_STACK *stack);
πΈ NAME πΈ
sk_new_null, sk_new, sk_set_cmp_func, sk_dup, sk_free, sk_pop_free, sk_num, sk_value, sk_find, sk_sort, sk_is_sorted, sk_push, sk_unshift, sk_insert, sk_set, sk_pop, sk_shift, sk_delete, sk_delete_ptr, sk_zero β variable-sized arrays of void pointers, called OpenSSL stacks π
π¦ DESCRIPTION π¦
So OpenSSL came up with this whole idiosyncratic concept of variable-sized arrays of pointers and then β somewhat misleadingly, ngl β decided to call such an array a "stack". π Intrinsically, and fr fr as documented on this very page, OpenSSL stacks are not type safe β they only handle void * function arguments and return values.
OpenSSL also ships a fragile, unusually complicated system of macro-generated wrappers that offers superficial type safety at the expense of extensive obfuscation. It's implemented using large amounts of autogenerated code involving exceedingly ugly, nested cpp(1) macros β see the STACK_OF(3) manual page for the whole situation, iykyk. π
The fundamental data type is the _STACK structure. It stores a variable number of void pointers and remembers how many pointers are currently stored. It can optionally hold a pointer to a comparison function. As long as no comparison function is installed, the order of pointers is meaningful β but the moment a comparison function goes in, that order becomes ill-defined. β¨
π«Ά the constructors
sk_new_null()β allocates and initializes a new, empty stack. iconic behaviour.sk_new()β identical tosk_new_null(), except it also installscompfuncas the comparison function for the new stack object.sk_set_cmp_func()β installscompfuncfor an existing stack. Thecompfuncis allowed to beNULL, but the stack is not. π
π copying & freeing
sk_dup()β creates a shallow copy of the given stack, which must not be aNULLpointer. It neither copies the objects pointed to from the stack nor increases their reference counts β it merely copies the pointers. Extreme care must be taken to avoid freeing the memory twice, like for example by callingsk_free()on one copy and only callingsk_pop_free()on the other. πsk_free()β frees the given stack. It does not free any of the pointers stored on the stack. Unless those pointers are merely copies of pointers owned by other objects, they must be freed before callingsk_free(), in order to avoid leaking memory. Ifstackis aNULLpointer, no action occurs.sk_pop_free()β severely misnamed. It does not at all do what one would expect from a function called "pop". Instead it does the same assk_free(), except that it also calls the functionfreefuncon each of the pointers contained in the stack. If the calls tofreefuncare intended to free the memory in use by the objects on the stack, ensure that no other pointers to the same objects remain elsewhere. π
π₯ looking things up & sorting
sk_find()β searches the stack for thewantedpointer. If the stack contains more than one copy of thewantedpointer, only the first match is found. If a comparison function is installed for the stack, the stack is first sorted withsk_sort(), and instead of comparing pointers, two pointers are considered to match if the comparison function returns0.sk_sort()β sorts the stack usingqsort(3)and the installed comparison function. Ifstackis aNULLpointer or already considered sorted, no action occurs. This function can only be called if a comparison function is installed.sk_is_sorted()β reports whether the stack is considered sorted. Callingsk_new_null()orsk_new(), successfully callingsk_push(),sk_unshift(),sk_insert(), orsk_set(), or changing the comparison function sets the state to unsorted. If a comparison function is installed, callingsk_sort(), orsk_find()sets the state to sorted. π¦
β adding stuff
sk_push()β pushesnew_itemonto the end of the stack, increasing the number of pointers by1. Ifstackis aNULLpointer, no action occurs.sk_unshift()β insertsnew_itemat the beginning of the stack, such that it gets the index0. The number of pointers increases by1. Ifstackis aNULLpointer, no action occurs.sk_insert()β inserts thenew_iteminto the stack such that it gets the givenindex. Ifindexis less than0or greater than or equal tosk_num(stack), the effect is the same as forsk_push(). Ifstackis aNULLpointer, no action occurs.sk_set()β replaces the pointer with the givenindexon the stack with thenew_item. The old pointer is not freed, which may leak memory if no copy of it exists elsewhere. Ifstackis aNULLpointer or ifindexis less than0or greater than or equal tosk_num(stack), no action occurs. π
π removing stuff
sk_pop()andsk_shift()β remove the pointer with the highest or lowest index from the stack, respectively, reducing the number of pointers by1. Ifstackis aNULLpointer or if it is empty, no action occurs.sk_delete()β removes the pointer with the givenindexfrom the stack, reducing the number of pointers by1. Ifstackis aNULLpointer or theindexis less than0or greater than or equal tosk_num(stack), no action occurs.sk_delete_ptr()β removes thewantedpointer from the stack, reducing the number of pointers by1if it is found. It never uses a comparison function but only compares pointers themselves. The stack pointer must not beNULL. πsk_zero()β removes all pointers from the stack. It does not free any of the pointers. Unless those pointers are merely copies of pointers owned by other objects, they must be freed before callingsk_zero(), in order to avoid leaking memory. Ifstackis aNULLpointer, no action occurs. π
π RETURN VALUES π
sk_new_null(),sk_new(), andsk_dup()β return a pointer to the newly allocated stack object, orNULLif insufficient memory is available.sk_set_cmp_func()β returns a pointer to the comparison function that was previously installed for the stack, orNULLif none was installed.sk_num()β returns the number of pointers currently stored on the stack, or-1ifstackis aNULLpointer.sk_value()β returns the pointer with the givenindexfrom the stack, orNULLifstackis aNULLpointer or if theindexis less than0or greater than or equal tosk_num(stack).sk_find()β returns the lowest index considered to match, or-1ifstackis aNULLpointer or if no match is found.sk_is_sorted()β returns1if the stack is considered sorted or if it is aNULLpointer, or0otherwise.sk_push(),sk_unshift(), andsk_insert()β return the new number of pointers on the stack, or0ifstackis aNULLpointer or if memory allocation fails.sk_set()β returnsnew_item, orNULLifstackis aNULLpointer or if theindexis less than0or greater than or equal tosk_num(stack).sk_pop()andsk_shift()β return the deleted pointer, orNULLifstackis aNULLpointer or if it is empty.sk_delete()β returns the deleted pointer, orNULLifstackis aNULLpointer or if theindexis less than0or greater than or equal tosk_num(stack).sk_delete_ptr()β returnswanted, orNULLif it is not found. β¨
π§ SEE ALSO π§
STACK_OF(3) β go read it, it's giving the macro-wrapper saga π«Ά
π HISTORY π
sk_new_null(), sk_new(), sk_free(), sk_pop_free(), sk_num(), sk_value(), sk_find(), sk_push(), sk_unshift(), sk_insert(), sk_pop(), sk_shift(), sk_delete(), and sk_delete_ptr() first appeared in SSLeay 0.5.1. sk_set_cmp_func(), sk_dup(), and sk_zero() first appeared in SSLeay 0.8.0. These functions have been available since OpenBSD 2.4. πΈ
sk_set() first appeared in OpenSSL 0.9.3. sk_sort() first appeared in OpenSSL 0.9.4. Both functions have been available since OpenBSD 2.6.
sk_is_sorted() first appeared in OpenSSL 0.9.7e and has been available since OpenBSD 3.8. β
π BUGS π
Even if a comparison function is installed, empty stacks and stacks containing a single pointer are sometimes considered sorted and sometimes considered unsorted. literally make it make sense π
If a comparison function is installed, the concept of "first match" in sk_find() is ill-defined because qsort(3) is not a stable sorting function. It is probably best to only assume that they return an arbitrary match. fr fr π
okay that's the whole page bestie, go forth and stack responsibly π«Άπ
Debian Β· June 8, 2025 Β· OPENSSL_SK_NEW(3) β mwah, that's a wrap πβ¨
π¦ 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) 2018 Ingo Schwarze <schwarze@openbsd.org>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms