1*cc926e92Sschwarze.\" $OpenBSD: STACK_OF.3,v 1.5 2021/10/24 13:10:46 schwarze Exp $ 25d900409Sschwarze.\" 35d900409Sschwarze.\" Copyright (c) 2018 Ingo Schwarze <schwarze@openbsd.org> 45d900409Sschwarze.\" 55d900409Sschwarze.\" Permission to use, copy, modify, and distribute this software for any 65d900409Sschwarze.\" purpose with or without fee is hereby granted, provided that the above 75d900409Sschwarze.\" copyright notice and this permission notice appear in all copies. 85d900409Sschwarze.\" 95d900409Sschwarze.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 105d900409Sschwarze.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 115d900409Sschwarze.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 125d900409Sschwarze.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 135d900409Sschwarze.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 145d900409Sschwarze.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 155d900409Sschwarze.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 165d900409Sschwarze.\" 17*cc926e92Sschwarze.Dd $Mdocdate: October 24 2021 $ 185d900409Sschwarze.Dt STACK_OF 3 195d900409Sschwarze.Os 205d900409Sschwarze.Sh NAME 215d900409Sschwarze.Nm STACK_OF 225d900409Sschwarze.Nd variable-sized arrays of pointers, called OpenSSL stacks 235d900409Sschwarze.Sh SYNOPSIS 245d900409Sschwarze.In openssl/safestack.h 255d900409Sschwarze.Fn STACK_OF type 265d900409Sschwarze.Sh DESCRIPTION 275d900409SschwarzeThe 285d900409Sschwarze.In openssl/safestack.h 295d900409Sschwarzeheader provides a fragile, unusually complicated system of 305d900409Sschwarzemacro-generated wrappers around the functions described in the 315d900409Sschwarze.Xr OPENSSL_sk_new 3 325d900409Sschwarzemanual page. 335d900409SschwarzeIt is intended to implement superficially type-safe variable-sized 345d900409Sschwarzearrays of pointers, somewhat misleadingly called 355d900409Sschwarze.Dq stacks 365d900409Sschwarzeby OpenSSL. 375d900409SschwarzeDue to the excessive number of API functions, it is impossible to 385d900409Sschwarzeproperly document this system. 395d900409SschwarzeIn particular, calling 405d900409Sschwarze.Xr man 1 415d900409Sschwarzefor any of the functions operating on stacks cannot yield any result. 425d900409Sschwarze.Pp 435d900409SschwarzeUnfortunately, application programs can hardly avoid using the concept 445d900409Sschwarzebecause several important OpenSSL APIs rely on it; see the 455d900409Sschwarze.Sx SEE ALSO 465d900409Sschwarzesection for examples. 475d900409SschwarzeEven though both pages are more complicated than any manual page 485d900409Sschwarzeought to be, using the concept safely requires a complete understanding 495d900409Sschwarzeof all the details in both this manual page and in 505d900409Sschwarze.Xr OPENSSL_sk_new 3 . 515d900409Sschwarze.Pp 525d900409SschwarzeThe 535d900409Sschwarze.Fn STACK_OF 545d900409Sschwarzemacro takes a 555d900409Sschwarze.Fa type 565d900409Sschwarzename as its argument, typically the name of a type 575d900409Sschwarzethat has been defined as an alias for a specific 585d900409Sschwarze.Vt struct 595d900409Sschwarzetype using a 605d900409Sschwarze.Sy typedef 615d900409Sschwarzedeclaration. 625d900409SschwarzeIt expands to an incomplete 635d900409Sschwarze.Vt struct 645d900409Sschwarzetype which is intended to represent a 655d900409Sschwarze.Dq stack 665d900409Sschwarzeof objects of the given 675d900409Sschwarze.Fa type . 685d900409SschwarzeThat type does not actually exist, so it is not possible to define, 695d900409Sschwarzefor example, an automatic variable 705d900409Sschwarze.Ql STACK_OF(X509) my_certificates ; 715d900409Sschwarzeit is only possible to define pointers to stacks, for example 725d900409Sschwarze.Ql STACK_OF(X509) *my_certificates . 735d900409SschwarzeThe only way such pointers can ever be used is by wrapper functions 745d900409Sschwarzecasting them to the type 755d900409Sschwarze.Vt _STACK * 765d900409Sschwarzedescribed in 775d900409Sschwarze.Xr OPENSSL_sk_new 3 . 785d900409Sschwarze.Pp 795d900409SschwarzeFor a considerable number of types, OpenSSL provides one wrapper 805d900409Sschwarzefunction for each function described in 815d900409Sschwarze.Xr OPENSSL_sk_new 3 . 825d900409SschwarzeThe names of these wrapper functions are usually constructed by 835d900409Sschwarzeinserting the name of the type and an underscore after the 845d900409Sschwarze.Sq sk_ 855d900409Sschwarzeprefix of the function name. 865d900409SschwarzeUsually, where the real functions take 875d900409Sschwarze.Vt void * 885d900409Sschwarzearguments, the wrappers take pointers to the 895d900409Sschwarze.Fa type 905d900409Sschwarzein questions, and where the real functions take 915d900409Sschwarze.Vt _STACK * 925d900409Sschwarzearguments, the wrappers take pointers to 935d900409Sschwarze.Fn STACK_OF type . 945d900409SschwarzeThe same applies to return values. 955d900409SschwarzeVarious exceptions to all this exist, but the above applies to 965d900409Sschwarzeall the types listed below. 975d900409Sschwarze.Pp 985d900409SschwarzeUsing the above may make sense for the following types because 995d900409Sschwarzepublic API functions exist that take stacks of these types as 1005d900409Sschwarzearguments or return them: 1015d900409Sschwarze.Vt ASN1_INTEGER , 1025d900409Sschwarze.Vt ASN1_OBJECT , 1035d900409Sschwarze.Vt ASN1_UTF8STRING , 104*cc926e92Sschwarze.Vt CMS_RecipientInfo , 105*cc926e92Sschwarze.Vt CMS_SignerInfo , 1065d900409Sschwarze.Vt CONF_VALUE , 107*cc926e92Sschwarze.Vt GENERAL_NAMES , 1085d900409Sschwarze.Vt GENERAL_SUBTREE , 109*cc926e92Sschwarze.Vt OPENSSL_STRING Pq which is just Vt char * , 1105d900409Sschwarze.Vt PKCS12_SAFEBAG , 1115d900409Sschwarze.Vt PKCS7 , 1125d900409Sschwarze.Vt PKCS7_RECIP_INFO , 1135d900409Sschwarze.Vt PKCS7_SIGNER_INFO , 1145d900409Sschwarze.Vt POLICYQUALINFO , 115*cc926e92Sschwarze.Vt SRTP_PROTECTION_PROFILE , 116*cc926e92Sschwarze.Vt SSL_CIPHER , 117*cc926e92Sschwarze.Vt SSL_COMP , 1185d900409Sschwarze.Vt X509 , 1195d900409Sschwarze.Vt X509_ALGOR , 1205d900409Sschwarze.Vt X509_ATTRIBUTE , 1215d900409Sschwarze.Vt X509_CRL , 1225d900409Sschwarze.Vt X509_EXTENSION , 1235d900409Sschwarze.Vt X509_INFO , 124*cc926e92Sschwarze.Vt X509_NAME , 1255d900409Sschwarze.Vt X509_OBJECT , 1265d900409Sschwarze.Vt X509_POLICY_NODE , 1275d900409Sschwarze.Vt X509_REVOKED . 1285d900409Sschwarze.Pp 129*cc926e92SschwarzeAdditionally, some public API functions use the following types 130*cc926e92Sschwarzewhich are declared with 131*cc926e92Sschwarze.Sy typedef : 132*cc926e92Sschwarze.Bl -column STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS 133*cc926e92Sschwarze.It Vt STACK_OF(ACCESS_DESCRIPTION) Ta Vt AUTHORITY_INFO_ACCESS 134*cc926e92Sschwarze.It Vt STACK_OF(ASN1_OBJECT) Ta Vt EXTENDED_KEY_USAGE 135*cc926e92Sschwarze.It Vt STACK_OF(ASN1_TYPE) Ta Vt ASN1_SEQUENCE_ANY 136*cc926e92Sschwarze.It Vt STACK_OF(DIST_POINT) Ta Vt CRL_DIST_POINTS 137*cc926e92Sschwarze.It Vt STACK_OF(GENERAL_NAME) Ta Vt GENERAL_NAMES 138*cc926e92Sschwarze.It Vt STACK_OF(IPAddressFamily) Ta Vt IPAddrBlocks 139*cc926e92Sschwarze.It Vt STACK_OF(POLICY_MAPPING) Ta Vt POLICY_MAPPINGS 140*cc926e92Sschwarze.It Vt STACK_OF(POLICYINFO) Ta Vt CERTIFICATEPOLICIES 141*cc926e92Sschwarze.It Vt STACK_OF(X509_ALGOR) Ta Vt X509_ALGORS 142*cc926e92Sschwarze.It Vt STACK_OF(X509_EXTENSION) Ta Vt X509_EXTENSIONS 143*cc926e92Sschwarze.El 144*cc926e92Sschwarze.Pp 1455d900409SschwarzeEven though the OpenSSL headers declare wrapper functions for many 1465d900409Sschwarzemore types and even though the OpenSSL documentation says that users 1475d900409Sschwarzecan declare their own stack types, using 1485d900409Sschwarze.Fn STACK_OF 1495d900409Sschwarzewith any type not listed here is strongly discouraged. 1505d900409SschwarzeFor other types, there may be subtle, undocumented differences 1515d900409Sschwarzein syntax and semantics, and attempting to declare custom stack 1525d900409Sschwarzetypes is very error prone; using plain C arrays of pointers to 1535d900409Sschwarzethe desired type is much simpler and less dangerous. 1545d900409Sschwarze.Sh EXAMPLES 1555d900409SschwarzeThe following program creates a certificate object, puts two 1565d900409Sschwarzepointers to it on a stack, and uses 1575d900409Sschwarze.Xr X509_free 3 1585d900409Sschwarzeto clean up properly: 1595d900409Sschwarze.Bd -literal 1605d900409Sschwarze#include <err.h> 1615d900409Sschwarze#include <stdio.h> 1625d900409Sschwarze#include <openssl/x509.h> 1635d900409Sschwarze 1645d900409Sschwarzeint 1655d900409Sschwarzemain(void) 1665d900409Sschwarze{ 1675d900409Sschwarze STACK_OF(X509) *stack; 1685d900409Sschwarze X509 *x; 1695d900409Sschwarze 1705d900409Sschwarze if ((stack = sk_X509_new_null()) == NULL) 1715d900409Sschwarze err(1, NULL); 1725d900409Sschwarze if ((x = X509_new()) == NULL) 1735d900409Sschwarze err(1, NULL); 1745d900409Sschwarze if (sk_X509_push(stack, x) == 0) 1755d900409Sschwarze err(1, NULL); 1765d900409Sschwarze if (X509_up_ref(x) == 0) 1775d900409Sschwarze errx(1, "X509_up_ref failed"); 1785d900409Sschwarze if (sk_X509_push(stack, x) == 0) 1795d900409Sschwarze err(1, NULL); 1805d900409Sschwarze printf("%d pointers: %p, %p\en", sk_X509_num(stack), 1815d900409Sschwarze sk_X509_value(stack, 0), sk_X509_value(stack, 1)); 1825d900409Sschwarze sk_X509_pop_free(stack, X509_free); 1835d900409Sschwarze 1845d900409Sschwarze return 0; 1855d900409Sschwarze} 1865d900409Sschwarze.Ed 1875d900409Sschwarze.Pp 1885d900409SschwarzeThe output looks similar to: 1895d900409Sschwarze.Pp 1905d900409Sschwarze.Dl 2 pointers: 0x4693ff24c00, 0x4693ff24c00 1915d900409Sschwarze.Sh SEE ALSO 19200d4e240Sschwarze.Xr crypto 3 , 1935d900409Sschwarze.Xr OCSP_request_sign 3 , 194c4c55c71Sschwarze.Xr OPENSSL_sk_new 3 , 1955d900409Sschwarze.Xr PKCS12_parse 3 , 1965d900409Sschwarze.Xr PKCS7_encrypt 3 , 1975d900409Sschwarze.Xr SSL_CTX_set_client_CA_list 3 , 1985d900409Sschwarze.Xr SSL_get_ciphers 3 , 1995d900409Sschwarze.Xr SSL_get_peer_cert_chain 3 , 2005d900409Sschwarze.Xr SSL_load_client_CA_file 3 , 2015d900409Sschwarze.Xr X509_CRL_get_REVOKED 3 , 2025d900409Sschwarze.Xr X509_STORE_CTX_get0_chain 3 203c52b7c01Sschwarze.Sh HISTORY 204c52b7c01SschwarzeThe 205c52b7c01Sschwarze.Fn STACK_OF 206c52b7c01Sschwarzemacro first appeared in OpenSSL 0.9.3 and has been available since 207c52b7c01Sschwarze.Ox 2.6 . 208