1.\" $OpenBSD: STACK_OF.3,v 1.4 2019/06/10 09:49:48 schwarze Exp $ 2.\" 3.\" Copyright (c) 2018 Ingo Schwarze <schwarze@openbsd.org> 4.\" 5.\" Permission to use, copy, modify, and distribute this software for any 6.\" purpose with or without fee is hereby granted, provided that the above 7.\" copyright notice and this permission notice appear in all copies. 8.\" 9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16.\" 17.Dd $Mdocdate: June 10 2019 $ 18.Dt STACK_OF 3 19.Os 20.Sh NAME 21.Nm STACK_OF 22.Nd variable-sized arrays of pointers, called OpenSSL stacks 23.Sh SYNOPSIS 24.In openssl/safestack.h 25.Fn STACK_OF type 26.Sh DESCRIPTION 27The 28.In openssl/safestack.h 29header provides a fragile, unusually complicated system of 30macro-generated wrappers around the functions described in the 31.Xr OPENSSL_sk_new 3 32manual page. 33It is intended to implement superficially type-safe variable-sized 34arrays of pointers, somewhat misleadingly called 35.Dq stacks 36by OpenSSL. 37Due to the excessive number of API functions, it is impossible to 38properly document this system. 39In particular, calling 40.Xr man 1 41for any of the functions operating on stacks cannot yield any result. 42.Pp 43Unfortunately, application programs can hardly avoid using the concept 44because several important OpenSSL APIs rely on it; see the 45.Sx SEE ALSO 46section for examples. 47Even though both pages are more complicated than any manual page 48ought to be, using the concept safely requires a complete understanding 49of all the details in both this manual page and in 50.Xr OPENSSL_sk_new 3 . 51.Pp 52The 53.Fn STACK_OF 54macro takes a 55.Fa type 56name as its argument, typically the name of a type 57that has been defined as an alias for a specific 58.Vt struct 59type using a 60.Sy typedef 61declaration. 62It expands to an incomplete 63.Vt struct 64type which is intended to represent a 65.Dq stack 66of objects of the given 67.Fa type . 68That type does not actually exist, so it is not possible to define, 69for example, an automatic variable 70.Ql STACK_OF(X509) my_certificates ; 71it is only possible to define pointers to stacks, for example 72.Ql STACK_OF(X509) *my_certificates . 73The only way such pointers can ever be used is by wrapper functions 74casting them to the type 75.Vt _STACK * 76described in 77.Xr OPENSSL_sk_new 3 . 78.Pp 79For a considerable number of types, OpenSSL provides one wrapper 80function for each function described in 81.Xr OPENSSL_sk_new 3 . 82The names of these wrapper functions are usually constructed by 83inserting the name of the type and an underscore after the 84.Sq sk_ 85prefix of the function name. 86Usually, where the real functions take 87.Vt void * 88arguments, the wrappers take pointers to the 89.Fa type 90in questions, and where the real functions take 91.Vt _STACK * 92arguments, the wrappers take pointers to 93.Fn STACK_OF type . 94The same applies to return values. 95Various exceptions to all this exist, but the above applies to 96all the types listed below. 97.Pp 98Using the above may make sense for the following types because 99public API functions exist that take stacks of these types as 100arguments or return them: 101.Vt ACCESS_DESCRIPTION , 102.Vt ASN1_INTEGER , 103.Vt ASN1_OBJECT , 104.Vt ASN1_TYPE , 105.Vt ASN1_UTF8STRING , 106.Vt CONF_VALUE , 107.Vt DIST_POINT , 108.Vt GENERAL_NAME , 109.Vt GENERAL_SUBTREE , 110.Vt PKCS12_SAFEBAG , 111.Vt PKCS7 , 112.Vt PKCS7_RECIP_INFO , 113.Vt PKCS7_SIGNER_INFO , 114.Vt POLICY_MAPPING , 115.Vt POLICYINFO , 116.Vt POLICYQUALINFO , 117.Vt X509 , 118.Vt X509_ALGOR , 119.Vt X509_ATTRIBUTE , 120.Vt X509_CRL , 121.Vt X509_EXTENSION , 122.Vt X509_INFO , 123.Vt X509_OBJECT , 124.Vt X509_POLICY_NODE , 125.Vt X509_PURPOSE , 126.Vt X509_REVOKED . 127.Pp 128Even though the OpenSSL headers declare wrapper functions for many 129more types and even though the OpenSSL documentation says that users 130can declare their own stack types, using 131.Fn STACK_OF 132with any type not listed here is strongly discouraged. 133For other types, there may be subtle, undocumented differences 134in syntax and semantics, and attempting to declare custom stack 135types is very error prone; using plain C arrays of pointers to 136the desired type is much simpler and less dangerous. 137.Sh EXAMPLES 138The following program creates a certificate object, puts two 139pointers to it on a stack, and uses 140.Xr X509_free 3 141to clean up properly: 142.Bd -literal 143#include <err.h> 144#include <stdio.h> 145#include <openssl/x509.h> 146 147int 148main(void) 149{ 150 STACK_OF(X509) *stack; 151 X509 *x; 152 153 if ((stack = sk_X509_new_null()) == NULL) 154 err(1, NULL); 155 if ((x = X509_new()) == NULL) 156 err(1, NULL); 157 if (sk_X509_push(stack, x) == 0) 158 err(1, NULL); 159 if (X509_up_ref(x) == 0) 160 errx(1, "X509_up_ref failed"); 161 if (sk_X509_push(stack, x) == 0) 162 err(1, NULL); 163 printf("%d pointers: %p, %p\en", sk_X509_num(stack), 164 sk_X509_value(stack, 0), sk_X509_value(stack, 1)); 165 sk_X509_pop_free(stack, X509_free); 166 167 return 0; 168} 169.Ed 170.Pp 171The output looks similar to: 172.Pp 173.Dl 2 pointers: 0x4693ff24c00, 0x4693ff24c00 174.Sh SEE ALSO 175.Xr crypto 3 , 176.Xr OCSP_request_sign 3 , 177.Xr OPENSSL_sk_new 3 , 178.Xr PKCS12_parse 3 , 179.Xr PKCS7_encrypt 3 , 180.Xr SSL_CTX_set_client_CA_list 3 , 181.Xr SSL_get_ciphers 3 , 182.Xr SSL_get_peer_cert_chain 3 , 183.Xr SSL_load_client_CA_file 3 , 184.Xr X509_CRL_get_REVOKED 3 , 185.Xr X509_STORE_CTX_get0_chain 3 186.Sh HISTORY 187The 188.Fn STACK_OF 189macro first appeared in OpenSSL 0.9.3 and has been available since 190.Ox 2.6 . 191