diff -up gnutls-1.4.1/lib/minitasn1/decoding.c.length-check gnutls-1.4.1/lib/minitasn1/decoding.c --- gnutls-1.4.1/lib/minitasn1/decoding.c.length-check 2012-03-22 15:58:37.115025377 +0100 +++ gnutls-1.4.1/lib/minitasn1/decoding.c 2012-03-22 15:59:55.647647860 +0100 @@ -54,12 +54,14 @@ _asn1_error_description_tag_error (node_ * Extract a length field from DER data. * * Return value: Return the decoded length value, or -1 on indefinite - * length, or -2 when the value was too big. + * length, or -2 when the value was too big to fit in a int, or -4 + * when the decoded length value plus @len would exceed @der_len. + **/ signed long asn1_get_length_der (const unsigned char *der, int der_len, int *len) { - unsigned long ans; + int ans; int k, punt; *len = 0; @@ -82,7 +84,7 @@ asn1_get_length_der (const unsigned char ans = 0; while (punt <= k && punt < der_len) { - unsigned long last = ans; + int last = ans; ans = ans * 256 + der[punt++]; if (ans < last) @@ -92,10 +94,13 @@ asn1_get_length_der (const unsigned char } else { /* indefinite length method */ - ans = -1; + *len = punt; + return -1; } *len = punt; + if (ans + *len < ans || ans + *len > der_len) + return -4; return ans; } }