1 /* Copyright (C) 1995-1998 Eric Young ([email protected]) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young ([email protected]). 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 ([email protected]). 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 ([email protected])" 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 ([email protected])" 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. If 143 // |sk| is NULL, it is treated as the empty list and this function returns zero. 144 size_t sk_SAMPLE_num(const STACK_OF(SAMPLE) *sk); 145 146 // sk_SAMPLE_zero resets |sk| to the empty state but does nothing to free the 147 // individual elements themselves. 148 void sk_SAMPLE_zero(STACK_OF(SAMPLE) *sk); 149 150 // sk_SAMPLE_value returns the |i|th pointer in |sk|, or NULL if |i| is out of 151 // range. If |sk| is NULL, it is treated as an empty list and the function 152 // returns NULL. 153 SAMPLE *sk_SAMPLE_value(const STACK_OF(SAMPLE) *sk, size_t i); 154 155 // sk_SAMPLE_set sets the |i|th pointer in |sk| to |p| and returns |p|. If |i| 156 // is out of range, it returns NULL. 157 SAMPLE *sk_SAMPLE_set(STACK_OF(SAMPLE) *sk, size_t i, SAMPLE *p); 158 159 // sk_SAMPLE_free frees |sk|, but does nothing to free the individual elements. 160 // Use |sk_SAMPLE_pop_free| to also free the elements. 161 void sk_SAMPLE_free(STACK_OF(SAMPLE) *sk); 162 163 // sk_SAMPLE_pop_free calls |free_func| on each element in |sk| and then 164 // frees the stack itself. 165 void sk_SAMPLE_pop_free(STACK_OF(SAMPLE) *sk, sk_SAMPLE_free_func free_func); 166 167 // sk_SAMPLE_insert inserts |p| into the stack at index |where|, moving existing 168 // elements if needed. It returns the length of the new stack, or zero on 169 // error. 170 size_t sk_SAMPLE_insert(STACK_OF(SAMPLE) *sk, SAMPLE *p, size_t where); 171 172 // sk_SAMPLE_delete removes the pointer at index |where|, moving other elements 173 // down if needed. It returns the removed pointer, or NULL if |where| is out of 174 // range. 175 SAMPLE *sk_SAMPLE_delete(STACK_OF(SAMPLE) *sk, size_t where); 176 177 // sk_SAMPLE_delete_ptr removes, at most, one instance of |p| from |sk| based on 178 // pointer equality. If an instance of |p| is found then |p| is returned, 179 // otherwise it returns NULL. 180 SAMPLE *sk_SAMPLE_delete_ptr(STACK_OF(SAMPLE) *sk, const SAMPLE *p); 181 182 // sk_SAMPLE_delete_if_func is the callback function for |sk_SAMPLE_delete_if|. 183 // It should return one to remove |p| and zero to keep it. 184 typedef int (*sk_SAMPLE_delete_if_func)(SAMPLE *p, void *data); 185 186 // sk_SAMPLE_delete_if calls |func| with each element of |sk| and removes the 187 // entries where |func| returned one. This function does not free or return 188 // removed pointers so, if |sk| owns its contents, |func| should release the 189 // pointers prior to returning one. 190 void sk_SAMPLE_delete_if(STACK_OF(SAMPLE) *sk, sk_SAMPLE_delete_if_func func, 191 void *data); 192 193 // sk_SAMPLE_find find the first value in |sk| equal to |p|. |sk|'s comparison 194 // function determines equality, or pointer equality if |sk| has no comparison 195 // function. 196 // 197 // If the stack is sorted (see |sk_SAMPLE_sort|), this function uses a binary 198 // search. Otherwise it performs a linear search. If it finds a matching 199 // element, it writes the index to |*out_index| (if |out_index| is not NULL) and 200 // returns one. Otherwise, it returns zero. If |sk| is NULL, it is treated as 201 // the empty list and the function returns zero. 202 // 203 // Note this differs from OpenSSL. The type signature is slightly different, and 204 // OpenSSL's version will implicitly sort |sk| if it has a comparison function 205 // defined. 206 int sk_SAMPLE_find(const STACK_OF(SAMPLE) *sk, size_t *out_index, 207 const SAMPLE *p); 208 209 // sk_SAMPLE_shift removes and returns the first element in |sk|, or NULL if 210 // |sk| is empty. 211 SAMPLE *sk_SAMPLE_shift(STACK_OF(SAMPLE) *sk); 212 213 // sk_SAMPLE_push appends |p| to |sk| and returns the length of the new stack, 214 // or 0 on allocation failure. 215 size_t sk_SAMPLE_push(STACK_OF(SAMPLE) *sk, SAMPLE *p); 216 217 // sk_SAMPLE_pop removes and returns the last element of |sk|, or NULL if |sk| 218 // is empty. 219 SAMPLE *sk_SAMPLE_pop(STACK_OF(SAMPLE) *sk); 220 221 // sk_SAMPLE_dup performs a shallow copy of a stack and returns the new stack, 222 // or NULL on error. Use |sk_SAMPLE_deep_copy| to also copy the elements. 223 STACK_OF(SAMPLE) *sk_SAMPLE_dup(const STACK_OF(SAMPLE) *sk); 224 225 // sk_SAMPLE_sort sorts the elements of |sk| into ascending order based on the 226 // comparison function. The stack maintains a "sorted" flag and sorting an 227 // already sorted stack is a no-op. 228 void sk_SAMPLE_sort(STACK_OF(SAMPLE) *sk); 229 230 // sk_SAMPLE_is_sorted returns one if |sk| is known to be sorted and zero 231 // otherwise. 232 int sk_SAMPLE_is_sorted(const STACK_OF(SAMPLE) *sk); 233 234 // sk_SAMPLE_set_cmp_func sets the comparison function to be used by |sk| and 235 // returns the previous one. 236 sk_SAMPLE_cmp_func sk_SAMPLE_set_cmp_func(STACK_OF(SAMPLE) *sk, 237 sk_SAMPLE_cmp_func comp); 238 239 // sk_SAMPLE_deep_copy performs a copy of |sk| and of each of the non-NULL 240 // elements in |sk| by using |copy_func|. If an error occurs, it calls 241 // |free_func| to free any copies already made and returns NULL. 242 STACK_OF(SAMPLE) *sk_SAMPLE_deep_copy(const STACK_OF(SAMPLE) *sk, 243 sk_SAMPLE_copy_func copy_func, 244 sk_SAMPLE_free_func free_func); 245 246 #endif // Sample 247 248 249 // Private functions. 250 // 251 // The |sk_*| functions generated above are implemented internally using the 252 // type-erased functions below. Callers should use the typed wrappers instead. 253 // When using the type-erased functions, callers are responsible for ensuring 254 // the underlying types are correct. Casting pointers to the wrong types will 255 // result in memory errors. 256 257 // OPENSSL_sk_free_func is a function that frees an element in a stack. Note its 258 // actual type is void (*)(T *) for some T. Low-level |sk_*| functions will be 259 // passed a type-specific wrapper to call it correctly. 260 typedef void (*OPENSSL_sk_free_func)(void *ptr); 261 262 // OPENSSL_sk_copy_func is a function that copies an element in a stack. Note 263 // its actual type is T *(*)(const T *) for some T. Low-level |sk_*| functions 264 // will be passed a type-specific wrapper to call it correctly. 265 typedef void *(*OPENSSL_sk_copy_func)(const void *ptr); 266 267 // OPENSSL_sk_cmp_func is a comparison function that returns a value < 0, 0 or > 268 // 0 if |*a| is less than, equal to or greater than |*b|, respectively. Note 269 // the extra indirection - the function is given a pointer to a pointer to the 270 // element. This differs from the usual qsort/bsearch comparison function. 271 // 272 // Note its actual type is |int (*)(const T *const *a, const T *const *b)|. 273 // Low-level |sk_*| functions will be passed a type-specific wrapper to call it 274 // correctly. 275 typedef int (*OPENSSL_sk_cmp_func)(const void *const *a, const void *const *b); 276 277 // OPENSSL_sk_delete_if_func is the generic version of 278 // |sk_SAMPLE_delete_if_func|. 279 typedef int (*OPENSSL_sk_delete_if_func)(void *obj, void *data); 280 281 // The following function types call the above type-erased signatures with the 282 // true types. 283 typedef void (*OPENSSL_sk_call_free_func)(OPENSSL_sk_free_func, void *); 284 typedef void *(*OPENSSL_sk_call_copy_func)(OPENSSL_sk_copy_func, const void *); 285 typedef int (*OPENSSL_sk_call_cmp_func)(OPENSSL_sk_cmp_func, const void *, 286 const void *); 287 typedef int (*OPENSSL_sk_call_delete_if_func)(OPENSSL_sk_delete_if_func, void *, 288 void *); 289 290 // An OPENSSL_STACK contains an array of pointers. It is not designed to be used 291 // directly, rather the wrapper macros should be used. 292 typedef struct stack_st OPENSSL_STACK; 293 294 // The following are raw stack functions. They implement the corresponding typed 295 // |sk_SAMPLE_*| functions generated by |DEFINE_STACK_OF|. Callers shouldn't be 296 // using them. Rather, callers should use the typed functions. 297 OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_cmp_func comp); 298 OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_new_null(void); 299 OPENSSL_EXPORT size_t OPENSSL_sk_num(const OPENSSL_STACK *sk); 300 OPENSSL_EXPORT void OPENSSL_sk_zero(OPENSSL_STACK *sk); 301 OPENSSL_EXPORT void *OPENSSL_sk_value(const OPENSSL_STACK *sk, size_t i); 302 OPENSSL_EXPORT void *OPENSSL_sk_set(OPENSSL_STACK *sk, size_t i, void *p); 303 OPENSSL_EXPORT void OPENSSL_sk_free(OPENSSL_STACK *sk); 304 OPENSSL_EXPORT void OPENSSL_sk_pop_free_ex( 305 OPENSSL_STACK *sk, OPENSSL_sk_call_free_func call_free_func, 306 OPENSSL_sk_free_func free_func); 307 OPENSSL_EXPORT size_t OPENSSL_sk_insert(OPENSSL_STACK *sk, void *p, 308 size_t where); 309 OPENSSL_EXPORT void *OPENSSL_sk_delete(OPENSSL_STACK *sk, size_t where); 310 OPENSSL_EXPORT void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *sk, const void *p); 311 OPENSSL_EXPORT void OPENSSL_sk_delete_if( 312 OPENSSL_STACK *sk, OPENSSL_sk_call_delete_if_func call_func, 313 OPENSSL_sk_delete_if_func func, void *data); 314 OPENSSL_EXPORT int OPENSSL_sk_find(const OPENSSL_STACK *sk, size_t *out_index, 315 const void *p, 316 OPENSSL_sk_call_cmp_func call_cmp_func); 317 OPENSSL_EXPORT void *OPENSSL_sk_shift(OPENSSL_STACK *sk); 318 OPENSSL_EXPORT size_t OPENSSL_sk_push(OPENSSL_STACK *sk, void *p); 319 OPENSSL_EXPORT void *OPENSSL_sk_pop(OPENSSL_STACK *sk); 320 OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *sk); 321 OPENSSL_EXPORT void OPENSSL_sk_sort(OPENSSL_STACK *sk, 322 OPENSSL_sk_call_cmp_func call_cmp_func); 323 OPENSSL_EXPORT int OPENSSL_sk_is_sorted(const OPENSSL_STACK *sk); 324 OPENSSL_EXPORT OPENSSL_sk_cmp_func 325 OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, OPENSSL_sk_cmp_func comp); 326 OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_deep_copy( 327 const OPENSSL_STACK *sk, OPENSSL_sk_call_copy_func call_copy_func, 328 OPENSSL_sk_copy_func copy_func, OPENSSL_sk_call_free_func call_free_func, 329 OPENSSL_sk_free_func free_func); 330 331 332 // Deprecated private functions (hidden). 333 // 334 // TODO(crbug.com/boringssl/499): Migrate callers to the typed wrappers, or at 335 // least the new names and remove the old ones. 336 // 337 // TODO(b/290792019, b/290785937): Ideally these would at least be inline 338 // functions, so we do not squat the symbols. 339 340 typedef OPENSSL_STACK _STACK; 341 342 // The following functions call the corresponding |OPENSSL_sk_*| function. 343 OPENSSL_EXPORT OPENSSL_DEPRECATED OPENSSL_STACK *sk_new_null(void); 344 OPENSSL_EXPORT OPENSSL_DEPRECATED size_t sk_num(const OPENSSL_STACK *sk); 345 OPENSSL_EXPORT OPENSSL_DEPRECATED void *sk_value(const OPENSSL_STACK *sk, 346 size_t i); 347 OPENSSL_EXPORT OPENSSL_DEPRECATED void sk_free(OPENSSL_STACK *sk); 348 OPENSSL_EXPORT OPENSSL_DEPRECATED size_t sk_push(OPENSSL_STACK *sk, void *p); 349 OPENSSL_EXPORT OPENSSL_DEPRECATED void *sk_pop(OPENSSL_STACK *sk); 350 351 // sk_pop_free_ex calls |OPENSSL_sk_pop_free_ex|. 352 // 353 // TODO(b/291994116): Remove this. 354 OPENSSL_EXPORT OPENSSL_DEPRECATED void sk_pop_free_ex( 355 OPENSSL_STACK *sk, OPENSSL_sk_call_free_func call_free_func, 356 OPENSSL_sk_free_func free_func); 357 358 // sk_pop_free behaves like |OPENSSL_sk_pop_free_ex| but performs an invalid 359 // function pointer cast. It exists because some existing callers called 360 // |sk_pop_free| directly. 361 // 362 // TODO(davidben): Migrate callers to bssl::UniquePtr and remove this. 363 OPENSSL_EXPORT OPENSSL_DEPRECATED void sk_pop_free( 364 OPENSSL_STACK *sk, OPENSSL_sk_free_func free_func); 365 366 367 #if !defined(BORINGSSL_NO_CXX) 368 extern "C++" { 369 BSSL_NAMESPACE_BEGIN 370 namespace internal { 371 template <typename T> 372 struct StackTraits {}; 373 } 374 BSSL_NAMESPACE_END 375 } 376 377 #define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const) \ 378 extern "C++" { \ 379 BSSL_NAMESPACE_BEGIN \ 380 namespace internal { \ 381 template <> \ 382 struct StackTraits<STACK_OF(name)> { \ 383 static constexpr bool kIsStack = true; \ 384 using Type = type; \ 385 static constexpr bool kIsConst = is_const; \ 386 }; \ 387 } \ 388 BSSL_NAMESPACE_END \ 389 } 390 391 #else 392 #define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const) 393 #endif 394 395 #define BORINGSSL_DEFINE_STACK_OF_IMPL(name, ptrtype, constptrtype) \ 396 /* We disable MSVC C4191 in this macro, which warns when pointers are cast \ 397 * to the wrong type. While the cast itself is valid, it is often a bug \ 398 * because calling it through the cast is UB. However, we never actually \ 399 * call functions as |OPENSSL_sk_cmp_func|. The type is just a type-erased \ 400 * function pointer. (C does not guarantee function pointers fit in \ 401 * |void*|, and GCC will warn on this.) Thus we just disable the false \ 402 * positive warning. */ \ 403 OPENSSL_MSVC_PRAGMA(warning(push)) \ 404 OPENSSL_MSVC_PRAGMA(warning(disable : 4191)) \ 405 OPENSSL_CLANG_PRAGMA("clang diagnostic push") \ 406 OPENSSL_CLANG_PRAGMA("clang diagnostic ignored \"-Wunknown-warning-option\"") \ 407 OPENSSL_CLANG_PRAGMA("clang diagnostic ignored \"-Wcast-function-type-strict\"") \ 408 \ 409 DECLARE_STACK_OF(name) \ 410 \ 411 typedef void (*sk_##name##_free_func)(ptrtype); \ 412 typedef ptrtype (*sk_##name##_copy_func)(constptrtype); \ 413 typedef int (*sk_##name##_cmp_func)(constptrtype const *, \ 414 constptrtype const *); \ 415 typedef int (*sk_##name##_delete_if_func)(ptrtype, void *); \ 416 \ 417 OPENSSL_INLINE void sk_##name##_call_free_func( \ 418 OPENSSL_sk_free_func free_func, void *ptr) { \ 419 ((sk_##name##_free_func)free_func)((ptrtype)ptr); \ 420 } \ 421 \ 422 OPENSSL_INLINE void *sk_##name##_call_copy_func( \ 423 OPENSSL_sk_copy_func copy_func, const void *ptr) { \ 424 return (void *)((sk_##name##_copy_func)copy_func)((constptrtype)ptr); \ 425 } \ 426 \ 427 OPENSSL_INLINE int sk_##name##_call_cmp_func(OPENSSL_sk_cmp_func cmp_func, \ 428 const void *a, const void *b) { \ 429 constptrtype a_ptr = (constptrtype)a; \ 430 constptrtype b_ptr = (constptrtype)b; \ 431 /* |cmp_func| expects an extra layer of pointers to match qsort. */ \ 432 return ((sk_##name##_cmp_func)cmp_func)(&a_ptr, &b_ptr); \ 433 } \ 434 \ 435 OPENSSL_INLINE int sk_##name##_call_delete_if_func( \ 436 OPENSSL_sk_delete_if_func func, void *obj, void *data) { \ 437 return ((sk_##name##_delete_if_func)func)((ptrtype)obj, data); \ 438 } \ 439 \ 440 OPENSSL_INLINE STACK_OF(name) *sk_##name##_new(sk_##name##_cmp_func comp) { \ 441 return (STACK_OF(name) *)OPENSSL_sk_new((OPENSSL_sk_cmp_func)comp); \ 442 } \ 443 \ 444 OPENSSL_INLINE STACK_OF(name) *sk_##name##_new_null(void) { \ 445 return (STACK_OF(name) *)OPENSSL_sk_new_null(); \ 446 } \ 447 \ 448 OPENSSL_INLINE size_t sk_##name##_num(const STACK_OF(name) *sk) { \ 449 return OPENSSL_sk_num((const OPENSSL_STACK *)sk); \ 450 } \ 451 \ 452 OPENSSL_INLINE void sk_##name##_zero(STACK_OF(name) *sk) { \ 453 OPENSSL_sk_zero((OPENSSL_STACK *)sk); \ 454 } \ 455 \ 456 OPENSSL_INLINE ptrtype sk_##name##_value(const STACK_OF(name) *sk, \ 457 size_t i) { \ 458 return (ptrtype)OPENSSL_sk_value((const OPENSSL_STACK *)sk, i); \ 459 } \ 460 \ 461 OPENSSL_INLINE ptrtype sk_##name##_set(STACK_OF(name) *sk, size_t i, \ 462 ptrtype p) { \ 463 return (ptrtype)OPENSSL_sk_set((OPENSSL_STACK *)sk, i, (void *)p); \ 464 } \ 465 \ 466 OPENSSL_INLINE void sk_##name##_free(STACK_OF(name) *sk) { \ 467 OPENSSL_sk_free((OPENSSL_STACK *)sk); \ 468 } \ 469 \ 470 OPENSSL_INLINE void sk_##name##_pop_free(STACK_OF(name) *sk, \ 471 sk_##name##_free_func free_func) { \ 472 OPENSSL_sk_pop_free_ex((OPENSSL_STACK *)sk, sk_##name##_call_free_func, \ 473 (OPENSSL_sk_free_func)free_func); \ 474 } \ 475 \ 476 OPENSSL_INLINE size_t sk_##name##_insert(STACK_OF(name) *sk, ptrtype p, \ 477 size_t where) { \ 478 return OPENSSL_sk_insert((OPENSSL_STACK *)sk, (void *)p, where); \ 479 } \ 480 \ 481 OPENSSL_INLINE ptrtype sk_##name##_delete(STACK_OF(name) *sk, \ 482 size_t where) { \ 483 return (ptrtype)OPENSSL_sk_delete((OPENSSL_STACK *)sk, where); \ 484 } \ 485 \ 486 OPENSSL_INLINE ptrtype sk_##name##_delete_ptr(STACK_OF(name) *sk, \ 487 constptrtype p) { \ 488 return (ptrtype)OPENSSL_sk_delete_ptr((OPENSSL_STACK *)sk, \ 489 (const void *)p); \ 490 } \ 491 \ 492 OPENSSL_INLINE void sk_##name##_delete_if( \ 493 STACK_OF(name) *sk, sk_##name##_delete_if_func func, void *data) { \ 494 OPENSSL_sk_delete_if((OPENSSL_STACK *)sk, sk_##name##_call_delete_if_func, \ 495 (OPENSSL_sk_delete_if_func)func, data); \ 496 } \ 497 \ 498 OPENSSL_INLINE int sk_##name##_find(const STACK_OF(name) *sk, \ 499 size_t *out_index, constptrtype p) { \ 500 return OPENSSL_sk_find((const OPENSSL_STACK *)sk, out_index, \ 501 (const void *)p, sk_##name##_call_cmp_func); \ 502 } \ 503 \ 504 OPENSSL_INLINE ptrtype sk_##name##_shift(STACK_OF(name) *sk) { \ 505 return (ptrtype)OPENSSL_sk_shift((OPENSSL_STACK *)sk); \ 506 } \ 507 \ 508 OPENSSL_INLINE size_t sk_##name##_push(STACK_OF(name) *sk, ptrtype p) { \ 509 return OPENSSL_sk_push((OPENSSL_STACK *)sk, (void *)p); \ 510 } \ 511 \ 512 OPENSSL_INLINE ptrtype sk_##name##_pop(STACK_OF(name) *sk) { \ 513 return (ptrtype)OPENSSL_sk_pop((OPENSSL_STACK *)sk); \ 514 } \ 515 \ 516 OPENSSL_INLINE STACK_OF(name) *sk_##name##_dup(const STACK_OF(name) *sk) { \ 517 return (STACK_OF(name) *)OPENSSL_sk_dup((const OPENSSL_STACK *)sk); \ 518 } \ 519 \ 520 OPENSSL_INLINE void sk_##name##_sort(STACK_OF(name) *sk) { \ 521 OPENSSL_sk_sort((OPENSSL_STACK *)sk, sk_##name##_call_cmp_func); \ 522 } \ 523 \ 524 OPENSSL_INLINE int sk_##name##_is_sorted(const STACK_OF(name) *sk) { \ 525 return OPENSSL_sk_is_sorted((const OPENSSL_STACK *)sk); \ 526 } \ 527 \ 528 OPENSSL_INLINE sk_##name##_cmp_func sk_##name##_set_cmp_func( \ 529 STACK_OF(name) *sk, sk_##name##_cmp_func comp) { \ 530 return (sk_##name##_cmp_func)OPENSSL_sk_set_cmp_func( \ 531 (OPENSSL_STACK *)sk, (OPENSSL_sk_cmp_func)comp); \ 532 } \ 533 \ 534 OPENSSL_INLINE STACK_OF(name) *sk_##name##_deep_copy( \ 535 const STACK_OF(name) *sk, sk_##name##_copy_func copy_func, \ 536 sk_##name##_free_func free_func) { \ 537 return (STACK_OF(name) *)OPENSSL_sk_deep_copy( \ 538 (const OPENSSL_STACK *)sk, sk_##name##_call_copy_func, \ 539 (OPENSSL_sk_copy_func)copy_func, sk_##name##_call_free_func, \ 540 (OPENSSL_sk_free_func)free_func); \ 541 } \ 542 \ 543 OPENSSL_CLANG_PRAGMA("clang diagnostic pop") \ 544 OPENSSL_MSVC_PRAGMA(warning(pop)) 545 546 547 // Built-in stacks. 548 549 typedef char *OPENSSL_STRING; 550 551 DEFINE_STACK_OF(void) 552 DEFINE_NAMED_STACK_OF(OPENSSL_STRING, char) 553 554 555 #if defined(__cplusplus) 556 } // extern C 557 #endif 558 559 #if !defined(BORINGSSL_NO_CXX) 560 extern "C++" { 561 562 #include <type_traits> 563 564 BSSL_NAMESPACE_BEGIN 565 566 namespace internal { 567 568 // Stacks defined with |DEFINE_CONST_STACK_OF| are freed with |sk_free|. 569 template <typename Stack> 570 struct DeleterImpl<Stack, std::enable_if_t<StackTraits<Stack>::kIsConst>> { 571 static void Free(Stack *sk) { 572 OPENSSL_sk_free(reinterpret_cast<OPENSSL_STACK *>(sk)); 573 } 574 }; 575 576 // Stacks defined with |DEFINE_STACK_OF| are freed with |sk_pop_free| and the 577 // corresponding type's deleter. 578 template <typename Stack> 579 struct DeleterImpl<Stack, std::enable_if_t<!StackTraits<Stack>::kIsConst>> { 580 static void Free(Stack *sk) { 581 // sk_FOO_pop_free is defined by macros and bound by name, so we cannot 582 // access it from C++ here. 583 using Type = typename StackTraits<Stack>::Type; 584 OPENSSL_sk_pop_free_ex( 585 reinterpret_cast<OPENSSL_STACK *>(sk), 586 [](OPENSSL_sk_free_func /* unused */, void *ptr) { 587 DeleterImpl<Type>::Free(reinterpret_cast<Type *>(ptr)); 588 }, 589 nullptr); 590 } 591 }; 592 593 template <typename Stack> 594 class StackIteratorImpl { 595 public: 596 using Type = typename StackTraits<Stack>::Type; 597 // Iterators must be default-constructable. 598 StackIteratorImpl() : sk_(nullptr), idx_(0) {} 599 StackIteratorImpl(const Stack *sk, size_t idx) : sk_(sk), idx_(idx) {} 600 601 bool operator==(StackIteratorImpl other) const { 602 return sk_ == other.sk_ && idx_ == other.idx_; 603 } 604 bool operator!=(StackIteratorImpl other) const { 605 return !(*this == other); 606 } 607 608 Type *operator*() const { 609 return reinterpret_cast<Type *>( 610 OPENSSL_sk_value(reinterpret_cast<const OPENSSL_STACK *>(sk_), idx_)); 611 } 612 613 StackIteratorImpl &operator++(/* prefix */) { 614 idx_++; 615 return *this; 616 } 617 618 StackIteratorImpl operator++(int /* postfix */) { 619 StackIteratorImpl copy(*this); 620 ++(*this); 621 return copy; 622 } 623 624 private: 625 const Stack *sk_; 626 size_t idx_; 627 }; 628 629 template <typename Stack> 630 using StackIterator = 631 std::enable_if_t<StackTraits<Stack>::kIsStack, StackIteratorImpl<Stack>>; 632 633 } // namespace internal 634 635 // PushToStack pushes |elem| to |sk|. It returns true on success and false on 636 // allocation failure. 637 template <typename Stack> 638 inline std::enable_if_t<!internal::StackTraits<Stack>::kIsConst, bool> 639 PushToStack(Stack *sk, 640 UniquePtr<typename internal::StackTraits<Stack>::Type> elem) { 641 if (!OPENSSL_sk_push(reinterpret_cast<OPENSSL_STACK *>(sk), elem.get())) { 642 return false; 643 } 644 // OPENSSL_sk_push takes ownership on success. 645 elem.release(); 646 return true; 647 } 648 649 BSSL_NAMESPACE_END 650 651 // Define begin() and end() for stack types so C++ range for loops work. 652 template <typename Stack> 653 inline bssl::internal::StackIterator<Stack> begin(const Stack *sk) { 654 return bssl::internal::StackIterator<Stack>(sk, 0); 655 } 656 657 template <typename Stack> 658 inline bssl::internal::StackIterator<Stack> end(const Stack *sk) { 659 return bssl::internal::StackIterator<Stack>( 660 sk, OPENSSL_sk_num(reinterpret_cast<const OPENSSL_STACK *>(sk))); 661 } 662 663 } // extern C++ 664 #endif 665 666 #endif // OPENSSL_HEADER_STACK_H 667