diff options
author | schwarze <> | 2021-12-11 22:58:48 +0000 |
---|---|---|
committer | schwarze <> | 2021-12-11 22:58:48 +0000 |
commit | 693b9af2c868379acbde502b0fdd91708ee6da6e (patch) | |
tree | 532c5bb73c4be67f02e0555a36f578b690062300 /src/lib | |
parent | ba300c78ab7a7a24256b3e243db2e3f84ada4c14 (diff) | |
download | openbsd-693b9af2c868379acbde502b0fdd91708ee6da6e.tar.gz openbsd-693b9af2c868379acbde502b0fdd91708ee6da6e.tar.bz2 openbsd-693b9af2c868379acbde502b0fdd91708ee6da6e.zip |
Merge two bugfixes in ASN1_STRING_TABLE_add(3) and ASN1_STRING_TABLE_get(3)
from the OpenSSL 1.1.1 branch, which is still under a free license,
mostly this commit:
commit d35c0ff30b31be9fd5dcf3d552a16feb8de464bc
Author: Dr. Stephen Henson <steve@openssl.org>
Date: Fri Oct 19 15:06:31 2012 +0000
fix ASN1_STRING_TABLE_add so it can override existing string table values
This fixes a segfault in ASN1_STRING_TABLE_add(3), which tried to change a
static const entry when called with an nid already in the default table,
and it switches the precedence of the two tables in ASN1_STRING_TABLE_get(3).
In addition, it changes behaviour in the following minor ways:
* Ignore negative minsize and maxsize arguments, not just -1.
* Ignore a zero mask and zero flags.
It's unclear whether these additional changes make the API absolutely
better, but we want compatibility with OpenSSL in these functions.
Tweaks & OK tb@.
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/asn1/a_strnid.c | 92 |
1 files changed, 58 insertions, 34 deletions
diff --git a/src/lib/libcrypto/asn1/a_strnid.c b/src/lib/libcrypto/asn1/a_strnid.c index 0cc8dc8428..08043f723b 100644 --- a/src/lib/libcrypto/asn1/a_strnid.c +++ b/src/lib/libcrypto/asn1/a_strnid.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: a_strnid.c,v 1.22 2021/12/11 22:34:36 schwarze Exp $ */ | 1 | /* $OpenBSD: a_strnid.c,v 1.23 2021/12/11 22:58:48 schwarze Exp $ */ |
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
3 | * project 1999. | 3 | * project 1999. |
4 | */ | 4 | */ |
@@ -64,6 +64,8 @@ | |||
64 | #include <openssl/objects.h> | 64 | #include <openssl/objects.h> |
65 | 65 | ||
66 | static STACK_OF(ASN1_STRING_TABLE) *stable = NULL; | 66 | static STACK_OF(ASN1_STRING_TABLE) *stable = NULL; |
67 | |||
68 | static ASN1_STRING_TABLE *stable_get(int nid); | ||
67 | static void st_free(ASN1_STRING_TABLE *tbl); | 69 | static void st_free(ASN1_STRING_TABLE *tbl); |
68 | static int sk_table_cmp(const ASN1_STRING_TABLE * const *a, | 70 | static int sk_table_cmp(const ASN1_STRING_TABLE * const *a, |
69 | const ASN1_STRING_TABLE * const *b); | 71 | const ASN1_STRING_TABLE * const *b); |
@@ -235,20 +237,59 @@ ASN1_STRING_TABLE * | |||
235 | ASN1_STRING_TABLE_get(int nid) | 237 | ASN1_STRING_TABLE_get(int nid) |
236 | { | 238 | { |
237 | int idx; | 239 | int idx; |
238 | ASN1_STRING_TABLE *ttmp; | ||
239 | ASN1_STRING_TABLE fnd; | 240 | ASN1_STRING_TABLE fnd; |
240 | 241 | ||
241 | fnd.nid = nid; | 242 | fnd.nid = nid; |
242 | ttmp = OBJ_bsearch_table(&fnd, tbl_standard, | 243 | if (stable != NULL) { |
244 | idx = sk_ASN1_STRING_TABLE_find(stable, &fnd); | ||
245 | if (idx >= 0) | ||
246 | return sk_ASN1_STRING_TABLE_value(stable, idx); | ||
247 | } | ||
248 | return OBJ_bsearch_table(&fnd, tbl_standard, | ||
243 | sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE)); | 249 | sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE)); |
244 | if (ttmp) | 250 | } |
245 | return ttmp; | 251 | |
246 | if (!stable) | 252 | /* |
253 | * Return a string table pointer which can be modified: either directly | ||
254 | * from table or a copy of an internal value added to the table. | ||
255 | */ | ||
256 | |||
257 | static ASN1_STRING_TABLE * | ||
258 | stable_get(int nid) | ||
259 | { | ||
260 | ASN1_STRING_TABLE *tmp, *rv; | ||
261 | |||
262 | /* Always need a string table so allocate one if NULL */ | ||
263 | if (stable == NULL) { | ||
264 | stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp); | ||
265 | if (stable == NULL) | ||
266 | return NULL; | ||
267 | } | ||
268 | tmp = ASN1_STRING_TABLE_get(nid); | ||
269 | if (tmp != NULL && (tmp->flags & STABLE_FLAGS_MALLOC) != 0) | ||
270 | return tmp; | ||
271 | |||
272 | if ((rv = calloc(1, sizeof(*rv))) == NULL) { | ||
273 | ASN1error(ERR_R_MALLOC_FAILURE); | ||
247 | return NULL; | 274 | return NULL; |
248 | idx = sk_ASN1_STRING_TABLE_find(stable, &fnd); | 275 | } |
249 | if (idx < 0) | 276 | if (!sk_ASN1_STRING_TABLE_push(stable, rv)) { |
277 | free(rv); | ||
250 | return NULL; | 278 | return NULL; |
251 | return sk_ASN1_STRING_TABLE_value(stable, idx); | 279 | } |
280 | if (tmp != NULL) { | ||
281 | rv->nid = tmp->nid; | ||
282 | rv->minsize = tmp->minsize; | ||
283 | rv->maxsize = tmp->maxsize; | ||
284 | rv->mask = tmp->mask; | ||
285 | rv->flags = tmp->flags | STABLE_FLAGS_MALLOC; | ||
286 | } else { | ||
287 | rv->nid = nid; | ||
288 | rv->minsize = -1; | ||
289 | rv->maxsize = -1; | ||
290 | rv->flags = STABLE_FLAGS_MALLOC; | ||
291 | } | ||
292 | return rv; | ||
252 | } | 293 | } |
253 | 294 | ||
254 | int | 295 | int |
@@ -256,37 +297,20 @@ ASN1_STRING_TABLE_add(int nid, long minsize, long maxsize, unsigned long mask, | |||
256 | unsigned long flags) | 297 | unsigned long flags) |
257 | { | 298 | { |
258 | ASN1_STRING_TABLE *tmp; | 299 | ASN1_STRING_TABLE *tmp; |
259 | char new_nid = 0; | ||
260 | 300 | ||
261 | flags &= ~STABLE_FLAGS_MALLOC; | 301 | if ((tmp = stable_get(nid)) == NULL) { |
262 | if (!stable) | ||
263 | stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp); | ||
264 | if (!stable) { | ||
265 | ASN1error(ERR_R_MALLOC_FAILURE); | 302 | ASN1error(ERR_R_MALLOC_FAILURE); |
266 | return 0; | 303 | return 0; |
267 | } | 304 | } |
268 | if (!(tmp = ASN1_STRING_TABLE_get(nid))) { | 305 | if (minsize >= 0) |
269 | tmp = malloc(sizeof(ASN1_STRING_TABLE)); | ||
270 | if (!tmp) { | ||
271 | ASN1error(ERR_R_MALLOC_FAILURE); | ||
272 | return 0; | ||
273 | } | ||
274 | tmp->flags = flags | STABLE_FLAGS_MALLOC; | ||
275 | tmp->nid = nid; | ||
276 | new_nid = 1; | ||
277 | } else tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags; | ||
278 | if (minsize != -1) | ||
279 | tmp->minsize = minsize; | 306 | tmp->minsize = minsize; |
280 | if (maxsize != -1) | 307 | if (maxsize >= 0) |
281 | tmp->maxsize = maxsize; | 308 | tmp->maxsize = maxsize; |
282 | tmp->mask = mask; | 309 | if (mask != 0) |
283 | if (new_nid) { | 310 | tmp->mask = mask; |
284 | if (sk_ASN1_STRING_TABLE_push(stable, tmp) == 0) { | 311 | if (flags != 0) |
285 | free(tmp); | 312 | tmp->flags = flags | STABLE_FLAGS_MALLOC; |
286 | ASN1error(ERR_R_MALLOC_FAILURE); | 313 | |
287 | return 0; | ||
288 | } | ||
289 | } | ||
290 | return 1; | 314 | return 1; |
291 | } | 315 | } |
292 | 316 | ||