summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorbeck <>2019-03-23 18:48:15 +0000
committerbeck <>2019-03-23 18:48:15 +0000
commitca4bb8fd7a5a26fd8735668aa2353f221a0d0fbc (patch)
tree5a672c6d12222c102b5aef132ff6174f5fec66f9 /src/lib
parent4b69e569a2d9519abb4e7e10e2640d010e7d2744 (diff)
downloadopenbsd-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.c56
-rw-r--r--src/lib/libcrypto/asn1/tasn_prn.c8
-rw-r--r--src/lib/libcrypto/bn/bn_lib.c4
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
68static int
69ASN1_INTEGER_valid(const ASN1_INTEGER *a)
70{
71 return (a != NULL && a->length >= 0);
72}
73
66ASN1_INTEGER * 74ASN1_INTEGER *
67ASN1_INTEGER_dup(const ASN1_INTEGER *x) 75ASN1_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 */
378long 418long
379ASN1_INTEGER_get(const ASN1_INTEGER *a) 419ASN1_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)