1.\" $OpenBSD: OPENSSL_sk_new.3,v 1.11 2019/06/06 01:06:58 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 6 2019 $ 18.Dt OPENSSL_SK_NEW 3 19.Os 20.Sh NAME 21.Nm sk_new_null , 22.Nm sk_new , 23.Nm sk_set_cmp_func , 24.Nm sk_dup , 25.Nm sk_free , 26.Nm sk_pop_free , 27.Nm sk_num , 28.Nm sk_value , 29.Nm sk_find , 30.Nm sk_find_ex , 31.Nm sk_sort , 32.Nm sk_is_sorted , 33.Nm sk_push , 34.Nm sk_unshift , 35.Nm sk_insert , 36.Nm sk_set , 37.Nm sk_pop , 38.Nm sk_shift , 39.Nm sk_delete , 40.Nm sk_delete_ptr , 41.Nm sk_zero 42.Nd variable-sized arrays of void pointers, called OpenSSL stacks 43.Sh SYNOPSIS 44.In openssl/stack.h 45.Ft _STACK * 46.Fn sk_new_null void 47.Ft _STACK * 48.Fo sk_new 49.Fa "int (*compfunc)(const void *, const void *)" 50.Fc 51.Ft old_function_pointer 52.Fo sk_set_cmp_func 53.Fa "_STACK *stack" 54.Fa "int (*compfunc)(const void *, const void *)" 55.Fc 56.Ft _STACK * 57.Fo sk_dup 58.Fa "_STACK *stack" 59.Fc 60.Ft void 61.Fo sk_free 62.Fa "_STACK *stack" 63.Fc 64.Ft void 65.Fo sk_pop_free 66.Fa "_STACK *stack" 67.Fa "void (*freefunc)(void *)" 68.Fc 69.Ft int 70.Fo sk_num 71.Fa "const _STACK *stack" 72.Fc 73.Ft void * 74.Fo sk_value 75.Fa "const _STACK *stack" 76.Fa "int index" 77.Fc 78.Ft int 79.Fo sk_find 80.Fa "_STACK *stack" 81.Fa "void *wanted" 82.Fc 83.Ft int 84.Fo sk_find_ex 85.Fa "_STACK *stack" 86.Fa "void *wanted" 87.Fc 88.Ft void 89.Fo sk_sort 90.Fa "_STACK *stack" 91.Fc 92.Ft int 93.Fo sk_is_sorted 94.Fa "const _STACK *stack" 95.Fc 96.Ft int 97.Fo sk_push 98.Fa "_STACK *stack" 99.Fa "void *new_item" 100.Fc 101.Ft int 102.Fo sk_unshift 103.Fa "_STACK *stack" 104.Fa "void *new_item" 105.Fc 106.Ft int 107.Fo sk_insert 108.Fa "_STACK *stack" 109.Fa "void *new_item" 110.Fa "int index" 111.Fc 112.Ft void * 113.Fo sk_set 114.Fa "_STACK *stack" 115.Fa "int index" 116.Fa "void *new_item" 117.Fc 118.Ft void * 119.Fo sk_pop 120.Fa "_STACK *stack" 121.Fc 122.Ft void * 123.Fo sk_shift 124.Fa "_STACK *stack" 125.Fc 126.Ft void * 127.Fo sk_delete 128.Fa "_STACK *stack" 129.Fa "int index" 130.Fc 131.Ft void * 132.Fo sk_delete_ptr 133.Fa "_STACK *stack" 134.Fa "void *wanted" 135.Fc 136.Ft void 137.Fo sk_zero 138.Fa "_STACK *stack" 139.Fc 140.Sh DESCRIPTION 141OpenSSL introduced an idiosyncratic concept of variable sized arrays 142of pointers and somewhat misleadingly called such an array a 143.Dq stack . 144Intrinsically, and as documented in this manual page, OpenSSL stacks 145are not type safe but only handle 146.Vt void * 147function arguments and return values. 148.Pp 149OpenSSL also provides a fragile, unusually complicated system of 150macro-generated wrappers that offers superficial type safety at the 151expense of extensive obfuscation, implemented using large amounts 152of autogenerated code involving exceedingly ugly, nested 153.Xr cpp 1 154macros; see the 155.Xr STACK_OF 3 156manual page for details. 157.Pp 158The fundamental data type is the 159.Vt _STACK 160structure. 161It stores a variable number of void pointers 162and remembers the number of pointers currently stored. 163It can optionally hold a pointer to a comparison function. 164As long as no comparison function is installed, the order of pointers 165is meaningful; as soon as a comparison function is installed, it 166becomes ill-defined. 167.Pp 168.Fn sk_new_null 169allocates and initializes a new, empty stack. 170.Fn sk_new 171is identical except that it also installs 172.Fa compfunc 173as the comparison function for the new stack object. 174.Fn sk_set_cmp_func 175installs 176.Fa compfunc 177for the existing 178.Fa stack . 179The 180.Fa compfunc 181is allowed to be 182.Dv NULL , 183but the 184.Fa stack 185is not. 186.Pp 187.Fn sk_dup 188creates a shallow copy of the given 189.Fa stack , 190which must not be a 191.Dv NULL 192pointer. 193It neither copies the objects pointed to from the stack nor 194increases their reference counts, but merely copies the pointers. 195Extreme care must be taken in order to avoid freeing the memory twice, 196for example by calling 197.Fn sk_free 198on one copy and only calling 199.Fn sk_pop_free 200on the other. 201.Pp 202.Fn sk_free 203frees the given 204.Fa stack . 205It does not free any of the pointers stored on the stack. 206Unless these pointers are merely copies of pointers owned by 207other objects, they must be freed before calling 208.Fn sk_free , 209in order to avoid leaking memory. 210If 211.Fa stack 212is a 213.Dv NULL 214pointer, no action occurs. 215.Pp 216.Fn sk_pop_free 217is severely misnamed. 218It does not at all do what one would expect from a function called 219.Dq pop . 220Instead, it does the same as 221.Fn sk_free , 222except that it also calls the function 223.Fa freefunc 224on each of the pointers contained in the 225.Fa stack . 226If the calls to 227.Fa freefunc 228are intended to free the memory in use by the objects on the stack, 229ensure that no other pointers to the same objects remain elsewhere. 230.Pp 231.Fn sk_find 232searches the 233.Fa stack 234for the 235.Fa wanted 236pointer. 237If the 238.Fa stack 239contains more than one copy of the 240.Fa wanted 241pointer, only the first match is found. 242If a comparison function is installed for the stack, the stack is 243first sorted with 244.Fn sk_sort , 245and instead of comparing pointers, two pointers are considered to match 246if the comparison function returns 0. 247.Pp 248.Fn sk_find_ex 249is identical to 250.Fn sk_find 251except that if the 252.Fa stack 253is not empty but no match is found, 254the index of some pointer considered closest to 255.Fa wanted 256is returned. 257.Pp 258.Fn sk_sort 259sorts the 260.Fa stack 261using 262.Xr qsort 3 263and the installed comparison function. 264If 265.Fa stack 266is a 267.Dv NULL 268pointer or already considered sorted, no action occurs. 269This function can only be called if a comparison function is installed. 270.Pp 271.Fn sk_is_sorted 272reports whether the 273.Fa stack 274is considered sorted. 275Calling 276.Fn sk_new_null 277or 278.Fn sk_new , 279successfuly calling 280.Fn sk_push , 281.Fn sk_unshift , 282.Fn sk_insert , 283or 284.Fn sk_set , 285or changing the comparison function sets the state to unsorted. 286If a comparison function is installed, calling 287.Fn sk_sort , 288.Fn sk_find , 289or 290.Fn sk_find_ex 291sets the state to sorted. 292.Pp 293.Fn sk_push 294pushes 295.Fa new_item 296onto the end of the 297.Fa stack , 298increasing the number of pointers by 1. 299If 300.Fa stack 301is a 302.Dv NULL 303pointer, no action occurs. 304.Pp 305.Fn sk_unshift 306inserts 307.Fa new_item 308at the beginning of the 309.Fa stack , 310such that it gets the index 0. 311The number of pointers increases by 1. 312If 313.Fa stack 314is a 315.Dv NULL 316pointer, no action occurs. 317.Pp 318.Fn sk_insert 319inserts the 320.Fa new_item 321into the 322.Fa stack 323such that it gets the given 324.Fa index . 325If 326.Fa index 327is less than 0 or greater than or equal to 328.Fn sk_num stack , 329the effect is the same as for 330.Fn sk_push . 331If 332.Fa stack 333is a 334.Dv NULL 335pointer, no action occurs. 336.Pp 337.Fn sk_set 338replaces the pointer with the given 339.Fa index 340on the 341.Fa stack 342with the 343.Fa new_item . 344The old pointer is not freed, 345which may leak memory if no copy of it exists elsewhere. 346If 347.Fa stack 348is a 349.Dv NULL 350pointer or if 351.Fa index 352is less than 0 or greater than or equal to 353.Fn sk_num stack , 354no action occurs. 355.Pp 356.Fn sk_pop 357and 358.Fn sk_shift 359remove the pointer with the highest or lowest index from the 360.Fa stack , 361respectively, reducing the number of pointers by 1. 362If 363.Fa stack 364is a 365.Dv NULL 366pointer or if it is empty, no action occurs. 367.Pp 368.Fn sk_delete 369removes the pointer with the given 370.Fa index 371from the 372.Fa stack , 373reducing the number of pointers by 1. 374If 375.Fa stack 376is a 377.Dv NULL 378pointer or the 379.Fa index 380is less than 0 or greater than or equal to 381.Fn sk_num stack , 382no action occurs. 383.Pp 384.Fn sk_delete_ptr 385removes the 386.Fa wanted 387pointer from the 388.Fa stack , 389reducing the number of pointers by 1 if it is found. 390It never uses a comparison function 391but only compares pointers themselves. 392The 393.Fa stack 394pointer must not be 395.Dv NULL . 396.Pp 397.Fn sk_zero 398removes all pointers from the 399.Fa stack . 400It does not free any of the pointers. 401Unless these pointers are merely copies of pointers owned by other 402objects, they must be freed before calling 403.Fn sk_zero , 404in order to avoid leaking memory. 405If 406.Fa stack 407is a 408.Dv NULL 409pointer, no action occurs. 410.Sh RETURN VALUES 411.Fn sk_new_null , 412.Fn sk_new , 413and 414.Fn sk_dup 415return a pointer to the newly allocated stack object or 416.Dv NULL 417if insufficient memory is available. 418.Pp 419.Fn sk_set_cmp_func 420returns a pointer to the comparison function 421that was previously installed for the 422.Fa stack 423or 424.Dv NULL 425if none was installed. 426.Pp 427.Fn sk_num 428returns the number of pointers currently stored on the 429.Fa stack , 430or \-1 if 431.Fa stack 432is a 433.Dv NULL 434pointer. 435.Pp 436.Fn sk_value 437returns the pointer with the given 438.Fa index 439from the 440.Fa stack , 441or 442.Dv NULL 443if 444.Fa stack 445is a 446.Dv NULL 447pointer or if the 448.Fa index 449is less than 0 or greater than or equal to 450.Fn sk_num stack . 451.Pp 452.Fn sk_find 453returns the lowest index considered to match or \-1 if 454.Fa stack 455is a 456.Dv NULL 457pointer or if no match is found. 458.Pp 459.Fn sk_find_ex 460returns some index or \-1 if 461.Fa stack 462is a 463.Dv NULL 464pointer or empty. 465.Pp 466.Fn sk_is_sorted 467returns 1 if the 468.Fa stack 469is considered sorted or if it is a 470.Dv NULL 471pointer, or 0 otherwise. 472.Pp 473.Fn sk_push , 474.Fn sk_unshift , 475and 476.Fn sk_insert 477return the new number of pointers on the 478.Fa stack 479or 0 if 480.Fa stack 481is a 482.Dv NULL 483pointer or if memory allocation fails. 484.Pp 485.Fn sk_set 486returns 487.Fa new_item 488or 489.Dv NULL 490if 491.Fa stack 492is a 493.Dv NULL 494pointer or if the 495.Fa index 496is less than 0 or greater than or equal to 497.Fn sk_num stack . 498.Pp 499.Fn sk_pop 500and 501.Fn sk_shift 502return the deleted pointer or 503.Dv NULL 504if 505.Fa stack 506is a 507.Dv NULL 508pointer or if it is empty. 509.Pp 510.Fn sk_delete 511returns the deleted pointer or 512.Dv NULL 513if 514.Fa stack 515is a 516.Dv NULL 517pointer or if the 518.Fa index 519is less than 0 or greater than or equal to 520.Fn sk_num stack . 521.Pp 522.Fn sk_delete_ptr 523returns 524.Fa wanted 525or 526.Dv NULL 527if it is not found. 528.Sh SEE ALSO 529.Xr STACK_OF 3 530.Sh HISTORY 531.Fn sk_new_null , 532.Fn sk_new , 533.Fn sk_free , 534.Fn sk_pop_free , 535.Fn sk_num , 536.Fn sk_value , 537.Fn sk_find , 538.Fn sk_push , 539.Fn sk_unshift , 540.Fn sk_insert , 541.Fn sk_pop , 542.Fn sk_shift , 543.Fn sk_delete , 544and 545.Fn sk_delete_ptr 546first appeared in SSLeay 0.5.1. 547.Fn sk_set_cmp_func , 548.Fn sk_dup , 549and 550.Fn sk_zero 551first appeared in SSLeay 0.8.0. 552These functions have been available since 553.Ox 2.4 . 554.Pp 555.Fn sk_set 556first appeared in OpenSSL 0.9.3. 557.Fn sk_sort 558first appeared in OpenSSL 0.9.4. 559Both functions have been available since 560.Ox 2.6 . 561.Pp 562.Fn sk_is_sorted 563first appeared in OpenSSL 0.9.7e and has been available since 564.Ox 3.8 . 565.Pp 566.Fn sk_find_ex 567first appeared in OpenSSL 0.9.8 and has been available since 568.Ox 4.5 . 569.Sh BUGS 570Even if a comparison function is installed, empty stacks and 571stacks containing a single pointer are sometimes considered 572sorted and sometimes considered unsorted. 573.Pp 574If a comparison function is installed, the concept of 575.Dq first match 576in 577.Fn sk_find 578and 579.Fn sk_find_ex 580is ill-defined because 581.Xr qsort 3 582is not a stable sorting function. 583It is probably best to only assume that they return an arbitrary match. 584.Pp 585The concept of 586.Dq closest 587for 588.Fn sk_find_ex 589is even less clearly defined. 590The match may sometimes be smaller and sometimes larger than 591.Fa wanted , 592even if both smaller and larger pointers exist in the 593.Fa stack . 594Besides, it is again ill-defined 595which of several pointers that compare equal is selected. 596It is probably best to not assume anything about the selection 597for cases where there is no match. 598