DEFINE_STACK_OF(3ossl)
๐ธ NAME ๐ธ
okay bestie, this is the OpenSSL manual page for DEFINE_STACK_OF(3ossl) โ the one all about the stack container. The full name-drop list is: DEFINE_STACK_OF, DEFINE_STACK_OF_CONST, DEFINE_SPECIAL_STACK_OF, DEFINE_SPECIAL_STACK_OF_CONST, sk_TYPE_num, sk_TYPE_value, sk_TYPE_new, sk_TYPE_new_null, sk_TYPE_reserve, sk_TYPE_free, sk_TYPE_zero, sk_TYPE_delete, sk_TYPE_delete_ptr, sk_TYPE_push, sk_TYPE_unshift, sk_TYPE_pop, sk_TYPE_shift, sk_TYPE_pop_free, sk_TYPE_insert, sk_TYPE_set, sk_TYPE_find, sk_TYPE_find_ex, sk_TYPE_find_all, sk_TYPE_sort, sk_TYPE_is_sorted, sk_TYPE_dup, sk_TYPE_deep_copy, sk_TYPE_set_cmp_func, sk_TYPE_new_reserve, OPENSSL_sk_deep_copy, OPENSSL_sk_delete, OPENSSL_sk_delete_ptr, OPENSSL_sk_dup, OPENSSL_sk_find, OPENSSL_sk_find_ex, OPENSSL_sk_find_all, OPENSSL_sk_free, OPENSSL_sk_insert, OPENSSL_sk_is_sorted, OPENSSL_sk_new, OPENSSL_sk_new_null, OPENSSL_sk_new_reserve, OPENSSL_sk_num, OPENSSL_sk_pop, OPENSSL_sk_pop_free, OPENSSL_sk_push, OPENSSL_sk_reserve, OPENSSL_sk_set, OPENSSL_sk_set_cmp_func, OPENSSL_sk_shift, OPENSSL_sk_sort, OPENSSL_sk_unshift, OPENSSL_sk_value, OPENSSL_sk_zero โ all under the umbrella of stack container. Yes, that is a lot of names, and every single one is invited to the function party ๐
.
โจ SYNOPSIS โจ
#include <openssl/safestack.h>
STACK_OF(TYPE)
DEFINE_STACK_OF(TYPE)
DEFINE_STACK_OF_CONST(TYPE)
DEFINE_SPECIAL_STACK_OF(FUNCTYPE, TYPE)
DEFINE_SPECIAL_STACK_OF_CONST(FUNCTYPE, TYPE)
typedef int (*sk_TYPE_compfunc)(const TYPE *const *a, const TYPE *const *b);
typedef TYPE * (*sk_TYPE_copyfunc)(const TYPE *a);
typedef void (*sk_TYPE_freefunc)(TYPE *a);
int sk_TYPE_num(const STACK_OF(TYPE) *sk);
TYPE *sk_TYPE_value(const STACK_OF(TYPE) *sk, int idx);
STACK_OF(TYPE) *sk_TYPE_new(sk_TYPE_compfunc compare);
STACK_OF(TYPE) *sk_TYPE_new_null(void);
int sk_TYPE_reserve(STACK_OF(TYPE) *sk, int n);
void sk_TYPE_free(STACK_OF(TYPE) *sk);
void sk_TYPE_zero(STACK_OF(TYPE) *sk);
TYPE *sk_TYPE_delete(STACK_OF(TYPE) *sk, int i);
TYPE *sk_TYPE_delete_ptr(STACK_OF(TYPE) *sk, TYPE *ptr);
int sk_TYPE_push(STACK_OF(TYPE) *sk, const TYPE *ptr);
int sk_TYPE_unshift(STACK_OF(TYPE) *sk, const TYPE *ptr);
TYPE *sk_TYPE_pop(STACK_OF(TYPE) *sk);
TYPE *sk_TYPE_shift(STACK_OF(TYPE) *sk);
void sk_TYPE_pop_free(STACK_OF(TYPE) *sk, sk_TYPE_freefunc freefunc);
int sk_TYPE_insert(STACK_OF(TYPE) *sk, TYPE *ptr, int idx);
TYPE *sk_TYPE_set(STACK_OF(TYPE) *sk, int idx, const TYPE *ptr);
int sk_TYPE_find(STACK_OF(TYPE) *sk, TYPE *ptr);
int sk_TYPE_find_ex(STACK_OF(TYPE) *sk, TYPE *ptr);
int sk_TYPE_find_all(STACK_OF(TYPE) *sk, TYPE *ptr, int *pnum);
void sk_TYPE_sort(const STACK_OF(TYPE) *sk);
int sk_TYPE_is_sorted(const STACK_OF(TYPE) *sk);
STACK_OF(TYPE) *sk_TYPE_dup(const STACK_OF(TYPE) *sk);
STACK_OF(TYPE) *sk_TYPE_deep_copy(const STACK_OF(TYPE) *sk,
sk_TYPE_copyfunc copyfunc,
sk_TYPE_freefunc freefunc);
sk_TYPE_compfunc (*sk_TYPE_set_cmp_func(STACK_OF(TYPE) *sk,
sk_TYPE_compfunc compare));
STACK_OF(TYPE) *sk_TYPE_new_reserve(sk_TYPE_compfunc compare, int n);
๐ DESCRIPTION ๐
okay so here's the tea: applications can create and use their own stacks by placing any of the macros described below in a header file. These macros define typesafe inline functions that wrap around the utility OPENSSL_sk_ API. In the description here, TYPE is used as a placeholder for any of the OpenSSL datatypes, such as X509.
The STACK_OF() macro returns the name for a stack of the specified TYPE. This is an opaque pointer to a structure declaration. This can be used in every header file that references the stack. There are several DEFINE... macros that create static inline functions for all of the functions described on this page. This should normally be used in one source file, and the stack manipulation is wrapped with application-specific functions.
DEFINE_STACK_OF() creates set of functions for a stack of TYPE elements. The type is referenced by STACK_OF(TYPE) and each function name begins with sk_TYPE_. DEFINE_STACK_OF_CONST() is identical to DEFINE_STACK_OF() except each element is constant.
/* DEFINE_STACK_OF(TYPE) */
TYPE *sk_TYPE_value(STACK_OF(TYPE) *sk, int idx);
/* DEFINE_STACK_OF_CONST(TYPE) */
const TYPE *sk_TYPE_value(STACK_OF(TYPE) *sk, int idx);
DEFINE_SPECIAL_STACK_OF() and DEFINE_SPECIAL_STACK_OF_CONST() are similar except FUNCNAME is used in the function names:
/* DEFINE_SPECIAL_STACK_OF(TYPE, FUNCNAME) */
TYPE *sk_FUNCNAME_value(STACK_OF(TYPE) *sk, int idx);
/* DEFINE_SPECIAL_STACK_OF(TYPE, FUNCNAME) */
const TYPE *sk_FUNCNAME_value(STACK_OF(TYPE) *sk, int idx);
sk_TYPE_num()โ returns the number of elements inskor-1ifskisNULL. ๐งฎsk_TYPE_value()โ returns elementidxinsk, whereidxstarts at zero. Ifidxis out of range thenNULLis returned.sk_TYPE_new()โ allocates a new empty stack using comparison functioncompare. IfcompareisNULLthen no comparison function is used. This function is equivalent tosk_TYPE_new_reserve(compare, 0).sk_TYPE_new_null()โ allocates a new empty stack with no comparison function. This function is equivalent tosk_TYPE_new_reserve(NULL, 0).sk_TYPE_reserve()โ allocates additional memory in theskstructure such that the nextncalls tosk_TYPE_insert(),sk_TYPE_push()orsk_TYPE_unshift()will not fail or cause memory to be allocated or reallocated. Ifnis zero, any excess space allocated in theskstructure is freed. On errorskis unchanged.sk_TYPE_new_reserve()โ allocates a new stack. The new stack will have additional memory allocated to holdnelements ifnis positive. The nextncalls tosk_TYPE_insert(),sk_TYPE_push()orsk_TYPE_unshift()will not fail or cause memory to be allocated or reallocated. Ifnis zero or less than zero, no memory is allocated.sk_TYPE_new_reserve()also sets the comparison functioncompareto the newly created stack. IfcompareisNULLthen no comparison function is used.sk_TYPE_set_cmp_func()โ sets the comparison function ofsktocompare. The previous comparison function is returned orNULLif there was no previous comparison function.sk_TYPE_free()โ frees up theskstructure. It does not free up any elements ofsk. After this callskis no longer valid. do not touch it after, bestie โ it's giving expired ๐sk_TYPE_zero()โ sets the number of elements inskto zero. It does not freeskso after this callskis still valid.sk_TYPE_pop_free()โ frees up all elements ofskandskitself. The free functionfreefunc()is called on each element to free it.sk_TYPE_delete()โ deletes elementifromsk. It returns the deleted element orNULLifiis out of range.sk_TYPE_delete_ptr()โ deletes element matchingptrfromsk. It returns the deleted element orNULLif no element matchingptrwas found.sk_TYPE_insert()โ insertsptrintoskat positionidx. Any existing elements at or afteridxare moved downwards. Ifidxis out of range the new element is appended tosk.sk_TYPE_insert()either returns the number of elements inskafter the new element is inserted or zero if an error (such as memory allocation failure) occurred.sk_TYPE_push()โ appendsptrtosk; it is equivalent to:
sk_TYPE_insert(sk, ptr, -1);
sk_TYPE_unshift()โ insertsptrat the start ofsk; it is equivalent to:
sk_TYPE_insert(sk, ptr, 0);
sk_TYPE_pop()โ returns and removes the last element fromsk.sk_TYPE_shift()โ returns and removes the first element fromsk.sk_TYPE_set()โ sets elementidxofsktoptr, replacing the current element. The new element value is returned orNULLif an error occurred: this will only happen ifskisNULLoridxis out of range.sk_TYPE_find()โ searchesskfor the elementptr. In the case where no comparison function has been specified, the function performs a linear search for a pointer equal toptr. In the case where a comparison function has been specified, the function performs a search for a element that the comparison function indicates is a match. If the stack is sorted, a binary search is used, otherwise, a linear search is used.sk_TYPE_find()returns the index of a matching element or-1if there is no match.sk_TYPE_find_ex()โ operates likesk_TYPE_find()except when a comparison function has been specified and no matching element is found. Instead of returning-1,sk_TYPE_find_ex()returns the index of the element either before or after the location whereptrwould be if it were present insk. The function also does not guarantee that the first matching element in the sorted stack is returned.sk_TYPE_find_all()โ operates likesk_TYPE_find()but it also sets the*pnumto number of matching elements in the stack. In case no comparison function has been specified the*pnumwill be always set to1if matching element was found,0otherwise.sk_TYPE_sort()โ sortsskusing the supplied comparison function.sk_TYPE_is_sorted()โ returns1ifskis sorted and0otherwise.sk_TYPE_dup()โ returns a shallow copy ofskor an empty stack if the passed stack isNULL. Note the pointers in the copy are identical to the original.sk_TYPE_deep_copy()โ returns a new stack where each element has been copied or an empty stack if the passed stack isNULL. Copying is performed by the suppliedcopyfunc()and freeing byfreefunc(). The functionfreefunc()is only called if an error occurs. ๐ซถ
๐ NOTES ๐
okay bestie, multi-threaded stack stuff needs actual care, no cap. Any operation that increases the size of a stack โ like sk_TYPE_insert() or sk_TYPE_push() โ can โgrowโ the size of an internal array, and that can cause race conditions if the same stack gets accessed in a different thread ๐ญ. Operations such as sk_TYPE_find() and sk_TYPE_sort() can also reorder the stack, so yeah, vibe check your threads.
Any comparison function you supply should use a metric suitable for use in a binary search operation. That means it should return zero, a positive value, or a negative value if a is equal to, greater than, or less than b, respectively. Literally the classic binary-search behavior, periodt.
๐จ Careful with the return values fromsk_TYPE_find()andsk_TYPE_find_ex(), bestie. They return an index to the matching element. In particular,0indicates a matching first element. A failed search is indicated by a-1return value โ so do not treat0as โnope,โ because it is lowkey a slay.
STACK_OF(), DEFINE_STACK_OF(), DEFINE_STACK_OF_CONST(), and DEFINE_SPECIAL_STACK_OF() are implemented as macros. Yes, macros. Iconic behavior, honestly.
It is not an error to call sk_TYPE_num(), sk_TYPE_value(), sk_TYPE_free(), sk_TYPE_zero(), sk_TYPE_pop_free(), sk_TYPE_delete(), sk_TYPE_delete_ptr(), sk_TYPE_pop(), sk_TYPE_shift(), sk_TYPE_find(), sk_TYPE_find_ex(), and sk_TYPE_find_all() on a NULL stack, an empty stack, or with an invalid index. An error is not raised in these conditions. So no dramatic error meltdown there ๐.
The underlying utility OPENSSL_sk_ API should not be used directly. It defines these functions: OPENSSL_sk_deep_copy(), OPENSSL_sk_delete(), OPENSSL_sk_delete_ptr(), OPENSSL_sk_dup(), OPENSSL_sk_find(), OPENSSL_sk_find_ex(), OPENSSL_sk_find_all(), OPENSSL_sk_free(), OPENSSL_sk_insert(), OPENSSL_sk_is_sorted(), OPENSSL_sk_new(), OPENSSL_sk_new_null(), OPENSSL_sk_new_reserve(), OPENSSL_sk_num(), OPENSSL_sk_pop(), OPENSSL_sk_pop_free(), OPENSSL_sk_push(), OPENSSL_sk_reserve(), OPENSSL_sk_set(), OPENSSL_sk_set_cmp_func(), OPENSSL_sk_shift(), OPENSSL_sk_sort(), OPENSSL_sk_unshift(), OPENSSL_sk_value(), OPENSSL_sk_zero(). Leave them alone unless you know exactly what youโre doing, iykyk ๐ซถ.
โจ RETURN VALUES โจ
sk_TYPE_num()โ returns the number of elements in the stack, or-1if the passed stack isNULL. ๐sk_TYPE_value()โ returns a pointer to a stack element, orNULLif the index is out of range.sk_TYPE_new(),sk_TYPE_new_null(), andsk_TYPE_new_reserve()โ return an empty stack, orNULLif an error occurs.sk_TYPE_reserve()โ returns1on successful allocation of the required memory, or0on error.sk_TYPE_set_cmp_func()โ returns the old comparison function, orNULLif there was no old comparison function.sk_TYPE_free(),sk_TYPE_zero(),sk_TYPE_pop_free(), andsk_TYPE_sort()โ do not return values. Theyโre just out here doing their thing โจ.sk_TYPE_pop(),sk_TYPE_shift(),sk_TYPE_delete(), andsk_TYPE_delete_ptr()โ return a pointer to the deleted element, orNULLon error.sk_TYPE_insert(),sk_TYPE_push(), andsk_TYPE_unshift()โ return the total number of elements in the stack, and0if an error occurred.sk_TYPE_set()โ returns a pointer to the replacement element, orNULLon error.sk_TYPE_find()andsk_TYPE_find_ex()โ return an index to the found element, or-1on error.sk_TYPE_is_sorted()โ returns1if the stack is sorted, and0if it is not.sk_TYPE_dup()andsk_TYPE_deep_copy()โ return a pointer to the copy of the stack, orNULLon error.
๐ธ HISTORY ๐ธ
- Before OpenSSL 1.1.0, this was implemented via macros and not inline functions, and was not a public API. Ancient lore, honestly ๐ง.
sk_TYPE_reserve()andsk_TYPE_new_reserve()were added in OpenSSL 1.1.1.- From OpenSSL 3.2.0, the
sk_TYPE_find(),sk_TYPE_find_ex(), andsk_TYPE_find_all()calls are read-only and do not sort the stack. To avoid any performance implications this change introduces,sk_TYPE_sort()should be called before these find operations ๐. - Before OpenSSL 3.3.0,
sk_TYPE_push()returned-1ifskwasNULL. It was changed to return0in this condition as for other errors.
๐ COPYRIGHT ๐
Copyright 2000-2025 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> ๐.
source/version + date check for this page: 3.5.6 ยท 2026-04-07 ยท DEFINE_STACK_OF(3ossl) โ and thatโs the whole stack of it, bestie ๐๐ฆ
๐ฆ where this page comes from
- freebsd 15.1: base 15.1
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms