summaryrefslogtreecommitdiff
path: root/lib/minitasn1/decoding.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/minitasn1/decoding.c')
-rw-r--r--lib/minitasn1/decoding.c368
1 files changed, 219 insertions, 149 deletions
diff --git a/lib/minitasn1/decoding.c b/lib/minitasn1/decoding.c
index 3849375d07..968fa96bfd 100644
--- a/lib/minitasn1/decoding.c
+++ b/lib/minitasn1/decoding.c
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2002, 2004, 2006, 2008, 2009, 2010, 2011 Free Software
- * Foundation, Inc.
+ * Copyright (C) 2002-2012 Free Software Foundation, Inc.
*
* This file is part of LIBTASN1.
*
@@ -55,12 +54,13 @@ _asn1_error_description_tag_error (ASN1_TYPE node, char *ErrorDescription)
* Extract a length field from DER data.
*
* Returns: 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;
@@ -83,7 +83,7 @@ asn1_get_length_der (const unsigned char *der, int der_len, int *len)
ans = 0;
while (punt <= k && punt < der_len)
{
- unsigned long last = ans;
+ int last = ans;
ans = ans * 256 + der[punt++];
if (ans < last)
@@ -93,10 +93,13 @@ asn1_get_length_der (const unsigned char *der, int der_len, int *len)
}
else
{ /* indefinite length method */
- ans = -1;
+ *len = punt;
+ return -1;
}
*len = punt;
+ if (ans + *len < ans || ans + *len > der_len)
+ return -4;
return ans;
}
}
@@ -724,8 +727,6 @@ _asn1_get_octet_string (const unsigned char *der, ASN1_TYPE node, int *len)
len2 = asn1_get_length_der (der, *len, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
- if (len3 + len2 > *len)
- return ASN1_DER_ERROR;
if (node)
_asn1_set_value (node, der, len3 + len2);
counter = len3 + len2;
@@ -824,8 +825,8 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
if (node->type & CONST_OPTION)
{
- asn1_delete_structure (element);
- return ASN1_GENERIC_ERROR;
+ result = ASN1_GENERIC_ERROR;
+ goto cleanup;
}
counter = 0;
@@ -839,7 +840,7 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
if (p->type & CONST_SET)
{
p2 = _asn1_find_up (p);
- len2 = strtol (p2->value, NULL, 10);
+ len2 = _asn1_strtol (p2->value, NULL, 10);
if (len2 == -1)
{
if (!der[counter] && !der[counter + 1])
@@ -858,8 +859,8 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
}
else if (counter > len2)
{
- asn1_delete_structure (element);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
p2 = p2->down;
while (p2)
@@ -894,15 +895,15 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
}
if (p2 == NULL)
{
- asn1_delete_structure (element);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
}
if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
{
p2 = _asn1_find_up (p);
- len2 = strtol (p2->value, NULL, 10);
+ len2 = _asn1_strtol (p2->value, NULL, 10);
if (counter == len2)
{
if (p->right)
@@ -942,8 +943,8 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
}
else if (ris == ASN1_ERROR_TYPE_ANY)
{
- asn1_delete_structure (element);
- return ASN1_ERROR_TYPE_ANY;
+ result = ASN1_ERROR_TYPE_ANY;
+ goto cleanup;
}
else
{
@@ -956,8 +957,8 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
{
if (!(p->type & CONST_OPTION))
{
- asn1_delete_structure (element);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
}
else
@@ -967,7 +968,7 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
{
p2 = _asn1_find_up (p);
- len2 = strtol (p2->value, NULL, 10);
+ len2 = _asn1_strtol (p2->value, NULL, 10);
if ((len2 != -1) && (counter > len2))
ris = ASN1_TAG_ERROR;
}
@@ -992,8 +993,8 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
if (errorDescription != NULL)
_asn1_error_description_tag_error (p, errorDescription);
- asn1_delete_structure (element);
- return ASN1_TAG_ERROR;
+ result = ASN1_TAG_ERROR;
+ goto cleanup;
}
}
else
@@ -1007,8 +1008,8 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
case TYPE_NULL:
if (der[counter])
{
- asn1_delete_structure (element);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
counter++;
move = RIGHT;
@@ -1016,8 +1017,8 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
case TYPE_BOOLEAN:
if (der[counter++] != 1)
{
- asn1_delete_structure (element);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
if (der[counter++] == 0)
_asn1_set_value (p, "F", 1);
@@ -1030,9 +1031,11 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
- return ASN1_DER_ERROR;
- if (len2 + len3 > len - counter)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+
_asn1_set_value (p, der + counter, len3 + len2);
counter += len3 + len2;
move = RIGHT;
@@ -1042,10 +1045,7 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
_asn1_get_objectid_der (der + counter, len - counter, &len2,
temp, sizeof (temp));
if (result != ASN1_SUCCESS)
- {
- asn1_delete_structure (element);
- return result;
- }
+ goto cleanup;
tlen = strlen (temp);
if (tlen > 0)
@@ -1058,10 +1058,8 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
_asn1_get_time_der (der + counter, len - counter, &len2, temp,
sizeof (temp) - 1);
if (result != ASN1_SUCCESS)
- {
- asn1_delete_structure (element);
- return result;
- }
+ goto cleanup;
+
tlen = strlen (temp);
if (tlen > 0)
_asn1_set_value (p, temp, tlen + 1);
@@ -1070,9 +1068,10 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
break;
case TYPE_OCTET_STRING:
len3 = len - counter;
- ris = _asn1_get_octet_string (der + counter, p, &len3);
- if (ris != ASN1_SUCCESS)
- return ris;
+ result = _asn1_get_octet_string (der + counter, p, &len3);
+ if (result != ASN1_SUCCESS)
+ goto cleanup;
+
counter += len3;
move = RIGHT;
break;
@@ -1080,9 +1079,11 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
- return ASN1_DER_ERROR;
- if (len3 + len2 > len - counter)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+
_asn1_set_value (p, der + counter, len3 + len2);
counter += len3 + len2;
move = RIGHT;
@@ -1091,9 +1092,11 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
- return ASN1_DER_ERROR;
- if (len3 + len2 > len - counter)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+
_asn1_set_value (p, der + counter, len3 + len2);
counter += len3 + len2;
move = RIGHT;
@@ -1102,7 +1105,7 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
case TYPE_SET:
if (move == UP)
{
- len2 = strtol (p->value, NULL, 10);
+ len2 = _asn1_strtol (p->value, NULL, 10);
_asn1_set_value (p, NULL, 0);
if (len2 == -1)
{ /* indefinite length method */
@@ -1110,20 +1113,23 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
{
if ((der[counter]) || der[counter + 1])
{
- asn1_delete_structure (element);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
}
else
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
counter += 2;
}
else
{ /* definite length method */
if (len2 != counter)
{
- asn1_delete_structure (element);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
}
move = RIGHT;
@@ -1133,7 +1139,10 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
len3 =
asn1_get_length_der (der + counter, len - counter, &len2);
if (len3 < -1)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
counter += len2;
if (len3 > 0)
{
@@ -1170,11 +1179,15 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
case TYPE_SET_OF:
if (move == UP)
{
- len2 = strtol (p->value, NULL, 10);
+ len2 = _asn1_strtol (p->value, NULL, 10);
if (len2 == -1)
{ /* indefinite length method */
if ((counter + 2) > len)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+
if ((der[counter]) || der[counter + 1])
{
_asn1_append_sequence_set (p);
@@ -1201,8 +1214,8 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
_asn1_set_value (p, NULL, 0);
if (len2 != counter)
{
- asn1_delete_structure (element);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
}
}
@@ -1211,7 +1224,10 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
len3 =
asn1_get_length_der (der + counter, len - counter, &len2);
if (len3 < -1)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
counter += len2;
if (len3)
{
@@ -1242,16 +1258,24 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
if (asn1_get_tag_der
(der + counter, len - counter, &class, &len2,
&tag) != ASN1_SUCCESS)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+
if (counter + len2 > len)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
len4 =
asn1_get_length_der (der + counter + len2,
len - counter - len2, &len3);
if (len4 < -1)
- return ASN1_DER_ERROR;
- if (len4 > len - counter + len2 + len3)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
if (len4 != -1)
{
len2 += len4;
@@ -1267,13 +1291,10 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
indefinite = 0;
len2 = len - counter;
- ris =
+ result =
_asn1_get_indefinite_length_string (der + counter, &len2);
- if (ris != ASN1_SUCCESS)
- {
- asn1_delete_structure (element);
- return ris;
- }
+ if (result != ASN1_SUCCESS)
+ goto cleanup;
_asn1_set_value_octet (p, der + counter, len2);
counter += len2;
@@ -1288,9 +1309,9 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
}
else
{
- asn1_delete_structure (element);
- return ASN1_DER_ERROR;
- }
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
}
}
move = RIGHT;
@@ -1326,11 +1347,15 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
if (counter != len)
{
- asn1_delete_structure (element);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
return ASN1_SUCCESS;
+
+cleanup:
+ asn1_delete_structure (element);
+ return result;
}
#define FOUND 1
@@ -1379,14 +1404,14 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
if (elementName == NULL)
{
- asn1_delete_structure (structure);
- return ASN1_ELEMENT_NOT_FOUND;
+ result = ASN1_ELEMENT_NOT_FOUND;
+ goto cleanup;
}
if (node->type & CONST_OPTION)
{
- asn1_delete_structure (structure);
- return ASN1_GENERIC_ERROR;
+ result = ASN1_GENERIC_ERROR;
+ goto cleanup;
}
if ((*structure)->name)
@@ -1396,8 +1421,8 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
strcpy (currentName, (*structure)->name);
else
{
- asn1_delete_structure (structure);
- return ASN1_MEM_ERROR;
+ result = ASN1_MEM_ERROR;
+ goto cleanup;
}
if (!(strcmp (currentName, elementName)))
{
@@ -1436,7 +1461,7 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
if (p->type & CONST_SET)
{
p2 = _asn1_find_up (p);
- len2 = strtol (p2->value, NULL, 10);
+ len2 = _asn1_strtol (p2->value, NULL, 10);
if (counter == len2)
{
p = p2;
@@ -1445,8 +1470,8 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
}
else if (counter > len2)
{
- asn1_delete_structure (structure);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
p2 = p2->down;
while (p2)
@@ -1481,15 +1506,15 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
}
if (p2 == NULL)
{
- asn1_delete_structure (structure);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
}
if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
{
p2 = _asn1_find_up (p);
- len2 = strtol (p2->value, NULL, 10);
+ len2 = _asn1_strtol (p2->value, NULL, 10);
if (counter == len2)
{
if (p->right)
@@ -1529,8 +1554,8 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
}
else if (ris == ASN1_ERROR_TYPE_ANY)
{
- asn1_delete_structure (structure);
- return ASN1_ERROR_TYPE_ANY;
+ result = ASN1_ERROR_TYPE_ANY;
+ goto cleanup;
}
else
{
@@ -1543,8 +1568,8 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
{
if (!(p->type & CONST_OPTION))
{
- asn1_delete_structure (structure);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
}
else
@@ -1554,7 +1579,7 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
{
p2 = _asn1_find_up (p);
- len2 = strtol (p2->value, NULL, 10);
+ len2 = _asn1_strtol (p2->value, NULL, 10);
if (counter > len2)
ris = ASN1_TAG_ERROR;
}
@@ -1579,8 +1604,8 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
if (errorDescription != NULL)
_asn1_error_description_tag_error (p, errorDescription);
- asn1_delete_structure (structure);
- return ASN1_TAG_ERROR;
+ result = ASN1_TAG_ERROR;
+ goto cleanup;
}
}
else
@@ -1594,8 +1619,8 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
case TYPE_NULL:
if (der[counter])
{
- asn1_delete_structure (structure);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
if (p == nodeFound)
@@ -1607,8 +1632,8 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
case TYPE_BOOLEAN:
if (der[counter++] != 1)
{
- asn1_delete_structure (structure);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
if (state == FOUND)
@@ -1632,11 +1657,18 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+
if (state == FOUND)
{
if (len3 + len2 > len - counter)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
_asn1_set_value (p, der + counter, len3 + len2);
if (p == nodeFound)
@@ -1652,9 +1684,7 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
_asn1_get_objectid_der (der + counter, len - counter,
&len2, temp, sizeof (temp));
if (result != ASN1_SUCCESS)
- {
- return result;
- }
+ goto cleanup;
tlen = strlen (temp);
@@ -1669,7 +1699,10 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
len2 += len3;
}
@@ -1683,10 +1716,7 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
_asn1_get_time_der (der + counter, len - counter, &len2,
temp, sizeof (temp) - 1);
if (result != ASN1_SUCCESS)
- {
- asn1_delete_structure (structure);
- return result;
- }
+ goto cleanup;
tlen = strlen (temp);
if (tlen > 0)
@@ -1700,7 +1730,10 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
len2 += len3;
}
@@ -1711,15 +1744,16 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
len3 = len - counter;
if (state == FOUND)
{
- ris = _asn1_get_octet_string (der + counter, p, &len3);
+ result = _asn1_get_octet_string (der + counter, p, &len3);
if (p == nodeFound)
state = EXIT;
}
else
- ris = _asn1_get_octet_string (der + counter, NULL, &len3);
+ result = _asn1_get_octet_string (der + counter, NULL, &len3);
+
+ if (result != ASN1_SUCCESS)
+ goto cleanup;
- if (ris != ASN1_SUCCESS)
- return ris;
counter += len3;
move = RIGHT;
break;
@@ -1727,11 +1761,18 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+
if (state == FOUND)
{
if (len3 + len2 > len - counter)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
_asn1_set_value (p, der + counter, len3 + len2);
if (p == nodeFound)
@@ -1744,11 +1785,17 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
if (state == FOUND)
{
if (len3 + len2 > len - counter)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
_asn1_set_value (p, der + counter, len3 + len2);
if (p == nodeFound)
@@ -1761,14 +1808,14 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
case TYPE_SET:
if (move == UP)
{
- len2 = strtol (p->value, NULL, 10);
+ len2 = _asn1_strtol (p->value, NULL, 10);
_asn1_set_value (p, NULL, 0);
if (len2 == -1)
{ /* indefinite length method */
if ((der[counter]) || der[counter + 1])
{
- asn1_delete_structure (structure);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
counter += 2;
}
@@ -1776,8 +1823,8 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
{ /* definite length method */
if (len2 != counter)
{
- asn1_delete_structure (structure);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
}
if (p == nodeFound)
@@ -1792,7 +1839,10 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
asn1_get_length_der (der + counter, len - counter,
&len2);
if (len3 < 0)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
counter += len2 + len3;
move = RIGHT;
}
@@ -1802,7 +1852,10 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
asn1_get_length_der (der + counter, len - counter,
&len2);
if (len3 < 0)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
counter += len2;
if (len3 > 0)
{
@@ -1841,7 +1894,7 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
case TYPE_SET_OF:
if (move == UP)
{
- len2 = strtol (p->value, NULL, 10);
+ len2 = _asn1_strtol (p->value, NULL, 10);
if (len2 > counter)
{
_asn1_append_sequence_set (p);
@@ -1854,8 +1907,8 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
_asn1_set_value (p, NULL, 0);
if (len2 != counter)
{
- asn1_delete_structure (structure);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
if (p == nodeFound)
@@ -1869,7 +1922,10 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
asn1_get_length_der (der + counter, len - counter,
&len2);
if (len3 < 0)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
counter += len2 + len3;
move = RIGHT;
}
@@ -1879,7 +1935,10 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
asn1_get_length_der (der + counter, len - counter,
&len2);
if (len3 < 0)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
counter += len2;
if (len3)
{
@@ -1905,15 +1964,25 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
if (asn1_get_tag_der
(der + counter, len - counter, &class, &len2,
&tag) != ASN1_SUCCESS)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
+
if (counter + len2 > len)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
len4 =
asn1_get_length_der (der + counter + len2,
len - counter - len2, &len3);
if (len4 < -1)
- return ASN1_DER_ERROR;
+ {
+ result = ASN1_DER_ERROR;
+ goto cleanup;
+ }
if (len4 != -1)
{
@@ -1936,13 +2005,10 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
indefinite = 0;
len2 = len - counter;
- ris =
+ result =
_asn1_get_indefinite_length_string (der + counter, &len2);
- if (ris != ASN1_SUCCESS)
- {
- asn1_delete_structure (structure);
- return ris;
- }
+ if (result != ASN1_SUCCESS)
+ goto cleanup;
if (state == FOUND)
{
@@ -1964,8 +2030,8 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
}
else
{
- asn1_delete_structure (structure);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
}
}
@@ -1998,8 +2064,8 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
}
else
{
- asn1_delete_structure (structure);
- return ASN1_MEM_ERROR;
+ result = ASN1_MEM_ERROR;
+ goto cleanup;
}
if (!(strcmp (currentName, elementName)))
{
@@ -2041,8 +2107,8 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
strcat (currentName, p->name);
else
{
- asn1_delete_structure (structure);
- return ASN1_MEM_ERROR;
+ result = ASN1_MEM_ERROR;
+ goto cleanup;
}
if (!(strcmp (currentName, elementName)))
@@ -2096,11 +2162,15 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
if (counter > len)
{
- asn1_delete_structure (structure);
- return ASN1_DER_ERROR;
+ result = ASN1_DER_ERROR;
+ goto cleanup;
}
return ASN1_SUCCESS;
+
+cleanup:
+ asn1_delete_structure (structure);
+ return result;
}
/**
@@ -2171,7 +2241,7 @@ asn1_der_decoding_startEnd (ASN1_TYPE element, const void *ider, int len,
if (p->type & CONST_SET)
{
p2 = _asn1_find_up (p);
- len2 = strtol (p2->value, NULL, 10);
+ len2 = _asn1_strtol (p2->value, NULL, 10);
if (len2 == -1)
{
if (!der[counter] && !der[counter + 1])
@@ -2562,7 +2632,7 @@ asn1_expand_any_defined_by (ASN1_TYPE definitions, ASN1_TYPE * element)
asn1_read_value (definitions, name, value, &len);
if ((result == ASN1_SUCCESS)
- && (!strcmp (p3->value, value)))
+ && (!_asn1_strcmp (p3->value, value)))
{
p2 = p2->right; /* pointer to the structure to
use for expansion */
@@ -2743,7 +2813,7 @@ asn1_expand_octet_string (ASN1_TYPE definitions, ASN1_TYPE * element,
result = asn1_read_value (definitions, name, value, &len);
if ((result == ASN1_SUCCESS)
- && (!strcmp (objectNode->value, value)))
+ && (!_asn1_strcmp (objectNode->value, value)))
{
p2 = p2->right; /* pointer to the structure to