NAME
STACK_OF
—
variable-sized arrays of pointers,
called OpenSSL stacks
SYNOPSIS
#include
<openssl/safestack.h>
STACK_OF
(type);
DESCRIPTION
The
<openssl/safestack.h>
header
provides a fragile, unusually complicated system of macro-generated wrappers
around the functions described in the
OPENSSL_sk_new(3) manual page. It is intended to implement
superficially type-safe variable-sized arrays of pointers, somewhat
misleadingly called “stacks” by OpenSSL. Due to the excessive
number of API functions, it is impossible to properly document this system.
In particular, calling
man(1) for any of the functions operating on stacks cannot yield any
result.
Unfortunately, application programs can hardly avoid using the concept because several important OpenSSL APIs rely on it; see the SEE ALSO section for examples. Even though both pages are more complicated than any manual page ought to be, using the concept safely requires a complete understanding of all the details in both this manual page and in OPENSSL_sk_new(3).
The
STACK_OF
()
macro takes a type name as its argument, typically the
name of a type that has been defined as an alias for a specific
struct type using a typedef
declaration. It expands to an incomplete struct type
which is intended to represent a “stack” of objects of the
given type. That type does not actually exist, so it
is not possible to define, for example, an automatic variable
‘STACK_OF(X509) my_certificates
’; it
is only possible to define pointers to stacks, for example
‘STACK_OF(X509) *my_certificates
’. The
only way such pointers can ever be used is by wrapper functions casting them
to the type _STACK * described in
OPENSSL_sk_new(3).
For a considerable number of types, OpenSSL
provides one wrapper function for each function described in
OPENSSL_sk_new(3). The names of these wrapper functions are
usually constructed by inserting the name of the type and an underscore
after the ‘sk_’ prefix of the function name. Usually, where
the real functions take void * arguments, the wrappers
take pointers to the type in questions, and where the
real functions take _STACK * arguments, the wrappers
take pointers to
STACK_OF
(type).
The same applies to return values. Various exceptions to all this exist, but
the above applies to all the types listed below.
Using the above may make sense for the following types because public API functions exist that take stacks of these types as arguments or return them: ASN1_INTEGER, ASN1_OBJECT, ASN1_UTF8STRING, CMS_RecipientInfo, CMS_SignerInfo, CONF_VALUE, GENERAL_NAMES, GENERAL_SUBTREE, OPENSSL_STRING (which is just char *), PKCS12_SAFEBAG, PKCS7, PKCS7_RECIP_INFO, PKCS7_SIGNER_INFO, POLICYQUALINFO, SRTP_PROTECTION_PROFILE, SSL_CIPHER, SSL_COMP, X509, X509_ALGOR, X509_ATTRIBUTE, X509_CRL, X509_EXTENSION, X509_INFO, X509_NAME, X509_OBJECT, X509_POLICY_NODE, X509_REVOKED.
Additionally, some public API functions use the following types which are declared with typedef:
STACK_OF(ACCESS_DESCRIPTION) | AUTHORITY_INFO_ACCESS |
STACK_OF(ASN1_OBJECT) | EXTENDED_KEY_USAGE |
STACK_OF(ASN1_TYPE) | ASN1_SEQUENCE_ANY |
STACK_OF(DIST_POINT) | CRL_DIST_POINTS |
STACK_OF(GENERAL_NAME) | GENERAL_NAMES |
STACK_OF(IPAddressFamily) | IPAddrBlocks |
STACK_OF(POLICY_MAPPING) | POLICY_MAPPINGS |
STACK_OF(POLICYINFO) | CERTIFICATEPOLICIES |
STACK_OF(X509_ALGOR) | X509_ALGORS |
STACK_OF(X509_EXTENSION) | X509_EXTENSIONS |
Even though the OpenSSL headers declare wrapper
functions for many more types and even though the OpenSSL documentation says
that users can declare their own stack types, using
STACK_OF
()
with any type not listed here is strongly discouraged. For other types,
there may be subtle, undocumented differences in syntax and semantics, and
attempting to declare custom stack types is very error prone; using plain C
arrays of pointers to the desired type is much simpler and less
dangerous.
EXAMPLES
The following program creates a certificate object, puts two pointers to it on a stack, and uses X509_free(3) to clean up properly:
#include <err.h> #include <stdio.h> #include <openssl/x509.h> int main(void) { STACK_OF(X509) *stack; X509 *x; if ((stack = sk_X509_new_null()) == NULL) err(1, NULL); if ((x = X509_new()) == NULL) err(1, NULL); if (sk_X509_push(stack, x) == 0) err(1, NULL); if (X509_up_ref(x) == 0) errx(1, "X509_up_ref failed"); if (sk_X509_push(stack, x) == 0) err(1, NULL); printf("%d pointers: %p, %p\n", sk_X509_num(stack), sk_X509_value(stack, 0), sk_X509_value(stack, 1)); sk_X509_pop_free(stack, X509_free); return 0; }
The output looks similar to:
2 pointers: 0x4693ff24c00,
0x4693ff24c00
SEE ALSO
crypto(3), OCSP_request_sign(3), OPENSSL_sk_new(3), PKCS12_parse(3), PKCS7_encrypt(3), SSL_CTX_set_client_CA_list(3), SSL_get_ciphers(3), SSL_get_peer_cert_chain(3), SSL_load_client_CA_file(3), X509_CRL_get_REVOKED(3), X509_STORE_CTX_get0_chain(3)
HISTORY
The STACK_OF
() macro first appeared in
OpenSSL 0.9.3 and has been available since OpenBSD
2.6.