204 lines
6.5 KiB
Diff
204 lines
6.5 KiB
Diff
From 1213efef01cd0e58dff341e126b1af180cc27a1e Mon Sep 17 00:00:00 2001
|
|
From: Mike Gorse <mgorse@alum.wpi.edu>
|
|
Date: Thu, 11 Apr 2019 11:14:58 -0500
|
|
Subject: [PATCH] _asn1_expand_object_id: Limit recursion
|
|
|
|
Resolves #4
|
|
|
|
Signed-off-by: Mike Gorse <mgorse@suse.com>
|
|
Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
|
|
---
|
|
lib/ASN1.c | 8 +++++++-
|
|
lib/ASN1.y | 5 ++++-
|
|
lib/errors.c | 1 +
|
|
lib/libtasn1.h | 1 +
|
|
lib/parser_aux.c | 31 ++++++++++++++++++++++++++++---
|
|
lib/parser_aux.h | 1 +
|
|
lib/structure.c | 2 +-
|
|
7 files changed, 43 insertions(+), 6 deletions(-)
|
|
|
|
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 7d7ccf3..e5fecbd 100644
|
|
--- a/lib/parser_aux.c
|
|
+++ b/lib/parser_aux.c
|
|
@@ -517,6 +517,23 @@ _asn1_find_up (asn1_node node)
|
|
}
|
|
|
|
/******************************************************************/
|
|
+/* 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 */
|
|
/* pointed by them). */
|
|
@@ -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
|
|
--
|
|
1.8.3.1
|
|
|