diff --git a/lib/ASN1.c b/lib/ASN1.c index 586dcca..47074f0 100644 --- a/lib/ASN1.c +++ b/lib/ASN1.c @@ -2811,7 +2811,12 @@ asn1_parser2tree (const char *file, asn1_node * definitions, /* Convert into DER coding the value assign to INTEGER constants */ _asn1_change_integer_value (p_tree); /* Expand the IDs of OBJECT IDENTIFIER constants */ - _asn1_expand_object_id (p_tree); + result_parse = _asn1_expand_object_id (p_tree); + if (result_parse != ASN1_SUCCESS) + { + _asn1_delete_list_and_nodes (); + goto error; + } *definitions = p_tree; } @@ -2824,6 +2829,7 @@ asn1_parser2tree (const char *file, asn1_node * definitions, _asn1_delete_list_and_nodes (); } + error: _asn1_create_errorDescription (result_parse, error_desc); return result_parse; diff --git a/lib/ASN1.y b/lib/ASN1.y index 534a9f1..0b81b5b 100644 --- a/lib/ASN1.y +++ b/lib/ASN1.y @@ -701,7 +701,9 @@ asn1_parser2tree (const char *file, asn1_node * definitions, /* Convert into DER coding the value assign to INTEGER constants */ _asn1_change_integer_value (p_tree); /* Expand the IDs of OBJECT IDENTIFIER constants */ - _asn1_expand_object_id (p_tree); + result_parse = _asn1_expand_object_id (p_tree); + if (result_parse != ASN1_SUCCESS) + goto error; *definitions = p_tree; } @@ -714,6 +716,7 @@ asn1_parser2tree (const char *file, asn1_node * definitions, _asn1_delete_list_and_nodes (); } + error: _asn1_create_errorDescription (result_parse, error_desc); return result_parse; diff --git a/lib/errors.c b/lib/errors.c index fef45ae..cee74da 100644 --- a/lib/errors.c +++ b/lib/errors.c @@ -53,6 +53,7 @@ static const libtasn1_error_entry error_algorithms[] = { LIBTASN1_ERROR_ENTRY (ASN1_ARRAY_ERROR), LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_EMPTY), LIBTASN1_ERROR_ENTRY (ASN1_TIME_ENCODING_ERROR), + LIBTASN1_ERROR_ENTRY (ASN1_RECURSION), {0, 0} }; diff --git a/lib/libtasn1.h b/lib/libtasn1.h index ea26b78..8c757d6 100644 --- a/lib/libtasn1.h +++ b/lib/libtasn1.h @@ -79,6 +79,7 @@ extern "C" #define ASN1_ARRAY_ERROR 16 #define ASN1_ELEMENT_NOT_EMPTY 17 #define ASN1_TIME_ENCODING_ERROR 18 +#define ASN1_RECURSION 19 /*************************************/ /* Constants used in asn1_visit_tree */ diff --git a/lib/parser_aux.c b/lib/parser_aux.c index 786ea64..0090157 100644 --- a/lib/parser_aux.c +++ b/lib/parser_aux.c @@ -516,6 +516,23 @@ _asn1_find_up (asn1_node node) return p->left; } +/******************************************************************/ +/* Function : _asn1_delete_node_from_list */ +/* Description: deletes the list element given */ +/******************************************************************/ +static void +_asn1_delete_node_from_list (asn1_node node) +{ + list_type *p = firstElement; + + while (p) + { + if (p->node == node) + p->node = NULL; + p = p->next; + } +} + /******************************************************************/ /* Function : _asn1_delete_list */ /* Description: deletes the list elements (not the elements */ @@ -667,15 +684,15 @@ _asn1_change_integer_value (asn1_node node) /* Parameters: */ /* node: root of an ASN1 element. */ /* Return: */ -/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ -/* otherwise ASN1_SUCCESS */ +/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ +/* otherwise ASN1_SUCCESS */ /******************************************************************/ int _asn1_expand_object_id (asn1_node node) { asn1_node p, p2, p3, p4, p5; char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1]; - int move, tlen; + int move, tlen, tries; if (node == NULL) return ASN1_ELEMENT_NOT_FOUND; @@ -684,6 +701,7 @@ _asn1_expand_object_id (asn1_node node) p = node; move = DOWN; + tries = 0; while (!((p == node) && (move == UP))) { @@ -707,6 +725,7 @@ _asn1_expand_object_id (asn1_node node) || !(p3->type & CONST_ASSIGN)) return ASN1_ELEMENT_NOT_FOUND; _asn1_set_down (p, p2->right); + _asn1_delete_node_from_list(p2); _asn1_remove_node (p2, 0); p2 = p; p4 = p3->down; @@ -738,6 +757,11 @@ _asn1_expand_object_id (asn1_node node) p4 = p4->right; } move = DOWN; + + tries++; + if (tries >= EXPAND_OBJECT_ID_MAX_RECURSION) + return ASN1_RECURSION; + continue; } } @@ -747,6 +771,7 @@ _asn1_expand_object_id (asn1_node node) else move = RIGHT; + tries = 0; if (move == DOWN) { if (p->down) diff --git a/lib/parser_aux.h b/lib/parser_aux.h index 9f91833..bb05ae8 100644 --- a/lib/parser_aux.h +++ b/lib/parser_aux.h @@ -60,6 +60,7 @@ asn1_node _asn1_find_up (asn1_node node); int _asn1_change_integer_value (asn1_node node); +#define EXPAND_OBJECT_ID_MAX_RECURSION 16 int _asn1_expand_object_id (asn1_node node); int _asn1_type_set_config (asn1_node node); diff --git a/lib/structure.c b/lib/structure.c index 01715b1..f6a93fa 100644 --- a/lib/structure.c +++ b/lib/structure.c @@ -245,7 +245,7 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, if (result == ASN1_SUCCESS) { _asn1_change_integer_value (*definitions); - _asn1_expand_object_id (*definitions); + result = _asn1_expand_object_id (*definitions); } } else