summaryrefslogtreecommitdiff
path: root/egg
diff options
context:
space:
mode:
authorStef Walter <stefw@gnome.org>2012-11-05 21:24:31 +0100
committerStef Walter <stefw@gnome.org>2012-11-09 12:15:39 +0100
commit46e5c1ee631146bddd7f8309ffcc05c4aa8a757f (patch)
treed7a35762ff4e3d1d8be19205c441be345f27e133 /egg
parentf7d5a800efa856a27ca16378d6bbe9fcb42e501a (diff)
downloadgnome-keyring-46e5c1ee631146bddd7f8309ffcc05c4aa8a757f.tar.gz
egg-asn1x: Fix crash when parsing invalid DER files
* When parsing invalid DER files and more than one sub-TLV is encountered we would do a NULL dereference. * Catch this condition and test for it.
Diffstat (limited to 'egg')
-rw-r--r--egg/egg-asn1x.c8
-rw-r--r--egg/tests/test-asn1.c47
2 files changed, 55 insertions, 0 deletions
diff --git a/egg/egg-asn1x.c b/egg/egg-asn1x.c
index 6a1f3791..105540f6 100644
--- a/egg/egg-asn1x.c
+++ b/egg/egg-asn1x.c
@@ -1181,11 +1181,17 @@ static gboolean
anode_decode_anything (GNode *node,
Atlv *tlv)
{
+ GNode *prev = NULL;
GNode *next;
gulong tag;
gint flags;
+ g_assert (node != NULL);
+
while (tlv != NULL) {
+ if (node == NULL)
+ return anode_failure (prev, "encountered extra tag");
+
flags = anode_def_flags (node);
tag = anode_calc_tag_for_flags (node, flags);
@@ -1205,6 +1211,7 @@ anode_decode_anything (GNode *node,
if (next == NULL)
return anode_failure (node, "decoded tag did not match expected");
+ prev = node;
node = next;
continue;
}
@@ -1213,6 +1220,7 @@ anode_decode_anything (GNode *node,
return FALSE;
/* Next node and tag */
+ prev = node;
node = g_node_next_sibling (node);
tlv = tlv->next;
}
diff --git a/egg/tests/test-asn1.c b/egg/tests/test-asn1.c
index 13130994..09645d6d 100644
--- a/egg/tests/test-asn1.c
+++ b/egg/tests/test-asn1.c
@@ -1331,6 +1331,51 @@ test_count (Test* test, gconstpointer unused)
g_assert_cmpuint (egg_asn1x_count (node), ==, 7);
}
+static void
+test_nested_fails_with_extra (void)
+{
+ gboolean ret;
+ GBytes *bytes;
+ GNode *asn;
+
+ const gchar SEQ_NESTED[] = "\x30\x0C"
+ "\x04\x03""one"
+ "\x04\x05""extra";
+
+ asn = egg_asn1x_create (test_asn1_tab, "TestData");
+ g_assert ("asn test structure is null" && asn != NULL);
+
+ bytes = g_bytes_new_static (SEQ_NESTED, XL (SEQ_NESTED));
+ ret = egg_asn1x_decode (asn, bytes);
+ egg_asn1x_assert (ret == FALSE, asn);
+ egg_asn1x_assert (strstr (egg_asn1x_message (asn), "encountered extra tag"), asn);
+ g_bytes_unref (bytes);
+
+ egg_asn1x_destroy (asn);
+}
+
+static void
+test_nested_unexpected (void)
+{
+ gboolean ret;
+ GBytes *bytes;
+ GNode *asn;
+
+ const gchar SEQ_NESTED[] = "\x30\x03"
+ "\x02\x01\x2A";
+
+ asn = egg_asn1x_create (test_asn1_tab, "TestData");
+ g_assert ("asn test structure is null" && asn != NULL);
+
+ bytes = g_bytes_new_static (SEQ_NESTED, XL (SEQ_NESTED));
+ ret = egg_asn1x_decode (asn, bytes);
+ egg_asn1x_assert (ret == FALSE, asn);
+ egg_asn1x_assert (strstr (egg_asn1x_message (asn), "decoded tag did not match expected"), asn);
+ g_bytes_unref (bytes);
+
+ egg_asn1x_destroy (asn);
+}
+
int
main (int argc, char **argv)
{
@@ -1365,6 +1410,8 @@ main (int argc, char **argv)
g_test_add_func ("/asn1/setof", test_setof);
g_test_add_func ("/asn1/setof_empty", test_setof_empty);
g_test_add_func ("/asn1/enumerated", test_enumerated);
+ g_test_add_func ("/asn1/nested-fails-with-extra", test_nested_fails_with_extra);
+ g_test_add_func ("/asn1/nested-unexpected", test_nested_unexpected);
g_test_add ("/asn1/node_name", Test, NULL, setup, test_node_name, teardown);
g_test_add ("/asn1/asn1_integers", Test, NULL, setup, test_asn1_integers, teardown);
g_test_add ("/asn1/boolean_seq", Test, NULL, setup, test_boolean_seq, teardown);