diff options
author | Stef Walter <stefw@gnome.org> | 2012-11-05 21:24:31 +0100 |
---|---|---|
committer | Stef Walter <stefw@gnome.org> | 2012-11-09 12:15:39 +0100 |
commit | 46e5c1ee631146bddd7f8309ffcc05c4aa8a757f (patch) | |
tree | d7a35762ff4e3d1d8be19205c441be345f27e133 /egg | |
parent | f7d5a800efa856a27ca16378d6bbe9fcb42e501a (diff) | |
download | gnome-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.c | 8 | ||||
-rw-r--r-- | egg/tests/test-asn1.c | 47 |
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); |