summaryrefslogtreecommitdiff
path: root/crypto/stack/stack.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/stack/stack.c')
-rw-r--r--crypto/stack/stack.c155
1 files changed, 110 insertions, 45 deletions
diff --git a/crypto/stack/stack.c b/crypto/stack/stack.c
index 975515db5972..51080b876797 100644
--- a/crypto/stack/stack.c
+++ b/crypto/stack/stack.c
@@ -1,7 +1,7 @@
/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -11,7 +11,6 @@
#include "internal/cryptlib.h"
#include "internal/numbers.h"
#include <openssl/stack.h>
-#include <openssl/objects.h>
#include <errno.h>
#include <openssl/e_os2.h> /* For ossl_inline */
@@ -20,8 +19,7 @@
*/
static const int min_nodes = 4;
static const int max_nodes = SIZE_MAX / sizeof(void *) < INT_MAX
- ? (int)(SIZE_MAX / sizeof(void *))
- : INT_MAX;
+ ? (int)(SIZE_MAX / sizeof(void *)) : INT_MAX;
struct stack_st {
int num;
@@ -31,7 +29,8 @@ struct stack_st {
OPENSSL_sk_compfunc comp;
};
-OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, OPENSSL_sk_compfunc c)
+OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk,
+ OPENSSL_sk_compfunc c)
{
OPENSSL_sk_compfunc old = sk->comp;
@@ -46,46 +45,58 @@ OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *sk)
{
OPENSSL_STACK *ret;
- if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) {
- CRYPTOerr(CRYPTO_F_OPENSSL_SK_DUP, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
+ if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
+ goto err;
- /* direct structure assignment */
- *ret = *sk;
+ if (sk == NULL) {
+ ret->num = 0;
+ ret->sorted = 0;
+ ret->comp = NULL;
+ } else {
+ /* direct structure assignment */
+ *ret = *sk;
+ }
- if (sk->num == 0) {
+ if (sk == NULL || sk->num == 0) {
/* postpone |ret->data| allocation */
ret->data = NULL;
ret->num_alloc = 0;
return ret;
}
+
/* duplicate |sk->data| content */
- if ((ret->data = OPENSSL_malloc(sizeof(*ret->data) * sk->num_alloc)) == NULL)
+ ret->data = OPENSSL_malloc(sizeof(*ret->data) * sk->num_alloc);
+ if (ret->data == NULL)
goto err;
memcpy(ret->data, sk->data, sizeof(void *) * sk->num);
return ret;
+
err:
+ ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
OPENSSL_sk_free(ret);
return NULL;
}
OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk,
- OPENSSL_sk_copyfunc copy_func,
- OPENSSL_sk_freefunc free_func)
+ OPENSSL_sk_copyfunc copy_func,
+ OPENSSL_sk_freefunc free_func)
{
OPENSSL_STACK *ret;
int i;
- if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) {
- CRYPTOerr(CRYPTO_F_OPENSSL_SK_DEEP_COPY, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
+ if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
+ goto err;
- /* direct structure assignment */
- *ret = *sk;
+ if (sk == NULL) {
+ ret->num = 0;
+ ret->sorted = 0;
+ ret->comp = NULL;
+ } else {
+ /* direct structure assignment */
+ *ret = *sk;
+ }
- if (sk->num == 0) {
+ if (sk == NULL || sk->num == 0) {
/* postpone |ret| data allocation */
ret->data = NULL;
ret->num_alloc = 0;
@@ -94,10 +105,8 @@ OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk,
ret->num_alloc = sk->num > min_nodes ? sk->num : min_nodes;
ret->data = OPENSSL_zalloc(sizeof(*ret->data) * ret->num_alloc);
- if (ret->data == NULL) {
- OPENSSL_free(ret);
- return NULL;
- }
+ if (ret->data == NULL)
+ goto err;
for (i = 0; i < ret->num; ++i) {
if (sk->data[i] == NULL)
@@ -106,11 +115,15 @@ OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk,
while (--i >= 0)
if (ret->data[i] != NULL)
free_func((void *)ret->data[i]);
- OPENSSL_sk_free(ret);
- return NULL;
+ goto err;
}
}
return ret;
+
+ err:
+ ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
+ OPENSSL_sk_free(ret);
+ return NULL;
}
OPENSSL_STACK *OPENSSL_sk_new_null(void)
@@ -163,8 +176,10 @@ static int sk_reserve(OPENSSL_STACK *st, int n, int exact)
int num_alloc;
/* Check to see the reservation isn't exceeding the hard limit */
- if (n > max_nodes - st->num)
+ if (n > max_nodes - st->num) {
+ ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_RECORDS);
return 0;
+ }
/* Figure out the new size */
num_alloc = st->num + n;
@@ -178,7 +193,7 @@ static int sk_reserve(OPENSSL_STACK *st, int n, int exact)
* so |num_alloc| value is |n| or |min_nodes| if greater than |n|.
*/
if ((st->data = OPENSSL_zalloc(sizeof(void *) * num_alloc)) == NULL) {
- CRYPTOerr(CRYPTO_F_SK_RESERVE, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
return 0;
}
st->num_alloc = num_alloc;
@@ -189,15 +204,19 @@ static int sk_reserve(OPENSSL_STACK *st, int n, int exact)
if (num_alloc <= st->num_alloc)
return 1;
num_alloc = compute_growth(num_alloc, st->num_alloc);
- if (num_alloc == 0)
+ if (num_alloc == 0) {
+ ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_RECORDS);
return 0;
+ }
} else if (num_alloc == st->num_alloc) {
return 1;
}
tmpdata = OPENSSL_realloc((void *)st->data, sizeof(void *) * num_alloc);
- if (tmpdata == NULL)
+ if (tmpdata == NULL) {
+ ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
return 0;
+ }
st->data = tmpdata;
st->num_alloc = num_alloc;
@@ -208,8 +227,10 @@ OPENSSL_STACK *OPENSSL_sk_new_reserve(OPENSSL_sk_compfunc c, int n)
{
OPENSSL_STACK *st = OPENSSL_zalloc(sizeof(OPENSSL_STACK));
- if (st == NULL)
+ if (st == NULL) {
+ ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
return NULL;
+ }
st->comp = c;
@@ -226,8 +247,10 @@ OPENSSL_STACK *OPENSSL_sk_new_reserve(OPENSSL_sk_compfunc c, int n)
int OPENSSL_sk_reserve(OPENSSL_STACK *st, int n)
{
- if (st == NULL)
+ if (st == NULL) {
+ ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
return 0;
+ }
if (n < 0)
return 1;
@@ -236,8 +259,14 @@ int OPENSSL_sk_reserve(OPENSSL_STACK *st, int n)
int OPENSSL_sk_insert(OPENSSL_STACK *st, const void *data, int loc)
{
- if (st == NULL || st->num == max_nodes)
+ if (st == NULL) {
+ ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ if (st->num == max_nodes) {
+ ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_RECORDS);
return 0;
+ }
if (!sk_reserve(st, 1, 0))
return 0;
@@ -259,8 +288,8 @@ static ossl_inline void *internal_delete(OPENSSL_STACK *st, int loc)
const void *ret = st->data[loc];
if (loc != st->num - 1)
- memmove(&st->data[loc], &st->data[loc + 1],
- sizeof(st->data[0]) * (st->num - loc - 1));
+ memmove(&st->data[loc], &st->data[loc + 1],
+ sizeof(st->data[0]) * (st->num - loc - 1));
st->num--;
return (void *)ret;
@@ -270,6 +299,9 @@ void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *st, const void *p)
{
int i;
+ if (st == NULL)
+ return NULL;
+
for (i = 0; i < st->num; i++)
if (st->data[i] == p)
return internal_delete(st, i);
@@ -285,7 +317,7 @@ void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc)
}
static int internal_find(OPENSSL_STACK *st, const void *data,
- int ret_val_options)
+ int ret_val_options, int *pnum)
{
const void *r;
int i;
@@ -295,8 +327,13 @@ static int internal_find(OPENSSL_STACK *st, const void *data,
if (st->comp == NULL) {
for (i = 0; i < st->num; i++)
- if (st->data[i] == data)
+ if (st->data[i] == data) {
+ if (pnum != NULL)
+ *pnum = 1;
return i;
+ }
+ if (pnum != NULL)
+ *pnum = 0;
return -1;
}
@@ -307,20 +344,41 @@ static int internal_find(OPENSSL_STACK *st, const void *data,
}
if (data == NULL)
return -1;
- r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp,
- ret_val_options);
+ if (pnum != NULL)
+ ret_val_options |= OSSL_BSEARCH_FIRST_VALUE_ON_MATCH;
+ r = ossl_bsearch(&data, st->data, st->num, sizeof(void *), st->comp,
+ ret_val_options);
+
+ if (pnum != NULL) {
+ *pnum = 0;
+ if (r != NULL) {
+ const void **p = (const void **)r;
+
+ while (p < st->data + st->num) {
+ if (st->comp(&data, p) != 0)
+ break;
+ ++*pnum;
+ ++p;
+ }
+ }
+ }
return r == NULL ? -1 : (int)((const void **)r - st->data);
}
int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data)
{
- return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH);
+ return internal_find(st, data, OSSL_BSEARCH_FIRST_VALUE_ON_MATCH, NULL);
}
int OPENSSL_sk_find_ex(OPENSSL_STACK *st, const void *data)
{
- return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH);
+ return internal_find(st, data, OSSL_BSEARCH_VALUE_ON_NOMATCH, NULL);
+}
+
+int OPENSSL_sk_find_all(OPENSSL_STACK *st, const void *data, int *pnum)
+{
+ return internal_find(st, data, OSSL_BSEARCH_FIRST_VALUE_ON_MATCH, pnum);
}
int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data)
@@ -391,8 +449,15 @@ void *OPENSSL_sk_value(const OPENSSL_STACK *st, int i)
void *OPENSSL_sk_set(OPENSSL_STACK *st, int i, const void *data)
{
- if (st == NULL || i < 0 || i >= st->num)
+ if (st == NULL) {
+ ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
+ }
+ if (i < 0 || i >= st->num) {
+ ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT,
+ "i=%d", i);
+ return NULL;
+ }
st->data[i] = data;
st->sorted = 0;
return (void *)st->data[i];