1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay@cryptsoft.com). 6 * The implementation was written so as to conform with Netscapes SSL. 7 * 8 * This library is free for commercial and non-commercial use as long as 9 * the following conditions are aheared to. The following conditions 10 * apply to all code found in this distribution, be it the RC4, RSA, 11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * included with this distribution is covered by the same copyright terms 13 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 14 * 15 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * the code are not to be removed. 17 * If this package is used in a product, Eric Young should be given attribution 18 * as the author of the parts of the library used. 19 * This can be in the form of a textual message at program startup or 20 * in documentation (online or textual) provided with the package. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 1. Redistributions of source code must retain the copyright 26 * notice, this list of conditions and the following disclaimer. 27 * 2. Redistributions in binary form must reproduce the above copyright 28 * notice, this list of conditions and the following disclaimer in the 29 * documentation and/or other materials provided with the distribution. 30 * 3. All advertising materials mentioning features or use of this software 31 * must display the following acknowledgement: 32 * "This product includes cryptographic software written by 33 * Eric Young (eay@cryptsoft.com)" 34 * The word 'cryptographic' can be left out if the rouines from the library 35 * being used are not cryptographic related :-). 36 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * the apps directory (application code) you must include an acknowledgement: 38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * SUCH DAMAGE. 51 * 52 * The licence and distribution terms for any publically available version or 53 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * copied and put under another distribution licence 55 * [including the GNU Public Licence.] */ 56 57 #ifndef OPENSSL_HEADER_STACK_H 58 #define OPENSSL_HEADER_STACK_H 59 60 #include <openssl/base.h> 61 62 #if defined(__cplusplus) 63 extern "C" { 64 #endif 65 66 67 // A stack, in OpenSSL, is an array of pointers. They are the most commonly 68 // used collection object. 69 // 70 // This file defines macros for type-safe use of the stack functions. A stack 71 // type is named like |STACK_OF(FOO)| and is accessed with functions named 72 // like |sk_FOO_*|. Note the stack will typically contain /pointers/ to |FOO|. 73 // 74 // The |DECLARE_STACK_OF| macro makes |STACK_OF(FOO)| available, and 75 // |DEFINE_STACK_OF| makes the corresponding functions available. 76 77 78 // Defining stacks. 79 80 // STACK_OF expands to the stack type for |type|. 81 #define STACK_OF(type) struct stack_st_##type 82 83 // DECLARE_STACK_OF declares the |STACK_OF(type)| type. It does not make the 84 // corresponding |sk_type_*| functions available. This macro should be used in 85 // files which only need the type. 86 #define DECLARE_STACK_OF(type) STACK_OF(type); 87 88 // DEFINE_NAMED_STACK_OF defines |STACK_OF(name)| to be a stack whose elements 89 // are |type| *. This macro makes the |sk_name_*| functions available. 90 // 91 // It is not necessary to use |DECLARE_STACK_OF| in files which use this macro. 92 #define DEFINE_NAMED_STACK_OF(name, type) \ 93 BORINGSSL_DEFINE_STACK_OF_IMPL(name, type *, const type *) \ 94 BORINGSSL_DEFINE_STACK_TRAITS(name, type, false) 95 96 // DEFINE_STACK_OF defines |STACK_OF(type)| to be a stack whose elements are 97 // |type| *. This macro makes the |sk_type_*| functions available. 98 // 99 // It is not necessary to use |DECLARE_STACK_OF| in files which use this macro. 100 #define DEFINE_STACK_OF(type) DEFINE_NAMED_STACK_OF(type, type) 101 102 // DEFINE_CONST_STACK_OF defines |STACK_OF(type)| to be a stack whose elements 103 // are const |type| *. This macro makes the |sk_type_*| functions available. 104 // 105 // It is not necessary to use |DECLARE_STACK_OF| in files which use this macro. 106 #define DEFINE_CONST_STACK_OF(type) \ 107 BORINGSSL_DEFINE_STACK_OF_IMPL(type, const type *, const type *) \ 108 BORINGSSL_DEFINE_STACK_TRAITS(type, const type, true) 109 110 111 // Using stacks. 112 // 113 // After the |DEFINE_STACK_OF| macro is used, the following functions are 114 // available. 115 116 #if 0 // Sample 117 118 // sk_SAMPLE_free_func is a callback to free an element in a stack. 119 typedef void (*sk_SAMPLE_free_func)(SAMPLE *); 120 121 // sk_SAMPLE_copy_func is a callback to copy an element in a stack. It should 122 // return the copy or NULL on error. 123 typedef SAMPLE *(*sk_SAMPLE_copy_func)(const SAMPLE *); 124 125 // sk_SAMPLE_cmp_func is a callback to compare |*a| to |*b|. It should return a 126 // value < 0, 0, or > 0 if |*a| is less than, equal to, or greater than |*b|, 127 // respectively. Note the extra indirection - the function is given a pointer 128 // to a pointer to the element. This is the |qsort|/|bsearch| comparison 129 // function applied to an array of |SAMPLE*|. 130 typedef int (*sk_SAMPLE_cmp_func)(const SAMPLE *const *a, 131 const SAMPLE *const *b); 132 133 // sk_SAMPLE_new creates a new, empty stack with the given comparison function, 134 // which may be NULL. It returns the new stack or NULL on allocation failure. 135 STACK_OF(SAMPLE) *sk_SAMPLE_new(sk_SAMPLE_cmp_func comp); 136 137 // sk_SAMPLE_new_null creates a new, empty stack. It returns the new stack or 138 // NULL on allocation failure. 139 STACK_OF(SAMPLE) *sk_SAMPLE_new_null(void); 140 141 // sk_SAMPLE_num returns the number of elements in |sk|. It is safe to cast this 142 // value to |int|. |sk| is guaranteed to have at most |INT_MAX| elements. 143 size_t sk_SAMPLE_num(const STACK_OF(SAMPLE) *sk); 144 145 // sk_SAMPLE_zero resets |sk| to the empty state but does nothing to free the 146 // individual elements themselves. 147 void sk_SAMPLE_zero(STACK_OF(SAMPLE) *sk); 148 149 // sk_SAMPLE_value returns the |i|th pointer in |sk|, or NULL if |i| is out of 150 // range. 151 SAMPLE *sk_SAMPLE_value(const STACK_OF(SAMPLE) *sk, size_t i); 152 153 // sk_SAMPLE_set sets the |i|th pointer in |sk| to |p| and returns |p|. If |i| 154 // is out of range, it returns NULL. 155 SAMPLE *sk_SAMPLE_set(STACK_OF(SAMPLE) *sk, size_t i, SAMPLE *p); 156 157 // sk_SAMPLE_free frees |sk|, but does nothing to free the individual elements. 158 // Use |sk_SAMPLE_pop_free| to also free the elements. 159 void sk_SAMPLE_free(STACK_OF(SAMPLE) *sk); 160 161 // sk_SAMPLE_pop_free calls |free_func| on each element in |sk| and then 162 // frees the stack itself. 163 void sk_SAMPLE_pop_free(STACK_OF(SAMPLE) *sk, sk_SAMPLE_free_func free_func); 164 165 // sk_SAMPLE_insert inserts |p| into the stack at index |where|, moving existing 166 // elements if needed. It returns the length of the new stack, or zero on 167 // error. 168 size_t sk_SAMPLE_insert(STACK_OF(SAMPLE) *sk, SAMPLE *p, size_t where); 169 170 // sk_SAMPLE_delete removes the pointer at index |where|, moving other elements 171 // down if needed. It returns the removed pointer, or NULL if |where| is out of 172 // range. 173 SAMPLE *sk_SAMPLE_delete(STACK_OF(SAMPLE) *sk, size_t where); 174 175 // sk_SAMPLE_delete_ptr removes, at most, one instance of |p| from |sk| based on 176 // pointer equality. If an instance of |p| is found then |p| is returned, 177 // otherwise it returns NULL. 178 SAMPLE *sk_SAMPLE_delete_ptr(STACK_OF(SAMPLE) *sk, const SAMPLE *p); 179 180 // sk_SAMPLE_delete_if_func is the callback function for |sk_SAMPLE_delete_if|. 181 // It should return one to remove |p| and zero to keep it. 182 typedef int (*sk_SAMPLE_delete_if_func)(SAMPLE *p, void *data); 183 184 // sk_SAMPLE_delete_if calls |func| with each element of |sk| and removes the 185 // entries where |func| returned one. This function does not free or return 186 // removed pointers so, if |sk| owns its contents, |func| should release the 187 // pointers prior to returning one. 188 void sk_SAMPLE_delete_if(STACK_OF(SAMPLE) *sk, sk_SAMPLE_delete_if_func func, 189 void *data); 190 191 // sk_SAMPLE_find find the first value in |sk| equal to |p|. |sk|'s comparison 192 // function determines equality, or pointer equality if |sk| has no comparison 193 // function. 194 // 195 // If the stack is sorted (see |sk_SAMPLE_sort|), this function uses a binary 196 // search. Otherwise it performs a linear search. If it finds a matching 197 // element, it writes the index to |*out_index| (if |out_index| is not NULL) and 198 // returns one. Otherwise, it returns zero. 199 // 200 // Note this differs from OpenSSL. The type signature is slightly different, and 201 // OpenSSL's version will implicitly sort |sk| if it has a comparison function 202 // defined. 203 int sk_SAMPLE_find(const STACK_OF(SAMPLE) *sk, size_t *out_index, 204 const SAMPLE *p); 205 206 // sk_SAMPLE_shift removes and returns the first element in |sk|, or NULL if 207 // |sk| is empty. 208 SAMPLE *sk_SAMPLE_shift(STACK_OF(SAMPLE) *sk); 209 210 // sk_SAMPLE_push appends |p| to |sk| and returns the length of the new stack, 211 // or 0 on allocation failure. 212 size_t sk_SAMPLE_push(STACK_OF(SAMPLE) *sk, SAMPLE *p); 213 214 // sk_SAMPLE_pop removes and returns the last element of |sk|, or NULL if |sk| 215 // is empty. 216 SAMPLE *sk_SAMPLE_pop(STACK_OF(SAMPLE) *sk); 217 218 // sk_SAMPLE_dup performs a shallow copy of a stack and returns the new stack, 219 // or NULL on error. Use |sk_SAMPLE_deep_copy| to also copy the elements. 220 STACK_OF(SAMPLE) *sk_SAMPLE_dup(const STACK_OF(SAMPLE) *sk); 221 222 // sk_SAMPLE_sort sorts the elements of |sk| into ascending order based on the 223 // comparison function. The stack maintains a "sorted" flag and sorting an 224 // already sorted stack is a no-op. 225 void sk_SAMPLE_sort(STACK_OF(SAMPLE) *sk); 226 227 // sk_SAMPLE_is_sorted returns one if |sk| is known to be sorted and zero 228 // otherwise. 229 int sk_SAMPLE_is_sorted(const STACK_OF(SAMPLE) *sk); 230 231 // sk_SAMPLE_set_cmp_func sets the comparison function to be used by |sk| and 232 // returns the previous one. 233 sk_SAMPLE_cmp_func sk_SAMPLE_set_cmp_func(STACK_OF(SAMPLE) *sk, 234 sk_SAMPLE_cmp_func comp); 235 236 // sk_SAMPLE_deep_copy performs a copy of |sk| and of each of the non-NULL 237 // elements in |sk| by using |copy_func|. If an error occurs, it calls 238 // |free_func| to free any copies already made and returns NULL. 239 STACK_OF(SAMPLE) *sk_SAMPLE_deep_copy(const STACK_OF(SAMPLE) *sk, 240 sk_SAMPLE_copy_func copy_func, 241 sk_SAMPLE_free_func free_func); 242 243 #endif // Sample 244 245 246 // Private functions. 247 // 248 // The |sk_*| functions generated above are implemented internally using the 249 // type-erased functions below. Callers should use the typed wrappers instead. 250 // When using the type-erased functions, callers are responsible for ensuring 251 // the underlying types are correct. Casting pointers to the wrong types will 252 // result in memory errors. 253 254 // OPENSSL_sk_free_func is a function that frees an element in a stack. Note its 255 // actual type is void (*)(T *) for some T. Low-level |sk_*| functions will be 256 // passed a type-specific wrapper to call it correctly. 257 typedef void (*OPENSSL_sk_free_func)(void *ptr); 258 259 // OPENSSL_sk_copy_func is a function that copies an element in a stack. Note 260 // its actual type is T *(*)(const T *) for some T. Low-level |sk_*| functions 261 // will be passed a type-specific wrapper to call it correctly. 262 typedef void *(*OPENSSL_sk_copy_func)(const void *ptr); 263 264 // OPENSSL_sk_cmp_func is a comparison function that returns a value < 0, 0 or > 265 // 0 if |*a| is less than, equal to or greater than |*b|, respectively. Note 266 // the extra indirection - the function is given a pointer to a pointer to the 267 // element. This differs from the usual qsort/bsearch comparison function. 268 // 269 // Note its actual type is |int (*)(const T *const *a, const T *const *b)|. 270 // Low-level |sk_*| functions will be passed a type-specific wrapper to call it 271 // correctly. 272 typedef int (*OPENSSL_sk_cmp_func)(const void *const *a, const void *const *b); 273 274 // OPENSSL_sk_delete_if_func is the generic version of 275 // |sk_SAMPLE_delete_if_func|. 276 typedef int (*OPENSSL_sk_delete_if_func)(void *obj, void *data); 277 278 // The following function types call the above type-erased signatures with the 279 // true types. 280 typedef void (*OPENSSL_sk_call_free_func)(OPENSSL_sk_free_func, void *); 281 typedef void *(*OPENSSL_sk_call_copy_func)(OPENSSL_sk_copy_func, const void *); 282 typedef int (*OPENSSL_sk_call_cmp_func)(OPENSSL_sk_cmp_func, const void *, 283 const void *); 284 typedef int (*OPENSSL_sk_call_delete_if_func)(OPENSSL_sk_delete_if_func, void *, 285 void *); 286 287 // An OPENSSL_STACK contains an array of pointers. It is not designed to be used 288 // directly, rather the wrapper macros should be used. 289 typedef struct stack_st OPENSSL_STACK; 290 291 // The following are raw stack functions. They implement the corresponding typed 292 // |sk_SAMPLE_*| functions generated by |DEFINE_STACK_OF|. Callers shouldn't be 293 // using them. Rather, callers should use the typed functions. 294 OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_cmp_func comp); 295 OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_new_null(void); 296 OPENSSL_EXPORT size_t OPENSSL_sk_num(const OPENSSL_STACK *sk); 297 OPENSSL_EXPORT void OPENSSL_sk_zero(OPENSSL_STACK *sk); 298 OPENSSL_EXPORT void *OPENSSL_sk_value(const OPENSSL_STACK *sk, size_t i); 299 OPENSSL_EXPORT void *OPENSSL_sk_set(OPENSSL_STACK *sk, size_t i, void *p); 300 OPENSSL_EXPORT void OPENSSL_sk_free(OPENSSL_STACK *sk); 301 OPENSSL_EXPORT void OPENSSL_sk_pop_free_ex( 302 OPENSSL_STACK *sk, OPENSSL_sk_call_free_func call_free_func, 303 OPENSSL_sk_free_func free_func); 304 OPENSSL_EXPORT size_t OPENSSL_sk_insert(OPENSSL_STACK *sk, void *p, 305 size_t where); 306 OPENSSL_EXPORT void *OPENSSL_sk_delete(OPENSSL_STACK *sk, size_t where); 307 OPENSSL_EXPORT void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *sk, const void *p); 308 OPENSSL_EXPORT void OPENSSL_sk_delete_if( 309 OPENSSL_STACK *sk, OPENSSL_sk_call_delete_if_func call_func, 310 OPENSSL_sk_delete_if_func func, void *data); 311 OPENSSL_EXPORT int OPENSSL_sk_find(const OPENSSL_STACK *sk, size_t *out_index, 312 const void *p, 313 OPENSSL_sk_call_cmp_func call_cmp_func); 314 OPENSSL_EXPORT void *OPENSSL_sk_shift(OPENSSL_STACK *sk); 315 OPENSSL_EXPORT size_t OPENSSL_sk_push(OPENSSL_STACK *sk, void *p); 316 OPENSSL_EXPORT void *OPENSSL_sk_pop(OPENSSL_STACK *sk); 317 OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *sk); 318 OPENSSL_EXPORT void OPENSSL_sk_sort(OPENSSL_STACK *sk, 319 OPENSSL_sk_call_cmp_func call_cmp_func); 320 OPENSSL_EXPORT int OPENSSL_sk_is_sorted(const OPENSSL_STACK *sk); 321 OPENSSL_EXPORT OPENSSL_sk_cmp_func 322 OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, OPENSSL_sk_cmp_func comp); 323 OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_deep_copy( 324 const OPENSSL_STACK *sk, OPENSSL_sk_call_copy_func call_copy_func, 325 OPENSSL_sk_copy_func copy_func, OPENSSL_sk_call_free_func call_free_func, 326 OPENSSL_sk_free_func free_func); 327 328 329 // Deprecated private functions (hidden). 330 // 331 // TODO(crbug.com/boringssl/499): Migrate callers to the typed wrappers, or at 332 // least the new names and remove the old ones. 333 // 334 // TODO(b/290792019, b/290785937): Ideally these would at least be inline 335 // functions, so we do not squat the symbols. 336 337 typedef OPENSSL_STACK _STACK; 338 339 // The following functions call the corresponding |OPENSSL_sk_*| function. 340 OPENSSL_EXPORT OPENSSL_DEPRECATED OPENSSL_STACK *sk_new_null(void); 341 OPENSSL_EXPORT OPENSSL_DEPRECATED size_t sk_num(const OPENSSL_STACK *sk); 342 OPENSSL_EXPORT OPENSSL_DEPRECATED void *sk_value(const OPENSSL_STACK *sk, 343 size_t i); 344 OPENSSL_EXPORT OPENSSL_DEPRECATED void sk_free(OPENSSL_STACK *sk); 345 OPENSSL_EXPORT OPENSSL_DEPRECATED size_t sk_push(OPENSSL_STACK *sk, void *p); 346 OPENSSL_EXPORT OPENSSL_DEPRECATED void *sk_pop(OPENSSL_STACK *sk); 347 348 // sk_pop_free_ex calls |OPENSSL_sk_pop_free_ex|. 349 // 350 // TODO(b/291994116): Remove this. 351 OPENSSL_EXPORT OPENSSL_DEPRECATED void sk_pop_free_ex( 352 OPENSSL_STACK *sk, OPENSSL_sk_call_free_func call_free_func, 353 OPENSSL_sk_free_func free_func); 354 355 // sk_pop_free behaves like |OPENSSL_sk_pop_free_ex| but performs an invalid 356 // function pointer cast. It exists because some existing callers called 357 // |sk_pop_free| directly. 358 // 359 // TODO(davidben): Migrate callers to bssl::UniquePtr and remove this. 360 OPENSSL_EXPORT OPENSSL_DEPRECATED void sk_pop_free( 361 OPENSSL_STACK *sk, OPENSSL_sk_free_func free_func); 362 363 364 #if !defined(BORINGSSL_NO_CXX) 365 extern "C++" { 366 BSSL_NAMESPACE_BEGIN 367 namespace internal { 368 template <typename T> 369 struct StackTraits {}; 370 } 371 BSSL_NAMESPACE_END 372 } 373 374 #define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const) \ 375 extern "C++" { \ 376 BSSL_NAMESPACE_BEGIN \ 377 namespace internal { \ 378 template <> \ 379 struct StackTraits<STACK_OF(name)> { \ 380 static constexpr bool kIsStack = true; \ 381 using Type = type; \ 382 static constexpr bool kIsConst = is_const; \ 383 }; \ 384 } \ 385 BSSL_NAMESPACE_END \ 386 } 387 388 #else 389 #define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const) 390 #endif 391 392 #define BORINGSSL_DEFINE_STACK_OF_IMPL(name, ptrtype, constptrtype) \ 393 /* We disable MSVC C4191 in this macro, which warns when pointers are cast \ 394 * to the wrong type. While the cast itself is valid, it is often a bug \ 395 * because calling it through the cast is UB. However, we never actually \ 396 * call functions as |OPENSSL_sk_cmp_func|. The type is just a type-erased \ 397 * function pointer. (C does not guarantee function pointers fit in \ 398 * |void*|, and GCC will warn on this.) Thus we just disable the false \ 399 * positive warning. */ \ 400 OPENSSL_MSVC_PRAGMA(warning(push)) \ 401 OPENSSL_MSVC_PRAGMA(warning(disable : 4191)) \ 402 \ 403 DECLARE_STACK_OF(name) \ 404 \ 405 typedef void (*sk_##name##_free_func)(ptrtype); \ 406 typedef ptrtype (*sk_##name##_copy_func)(constptrtype); \ 407 typedef int (*sk_##name##_cmp_func)(constptrtype const *, \ 408 constptrtype const *); \ 409 typedef int (*sk_##name##_delete_if_func)(ptrtype, void *); \ 410 \ 411 OPENSSL_INLINE void sk_##name##_call_free_func( \ 412 OPENSSL_sk_free_func free_func, void *ptr) { \ 413 ((sk_##name##_free_func)free_func)((ptrtype)ptr); \ 414 } \ 415 \ 416 OPENSSL_INLINE void *sk_##name##_call_copy_func( \ 417 OPENSSL_sk_copy_func copy_func, const void *ptr) { \ 418 return (void *)((sk_##name##_copy_func)copy_func)((constptrtype)ptr); \ 419 } \ 420 \ 421 OPENSSL_INLINE int sk_##name##_call_cmp_func(OPENSSL_sk_cmp_func cmp_func, \ 422 const void *a, const void *b) { \ 423 constptrtype a_ptr = (constptrtype)a; \ 424 constptrtype b_ptr = (constptrtype)b; \ 425 /* |cmp_func| expects an extra layer of pointers to match qsort. */ \ 426 return ((sk_##name##_cmp_func)cmp_func)(&a_ptr, &b_ptr); \ 427 } \ 428 \ 429 OPENSSL_INLINE int sk_##name##_call_delete_if_func( \ 430 OPENSSL_sk_delete_if_func func, void *obj, void *data) { \ 431 return ((sk_##name##_delete_if_func)func)((ptrtype)obj, data); \ 432 } \ 433 \ 434 OPENSSL_INLINE STACK_OF(name) *sk_##name##_new(sk_##name##_cmp_func comp) { \ 435 return (STACK_OF(name) *)OPENSSL_sk_new((OPENSSL_sk_cmp_func)comp); \ 436 } \ 437 \ 438 OPENSSL_INLINE STACK_OF(name) *sk_##name##_new_null(void) { \ 439 return (STACK_OF(name) *)OPENSSL_sk_new_null(); \ 440 } \ 441 \ 442 OPENSSL_INLINE size_t sk_##name##_num(const STACK_OF(name) *sk) { \ 443 return OPENSSL_sk_num((const OPENSSL_STACK *)sk); \ 444 } \ 445 \ 446 OPENSSL_INLINE void sk_##name##_zero(STACK_OF(name) *sk) { \ 447 OPENSSL_sk_zero((OPENSSL_STACK *)sk); \ 448 } \ 449 \ 450 OPENSSL_INLINE ptrtype sk_##name##_value(const STACK_OF(name) *sk, \ 451 size_t i) { \ 452 return (ptrtype)OPENSSL_sk_value((const OPENSSL_STACK *)sk, i); \ 453 } \ 454 \ 455 OPENSSL_INLINE ptrtype sk_##name##_set(STACK_OF(name) *sk, size_t i, \ 456 ptrtype p) { \ 457 return (ptrtype)OPENSSL_sk_set((OPENSSL_STACK *)sk, i, (void *)p); \ 458 } \ 459 \ 460 OPENSSL_INLINE void sk_##name##_free(STACK_OF(name) *sk) { \ 461 OPENSSL_sk_free((OPENSSL_STACK *)sk); \ 462 } \ 463 \ 464 OPENSSL_INLINE void sk_##name##_pop_free(STACK_OF(name) *sk, \ 465 sk_##name##_free_func free_func) { \ 466 OPENSSL_sk_pop_free_ex((OPENSSL_STACK *)sk, sk_##name##_call_free_func, \ 467 (OPENSSL_sk_free_func)free_func); \ 468 } \ 469 \ 470 OPENSSL_INLINE size_t sk_##name##_insert(STACK_OF(name) *sk, ptrtype p, \ 471 size_t where) { \ 472 return OPENSSL_sk_insert((OPENSSL_STACK *)sk, (void *)p, where); \ 473 } \ 474 \ 475 OPENSSL_INLINE ptrtype sk_##name##_delete(STACK_OF(name) *sk, \ 476 size_t where) { \ 477 return (ptrtype)OPENSSL_sk_delete((OPENSSL_STACK *)sk, where); \ 478 } \ 479 \ 480 OPENSSL_INLINE ptrtype sk_##name##_delete_ptr(STACK_OF(name) *sk, \ 481 constptrtype p) { \ 482 return (ptrtype)OPENSSL_sk_delete_ptr((OPENSSL_STACK *)sk, \ 483 (const void *)p); \ 484 } \ 485 \ 486 OPENSSL_INLINE void sk_##name##_delete_if( \ 487 STACK_OF(name) *sk, sk_##name##_delete_if_func func, void *data) { \ 488 OPENSSL_sk_delete_if((OPENSSL_STACK *)sk, sk_##name##_call_delete_if_func, \ 489 (OPENSSL_sk_delete_if_func)func, data); \ 490 } \ 491 \ 492 OPENSSL_INLINE int sk_##name##_find(const STACK_OF(name) *sk, \ 493 size_t *out_index, constptrtype p) { \ 494 return OPENSSL_sk_find((const OPENSSL_STACK *)sk, out_index, \ 495 (const void *)p, sk_##name##_call_cmp_func); \ 496 } \ 497 \ 498 OPENSSL_INLINE ptrtype sk_##name##_shift(STACK_OF(name) *sk) { \ 499 return (ptrtype)OPENSSL_sk_shift((OPENSSL_STACK *)sk); \ 500 } \ 501 \ 502 OPENSSL_INLINE size_t sk_##name##_push(STACK_OF(name) *sk, ptrtype p) { \ 503 return OPENSSL_sk_push((OPENSSL_STACK *)sk, (void *)p); \ 504 } \ 505 \ 506 OPENSSL_INLINE ptrtype sk_##name##_pop(STACK_OF(name) *sk) { \ 507 return (ptrtype)OPENSSL_sk_pop((OPENSSL_STACK *)sk); \ 508 } \ 509 \ 510 OPENSSL_INLINE STACK_OF(name) *sk_##name##_dup(const STACK_OF(name) *sk) { \ 511 return (STACK_OF(name) *)OPENSSL_sk_dup((const OPENSSL_STACK *)sk); \ 512 } \ 513 \ 514 OPENSSL_INLINE void sk_##name##_sort(STACK_OF(name) *sk) { \ 515 OPENSSL_sk_sort((OPENSSL_STACK *)sk, sk_##name##_call_cmp_func); \ 516 } \ 517 \ 518 OPENSSL_INLINE int sk_##name##_is_sorted(const STACK_OF(name) *sk) { \ 519 return OPENSSL_sk_is_sorted((const OPENSSL_STACK *)sk); \ 520 } \ 521 \ 522 OPENSSL_INLINE sk_##name##_cmp_func sk_##name##_set_cmp_func( \ 523 STACK_OF(name) *sk, sk_##name##_cmp_func comp) { \ 524 return (sk_##name##_cmp_func)OPENSSL_sk_set_cmp_func( \ 525 (OPENSSL_STACK *)sk, (OPENSSL_sk_cmp_func)comp); \ 526 } \ 527 \ 528 OPENSSL_INLINE STACK_OF(name) *sk_##name##_deep_copy( \ 529 const STACK_OF(name) *sk, sk_##name##_copy_func copy_func, \ 530 sk_##name##_free_func free_func) { \ 531 return (STACK_OF(name) *)OPENSSL_sk_deep_copy( \ 532 (const OPENSSL_STACK *)sk, sk_##name##_call_copy_func, \ 533 (OPENSSL_sk_copy_func)copy_func, sk_##name##_call_free_func, \ 534 (OPENSSL_sk_free_func)free_func); \ 535 } \ 536 \ 537 OPENSSL_MSVC_PRAGMA(warning(pop)) 538 539 540 // Built-in stacks. 541 542 typedef char *OPENSSL_STRING; 543 544 DEFINE_STACK_OF(void) 545 DEFINE_NAMED_STACK_OF(OPENSSL_STRING, char) 546 547 548 #if defined(__cplusplus) 549 } // extern C 550 #endif 551 552 #if !defined(BORINGSSL_NO_CXX) 553 extern "C++" { 554 555 #include <type_traits> 556 557 BSSL_NAMESPACE_BEGIN 558 559 namespace internal { 560 561 // Stacks defined with |DEFINE_CONST_STACK_OF| are freed with |sk_free|. 562 template <typename Stack> 563 struct DeleterImpl<Stack, std::enable_if_t<StackTraits<Stack>::kIsConst>> { 564 static void Free(Stack *sk) { 565 OPENSSL_sk_free(reinterpret_cast<OPENSSL_STACK *>(sk)); 566 } 567 }; 568 569 // Stacks defined with |DEFINE_STACK_OF| are freed with |sk_pop_free| and the 570 // corresponding type's deleter. 571 template <typename Stack> 572 struct DeleterImpl<Stack, std::enable_if_t<!StackTraits<Stack>::kIsConst>> { 573 static void Free(Stack *sk) { 574 // sk_FOO_pop_free is defined by macros and bound by name, so we cannot 575 // access it from C++ here. 576 using Type = typename StackTraits<Stack>::Type; 577 OPENSSL_sk_pop_free_ex( 578 reinterpret_cast<OPENSSL_STACK *>(sk), 579 [](OPENSSL_sk_free_func /* unused */, void *ptr) { 580 DeleterImpl<Type>::Free(reinterpret_cast<Type *>(ptr)); 581 }, 582 nullptr); 583 } 584 }; 585 586 template <typename Stack> 587 class StackIteratorImpl { 588 public: 589 using Type = typename StackTraits<Stack>::Type; 590 // Iterators must be default-constructable. 591 StackIteratorImpl() : sk_(nullptr), idx_(0) {} 592 StackIteratorImpl(const Stack *sk, size_t idx) : sk_(sk), idx_(idx) {} 593 594 bool operator==(StackIteratorImpl other) const { 595 return sk_ == other.sk_ && idx_ == other.idx_; 596 } 597 bool operator!=(StackIteratorImpl other) const { 598 return !(*this == other); 599 } 600 601 Type *operator*() const { 602 return reinterpret_cast<Type *>( 603 OPENSSL_sk_value(reinterpret_cast<const OPENSSL_STACK *>(sk_), idx_)); 604 } 605 606 StackIteratorImpl &operator++(/* prefix */) { 607 idx_++; 608 return *this; 609 } 610 611 StackIteratorImpl operator++(int /* postfix */) { 612 StackIteratorImpl copy(*this); 613 ++(*this); 614 return copy; 615 } 616 617 private: 618 const Stack *sk_; 619 size_t idx_; 620 }; 621 622 template <typename Stack> 623 using StackIterator = 624 std::enable_if_t<StackTraits<Stack>::kIsStack, StackIteratorImpl<Stack>>; 625 626 } // namespace internal 627 628 // PushToStack pushes |elem| to |sk|. It returns true on success and false on 629 // allocation failure. 630 template <typename Stack> 631 inline std::enable_if_t<!internal::StackTraits<Stack>::kIsConst, bool> 632 PushToStack(Stack *sk, 633 UniquePtr<typename internal::StackTraits<Stack>::Type> elem) { 634 if (!OPENSSL_sk_push(reinterpret_cast<OPENSSL_STACK *>(sk), elem.get())) { 635 return false; 636 } 637 // OPENSSL_sk_push takes ownership on success. 638 elem.release(); 639 return true; 640 } 641 642 BSSL_NAMESPACE_END 643 644 // Define begin() and end() for stack types so C++ range for loops work. 645 template <typename Stack> 646 inline bssl::internal::StackIterator<Stack> begin(const Stack *sk) { 647 return bssl::internal::StackIterator<Stack>(sk, 0); 648 } 649 650 template <typename Stack> 651 inline bssl::internal::StackIterator<Stack> end(const Stack *sk) { 652 return bssl::internal::StackIterator<Stack>( 653 sk, OPENSSL_sk_num(reinterpret_cast<const OPENSSL_STACK *>(sk))); 654 } 655 656 } // extern C++ 657 #endif 658 659 #endif // OPENSSL_HEADER_STACK_H 660