summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorjsing <>2022-02-12 03:01:59 +0000
committerjsing <>2022-02-12 03:01:59 +0000
commit3cdfdb15c33fb6703fda85d18303cc7ccd42e71d (patch)
tree6c1fc324b3e83fe846b49e89187600b00a56fd00 /src/lib
parenta345ec92b1fce7cf942a7fc858ad531f08cafc5a (diff)
downloadopenbsd-3cdfdb15c33fb6703fda85d18303cc7ccd42e71d.tar.gz
openbsd-3cdfdb15c33fb6703fda85d18303cc7ccd42e71d.tar.bz2
openbsd-3cdfdb15c33fb6703fda85d18303cc7ccd42e71d.zip
Limit OID text conversion to 64 bits per arc.
The current implementation uses an unsigned long, then switches to BN once the arc exceeds its size. However, the complexity of BN_bn2dec() is quadratic in the length of number being converted. This means that OIDs with excessively large arcs take a lot of computation to convert to text. While the X.660 specification states that arcs are unbounded, in reality they are not overly large numbers - 640K^W64 bits ought to be enough for any arc. Remove BN entirely, switch from unsigned long to uin64_t and fail if an arc exceeds this size. Identified via oss-fuzz timeouts - should fix #41028 and #44372. ok tb@
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/objects/obj_dat.c71
1 files changed, 16 insertions, 55 deletions
diff --git a/src/lib/libcrypto/objects/obj_dat.c b/src/lib/libcrypto/objects/obj_dat.c
index 7aecda2641..03e65f1dfe 100644
--- a/src/lib/libcrypto/objects/obj_dat.c
+++ b/src/lib/libcrypto/objects/obj_dat.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: obj_dat.c,v 1.46 2022/02/11 16:39:16 jsing Exp $ */ 1/* $OpenBSD: obj_dat.c,v 1.47 2022/02/12 03:01:59 jsing 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 *
@@ -526,10 +526,9 @@ OBJ_txt2obj(const char *s, int no_name)
526int 526int
527OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) 527OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
528{ 528{
529 int i, ret = 0, len, nid, first = 1, use_bn; 529 int i, ret = 0, len, nid, first = 1;
530 BIGNUM *bl = NULL;
531 unsigned long l;
532 const unsigned char *p; 530 const unsigned char *p;
531 uint64_t l;
533 532
534 /* Ensure that, at every state, |buf| is NUL-terminated. */ 533 /* Ensure that, at every state, |buf| is NUL-terminated. */
535 if (buf_len > 0) 534 if (buf_len > 0)
@@ -554,42 +553,24 @@ OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
554 553
555 while (len > 0) { 554 while (len > 0) {
556 l = 0; 555 l = 0;
557 use_bn = 0;
558 for (;;) { 556 for (;;) {
559 unsigned char c = *p++; 557 unsigned char c = *p++;
560 len--; 558 len--;
561 if ((len == 0) && (c & 0x80)) 559 if ((len == 0) && (c & 0x80))
562 goto err; 560 goto err;
563 if (use_bn) { 561 l |= c & 0x7f;
564 if (!BN_add_word(bl, c & 0x7f))
565 goto err;
566 } else
567 l |= c & 0x7f;
568 if (!(c & 0x80)) 562 if (!(c & 0x80))
569 break; 563 break;
570 if (!use_bn && (l > (ULONG_MAX >> 7L))) { 564 if (l > (UINT64_MAX >> 7L))
571 if (!bl && !(bl = BN_new())) 565 goto err;
572 goto err; 566 l <<= 7L;
573 if (!BN_set_word(bl, l))
574 goto err;
575 use_bn = 1;
576 }
577 if (use_bn) {
578 if (!BN_lshift(bl, bl, 7))
579 goto err;
580 } else
581 l <<= 7L;
582 } 567 }
583 568
584 if (first) { 569 if (first) {
585 first = 0; 570 first = 0;
586 if (l >= 80) { 571 if (l >= 80) {
587 i = 2; 572 i = 2;
588 if (use_bn) { 573 l -= 80;
589 if (!BN_sub_word(bl, 80))
590 goto err;
591 } else
592 l -= 80;
593 } else { 574 } else {
594 i = (int)(l / 40); 575 i = (int)(l / 40);
595 l -= (long)(i * 40); 576 l -= (long)(i * 40);
@@ -602,39 +583,19 @@ OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
602 ret++; 583 ret++;
603 } 584 }
604 585
605 if (use_bn) { 586 i = snprintf(buf, buf_len, ".%llu", l);
606 char *bndec; 587 if (i < 0)
607 588 goto err;
608 bndec = BN_bn2dec(bl); 589 if (i >= buf_len) {
609 if (!bndec) 590 buf_len = 0;
610 goto err;
611 i = snprintf(buf, buf_len, ".%s", bndec);
612 free(bndec);
613 if (i < 0)
614 goto err;
615 if (i >= buf_len) {
616 buf_len = 0;
617 } else {
618 buf += i;
619 buf_len -= i;
620 }
621 ret += i;
622 } else { 591 } else {
623 i = snprintf(buf, buf_len, ".%lu", l); 592 buf += i;
624 if (i < 0) 593 buf_len -= i;
625 goto err;
626 if (i >= buf_len) {
627 buf_len = 0;
628 } else {
629 buf += i;
630 buf_len -= i;
631 }
632 ret += i;
633 } 594 }
595 ret += i;
634 } 596 }
635 597
636 out: 598 out:
637 BN_free(bl);
638 return ret; 599 return ret;
639 600
640 err: 601 err: