]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/stack/stack.c
Stop raising ERR_R_MALLOC_FAILURE in most places
[thirdparty/openssl.git] / crypto / stack / stack.c
CommitLineData
4f22f405 1/*
a28d06f3 2 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
d02b48c6 3 *
4fc56f90 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
4f22f405
RS
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
d02b48c6 8 */
4f22f405 9
d02b48c6 10#include <stdio.h>
b39fc560 11#include "internal/cryptlib.h"
9205ebeb 12#include "internal/numbers.h"
8347bfa0 13#include "internal/safe_math.h"
ec577822 14#include <openssl/stack.h>
1b3e2bbf
P
15#include <errno.h>
16#include <openssl/e_os2.h> /* For ossl_inline */
17
8347bfa0
P
18OSSL_SAFE_MATH_SIGNED(int, int)
19
1b3e2bbf
P
20/*
21 * The initial number of nodes in the array.
22 */
23static const int min_nodes = 4;
24static const int max_nodes = SIZE_MAX / sizeof(void *) < INT_MAX
30eba7f3 25 ? (int)(SIZE_MAX / sizeof(void *)) : INT_MAX;
d02b48c6 26
31c2b6ee
DSH
27struct stack_st {
28 int num;
1b3e2bbf 29 const void **data;
31c2b6ee 30 int sorted;
1b3e2bbf 31 int num_alloc;
739a1eb1 32 OPENSSL_sk_compfunc comp;
31c2b6ee
DSH
33};
34
30eba7f3
DDO
35OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk,
36 OPENSSL_sk_compfunc c)
739a1eb1
RS
37{
38 OPENSSL_sk_compfunc old = sk->comp;
eb90a483 39
0f113f3e
MC
40 if (sk->comp != c)
41 sk->sorted = 0;
42 sk->comp = c;
eb90a483 43
0f113f3e
MC
44 return old;
45}
d02b48c6 46
c0c9c0c0 47OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *sk)
0f113f3e 48{
739a1eb1 49 OPENSSL_STACK *ret;
9205ebeb 50
d53b437f
DDO
51 if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
52 goto err;
7e1445b0 53
d53b437f
DDO
54 if (sk == NULL) {
55 ret->num = 0;
56 ret->sorted = 0;
57 ret->comp = NULL;
58 } else {
59 /* direct structure assignment */
60 *ret = *sk;
61 }
0f113f3e 62
d53b437f 63 if (sk == NULL || sk->num == 0) {
8e8e507e
F
64 /* postpone |ret->data| allocation */
65 ret->data = NULL;
66 ret->num_alloc = 0;
67 return ret;
68 }
d53b437f 69
8e8e507e 70 /* duplicate |sk->data| content */
30eba7f3
DDO
71 ret->data = OPENSSL_malloc(sizeof(*ret->data) * sk->num_alloc);
72 if (ret->data == NULL)
7e1445b0 73 goto err;
1b3e2bbf 74 memcpy(ret->data, sk->data, sizeof(void *) * sk->num);
7e1445b0 75 return ret;
d53b437f 76
0f113f3e 77 err:
739a1eb1 78 OPENSSL_sk_free(ret);
7e1445b0 79 return NULL;
0f113f3e
MC
80}
81
c0c9c0c0 82OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk,
30eba7f3
DDO
83 OPENSSL_sk_copyfunc copy_func,
84 OPENSSL_sk_freefunc free_func)
0f113f3e 85{
739a1eb1 86 OPENSSL_STACK *ret;
0f113f3e
MC
87 int i;
88
d53b437f
DDO
89 if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
90 goto err;
7e1445b0 91
d53b437f
DDO
92 if (sk == NULL) {
93 ret->num = 0;
94 ret->sorted = 0;
95 ret->comp = NULL;
96 } else {
97 /* direct structure assignment */
98 *ret = *sk;
99 }
7e1445b0 100
d53b437f 101 if (sk == NULL || sk->num == 0) {
8e8e507e
F
102 /* postpone |ret| data allocation */
103 ret->data = NULL;
104 ret->num_alloc = 0;
105 return ret;
106 }
107
1b3e2bbf 108 ret->num_alloc = sk->num > min_nodes ? sk->num : min_nodes;
7e1445b0 109 ret->data = OPENSSL_zalloc(sizeof(*ret->data) * ret->num_alloc);
d53b437f
DDO
110 if (ret->data == NULL)
111 goto err;
0f113f3e
MC
112
113 for (i = 0; i < ret->num; ++i) {
114 if (sk->data[i] == NULL)
115 continue;
116 if ((ret->data[i] = copy_func(sk->data[i])) == NULL) {
117 while (--i >= 0)
118 if (ret->data[i] != NULL)
36639907 119 free_func((void *)ret->data[i]);
d53b437f 120 goto err;
0f113f3e
MC
121 }
122 }
123 return ret;
d53b437f
DDO
124
125 err:
d53b437f
DDO
126 OPENSSL_sk_free(ret);
127 return NULL;
0f113f3e 128}
66d884f0 129
739a1eb1 130OPENSSL_STACK *OPENSSL_sk_new_null(void)
0f113f3e 131{
3ceab379 132 return OPENSSL_sk_new_reserve(NULL, 0);
0f113f3e
MC
133}
134
739a1eb1 135OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_compfunc c)
0f113f3e 136{
3ceab379 137 return OPENSSL_sk_new_reserve(c, 0);
0f113f3e 138}
d02b48c6 139
1b3e2bbf
P
140/*
141 * Calculate the array growth based on the target size.
142 *
8347bfa0 143 * The growth factor is a rational number and is defined by a numerator
1b3e2bbf
P
144 * and a denominator. According to Andrew Koenig in his paper "Why Are
145 * Vectors Efficient?" from JOOP 11(5) 1998, this factor should be less
146 * than the golden ratio (1.618...).
147 *
8347bfa0
P
148 * Considering only the Fibonacci ratios less than the golden ratio, the
149 * number of steps from the minimum allocation to integer overflow is:
150 * factor decimal growths
151 * 3/2 1.5 51
152 * 8/5 1.6 45
153 * 21/13 1.615... 44
1b3e2bbf 154 *
8347bfa0 155 * All larger factors have the same number of growths.
8e8e507e 156 *
8347bfa0 157 * 3/2 and 8/5 have nice power of two shifts, so seem like a good choice.
1b3e2bbf
P
158 */
159static ossl_inline int compute_growth(int target, int current)
0f113f3e 160{
8347bfa0 161 int err = 0;
1b3e2bbf
P
162
163 while (current < target) {
1b3e2bbf
P
164 if (current >= max_nodes)
165 return 0;
166
8347bfa0 167 current = safe_muldiv_int(current, 8, 5, &err);
30eba7f3 168 if (err != 0)
8347bfa0 169 return 0;
7cc5738a 170 if (current >= max_nodes)
8347bfa0 171 current = max_nodes;
9731a9ce 172 }
1b3e2bbf
P
173 return current;
174}
9731a9ce 175
8e8e507e 176/* internal STACK storage allocation */
1b3e2bbf
P
177static int sk_reserve(OPENSSL_STACK *st, int n, int exact)
178{
179 const void **tmpdata;
180 int num_alloc;
9731a9ce 181
1b3e2bbf 182 /* Check to see the reservation isn't exceeding the hard limit */
30eba7f3
DDO
183 if (n > max_nodes - st->num) {
184 ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_RECORDS);
1b3e2bbf 185 return 0;
30eba7f3 186 }
9731a9ce 187
1b3e2bbf
P
188 /* Figure out the new size */
189 num_alloc = st->num + n;
190 if (num_alloc < min_nodes)
191 num_alloc = min_nodes;
9731a9ce 192
8e8e507e
F
193 /* If |st->data| allocation was postponed */
194 if (st->data == NULL) {
195 /*
196 * At this point, |st->num_alloc| and |st->num| are 0;
197 * so |num_alloc| value is |n| or |min_nodes| if greater than |n|.
198 */
e077455e 199 if ((st->data = OPENSSL_zalloc(sizeof(void *) * num_alloc)) == NULL)
8e8e507e
F
200 return 0;
201 st->num_alloc = num_alloc;
202 return 1;
203 }
204
1b3e2bbf
P
205 if (!exact) {
206 if (num_alloc <= st->num_alloc)
207 return 1;
208 num_alloc = compute_growth(num_alloc, st->num_alloc);
30eba7f3
DDO
209 if (num_alloc == 0) {
210 ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_RECORDS);
9205ebeb 211 return 0;
30eba7f3 212 }
1b3e2bbf
P
213 } else if (num_alloc == st->num_alloc) {
214 return 1;
0f113f3e 215 }
1b3e2bbf
P
216
217 tmpdata = OPENSSL_realloc((void *)st->data, sizeof(void *) * num_alloc);
e077455e 218 if (tmpdata == NULL)
1b3e2bbf
P
219 return 0;
220
221 st->data = tmpdata;
222 st->num_alloc = num_alloc;
223 return 1;
224}
225
3ceab379
PY
226OPENSSL_STACK *OPENSSL_sk_new_reserve(OPENSSL_sk_compfunc c, int n)
227{
228 OPENSSL_STACK *st = OPENSSL_zalloc(sizeof(OPENSSL_STACK));
229
e077455e 230 if (st == NULL)
3ceab379
PY
231 return NULL;
232
233 st->comp = c;
234
235 if (n <= 0)
236 return st;
237
238 if (!sk_reserve(st, n, 1)) {
239 OPENSSL_sk_free(st);
240 return NULL;
241 }
242
243 return st;
244}
245
1b3e2bbf
P
246int OPENSSL_sk_reserve(OPENSSL_STACK *st, int n)
247{
30eba7f3
DDO
248 if (st == NULL) {
249 ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
1049ae98 250 return 0;
30eba7f3 251 }
1049ae98 252
1b3e2bbf
P
253 if (n < 0)
254 return 1;
255 return sk_reserve(st, n, 1);
256}
257
258int OPENSSL_sk_insert(OPENSSL_STACK *st, const void *data, int loc)
259{
30eba7f3
DDO
260 if (st == NULL) {
261 ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
1b3e2bbf 262 return 0;
30eba7f3
DDO
263 }
264 if (st->num == max_nodes) {
265 ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_RECORDS);
266 return 0;
267 }
1b3e2bbf
P
268
269 if (!sk_reserve(st, 1, 0))
270 return 0;
271
9205ebeb 272 if ((loc >= st->num) || (loc < 0)) {
0f113f3e 273 st->data[st->num] = data;
9205ebeb 274 } else {
36639907
RS
275 memmove(&st->data[loc + 1], &st->data[loc],
276 sizeof(st->data[0]) * (st->num - loc));
0f113f3e
MC
277 st->data[loc] = data;
278 }
279 st->num++;
280 st->sorted = 0;
9205ebeb 281 return st->num;
0f113f3e 282}
d02b48c6 283
8e8e507e
F
284static ossl_inline void *internal_delete(OPENSSL_STACK *st, int loc)
285{
286 const void *ret = st->data[loc];
287
288 if (loc != st->num - 1)
30eba7f3
DDO
289 memmove(&st->data[loc], &st->data[loc + 1],
290 sizeof(st->data[0]) * (st->num - loc - 1));
8e8e507e
F
291 st->num--;
292
293 return (void *)ret;
294}
295
4591e5fb 296void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *st, const void *p)
0f113f3e
MC
297{
298 int i;
d02b48c6 299
0f113f3e
MC
300 for (i = 0; i < st->num; i++)
301 if (st->data[i] == p)
8e8e507e 302 return internal_delete(st, i);
4591e5fb 303 return NULL;
0f113f3e 304}
d02b48c6 305
739a1eb1 306void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc)
0f113f3e 307{
30eba7f3
DDO
308 if (st == NULL) {
309 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
310 return NULL;
311 }
312 if (loc < 0 || loc >= st->num) {
313 ERR_raise_data(ERR_LIB_X509, ERR_R_PASSED_INVALID_ARGUMENT,
314 "loc=%d", loc);
0f113f3e 315 return NULL;
30eba7f3 316 }
0f113f3e 317
8e8e507e 318 return internal_delete(st, loc);
0f113f3e 319}
d02b48c6 320
4591e5fb 321static int internal_find(OPENSSL_STACK *st, const void *data,
5fd7eb5c 322 int ret_val_options, int *pnum)
0f113f3e 323{
36639907 324 const void *r;
0f113f3e
MC
325 int i;
326
1049ae98 327 if (st == NULL || st->num == 0)
0f113f3e
MC
328 return -1;
329
330 if (st->comp == NULL) {
331 for (i = 0; i < st->num; i++)
5fd7eb5c
TM
332 if (st->data[i] == data) {
333 if (pnum != NULL)
334 *pnum = 1;
fbb7b33b 335 return i;
5fd7eb5c
TM
336 }
337 if (pnum != NULL)
338 *pnum = 0;
fbb7b33b
AP
339 return -1;
340 }
341
342 if (!st->sorted) {
343 if (st->num > 1)
344 qsort(st->data, st->num, sizeof(void *), st->comp);
345 st->sorted = 1; /* empty or single-element stack is considered sorted */
0f113f3e 346 }
0f113f3e 347 if (data == NULL)
fbb7b33b 348 return -1;
5fd7eb5c
TM
349 if (pnum != NULL)
350 ret_val_options |= OSSL_BSEARCH_FIRST_VALUE_ON_MATCH;
5c3f1e34
RL
351 r = ossl_bsearch(&data, st->data, st->num, sizeof(void *), st->comp,
352 ret_val_options);
fbb7b33b 353
5fd7eb5c
TM
354 if (pnum != NULL) {
355 *pnum = 0;
356 if (r != NULL) {
357 const void **p = (const void **)r;
358
359 while (p < st->data + st->num) {
360 if (st->comp(&data, p) != 0)
361 break;
362 ++*pnum;
363 ++p;
364 }
365 }
366 }
367
fbb7b33b 368 return r == NULL ? -1 : (int)((const void **)r - st->data);
0f113f3e 369}
26851b6b 370
4591e5fb 371int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data)
0f113f3e 372{
5fd7eb5c 373 return internal_find(st, data, OSSL_BSEARCH_FIRST_VALUE_ON_MATCH, NULL);
0f113f3e
MC
374}
375
4591e5fb 376int OPENSSL_sk_find_ex(OPENSSL_STACK *st, const void *data)
0f113f3e 377{
5fd7eb5c
TM
378 return internal_find(st, data, OSSL_BSEARCH_VALUE_ON_NOMATCH, NULL);
379}
380
381int OPENSSL_sk_find_all(OPENSSL_STACK *st, const void *data, int *pnum)
382{
383 return internal_find(st, data, OSSL_BSEARCH_FIRST_VALUE_ON_MATCH, pnum);
0f113f3e 384}
d02b48c6 385
36639907 386int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data)
0f113f3e 387{
1049ae98
MC
388 if (st == NULL)
389 return -1;
8e8e507e 390 return OPENSSL_sk_insert(st, data, st->num);
0f113f3e 391}
d02b48c6 392
36639907 393int OPENSSL_sk_unshift(OPENSSL_STACK *st, const void *data)
0f113f3e 394{
fbb7b33b 395 return OPENSSL_sk_insert(st, data, 0);
0f113f3e 396}
d02b48c6 397
739a1eb1 398void *OPENSSL_sk_shift(OPENSSL_STACK *st)
0f113f3e 399{
30eba7f3
DDO
400 if (st == NULL) {
401 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
8e8e507e 402 return NULL;
30eba7f3
DDO
403 }
404 if (st->num == 0) {
405 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_INVALID_ARGUMENT);
406 return NULL;
407 }
8e8e507e 408 return internal_delete(st, 0);
0f113f3e 409}
d02b48c6 410
739a1eb1 411void *OPENSSL_sk_pop(OPENSSL_STACK *st)
0f113f3e 412{
30eba7f3
DDO
413 if (st == NULL) {
414 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
415 return NULL;
416 }
417 if (st->num == 0) {
418 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_INVALID_ARGUMENT);
8e8e507e 419 return NULL;
30eba7f3 420 }
8e8e507e 421 return internal_delete(st, st->num - 1);
0f113f3e 422}
d02b48c6 423
739a1eb1 424void OPENSSL_sk_zero(OPENSSL_STACK *st)
0f113f3e 425{
30eba7f3
DDO
426 if (st == NULL) {
427 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
428 return;
429 }
430 if (st->num == 0)
0f113f3e 431 return;
16f8d4eb 432 memset(st->data, 0, sizeof(*st->data) * st->num);
0f113f3e
MC
433 st->num = 0;
434}
435
739a1eb1 436void OPENSSL_sk_pop_free(OPENSSL_STACK *st, OPENSSL_sk_freefunc func)
0f113f3e
MC
437{
438 int i;
439
440 if (st == NULL)
441 return;
442 for (i = 0; i < st->num; i++)
443 if (st->data[i] != NULL)
36639907 444 func((char *)st->data[i]);
739a1eb1 445 OPENSSL_sk_free(st);
0f113f3e 446}
d02b48c6 447
739a1eb1 448void OPENSSL_sk_free(OPENSSL_STACK *st)
0f113f3e
MC
449{
450 if (st == NULL)
451 return;
b548a1f1 452 OPENSSL_free(st->data);
0f113f3e
MC
453 OPENSSL_free(st);
454}
d02b48c6 455
739a1eb1 456int OPENSSL_sk_num(const OPENSSL_STACK *st)
e84240d4 457{
fbb7b33b 458 return st == NULL ? -1 : st->num;
e84240d4
DSH
459}
460
739a1eb1 461void *OPENSSL_sk_value(const OPENSSL_STACK *st, int i)
e84240d4 462{
30eba7f3
DDO
463 if (st == NULL) {
464 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
465 return NULL;
466 }
467 if (i < 0 || i >= st->num) {
468 ERR_raise_data(ERR_LIB_X509, ERR_R_PASSED_INVALID_ARGUMENT,
469 "i=%d", i);
0f113f3e 470 return NULL;
30eba7f3 471 }
36639907 472 return (void *)st->data[i];
e84240d4
DSH
473}
474
36639907 475void *OPENSSL_sk_set(OPENSSL_STACK *st, int i, const void *data)
e84240d4 476{
30eba7f3
DDO
477 if (st == NULL) {
478 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
0f113f3e 479 return NULL;
30eba7f3
DDO
480 }
481 if (i < 0 || i >= st->num) {
482 ERR_raise_data(ERR_LIB_X509, ERR_R_PASSED_INVALID_ARGUMENT,
483 "i=%d", i);
484 return NULL;
485 }
36639907 486 st->data[i] = data;
fbb7b33b 487 st->sorted = 0;
36639907 488 return (void *)st->data[i];
e84240d4 489}
ee8ba0b2 490
739a1eb1 491void OPENSSL_sk_sort(OPENSSL_STACK *st)
0f113f3e 492{
1049ae98 493 if (st != NULL && !st->sorted && st->comp != NULL) {
fbb7b33b 494 if (st->num > 1)
8e8e507e 495 qsort(st->data, st->num, sizeof(void *), st->comp);
fbb7b33b 496 st->sorted = 1; /* empty or single-element stack is considered sorted */
0f113f3e
MC
497 }
498}
2f605e8d 499
739a1eb1 500int OPENSSL_sk_is_sorted(const OPENSSL_STACK *st)
0f113f3e 501{
1049ae98 502 return st == NULL ? 1 : st->sorted;
0f113f3e 503}