[gnome-keyring/trust-store] [egg] Add accessor functions for enumerated ASN.1 values.



commit 72df6d30ed29ad0adebcd60845fdf11ca276315f
Author: Stef Walter <stef memberwebs com>
Date:   Mon Sep 20 02:02:21 2010 +0000

    [egg] Add accessor functions for enumerated ASN.1 values.
    
    Add getter and setter for ENUMERATED ASN.1 values, and DER
    encoder.

 egg/egg-asn1x.c       |   99 +++++++++++++++++++++++++++++++++++++++++++++----
 egg/egg-asn1x.h       |    5 ++
 egg/tests/test-asn1.c |   33 ++++++++++++++++
 egg/tests/test.asn    |    7 +++
 4 files changed, 136 insertions(+), 8 deletions(-)
---
diff --git a/egg/egg-asn1x.c b/egg/egg-asn1x.c
index a669b8b..9d82b94 100644
--- a/egg/egg-asn1x.c
+++ b/egg/egg-asn1x.c
@@ -310,6 +310,24 @@ anode_opt_lookup (GNode *node, gint type, const gchar *name)
 	return NULL;
 }
 
+static ASN1_ARRAY_TYPE*
+anode_opt_lookup_value (GNode *node, gint type, const gchar *value)
+{
+	Anode *an = node->data;
+	ASN1_ARRAY_TYPE* def;
+	GList *l;
+
+	for (l = an->opts; l; l = g_list_next (l)) {
+		def = l->data;
+		if (value && def->value && !g_str_equal (value, def->value))
+			continue;
+		if ((def->type & 0xFF) == type)
+			return def;
+	}
+
+	return NULL;
+}
+
 static GList*
 anode_opts_lookup (GNode *node, gint type, const gchar *name)
 {
@@ -2367,6 +2385,76 @@ egg_asn1x_set_boolean (GNode *node, gboolean value)
 	return TRUE;
 }
 
+GQuark
+egg_asn1x_get_enumerated (GNode *node)
+{
+	gchar buf[sizeof (gulong) * 3];
+	ASN1_ARRAY_TYPE *opt;
+	gulong val;
+	Atlv *tlv;
+
+	g_return_val_if_fail (node, 0);
+	g_return_val_if_fail (anode_def_type (node) == TYPE_ENUMERATED, 0);
+
+	tlv = anode_get_tlv_data (node);
+
+	/* TODO: Defaults */
+
+	if (tlv == NULL || tlv->buf == NULL)
+		return 0;
+
+	/* TODO: Signed values */
+
+	if (!anode_read_integer_as_ulong (node, tlv, &val))
+		return 0;
+
+	/* Format that as a string */
+	if (g_snprintf (buf, sizeof (buf), "%lu", val) < 0)
+		g_return_val_if_reached (0);
+
+	/* Lookup that value in our table */
+	opt = anode_opt_lookup_value (node, TYPE_CONSTANT, buf);
+	if (opt == NULL || opt->name == NULL)
+		return 0;
+
+	return g_quark_from_static_string (opt->name);
+}
+
+gboolean
+egg_asn1x_set_enumerated (GNode *node, GQuark value)
+{
+	ASN1_ARRAY_TYPE *opt;
+	const gchar *name;
+	gpointer data;
+	gsize n_data;
+	gulong val;
+
+	g_return_val_if_fail (node, FALSE);
+	g_return_val_if_fail (value, FALSE);
+	g_return_val_if_fail (anode_def_type (node) == TYPE_ENUMERATED, FALSE);
+
+	/* TODO: Handle default values */
+
+	name = g_quark_to_string (value);
+	g_return_val_if_fail (name, FALSE);
+
+	opt = anode_opt_lookup (node, TYPE_CONSTANT, name);
+	g_return_val_if_fail (opt && opt->value, FALSE);
+
+	/* TODO: Signed values */
+
+	val = anode_def_value_as_ulong (opt);
+	g_return_val_if_fail (val != G_MAXULONG, FALSE);
+
+	n_data = sizeof (gulong);
+	data = g_malloc0 (n_data);
+	if (!anode_write_integer_ulong (val, data, &n_data))
+		return FALSE;
+
+	anode_encode_tlv_and_enc (node, n_data, anode_encoder_simple, data, g_free);
+	return TRUE;
+}
+
 gboolean
 egg_asn1x_get_integer_as_ulong (GNode *node, gulong *value)
 {
@@ -2403,12 +2491,7 @@ egg_asn1x_get_integer_as_ulong (GNode *node, gulong *value)
 		return TRUE;
 	}
 
