Stack API: Pull out implementation into separate file

General stack APIs pulled out into ssl_sk.c.
Other simple APIs also pulled out into ssl_sk.c.
wolfSSL_lh_retrieve also pulled out into ssl_sk.c.

Added tests of public APIs that weren't already tested.
This commit is contained in:
Sean Parkinson
2025-10-27 15:27:40 +10:00
parent d54f5e7c6a
commit 093cc04076
19 changed files with 1885 additions and 1081 deletions

View File

@@ -2682,16 +2682,17 @@ if(WOLFSSL_EXAMPLES)
tests/api/test_pkcs7.c
tests/api/test_pkcs12.c
tests/api/test_ossl_asn1.c
tests/api/test_ossl_bn.c
tests/api/test_ossl_bio.c
tests/api/test_ossl_dgst.c
tests/api/test_ossl_mac.c
tests/api/test_ossl_bn.c
tests/api/test_ossl_cipher.c
tests/api/test_ossl_rsa.c
tests/api/test_ossl_dh.c
tests/api/test_ossl_dgst.c
tests/api/test_ossl_dsa.c
tests/api/test_ossl_ec.c
tests/api/test_ossl_ecx.c
tests/api/test_ossl_dsa.c
tests/api/test_ossl_mac.c
tests/api/test_ossl_rsa.c
tests/api/test_ossl_sk.c
tests/api/test_tls13.c
tests/srp.c
tests/suites.c

View File

@@ -22,3 +22,4 @@ Updates to Espressif ESP-IDF wolfssl_benchmark and wolfssl_test examples:
- Added optional `time_helper` for wolfssl_test
- Exclude `ssl_misc.c` in component cmake to fix warning: #warning ssl_misc.c does not need to be compiled separately from ssl.c
- Exclude `ssl_crypto.c` in component cmake to fix warning: #warning ssl_crypto.c does not need to be compiled separately from ssl.c
- Exclude `ssl_sk.c` in component cmake to fix warning: #warning ssl_sk.c does not need to be compiled separately from ssl.c

View File

@@ -845,6 +845,7 @@ else()
"\"${WOLFSSL_ROOT}/src/ssl_misc.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/ssl_p7p12.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/ssl_sess.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/ssl_sk.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/x509.c\""
"\"${WOLFSSL_ROOT}/src/x509_str.c\""
"\"${WOLFSSL_ROOT}/wolfcrypt/src/ext_kyber.c\"" # external non-wolfssl Kyber disabled by default

View File

@@ -845,6 +845,7 @@ else()
"\"${WOLFSSL_ROOT}/src/ssl_misc.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/ssl_p7p12.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/ssl_sess.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/ssl_sk.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/x509.c\""
"\"${WOLFSSL_ROOT}/src/x509_str.c\""
"\"${WOLFSSL_ROOT}/wolfcrypt/src/ext_kyber.c\"" # external non-wolfssl Kyber disabled by default

View File

@@ -845,6 +845,7 @@ else()
"\"${WOLFSSL_ROOT}/src/ssl_misc.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/ssl_p7p12.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/ssl_sess.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/ssl_sk.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/x509.c\""
"\"${WOLFSSL_ROOT}/src/x509_str.c\""
"\"${WOLFSSL_ROOT}/wolfcrypt/src/ext_kyber.c\"" # external non-wolfssl Kyber disabled by default

View File

@@ -845,6 +845,7 @@ else()
"\"${WOLFSSL_ROOT}/src/ssl_misc.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/ssl_p7p12.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/ssl_sess.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/ssl_sk.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/x509.c\""
"\"${WOLFSSL_ROOT}/src/x509_str.c\""
"\"${WOLFSSL_ROOT}/wolfcrypt/src/ext_kyber.c\"" # external non-wolfssl Kyber disabled by default

View File

@@ -845,6 +845,7 @@ else()
"\"${WOLFSSL_ROOT}/src/ssl_misc.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/ssl_p7p12.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/ssl_sess.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/ssl_sk.c\"" # included by ssl.c
"\"${WOLFSSL_ROOT}/src/x509.c\""
"\"${WOLFSSL_ROOT}/src/x509_str.c\""
"\"${WOLFSSL_ROOT}/wolfcrypt/src/ext_kyber.c\"" # external non-wolfssl Kyber disabled by default

