summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/decoding.c10
-rw-r--r--lib/element.c18
-rw-r--r--lib/element.h2
3 files changed, 22 insertions, 8 deletions
diff --git a/lib/decoding.c b/lib/decoding.c
index c79a5c4..199580c 100644
--- a/lib/decoding.c
+++ b/lib/decoding.c
@@ -899,6 +899,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len,
asn1_node node, p, p2, p3;
char temp[128];
int counter, len2, len3, len4, move, ris, tlen;
+ asn1_node ptail = NULL;
unsigned char class;
unsigned long tag;
int indefinite, result, total_len = ider_len;
@@ -1290,7 +1291,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len,
{ /* indefinite length method */
if (!HAVE_TWO(ider_len) || ((der[counter]) || der[counter + 1]))
{
- _asn1_append_sequence_set (p);
+ _asn1_append_sequence_set (p, &ptail);
p = p->down;
while (p->right)
p = p->right;
@@ -1299,6 +1300,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len,
}
p->tmp_ival = 0;
+ ptail = NULL; /* finished decoding this structure */
DECR_LEN(ider_len, 2);
counter += 2;
}
@@ -1306,7 +1308,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len,
{ /* definite length method */
if (len2 > counter)
{
- _asn1_append_sequence_set (p);
+ _asn1_append_sequence_set (p, &ptail);
p = p->down;
while (p->right)
p = p->right;
@@ -1315,6 +1317,8 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len,
}
p->tmp_ival = 0;
+ ptail = NULL; /* finished decoding this structure */
+
if (len2 != counter)
{
result = ASN1_DER_ERROR;
@@ -1351,7 +1355,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len,
|| (type_field (p2->type) == ASN1_ETYPE_SIZE))
p2 = p2->right;
if (p2->right == NULL)
- _asn1_append_sequence_set (p);
+ _asn1_append_sequence_set (p, &ptail);
p = p2;
}
}
diff --git a/lib/element.c b/lib/element.c
index b45c3ec..66bd8fa 100644
--- a/lib/element.c
+++ b/lib/element.c
@@ -130,7 +130,7 @@ _asn1_convert_integer (const unsigned char *value, unsigned char *value_out,
int
-_asn1_append_sequence_set (asn1_node node)
+_asn1_append_sequence_set (asn1_node node, asn1_node *ptail)
{
asn1_node p, p2;
char temp[LTOSTR_MAX_SIZE];
@@ -144,9 +144,19 @@ _asn1_append_sequence_set (asn1_node node)
|| (type_field (p->type) == ASN1_ETYPE_SIZE))
p = p->right;
p2 = _asn1_copy_structure3 (p);
- while (p->right)
- p = p->right;
+
+ if (ptail == NULL || *ptail == NULL || (*ptail)->up != p->up)
+ while (p->right) {
+ p = p->right;
+ }
+ else
+ {
+ p = *ptail;
+ }
+
_asn1_set_right (p, p2);
+ if (ptail)
+ *ptail = p2;
if (p->name[0] == 0)
_asn1_str_cpy (temp, sizeof (temp), "?1");
@@ -608,7 +618,7 @@ asn1_write_value (asn1_node node_root, const char *name,
case ASN1_ETYPE_SET_OF:
if (_asn1_strcmp (value, "NEW"))
return ASN1_VALUE_NOT_VALID;
- _asn1_append_sequence_set (node);
+ _asn1_append_sequence_set (node, NULL);
break;
default:
return ASN1_ELEMENT_NOT_FOUND;
diff --git a/lib/element.h b/lib/element.h
index fdecafb..65a4845 100644
--- a/lib/element.h
+++ b/lib/element.h
@@ -23,7 +23,7 @@
#define _ELEMENT_H
-int _asn1_append_sequence_set (asn1_node node);
+int _asn1_append_sequence_set (asn1_node node, asn1_node *pcached);
int _asn1_convert_integer (const unsigned char *value,
unsigned char *value_out,