#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
#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
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
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)
void wolfSSL_sk_free_node(WOLFSSL_STACK* node)
{
if (node != NULL) {
XFREE(node, node->heap, DYNAMIC_TYPE_OPENSSL);
}
}
#endif
#if !defined(NO_CERTS) && defined(OPENSSL_EXTRA)
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
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
#ifndef NO_CERTS
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:
case STACK_TYPE_X509_REVOKED:
case STACK_TYPE_GENERAL_SUBTREE:
default:
ret = node->data.generic;
break;
}
return ret;
}
static void wolfssl_sk_node_set_data(WOLFSSL_STACK* node, WOLF_STACK_TYPE type,
const void* data)
{
switch (type) {
case STACK_TYPE_CIPHER:
node->data.cipher = *(WOLFSSL_CIPHER*)data;
#ifdef OPENSSL_ALL
if (node->hash_fn != NULL)
node->hash = node->hash_fn(&node->data.cipher);
#endif
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:
case STACK_TYPE_X509_REVOKED:
case STACK_TYPE_GENERAL_SUBTREE:
default:
node->data.generic = (void*)data;
#ifdef OPENSSL_ALL
if (node->hash_fn != NULL)
node->hash = node->hash_fn(node->data.generic);
#endif
break;
}
}
int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* node)
{
int ret = WOLFSSL_SUCCESS;
if (stack == NULL || node == NULL) {
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS) {
if (*stack == NULL) {
node->num = 1;
}
else {
node->num = (*stack)->num + 1;
node->next = *stack;
}
*stack = node;
}
return ret;
}
int wolfSSL_sk_push_back_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* node)
{
int ret = WOLFSSL_SUCCESS;
if (stack == NULL || node == NULL) {
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS) {
node->next = NULL;
node->num = 1;
if (*stack == NULL) {
*stack = node;
}
else {
WOLFSSL_STACK* cur = *stack;
while (cur->next != NULL) {
cur->num++;
cur = cur->next;
}
cur->num++;
cur->next = node;
}
}
return ret;
}
void* wolfSSL_sk_pop_node(WOLFSSL_STACK* stack, int idx)
{
void* ret = NULL;
WOLFSSL_STACK* tmp = NULL;
WOLFSSL_STACK* prev;
if ((stack != NULL) && (stack->num != 0)) {
stack->num--;
if (idx == 0 || stack->next == NULL) {
ret = wolfssl_sk_node_get_data(stack, 1);
if (ret != NULL) {
stack->data.generic = NULL;
}
if (stack->next) {
tmp = stack->next;
XMEMCPY(stack, stack->next, sizeof(WOLFSSL_STACK));
wolfSSL_sk_free_node(tmp);
}
}
else {
prev = stack;
tmp = stack->next;
while ((--idx != 0) && (tmp->next != NULL)) {
prev = tmp;
prev->num--;
tmp = tmp->next;
}
prev->next = tmp->next;
ret = wolfssl_sk_node_get_data(tmp, 1);
wolfSSL_sk_free_node(tmp);
}
}
return ret;
}
#endif
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
WOLFSSL_STACK* wolfssl_sk_new_type(WOLF_STACK_TYPE type)
{
return wolfssl_sk_new_type_ex(type, NULL);
}
WOLFSSL_STACK* wolfssl_sk_new_type_ex(WOLF_STACK_TYPE type, void* heap)
{
WOLFSSL_STACK* stack = wolfSSL_sk_new_node(heap);
if (stack != NULL) {
stack->type = type;
}
return stack;
}
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
WOLFSSL_STACK* wolfSSL_sk_new_null(void)
{
WOLFSSL_ENTER("wolfSSL_sk_new_null");
return wolfssl_sk_new_type(STACK_TYPE_NULL);
}
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_CRL:
#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL)
if (src->data.crl == NULL) {
break;
}
dst->data.crl = wolfSSL_X509_CRL_dup(src->data.crl);
if (dst->data.crl == NULL) {
WOLFSSL_MSG("wolfSSL_X509_CRL_dup error");
err = 1;
break;
}
#else
WOLFSSL_MSG("CRL support not enabled");
err = 1;
#endif
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;
}
#else
WOLFSSL_MSG("OPENSSL_ALL support not enabled");
err = 1;
#endif
break;
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_REVOKED:
case STACK_TYPE_GENERAL_SUBTREE:
default:
WOLFSSL_MSG("Unsupported stack type");
err = 1;
break;
}
return err;
}
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) {
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) {
ret = cur;
}
if (last != NULL) {
last->next = cur;
}
last = cur;
XMEMCPY(cur, stack, sizeof(WOLFSSL_STACK));
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;
}
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;
}
XMEMCPY(cur, stack, sizeof(WOLFSSL_STACK));
cur->next = NULL;
*prev = cur;
prev = &cur->next;
}
return ret;
}
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
defined(OPENSSL_ALL)
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)
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;
}
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:
case STACK_TYPE_X509_REVOKED:
case STACK_TYPE_GENERAL_SUBTREE:
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)
int wolfSSL_sk_push(WOLFSSL_STACK* stack, const void *data)
{
WOLFSSL_ENTER("wolfSSL_sk_push");
return wolfSSL_sk_insert(stack, data, -1);
}
int wolfSSL_sk_insert(WOLFSSL_STACK *stack, const void *data, int idx)
{
int ret;
WOLFSSL_STACK* node;
WOLFSSL_ENTER("wolfSSL_sk_insert");
if (stack == NULL) {
ret = WOLFSSL_FATAL_ERROR;
}
else if (data == NULL) {
ret = WOLFSSL_FAILURE;
}
else if (stack->num == 0) {
wolfssl_sk_node_set_data(stack, stack->type, data);
stack->num = 1;
ret = 1;
}
else {
node = wolfSSL_sk_new_node(stack->heap);
if (node == NULL) {
WOLFSSL_MSG("Memory error");
ret = WOLFSSL_FAILURE;
}
else {
if (idx == 0) {
XMEMCPY(node, stack, sizeof(WOLFSSL_STACK));
wolfssl_sk_node_set_data(stack, stack->type, data);
stack->num++;
stack->next = node;
}
else {
WOLFSSL_STACK* prev;
unsigned long num = stack->num;
node->type = stack->type;
#ifdef OPENSSL_ALL
node->hash_fn = stack->hash_fn;
#endif
wolfssl_sk_node_set_data(node, stack->type, data);
stack->num++;
prev = stack;
while (((--idx) != 0) && (prev->next != NULL)) {
prev = prev->next;
prev->num = num--;
}
node->num = num;
node->next = prev->next;
prev->next = node;
}
ret = (int)stack->num;
}
}
return ret;
}
#endif
#if !defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || \
defined(WOLFSSL_WPAS_SMALL))
void* wolfSSL_sk_pop(WOLFSSL_STACK* stack)
{
WOLFSSL_ENTER("wolfSSL_sk_pop");
return wolfSSL_sk_pop_node(stack, -1);
}
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
void* wolfssl_sk_pop_type(WOLFSSL_STACK* stack, WOLF_STACK_TYPE type)
{
void* data = NULL;
if ((stack != NULL) && (stack->type == type))
data = wolfSSL_sk_pop(stack);
return data;
}
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_ALL)
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_GENERAL_SUBTREE:
#if defined(OPENSSL_EXTRA) && !defined(IGNORE_NAME_CONSTRAINTS)
func = (wolfSSL_sk_freefunc)wolfSSL_GENERAL_SUBTREE_free;
#endif
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_X509_REVOKED:
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA)
func = (wolfSSL_sk_freefunc)wolfSSL_X509_REVOKED_free;
#endif
break;
case STACK_TYPE_CIPHER:
case STACK_TYPE_NULL:
default:
break;
}
return func;
}
void wolfSSL_sk_pop_free(WOLFSSL_STACK* stack, wolfSSL_sk_freefunc func)
{
WOLFSSL_ENTER("wolfSSL_sk_pop_free");
if (stack == NULL) {
return;
}
#if defined(WOLFSSL_QT)
if (stack->type == STACK_TYPE_ACCESS_DESCRIPTION) {
func = (wolfSSL_sk_freefunc)wolfSSL_ACCESS_DESCRIPTION_free;
}
#endif
if (func == NULL) {
func = wolfssl_sk_get_free_func(stack->type);
}
while (stack != NULL) {
WOLFSSL_STACK* next = stack->next;
if ((func != NULL) && (stack->type != STACK_TYPE_CIPHER)) {
func(stack->data.generic);
}
XFREE(stack, stack->heap, DYNAMIC_TYPE_OPENSSL);
stack = next;
}
}
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK* sk)
{
wolfSSL_sk_free(sk);
}
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);
}
int wolfSSL_sk_GENERIC_push(WOLFSSL_STACK* sk, void* generic)
{
WOLFSSL_ENTER("wolfSSL_sk_GENERIC_push");
return wolfSSL_sk_push(sk, generic);
}
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
int wolfSSL_sk_SSL_COMP_num(WOLF_STACK_OF(WOLFSSL_COMP)* stack)
{
return wolfSSL_sk_num(stack);
}
#endif
#if defined(OPENSSL_EXTRA) && !defined(NO_WOLFSSL_STUB)
int wolfSSL_sk_SSL_COMP_zero(WOLFSSL_STACK* stack)
{
(void)stack;
WOLFSSL_STUB("wolfSSL_sk_SSL_COMP_zero");
return WOLFSSL_FAILURE;
}
#endif
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
WOLFSSL_STACK* wolfSSL_sk_new_cipher(void)
{
return wolfssl_sk_new_type(STACK_TYPE_CIPHER);
}
int wolfSSL_sk_CIPHER_push(WOLF_STACK_OF(WOLFSSL_CIPHER)* stack,
WOLFSSL_CIPHER* cipher)
{
return wolfSSL_sk_push(stack, cipher);
}
#ifndef NO_WOLFSSL_STUB
WOLFSSL_CIPHER* wolfSSL_sk_CIPHER_pop(WOLF_STACK_OF(WOLFSSL_CIPHER)* stack)
{
WOLFSSL_STUB("wolfSSL_sk_CIPHER_pop");
(void)stack;
return NULL;
}
#endif
#endif
#if defined(OPENSSL_EXTRA)
void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* ciphers)
{
WOLFSSL_ENTER("wolfSSL_sk_CIPHER_free");
wolfSSL_sk_free(ciphers);
}
#endif
#ifdef OPENSSL_EXTRA
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);
}
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)
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++) {
if ((next->data.cipher.cipherSuite0 == cipher->cipherSuite0) &&
(next->data.cipher.cipherSuite == cipher->cipherSuite)) {
ret = num - i;
break;
}
next = next->next;
}
}
return ret;
}
void wolfSSL_sk_SSL_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk)
{
WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_free");
wolfSSL_sk_free(sk);
}
#endif
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
WOLF_STACK_OF(WOLFSSL_STRING)* wolfSSL_sk_WOLFSSL_STRING_new(void)
{
return wolfssl_sk_new_type(STACK_TYPE_STRING);
}
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);
}
WOLFSSL_STRING wolfSSL_sk_WOLFSSL_STRING_value(
WOLF_STACK_OF(WOLFSSL_STRING)* strings, int idx)
{
return (WOLFSSL_STRING)wolfSSL_sk_value(strings, idx);
}
int wolfSSL_sk_WOLFSSL_STRING_num(WOLF_STACK_OF(WOLFSSL_STRING)* strings)
{
return wolfSSL_sk_num(strings);
}
#endif
#if !defined(NO_CERTS) && defined(OPENSSL_EXTRA) && defined(OPENSSL_ALL)
void *wolfSSL_lh_retrieve(WOLFSSL_STACK *stack, void *data)
{
unsigned long hash;
void* sk_data = NULL;
WOLFSSL_ENTER("wolfSSL_lh_retrieve");
if ((stack == NULL) || (data == NULL)) {
WOLFSSL_MSG("Bad parameters");
}
else if (stack->hash_fn == NULL) {
WOLFSSL_MSG("No hash function defined");
}
else {
hash = stack->hash_fn(data);
while (stack != NULL) {
if (!stack->hash) {
sk_data = wolfssl_sk_node_get_data(stack, 0);
stack->hash = stack->hash_fn(sk_data);
}
if (stack->hash == hash) {
if (sk_data == NULL) {
sk_data = wolfssl_sk_node_get_data(stack, 0);
}
break;
}
sk_data = NULL;
stack = stack->next;
}
}
return sk_data;
}
#endif
#endif