View File

@@ -79,6 +79,7 @@ set(COMPONENT_SRCEXCLUDE
"./src/ssl_misc.c" # included by ssl.c
"./src/ssl_p7p12.c" # included by ssl.c
"./src/ssl_sess.c" # included by ssl.c
"./src/ssl_sk.c" # included by ssl.c
"./src/x509.c"
"./src/x509_str.c"
"./wolfcrypt/src/evp.c"

View File

@@ -61,6 +61,10 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|INtime'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|INtime'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ssl_sk.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|INtime'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|INtime'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\tls13.c" />
<ClCompile Include="..\..\src\x509.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|INtime'">true</ExcludedFromBuild>
@@ -360,4 +364,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@@ -45,6 +45,7 @@ list( REMOVE_ITEM SSL_SOURCES ../../../src/ssl_load.c )
list( REMOVE_ITEM SSL_SOURCES ../../../src/ssl_misc.c )
list( REMOVE_ITEM SSL_SOURCES ../../../src/ssl_p7p12.c )
list( REMOVE_ITEM SSL_SOURCES ../../../src/ssl_sess.c )
list( REMOVE_ITEM SSL_SOURCES ../../../src/ssl_sk.c )
aux_source_directory( ${CRYPTO_SRC_DIR} CRYPTO_SOURCES )
list( REMOVE_ITEM CRYPTO_SOURCES ../../../wolfcrypt/src/evp.c )
list( REMOVE_ITEM CRYPTO_SOURCES ../../../wolfcrypt/src/misc.c )

View File

@@ -25,6 +25,7 @@ EXTRA_DIST += src/ssl_load.c
EXTRA_DIST += src/ssl_misc.c
EXTRA_DIST += src/ssl_p7p12.c
EXTRA_DIST += src/ssl_sess.c
EXTRA_DIST += src/ssl_sk.c
EXTRA_DIST += src/x509.c
EXTRA_DIST += src/x509_str.c

1108
src/ssl.c

File diff suppressed because it is too large Load Diff

1251
src/ssl_sk.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -227,6 +227,7 @@
#include <tests/api/test_ossl_ec.h>
#include <tests/api/test_ossl_ecx.h>
#include <tests/api/test_ossl_dsa.h>
#include <tests/api/test_ossl_sk.h>
#include <tests/api/test_tls13.h>
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
@@ -50870,6 +50871,8 @@ TEST_CASE testCases[] = {
TEST_OSSL_ASN1_TIME_DECLS,
TEST_OSSL_ASN1_TYPE_DECLS,
TEST_SSL_SK_DECLS,
TEST_DECL(test_wolfSSL_lhash),
TEST_DECL(test_wolfSSL_certs),

View File

@@ -77,6 +77,7 @@ tests_unit_test_SOURCES += tests/api/test_ossl_dh.c
tests_unit_test_SOURCES += tests/api/test_ossl_ec.c
tests_unit_test_SOURCES += tests/api/test_ossl_ecx.c
tests_unit_test_SOURCES += tests/api/test_ossl_dsa.c
tests_unit_test_SOURCES += tests/api/test_ossl_sk.c
# TLS 1.3 specific
tests_unit_test_SOURCES += tests/api/test_tls13.c
endif
@@ -145,5 +146,6 @@ EXTRA_DIST += tests/api/test_ossl_dh.h
EXTRA_DIST += tests/api/test_ossl_ec.h
EXTRA_DIST += tests/api/test_ossl_ecx.h
EXTRA_DIST += tests/api/test_ossl_dsa.h
EXTRA_DIST += tests/api/test_ossl_sk.h
EXTRA_DIST += tests/api/test_tls13.h

487
tests/api/test_ossl_sk.c Normal file
View File

@@ -0,0 +1,487 @@
/* test_ossl_sk.c
*
* Copyright (C) 2006-2025 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <tests/unit.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif
#include <wolfssl/ssl.h>
#include <wolfssl/openssl/lhash.h>
#include <tests/api/api.h>
#include <tests/api/test_ossl_sk.h>
int test_wolfSSL_sk_new_free_node(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
WOLFSSL_STACK* node = NULL;
wolfSSL_sk_free_node(NULL);
ExpectNotNull(node = wolfSSL_sk_new_node(HEAP_HINT));
wolfSSL_sk_free_node(node);
#endif
return EXPECT_RESULT();
}
int test_wolfSSL_sk_push_get_node(void)
{
EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) && \
!defined(NO_CERTS)
WOLFSSL_STACK* stack = NULL;
WOLFSSL_STACK* node1 = NULL;
WOLFSSL_STACK* node2 = NULL;
WOLFSSL_STACK* node;
ExpectNotNull(node1 = wolfSSL_sk_new_node(HEAP_HINT));
ExpectNotNull(node2 = wolfSSL_sk_new_node(HEAP_HINT));
ExpectNull(wolfSSL_sk_get_node(NULL, -1));
ExpectNull(wolfSSL_sk_get_node(stack, -1));
ExpectIntEQ(wolfSSL_sk_push_node(NULL, NULL), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_sk_push_node(&stack, NULL), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_sk_push_node(NULL, node1), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_sk_push_node(&stack, node1), WOLFSSL_SUCCESS);
ExpectPtrEq(stack, node1);
ExpectIntEQ(wolfSSL_sk_push_node(&stack, node2), WOLFSSL_SUCCESS);
ExpectPtrEq(stack, node2);
ExpectNull(wolfSSL_sk_get_node(stack, -1));
ExpectNull(wolfSSL_sk_get_node(stack, 2));
ExpectNotNull(node = wolfSSL_sk_get_node(stack, 1));
ExpectPtrEq(node, node1);
ExpectNotNull(node = wolfSSL_sk_get_node(stack, 0));
ExpectPtrEq(node, node2);
wolfSSL_sk_free_node(node2);
wolfSSL_sk_free_node(node1);
#endif
return EXPECT_RESULT();
}
int test_wolfSSL_sk_free(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
WOLFSSL_STACK* stack = NULL;
wolfSSL_sk_free(NULL);
/* If there is ever a public API that creates a stack with the same ifdef
* protection then use it here instead of wolfSSL_sk_new_node(). */
ExpectNotNull(stack = wolfSSL_sk_new_node(HEAP_HINT));
wolfSSL_sk_free(stack);
#endif
return EXPECT_RESULT();
}
int test_wolfSSL_sk_push_pop(void)
{
EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) && \
!defined(NO_CERTS)
WOLFSSL_STACK* stack = NULL;
unsigned char data_1[1] = { 1 };
unsigned char data_2[1] = { 2 };
unsigned char data_3[1] = { 3 };
/* If there is ever a public API that creates a stack with the same ifdef
* protection then use it here instead of wolfSSL_sk_new_node(). */
ExpectNotNull(stack = wolfSSL_sk_new_node(HEAP_HINT));
/* First node created and now have something to put data onto. */
ExpectIntEQ(wolfSSL_sk_push(NULL , NULL ), WOLFSSL_FATAL_ERROR);
ExpectIntEQ(wolfSSL_sk_push(NULL , data_1), WOLFSSL_FATAL_ERROR);
ExpectIntEQ(wolfSSL_sk_push(stack, NULL ), WOLFSSL_FAILURE);
ExpectNull(wolfSSL_sk_pop(NULL));
ExpectIntEQ(wolfSSL_sk_push(stack, data_1), 1);
ExpectIntEQ(wolfSSL_sk_push(stack, data_2), 2);
ExpectIntEQ(wolfSSL_sk_push(stack, data_3), 3);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_3);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_2);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_1);
ExpectIntEQ(wolfSSL_sk_push(stack, data_3), 1);
ExpectIntEQ(wolfSSL_sk_push(stack, data_2), 2);
ExpectIntEQ(wolfSSL_sk_push(stack, data_1), 3);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_1);
ExpectIntEQ(wolfSSL_sk_push(stack, data_1), 3);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_1);
wolfSSL_sk_free(stack);
#endif
return EXPECT_RESULT();
}
int test_wolfSSL_sk_insert(void)
{
EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) && \
!defined(NO_CERTS)
WOLFSSL_STACK* stack = NULL;
unsigned char data_1[1] = { 1 };
unsigned char data_2[1] = { 2 };
unsigned char data_3[1] = { 3 };
/* If there is ever a public API that creates a stack with the same ifdef
* protection then use it here instead of wolfSSL_sk_new_node(). */
ExpectNotNull(stack = wolfSSL_sk_new_node(HEAP_HINT));
/* First node created and now have something to put data onto. */
ExpectIntEQ(wolfSSL_sk_insert(NULL , NULL , 0), WOLFSSL_FATAL_ERROR);
ExpectIntEQ(wolfSSL_sk_insert(NULL , data_1, 0), WOLFSSL_FATAL_ERROR);
ExpectIntEQ(wolfSSL_sk_insert(stack, NULL , 0), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_sk_insert(stack, data_1, 0), 1);
ExpectIntEQ(wolfSSL_sk_insert(stack, data_2, 0), 2);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_1);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_2);
/* Zero or negative creates a node at the bottom of the stack. */
ExpectIntEQ(wolfSSL_sk_insert(stack, data_1, -2), 1);
ExpectIntEQ(wolfSSL_sk_insert(stack, data_2, -2), 2);
ExpectIntEQ(wolfSSL_sk_insert(stack, data_3, -2), 3);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_3);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_2);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_1);
ExpectIntEQ(wolfSSL_sk_insert(stack, data_1, 0), 1);
ExpectIntEQ(wolfSSL_sk_insert(stack, data_2, 1), 2);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_2);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_1);
ExpectIntEQ(wolfSSL_sk_insert(stack, data_1, 1), 1);
ExpectIntEQ(wolfSSL_sk_insert(stack, data_2, 0), 2);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_1);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_2);
ExpectIntEQ(wolfSSL_sk_insert(stack, data_1, 1), 1);
ExpectIntEQ(wolfSSL_sk_insert(stack, data_2, 1), 2);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_2);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_1);
ExpectIntEQ(wolfSSL_sk_insert(stack, data_1, 2), 1);
ExpectIntEQ(wolfSSL_sk_insert(stack, data_2, 1), 2);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_2);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_1);
ExpectIntEQ(wolfSSL_sk_insert(stack, data_1, 1), 1);
ExpectIntEQ(wolfSSL_sk_insert(stack, data_2, 2), 2);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_2);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_1);
wolfSSL_sk_free(stack);
#endif
return EXPECT_RESULT();
}
int test_wolfSSL_shallow_sk_dup(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
WOLFSSL_STACK* stack = NULL;
WOLFSSL_STACK* stack_dup = NULL;
unsigned char data_1[1] = { 1 };
unsigned char data_2[1] = { 2 };
unsigned char data_3[1] = { 3 };
ExpectNull(wolfSSL_shallow_sk_dup(NULL));
/* If there is ever a public API that creates a stack with the same ifdef
* protection then use it here instead of wolfSSL_sk_new_node(). */
ExpectNotNull(stack = wolfSSL_sk_new_node(HEAP_HINT));
/* First node created and now have something to put data onto. */
ExpectIntEQ(wolfSSL_sk_insert(stack, data_1, 0), 1);
ExpectIntEQ(wolfSSL_sk_insert(stack, data_2, 0), 2);
ExpectIntEQ(wolfSSL_sk_insert(stack, data_3, 0), 3);
ExpectNotNull(stack_dup = wolfSSL_shallow_sk_dup(stack));
ExpectPtrEq(wolfSSL_sk_pop(stack_dup), data_1);
ExpectPtrEq(wolfSSL_sk_pop(stack_dup), data_2);
ExpectPtrEq(wolfSSL_sk_pop(stack_dup), data_3);
wolfSSL_sk_free(stack_dup);
wolfSSL_sk_free(stack);
#endif
return EXPECT_RESULT();
}
int test_wolfSSL_sk_num(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
WOLFSSL_STACK* stack = NULL;
unsigned char data_1[1] = { 1 };
unsigned char data_2[1] = { 2 };
unsigned char data_3[1] = { 3 };
ExpectIntEQ(wolfSSL_sk_num(NULL), 0);
/* If there is ever a public API that creates a stack with the same ifdef
* protection then use it here instead of wolfSSL_sk_new_node(). */
ExpectNotNull(stack = wolfSSL_sk_new_node(HEAP_HINT));
/* First node created and now have something to put data onto. */
ExpectIntEQ(wolfSSL_sk_push(stack, data_1), 1);
ExpectIntEQ(wolfSSL_sk_num(stack), 1);
ExpectIntEQ(wolfSSL_sk_push(stack, data_2), 2);
ExpectIntEQ(wolfSSL_sk_num(stack), 2);
ExpectIntEQ(wolfSSL_sk_push(stack, data_3), 3);
ExpectIntEQ(wolfSSL_sk_num(stack), 3);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_3);
ExpectIntEQ(wolfSSL_sk_num(stack), 2);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_2);
ExpectIntEQ(wolfSSL_sk_num(stack), 1);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_1);
ExpectIntEQ(wolfSSL_sk_num(stack), 0);
ExpectIntEQ(wolfSSL_sk_push(stack, data_3), 1);
ExpectIntEQ(wolfSSL_sk_num(stack), 1);
ExpectIntEQ(wolfSSL_sk_push(stack, data_2), 2);
ExpectIntEQ(wolfSSL_sk_num(stack), 2);
ExpectIntEQ(wolfSSL_sk_push(stack, data_1), 3);
ExpectIntEQ(wolfSSL_sk_num(stack), 3);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_1);
ExpectIntEQ(wolfSSL_sk_num(stack), 2);
ExpectIntEQ(wolfSSL_sk_push(stack, data_1), 3);
ExpectIntEQ(wolfSSL_sk_num(stack), 3);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_1);
ExpectIntEQ(wolfSSL_sk_num(stack), 2);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_2);
ExpectIntEQ(wolfSSL_sk_num(stack), 1);
ExpectIntEQ(wolfSSL_sk_push(stack, data_2), 2);
ExpectIntEQ(wolfSSL_sk_num(stack), 2);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_2);
ExpectIntEQ(wolfSSL_sk_num(stack), 1);
ExpectPtrEq(wolfSSL_sk_pop(stack), data_3);
ExpectIntEQ(wolfSSL_sk_num(stack), 0);
wolfSSL_sk_free(stack);
#endif
return EXPECT_RESULT();
}
int test_wolfSSL_sk_value(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
WOLFSSL_STACK* stack = NULL;
unsigned char data_1[1] = { 1 };
unsigned char data_2[1] = { 2 };
unsigned char data_3[1] = { 3 };
/* If there is ever a public API that creates a stack with the same ifdef
* protection then use it here instead of wolfSSL_sk_new_node(). */
ExpectNotNull(stack = wolfSSL_sk_new_node(HEAP_HINT));
/* First node created and now have something to put data onto. */
ExpectNull(wolfSSL_sk_value(NULL, -1));
ExpectNull(wolfSSL_sk_value(NULL, 1));
ExpectNull(wolfSSL_sk_value(stack, -1));
ExpectNull(wolfSSL_sk_value(stack, 0));
ExpectIntEQ(wolfSSL_sk_push(stack, data_1), 1);
ExpectNull(wolfSSL_sk_value(stack, 1));
ExpectPtrEq(wolfSSL_sk_value(stack, 0), data_1);
ExpectIntEQ(wolfSSL_sk_push(stack, data_2), 2);
ExpectNull(wolfSSL_sk_value(stack, 2));
ExpectPtrEq(wolfSSL_sk_value(stack, 1), data_2);
ExpectPtrEq(wolfSSL_sk_value(stack, 0), data_1);
ExpectIntEQ(wolfSSL_sk_push(stack, data_3), 3);
ExpectNull(wolfSSL_sk_value(stack, 3));
ExpectPtrEq(wolfSSL_sk_value(stack, 2), data_3);
ExpectPtrEq(wolfSSL_sk_value(stack, 1), data_2);
ExpectPtrEq(wolfSSL_sk_value(stack, 0), data_1);
wolfSSL_sk_free(stack);
#endif
return EXPECT_RESULT();
}
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
static void test_sk_xfree(void* data)
{
XFREE(data, NULL, DYNAMIC_TYPE_OPENSSL);
}
#endif
int test_wolfssl_sk_GENERIC(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
WOLFSSL_STACK* stack = NULL;
unsigned char data_1[1] = { 1 };
unsigned char data_2[1] = { 2 };
unsigned char data_3[1] = { 3 };
char* str_1 = NULL;
/* If there is ever a public API that creates a stack with the same ifdef
* protection then use it here instead of wolfSSL_sk_new_node(). */
ExpectNotNull(stack = wolfSSL_sk_new_node(HEAP_HINT));
ExpectIntEQ(wolfSSL_sk_GENERIC_push(stack, data_1), 1);
ExpectNull(wolfSSL_sk_value(stack, 1));
ExpectPtrEq(wolfSSL_sk_value(stack, 0), data_1);
ExpectIntEQ(wolfSSL_sk_GENERIC_push(stack, data_2), 2);
ExpectNull(wolfSSL_sk_value(stack, 2));
ExpectPtrEq(wolfSSL_sk_value(stack, 1), data_2);
ExpectPtrEq(wolfSSL_sk_value(stack, 0), data_1);
ExpectIntEQ(wolfSSL_sk_GENERIC_push(stack, data_3), 3);
ExpectNull(wolfSSL_sk_value(stack, 3));
ExpectPtrEq(wolfSSL_sk_value(stack, 2), data_3);
ExpectPtrEq(wolfSSL_sk_value(stack, 1), data_2);
ExpectPtrEq(wolfSSL_sk_value(stack, 0), data_1);
wolfSSL_sk_GENERIC_free(stack);
stack = NULL;
/* If there is ever a public API that creates a stack with the same ifdef
* protection then use it here instead of wolfSSL_sk_new_node(). */
ExpectNotNull(stack = wolfSSL_sk_new_node(HEAP_HINT));
wolfSSL_sk_GENERIC_pop_free(stack, test_sk_xfree);
/* If there is ever a public API that creates a stack with the same ifdef
* protection then use it here instead of wolfSSL_sk_new_node(). */
ExpectNotNull(stack = wolfSSL_sk_new_node(HEAP_HINT));
ExpectNotNull(str_1 = (char*)XMALLOC(2, NULL, DYNAMIC_TYPE_OPENSSL));
if (EXPECT_SUCCESS()) {
XSTRNCPY(str_1, "1", 2);
}
ExpectIntEQ(wolfSSL_sk_GENERIC_push(stack, str_1), 1);
if (EXPECT_FAIL()) {
XFREE(str_1, NULL, DYNAMIC_TYPE_OPENSSL);
}
wolfSSL_sk_GENERIC_pop_free(NULL, NULL);
wolfSSL_sk_GENERIC_pop_free(NULL, test_sk_xfree);
wolfSSL_sk_GENERIC_pop_free(stack, test_sk_xfree);
#endif
return EXPECT_RESULT();
}
int test_wolfssl_sk_SSL_COMP(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
ExpectIntEQ(wolfSSL_sk_SSL_COMP_num(NULL), 0);
#endif
#if defined(OPENSSL_EXTRA) && !defined(NO_WOLFSSL_STUB)
ExpectIntEQ(wolfSSL_sk_SSL_COMP_zero(NULL), WOLFSSL_FAILURE);
#endif
return EXPECT_RESULT();
}
int test_wolfSSL_sk_CIPHER(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
/* TODO: figure out a way to get a WOLFSSL_CIPHER to test with. */
WOLFSSL_STACK* ciphers = NULL;
ExpectNotNull(ciphers = wolfSSL_sk_new_cipher());
#ifndef NO_WOLFSSL_STUB
ExpectNull(wolfSSL_sk_CIPHER_pop(NULL));
ExpectNull(wolfSSL_sk_CIPHER_pop(ciphers));
#endif
ExpectIntEQ(wolfSSL_sk_CIPHER_push(NULL, NULL), WOLFSSL_FATAL_ERROR);
ExpectIntEQ(wolfSSL_sk_CIPHER_push(ciphers, NULL), WOLFSSL_FAILURE);
#ifdef OPENSSL_EXTRA
wolfSSL_sk_CIPHER_free(NULL);
wolfSSL_sk_CIPHER_free(ciphers);
#else
wolfSSL_sk_free(ciphers);
#endif
#endif
return EXPECT_RESULT();
}
int test_wolfssl_sk_WOLFSSL_STRING(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
WOLF_STACK_OF(WOLFSSL_STRING)* strings = NULL;
char* str_1 = NULL;
char* str = NULL;
ExpectNotNull(str_1 = (char*)XMALLOC(2, NULL, DYNAMIC_TYPE_OPENSSL));
if (str_1 != NULL) {
XSTRNCPY(str_1, "1", 2);
}
ExpectNotNull(strings = wolfSSL_sk_WOLFSSL_STRING_new());
ExpectIntEQ(wolfSSL_sk_WOLFSSL_STRING_num(strings), 0);
ExpectNull(wolfSSL_sk_WOLFSSL_STRING_value(NULL, 0));
ExpectNull(wolfSSL_sk_WOLFSSL_STRING_value(NULL, 1));
ExpectNull(wolfSSL_sk_WOLFSSL_STRING_value(strings, -1));
ExpectNull(wolfSSL_sk_WOLFSSL_STRING_value(strings, 0));
ExpectIntEQ(wolfSSL_sk_push(strings, str_1), 1);
ExpectIntEQ(wolfSSL_sk_WOLFSSL_STRING_num(strings), 1);
ExpectNull(wolfSSL_sk_WOLFSSL_STRING_value(strings, 1));
ExpectPtrEq(str = wolfSSL_sk_WOLFSSL_STRING_value(strings, 0), str_1);
if (str != str_1) {
XFREE(str_1, NULL, DYNAMIC_TYPE_OPENSSL);
}
wolfSSL_sk_WOLFSSL_STRING_free(NULL);
wolfSSL_sk_WOLFSSL_STRING_free(strings);
#endif
return EXPECT_RESULT();
}
int test_wolfssl_lh_retrieve(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && defined(OPENSSL_EXTRA) && defined(OPENSSL_ALL)
WOLFSSL_STACK* stack = NULL;
unsigned char data_1[1] = { 1 };
/* If there is ever a public API that creates a stack with the same ifdef
* protection then use it here instead of wolfSSL_sk_new_node(). */
ExpectNotNull(stack = wolfSSL_sk_new_node(HEAP_HINT));
ExpectNull(wolfSSL_lh_retrieve(NULL, NULL));
ExpectNull(wolfSSL_lh_retrieve(stack, NULL));
ExpectNull(wolfSSL_lh_retrieve(NULL, data_1));
/* No hash function. */
ExpectNull(wolfSSL_lh_retrieve(stack, data_1));
ExpectIntEQ(wolfSSL_sk_push(stack, data_1), 1);
/* No hash function - data present. */
ExpectNull(wolfSSL_lh_retrieve(stack, data_1));
/* No public API to set hash function. */
wolfSSL_sk_free(stack);
#endif
return EXPECT_RESULT();
}

