diff options
Diffstat (limited to 'source4/heimdal/lib/asn1/der_get.c')
-rw-r--r-- | source4/heimdal/lib/asn1/der_get.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/source4/heimdal/lib/asn1/der_get.c b/source4/heimdal/lib/asn1/der_get.c index 403f5ab1ba..a75ab15c09 100644 --- a/source4/heimdal/lib/asn1/der_get.c +++ b/source4/heimdal/lib/asn1/der_get.c @@ -33,7 +33,7 @@ #include "der_locl.h" -RCSID("$Id: der_get.c,v 1.44 2005/07/19 18:04:00 lha Exp $"); +RCSID("$Id: der_get.c,v 1.45 2006/01/20 10:03:50 lha Exp $"); #include <version.h> @@ -241,19 +241,40 @@ der_get_heim_integer (const unsigned char *p, size_t len, return 0; } if (p[0] & 0x80) { + unsigned char *q; + int carry = 1; data->negative = 1; - return ASN1_OVERRUN; + data->length = len; + + if (p[0] == 0xff) { + p++; + data->length--; + } + data->data = malloc(data->length); + if (data->data == NULL) { + data->length = 0; + return ENOMEM; + } + q = &((unsigned char*)data->data)[data->length - 1]; + p += data->length - 1; + while (q >= (unsigned char*)data->data) { + *q = *p ^ 0xff; + if (carry) + carry = !++*q; + p--; + q--; + } } else { data->negative = 0; data->length = len; - if (p[0] == 0 && data->length != 1) { + if (p[0] == 0) { p++; data->length--; } data->data = malloc(data->length); - if (data->data == NULL) { + if (data->data == NULL && data->length != 0) { data->length = 0; return ENOMEM; } |