diff --git a/lib/asn1/der_get.c b/lib/asn1/der_get.c index 61f53b2b6..01f3d735a 100644 --- a/lib/asn1/der_get.c +++ b/lib/asn1/der_get.c @@ -251,6 +251,70 @@ der_get_octet_string (const unsigned char *p, size_t len, return 0; } +int +der_get_octet_string_ber (const unsigned char *p, size_t len, + heim_octet_string *data, size_t *size) +{ + int e; + Der_type type; + Der_class class; + unsigned int tag, depth = 0; + size_t l, datalen, oldlen = len; + + data->length = 0; + data->data = NULL; + + while (1) { + e = der_get_tag (p, len, &class, &type, &tag, &l); + if (e) goto out; + if (class != ASN1_C_UNIV) return ASN1_BAD_ID; + if (type == PRIM && tag == UT_EndOfContent) { + if (depth == 0) + break; + depth--; + } + if (tag != UT_OctetString) { + e = ASN1_BAD_ID; + goto out; + } + + p += l; + len -= l; + e = der_get_length (p, len, &datalen, &l); + if (e) goto out; + p += l; + len -= l; + + if (datalen > len) + return ASN1_OVERRUN; + + if (type == PRIM) { + void *ptr; + + ptr = realloc(data->data, data->length + datalen); + if (ptr == NULL) { + e = ENOMEM; + goto out; + } + data->data = ptr; + memcpy(((unsigned char *)data->data) + data->length, p, datalen); + data->length += datalen; + } else + depth++; + + p += datalen; + len -= datalen; + } + if(size) *size = oldlen - len; + return 0; + out: + free(data->data); + data->data = NULL; + data->length = 0; + return e; +} + + int der_get_heim_integer (const unsigned char *p, size_t len, heim_integer *data, size_t *size) @@ -454,18 +518,17 @@ der_get_tag (const unsigned char *p, size_t len, int der_match_tag (const unsigned char *p, size_t len, - Der_class class, Der_type type, - unsigned int tag, size_t *size) + Der_class class, Der_type *type, + unsigned int tag, size_t *size) { size_t l; Der_class thisclass; - Der_type thistype; unsigned int thistag; int e; - e = der_get_tag (p, len, &thisclass, &thistype, &thistag, &l); + e = der_get_tag (p, len, &thisclass, type, &thistag, &l); if (e) return e; - if (class != thisclass || type != thistype) + if (class != thisclass) return ASN1_BAD_ID; if(tag > thistag) return ASN1_MISPLACED_FIELD; @@ -477,7 +540,7 @@ der_match_tag (const unsigned char *p, size_t len, int der_match_tag_and_length (const unsigned char *p, size_t len, - Der_class class, Der_type type, unsigned int tag, + Der_class class, Der_type *type, unsigned int tag, size_t *length_ret, size_t *size) { size_t l, ret = 0; @@ -497,6 +560,8 @@ der_match_tag_and_length (const unsigned char *p, size_t len, return 0; } + + /* * Old versions of DCE was based on a very early beta of the MIT code, * which used MAVROS for ASN.1 encoding. MAVROS had the interesting