From: Pauli Date: Tue, 11 Jul 2017 22:54:14 +0000 (+1000) Subject: Avoid having an unsigned integer decrement below zero. X-Git-Tag: OpenSSL_1_1_1-pre1~1052 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=a9a157e74a0c6a886e593426f263f3d7359497b9;p=oweals%2Fopenssl.git Avoid having an unsigned integer decrement below zero. Reviewed-by: Andy Polyakov (Merged from https://github.com/openssl/openssl/pull/3912) --- diff --git a/crypto/asn1/asn1_lib.c b/crypto/asn1/asn1_lib.c index 8ca53b4ce4..3f5c12d50b 100644 --- a/crypto/asn1/asn1_lib.c +++ b/crypto/asn1/asn1_lib.c @@ -102,41 +102,48 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, return (0x80); } +/* + * Decode a length field. + * The short form is a single byte defining a length 0 - 127. + * The long form is a byte 0 - 127 with the top bit set and this indicates + * the number of following octets that contain the length. These octets + * are stored most significant digit first. + */ static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, long max) { const unsigned char *p = *pp; unsigned long ret = 0; - unsigned long i; + int i; if (max-- < 1) return 0; if (*p == 0x80) { *inf = 1; - ret = 0; p++; } else { *inf = 0; i = *p & 0x7f; - if (*(p++) & 0x80) { - if (max < (long)i + 1) + if (*p++ & 0x80) { + if (max < i + 1) return 0; /* Skip leading zeroes */ - while (i && *p == 0) { + while (i > 0 && *p == 0) { p++; i--; } - if (i > sizeof(long)) + if (i > (int)sizeof(long)) return 0; - while (i-- > 0) { - ret <<= 8L; - ret |= *(p++); + while (i > 0) { + ret <<= 8; + ret |= *p++; + i--; } + if (ret > LONG_MAX) + return 0; } else ret = i; } - if (ret > LONG_MAX) - return 0; *pp = p; *rl = (long)ret; return 1;