diff options
author | beck <> | 2019-03-23 18:48:15 +0000 |
---|---|---|
committer | beck <> | 2019-03-23 18:48:15 +0000 |
commit | ca4bb8fd7a5a26fd8735668aa2353f221a0d0fbc (patch) | |
tree | 5a672c6d12222c102b5aef132ff6174f5fec66f9 /src/lib | |
parent | 4b69e569a2d9519abb4e7e10e2640d010e7d2744 (diff) | |
download | openbsd-ca4bb8fd7a5a26fd8735668aa2353f221a0d0fbc.tar.gz openbsd-ca4bb8fd7a5a26fd8735668aa2353f221a0d0fbc.tar.bz2 openbsd-ca4bb8fd7a5a26fd8735668aa2353f221a0d0fbc.zip |
Add range checks to varios ASN1_INTEGER functions to ensure the
sizes used remain a positive integer. Should address issue
13799 from oss-fuzz
ok tb@ jsing@
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/asn1/a_int.c | 56 | ||||
-rw-r--r-- | src/lib/libcrypto/asn1/tasn_prn.c | 8 | ||||
-rw-r--r-- | src/lib/libcrypto/bn/bn_lib.c | 4 |
3 files changed, 62 insertions, 6 deletions
diff --git a/src/lib/libcrypto/asn1/a_int.c b/src/lib/libcrypto/asn1/a_int.c index 95d0f6dbb2..218d0b607b 100644 --- a/src/lib/libcrypto/asn1/a_int.c +++ b/src/lib/libcrypto/asn1/a_int.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: a_int.c,v 1.31 2017/01/29 17:49:22 beck Exp $ */ | 1 | /* $OpenBSD: a_int.c,v 1.32 2019/03/23 18:48:14 beck Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -59,13 +59,24 @@ | |||
59 | #include <stdio.h> | 59 | #include <stdio.h> |
60 | #include <string.h> | 60 | #include <string.h> |
61 | 61 | ||
62 | #include <sys/limits.h> | ||
63 | |||
62 | #include <openssl/asn1.h> | 64 | #include <openssl/asn1.h> |
63 | #include <openssl/bn.h> | 65 | #include <openssl/bn.h> |
64 | #include <openssl/err.h> | 66 | #include <openssl/err.h> |
65 | 67 | ||
68 | static int | ||
69 | ASN1_INTEGER_valid(const ASN1_INTEGER *a) | ||
70 | { | ||
71 | return (a != NULL && a->length >= 0); | ||
72 | } | ||
73 | |||
66 | ASN1_INTEGER * | 74 | ASN1_INTEGER * |
67 | ASN1_INTEGER_dup(const ASN1_INTEGER *x) | 75 | ASN1_INTEGER_dup(const ASN1_INTEGER *x) |
68 | { | 76 | { |
77 | if (!ASN1_INTEGER_valid(x)) | ||
78 | return NULL; | ||
79 | |||
69 | return ASN1_STRING_dup(x); | 80 | return ASN1_STRING_dup(x); |
70 | } | 81 | } |
71 | 82 | ||
@@ -123,8 +134,9 @@ i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) | |||
123 | int pad = 0, ret, i, neg; | 134 | int pad = 0, ret, i, neg; |
124 | unsigned char *p, *n, pb = 0; | 135 | unsigned char *p, *n, pb = 0; |
125 | 136 | ||
126 | if (a == NULL) | 137 | if (!ASN1_INTEGER_valid(a)) |
127 | return (0); | 138 | return 0; |
139 | |||
128 | neg = a->type & V_ASN1_NEG; | 140 | neg = a->type & V_ASN1_NEG; |
129 | if (a->length == 0) | 141 | if (a->length == 0) |
130 | ret = 1; | 142 | ret = 1; |
@@ -201,11 +213,24 @@ c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long len) | |||
201 | } else | 213 | } else |
202 | ret = (*a); | 214 | ret = (*a); |
203 | 215 | ||
216 | if (!ASN1_INTEGER_valid(ret)) { | ||
217 | /* | ||
218 | * XXX using i for an alert is confusing, | ||
219 | * we should call this al | ||
220 | */ | ||
221 | i = ERR_R_ASN1_LENGTH_MISMATCH; | ||
222 | goto err; | ||
223 | } | ||
224 | |||
204 | p = *pp; | 225 | p = *pp; |
205 | pend = p + len; | 226 | pend = p + len; |
206 | 227 | ||
207 | /* We must malloc stuff, even for 0 bytes otherwise it | 228 | /* We must malloc stuff, even for 0 bytes otherwise it |
208 | * signifies a missing NULL parameter. */ | 229 | * signifies a missing NULL parameter. */ |
230 | if (len < 0 || len > INT_MAX) { | ||
231 | i = ERR_R_ASN1_LENGTH_MISMATCH; | ||
232 | goto err; | ||
233 | } | ||
209 | s = malloc(len + 1); | 234 | s = malloc(len + 1); |
210 | if (s == NULL) { | 235 | if (s == NULL) { |
211 | i = ERR_R_MALLOC_FAILURE; | 236 | i = ERR_R_MALLOC_FAILURE; |
@@ -294,6 +319,11 @@ d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length) | |||
294 | } else | 319 | } else |
295 | ret = (*a); | 320 | ret = (*a); |
296 | 321 | ||
322 | if (!ASN1_INTEGER_valid(ret)) { | ||
323 | i = ERR_R_ASN1_LENGTH_MISMATCH; | ||
324 | goto err; | ||
325 | } | ||
326 | |||
297 | p = *pp; | 327 | p = *pp; |
298 | inf = ASN1_get_object(&p, &len, &tag, &xclass, length); | 328 | inf = ASN1_get_object(&p, &len, &tag, &xclass, length); |
299 | if (inf & 0x80) { | 329 | if (inf & 0x80) { |
@@ -308,6 +338,10 @@ d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length) | |||
308 | 338 | ||
309 | /* We must malloc stuff, even for 0 bytes otherwise it | 339 | /* We must malloc stuff, even for 0 bytes otherwise it |
310 | * signifies a missing NULL parameter. */ | 340 | * signifies a missing NULL parameter. */ |
341 | if (len < 0 || len > INT_MAX) { | ||
342 | i = ERR_R_ASN1_LENGTH_MISMATCH; | ||
343 | goto err; | ||
344 | } | ||
311 | s = malloc(len + 1); | 345 | s = malloc(len + 1); |
312 | if (s == NULL) { | 346 | if (s == NULL) { |
313 | i = ERR_R_MALLOC_FAILURE; | 347 | i = ERR_R_MALLOC_FAILURE; |
@@ -375,6 +409,12 @@ ASN1_INTEGER_set(ASN1_INTEGER *a, long v) | |||
375 | return (1); | 409 | return (1); |
376 | } | 410 | } |
377 | 411 | ||
412 | /* | ||
413 | * XXX this particular API is a gibbering eidrich horror that makes it | ||
414 | * impossible to determine valid return cases from errors.. "a bit | ||
415 | * ugly" is preserved for posterity, unfortunately this is probably | ||
416 | * unfixable without changing public API | ||
417 | */ | ||
378 | long | 418 | long |
379 | ASN1_INTEGER_get(const ASN1_INTEGER *a) | 419 | ASN1_INTEGER_get(const ASN1_INTEGER *a) |
380 | { | 420 | { |
@@ -389,6 +429,9 @@ ASN1_INTEGER_get(const ASN1_INTEGER *a) | |||
389 | else if (i != V_ASN1_INTEGER) | 429 | else if (i != V_ASN1_INTEGER) |
390 | return -1; | 430 | return -1; |
391 | 431 | ||
432 | if (!ASN1_INTEGER_valid(a)) | ||
433 | return -1; /* XXX best effort */ | ||
434 | |||
392 | if (a->length > (int)sizeof(long)) { | 435 | if (a->length > (int)sizeof(long)) { |
393 | /* hmm... a bit ugly, return all ones */ | 436 | /* hmm... a bit ugly, return all ones */ |
394 | return -1; | 437 | return -1; |
@@ -419,6 +462,10 @@ BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) | |||
419 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | 462 | ASN1error(ERR_R_NESTED_ASN1_ERROR); |
420 | goto err; | 463 | goto err; |
421 | } | 464 | } |
465 | |||
466 | if (!ASN1_INTEGER_valid(ret)) | ||
467 | goto err; | ||
468 | |||
422 | if (BN_is_negative(bn)) | 469 | if (BN_is_negative(bn)) |
423 | ret->type = V_ASN1_NEG_INTEGER; | 470 | ret->type = V_ASN1_NEG_INTEGER; |
424 | else | 471 | else |
@@ -453,6 +500,9 @@ ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) | |||
453 | { | 500 | { |
454 | BIGNUM *ret; | 501 | BIGNUM *ret; |
455 | 502 | ||
503 | if (!ASN1_INTEGER_valid(ai)) | ||
504 | return (NULL); | ||
505 | |||
456 | if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) | 506 | if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) |
457 | ASN1error(ASN1_R_BN_LIB); | 507 | ASN1error(ASN1_R_BN_LIB); |
458 | else if (ai->type == V_ASN1_NEG_INTEGER) | 508 | else if (ai->type == V_ASN1_NEG_INTEGER) |
diff --git a/src/lib/libcrypto/asn1/tasn_prn.c b/src/lib/libcrypto/asn1/tasn_prn.c index b8f7dd5294..9fbf177ba4 100644 --- a/src/lib/libcrypto/asn1/tasn_prn.c +++ b/src/lib/libcrypto/asn1/tasn_prn.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tasn_prn.c,v 1.17 2018/04/25 11:48:21 tb Exp $ */ | 1 | /* $OpenBSD: tasn_prn.c,v 1.18 2019/03/23 18:48:14 beck 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 2000. | 3 | * project 2000. |
4 | */ | 4 | */ |
@@ -507,7 +507,12 @@ asn1_primitive_print(BIO *out, ASN1_VALUE **fld, const ASN1_ITEM *it, | |||
507 | return 0; | 507 | return 0; |
508 | if (pf && pf->prim_print) | 508 | if (pf && pf->prim_print) |
509 | return pf->prim_print(out, fld, it, indent, pctx); | 509 | return pf->prim_print(out, fld, it, indent, pctx); |
510 | |||
510 | str = (ASN1_STRING *)*fld; | 511 | str = (ASN1_STRING *)*fld; |
512 | |||
513 | if (str->length < 0) | ||
514 | return 0; | ||
515 | |||
511 | if (it->itype == ASN1_ITYPE_MSTRING) | 516 | if (it->itype == ASN1_ITYPE_MSTRING) |
512 | utype = str->type & ~V_ASN1_NEG; | 517 | utype = str->type & ~V_ASN1_NEG; |
513 | else | 518 | else |
@@ -516,7 +521,6 @@ asn1_primitive_print(BIO *out, ASN1_VALUE **fld, const ASN1_ITEM *it, | |||
516 | ASN1_TYPE *atype = (ASN1_TYPE *)*fld; | 521 | ASN1_TYPE *atype = (ASN1_TYPE *)*fld; |
517 | utype = atype->type; | 522 | utype = atype->type; |
518 | fld = &atype->value.asn1_value; | 523 | fld = &atype->value.asn1_value; |
519 | str = (ASN1_STRING *)*fld; | ||
520 | if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE) | 524 | if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE) |
521 | pname = NULL; | 525 | pname = NULL; |
522 | else | 526 | else |
diff --git a/src/lib/libcrypto/bn/bn_lib.c b/src/lib/libcrypto/bn/bn_lib.c index 0b79a87413..0025cf52ef 100644 --- a/src/lib/libcrypto/bn/bn_lib.c +++ b/src/lib/libcrypto/bn/bn_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_lib.c,v 1.45 2018/07/23 18:14:32 tb Exp $ */ | 1 | /* $OpenBSD: bn_lib.c,v 1.46 2019/03/23 18:48:15 beck Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -578,6 +578,8 @@ BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) | |||
578 | BN_ULONG l; | 578 | BN_ULONG l; |
579 | BIGNUM *bn = NULL; | 579 | BIGNUM *bn = NULL; |
580 | 580 | ||
581 | if (len < 0) | ||
582 | return (NULL); | ||
581 | if (ret == NULL) | 583 | if (ret == NULL) |
582 | ret = bn = BN_new(); | 584 | ret = bn = BN_new(); |
583 | if (ret == NULL) | 585 | if (ret == NULL) |