57
tests/api/test_ossl_sk.h Normal file
View File

@@ -0,0 +1,57 @@
/* test_ossl_sk.h
*
* Copyright (C) 2006-2025 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifndef WOLFCRYPT_TEST_SSL_SK_H
#define WOLFCRYPT_TEST_SSL_SK_H
#include <tests/api/api_decl.h>
int test_wolfSSL_sk_new_free_node(void);
int test_wolfSSL_sk_push_get_node(void);
int test_wolfSSL_sk_free(void);
int test_wolfSSL_sk_push_pop(void);
int test_wolfSSL_sk_insert(void);
int test_wolfSSL_shallow_sk_dup(void);
int test_wolfSSL_sk_num(void);
int test_wolfSSL_sk_value(void);
int test_wolfssl_sk_GENERIC(void);
int test_wolfssl_sk_SSL_COMP(void);
int test_wolfSSL_sk_CIPHER(void);
int test_wolfssl_sk_WOLFSSL_STRING(void);
int test_wolfssl_lh_retrieve(void);
#define TEST_SSL_SK_DECLS \
TEST_DECL_GROUP("ossl_sk", test_wolfSSL_sk_new_free_node), \
TEST_DECL_GROUP("ossl_sk", test_wolfSSL_sk_push_get_node), \
TEST_DECL_GROUP("ossl_sk", test_wolfSSL_sk_free), \
TEST_DECL_GROUP("ossl_sk", test_wolfSSL_sk_push_pop), \
TEST_DECL_GROUP("ossl_sk", test_wolfSSL_sk_insert), \
TEST_DECL_GROUP("ossl_sk", test_wolfSSL_shallow_sk_dup), \
TEST_DECL_GROUP("ossl_sk", test_wolfSSL_sk_num), \
TEST_DECL_GROUP("ossl_sk", test_wolfSSL_sk_value), \
TEST_DECL_GROUP("ossl_sk", test_wolfssl_sk_GENERIC), \
TEST_DECL_GROUP("ossl_sk", test_wolfssl_sk_SSL_COMP), \
TEST_DECL_GROUP("ossl_sk", test_wolfSSL_sk_CIPHER), \
TEST_DECL_GROUP("ossl_sk", test_wolfssl_sk_WOLFSSL_STRING), \
TEST_DECL_GROUP("ossl_sk", test_wolfssl_lh_retrieve)
#endif /* WOLFCRYPT_TEST_SSL_SK_H */

View File

@@ -135,7 +135,7 @@ int mem_fail_allocs = 0;
int mem_fail_frees = 0;
int mem_fail_cnt = 0;
void wc_MemFailCount_Init()
void wc_MemFailCount_Init(void)
{
char* cnt;
#ifndef WOLFSSL_MUTEX_INITIALIZER
@@ -168,7 +168,7 @@ static void wc_MemFailCount_FreeMem(void)
mem_fail_frees++;
wc_UnLockMutex(&memFailMutex);
}
void wc_MemFailCount_Free()
void wc_MemFailCount_Free(void)
{
#ifndef WOLFSSL_MUTEX_INITIALIZER
wc_FreeMutex(&memFailMutex);

View File

@@ -1883,18 +1883,35 @@ WOLFSSL_LOCAL int CertSetupCbWrapper(WOLFSSL* ssl);
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
WOLFSSL_API void wolfSSL_ERR_print_errors(WOLFSSL_BIO *bio);
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_ALL)
WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_new_node(void* heap);
WOLFSSL_API void wolfSSL_sk_free(WOLFSSL_STACK* sk);
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
WOLFSSL_API void wolfSSL_sk_free_node(WOLFSSL_STACK* in);
#endif
#if !defined(NO_CERTS) && defined(OPENSSL_EXTRA)
WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx);
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
WOLFSSL_API int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in);
WOLFSSL_API void wolfSSL_sk_free(WOLFSSL_STACK* sk);
WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_dup(WOLFSSL_STACK* sk);
WOLFSSL_API WOLFSSL_STACK* wolfSSL_shallow_sk_dup(WOLFSSL_STACK* sk);
WOLFSSL_API int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in);
WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx);
WOLFSSL_API int wolfSSL_sk_push(WOLFSSL_STACK *st, const void *data);
WOLFSSL_API int wolfSSL_sk_insert(WOLFSSL_STACK *sk, const void *data, int idx);
WOLFSSL_API void* wolfSSL_sk_pop(WOLFSSL_STACK* sk);
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_ALL)
WOLFSSL_API int wolfSSL_sk_num(const WOLFSSL_STACK* sk);
WOLFSSL_API void* wolfSSL_sk_value(const WOLFSSL_STACK* sk, int i);
#endif
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(WOLFSSL_QT)
WOLFSSL_API int wolfSSL_sk_ACCESS_DESCRIPTION_push(
WOLF_STACK_OF(ACCESS_DESCRIPTION)* sk,
@@ -3237,11 +3254,6 @@ WOLFSSL_API int wolfSSL_ASN1_TIME_set_string_X509(WOLFSSL_ASN1_TIME *t,
#endif /* OPENSSL_EXTRA */
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
WOLFSSL_API int wolfSSL_sk_num(const WOLFSSL_STACK* sk);
WOLFSSL_API void* wolfSSL_sk_value(const WOLFSSL_STACK* sk, int i);
#endif
/* stunnel 4.28 needs */
WOLFSSL_API void wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX* ctx,