safestack.h 7.7 KB
Newer Older
R
Rich Salz 已提交
1
/*
2
 * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved.
B
Ben Laurie 已提交
3
 *
R
Rich Salz 已提交
4 5 6 7
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
B
Ben Laurie 已提交
8 9 10
 */

#ifndef HEADER_SAFESTACK_H
11
# define HEADER_SAFESTACK_H
B
Ben Laurie 已提交
12

13
# include <openssl/stack.h>
14
# include <openssl/e_os2.h>
B
Ben Laurie 已提交
15

16 17 18 19
#ifdef __cplusplus
extern "C" {
#endif

20
# define STACK_OF(type) struct stack_st_##type
21

22
# define SKM_DEFINE_STACK_OF(t1, t2, t3) \
23
    STACK_OF(t1); \
24 25 26
    typedef int (*sk_##t1##_compfunc)(const t3 * const *a, const t3 *const *b); \
    typedef void (*sk_##t1##_freefunc)(t3 *a); \
    typedef t3 * (*sk_##t1##_copyfunc)(const t3 *a); \
27 28
    static ossl_inline int sk_##t1##_num(const STACK_OF(t1) *sk) \
    { \
29
        return OPENSSL_sk_num((const OPENSSL_STACK *)sk); \
30 31 32
    } \
    static ossl_inline t2 *sk_##t1##_value(const STACK_OF(t1) *sk, int idx) \
    { \
33
        return (t2 *)OPENSSL_sk_value((const OPENSSL_STACK *)sk, idx); \
34
    } \
35
    static ossl_inline STACK_OF(t1) *sk_##t1##_new(sk_##t1##_compfunc compare) \
36
    { \
37
        return (STACK_OF(t1) *)OPENSSL_sk_new((OPENSSL_sk_compfunc)compare); \
38 39 40
    } \
    static ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \
    { \
41
        return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \
42
    } \
P
Paul Yang 已提交
43 44 45 46
    static ossl_inline STACK_OF(t1) *sk_##t1##_new_reserve(sk_##t1##_compfunc compare, int n) \
    { \
        return (STACK_OF(t1) *)OPENSSL_sk_new_reserve((OPENSSL_sk_compfunc)compare, n); \
    } \
47 48 49 50
    static ossl_inline int sk_##t1##_reserve(STACK_OF(t1) *sk, int n) \
    { \
        return OPENSSL_sk_reserve((OPENSSL_STACK *)sk, n); \
    } \
51
    static ossl_inline void sk_##t1##_free(STACK_OF(t1) *sk) \
52
    { \
53
        OPENSSL_sk_free((OPENSSL_STACK *)sk); \
54
    } \
55
    static ossl_inline void sk_##t1##_zero(STACK_OF(t1) *sk) \
56
    { \
57
        OPENSSL_sk_zero((OPENSSL_STACK *)sk); \
58 59 60
    } \
    static ossl_inline t2 *sk_##t1##_delete(STACK_OF(t1) *sk, int i) \
    { \
61
        return (t2 *)OPENSSL_sk_delete((OPENSSL_STACK *)sk, i); \
62 63 64
    } \
    static ossl_inline t2 *sk_##t1##_delete_ptr(STACK_OF(t1) *sk, t2 *ptr) \
    { \
65 66
        return (t2 *)OPENSSL_sk_delete_ptr((OPENSSL_STACK *)sk, \
                                           (const void *)ptr); \
67 68 69
    } \
    static ossl_inline int sk_##t1##_push(STACK_OF(t1) *sk, t2 *ptr) \
    { \
R
Rich Salz 已提交
70
        return OPENSSL_sk_push((OPENSSL_STACK *)sk, (const void *)ptr); \
71 72 73
    } \
    static ossl_inline int sk_##t1##_unshift(STACK_OF(t1) *sk, t2 *ptr) \
    { \
R
Rich Salz 已提交
74
        return OPENSSL_sk_unshift((OPENSSL_STACK *)sk, (const void *)ptr); \
75 76 77
    } \
    static ossl_inline t2 *sk_##t1##_pop(STACK_OF(t1) *sk) \
    { \
78
        return (t2 *)OPENSSL_sk_pop((OPENSSL_STACK *)sk); \
79 80 81
    } \
    static ossl_inline t2 *sk_##t1##_shift(STACK_OF(t1) *sk) \
    { \
82
        return (t2 *)OPENSSL_sk_shift((OPENSSL_STACK *)sk); \
83
    } \
84
    static ossl_inline void sk_##t1##_pop_free(STACK_OF(t1) *sk, sk_##t1##_freefunc freefunc) \
85
    { \
86
        OPENSSL_sk_pop_free((OPENSSL_STACK *)sk, (OPENSSL_sk_freefunc)freefunc); \
87 88 89
    } \
    static ossl_inline int sk_##t1##_insert(STACK_OF(t1) *sk, t2 *ptr, int idx) \
    { \
R
Rich Salz 已提交
90
        return OPENSSL_sk_insert((OPENSSL_STACK *)sk, (const void *)ptr, idx); \
91 92 93
    } \
    static ossl_inline t2 *sk_##t1##_set(STACK_OF(t1) *sk, int idx, t2 *ptr) \
    { \
R
Rich Salz 已提交
94
        return (t2 *)OPENSSL_sk_set((OPENSSL_STACK *)sk, idx, (const void *)ptr); \
95 96 97
    } \
    static ossl_inline int sk_##t1##_find(STACK_OF(t1) *sk, t2 *ptr) \
    { \
98
        return OPENSSL_sk_find((OPENSSL_STACK *)sk, (const void *)ptr); \
99 100 101
    } \
    static ossl_inline int sk_##t1##_find_ex(STACK_OF(t1) *sk, t2 *ptr) \
    { \
102
        return OPENSSL_sk_find_ex((OPENSSL_STACK *)sk, (const void *)ptr); \
103
    } \
104
    static ossl_inline void sk_##t1##_sort(STACK_OF(t1) *sk) \
105
    { \
106
        OPENSSL_sk_sort((OPENSSL_STACK *)sk); \
107 108 109
    } \
    static ossl_inline int sk_##t1##_is_sorted(const STACK_OF(t1) *sk) \
    { \
110
        return OPENSSL_sk_is_sorted((const OPENSSL_STACK *)sk); \
111
    } \
F
FdaSilvaYY 已提交
112
    static ossl_inline STACK_OF(t1) * sk_##t1##_dup(const STACK_OF(t1) *sk) \
113
    { \
F
FdaSilvaYY 已提交
114
        return (STACK_OF(t1) *)OPENSSL_sk_dup((const OPENSSL_STACK *)sk); \
115
    } \
F
FdaSilvaYY 已提交
116
    static ossl_inline STACK_OF(t1) *sk_##t1##_deep_copy(const STACK_OF(t1) *sk, \
117 118
                                                    sk_##t1##_copyfunc copyfunc, \
                                                    sk_##t1##_freefunc freefunc) \
119
    { \
R
Rich Salz 已提交
120
        return (STACK_OF(t1) *)OPENSSL_sk_deep_copy((const OPENSSL_STACK *)sk, \
121 122
                                            (OPENSSL_sk_copyfunc)copyfunc, \
                                            (OPENSSL_sk_freefunc)freefunc); \
123
    } \
124
    static ossl_inline sk_##t1##_compfunc sk_##t1##_set_cmp_func(STACK_OF(t1) *sk, sk_##t1##_compfunc compare) \
125
    { \
126
        return (sk_##t1##_compfunc)OPENSSL_sk_set_cmp_func((OPENSSL_STACK *)sk, (OPENSSL_sk_compfunc)compare); \
127 128
    }

129 130
# define DEFINE_SPECIAL_STACK_OF(t1, t2) SKM_DEFINE_STACK_OF(t1, t2, t2)
# define DEFINE_STACK_OF(t) SKM_DEFINE_STACK_OF(t, t, t)
131 132
# define DEFINE_SPECIAL_STACK_OF_CONST(t1, t2) \
            SKM_DEFINE_STACK_OF(t1, const t2, t2)
133
# define DEFINE_STACK_OF_CONST(t) SKM_DEFINE_STACK_OF(t, const t, t)
134

135 136
/*-
 * Strings are special: normally an lhash entry will point to a single
B
Ben Laurie 已提交
137 138 139 140 141 142 143 144
 * (somewhat) mutable object. In the case of strings:
 *
 * a) Instead of a single char, there is an array of chars, NUL-terminated.
 * b) The string may have be immutable.
 *
 * So, they need their own declarations. Especially important for
 * type-checking tools, such as Deputy.
 *
145
 * In practice, however, it appears to be hard to have a const
B
Ben Laurie 已提交
146 147 148
 * string. For now, I'm settling for dealing with the fact it is a
 * string at all.
 */
D
Dr. Stephen Henson 已提交
149 150
typedef char *OPENSSL_STRING;
typedef const char *OPENSSL_CSTRING;
B
Ben Laurie 已提交
151

152
/*-
153 154 155 156 157
 * Confusingly, LHASH_OF(STRING) deals with char ** throughout, but
 * STACK_OF(STRING) is really more like STACK_OF(char), only, as mentioned
 * above, instead of a single char each entry is a NUL-terminated array of
 * chars. So, we have to implement STRING specially for STACK_OF. This is
 * dealt with in the autogenerated macros below.
B
Ben Laurie 已提交
158
 */
159
DEFINE_SPECIAL_STACK_OF(OPENSSL_STRING, char)
160
DEFINE_SPECIAL_STACK_OF_CONST(OPENSSL_CSTRING, char)
B
Ben Laurie 已提交
161

162 163 164 165
/*
 * Similarly, we sometimes use a block of characters, NOT nul-terminated.
 * These should also be distinguished from "normal" stacks.
 */
D
Dr. Stephen Henson 已提交
166
typedef void *OPENSSL_BLOCK;
167
DEFINE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
B
Ben Laurie 已提交
168

169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
/*
 * If called without higher optimization (min. -xO3) the Oracle Developer
 * Studio compiler generates code for the defined (static inline) functions
 * above.
 * This would later lead to the linker complaining about missing symbols when
 * this header file is included but the resulting object is not linked against
 * the Crypto library (openssl#6912).
 */
# ifdef __SUNPRO_C
#  pragma weak OPENSSL_sk_num
#  pragma weak OPENSSL_sk_value
#  pragma weak OPENSSL_sk_new
#  pragma weak OPENSSL_sk_new_null
#  pragma weak OPENSSL_sk_new_reserve
#  pragma weak OPENSSL_sk_reserve
#  pragma weak OPENSSL_sk_free
#  pragma weak OPENSSL_sk_zero
#  pragma weak OPENSSL_sk_delete
#  pragma weak OPENSSL_sk_delete_ptr
#  pragma weak OPENSSL_sk_push
#  pragma weak OPENSSL_sk_unshift
#  pragma weak OPENSSL_sk_pop
#  pragma weak OPENSSL_sk_shift
#  pragma weak OPENSSL_sk_pop_free
#  pragma weak OPENSSL_sk_insert
#  pragma weak OPENSSL_sk_set
#  pragma weak OPENSSL_sk_find
#  pragma weak OPENSSL_sk_find_ex
#  pragma weak OPENSSL_sk_sort
#  pragma weak OPENSSL_sk_is_sorted
#  pragma weak OPENSSL_sk_dup
#  pragma weak OPENSSL_sk_deep_copy
#  pragma weak OPENSSL_sk_set_cmp_func
# endif /* __SUNPRO_C */

204
# ifdef  __cplusplus
205
}
206
# endif
207
#endif