From 38536d7313b080bc0b3c536f09fac533502df5a1 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Wed, 19 Jan 2022 22:53:25 -0500 Subject: [PATCH] lib/asn1: set *size output to zero at start of der funcs Assign zero to the output size parameter at the start so that callers that use the value when an error occurs do not see garbage that might be misinterpreted. Change-Id: Iccfcf4f6944b1bf72789c83919901d9b9d6f9153 --- lib/asn1/der_get.c | 42 ++++++++++++++++++++++++++++++++++++++---- lib/asn1/der_put.c | 27 +++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/lib/asn1/der_get.c b/lib/asn1/der_get.c index 264138e11..152d2527f 100644 --- a/lib/asn1/der_get.c +++ b/lib/asn1/der_get.c @@ -174,6 +174,9 @@ der_get_general_string (const unsigned char *p, size_t len, const unsigned char *p1; char *s; + if (size) + *size = 0; + p1 = memchr(p, 0, len); if (p1 != NULL) { /* @@ -217,6 +220,9 @@ int ASN1CALL der_get_printable_string(const unsigned char *p, size_t len, heim_printable_string *str, size_t *size) { + if (size) + *size = 0; + if (len == SIZE_MAX) { gen_data_zero(str); return ASN1_BAD_LENGTH; @@ -246,6 +252,9 @@ der_get_bmp_string (const unsigned char *p, size_t len, { size_t i; + if (size) + *size = 0; + if (len & 1) { gen_data_zero(data); return ASN1_BAD_FORMAT; @@ -282,6 +291,9 @@ der_get_universal_string (const unsigned char *p, size_t len, { size_t i; + if (size) + *size = 0; + if (len & 3) { gen_data_zero(data); return ASN1_BAD_FORMAT; @@ -322,6 +334,8 @@ int ASN1CALL der_get_octet_string (const unsigned char *p, size_t len, heim_octet_string *data, size_t *size) { + if (size) + *size = 0; data->length = len; data->data = malloc(len); if (data->data == NULL && data->length != 0) @@ -341,6 +355,9 @@ der_get_octet_string_ber (const unsigned char *p, size_t len, unsigned int tag, depth = 0; size_t l, datalen, oldlen = len; + if (size) + *size = 0; + data->length = 0; data->data = NULL; @@ -408,11 +425,12 @@ der_get_heim_integer (const unsigned char *p, size_t len, data->negative = 0; data->data = NULL; - if (len == 0) { - if (size) - *size = 0; + if (size) + *size = 0; + + if (len == 0) return 0; - } + if (p[0] & 0x80) { unsigned char *q; int carry = 1; @@ -493,6 +511,9 @@ der_get_time (const unsigned char *p, size_t len, char *times; int e; + if (size) + *size = 0; + if (len == SIZE_MAX || len == 0) return ASN1_BAD_LENGTH; @@ -528,6 +549,9 @@ der_get_oid (const unsigned char *p, size_t len, size_t n; size_t oldlen = len; + if (size) + *size = 0; + if (len < 1) return ASN1_OVERRUN; @@ -575,6 +599,10 @@ der_get_tag (const unsigned char *p, size_t len, unsigned int *tag, size_t *size) { size_t ret = 0; + + if (size) + *size = 0; + if (len < 1) return ASN1_MISSING_FIELD; *cls = (Der_class)(((*p) >> 6) & 0x03); @@ -625,6 +653,9 @@ der_match_tag2 (const unsigned char *p, size_t len, unsigned int thistag; int e; + if (size) + *size = 0; + e = der_get_tag(p, len, &thisclass, type, &thistag, &l); if (e) return e; /* @@ -700,6 +731,9 @@ int ASN1CALL der_get_bit_string (const unsigned char *p, size_t len, heim_bit_string *data, size_t *size) { + if (size) + *size = 0; + if (len < 1) return ASN1_OVERRUN; if (p[0] > 7) diff --git a/lib/asn1/der_put.c b/lib/asn1/der_put.c index 7fab5f4e0..6c4aa9d65 100644 --- a/lib/asn1/der_put.c +++ b/lib/asn1/der_put.c @@ -49,6 +49,8 @@ der_put_unsigned (unsigned char *p, size_t len, const unsigned *v, size_t *size) unsigned char *base = p; unsigned val = *v; + *size = 0; + if (val) { while (len > 0 && val) { *p-- = val % 256; @@ -81,6 +83,8 @@ der_put_unsigned64 (unsigned char *p, size_t len, const uint64_t *v, size_t *siz unsigned char *base = p; uint64_t val = *v; + *size = 0; + if (val) { while (len > 0 && val) { *p-- = val % 256; @@ -113,6 +117,8 @@ der_put_integer (unsigned char *p, size_t len, const int *v, size_t *size) unsigned char *base = p; int val = *v; + *size = 0; + if(val >= 0) { do { if(len < 1) @@ -153,6 +159,8 @@ der_put_integer64 (unsigned char *p, size_t len, const int64_t *v, size_t *size) unsigned char *base = p; int64_t val = *v; + *size = 0; + if(val >= 0) { do { if(len < 1) @@ -191,6 +199,8 @@ der_put_integer64 (unsigned char *p, size_t len, const int64_t *v, size_t *size) int ASN1CALL der_put_length (unsigned char *p, size_t len, size_t val, size_t *size) { + *size = 0; + if (len < 1) return ASN1_OVERFLOW; @@ -218,6 +228,8 @@ der_put_length (unsigned char *p, size_t len, size_t val, size_t *size) int ASN1CALL der_put_boolean(unsigned char *p, size_t len, const int *data, size_t *size) { + *size = 0; + if(len < 1) return ASN1_OVERFLOW; if(*data != 0) @@ -234,6 +246,7 @@ der_put_general_string (unsigned char *p, size_t len, { size_t slen = strlen(*str); + *size = 0; if (len < slen) return ASN1_OVERFLOW; p -= slen; @@ -268,6 +281,10 @@ der_put_bmp_string (unsigned char *p, size_t len, const heim_bmp_string *data, size_t *size) { size_t i; + + if (size) + *size = 0; + if (len / 2 < data->length) return ASN1_OVERFLOW; p -= data->length * 2; @@ -285,6 +302,10 @@ der_put_universal_string (unsigned char *p, size_t len, const heim_universal_string *data, size_t *size) { size_t i; + + if (size) + *size = 0; + if (len / 4 < data->length) return ASN1_OVERFLOW; p -= data->length * 4; @@ -310,6 +331,7 @@ int ASN1CALL der_put_octet_string (unsigned char *p, size_t len, const heim_octet_string *data, size_t *size) { + *size = 0; if (len < data->length) return ASN1_OVERFLOW; p -= data->length; @@ -325,6 +347,9 @@ der_put_heim_integer (unsigned char *p, size_t len, unsigned char *buf = data->data; int hibitset = 0; + if (size) + *size = 0; + if (data->length == 0) { if (len < 1) return ASN1_OVERFLOW; @@ -629,6 +654,8 @@ der_put_bit_string (unsigned char *p, size_t len, const heim_bit_string *data, size_t *size) { size_t data_size = (data->length + 7) / 8; + + *size = 0; if (len < data_size + 1) return ASN1_OVERFLOW; p -= data_size + 1;