/src/wolfssl-openssl-api/src/ssl_sk.c
Line | Count | Source |
1 | | /* ssl_sk.c |
2 | | * |
3 | | * Copyright (C) 2006-2026 wolfSSL Inc. |
4 | | * |
5 | | * This file is part of wolfSSL. |
6 | | * |
7 | | * wolfSSL is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU General Public License as published by |
9 | | * the Free Software Foundation; either version 3 of the License, or |
10 | | * (at your option) any later version. |
11 | | * |
12 | | * wolfSSL is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU General Public License |
18 | | * along with this program; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA |
20 | | */ |
21 | | |
22 | | #include <wolfssl/wolfcrypt/libwolfssl_sources.h> |
23 | | |
24 | | #if !defined(WOLFSSL_SSL_SK_INCLUDED) |
25 | | #ifndef WOLFSSL_IGNORE_FILE_WARN |
26 | | #warning ssl_sk.c does not need to be compiled separately from ssl.c |
27 | | #endif |
28 | | #else |
29 | | |
30 | | /* In OpenSSL, OPENSSL_STACK is structure with an array of data pointers. |
31 | | * |
32 | | * In wolfSSL, WOLFSSL_STACK is a linked-list of nodes and therefore the first |
33 | | * node has no data but the type is set. |
34 | | * When the first data is set, the first node has the data stored against it and |
35 | | * the number of nodes goes up to 1. |
36 | | * If a new node is prepended then, to keep the pointer the same, the first |
37 | | * node is copied into a new node and inserted after first node, and the new |
38 | | * data is put into the first node. |
39 | | */ |
40 | | |
41 | | /******************************************************************************* |
42 | | * SK node APIs |
43 | | ******************************************************************************/ |
44 | | |
45 | | #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \ |
46 | | defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ |
47 | | defined(OPENSSL_ALL) || defined(WOLFSSL_QT) |
48 | | /* Creates a generic wolfSSL stack node. |
49 | | * |
50 | | * @param [in] heap eap hint for dynamic memory allocation. |
51 | | * @return WOLFSSL_STACK structure on success. |
52 | | * @return NULL when dynamic memory allocation fails. |
53 | | */ |
54 | | WOLFSSL_STACK* wolfSSL_sk_new_node(void* heap) |
55 | 38.2k | { |
56 | 38.2k | WOLFSSL_STACK* node; |
57 | | |
58 | 38.2k | WOLFSSL_ENTER("wolfSSL_sk_new_node"); |
59 | | |
60 | 38.2k | node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), heap, |
61 | 38.2k | DYNAMIC_TYPE_OPENSSL); |
62 | 38.2k | if (node != NULL) { |
63 | 38.2k | XMEMSET(node, 0, sizeof(*node)); |
64 | 38.2k | node->heap = heap; |
65 | 38.2k | } |
66 | | |
67 | 38.2k | return node; |
68 | 38.2k | } |
69 | | #endif |
70 | | |
71 | | #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \ |
72 | | defined(OPENSSL_ALL) |
73 | | /* Disposes of WOLFSSL_STACK object. |
74 | | * |
75 | | * Cannot use node after this call. |
76 | | * |
77 | | * @param [in] node WOLFSSL_STACK object. |
78 | | */ |
79 | | void wolfSSL_sk_free_node(WOLFSSL_STACK* node) |
80 | 37.9k | { |
81 | | /* Don't dereference node for heap when NULL. */ |
82 | 37.9k | if (node != NULL) { |
83 | 37.9k | XFREE(node, node->heap, DYNAMIC_TYPE_OPENSSL); |
84 | 37.9k | } |
85 | 37.9k | } |
86 | | #endif |
87 | | |
88 | | #if !defined(NO_CERTS) && defined(OPENSSL_EXTRA) |
89 | | /* Gets the node from stack at the index. |
90 | | * |
91 | | * @param [in] stack Stack of nodes. |
92 | | * @param [in] idx Index of node to get. |
93 | | * @return Node at index on success. |
94 | | * @return NULL when no node at index. |
95 | | */ |
96 | | WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* stack, int idx) |
97 | 0 | { |
98 | 0 | int i; |
99 | 0 | WOLFSSL_STACK* ret; |
100 | |
|
101 | 0 | if ((idx < 0) || (idx > (int)stack->num)) { |
102 | 0 | ret = NULL; |
103 | 0 | } |
104 | 0 | else { |
105 | 0 | ret = stack; |
106 | 0 | for (i = 0; i < idx; i++) { |
107 | 0 | ret = ret->next; |
108 | 0 | } |
109 | 0 | } |
110 | |
|
111 | 0 | return ret; |
112 | 0 | } |
113 | | #endif /* !NO_CERT && OPENSSL_EXTRA*/ |
114 | | |
115 | | #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) |
116 | | |
117 | | #ifndef NO_CERTS |
118 | | /* Get data pointer from node. |
119 | | * |
120 | | * @param [in] node Node to get data from. |
121 | | * @param [in] no_static Don't return static data. |
122 | | * @return Data pointer of node on success. |
123 | | * @return NULL when node type is STACK_TYPE_CIPHER. |
124 | | */ |
125 | | static void* wolfssl_sk_node_get_data(WOLFSSL_STACK* node, int no_static) |
126 | 0 | { |
127 | 0 | void *ret = NULL; |
128 | |
|
129 | 0 | switch (node->type) { |
130 | 0 | case STACK_TYPE_CIPHER: |
131 | 0 | if (!no_static) { |
132 | 0 | ret = &node->data.cipher; |
133 | 0 | } |
134 | 0 | break; |
135 | 0 | case STACK_TYPE_X509: |
136 | 0 | case STACK_TYPE_GEN_NAME: |
137 | 0 | case STACK_TYPE_BIO: |
138 | 0 | case STACK_TYPE_OBJ: |
139 | 0 | case STACK_TYPE_STRING: |
140 | 0 | case STACK_TYPE_ACCESS_DESCRIPTION: |
141 | 0 | case STACK_TYPE_X509_EXT: |
142 | 0 | case STACK_TYPE_X509_REQ_ATTR: |
143 | 0 | case STACK_TYPE_NULL: |
144 | 0 | case STACK_TYPE_X509_NAME: |
145 | 0 | case STACK_TYPE_X509_NAME_ENTRY: |
146 | 0 | case STACK_TYPE_CONF_VALUE: |
147 | 0 | case STACK_TYPE_X509_INFO: |
148 | 0 | case STACK_TYPE_BY_DIR_entry: |
149 | 0 | case STACK_TYPE_BY_DIR_hash: |
150 | 0 | case STACK_TYPE_X509_OBJ: |
151 | 0 | case STACK_TYPE_DIST_POINT: |
152 | 0 | case STACK_TYPE_X509_CRL: |
153 | 0 | case STACK_TYPE_X509_REVOKED: |
154 | 0 | case STACK_TYPE_GENERAL_SUBTREE: |
155 | 0 | default: |
156 | 0 | ret = node->data.generic; |
157 | 0 | break; |
158 | 0 | } |
159 | | |
160 | 0 | return ret; |
161 | 0 | } |
162 | | |
163 | | /* Set data with type into node. |
164 | | * |
165 | | * @param [in, out] node Node to place data into. |
166 | | * @param [in] type Type of data. |
167 | | * @param [in] data Data to set. |
168 | | */ |
169 | | static void wolfssl_sk_node_set_data(WOLFSSL_STACK* node, WOLF_STACK_TYPE type, |
170 | | const void* data) |
171 | 37.9k | { |
172 | 37.9k | switch (type) { |
173 | 0 | case STACK_TYPE_CIPHER: |
174 | 0 | node->data.cipher = *(WOLFSSL_CIPHER*)data; |
175 | 0 | #ifdef OPENSSL_ALL |
176 | 0 | if (node->hash_fn != NULL) |
177 | 0 | node->hash = node->hash_fn(&node->data.cipher); |
178 | 0 | #endif |
179 | 0 | break; |
180 | 0 | case STACK_TYPE_X509: |
181 | 0 | case STACK_TYPE_GEN_NAME: |
182 | 0 | case STACK_TYPE_BIO: |
183 | 0 | case STACK_TYPE_OBJ: |
184 | 0 | case STACK_TYPE_STRING: |
185 | 0 | case STACK_TYPE_ACCESS_DESCRIPTION: |
186 | 0 | case STACK_TYPE_X509_EXT: |
187 | 0 | case STACK_TYPE_X509_REQ_ATTR: |
188 | 0 | case STACK_TYPE_NULL: |
189 | 37.9k | case STACK_TYPE_X509_NAME: |
190 | 37.9k | case STACK_TYPE_X509_NAME_ENTRY: |
191 | 37.9k | case STACK_TYPE_CONF_VALUE: |
192 | 37.9k | case STACK_TYPE_X509_INFO: |
193 | 37.9k | case STACK_TYPE_BY_DIR_entry: |
194 | 37.9k | case STACK_TYPE_BY_DIR_hash: |
195 | 37.9k | case STACK_TYPE_X509_OBJ: |
196 | 37.9k | case STACK_TYPE_DIST_POINT: |
197 | 37.9k | case STACK_TYPE_X509_CRL: |
198 | 37.9k | case STACK_TYPE_X509_REVOKED: |
199 | 37.9k | case STACK_TYPE_GENERAL_SUBTREE: |
200 | 37.9k | default: |
201 | 37.9k | node->data.generic = (void*)data; |
202 | 37.9k | #ifdef OPENSSL_ALL |
203 | 37.9k | if (node->hash_fn != NULL) |
204 | 0 | node->hash = node->hash_fn(node->data.generic); |
205 | 37.9k | #endif |
206 | 37.9k | break; |
207 | 37.9k | } |
208 | 37.9k | } |
209 | | |
210 | | /* Pushes the node onto the stack. |
211 | | * |
212 | | * stack will point to node on success. |
213 | | * |
214 | | * @param [in, out] stack Stack of nodes. |
215 | | * @param [in] node Node to push on. |
216 | | * |
217 | | * @return WOLFSSL_SUCCESS on success |
218 | | * @return WOLFSSL_FAILURE when stack or node is NULL. |
219 | | */ |
220 | | int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* node) |
221 | 0 | { |
222 | 0 | int ret = WOLFSSL_SUCCESS; |
223 | | |
224 | | /* Validate parameters. */ |
225 | 0 | if (stack == NULL || node == NULL) { |
226 | 0 | ret = WOLFSSL_FAILURE; |
227 | 0 | } |
228 | 0 | if (ret == WOLFSSL_SUCCESS) { |
229 | 0 | if (*stack == NULL) { |
230 | | /* First node. */ |
231 | 0 | node->num = 1; |
232 | 0 | } |
233 | 0 | else { |
234 | | /* Place new node at start of the stack. */ |
235 | 0 | node->num = (*stack)->num + 1; |
236 | 0 | node->next = *stack; |
237 | 0 | } |
238 | | /* Return new start. */ |
239 | 0 | *stack = node; |
240 | 0 | } |
241 | |
|
242 | 0 | return ret; |
243 | 0 | } |
244 | | |
245 | | /* Pushes the node onto the back of the stack. |
246 | | * |
247 | | * If *stack is NULL, node becomes the head. |
248 | | * |
249 | | * @param [in, out] stack Stack of nodes. |
250 | | * @param [in] node Node to append. |
251 | | * |
252 | | * @return WOLFSSL_SUCCESS on success |
253 | | * @return WOLFSSL_FAILURE when stack or node is NULL. |
254 | | */ |
255 | | int wolfSSL_sk_push_back_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* node) |
256 | 0 | { |
257 | 0 | int ret = WOLFSSL_SUCCESS; |
258 | | |
259 | | /* Validate parameters. */ |
260 | 0 | if (stack == NULL || node == NULL) { |
261 | 0 | ret = WOLFSSL_FAILURE; |
262 | 0 | } |
263 | 0 | if (ret == WOLFSSL_SUCCESS) { |
264 | 0 | node->next = NULL; |
265 | | /* Tail node has num of 1, indicating 1 node till the end */ |
266 | 0 | node->num = 1; |
267 | |
|
268 | 0 | if (*stack == NULL) { |
269 | | /* First node. */ |
270 | 0 | *stack = node; |
271 | 0 | } |
272 | 0 | else { |
273 | | /* Walk to the end and append. Each node's num field holds the |
274 | | * count of nodes from that node to the tail (inclusive), so |
275 | | * every existing node's num increases by one. */ |
276 | 0 | WOLFSSL_STACK* cur = *stack; |
277 | 0 | while (cur->next != NULL) { |
278 | 0 | cur->num++; |
279 | 0 | cur = cur->next; |
280 | 0 | } |
281 | 0 | cur->num++; |
282 | 0 | cur->next = node; |
283 | 0 | } |
284 | 0 | } |
285 | |
|
286 | 0 | return ret; |
287 | 0 | } |
288 | | |
289 | | /* Removes the node at the index from the stack and returns data. |
290 | | * |
291 | | * This is an internal API. |
292 | | * |
293 | | * @param [in, out] stack Stack of nodes. |
294 | | * @param [in] idx Index of node to remove. |
295 | | * @return Data in node on success. |
296 | | * @return NULL when no node at index or no data. |
297 | | */ |
298 | | void* wolfSSL_sk_pop_node(WOLFSSL_STACK* stack, int idx) |
299 | 0 | { |
300 | 0 | void* ret = NULL; |
301 | 0 | WOLFSSL_STACK* tmp = NULL; |
302 | 0 | WOLFSSL_STACK* prev; |
303 | | |
304 | | /* Validate parameters. */ |
305 | 0 | if ((stack != NULL) && (stack->num != 0)) { |
306 | 0 | stack->num--; |
307 | | /* Popping first node handled differently. */ |
308 | 0 | if (idx == 0 || stack->next == NULL) { |
309 | 0 | ret = wolfssl_sk_node_get_data(stack, 1); |
310 | | /* Clear out data if we are returning it. */ |
311 | 0 | if (ret != NULL) { |
312 | 0 | stack->data.generic = NULL; |
313 | 0 | } |
314 | 0 | if (stack->next) { |
315 | | /* Keep the first node as it is the pointer passed in. */ |
316 | 0 | tmp = stack->next; |
317 | 0 | XMEMCPY(stack, stack->next, sizeof(WOLFSSL_STACK)); |
318 | 0 | wolfSSL_sk_free_node(tmp); |
319 | 0 | } |
320 | 0 | } |
321 | 0 | else { |
322 | | /* Find node at index and take out it. */ |
323 | 0 | prev = stack; |
324 | 0 | tmp = stack->next; |
325 | 0 | while ((--idx != 0) && (tmp->next != NULL)) { |
326 | 0 | prev = tmp; |
327 | 0 | prev->num--; |
328 | 0 | tmp = tmp->next; |
329 | 0 | } |
330 | 0 | prev->next = tmp->next; |
331 | | |
332 | | /* Get data to return and free node only. */ |
333 | 0 | ret = wolfssl_sk_node_get_data(tmp, 1); |
334 | 0 | wolfSSL_sk_free_node(tmp); |
335 | 0 | } |
336 | 0 | } |
337 | |
|
338 | 0 | return ret; |
339 | 0 | } |
340 | | #endif /* NO_CERTS */ |
341 | | #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ |
342 | | |
343 | | /******************************************************************************* |
344 | | * SK APIs |
345 | | ******************************************************************************/ |
346 | | |
347 | | #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \ |
348 | | defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ |
349 | | defined(OPENSSL_ALL) || defined(WOLFSSL_QT) |
350 | | /* Creates a new stack of the requested type. |
351 | | * |
352 | | * This is an internal API. |
353 | | * |
354 | | * @param [in] type Type of stack. |
355 | | * @return Empty stack on success. |
356 | | * @return NULL when dynamic memory allocation fails. |
357 | | */ |
358 | | WOLFSSL_STACK* wolfssl_sk_new_type(WOLF_STACK_TYPE type) |
359 | 0 | { |
360 | 0 | return wolfssl_sk_new_type_ex(type, NULL); |
361 | 0 | } |
362 | | |
363 | | WOLFSSL_STACK* wolfssl_sk_new_type_ex(WOLF_STACK_TYPE type, void* heap) |
364 | 0 | { |
365 | 0 | WOLFSSL_STACK* stack = wolfSSL_sk_new_node(heap); |
366 | 0 | if (stack != NULL) { |
367 | 0 | stack->type = type; |
368 | 0 | } |
369 | 0 | return stack; |
370 | 0 | } |
371 | | #endif |
372 | | |
373 | | #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) |
374 | | /* Creates a new NULL type stack. |
375 | | * |
376 | | * This is an internal API. |
377 | | * |
378 | | * @return Empty stack on success. |
379 | | * @return NULL when dynamic memory allocation fails. |
380 | | */ |
381 | | WOLFSSL_STACK* wolfSSL_sk_new_null(void) |
382 | 0 | { |
383 | 0 | WOLFSSL_ENTER("wolfSSL_sk_new_null"); |
384 | |
|
385 | 0 | return wolfssl_sk_new_type(STACK_TYPE_NULL); |
386 | 0 | } |
387 | | |
388 | | /* Duplicate the data of a node into another. |
389 | | * |
390 | | * Limited too: STACK_TYPE_X509, STACK_TYPE_CIPHER, STACK_TYPE_GEN_NAME, |
391 | | * STACK_TYPE_OBJ, STACK_TYPE_X509_OBJ. |
392 | | * |
393 | | * @param [in, out] dst Destination node. |
394 | | * @param [in] src Source node. |
395 | | * @return 0 on success. |
396 | | * @return 1 when duplication failed or stack type is not supported. |
397 | | */ |
398 | | static int wolfssl_sk_dup_data(WOLFSSL_STACK* dst, WOLFSSL_STACK* src) |
399 | 0 | { |
400 | 0 | int err = 0; |
401 | |
|
402 | 0 | switch (src->type) { |
403 | 0 | case STACK_TYPE_X509: |
404 | 0 | if (src->data.x509 == NULL) { |
405 | 0 | break; |
406 | 0 | } |
407 | 0 | dst->data.x509 = wolfSSL_X509_dup(src->data.x509); |
408 | 0 | if (dst->data.x509 == NULL) { |
409 | 0 | WOLFSSL_MSG("wolfSSL_X509_dup error"); |
410 | 0 | err = 1; |
411 | 0 | break; |
412 | 0 | } |
413 | 0 | break; |
414 | 0 | case STACK_TYPE_CIPHER: |
415 | 0 | wolfSSL_CIPHER_copy(&src->data.cipher, &dst->data.cipher); |
416 | 0 | break; |
417 | 0 | case STACK_TYPE_GEN_NAME: |
418 | 0 | if (src->data.gn == NULL) { |
419 | 0 | break; |
420 | 0 | } |
421 | 0 | dst->data.gn = wolfSSL_GENERAL_NAME_dup(src->data.gn); |
422 | 0 | if (dst->data.gn == NULL) { |
423 | 0 | WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error"); |
424 | 0 | err = 1; |
425 | 0 | break; |
426 | 0 | } |
427 | 0 | break; |
428 | 0 | case STACK_TYPE_OBJ: |
429 | 0 | if (src->data.obj == NULL) { |
430 | 0 | break; |
431 | 0 | } |
432 | 0 | dst->data.obj = wolfSSL_ASN1_OBJECT_dup(src->data.obj); |
433 | 0 | if (dst->data.obj == NULL) { |
434 | 0 | WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup error"); |
435 | 0 | err = 1; |
436 | 0 | break; |
437 | 0 | } |
438 | 0 | break; |
439 | 0 | case STACK_TYPE_X509_CRL: |
440 | | #if defined(OPENSSL_EXTRA) && defined(HAVE_CRL) |
441 | | if (src->data.crl == NULL) { |
442 | | break; |
443 | | } |
444 | | dst->data.crl = wolfSSL_X509_CRL_dup(src->data.crl); |
445 | | if (dst->data.crl == NULL) { |
446 | | WOLFSSL_MSG("wolfSSL_X509_CRL_dup error"); |
447 | | err = 1; |
448 | | break; |
449 | | } |
450 | | #else |
451 | 0 | WOLFSSL_MSG("CRL support not enabled"); |
452 | 0 | err = 1; |
453 | 0 | #endif |
454 | 0 | break; |
455 | 0 | case STACK_TYPE_X509_OBJ: |
456 | 0 | #if defined(OPENSSL_ALL) |
457 | 0 | if (src->data.x509_obj == NULL) { |
458 | 0 | break; |
459 | 0 | } |
460 | 0 | dst->data.x509_obj = wolfSSL_X509_OBJECT_dup( |
461 | 0 | src->data.x509_obj); |
462 | 0 | if (dst->data.x509_obj == NULL) { |
463 | 0 | WOLFSSL_MSG("wolfSSL_X509_OBJECT_dup error"); |
464 | 0 | err = 1; |
465 | 0 | break; |
466 | 0 | } |
467 | | #else |
468 | | WOLFSSL_MSG("OPENSSL_ALL support not enabled"); |
469 | | err = 1; |
470 | | #endif |
471 | 0 | break; |
472 | 0 | case STACK_TYPE_BIO: |
473 | 0 | case STACK_TYPE_STRING: |
474 | 0 | case STACK_TYPE_ACCESS_DESCRIPTION: |
475 | 0 | case STACK_TYPE_X509_EXT: |
476 | 0 | case STACK_TYPE_X509_REQ_ATTR: |
477 | 0 | case STACK_TYPE_NULL: |
478 | 0 | case STACK_TYPE_X509_NAME: |
479 | 0 | case STACK_TYPE_X509_NAME_ENTRY: |
480 | 0 | case STACK_TYPE_CONF_VALUE: |
481 | 0 | case STACK_TYPE_X509_INFO: |
482 | 0 | case STACK_TYPE_BY_DIR_entry: |
483 | 0 | case STACK_TYPE_BY_DIR_hash: |
484 | 0 | case STACK_TYPE_DIST_POINT: |
485 | 0 | case STACK_TYPE_X509_REVOKED: |
486 | 0 | case STACK_TYPE_GENERAL_SUBTREE: |
487 | 0 | default: |
488 | 0 | WOLFSSL_MSG("Unsupported stack type"); |
489 | 0 | err = 1; |
490 | 0 | break; |
491 | 0 | } |
492 | | |
493 | 0 | return err; |
494 | 0 | } |
495 | | |
496 | | /* Duplicate the stack of nodes. |
497 | | * |
498 | | * OpenSSL does a shallow copy but we map to wolfSSL_shallow_sk_dup() |
499 | | * when we want a shallow copy. |
500 | | * |
501 | | * Data is copied/duplicated - deep copy. |
502 | | * |
503 | | * Limited too: STACK_TYPE_X509, STACK_TYPE_CIPHER, STACK_TYPE_GEN_NAME, |
504 | | * STACK_TYPE_OBJ, STACK_TYPE_X509_OBJ. |
505 | | * |
506 | | * @param [in, out] stack Stack of nodes. |
507 | | * @return A new stack of nodes with data duplicated/copied on success. |
508 | | * @return NULL on error. |
509 | | */ |
510 | | WOLFSSL_STACK* wolfSSL_sk_dup(WOLFSSL_STACK* stack) |
511 | 0 | { |
512 | 0 | WOLFSSL_STACK* ret = NULL; |
513 | 0 | WOLFSSL_STACK* last = NULL; |
514 | 0 | int err = 0; |
515 | |
|
516 | 0 | WOLFSSL_ENTER("wolfSSL_sk_dup"); |
517 | |
|
518 | 0 | for (; stack != NULL; stack = stack->next) { |
519 | | /* New node for duplicate stack. */ |
520 | 0 | WOLFSSL_STACK* cur = wolfSSL_sk_new_node(stack->heap); |
521 | 0 | if (cur == NULL) { |
522 | 0 | WOLFSSL_MSG("wolfSSL_sk_new_node error"); |
523 | 0 | err = 1; |
524 | 0 | break; |
525 | 0 | } |
526 | | |
527 | 0 | if (ret == NULL) { |
528 | | /* Keep the first node for returning. */ |
529 | 0 | ret = cur; |
530 | 0 | } |
531 | 0 | if (last != NULL) { |
532 | | /* Add new node to end of list. */ |
533 | 0 | last->next = cur; |
534 | 0 | } |
535 | | /* Update last node in linked list. */ |
536 | 0 | last = cur; |
537 | |
|
538 | 0 | XMEMCPY(cur, stack, sizeof(WOLFSSL_STACK)); |
539 | | /* We will allocate new memory for this */ |
540 | 0 | XMEMSET(&cur->data, 0, sizeof(cur->data)); |
541 | 0 | cur->next = NULL; |
542 | |
|
543 | 0 | err = wolfssl_sk_dup_data(cur, stack); |
544 | 0 | if (err) { |
545 | 0 | break; |
546 | 0 | } |
547 | 0 | } |
548 | |
|
549 | 0 | if (err && (ret != NULL)) { |
550 | 0 | wolfSSL_sk_pop_free(ret, NULL); |
551 | 0 | ret = NULL; |
552 | 0 | } |
553 | |
|
554 | 0 | return ret; |
555 | 0 | } |
556 | | |
557 | | /* Shallow duplicate a stack of nodes. |
558 | | * |
559 | | * @param [in] stack Stack of nodes. |
560 | | * @return A new stack of nodes with data duplicated/copied on success. |
561 | | * @return NULL on error. |
562 | | */ |
563 | | WOLFSSL_STACK* wolfSSL_shallow_sk_dup(WOLFSSL_STACK* stack) |
564 | 0 | { |
565 | |
|
566 | 0 | WOLFSSL_STACK* ret = NULL; |
567 | 0 | WOLFSSL_STACK** prev = &ret; |
568 | |
|
569 | 0 | WOLFSSL_ENTER("wolfSSL_shallow_sk_dup"); |
570 | |
|
571 | 0 | for (; stack != NULL; stack = stack->next) { |
572 | 0 | WOLFSSL_STACK* cur = wolfSSL_sk_new_node(stack->heap); |
573 | 0 | if (cur == NULL) { |
574 | 0 | WOLFSSL_MSG("wolfSSL_sk_new_node error"); |
575 | 0 | wolfSSL_sk_free(ret); |
576 | 0 | ret = NULL; |
577 | 0 | break; |
578 | 0 | } |
579 | | |
580 | 0 | XMEMCPY(cur, stack, sizeof(WOLFSSL_STACK)); |
581 | 0 | cur->next = NULL; |
582 | |
|
583 | 0 | *prev = cur; |
584 | 0 | prev = &cur->next; |
585 | 0 | } |
586 | |
|
587 | 0 | return ret; |
588 | 0 | } |
589 | | #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ |
590 | | |
591 | | #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \ |
592 | | defined(OPENSSL_ALL) |
593 | | /* Free the nodes in the stack only. |
594 | | * |
595 | | * @param [in] stack Stack of nodes. |
596 | | */ |
597 | | void wolfSSL_sk_free(WOLFSSL_STACK* stack) |
598 | 98.1k | { |
599 | 98.1k | WOLFSSL_ENTER("wolfSSL_sk_free"); |
600 | | |
601 | 136k | while (stack != NULL) { |
602 | 37.9k | WOLFSSL_STACK* next = stack->next; |
603 | 37.9k | wolfSSL_sk_free_node(stack); |
604 | 37.9k | stack = next; |
605 | 37.9k | } |
606 | 98.1k | } |
607 | | #endif |
608 | | |
609 | | #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \ |
610 | | defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_ALL) |
611 | | /* Get the number of nodes in the stack. |
612 | | * |
613 | | * @param [in] stack Stack of nodes. |
614 | | * @return Number of nodes in stack on success. |
615 | | * @return 0 when no nodes or stack is NULL. |
616 | | */ |
617 | | int wolfSSL_sk_num(const WOLFSSL_STACK* stack) |
618 | 0 | { |
619 | 0 | int num = 0; |
620 | |
|
621 | 0 | WOLFSSL_ENTER("wolfSSL_sk_num"); |
622 | |
|
623 | 0 | if (stack != NULL) { |
624 | 0 | num = (int)stack->num; |
625 | 0 | } |
626 | |
|
627 | 0 | return num; |
628 | 0 | } |
629 | | |
630 | | /* Get the value/data in a node from the stack at the index. |
631 | | * |
632 | | * If stack type is STACK_TYPE_CONF_VALUE and OPENSSL_EXTRA is not defined, |
633 | | * the value will be NULL. |
634 | | * |
635 | | * @param [in] stack Stack of nodes. |
636 | | * @param [in] i Index of node to get value/data. |
637 | | * @return Data in node at index on success. |
638 | | * @return NULL when no node at index. |
639 | | */ |
640 | | void* wolfSSL_sk_value(const WOLFSSL_STACK* sk, int i) |
641 | 0 | { |
642 | 0 | void* val; |
643 | |
|
644 | 0 | WOLFSSL_ENTER("wolfSSL_sk_value"); |
645 | |
|
646 | 0 | for (; (sk != NULL) && (i > 0); i--) { |
647 | 0 | sk = sk->next; |
648 | 0 | } |
649 | |
|
650 | 0 | if (sk == NULL) { |
651 | 0 | val = NULL; |
652 | 0 | } |
653 | 0 | else { |
654 | 0 | switch (sk->type) { |
655 | 0 | case STACK_TYPE_CIPHER: |
656 | 0 | val = (void*)&sk->data.cipher; |
657 | 0 | break; |
658 | 0 | case STACK_TYPE_CONF_VALUE: |
659 | | #ifndef OPENSSL_EXTRA |
660 | | val = NULL; |
661 | | break; |
662 | | #endif |
663 | 0 | case STACK_TYPE_X509: |
664 | 0 | case STACK_TYPE_GEN_NAME: |
665 | 0 | case STACK_TYPE_BIO: |
666 | 0 | case STACK_TYPE_OBJ: |
667 | 0 | case STACK_TYPE_STRING: |
668 | 0 | case STACK_TYPE_ACCESS_DESCRIPTION: |
669 | 0 | case STACK_TYPE_X509_EXT: |
670 | 0 | case STACK_TYPE_X509_REQ_ATTR: |
671 | 0 | case STACK_TYPE_NULL: |
672 | 0 | case STACK_TYPE_X509_NAME: |
673 | 0 | case STACK_TYPE_X509_NAME_ENTRY: |
674 | 0 | case STACK_TYPE_X509_INFO: |
675 | 0 | case STACK_TYPE_BY_DIR_entry: |
676 | 0 | case STACK_TYPE_BY_DIR_hash: |
677 | 0 | case STACK_TYPE_X509_OBJ: |
678 | 0 | case STACK_TYPE_DIST_POINT: |
679 | 0 | case STACK_TYPE_X509_CRL: |
680 | 0 | case STACK_TYPE_X509_REVOKED: |
681 | 0 | case STACK_TYPE_GENERAL_SUBTREE: |
682 | 0 | default: |
683 | 0 | val = sk->data.generic; |
684 | 0 | break; |
685 | 0 | } |
686 | 0 | } |
687 | | |
688 | 0 | return val; |
689 | 0 | } |
690 | | #endif |
691 | | |
692 | | #if (!defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || \ |
693 | | defined(WOLFSSL_WPAS_SMALL))) || defined(WOLFSSL_QT) || \ |
694 | | defined(OPENSSL_ALL) |
695 | | /* Put the data into a node at the end of the list. |
696 | | * |
697 | | * @param [in, out] stack Stack of objects. |
698 | | * @param [in] data Data to store in stack. |
699 | | * @return Number of nodes in stack on success. |
700 | | * @return WOLFSSL_FAILURE when data is NULL. |
701 | | * @return WOLFSSL_FATAL_ERROR when stack is NULL. |
702 | | */ |
703 | | int wolfSSL_sk_push(WOLFSSL_STACK* stack, const void *data) |
704 | 37.9k | { |
705 | 37.9k | WOLFSSL_ENTER("wolfSSL_sk_push"); |
706 | | |
707 | 37.9k | return wolfSSL_sk_insert(stack, data, -1); |
708 | 37.9k | } |
709 | | |
710 | | /* Put the data into a node at an index in the list. |
711 | | * |
712 | | * @param [in, out] stack Stack of objects. |
713 | | * @param [in] data Data to store in stack. |
714 | | * @return Number of nodes in stack on success. |
715 | | * @return WOLFSSL_FAILURE when data is NULL. |
716 | | * @return WOLFSSL_FATAL_ERROR when stack is NULL. |
717 | | */ |
718 | | int wolfSSL_sk_insert(WOLFSSL_STACK *stack, const void *data, int idx) |
719 | 37.9k | { |
720 | 37.9k | int ret; |
721 | 37.9k | WOLFSSL_STACK* node; |
722 | 37.9k | WOLFSSL_ENTER("wolfSSL_sk_insert"); |
723 | | |
724 | | /* Validate parameters. */ |
725 | 37.9k | if (stack == NULL) { |
726 | 0 | ret = WOLFSSL_FATAL_ERROR; |
727 | 0 | } |
728 | 37.9k | else if (data == NULL) { |
729 | 0 | ret = WOLFSSL_FAILURE; |
730 | 0 | } |
731 | 37.9k | else if (stack->num == 0) { |
732 | | /* No data set in stack - set data into empty first node. */ |
733 | 12.1k | wolfssl_sk_node_set_data(stack, stack->type, data); |
734 | 12.1k | stack->num = 1; |
735 | 12.1k | ret = 1; |
736 | 12.1k | } |
737 | 25.8k | else { |
738 | | /* Create a new node. */ |
739 | 25.8k | node = wolfSSL_sk_new_node(stack->heap); |
740 | 25.8k | if (node == NULL) { |
741 | 1 | WOLFSSL_MSG("Memory error"); |
742 | 1 | ret = WOLFSSL_FAILURE; |
743 | 1 | } |
744 | 25.8k | else { |
745 | | /* Place at front of linked-list. */ |
746 | 25.8k | if (idx == 0) { |
747 | | /* Special case where we need to change the values in the head |
748 | | * element to avoid changing the initial pointer. */ |
749 | 0 | XMEMCPY(node, stack, sizeof(WOLFSSL_STACK)); |
750 | 0 | wolfssl_sk_node_set_data(stack, stack->type, data); |
751 | 0 | stack->num++; |
752 | 0 | stack->next = node; |
753 | 0 | } |
754 | | /* Place new node with data into list. */ |
755 | 25.8k | else { |
756 | 25.8k | WOLFSSL_STACK* prev; |
757 | 25.8k | unsigned long num = stack->num; |
758 | | |
759 | 25.8k | node->type = stack->type; |
760 | 25.8k | #ifdef OPENSSL_ALL |
761 | 25.8k | node->hash_fn = stack->hash_fn; |
762 | 25.8k | #endif |
763 | | /* Put data into new node. */ |
764 | 25.8k | wolfssl_sk_node_set_data(node, stack->type, data); |
765 | | |
766 | | /* Update count as new node being placed after first. */ |
767 | 25.8k | stack->num++; |
768 | 25.8k | prev = stack; |
769 | 72.0k | while (((--idx) != 0) && (prev->next != NULL)) { |
770 | 46.2k | prev = prev->next; |
771 | | /* Update count as new node being placed after this one. */ |
772 | 46.2k | prev->num = num--; |
773 | 46.2k | } |
774 | | /* Set count for new node. */ |
775 | 25.8k | node->num = num; |
776 | | /* Place node in linked list after prev. */ |
777 | 25.8k | node->next = prev->next; |
778 | 25.8k | prev->next = node; |
779 | 25.8k | } |
780 | | |
781 | | /* Returning new stack count. */ |
782 | 25.8k | ret = (int)stack->num; |
783 | 25.8k | } |
784 | 25.8k | } |
785 | | |
786 | 37.9k | return ret; |
787 | 37.9k | } |
788 | | #endif |
789 | | |
790 | | #if !defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || \ |
791 | | defined(WOLFSSL_WPAS_SMALL)) |
792 | | /* Remove the top node from the stack and return its data. |
793 | | * |
794 | | * @param [in, out] stack Stack of nodes with data. |
795 | | * @return Data in top node on success. |
796 | | * @return NULL when stack is NULL or stack is empty. |
797 | | */ |
798 | | void* wolfSSL_sk_pop(WOLFSSL_STACK* stack) |
799 | 0 | { |
800 | 0 | WOLFSSL_ENTER("wolfSSL_sk_pop"); |
801 | |
|
802 | 0 | return wolfSSL_sk_pop_node(stack, -1); |
803 | 0 | } |
804 | | |
805 | | #endif /* !NO_CERTS && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */ |
806 | | |
807 | | #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) |
808 | | /* Pop off data from the stack. Checks that the type matches the stack type. |
809 | | * |
810 | | * This is an internal API. |
811 | | * |
812 | | * @param [in, out] stack Stack of data. |
813 | | * @param [in] type Type of stack. |
814 | | * @return Data on success. |
815 | | * @return NULL when stack is NULL or no nodes left in stack. |
816 | | */ |
817 | | void* wolfssl_sk_pop_type(WOLFSSL_STACK* stack, WOLF_STACK_TYPE type) |
818 | 0 | { |
819 | 0 | void* data = NULL; |
820 | | |
821 | | /* Check we have a stack passed in of the right type. */ |
822 | 0 | if ((stack != NULL) && (stack->type == type)) |
823 | 0 | data = wolfSSL_sk_pop(stack); |
824 | |
|
825 | 0 | return data; |
826 | 0 | } |
827 | | #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ |
828 | | |
829 | | #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \ |
830 | | defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_ALL) |
831 | | /* Get the free function for the stack type. |
832 | | * |
833 | | * @param [in] type Type of stack object. |
834 | | * @return A free function on success. |
835 | | * @return NULL when no free function to use. |
836 | | */ |
837 | | static wolfSSL_sk_freefunc wolfssl_sk_get_free_func(WOLF_STACK_TYPE type) |
838 | 298 | { |
839 | 298 | wolfSSL_sk_freefunc func = NULL; |
840 | | |
841 | 298 | switch(type) { |
842 | 0 | case STACK_TYPE_ACCESS_DESCRIPTION: |
843 | 0 | #if defined(OPENSSL_ALL) |
844 | 0 | func = (wolfSSL_sk_freefunc)wolfSSL_ACCESS_DESCRIPTION_free; |
845 | 0 | #endif |
846 | 0 | break; |
847 | 0 | case STACK_TYPE_X509: |
848 | 0 | func = (wolfSSL_sk_freefunc)wolfSSL_X509_free; |
849 | 0 | break; |
850 | 0 | case STACK_TYPE_X509_OBJ: |
851 | 0 | #ifdef OPENSSL_ALL |
852 | 0 | func = (wolfSSL_sk_freefunc)wolfSSL_X509_OBJECT_free; |
853 | 0 | #endif |
854 | 0 | break; |
855 | 0 | case STACK_TYPE_OBJ: |
856 | 0 | func = (wolfSSL_sk_freefunc)wolfSSL_ASN1_OBJECT_free; |
857 | 0 | break; |
858 | 0 | case STACK_TYPE_DIST_POINT: |
859 | 0 | #ifdef OPENSSL_EXTRA |
860 | 0 | func = (wolfSSL_sk_freefunc)wolfSSL_DIST_POINT_free; |
861 | 0 | #endif |
862 | 0 | break; |
863 | 0 | case STACK_TYPE_GEN_NAME: |
864 | 0 | func = (wolfSSL_sk_freefunc)wolfSSL_GENERAL_NAME_free; |
865 | 0 | break; |
866 | 0 | case STACK_TYPE_GENERAL_SUBTREE: |
867 | 0 | #if defined(OPENSSL_EXTRA) && !defined(IGNORE_NAME_CONSTRAINTS) |
868 | 0 | func = (wolfSSL_sk_freefunc)wolfSSL_GENERAL_SUBTREE_free; |
869 | 0 | #endif |
870 | 0 | break; |
871 | 0 | case STACK_TYPE_STRING: |
872 | 0 | #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ |
873 | 0 | defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) |
874 | 0 | func = (wolfSSL_sk_freefunc)wolfSSL_WOLFSSL_STRING_free; |
875 | 0 | #endif |
876 | 0 | break; |
877 | 298 | case STACK_TYPE_X509_NAME: |
878 | 298 | #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \ |
879 | 298 | && !defined(WOLFCRYPT_ONLY) |
880 | 298 | func = (wolfSSL_sk_freefunc)wolfSSL_X509_NAME_free; |
881 | 298 | #endif |
882 | 298 | break; |
883 | 0 | case STACK_TYPE_X509_NAME_ENTRY: |
884 | 0 | #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \ |
885 | 0 | && !defined(WOLFCRYPT_ONLY) |
886 | 0 | func = (wolfSSL_sk_freefunc)wolfSSL_X509_NAME_ENTRY_free; |
887 | 0 | #endif |
888 | 0 | break; |
889 | 0 | case STACK_TYPE_X509_EXT: |
890 | 0 | #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) |
891 | 0 | func = (wolfSSL_sk_freefunc)wolfSSL_X509_EXTENSION_free; |
892 | 0 | #endif |
893 | 0 | break; |
894 | 0 | case STACK_TYPE_X509_REQ_ATTR: |
895 | | #if defined(OPENSSL_ALL) && \ |
896 | | (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_REQ)) |
897 | | func = (wolfSSL_sk_freefunc)wolfSSL_X509_ATTRIBUTE_free; |
898 | | #endif |
899 | 0 | break; |
900 | 0 | case STACK_TYPE_CONF_VALUE: |
901 | 0 | #if defined(OPENSSL_ALL) |
902 | 0 | func = (wolfSSL_sk_freefunc)wolfSSL_X509V3_conf_free; |
903 | 0 | #endif |
904 | 0 | break; |
905 | 0 | case STACK_TYPE_X509_INFO: |
906 | 0 | #if defined(OPENSSL_ALL) |
907 | 0 | func = (wolfSSL_sk_freefunc)wolfSSL_X509_INFO_free; |
908 | 0 | #endif |
909 | 0 | break; |
910 | 0 | case STACK_TYPE_BIO: |
911 | 0 | #if !defined(NO_BIO) && defined(OPENSSL_EXTRA) |
912 | 0 | func = (wolfSSL_sk_freefunc)wolfSSL_BIO_vfree; |
913 | 0 | #endif |
914 | 0 | break; |
915 | 0 | case STACK_TYPE_BY_DIR_entry: |
916 | 0 | #if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && \ |
917 | 0 | !defined(NO_WOLFSSL_DIR) |
918 | 0 | func = (wolfSSL_sk_freefunc)wolfSSL_BY_DIR_entry_free; |
919 | 0 | #endif |
920 | 0 | break; |
921 | 0 | case STACK_TYPE_BY_DIR_hash: |
922 | 0 | #if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && \ |
923 | 0 | !defined(NO_WOLFSSL_DIR) |
924 | 0 | func = (wolfSSL_sk_freefunc)wolfSSL_BY_DIR_HASH_free; |
925 | 0 | #endif |
926 | 0 | break; |
927 | 0 | case STACK_TYPE_X509_CRL: |
928 | | #if defined(HAVE_CRL) && (defined(OPENSSL_EXTRA) || \ |
929 | | defined(WOLFSSL_WPAS_SMALL)) |
930 | | func = (wolfSSL_sk_freefunc)wolfSSL_X509_CRL_free; |
931 | | #endif |
932 | 0 | break; |
933 | 0 | case STACK_TYPE_X509_REVOKED: |
934 | | #if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) |
935 | | func = (wolfSSL_sk_freefunc)wolfSSL_X509_REVOKED_free; |
936 | | #endif |
937 | 0 | break; |
938 | 0 | case STACK_TYPE_CIPHER: |
939 | | /* Static copy kept in node. */ |
940 | 0 | case STACK_TYPE_NULL: |
941 | 0 | default: |
942 | 0 | break; |
943 | 298 | } |
944 | | |
945 | 298 | return func; |
946 | 298 | } |
947 | | |
948 | | /* Free all nodes and the dynamic data associated with them. |
949 | | * |
950 | | * This is an internal API. |
951 | | * |
952 | | * @param [in, out] sk Stack of objects. |
953 | | * @param [in] func Function to use to free objects. |
954 | | */ |
955 | | void wolfSSL_sk_pop_free(WOLFSSL_STACK* stack, wolfSSL_sk_freefunc func) |
956 | 516k | { |
957 | 516k | WOLFSSL_ENTER("wolfSSL_sk_pop_free"); |
958 | | |
959 | | /* Validate parameters. */ |
960 | 516k | if (stack == NULL) { |
961 | | /* pop_free can be called with NULL, do not print bad argument */ |
962 | 515k | return; |
963 | 515k | } |
964 | | #if defined(WOLFSSL_QT) |
965 | | /* In Qt v15.5, it calls OPENSSL_sk_free(xxx, OPENSSL_sk_free). |
966 | | * By using OPENSSL_sk_free for free causes access violation. |
967 | | * Therefore, switching free func to wolfSSL_ACCESS_DESCRIPTION_free |
968 | | * is needed even when func isn't NULL. |
969 | | */ |
970 | | if (stack->type == STACK_TYPE_ACCESS_DESCRIPTION) { |
971 | | func = (wolfSSL_sk_freefunc)wolfSSL_ACCESS_DESCRIPTION_free; |
972 | | } |
973 | | #endif |
974 | | /* Discover free function if none provided. */ |
975 | 298 | if (func == NULL) { |
976 | 298 | func = wolfssl_sk_get_free_func(stack->type); |
977 | 298 | } |
978 | | |
979 | | /* Free all nodes and data. */ |
980 | 597 | while (stack != NULL) { |
981 | 299 | WOLFSSL_STACK* next = stack->next; |
982 | | |
983 | | /* Free the data of the node. */ |
984 | 299 | if ((func != NULL) && (stack->type != STACK_TYPE_CIPHER)) { |
985 | 299 | func(stack->data.generic); |
986 | 299 | } |
987 | | /* Dispose of node. */ |
988 | 299 | XFREE(stack, stack->heap, DYNAMIC_TYPE_OPENSSL); |
989 | 299 | stack = next; |
990 | 299 | } |
991 | 298 | } |
992 | | #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ |
993 | | |
994 | | /******************************************************************************* |
995 | | * Stack - Generic |
996 | | ******************************************************************************/ |
997 | | |
998 | | #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) |
999 | | /* Free the nodes in the stack only. |
1000 | | * |
1001 | | * @param [in] stack Stack of nodes. |
1002 | | */ |
1003 | | void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK* sk) |
1004 | 0 | { |
1005 | 0 | wolfSSL_sk_free(sk); |
1006 | 0 | } |
1007 | | |
1008 | | /* Free all nodes and the dynamic data associated with them. |
1009 | | * |
1010 | | * This is an internal API. |
1011 | | * |
1012 | | * @param [in, out] sk Stack of objects. |
1013 | | * @param [in] func Function to use to free objects. |
1014 | | */ |
1015 | | void wolfSSL_sk_GENERIC_pop_free(WOLFSSL_STACK* sk, void (*f) (void*)) |
1016 | 0 | { |
1017 | 0 | WOLFSSL_ENTER("wolfSSL_sk_GENERIC_pop_free"); |
1018 | 0 | wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f); |
1019 | 0 | } |
1020 | | |
1021 | | /* Put the data into a node at the top of the stack. |
1022 | | * |
1023 | | * @param [in, out] stack Stack of objects. |
1024 | | * @param [in] data Data to store in stack. |
1025 | | * @return Number of nodes in stack on success. |
1026 | | * @return WOLFSSL_FAILURE when data is NULL. |
1027 | | * @return WOLFSSL_FATAL_ERROR when stack is NULL. |
1028 | | */ |
1029 | | int wolfSSL_sk_GENERIC_push(WOLFSSL_STACK* sk, void* generic) |
1030 | 0 | { |
1031 | 0 | WOLFSSL_ENTER("wolfSSL_sk_GENERIC_push"); |
1032 | |
|
1033 | 0 | return wolfSSL_sk_push(sk, generic); |
1034 | 0 | } |
1035 | | #endif |
1036 | | |
1037 | | /******************************************************************************* |
1038 | | * Stack - Compression |
1039 | | ******************************************************************************/ |
1040 | | |
1041 | | #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) |
1042 | | /* Get the number of compression algorithms in stack. |
1043 | | * |
1044 | | * @param [in] stack Stack of compression algorithms. |
1045 | | * @return Number of compression algorithms in stack on success. |
1046 | | * @return 0 when no compression algorithms or stack is NULL. |
1047 | | */ |
1048 | | int wolfSSL_sk_SSL_COMP_num(WOLF_STACK_OF(WOLFSSL_COMP)* stack) |
1049 | 0 | { |
1050 | 0 | return wolfSSL_sk_num(stack); |
1051 | 0 | } |
1052 | | #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ |
1053 | | |
1054 | | #if defined(OPENSSL_EXTRA) && !defined(NO_WOLFSSL_STUB) |
1055 | | /* Remove all compression algorithms from stack. |
1056 | | * |
1057 | | * TBD |
1058 | | * Used when |
1059 | | * wolfSSL_set_options(ssl, SSL_OP_NO_COMPRESSION); |
1060 | | * is called. |
1061 | | * |
1062 | | * @param [in, out] stack Stack of compression algorithms. |
1063 | | * @return WOLFSSL_FAILURE always. |
1064 | | */ |
1065 | | int wolfSSL_sk_SSL_COMP_zero(WOLFSSL_STACK* stack) |
1066 | 0 | { |
1067 | 0 | (void)stack; |
1068 | 0 | WOLFSSL_STUB("wolfSSL_sk_SSL_COMP_zero"); |
1069 | 0 | return WOLFSSL_FAILURE; |
1070 | 0 | } |
1071 | | #endif |
1072 | | |
1073 | | /******************************************************************************* |
1074 | | * Stack - Cipher |
1075 | | ******************************************************************************/ |
1076 | | |
1077 | | #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) |
1078 | | /* Creates a new stack of ciphers. |
1079 | | * |
1080 | | * This is not an OpenSSL API. |
1081 | | * |
1082 | | * @return Empty stack on success. |
1083 | | * @return NULL when dynamic memory allocation fails. |
1084 | | */ |
1085 | | WOLFSSL_STACK* wolfSSL_sk_new_cipher(void) |
1086 | 0 | { |
1087 | 0 | return wolfssl_sk_new_type(STACK_TYPE_CIPHER); |
1088 | 0 | } |
1089 | | |
1090 | | /* Put the cipher into a node at the top of the stack. |
1091 | | * |
1092 | | * This is an internal API. |
1093 | | * |
1094 | | * @param [in, out] stack Stack of ciphers. |
1095 | | * @param [in] cipher Cipher to store in stack. |
1096 | | * @return Number of ciphers in stack on success. |
1097 | | * @return WOLFSSL_FAILURE when data is NULL. |
1098 | | * @return WOLFSSL_FATAL_ERROR when stack is NULL. |
1099 | | */ |
1100 | | int wolfSSL_sk_CIPHER_push(WOLF_STACK_OF(WOLFSSL_CIPHER)* stack, |
1101 | | WOLFSSL_CIPHER* cipher) |
1102 | 0 | { |
1103 | 0 | return wolfSSL_sk_push(stack, cipher); |
1104 | 0 | } |
1105 | | |
1106 | | #ifndef NO_WOLFSSL_STUB |
1107 | | /* Does not do anythting at this time. |
1108 | | * |
1109 | | * @param [in, out] stack Stack of nodes with data. |
1110 | | * @return NULL always. |
1111 | | */ |
1112 | | WOLFSSL_CIPHER* wolfSSL_sk_CIPHER_pop(WOLF_STACK_OF(WOLFSSL_CIPHER)* stack) |
1113 | 0 | { |
1114 | 0 | WOLFSSL_STUB("wolfSSL_sk_CIPHER_pop"); |
1115 | 0 | (void)stack; |
1116 | 0 | return NULL; |
1117 | 0 | } |
1118 | | #endif /* NO_WOLFSSL_STUB */ |
1119 | | #endif /* WOLFSSL_QT || OPENSSL_ALL */ |
1120 | | |
1121 | | #if defined(OPENSSL_EXTRA) |
1122 | | /* Free the nodes in the stack only. |
1123 | | * |
1124 | | * Ciphers are stored into a structure in a node and therefore don't need to be |
1125 | | * freed. |
1126 | | * |
1127 | | * @param [in] ciphers Stack of ciphers. |
1128 | | */ |
1129 | | void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* ciphers) |
1130 | 85.9k | { |
1131 | 85.9k | WOLFSSL_ENTER("wolfSSL_sk_CIPHER_free"); |
1132 | | |
1133 | 85.9k | wolfSSL_sk_free(ciphers); |
1134 | 85.9k | } |
1135 | | #endif /* OPENSSL_ALL */ |
1136 | | |
1137 | | #ifdef OPENSSL_EXTRA |
1138 | | /* Get the number of ciphers in the stack. |
1139 | | * |
1140 | | * @param [in] ciphers Stack of ciphers. |
1141 | | * @return Number of strings in stack on success. |
1142 | | * @return 0 when no strings or stack is NULL. |
1143 | | */ |
1144 | | int wolfSSL_sk_SSL_CIPHER_num(const WOLF_STACK_OF(WOLFSSL_CIPHER)* ciphers) |
1145 | 0 | { |
1146 | 0 | WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_num"); |
1147 | 0 | return wolfSSL_sk_num(ciphers); |
1148 | 0 | } |
1149 | | |
1150 | | /* Get the cipher from the stack at the index. |
1151 | | * |
1152 | | * @param [in] ciphers Stack of cihers |
1153 | | * @param [in] i Index of node to get cipher from. |
1154 | | * @return Cipher in node at index on success. |
1155 | | * @return NULL when no node at index. |
1156 | | */ |
1157 | | WOLFSSL_CIPHER* wolfSSL_sk_SSL_CIPHER_value(WOLFSSL_STACK* ciphers, int i) |
1158 | 0 | { |
1159 | 0 | WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_value"); |
1160 | 0 | return (WOLFSSL_CIPHER*)wolfSSL_sk_value(ciphers, i); |
1161 | 0 | } |
1162 | | #endif |
1163 | | |
1164 | | #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) |
1165 | | /* Get the priority level of the cipher if it is in the stack. |
1166 | | * |
1167 | | * Priority level is the number of ciphers minus the idex of the cipher. |
1168 | | * |
1169 | | * @param [in] ciphers Stack of ciphers. |
1170 | | * @param [in] cipher Cipher to find in stack. |
1171 | | * @return Priority level of cipher on success. |
1172 | | * @return WOLFSSL_FATAL_ERROR (-1) on failure to match. |
1173 | | */ |
1174 | | int wolfSSL_sk_SSL_CIPHER_find(WOLF_STACK_OF(WOLFSSL_CIPHER)* ciphers, |
1175 | | const WOLFSSL_CIPHER* cipher) |
1176 | 0 | { |
1177 | 0 | int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR); |
1178 | |
|
1179 | 0 | if (ciphers != NULL && cipher != NULL) { |
1180 | 0 | int i; |
1181 | 0 | int num = wolfSSL_sk_SSL_CIPHER_num(ciphers); |
1182 | 0 | WOLFSSL_STACK* next = ciphers; |
1183 | |
|
1184 | 0 | for (i = 0; (i < num) && (next != NULL); i++) { |
1185 | | /* Match on SSL/TLS cipher suite values. */ |
1186 | 0 | if ((next->data.cipher.cipherSuite0 == cipher->cipherSuite0) && |
1187 | 0 | (next->data.cipher.cipherSuite == cipher->cipherSuite)) { |
1188 | | /* reverse because stack pushed highest on first */ |
1189 | 0 | ret = num - i; |
1190 | 0 | break; |
1191 | 0 | } |
1192 | 0 | next = next->next; |
1193 | 0 | } |
1194 | 0 | } |
1195 | |
|
1196 | 0 | return ret; |
1197 | 0 | } |
1198 | | |
1199 | | /* Free the nodes in the stack only. |
1200 | | * |
1201 | | * @param [in] ciphers Stack of ciphers. |
1202 | | */ |
1203 | | void wolfSSL_sk_SSL_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk) |
1204 | 0 | { |
1205 | 0 | WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_free"); |
1206 | 0 | wolfSSL_sk_free(sk); |
1207 | 0 | } |
1208 | | #endif /* OPENSSL_ALL || OPENSSL_EXTRA */ |
1209 | | |
1210 | | /******************************************************************************* |
1211 | | * Stack - String |
1212 | | ******************************************************************************/ |
1213 | | |
1214 | | #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ |
1215 | | defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) |
1216 | | /* Creates a new stack of strings. |
1217 | | * |
1218 | | * @return Empty stack on success. |
1219 | | * @return NULL when dynamic memory allocation fails. |
1220 | | */ |
1221 | | WOLF_STACK_OF(WOLFSSL_STRING)* wolfSSL_sk_WOLFSSL_STRING_new(void) |
1222 | 0 | { |
1223 | 0 | return wolfssl_sk_new_type(STACK_TYPE_STRING); |
1224 | 0 | } |
1225 | | |
1226 | | /* Free the nodes and strings of the stack. |
1227 | | * |
1228 | | * OpenSSL equivalent does not free data. |
1229 | | * |
1230 | | * @param [in] strings Stack of strings. |
1231 | | */ |
1232 | | void wolfSSL_sk_WOLFSSL_STRING_free(WOLF_STACK_OF(WOLFSSL_STRING)* strings) |
1233 | 0 | { |
1234 | 0 | WOLFSSL_ENTER("wolfSSL_sk_WOLFSSL_STRING_free"); |
1235 | |
|
1236 | 0 | wolfSSL_sk_pop_free(strings, NULL); |
1237 | 0 | } |
1238 | | |
1239 | | /* Get the string from the node at an index. |
1240 | | * |
1241 | | * @param [in] strings Stack of strings. |
1242 | | * @param [in] idx Index of node. |
1243 | | * @return String in node at index on success. |
1244 | | * @return NULL when no node at index. |
1245 | | */ |
1246 | | WOLFSSL_STRING wolfSSL_sk_WOLFSSL_STRING_value( |
1247 | | WOLF_STACK_OF(WOLFSSL_STRING)* strings, int idx) |
1248 | 0 | { |
1249 | 0 | return (WOLFSSL_STRING)wolfSSL_sk_value(strings, idx); |
1250 | 0 | } |
1251 | | |
1252 | | /* Get the number of strings in the stack. |
1253 | | * |
1254 | | * @param [in] strings Stack of strings. |
1255 | | * @return Number of strings in stack on success. |
1256 | | * @return 0 when no strings or stack is NULL. |
1257 | | */ |
1258 | | int wolfSSL_sk_WOLFSSL_STRING_num(WOLF_STACK_OF(WOLFSSL_STRING)* strings) |
1259 | 0 | { |
1260 | 0 | return wolfSSL_sk_num(strings); |
1261 | 0 | } |
1262 | | #endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */ |
1263 | | |
1264 | | /******************************************************************************* |
1265 | | * Stack - Linear Hash |
1266 | | ******************************************************************************/ |
1267 | | |
1268 | | #if !defined(NO_CERTS) && defined(OPENSSL_EXTRA) && defined(OPENSSL_ALL) |
1269 | | /* Retrieve data from the stack by comparing with hash. |
1270 | | * |
1271 | | * @param [in] stack Stack of data. |
1272 | | * @param [in] data Data to look-up. |
1273 | | * @return Data of node with the same hash as data passed in. |
1274 | | * @return NULL when no match found. |
1275 | | */ |
1276 | | void *wolfSSL_lh_retrieve(WOLFSSL_STACK *stack, void *data) |
1277 | 0 | { |
1278 | 0 | unsigned long hash; |
1279 | 0 | void* sk_data = NULL; |
1280 | |
|
1281 | 0 | WOLFSSL_ENTER("wolfSSL_lh_retrieve"); |
1282 | | |
1283 | | /* Validate parameters. */ |
1284 | 0 | if ((stack == NULL) || (data == NULL)) { |
1285 | 0 | WOLFSSL_MSG("Bad parameters"); |
1286 | 0 | } |
1287 | 0 | else if (stack->hash_fn == NULL) { |
1288 | 0 | WOLFSSL_MSG("No hash function defined"); |
1289 | 0 | } |
1290 | 0 | else { |
1291 | | /* Calculate hassh of data we are looking for. */ |
1292 | 0 | hash = stack->hash_fn(data); |
1293 | |
|
1294 | 0 | while (stack != NULL) { |
1295 | | /* Calculate hash if not done so yet. */ |
1296 | 0 | if (!stack->hash) { |
1297 | 0 | sk_data = wolfssl_sk_node_get_data(stack, 0); |
1298 | 0 | stack->hash = stack->hash_fn(sk_data); |
1299 | 0 | } |
1300 | | /* Return data if hash matches. */ |
1301 | 0 | if (stack->hash == hash) { |
1302 | 0 | if (sk_data == NULL) { |
1303 | 0 | sk_data = wolfssl_sk_node_get_data(stack, 0); |
1304 | 0 | } |
1305 | 0 | break; |
1306 | 0 | } |
1307 | | |
1308 | | /* Not data to return. */ |
1309 | 0 | sk_data = NULL; |
1310 | 0 | stack = stack->next; |
1311 | 0 | } |
1312 | 0 | } |
1313 | |
|
1314 | 0 | return sk_data; |
1315 | 0 | } |
1316 | | #endif /* !NO_CERTS && OPENSSL_EXTRA && OPENSSL_ALL */ |
1317 | | |
1318 | | #endif /* !WOLFSSL_SSL_SK_INCLUDED */ |