summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/asn1/tasn_dec.c68
1 files changed, 37 insertions, 31 deletions
diff --git a/src/lib/libcrypto/asn1/tasn_dec.c b/src/lib/libcrypto/asn1/tasn_dec.c
index 7338f6800a..a04a84cce8 100644
--- a/src/lib/libcrypto/asn1/tasn_dec.c
+++ b/src/lib/libcrypto/asn1/tasn_dec.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tasn_dec.c,v 1.44 2021/12/09 17:01:41 jsing Exp $ */ 1/* $OpenBSD: tasn_dec.c,v 1.45 2021/12/13 17:50:24 jsing 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 */
@@ -56,6 +56,7 @@
56 * 56 *
57 */ 57 */
58 58
59#include <limits.h>
59#include <stddef.h> 60#include <stddef.h>
60#include <string.h> 61#include <string.h>
61 62
@@ -65,6 +66,8 @@
65#include <openssl/err.h> 66#include <openssl/err.h>
66#include <openssl/objects.h> 67#include <openssl/objects.h>
67 68
69#include "bytestring.h"
70
68/* Constructed types with a recursive definition (such as can be found in PKCS7) 71/* Constructed types with a recursive definition (such as can be found in PKCS7)
69 * could eventually exceed the stack given malicious input with excessive 72 * could eventually exceed the stack given malicious input with excessive
70 * recursion. Therefore we limit the stack depth. 73 * recursion. Therefore we limit the stack depth.
@@ -74,7 +77,7 @@
74static int asn1_check_eoc(const unsigned char **in, long len); 77static int asn1_check_eoc(const unsigned char **in, long len);
75static int asn1_find_end(const unsigned char **in, long len, char inf); 78static int asn1_find_end(const unsigned char **in, long len, char inf);
76 79
77static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, 80static int asn1_collect(CBB *cbb, const unsigned char **in, long len,
78 char inf, int tag, int aclass, int depth); 81 char inf, int tag, int aclass, int depth);
79 82
80static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, 83static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
@@ -681,13 +684,13 @@ asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen,
681 long plen; 684 long plen;
682 char cst, inf, free_cont = 0; 685 char cst, inf, free_cont = 0;
683 const unsigned char *p; 686 const unsigned char *p;
684 BUF_MEM buf;
685 const unsigned char *cont = NULL; 687 const unsigned char *cont = NULL;
688 uint8_t *data = NULL;
689 size_t data_len = 0;
690 CBB cbb;
686 long len; 691 long len;
687 692
688 buf.length = 0; 693 memset(&cbb, 0, sizeof(cbb));
689 buf.max = 0;
690 buf.data = NULL;
691 694
692 if (!pval) { 695 if (!pval) {
693 ASN1error(ASN1_R_ILLEGAL_NULL); 696 ASN1error(ASN1_R_ILLEGAL_NULL);
@@ -758,28 +761,34 @@ asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen,
758 } else { 761 } else {
759 len = p - cont + plen; 762 len = p - cont + plen;
760 p += plen; 763 p += plen;
761 buf.data = NULL;
762 } 764 }
763 } else if (cst) { 765 } else if (cst) {
764 /* Should really check the internal tags are correct but 766 /*
767 * Should really check the internal tags are correct but
765 * some things may get this wrong. The relevant specs 768 * some things may get this wrong. The relevant specs
766 * say that constructed string types should be OCTET STRINGs 769 * say that constructed string types should be OCTET STRINGs
767 * internally irrespective of the type. So instead just check 770 * internally irrespective of the type. So instead just check
768 * for UNIVERSAL class and ignore the tag. 771 * for UNIVERSAL class and ignore the tag.
769 */ 772 */
770 if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) { 773 if (!CBB_init(&cbb, 0))
771 free_cont = 1;
772 goto err; 774 goto err;
773 } 775 if (!asn1_collect(&cbb, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0))
774 len = buf.length; 776 goto err;
775 /* Append a final null to string */ 777
776 if (!BUF_MEM_grow_clean(&buf, len + 1)) { 778 /* Append a final NUL to string. */
777 ASN1error(ERR_R_MALLOC_FAILURE); 779 if (!CBB_add_u8(&cbb, 0))
778 return 0; 780 goto err;
779 } 781
780 buf.data[len] = 0; 782 if (!CBB_finish(&cbb, &data, &data_len))
781 cont = (const unsigned char *)buf.data; 783 goto err;
784
782 free_cont = 1; 785 free_cont = 1;
786
787 if (data_len < 1 || data_len > LONG_MAX)
788 goto err;
789
790 cont = data;
791 len = data_len - 1;
783 } else { 792 } else {
784 cont = p; 793 cont = p;
785 len = plen; 794 len = plen;
@@ -793,9 +802,12 @@ asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen,
793 *in = p; 802 *in = p;
794 ret = 1; 803 ret = 1;
795 804
796err: 805 err:
797 if (free_cont && buf.data) 806 CBB_cleanup(&cbb);
798 free(buf.data); 807
808 if (free_cont)
809 freezero(data, data_len);
810
799 return ret; 811 return ret;
800} 812}
801 813
@@ -1011,7 +1023,7 @@ asn1_find_end(const unsigned char **in, long len, char inf)
1011#endif 1023#endif
1012 1024
1013static int 1025static int
1014asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, char inf, 1026asn1_collect(CBB *cbb, const unsigned char **in, long len, char inf,
1015 int tag, int aclass, int depth) 1027 int tag, int aclass, int depth)
1016{ 1028{
1017 const unsigned char *p, *q; 1029 const unsigned char *p, *q;
@@ -1048,18 +1060,12 @@ asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, char inf,
1048 1060
1049 /* If indefinite length constructed update max length */ 1061 /* If indefinite length constructed update max length */
1050 if (cst) { 1062 if (cst) {
1051 if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, 1063 if (!asn1_collect(cbb, &p, plen, ininf, tag, aclass,
1052 depth + 1)) 1064 depth + 1))
1053 return 0; 1065 return 0;
1054 } else if (plen > 0) { 1066 } else if (plen > 0) {
1055 size_t len = buf->length; 1067 if (!CBB_add_bytes(cbb, p, plen))
1056
1057 if (!BUF_MEM_grow_clean(buf, len + plen)) {
1058 ASN1error(ERR_R_MALLOC_FAILURE);
1059 return 0; 1068 return 0;
1060 }
1061 memcpy(buf->data + len, p, plen);
1062
1063 p += plen; 1069 p += plen;
1064 } 1070 }
1065 len -= p - q; 1071 len -= p - q;