diff --git a/CMakeLists.txt b/CMakeLists.txt index 410518e4a..d5c3d3d97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/IDE/Espressif/ESP-IDF/UPDATE.md b/IDE/Espressif/ESP-IDF/UPDATE.md index 010054e9e..7ccc655e3 100644 --- a/IDE/Espressif/ESP-IDF/UPDATE.md +++ b/IDE/Espressif/ESP-IDF/UPDATE.md @@ -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 diff --git a/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/CMakeLists.txt b/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/CMakeLists.txt index a266a9c1c..66eb43909 100644 --- a/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/CMakeLists.txt @@ -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 diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/CMakeLists.txt b/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/CMakeLists.txt index a266a9c1c..66eb43909 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/CMakeLists.txt @@ -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 diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/CMakeLists.txt b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/CMakeLists.txt index a266a9c1c..66eb43909 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/CMakeLists.txt @@ -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 diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/CMakeLists.txt b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/CMakeLists.txt index a266a9c1c..66eb43909 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/CMakeLists.txt @@ -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 diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/CMakeLists.txt b/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/CMakeLists.txt index a266a9c1c..66eb43909 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/CMakeLists.txt @@ -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 diff --git a/IDE/Espressif/ESP-IDF/libs/CMakeLists.txt b/IDE/Espressif/ESP-IDF/libs/CMakeLists.txt index b25311e38..5d8bad01d 100644 --- a/IDE/Espressif/ESP-IDF/libs/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/libs/CMakeLists.txt @@ -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" diff --git a/IDE/INTIME-RTOS/wolfssl-lib.vcxproj b/IDE/INTIME-RTOS/wolfssl-lib.vcxproj index c00ecf0c7..3c5bd1d8d 100644 --- a/IDE/INTIME-RTOS/wolfssl-lib.vcxproj +++ b/IDE/INTIME-RTOS/wolfssl-lib.vcxproj @@ -61,6 +61,10 @@ true true + + true + true + true @@ -360,4 +364,4 @@ - \ No newline at end of file + diff --git a/IDE/MSVS-2019-AZSPHERE/wolfssl_new_azsphere/CMakeLists.txt b/IDE/MSVS-2019-AZSPHERE/wolfssl_new_azsphere/CMakeLists.txt index 18c3633b0..9cecc1a8c 100644 --- a/IDE/MSVS-2019-AZSPHERE/wolfssl_new_azsphere/CMakeLists.txt +++ b/IDE/MSVS-2019-AZSPHERE/wolfssl_new_azsphere/CMakeLists.txt @@ -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 ) diff --git a/src/include.am b/src/include.am index d7642d67d..f1dd851b0 100644 --- a/src/include.am +++ b/src/include.am @@ -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 diff --git a/src/ssl.c b/src/ssl.c index daa9b6dc7..966c94065 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -359,6 +359,49 @@ WC_RNG* wolfssl_make_rng(WC_RNG* rng, int* local) #define WOLFSSL_PK_INCLUDED #include "src/pk.c" +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) +/* copies over data of "in" to "out" */ +static void wolfSSL_CIPHER_copy(WOLFSSL_CIPHER* in, WOLFSSL_CIPHER* out) +{ + if (in == NULL || out == NULL) + return; + + *out = *in; +} + + +#if defined(OPENSSL_ALL) +static WOLFSSL_X509_OBJECT* wolfSSL_X509_OBJECT_dup(WOLFSSL_X509_OBJECT* obj) +{ + WOLFSSL_X509_OBJECT* ret = NULL; + if (obj) { + ret = wolfSSL_X509_OBJECT_new(); + if (ret) { + ret->type = obj->type; + switch (ret->type) { + case WOLFSSL_X509_LU_NONE: + break; + case WOLFSSL_X509_LU_X509: + ret->data.x509 = wolfSSL_X509_dup(obj->data.x509); + break; + case WOLFSSL_X509_LU_CRL: + #if defined(HAVE_CRL) + ret->data.crl = wolfSSL_X509_CRL_dup(obj->data.crl); + #endif + break; + } + } + } + return ret; +} +#endif /* OPENSSL_ALL */ + +#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ + +#define WOLFSSL_SSL_SK_INCLUDED +#include "src/ssl_sk.c" + + #include #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) @@ -14844,468 +14887,6 @@ WOLF_STACK_OF(WOLFSSL_X509) *wolfSSL_get0_verified_chain(const WOLFSSL *ssl) #endif /* SESSION_CERTS && OPENSSL_EXTRA */ #ifndef NO_CERTS -#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) - -/* create a generic wolfSSL stack node - * returns a new WOLFSSL_STACK structure on success */ -WOLFSSL_STACK* wolfSSL_sk_new_node(void* heap) -{ - WOLFSSL_STACK* sk; - WOLFSSL_ENTER("wolfSSL_sk_new_node"); - - sk = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), heap, - DYNAMIC_TYPE_OPENSSL); - if (sk != NULL) { - XMEMSET(sk, 0, sizeof(*sk)); - sk->heap = heap; - } - - return sk; -} - -/* free's node but does not free internal data such as in->data.x509 */ -void wolfSSL_sk_free_node(WOLFSSL_STACK* in) -{ - if (in != NULL) { - XFREE(in, in->heap, DYNAMIC_TYPE_OPENSSL); - } -} - -/* pushes node "in" onto "stack" and returns pointer to the new stack on success - * also handles internal "num" for number of nodes on stack - * return WOLFSSL_SUCCESS on success - */ -int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in) -{ - if (stack == NULL || in == NULL) { - return WOLFSSL_FAILURE; - } - - if (*stack == NULL) { - in->num = 1; - *stack = in; - return WOLFSSL_SUCCESS; - } - - in->num = (*stack)->num + 1; - in->next = *stack; - *stack = in; - return WOLFSSL_SUCCESS; -} - -#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) -static WC_INLINE int compare_WOLFSSL_CIPHER( - WOLFSSL_CIPHER *a, - WOLFSSL_CIPHER *b) -{ - if ((a->cipherSuite0 == b->cipherSuite0) && - (a->cipherSuite == b->cipherSuite) && - (a->ssl == b->ssl) && - (XMEMCMP(a->description, b->description, sizeof a->description) == 0) && - (a->offset == b->offset) && - (a->in_stack == b->in_stack) && - (a->bits == b->bits)) - return 0; - else - return WOLFSSL_FATAL_ERROR; -} -#endif /* OPENSSL_ALL || WOLFSSL_QT */ - - -/* return number of elements on success 0 on fail */ -int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data) -{ - WOLFSSL_ENTER("wolfSSL_sk_push"); - - return wolfSSL_sk_insert(sk, data, -1); -} - -void* wolfSSL_sk_pop(WOLFSSL_STACK* sk) -{ - WOLFSSL_ENTER("wolfSSL_sk_pop"); - - return wolfSSL_sk_pop_node(sk, -1); -} - -/* return number of elements on success 0 on fail */ -int wolfSSL_sk_insert(WOLFSSL_STACK *sk, const void *data, int idx) -{ - WOLFSSL_STACK* node; -#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) - WOLFSSL_CIPHER ciph; -#endif - WOLFSSL_ENTER("wolfSSL_sk_insert"); - - if (!sk) - return WOLFSSL_FATAL_ERROR; - if (!data) - return WOLFSSL_FAILURE; - - if (idx == 0 || sk->num == 0) { - /* Check if empty data */ - switch (sk->type) { - case STACK_TYPE_CIPHER: -#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) - /* check if entire struct is zero */ - XMEMSET(&ciph, 0, sizeof(WOLFSSL_CIPHER)); - if (compare_WOLFSSL_CIPHER(&sk->data.cipher, &ciph) == 0) { - sk->data.cipher = *(WOLFSSL_CIPHER*)data; - sk->num = 1; - if (sk->hash_fn) { - sk->hash = sk->hash_fn(&sk->data.cipher); - } - return (int)sk->num; - } - if (sk->num == 0) - sk->num = 1; /* confirmed at least one element */ - break; -#endif - case STACK_TYPE_X509: - case STACK_TYPE_GEN_NAME: - case STACK_TYPE_BIO: - case STACK_TYPE_OBJ: - case STACK_TYPE_STRING: - case STACK_TYPE_ACCESS_DESCRIPTION: - case STACK_TYPE_X509_EXT: - case STACK_TYPE_X509_REQ_ATTR: - case STACK_TYPE_NULL: - case STACK_TYPE_X509_NAME: - case STACK_TYPE_X509_NAME_ENTRY: - case STACK_TYPE_CONF_VALUE: - case STACK_TYPE_X509_INFO: - case STACK_TYPE_BY_DIR_entry: - case STACK_TYPE_BY_DIR_hash: - case STACK_TYPE_X509_OBJ: - case STACK_TYPE_DIST_POINT: - case STACK_TYPE_X509_CRL: - default: - /* All other types are pointers */ - if (!sk->data.generic) { - sk->data.generic = (void*)data; - sk->num = 1; -#ifdef OPENSSL_ALL - if (sk->hash_fn) - sk->hash = sk->hash_fn(sk->data.generic); -#endif - return (int)sk->num; - } - if (sk->num == 0) - sk->num = 1; /* confirmed at least one element */ - break; - } - } - - /* stack already has value(s) create a new node and add more */ - node = wolfSSL_sk_new_node(sk->heap); - if (!node) { - WOLFSSL_MSG("Memory error"); - return WOLFSSL_FAILURE; - } - node->type = sk->type; - sk->num += 1; -#ifdef OPENSSL_ALL - node->hash_fn = sk->hash_fn; -#endif - - if (idx == 0) { - /* Special case where we need to change the values in the head element - * to avoid changing the initial pointer. */ - /* push new item onto head of stack */ - node->next = sk->next; - sk->next = node; -#ifdef OPENSSL_ALL - node->hash = sk->hash; - sk->hash = 0; -#endif - switch (sk->type) { - case STACK_TYPE_CIPHER: -#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) - node->data.cipher = sk->data.cipher; - sk->data.cipher = *(WOLFSSL_CIPHER*)data; - if (sk->hash_fn) { - sk->hash = sk->hash_fn(&sk->data.cipher); - } - break; -#endif - case STACK_TYPE_X509: - case STACK_TYPE_GEN_NAME: - case STACK_TYPE_BIO: - case STACK_TYPE_OBJ: - case STACK_TYPE_STRING: - case STACK_TYPE_ACCESS_DESCRIPTION: - case STACK_TYPE_X509_EXT: - case STACK_TYPE_X509_REQ_ATTR: - case STACK_TYPE_NULL: - case STACK_TYPE_X509_NAME: - case STACK_TYPE_X509_NAME_ENTRY: - case STACK_TYPE_CONF_VALUE: - case STACK_TYPE_X509_INFO: - case STACK_TYPE_BY_DIR_entry: - case STACK_TYPE_BY_DIR_hash: - case STACK_TYPE_X509_OBJ: - case STACK_TYPE_DIST_POINT: - case STACK_TYPE_X509_CRL: - default: - /* All other types are pointers */ - node->data.generic = sk->data.generic; - sk->data.generic = (void*)data; -#ifdef OPENSSL_ALL - if (sk->hash_fn) - sk->hash = sk->hash_fn(sk->data.generic); -#endif - break; - } - - return (int)sk->num; - } - - /* populate node */ - switch (sk->type) { - case STACK_TYPE_CIPHER: -#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) - node->data.cipher = *(WOLFSSL_CIPHER*)data; - if (node->hash_fn) - node->hash = node->hash_fn(&node->data.cipher); - break; -#endif - case STACK_TYPE_X509: - case STACK_TYPE_GEN_NAME: - case STACK_TYPE_BIO: - case STACK_TYPE_OBJ: - case STACK_TYPE_STRING: - case STACK_TYPE_ACCESS_DESCRIPTION: - case STACK_TYPE_X509_EXT: - case STACK_TYPE_X509_REQ_ATTR: - case STACK_TYPE_NULL: - case STACK_TYPE_X509_NAME: - case STACK_TYPE_X509_NAME_ENTRY: - case STACK_TYPE_CONF_VALUE: - case STACK_TYPE_X509_INFO: - case STACK_TYPE_BY_DIR_entry: - case STACK_TYPE_BY_DIR_hash: - case STACK_TYPE_X509_OBJ: - case STACK_TYPE_DIST_POINT: - case STACK_TYPE_X509_CRL: - default: - /* All other types are pointers */ - node->data.generic = (void*)data; -#ifdef OPENSSL_ALL - if (node->hash_fn) - node->hash = node->hash_fn(node->data.generic); -#endif - break; - } - { - /* insert node into stack. not using sk since we return sk->num after */ - WOLFSSL_STACK* prev_node = sk; - while (--idx != 0 && prev_node->next != NULL) - prev_node = prev_node->next; - node->next = prev_node->next; - prev_node->next = node; - } - - return (int)sk->num; -} - -void* wolfSSL_sk_pop_node(WOLFSSL_STACK* sk, int idx) -{ - void* ret = NULL; - WOLFSSL_STACK* tmp = NULL; - - if (!sk) - return NULL; - if (sk->num == 0) - return NULL; - - sk->num--; - if (idx == 0 || sk->next == NULL) { - switch (sk->type) { - case STACK_TYPE_CIPHER: - /* Can't return cipher type */ - break; - case STACK_TYPE_X509: - case STACK_TYPE_GEN_NAME: - case STACK_TYPE_BIO: - case STACK_TYPE_OBJ: - case STACK_TYPE_STRING: - case STACK_TYPE_ACCESS_DESCRIPTION: - case STACK_TYPE_X509_EXT: - case STACK_TYPE_X509_REQ_ATTR: - case STACK_TYPE_NULL: - case STACK_TYPE_X509_NAME: - case STACK_TYPE_X509_NAME_ENTRY: - case STACK_TYPE_CONF_VALUE: - case STACK_TYPE_X509_INFO: - case STACK_TYPE_BY_DIR_entry: - case STACK_TYPE_BY_DIR_hash: - case STACK_TYPE_X509_OBJ: - case STACK_TYPE_DIST_POINT: - case STACK_TYPE_X509_CRL: - default: - ret = sk->data.generic; - sk->data.generic = NULL; - break; - } - if (sk->next) { - tmp = sk->next; - sk->next = tmp->next; - XMEMCPY(&sk->data, &tmp->data, sizeof(sk->data)); - wolfSSL_sk_free_node(tmp); - } - return ret; - } - - { - WOLFSSL_STACK* prev_node = sk; - tmp = sk->next; - while (--idx != 0 && tmp->next != NULL) { - prev_node = tmp; - tmp = tmp->next; - } - prev_node->next = tmp->next; - switch (sk->type) { - case STACK_TYPE_CIPHER: - /* Can't return cipher type */ - break; - case STACK_TYPE_X509: - case STACK_TYPE_GEN_NAME: - case STACK_TYPE_BIO: - case STACK_TYPE_OBJ: - case STACK_TYPE_STRING: - case STACK_TYPE_ACCESS_DESCRIPTION: - case STACK_TYPE_X509_EXT: - case STACK_TYPE_X509_REQ_ATTR: - case STACK_TYPE_NULL: - case STACK_TYPE_X509_NAME: - case STACK_TYPE_X509_NAME_ENTRY: - case STACK_TYPE_CONF_VALUE: - case STACK_TYPE_X509_INFO: - case STACK_TYPE_BY_DIR_entry: - case STACK_TYPE_BY_DIR_hash: - case STACK_TYPE_X509_OBJ: - case STACK_TYPE_DIST_POINT: - case STACK_TYPE_X509_CRL: - default: - ret = tmp->data.generic; - break; - } - wolfSSL_sk_free_node(tmp); - } - return ret; -} - -#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ - -#ifdef OPENSSL_EXTRA - -/* returns the node at index "idx", NULL if not found */ -WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx) -{ - int i; - WOLFSSL_STACK* ret = NULL; - WOLFSSL_STACK* current; - - current = sk; - for (i = 0; i <= idx && current != NULL; i++) { - if (i == idx) { - ret = current; - break; - } - current = current->next; - } - return ret; -} - - -#endif /* OPENSSL_EXTRA */ - -#ifdef OPENSSL_EXTRA - -#if defined(OPENSSL_ALL) - -void *wolfSSL_lh_retrieve(WOLFSSL_STACK *sk, void *data) -{ - unsigned long hash; - - WOLFSSL_ENTER("wolfSSL_lh_retrieve"); - - if (!sk || !data) { - WOLFSSL_MSG("Bad parameters"); - return NULL; - } - - if (!sk->hash_fn) { - WOLFSSL_MSG("No hash function defined"); - return NULL; - } - - hash = sk->hash_fn(data); - - while (sk) { - /* Calc hash if not done so yet */ - if (!sk->hash) { - switch (sk->type) { - case STACK_TYPE_CIPHER: - sk->hash = sk->hash_fn(&sk->data.cipher); - break; - case STACK_TYPE_X509: - case STACK_TYPE_GEN_NAME: - case STACK_TYPE_BIO: - case STACK_TYPE_OBJ: - case STACK_TYPE_STRING: - case STACK_TYPE_ACCESS_DESCRIPTION: - case STACK_TYPE_X509_EXT: - case STACK_TYPE_X509_REQ_ATTR: - case STACK_TYPE_NULL: - case STACK_TYPE_X509_NAME: - case STACK_TYPE_X509_NAME_ENTRY: - case STACK_TYPE_CONF_VALUE: - case STACK_TYPE_X509_INFO: - case STACK_TYPE_BY_DIR_entry: - case STACK_TYPE_BY_DIR_hash: - case STACK_TYPE_X509_OBJ: - case STACK_TYPE_DIST_POINT: - case STACK_TYPE_X509_CRL: - default: - sk->hash = sk->hash_fn(sk->data.generic); - break; - } - } - if (sk->hash == hash) { - switch (sk->type) { - case STACK_TYPE_CIPHER: - return &sk->data.cipher; - case STACK_TYPE_X509: - case STACK_TYPE_GEN_NAME: - case STACK_TYPE_BIO: - case STACK_TYPE_OBJ: - case STACK_TYPE_STRING: - case STACK_TYPE_ACCESS_DESCRIPTION: - case STACK_TYPE_X509_EXT: - case STACK_TYPE_X509_REQ_ATTR: - case STACK_TYPE_NULL: - case STACK_TYPE_X509_NAME: - case STACK_TYPE_X509_NAME_ENTRY: - case STACK_TYPE_CONF_VALUE: - case STACK_TYPE_X509_INFO: - case STACK_TYPE_BY_DIR_entry: - case STACK_TYPE_BY_DIR_hash: - case STACK_TYPE_X509_OBJ: - case STACK_TYPE_DIST_POINT: - case STACK_TYPE_X509_CRL: - default: - return sk->data.generic; - } - } - sk = sk->next; - } - - return NULL; -} - -#endif /* OPENSSL_ALL */ - -#endif /* OPENSSL_EXTRA */ /* OPENSSL_EXTRA is needed for wolfSSL_X509_d21 function KEEP_OUR_CERT is to insure ability for returning ssl certificate */ @@ -15626,38 +15207,6 @@ int wolfSSL_get_cipher_suite_from_name(const char* name, byte* cipherSuite0, } -#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) -/* Creates and returns a new WOLFSSL_CIPHER stack. */ -WOLFSSL_STACK* wolfSSL_sk_new_cipher(void) -{ - WOLFSSL_STACK* sk; - WOLFSSL_ENTER("wolfSSL_sk_new_cipher"); - - sk = wolfSSL_sk_new_null(); - if (sk == NULL) - return NULL; - sk->type = STACK_TYPE_CIPHER; - - return sk; -} - -/* returns the number of elements in stack on success, 0 on fail */ -int wolfSSL_sk_CIPHER_push(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk, - WOLFSSL_CIPHER* cipher) -{ - return wolfSSL_sk_push(sk, cipher); -} - -#ifndef NO_WOLFSSL_STUB -WOLFSSL_CIPHER* wolfSSL_sk_CIPHER_pop(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk) -{ - WOLFSSL_STUB("wolfSSL_sk_CIPHER_pop"); - (void)sk; - return NULL; -} -#endif /* NO_WOLFSSL_STUB */ -#endif /* WOLFSSL_QT || OPENSSL_ALL */ - word32 wolfSSL_CIPHER_get_id(const WOLFSSL_CIPHER* cipher) { word16 cipher_id = 0; @@ -15690,19 +15239,6 @@ const WOLFSSL_CIPHER* wolfSSL_get_cipher_by_value(word16 value) } -#if defined(OPENSSL_EXTRA) -/* Free the structure for WOLFSSL_CIPHER stack - * - * sk stack to free nodes in - */ -void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk) -{ - WOLFSSL_ENTER("wolfSSL_sk_CIPHER_free"); - - wolfSSL_sk_free(sk); -} -#endif /* OPENSSL_ALL */ - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \ !defined(NO_DH) #ifdef HAVE_FFDHE @@ -17702,17 +17238,6 @@ long wolfSSL_set_tlsext_debug_arg(WOLFSSL* ssl, void *arg) } #endif /* HAVE_PK_CALLBACKS */ -/*** TBD ***/ -#ifndef NO_WOLFSSL_STUB -int wolfSSL_sk_SSL_COMP_zero(WOLFSSL_STACK* st) -{ - (void)st; - WOLFSSL_STUB("wolfSSL_sk_SSL_COMP_zero"); - /* wolfSSL_set_options(ssl, SSL_OP_NO_COMPRESSION); */ - return WOLFSSL_FAILURE; -} -#endif - #ifdef HAVE_CERTIFICATE_STATUS_REQUEST long wolfSSL_set_tlsext_status_type(WOLFSSL *s, int type) { @@ -17819,21 +17344,6 @@ WOLF_STACK_OF(WOLFSSL_COMP) *WOLFSSL_COMP_get_compression_methods(void) #endif -int wolfSSL_sk_SSL_CIPHER_num(const WOLF_STACK_OF(WOLFSSL_CIPHER)* p) -{ - WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_num"); - if (p == NULL) { - return WOLFSSL_FATAL_ERROR; - } - return (int)p->num; -} - -WOLFSSL_CIPHER* wolfSSL_sk_SSL_CIPHER_value(WOLFSSL_STACK* sk, int i) -{ - WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_value"); - return (WOLFSSL_CIPHER*)wolfSSL_sk_value(sk, i); -} - #if !defined(NETOS) void wolfSSL_ERR_load_SSL_strings(void) { @@ -18106,461 +17616,6 @@ long wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg(WOLFSSL_CTX* ctx, #endif /* OPENSSL_EXTRA */ -#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) -int wolfSSL_sk_num(const WOLFSSL_STACK* sk) -{ - WOLFSSL_ENTER("wolfSSL_sk_num"); - if (sk == NULL) - return 0; - return (int)sk->num; -} - -void* wolfSSL_sk_value(const WOLFSSL_STACK* sk, int i) -{ - WOLFSSL_ENTER("wolfSSL_sk_value"); - - for (; sk != NULL && i > 0; i--) - sk = sk->next; - if (sk == NULL) - return NULL; - - switch (sk->type) { - case STACK_TYPE_X509: - return (void*)sk->data.x509; - case STACK_TYPE_GEN_NAME: - return (void*)sk->data.gn; - case STACK_TYPE_BIO: - return (void*)sk->data.bio; - case STACK_TYPE_OBJ: - return (void*)sk->data.obj; - case STACK_TYPE_STRING: - return (void*)sk->data.string; - case STACK_TYPE_CIPHER: - return (void*)&sk->data.cipher; - case STACK_TYPE_ACCESS_DESCRIPTION: - return (void*)sk->data.access; - case STACK_TYPE_X509_EXT: - return (void*)sk->data.ext; - case STACK_TYPE_X509_REQ_ATTR: - return (void*)sk->data.generic; - case STACK_TYPE_NULL: - return (void*)sk->data.generic; - case STACK_TYPE_X509_NAME: - return (void*)sk->data.name; - case STACK_TYPE_X509_NAME_ENTRY: - return (void*)sk->data.name_entry; - case STACK_TYPE_CONF_VALUE: - #ifdef OPENSSL_EXTRA - return (void*)sk->data.conf; - #else - return NULL; - #endif - case STACK_TYPE_X509_INFO: - return (void*)sk->data.info; - case STACK_TYPE_BY_DIR_entry: - return (void*)sk->data.dir_entry; - case STACK_TYPE_BY_DIR_hash: - return (void*)sk->data.dir_hash; - case STACK_TYPE_X509_OBJ: - return (void*)sk->data.x509_obj; - case STACK_TYPE_DIST_POINT: - return (void*)sk->data.dp; - case STACK_TYPE_X509_CRL: - return (void*)sk->data.crl; - default: - return (void*)sk->data.generic; - } -} - -/* copies over data of "in" to "out" */ -static void wolfSSL_CIPHER_copy(WOLFSSL_CIPHER* in, WOLFSSL_CIPHER* out) -{ - if (in == NULL || out == NULL) - return; - - *out = *in; -} - - -#if defined(OPENSSL_ALL) -static WOLFSSL_X509_OBJECT* wolfSSL_X509_OBJECT_dup(WOLFSSL_X509_OBJECT* obj) -{ - WOLFSSL_X509_OBJECT* ret = NULL; - if (obj) { - ret = wolfSSL_X509_OBJECT_new(); - if (ret) { - ret->type = obj->type; - switch (ret->type) { - case WOLFSSL_X509_LU_NONE: - break; - case WOLFSSL_X509_LU_X509: - ret->data.x509 = wolfSSL_X509_dup(obj->data.x509); - break; - case WOLFSSL_X509_LU_CRL: - #if defined(HAVE_CRL) - ret->data.crl = wolfSSL_X509_CRL_dup(obj->data.crl); - #endif - break; - } - } - } - return ret; -} -#endif /* OPENSSL_ALL */ - -WOLFSSL_STACK* wolfSSL_sk_dup(WOLFSSL_STACK* sk) -{ - - WOLFSSL_STACK* ret = NULL; - WOLFSSL_STACK* last = NULL; - - WOLFSSL_ENTER("wolfSSL_sk_dup"); - - while (sk) { - WOLFSSL_STACK* cur = wolfSSL_sk_new_node(sk->heap); - - if (!cur) { - WOLFSSL_MSG("wolfSSL_sk_new_node error"); - goto error; - } - - if (!ret) { - /* Set first node */ - ret = cur; - } - - if (last) { - last->next = cur; - } - - XMEMCPY(cur, sk, sizeof(WOLFSSL_STACK)); - - /* We will allocate new memory for this */ - XMEMSET(&cur->data, 0, sizeof(cur->data)); - cur->next = NULL; - - switch (sk->type) { - case STACK_TYPE_X509: - if (!sk->data.x509) - break; - cur->data.x509 = wolfSSL_X509_dup(sk->data.x509); - if (!cur->data.x509) { - WOLFSSL_MSG("wolfSSL_X509_dup error"); - goto error; - } - break; - case STACK_TYPE_CIPHER: - wolfSSL_CIPHER_copy(&sk->data.cipher, &cur->data.cipher); - break; - case STACK_TYPE_GEN_NAME: - if (!sk->data.gn) - break; - cur->data.gn = wolfSSL_GENERAL_NAME_dup(sk->data.gn); - if (!cur->data.gn) { - WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error"); - goto error; - } - break; - case STACK_TYPE_OBJ: - if (!sk->data.obj) - break; - cur->data.obj = wolfSSL_ASN1_OBJECT_dup(sk->data.obj); - if (!cur->data.obj) { - WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup error"); - goto error; - } - break; - case STACK_TYPE_X509_OBJ: - #if defined(OPENSSL_ALL) - if (!sk->data.x509_obj) - break; - cur->data.x509_obj = wolfSSL_X509_OBJECT_dup(sk->data.x509_obj); - if (!cur->data.x509_obj) { - WOLFSSL_MSG("wolfSSL_X509_OBJECT_dup error"); - goto error; - } - break; - #endif - case STACK_TYPE_BIO: - case STACK_TYPE_STRING: - case STACK_TYPE_ACCESS_DESCRIPTION: - case STACK_TYPE_X509_EXT: - case STACK_TYPE_X509_REQ_ATTR: - case STACK_TYPE_NULL: - case STACK_TYPE_X509_NAME: - case STACK_TYPE_X509_NAME_ENTRY: - case STACK_TYPE_CONF_VALUE: - case STACK_TYPE_X509_INFO: - case STACK_TYPE_BY_DIR_entry: - case STACK_TYPE_BY_DIR_hash: - case STACK_TYPE_DIST_POINT: - case STACK_TYPE_X509_CRL: - default: - WOLFSSL_MSG("Unsupported stack type"); - goto error; - } - - sk = sk->next; - last = cur; - } - return ret; - -error: - if (ret) { - wolfSSL_sk_GENERAL_NAME_free(ret); - } - return NULL; -} - - -WOLFSSL_STACK* wolfSSL_shallow_sk_dup(WOLFSSL_STACK* sk) -{ - - WOLFSSL_STACK* ret = NULL; - WOLFSSL_STACK** prev = &ret; - - WOLFSSL_ENTER("wolfSSL_shallow_sk_dup"); - - for (; sk != NULL; sk = sk->next) { - WOLFSSL_STACK* cur = wolfSSL_sk_new_node(sk->heap); - - if (!cur) { - WOLFSSL_MSG("wolfSSL_sk_new_node error"); - goto error; - } - - XMEMCPY(cur, sk, sizeof(WOLFSSL_STACK)); - cur->next = NULL; - - *prev = cur; - prev = &cur->next; - } - return ret; - -error: - if (ret) { - wolfSSL_sk_free(ret); - } - return NULL; -} - -/* Free the just the stack structure */ -void wolfSSL_sk_free(WOLFSSL_STACK* sk) -{ - WOLFSSL_ENTER("wolfSSL_sk_free"); - - while (sk != NULL) { - WOLFSSL_STACK* next = sk->next; - wolfSSL_sk_free_node(sk); - sk = next; - } -} - -/* Frees each node in the stack and frees the stack. - */ -void wolfSSL_sk_GENERIC_pop_free(WOLFSSL_STACK* sk, - void (*f) (void*)) -{ - WOLFSSL_ENTER("wolfSSL_sk_GENERIC_pop_free"); - wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f); -} - -/* returns the number of elements in stack on success, 0 on fail */ -int wolfSSL_sk_GENERIC_push(WOLFSSL_STACK* sk, void* generic) -{ - WOLFSSL_ENTER("wolfSSL_sk_GENERIC_push"); - - return wolfSSL_sk_push(sk, generic); -} -void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK* sk) -{ - wolfSSL_sk_free(sk); -} - -/* Pop off data from the stack. Checks that the type matches the stack type. - * - * @param [in, out] sk Stack of objects. - * @param [in] type Type of stack. - * @return Object on success. - * @return NULL when stack is NULL or no nodes left in stack. - */ -void* wolfssl_sk_pop_type(WOLFSSL_STACK* sk, WOLF_STACK_TYPE type) -{ - void* data = NULL; - - /* Check we have a stack passed in of the right type. */ - if ((sk != NULL) && (sk->type == type)) - data = wolfSSL_sk_pop(sk); - - return data; -} - -/* Free all nodes in a stack including the pushed objects */ -void wolfSSL_sk_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, - wolfSSL_sk_freefunc func) -{ - WOLFSSL_ENTER("wolfSSL_sk_pop_free"); - - if (sk == NULL) { - /* pop_free can be called with NULL, do not print bad argument */ - return; - } - #if defined(WOLFSSL_QT) - /* In Qt v15.5, it calls OPENSSL_sk_free(xxx, OPENSSL_sk_free). - * By using OPENSSL_sk_free for free causes access violation. - * Therefore, switching free func to wolfSSL_ACCESS_DESCRIPTION_free - * is needed even the func isn't NULL. - */ - if (sk->type == STACK_TYPE_ACCESS_DESCRIPTION) { - func = (wolfSSL_sk_freefunc)wolfSSL_ACCESS_DESCRIPTION_free; - } - #endif - if (func == NULL) { - switch(sk->type) { - case STACK_TYPE_ACCESS_DESCRIPTION: - #if defined(OPENSSL_ALL) - func = (wolfSSL_sk_freefunc)wolfSSL_ACCESS_DESCRIPTION_free; - #endif - break; - case STACK_TYPE_X509: - func = (wolfSSL_sk_freefunc)wolfSSL_X509_free; - break; - case STACK_TYPE_X509_OBJ: - #ifdef OPENSSL_ALL - func = (wolfSSL_sk_freefunc)wolfSSL_X509_OBJECT_free; - #endif - break; - case STACK_TYPE_OBJ: - func = (wolfSSL_sk_freefunc)wolfSSL_ASN1_OBJECT_free; - break; - case STACK_TYPE_DIST_POINT: - #ifdef OPENSSL_EXTRA - func = (wolfSSL_sk_freefunc)wolfSSL_DIST_POINT_free; - #endif - break; - case STACK_TYPE_GEN_NAME: - func = (wolfSSL_sk_freefunc)wolfSSL_GENERAL_NAME_free; - break; - case STACK_TYPE_STRING: - #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ - defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) - func = (wolfSSL_sk_freefunc)wolfSSL_WOLFSSL_STRING_free; - #endif - break; - case STACK_TYPE_X509_NAME: - #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \ - && !defined(WOLFCRYPT_ONLY) - func = (wolfSSL_sk_freefunc)wolfSSL_X509_NAME_free; - #endif - break; - case STACK_TYPE_X509_NAME_ENTRY: - #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \ - && !defined(WOLFCRYPT_ONLY) - func = (wolfSSL_sk_freefunc)wolfSSL_X509_NAME_ENTRY_free; - #endif - break; - case STACK_TYPE_X509_EXT: - #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) - func = (wolfSSL_sk_freefunc)wolfSSL_X509_EXTENSION_free; - #endif - break; - case STACK_TYPE_X509_REQ_ATTR: - #if defined(OPENSSL_ALL) && \ - (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_REQ)) - func = (wolfSSL_sk_freefunc)wolfSSL_X509_ATTRIBUTE_free; - #endif - break; - case STACK_TYPE_CONF_VALUE: - #if defined(OPENSSL_ALL) - func = (wolfSSL_sk_freefunc)wolfSSL_X509V3_conf_free; - #endif - break; - case STACK_TYPE_X509_INFO: - #if defined(OPENSSL_ALL) - func = (wolfSSL_sk_freefunc)wolfSSL_X509_INFO_free; - #endif - break; - case STACK_TYPE_BIO: -#if !defined(NO_BIO) && defined(OPENSSL_EXTRA) - func = (wolfSSL_sk_freefunc)wolfSSL_BIO_vfree; -#endif - break; - case STACK_TYPE_BY_DIR_entry: -#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) - func = (wolfSSL_sk_freefunc)wolfSSL_BY_DIR_entry_free; -#endif - break; - case STACK_TYPE_BY_DIR_hash: -#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) - func = (wolfSSL_sk_freefunc)wolfSSL_BY_DIR_HASH_free; -#endif - break; - case STACK_TYPE_X509_CRL: -#if defined(HAVE_CRL) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) - func = (wolfSSL_sk_freefunc)wolfSSL_X509_CRL_free; -#endif - break; - case STACK_TYPE_CIPHER: - case STACK_TYPE_NULL: - default: - break; - } - } - - while (sk != NULL) { - WOLFSSL_STACK* next = sk->next; - - if (func != NULL) { - if (sk->type != STACK_TYPE_CIPHER) - func(sk->data.generic); - } - XFREE(sk, sk->heap, DYNAMIC_TYPE_OPENSSL); - sk = next; - } -} - -/* Creates a new stack of the requested type. - * - * @param [in] type Type of stack. - * @return Empty stack on success. - * @return NULL when dynamic memory allocation fails. - */ -WOLFSSL_STACK* wolfssl_sk_new_type(WOLF_STACK_TYPE type) -{ - WOLFSSL_STACK* sk; - - /* Allocate a new stack - first node. */ - sk = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, - DYNAMIC_TYPE_OPENSSL); - if (sk == NULL) { - WOLFSSL_MSG("WOLFSSL_STACK memory error"); - } - else { - /* Clear node and set type. */ - XMEMSET(sk, 0, sizeof(WOLFSSL_STACK)); - sk->type = type; - } - - return sk; -} - -/* Creates and returns a new null stack. */ -WOLFSSL_STACK* wolfSSL_sk_new_null(void) -{ - WOLFSSL_ENTER("wolfSSL_sk_new_null"); - - return wolfssl_sk_new_type(STACK_TYPE_NULL); -} - -int wolfSSL_sk_SSL_COMP_num(WOLF_STACK_OF(WOLFSSL_COMP)* sk) -{ - if (sk == NULL) - return 0; - return (int)sk->num; -} - -#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ - #if defined(OPENSSL_EXTRA) && defined(KEEP_PEER_CERT) && \ defined(HAVE_EX_DATA) && !defined(NO_FILESYSTEM) int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname) @@ -21748,38 +20803,6 @@ int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits) return ret; } -/* returns value less than 0 on fail to match - * On a successful match the priority level found is returned - */ -int wolfSSL_sk_SSL_CIPHER_find( - WOLF_STACK_OF(WOLFSSL_CIPHER)* sk, const WOLFSSL_CIPHER* toFind) -{ - WOLFSSL_STACK* next; - int i, sz; - - if (sk == NULL || toFind == NULL) { - return WOLFSSL_FATAL_ERROR; - } - - sz = wolfSSL_sk_SSL_CIPHER_num(sk); - next = sk; - for (i = 0; i < sz && next != NULL; i++) { - if (next->data.cipher.cipherSuite0 == toFind->cipherSuite0 && - next->data.cipher.cipherSuite == toFind->cipherSuite) { - return sz - i; /* reverse because stack pushed highest on first */ - } - next = next->next; - } - return WOLFSSL_FATAL_ERROR; -} - -/* free's all nodes in the stack and there data */ -void wolfSSL_sk_SSL_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk) -{ - WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_free"); - wolfSSL_sk_free(sk); -} - #ifdef HAVE_SNI int wolfSSL_set_tlsext_host_name(WOLFSSL* ssl, const char* host_name) { @@ -23187,17 +22210,6 @@ int wolfSSL_get0_chain_certs(WOLFSSL *ssl, } #endif -WOLF_STACK_OF(WOLFSSL_STRING)* wolfSSL_sk_WOLFSSL_STRING_new(void) -{ - WOLF_STACK_OF(WOLFSSL_STRING)* ret = wolfSSL_sk_new_node(NULL); - - if (ret) { - ret->type = STACK_TYPE_STRING; - } - - return ret; -} - void wolfSSL_WOLFSSL_STRING_free(WOLFSSL_STRING s) { WOLFSSL_ENTER("wolfSSL_WOLFSSL_STRING_free"); @@ -23205,40 +22217,6 @@ void wolfSSL_WOLFSSL_STRING_free(WOLFSSL_STRING s) XFREE(s, NULL, DYNAMIC_TYPE_OPENSSL); } -void wolfSSL_sk_WOLFSSL_STRING_free(WOLF_STACK_OF(WOLFSSL_STRING)* sk) -{ - WOLFSSL_STACK* tmp; - WOLFSSL_ENTER("wolfSSL_sk_WOLFSSL_STRING_free"); - - if (sk == NULL) - return; - - /* parse through stack freeing each node */ - while (sk) { - tmp = sk->next; - XFREE(sk->data.string, NULL, DYNAMIC_TYPE_OPENSSL); - XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); - sk = tmp; - } -} - -WOLFSSL_STRING wolfSSL_sk_WOLFSSL_STRING_value( - WOLF_STACK_OF(WOLFSSL_STRING)* strings, int idx) -{ - for (; idx > 0 && strings != NULL; idx--) - strings = strings->next; - if (strings == NULL) - return NULL; - return strings->data.string; -} - -int wolfSSL_sk_WOLFSSL_STRING_num(WOLF_STACK_OF(WOLFSSL_STRING)* strings) -{ - if (strings) - return (int)strings->num; - return 0; -} - #endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */ #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ diff --git a/src/ssl_sk.c b/src/ssl_sk.c new file mode 100644 index 000000000..4b01b443f --- /dev/null +++ b/src/ssl_sk.c @@ -0,0 +1,1251 @@ +/* ssl_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 + +#if !defined(WOLFSSL_SSL_SK_INCLUDED) + #ifndef WOLFSSL_IGNORE_FILE_WARN + #warning ssl_sk.c does not need to be compiled separately from ssl.c + #endif +#else + +/* In OpenSSL, OPENSSL_STACK is structure with an array of data pointers. + * + * In wolfSSL, WOLFSSL_STACK is a linked-list of nodes and therefore the first + * node has no data but the type is set. + * When the first data is set, the first node has the data stored against it and + * the number of nodes goes up to 1. + * If a new node is prepended then, to keep the pointer the same, the first + * node is copied into a new node and inserted after first node, and the new + * data is put into the first node. + */ + +/******************************************************************************* + * SK node APIs + ******************************************************************************/ + +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \ + defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ + defined(OPENSSL_ALL) || defined(WOLFSSL_QT) +/* Creates a generic wolfSSL stack node. + * + * @param [in] heap eap hint for dynamic memory allocation. + * @return WOLFSSL_STACK structure on success. + * @return NULL when dynamic memory allocation fails. + */ +WOLFSSL_STACK* wolfSSL_sk_new_node(void* heap) +{ + WOLFSSL_STACK* node; + + WOLFSSL_ENTER("wolfSSL_sk_new_node"); + + node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), heap, + DYNAMIC_TYPE_OPENSSL); + if (node != NULL) { + XMEMSET(node, 0, sizeof(*node)); + node->heap = heap; + } + + return node; +} +#endif + +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \ + defined(OPENSSL_ALL) +/* Disposes of WOLFSSL_STACK object. + * + * Cannot use node after this call. + * + * @param [in] node WOLFSSL_STACK object. + */ +void wolfSSL_sk_free_node(WOLFSSL_STACK* node) +{ + /* Don't dereference node for heap when NULL. */ + if (node != NULL) { + XFREE(node, node->heap, DYNAMIC_TYPE_OPENSSL); + } +} +#endif + +#if !defined(NO_CERTS) && defined(OPENSSL_EXTRA) +/* Gets the node from stack at the index. + * + * @param [in] stack Stack of nodes. + * @param [in] idx Index of node to get. + * @return Node at index on success. + * @return NULL when no node at index. + */ +WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* stack, int idx) +{ + int i; + WOLFSSL_STACK* ret; + + if ((idx < 0) || (idx > (int)stack->num)) { + ret = NULL; + } + else { + ret = stack; + for (i = 0; i < idx; i++) { + ret = ret->next; + } + } + + return ret; +} +#endif /* !NO_CERT && OPENSSL_EXTRA*/ + +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) +/* Copy all fields from src into dst. + * + * Shallow copy only. + * + * @param [in, out] dst Node to copy into. + * @param [in] src Node to copy. + */ +static void wolfssl_sk_node_copy(WOLFSSL_STACK* dst, WOLFSSL_STACK* src) +{ + dst->data.generic = src->data.generic; + dst->next = src->next; +#ifdef OPENSSL_ALL + dst->hash_fn = src->hash_fn; + dst->hash = src->hash; +#endif + dst->type = src->type; + dst->num = src->num; +} + +#ifndef NO_CERTS +/* Get data pointer from node. + * + * @param [in] node Node to get data from. + * @param [in] no_static Don't return static data. + * @return Data pointer of node on success. + * @return NULL when node type is STACK_TYPE_CIPHER. + */ +static void* wolfssl_sk_node_get_data(WOLFSSL_STACK* node, int no_static) +{ + void *ret = NULL; + + switch (node->type) { + case STACK_TYPE_CIPHER: + if (!no_static) { + ret = &node->data.cipher; + } + break; + case STACK_TYPE_X509: + case STACK_TYPE_GEN_NAME: + case STACK_TYPE_BIO: + case STACK_TYPE_OBJ: + case STACK_TYPE_STRING: + case STACK_TYPE_ACCESS_DESCRIPTION: + case STACK_TYPE_X509_EXT: + case STACK_TYPE_X509_REQ_ATTR: + case STACK_TYPE_NULL: + case STACK_TYPE_X509_NAME: + case STACK_TYPE_X509_NAME_ENTRY: + case STACK_TYPE_CONF_VALUE: + case STACK_TYPE_X509_INFO: + case STACK_TYPE_BY_DIR_entry: + case STACK_TYPE_BY_DIR_hash: + case STACK_TYPE_X509_OBJ: + case STACK_TYPE_DIST_POINT: + case STACK_TYPE_X509_CRL: + default: + ret = node->data.generic; + break; + } + + return ret; +} + +/* Set data with type into node. + * + * @param [in, out] node Node to place data into. + * @param [in] type Type of data. + * @param [in] data Data to set. + */ +static void wolfssl_sk_node_set_data(WOLFSSL_STACK* node, WOLF_STACK_TYPE type, + const void* data) +{ + switch (type) { + case STACK_TYPE_CIPHER: +#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) + node->data.cipher = *(WOLFSSL_CIPHER*)data; + if (node->hash_fn != NULL) { + node->hash = node->hash_fn(&node->data.cipher); + } + break; +#endif + case STACK_TYPE_X509: + case STACK_TYPE_GEN_NAME: + case STACK_TYPE_BIO: + case STACK_TYPE_OBJ: + case STACK_TYPE_STRING: + case STACK_TYPE_ACCESS_DESCRIPTION: + case STACK_TYPE_X509_EXT: + case STACK_TYPE_X509_REQ_ATTR: + case STACK_TYPE_NULL: + case STACK_TYPE_X509_NAME: + case STACK_TYPE_X509_NAME_ENTRY: + case STACK_TYPE_CONF_VALUE: + case STACK_TYPE_X509_INFO: + case STACK_TYPE_BY_DIR_entry: + case STACK_TYPE_BY_DIR_hash: + case STACK_TYPE_X509_OBJ: + case STACK_TYPE_DIST_POINT: + case STACK_TYPE_X509_CRL: + default: + node->data.generic = (void*)data; +#ifdef OPENSSL_ALL + if (node->hash_fn != NULL) + node->hash = node->hash_fn(node->data.generic); +#endif + break; + } +} + +/* Pushes the node onto the stack. + * + * stack will point to node on success. + * + * @param [in, out] stack Stack of nodes. + * @param [in] node Node to push on. + * + * @return WOLFSSL_SUCCESS on success + * @return WOLFSSL_FAILURE when stack or node is NULL. + */ +int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* node) +{ + int ret = WOLFSSL_SUCCESS; + + /* Validate parameters. */ + if (stack == NULL || node == NULL) { + ret = WOLFSSL_FAILURE; + } + if (ret == WOLFSSL_SUCCESS) { + if (*stack == NULL) { + /* First node. */ + node->num = 1; + } + else { + /* Place new node at start of the stack. */ + node->num = (*stack)->num + 1; + node->next = *stack; + } + /* Return new start. */ + *stack = node; + } + + return ret; +} + +/* Removes the node at the index from the stack and returns data. + * + * This is an internal API. + * + * @param [in, out] stack Stack of nodes. + * @param [in] idx Index of node to remove. + * @return Data in node on success. + * @return NULL when no node at index or no data. + */ +void* wolfSSL_sk_pop_node(WOLFSSL_STACK* stack, int idx) +{ + void* ret = NULL; + WOLFSSL_STACK* tmp = NULL; + WOLFSSL_STACK* prev; + + /* Validate parameters. */ + if ((stack != NULL) && (stack->num != 0)) { + stack->num--; + /* Popping first node handled differently. */ + if (idx == 0 || stack->next == NULL) { + ret = wolfssl_sk_node_get_data(stack, 1); + /* Clear out data if we are returning it. */ + if (ret != NULL) { + stack->data.generic = NULL; + } + if (stack->next) { + /* Keep the first node as it is the pointer passed in. */ + tmp = stack->next; + wolfssl_sk_node_copy(stack, stack->next); + wolfSSL_sk_free_node(tmp); + } + } + else { + /* Find node at index and take out it. */ + prev = stack; + tmp = stack->next; + while ((--idx != 0) && (tmp->next != NULL)) { + prev = tmp; + prev->num--; + tmp = tmp->next; + } + prev->next = tmp->next; + + /* Get data to return and free node only. */ + ret = wolfssl_sk_node_get_data(tmp, 1); + wolfSSL_sk_free_node(tmp); + } + } + + return ret; +} +#endif /* NO_CERTS */ +#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ + +/******************************************************************************* + * SK APIs + ******************************************************************************/ + +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \ + defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ + defined(OPENSSL_ALL) || defined(WOLFSSL_QT) +/* Creates a new stack of the requested type. + * + * This is an internal API. + * + * @param [in] type Type of stack. + * @return Empty stack on success. + * @return NULL when dynamic memory allocation fails. + */ +WOLFSSL_STACK* wolfssl_sk_new_type(WOLF_STACK_TYPE type) +{ + WOLFSSL_STACK* stack = wolfSSL_sk_new_node(NULL); + if (stack != NULL) { + stack->type = type; + } + return stack; +} +#endif + +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) +/* Creates a new NULL type stack. + * + * This is an internal API. + * + * @return Empty stack on success. + * @return NULL when dynamic memory allocation fails. + */ +WOLFSSL_STACK* wolfSSL_sk_new_null(void) +{ + WOLFSSL_ENTER("wolfSSL_sk_new_null"); + + return wolfssl_sk_new_type(STACK_TYPE_NULL); +} + +/* Duplicate the data of a node into another. + * + * Limited too: STACK_TYPE_X509, STACK_TYPE_CIPHER, STACK_TYPE_GEN_NAME, + * STACK_TYPE_OBJ, STACK_TYPE_X509_OBJ. + * + * @param [in, out] dst Destination node. + * @param [in] src Source node. + * @return 0 on success. + * @return 1 when duplication failed or stack type is not supported. + */ +static int wolfssl_sk_dup_data(WOLFSSL_STACK* dst, WOLFSSL_STACK* src) +{ + int err = 0; + + switch (src->type) { + case STACK_TYPE_X509: + if (src->data.x509 == NULL) { + break; + } + dst->data.x509 = wolfSSL_X509_dup(src->data.x509); + if (dst->data.x509 == NULL) { + WOLFSSL_MSG("wolfSSL_X509_dup error"); + err = 1; + break; + } + break; + case STACK_TYPE_CIPHER: + wolfSSL_CIPHER_copy(&src->data.cipher, &dst->data.cipher); + break; + case STACK_TYPE_GEN_NAME: + if (src->data.gn == NULL) { + break; + } + dst->data.gn = wolfSSL_GENERAL_NAME_dup(src->data.gn); + if (dst->data.gn == NULL) { + WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error"); + err = 1; + break; + } + break; + case STACK_TYPE_OBJ: + if (src->data.obj == NULL) { + break; + } + dst->data.obj = wolfSSL_ASN1_OBJECT_dup(src->data.obj); + if (dst->data.obj == NULL) { + WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup error"); + err = 1; + break; + } + break; + case STACK_TYPE_X509_OBJ: + #if defined(OPENSSL_ALL) + if (src->data.x509_obj == NULL) { + break; + } + dst->data.x509_obj = wolfSSL_X509_OBJECT_dup( + src->data.x509_obj); + if (dst->data.x509_obj == NULL) { + WOLFSSL_MSG("wolfSSL_X509_OBJECT_dup error"); + err = 1; + break; + } + break; + #endif + case STACK_TYPE_BIO: + case STACK_TYPE_STRING: + case STACK_TYPE_ACCESS_DESCRIPTION: + case STACK_TYPE_X509_EXT: + case STACK_TYPE_X509_REQ_ATTR: + case STACK_TYPE_NULL: + case STACK_TYPE_X509_NAME: + case STACK_TYPE_X509_NAME_ENTRY: + case STACK_TYPE_CONF_VALUE: + case STACK_TYPE_X509_INFO: + case STACK_TYPE_BY_DIR_entry: + case STACK_TYPE_BY_DIR_hash: + case STACK_TYPE_DIST_POINT: + case STACK_TYPE_X509_CRL: + default: + WOLFSSL_MSG("Unsupported stack type"); + err = 1; + break; + } + + return err; +} + +/* Duplicate the stack of nodes. + * + * TODO: OpenSSL does a shallow copy but we have wolfSSL_shallow_sk_dup(). + * + * Data is copied/duplicated - deep copy. + * + * Limited too: STACK_TYPE_X509, STACK_TYPE_CIPHER, STACK_TYPE_GEN_NAME, + * STACK_TYPE_OBJ, STACK_TYPE_X509_OBJ. + * + * @param [in, out] stack Stack of nodes. + * @return A new stack of nodes with data duplicated/copied on success. + * @return NULL on error. + */ +WOLFSSL_STACK* wolfSSL_sk_dup(WOLFSSL_STACK* stack) +{ + WOLFSSL_STACK* ret = NULL; + WOLFSSL_STACK* last = NULL; + int err = 0; + + WOLFSSL_ENTER("wolfSSL_sk_dup"); + + for (; stack != NULL; stack = stack->next) { + /* New node for duplicate stack. */ + WOLFSSL_STACK* cur = wolfSSL_sk_new_node(stack->heap); + if (cur == NULL) { + WOLFSSL_MSG("wolfSSL_sk_new_node error"); + err = 1; + break; + } + + if (ret == NULL) { + /* Keep the first node for returning. */ + ret = cur; + } + if (last != NULL) { + /* Add new node to end of list. */ + last->next = cur; + } + /* Update last node in linked list. */ + last = cur; + + wolfssl_sk_node_copy(cur, stack); + /* We will allocate new memory for this */ + XMEMSET(&cur->data, 0, sizeof(cur->data)); + cur->next = NULL; + + err = wolfssl_sk_dup_data(cur, stack); + if (err) { + break; + } + } + + if (err && (ret != NULL)) { + wolfSSL_sk_pop_free(ret, NULL); + ret = NULL; + } + + return ret; +} + +/* Shallow duplicate a stack of nodes. + * + * @param [in] stack Stack of nodes. + * @return A new stack of nodes with data duplicated/copied on success. + * @return NULL on error. + */ +WOLFSSL_STACK* wolfSSL_shallow_sk_dup(WOLFSSL_STACK* stack) +{ + + WOLFSSL_STACK* ret = NULL; + WOLFSSL_STACK** prev = &ret; + + WOLFSSL_ENTER("wolfSSL_shallow_sk_dup"); + + for (; stack != NULL; stack = stack->next) { + WOLFSSL_STACK* cur = wolfSSL_sk_new_node(stack->heap); + if (cur == NULL) { + WOLFSSL_MSG("wolfSSL_sk_new_node error"); + wolfSSL_sk_free(ret); + ret = NULL; + break; + } + + wolfssl_sk_node_copy(cur, stack); + cur->next = NULL; + + *prev = cur; + prev = &cur->next; + } + + return ret; +} +#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ + +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \ + defined(OPENSSL_ALL) +/* Free the nodes in the stack only. + * + * @param [in] stack Stack of nodes. + */ +void wolfSSL_sk_free(WOLFSSL_STACK* stack) +{ + WOLFSSL_ENTER("wolfSSL_sk_free"); + + while (stack != NULL) { + WOLFSSL_STACK* next = stack->next; + wolfSSL_sk_free_node(stack); + stack = next; + } +} +#endif + +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \ + defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_ALL) +/* Get the number of nodes in the stack. + * + * @param [in] stack Stack of nodes. + * @return Number of nodes in stack on success. + * @return 0 when no nodes or stack is NULL. + */ +int wolfSSL_sk_num(const WOLFSSL_STACK* stack) +{ + int num = 0; + + WOLFSSL_ENTER("wolfSSL_sk_num"); + + if (stack != NULL) { + num = (int)stack->num; + } + + return num; +} + +/* Get the value/data in a node from the stack at the index. + * + * If stack type is STACK_TYPE_CONF_VALUE and OPENSSL_EXTRA is not defined, + * the value will be NULL. + * + * @param [in] stack Stack of nodes. + * @param [in] i Index of node to get value/data. + * @return Data in node at index on success. + * @return NULL when no node at index. + */ +void* wolfSSL_sk_value(const WOLFSSL_STACK* sk, int i) +{ + void* val; + + WOLFSSL_ENTER("wolfSSL_sk_value"); + + for (; (sk != NULL) && (i > 0); i--) { + sk = sk->next; + } + + if (sk == NULL) { + val = NULL; + } + else { + switch (sk->type) { + case STACK_TYPE_CIPHER: + val = (void*)&sk->data.cipher; + break; + case STACK_TYPE_CONF_VALUE: + #ifndef OPENSSL_EXTRA + val = NULL; + break; + #endif + case STACK_TYPE_X509: + case STACK_TYPE_GEN_NAME: + case STACK_TYPE_BIO: + case STACK_TYPE_OBJ: + case STACK_TYPE_STRING: + case STACK_TYPE_ACCESS_DESCRIPTION: + case STACK_TYPE_X509_EXT: + case STACK_TYPE_X509_REQ_ATTR: + case STACK_TYPE_NULL: + case STACK_TYPE_X509_NAME: + case STACK_TYPE_X509_NAME_ENTRY: + case STACK_TYPE_X509_INFO: + case STACK_TYPE_BY_DIR_entry: + case STACK_TYPE_BY_DIR_hash: + case STACK_TYPE_X509_OBJ: + case STACK_TYPE_DIST_POINT: + case STACK_TYPE_X509_CRL: + default: + val = sk->data.generic; + break; + } + } + + return val; +} +#endif + +#if (!defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || \ + defined(WOLFSSL_WPAS_SMALL))) || defined(WOLFSSL_QT) || \ + defined(OPENSSL_ALL) +/* Put the data into a node at the top of the stack. + * + * @param [in, out] stack Stack of objects. + * @param [in] data Data to store in stack. + * @return Number of nodes in stack on success. + * @return WOLFSSL_FAILURE when data is NULL. + * @return WOLFSSL_FATAL_ERROR when stack is NULL. + */ +int wolfSSL_sk_push(WOLFSSL_STACK* stack, const void *data) +{ + WOLFSSL_ENTER("wolfSSL_sk_push"); + + return wolfSSL_sk_insert(stack, data, -1); +} + +/* Put the data into a node at an index in the stack. + * + * @param [in, out] stack Stack of objects. + * @param [in] data Data to store in stack. + * @return Number of nodes in stack on success. + * @return WOLFSSL_FAILURE when data is NULL. + * @return WOLFSSL_FATAL_ERROR when stack is NULL. + */ +int wolfSSL_sk_insert(WOLFSSL_STACK *stack, const void *data, int idx) +{ + int ret; + WOLFSSL_STACK* node; + WOLFSSL_ENTER("wolfSSL_sk_insert"); + + /* Validate parameters. */ + if (stack == NULL) { + ret = WOLFSSL_FATAL_ERROR; + } + else if (data == NULL) { + ret = WOLFSSL_FAILURE; + } + else if (stack->num == 0) { + /* No data set in stack - set data into empty first node. */ + wolfssl_sk_node_set_data(stack, stack->type, data); + stack->num = 1; + ret = 1; + } + else { + /* Create a new node. */ + node = wolfSSL_sk_new_node(stack->heap); + if (node == NULL) { + WOLFSSL_MSG("Memory error"); + ret = WOLFSSL_FAILURE; + } + else { + /* Place at front of linked-list. */ + if (idx == 0) { + /* Special case where we need to change the values in the head + * element to avoid changing the initial pointer. */ + wolfssl_sk_node_copy(node, stack); + wolfssl_sk_node_set_data(stack, stack->type, data); + stack->num++; + stack->next = node; + } + /* Place new node with data into list. */ + else { + WOLFSSL_STACK* prev; + unsigned long num = stack->num; + + node->type = stack->type; + #ifdef OPENSSL_ALL + node->hash_fn = stack->hash_fn; + #endif + /* Put data into new node. */ + wolfssl_sk_node_set_data(node, stack->type, data); + + /* Update count as new node being placed after first. */ + stack->num++; + prev = stack; + while (((--idx) != 0) && (prev->next != NULL)) { + prev = prev->next; + /* Update count as new node being placed after this one. */ + prev->num = num--; + } + /* Set count for new node. */ + node->num = num; + /* Place node in linked list after prev. */ + node->next = prev->next; + prev->next = node; + } + + /* Returning new stack count. */ + ret = (int)stack->num; + } + } + + return ret; +} +#endif + +#if !defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || \ + defined(WOLFSSL_WPAS_SMALL)) +/* Remove the top node from the stack and return its data. + * + * @param [in, out] stack Stack of nodes with data. + * @return Data in top node on success. + * @return NULL when stack is NULL or stack is empty. + */ +void* wolfSSL_sk_pop(WOLFSSL_STACK* stack) +{ + WOLFSSL_ENTER("wolfSSL_sk_pop"); + + return wolfSSL_sk_pop_node(stack, -1); +} + +#endif /* !NO_CERTS && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */ + +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) +/* Pop off data from the stack. Checks that the type matches the stack type. + * + * This is an internal API. + * + * @param [in, out] stack Stack of data. + * @param [in] type Type of stack. + * @return Data on success. + * @return NULL when stack is NULL or no nodes left in stack. + */ +void* wolfssl_sk_pop_type(WOLFSSL_STACK* stack, WOLF_STACK_TYPE type) +{ + void* data = NULL; + + /* Check we have a stack passed in of the right type. */ + if ((stack != NULL) && (stack->type == type)) + data = wolfSSL_sk_pop(stack); + + return data; +} +#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ + +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \ + defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_ALL) +/* Get the free function for the stack type. + * + * @param [in] type Type of stack object. + * @return A free function on success. + * @return NULL when no free function to use. + */ +static wolfSSL_sk_freefunc wolfssl_sk_get_free_func(WOLF_STACK_TYPE type) +{ + wolfSSL_sk_freefunc func = NULL; + + switch(type) { + case STACK_TYPE_ACCESS_DESCRIPTION: + #if defined(OPENSSL_ALL) + func = (wolfSSL_sk_freefunc)wolfSSL_ACCESS_DESCRIPTION_free; + #endif + break; + case STACK_TYPE_X509: + func = (wolfSSL_sk_freefunc)wolfSSL_X509_free; + break; + case STACK_TYPE_X509_OBJ: + #ifdef OPENSSL_ALL + func = (wolfSSL_sk_freefunc)wolfSSL_X509_OBJECT_free; + #endif + break; + case STACK_TYPE_OBJ: + func = (wolfSSL_sk_freefunc)wolfSSL_ASN1_OBJECT_free; + break; + case STACK_TYPE_DIST_POINT: + #ifdef OPENSSL_EXTRA + func = (wolfSSL_sk_freefunc)wolfSSL_DIST_POINT_free; + #endif + break; + case STACK_TYPE_GEN_NAME: + func = (wolfSSL_sk_freefunc)wolfSSL_GENERAL_NAME_free; + break; + case STACK_TYPE_STRING: + #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ + defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) + func = (wolfSSL_sk_freefunc)wolfSSL_WOLFSSL_STRING_free; + #endif + break; + case STACK_TYPE_X509_NAME: + #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \ + && !defined(WOLFCRYPT_ONLY) + func = (wolfSSL_sk_freefunc)wolfSSL_X509_NAME_free; + #endif + break; + case STACK_TYPE_X509_NAME_ENTRY: + #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \ + && !defined(WOLFCRYPT_ONLY) + func = (wolfSSL_sk_freefunc)wolfSSL_X509_NAME_ENTRY_free; + #endif + break; + case STACK_TYPE_X509_EXT: + #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) + func = (wolfSSL_sk_freefunc)wolfSSL_X509_EXTENSION_free; + #endif + break; + case STACK_TYPE_X509_REQ_ATTR: + #if defined(OPENSSL_ALL) && \ + (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_REQ)) + func = (wolfSSL_sk_freefunc)wolfSSL_X509_ATTRIBUTE_free; + #endif + break; + case STACK_TYPE_CONF_VALUE: + #if defined(OPENSSL_ALL) + func = (wolfSSL_sk_freefunc)wolfSSL_X509V3_conf_free; + #endif + break; + case STACK_TYPE_X509_INFO: + #if defined(OPENSSL_ALL) + func = (wolfSSL_sk_freefunc)wolfSSL_X509_INFO_free; + #endif + break; + case STACK_TYPE_BIO: + #if !defined(NO_BIO) && defined(OPENSSL_EXTRA) + func = (wolfSSL_sk_freefunc)wolfSSL_BIO_vfree; + #endif + break; + case STACK_TYPE_BY_DIR_entry: + #if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && \ + !defined(NO_WOLFSSL_DIR) + func = (wolfSSL_sk_freefunc)wolfSSL_BY_DIR_entry_free; + #endif + break; + case STACK_TYPE_BY_DIR_hash: + #if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && \ + !defined(NO_WOLFSSL_DIR) + func = (wolfSSL_sk_freefunc)wolfSSL_BY_DIR_HASH_free; + #endif + break; + case STACK_TYPE_X509_CRL: + #if defined(HAVE_CRL) && (defined(OPENSSL_EXTRA) || \ + defined(WOLFSSL_WPAS_SMALL)) + func = (wolfSSL_sk_freefunc)wolfSSL_X509_CRL_free; + #endif + break; + case STACK_TYPE_CIPHER: + /* Static copy kept in node. */ + case STACK_TYPE_NULL: + default: + break; + } + + return func; +} + +/* Free all nodes and the dynamic data associated with them. + * + * This is an internal API. + * + * @param [in, out] sk Stack of objects. + * @param [in] func Function to use to free objects. + */ +void wolfSSL_sk_pop_free(WOLFSSL_STACK* stack, wolfSSL_sk_freefunc func) +{ + WOLFSSL_ENTER("wolfSSL_sk_pop_free"); + + /* Validate parameters. */ + if (stack == NULL) { + /* pop_free can be called with NULL, do not print bad argument */ + return; + } +#if defined(WOLFSSL_QT) + /* In Qt v15.5, it calls OPENSSL_sk_free(xxx, OPENSSL_sk_free). + * By using OPENSSL_sk_free for free causes access violation. + * Therefore, switching free func to wolfSSL_ACCESS_DESCRIPTION_free + * is needed even when func isn't NULL. + */ + if (stack->type == STACK_TYPE_ACCESS_DESCRIPTION) { + func = (wolfSSL_sk_freefunc)wolfSSL_ACCESS_DESCRIPTION_free; + } +#endif + /* Discover free function if none provided. */ + if (func == NULL) { + func = wolfssl_sk_get_free_func(stack->type); + } + + /* Free all nodes and data. */ + while (stack != NULL) { + WOLFSSL_STACK* next = stack->next; + + /* Free the data of the node. */ + if ((func != NULL) && (stack->type != STACK_TYPE_CIPHER)) { + func(stack->data.generic); + } + /* Dispose of node. */ + XFREE(stack, stack->heap, DYNAMIC_TYPE_OPENSSL); + stack = next; + } +} +#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ + +/******************************************************************************* + * Stack - Generic + ******************************************************************************/ + +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) +/* Free the nodes in the stack only. + * + * @param [in] stack Stack of nodes. + */ +void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK* sk) +{ + wolfSSL_sk_free(sk); +} + +/* Free all nodes and the dynamic data associated with them. + * + * This is an internal API. + * + * @param [in, out] sk Stack of objects. + * @param [in] func Function to use to free objects. + */ +void wolfSSL_sk_GENERIC_pop_free(WOLFSSL_STACK* sk, void (*f) (void*)) +{ + WOLFSSL_ENTER("wolfSSL_sk_GENERIC_pop_free"); + wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f); +} + +/* Put the data into a node at the top of the stack. + * + * @param [in, out] stack Stack of objects. + * @param [in] data Data to store in stack. + * @return Number of nodes in stack on success. + * @return WOLFSSL_FAILURE when data is NULL. + * @return WOLFSSL_FATAL_ERROR when stack is NULL. + */ +int wolfSSL_sk_GENERIC_push(WOLFSSL_STACK* sk, void* generic) +{ + WOLFSSL_ENTER("wolfSSL_sk_GENERIC_push"); + + return wolfSSL_sk_push(sk, generic); +} +#endif + +/******************************************************************************* + * Stack - Compression + ******************************************************************************/ + +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) +/* Get the number of compression algorithms in stack. + * + * @param [in] stack Stack of compression algorithms. + * @return Number of compression algorithms in stack on success. + * @return 0 when no compression algorithms or stack is NULL. + */ +int wolfSSL_sk_SSL_COMP_num(WOLF_STACK_OF(WOLFSSL_COMP)* stack) +{ + return wolfSSL_sk_num(stack); +} +#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ + +#if defined(OPENSSL_EXTRA) && !defined(NO_WOLFSSL_STUB) +/* Remove all compression algorithms from stack. + * + * TBD + * Used when + * wolfSSL_set_options(ssl, SSL_OP_NO_COMPRESSION); + * is called. + * + * @param [in, out] stack Stack of compression algorithms. + * @return WOLFSSL_FAILURE always. + */ +int wolfSSL_sk_SSL_COMP_zero(WOLFSSL_STACK* stack) +{ + (void)stack; + WOLFSSL_STUB("wolfSSL_sk_SSL_COMP_zero"); + return WOLFSSL_FAILURE; +} +#endif + +/******************************************************************************* + * Stack - Cipher + ******************************************************************************/ + +#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) +/* Creates a new stack of ciphers. + * + * This is not an OpenSSL API. + * + * @return Empty stack on success. + * @return NULL when dynamic memory allocation fails. + */ +WOLFSSL_STACK* wolfSSL_sk_new_cipher(void) +{ + return wolfssl_sk_new_type(STACK_TYPE_CIPHER); +} + +/* Put the cipher into a node at the top of the stack. + * + * This is an internal API. + * + * @param [in, out] stack Stack of ciphers. + * @param [in] cipher Cipher to store in stack. + * @return Number of ciphers in stack on success. + * @return WOLFSSL_FAILURE when data is NULL. + * @return WOLFSSL_FATAL_ERROR when stack is NULL. + */ +int wolfSSL_sk_CIPHER_push(WOLF_STACK_OF(WOLFSSL_CIPHER)* stack, + WOLFSSL_CIPHER* cipher) +{ + return wolfSSL_sk_push(stack, cipher); +} + +#ifndef NO_WOLFSSL_STUB +/* Does not do anythting at this time. + * + * @param [in, out] stack Stack of nodes with data. + * @return NULL always. + */ +WOLFSSL_CIPHER* wolfSSL_sk_CIPHER_pop(WOLF_STACK_OF(WOLFSSL_CIPHER)* stack) +{ + WOLFSSL_STUB("wolfSSL_sk_CIPHER_pop"); + (void)stack; + return NULL; +} +#endif /* NO_WOLFSSL_STUB */ +#endif /* WOLFSSL_QT || OPENSSL_ALL */ + +#if defined(OPENSSL_EXTRA) +/* Free the nodes in the stack only. + * + * Ciphers are stored into a structure in a node and therefore don't need to be + * freed. + * + * @param [in] ciphers Stack of ciphers. + */ +void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* ciphers) +{ + WOLFSSL_ENTER("wolfSSL_sk_CIPHER_free"); + + wolfSSL_sk_free(ciphers); +} +#endif /* OPENSSL_ALL */ + +#ifdef OPENSSL_EXTRA +/* Get the number of ciphers in the stack. + * + * @param [in] ciphers Stack of ciphers. + * @return Number of strings in stack on success. + * @return 0 when no strings or stack is NULL. + */ +int wolfSSL_sk_SSL_CIPHER_num(const WOLF_STACK_OF(WOLFSSL_CIPHER)* ciphers) +{ + WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_num"); + return wolfSSL_sk_num(ciphers); +} + +/* Get the cipher from the stack at the index. + * + * @param [in] ciphers Stack of cihers + * @param [in] i Index of node to get cipher from. + * @return Cipher in node at index on success. + * @return NULL when no node at index. + */ +WOLFSSL_CIPHER* wolfSSL_sk_SSL_CIPHER_value(WOLFSSL_STACK* ciphers, int i) +{ + WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_value"); + return (WOLFSSL_CIPHER*)wolfSSL_sk_value(ciphers, i); +} +#endif + +#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) +/* Get the priority level of the cipher if it is in the stack. + * + * Priority level is the number of ciphers minus the idex of the cipher. + * + * @param [in] ciphers Stack of ciphers. + * @param [in] cipher Cipher to find in stack. + * @return Priority level of cipher on success. + * @return WOLFSSL_FATAL_ERROR (-1) on failure to match. + */ +int wolfSSL_sk_SSL_CIPHER_find(WOLF_STACK_OF(WOLFSSL_CIPHER)* ciphers, + const WOLFSSL_CIPHER* cipher) +{ + int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR); + + if (ciphers != NULL && cipher != NULL) { + int i; + int num = wolfSSL_sk_SSL_CIPHER_num(ciphers); + WOLFSSL_STACK* next = ciphers; + + for (i = 0; (i < num) && (next != NULL); i++) { + /* Match on SSL/TLS cipher suite values. */ + if ((next->data.cipher.cipherSuite0 == cipher->cipherSuite0) && + (next->data.cipher.cipherSuite == cipher->cipherSuite)) { + /* reverse because stack pushed highest on first */ + ret = num - i; + break; + } + next = next->next; + } + } + + return ret; +} + +/* Free the nodes in the stack only. + * + * @param [in] ciphers Stack of ciphers. + */ +void wolfSSL_sk_SSL_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk) +{ + WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_free"); + wolfSSL_sk_free(sk); +} +#endif /* OPENSSL_ALL || OPENSSL_EXTRA */ + +/******************************************************************************* + * Stack - String + ******************************************************************************/ + +#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ + defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) +/* Creates a new stack of strings. + * + * @return Empty stack on success. + * @return NULL when dynamic memory allocation fails. + */ +WOLF_STACK_OF(WOLFSSL_STRING)* wolfSSL_sk_WOLFSSL_STRING_new(void) +{ + return wolfssl_sk_new_type(STACK_TYPE_STRING); +} + +/* Free the nodes and strings of the stack. + * + * OpenSSL equivalent does not free data. + * + * @param [in] strings Stack of strings. + */ +void wolfSSL_sk_WOLFSSL_STRING_free(WOLF_STACK_OF(WOLFSSL_STRING)* strings) +{ + WOLFSSL_ENTER("wolfSSL_sk_WOLFSSL_STRING_free"); + + wolfSSL_sk_pop_free(strings, NULL); +} + +/* Get the string from the node at an index. + * + * @param [in] strings Stack of strings. + * @param [in] idx Index of node. + * @return String in node at index on success. + * @return NULL when no node at index. + */ +WOLFSSL_STRING wolfSSL_sk_WOLFSSL_STRING_value( + WOLF_STACK_OF(WOLFSSL_STRING)* strings, int idx) +{ + return (WOLFSSL_STRING)wolfSSL_sk_value(strings, idx); +} + +/* Get the number of strings in the stack. + * + * @param [in] strings Stack of strings. + * @return Number of strings in stack on success. + * @return 0 when no strings or stack is NULL. + */ +int wolfSSL_sk_WOLFSSL_STRING_num(WOLF_STACK_OF(WOLFSSL_STRING)* strings) +{ + return wolfSSL_sk_num(strings); +} +#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */ + +/******************************************************************************* + * Stack - Linear Hash + ******************************************************************************/ + +#if !defined(NO_CERTS) && defined(OPENSSL_EXTRA) && defined(OPENSSL_ALL) +/* Retrieve data from the stack by comparing with hash. + * + * @param [in] stack Stack of data. + * @param [in] data Data to look-up. + * @return Data of node with the same hash as data passed in. + * @return NULL when no match found. + */ +void *wolfSSL_lh_retrieve(WOLFSSL_STACK *stack, void *data) +{ + unsigned long hash; + void* sk_data = NULL; + + WOLFSSL_ENTER("wolfSSL_lh_retrieve"); + + /* Validate parameters. */ + if ((stack == NULL) || (data == NULL)) { + WOLFSSL_MSG("Bad parameters"); + } + else if (stack->hash_fn == NULL) { + WOLFSSL_MSG("No hash function defined"); + } + else { + /* Calculate hassh of data we are looking for. */ + hash = stack->hash_fn(data); + + while (stack != NULL) { + /* Calculate hash if not done so yet. */ + if (!stack->hash) { + sk_data = wolfssl_sk_node_get_data(stack, 0); + stack->hash = stack->hash_fn(sk_data); + } + /* Return data if hash matches. */ + if (stack->hash == hash) { + if (sk_data == NULL) { + sk_data = wolfssl_sk_node_get_data(stack, 0); + } + break; + } + + /* Not data to return. */ + sk_data = NULL; + stack = stack->next; + } + } + + return sk_data; +} +#endif /* !NO_CERTS && OPENSSL_EXTRA && OPENSSL_ALL */ + +#endif /* !WOLFSSL_SSL_SK_INCLUDED */ diff --git a/tests/api.c b/tests/api.c index 30b9dcddb..1730db85e 100644 --- a/tests/api.c +++ b/tests/api.c @@ -227,6 +227,7 @@ #include #include #include +#include #include #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), diff --git a/tests/api/include.am b/tests/api/include.am index 21d7dd89e..d6274cbff 100644 --- a/tests/api/include.am +++ b/tests/api/include.am @@ -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 diff --git a/tests/api/test_ossl_sk.c b/tests/api/test_ossl_sk.c new file mode 100644 index 000000000..23d69b1c2 --- /dev/null +++ b/tests/api/test_ossl_sk.c @@ -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 + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#include +#include +#include +#include + + +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(); +} + diff --git a/tests/api/test_ossl_sk.h b/tests/api/test_ossl_sk.h new file mode 100644 index 000000000..0ab75398e --- /dev/null +++ b/tests/api/test_ossl_sk.h @@ -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 + +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 */ + diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index b8570f3f6..779898989 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -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); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 064dedcdf..ca8f4f81d 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -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,