-	if (tlv == NULL || tlv->buf == NULL)
-		return FALSE;
-
-	/* TODO: Default integer values */
-
-	return anode_read_integer_as_ulong(node, tlv, value);
+	return anode_read_integer_as_ulong (node, tlv, value);
 }
 
 gboolean
@@ -2422,8 +2505,8 @@ egg_asn1x_set_integer_as_ulong (GNode *node, gulong value)
 
 	/* TODO: Handle default values */
 
-	n_data = 8;
-	data = g_malloc0 (8);
+	n_data = sizeof (gulong);
+	data = g_malloc0 (n_data);
 	if (!anode_write_integer_ulong (value, data, &n_data))
 		return FALSE;
 	anode_encode_tlv_and_enc (node, n_data, anode_encoder_simple, data, g_free);
diff --git a/egg/egg-asn1x.h b/egg/egg-asn1x.h
index 2bff216..197826a 100644
--- a/egg/egg-asn1x.h
+++ b/egg/egg-asn1x.h
@@ -81,6 +81,11 @@ gboolean            egg_asn1x_get_boolean            (GNode *node,
 gboolean            egg_asn1x_set_boolean            (GNode *node,
                                                       gboolean value);
 
+GQuark              egg_asn1x_get_enumerated         (GNode *node);
+
+gboolean            egg_asn1x_set_enumerated         (GNode *node,
+                                                      GQuark value);
+
 gboolean            egg_asn1x_get_integer_as_ulong   (GNode *node,
                                                       gulong *value);
 
diff --git a/egg/tests/test-asn1.c b/egg/tests/test-asn1.c
index 809ba93..6e9d77d 100644
--- a/egg/tests/test-asn1.c
+++ b/egg/tests/test-asn1.c
@@ -47,6 +47,12 @@ const gchar BITS_TEST[] =  "\x03\x04\x06\x6e\x5d\xc0";
 const gchar BITS_BAD[] =  "\x03\x04\x06\x6e\x5d\xc1";
 const gchar BITS_ZERO[] =  "\x03\x01\x00";
 
+/* ENUM with value = 2 */
+const gchar ENUM_TWO[] =           "\x0A\x01\x02";
+
+/* ENUM with value = 3 */
+const gchar ENUM_THREE[] =           "\x0A\x01\x03";
+
 /* SEQUENCE OF with one INTEGER = 1 */
 const gchar SEQOF_ONE[] =  "\x30\x03\x02\x01\x01";
 
@@ -448,3 +454,30 @@ DEFINE_TEST(asn1_append)
 	g_free (data);
 	egg_asn1x_destroy (asn);
 }
+
+DEFINE_TEST (asn1_enumerated)
+{
+	GNode *asn;
+	gpointer data;
+	gsize n_data;
+	GQuark value;
+
+	asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestEnumerated", ENUM_TWO, XL (ENUM_TWO));
+	g_assert (asn);
+
+	value = egg_asn1x_get_enumerated (asn);
+	g_assert (value);
+	g_assert_cmpstr (g_quark_to_string (value), ==, "valueTwo");
+
+	if (!egg_asn1x_set_enumerated (asn, g_quark_from_static_string ("valueThree")))
+		g_assert_not_reached ();
+
+	data = egg_asn1x_encode (asn, NULL, &n_data);
+	g_assert (data);
+
+	g_assert (n_data == XL (ENUM_THREE));
+	g_assert (memcmp (data, ENUM_THREE, n_data) == 0);
+
+	g_free (data);
+	egg_asn1x_destroy (asn);
+}
diff --git a/egg/tests/test.asn b/egg/tests/test.asn
index d55dba8..3c7c342 100644
--- a/egg/tests/test.asn
+++ b/egg/tests/test.asn
@@ -42,4 +42,11 @@ TestAnySeq ::= SEQUENCE {
 
 TestSeqOf ::= SEQUENCE OF INTEGER
 
+TestEnumerated ::= ENUMERATED {
+	valueZero         (0),
+	valueOne          (1),
+	valueTwo          (2),
+	valueThree        (3)
+}
+
 END



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]