[gcr] egg: Add support for building simple DNs



commit b9ce2ad2d7a24aba078238ba0e2f38726a5627c1
Author: Stef Walter <stefw collabora co uk>
Date:   Thu Nov 17 10:51:53 2011 +0100

    egg: Add support for building simple DNs

 egg/egg-dn.c        |   85 +++++++++++++++++++++++++++++++++++++++++++++++++++
 egg/egg-dn.h        |    4 ++
 egg/tests/test-dn.c |   39 +++++++++++++++++++++++
 3 files changed, 128 insertions(+), 0 deletions(-)
---
diff --git a/egg/egg-dn.c b/egg/egg-dn.c
index 234ae16..2ec5751 100644
--- a/egg/egg-dn.c
+++ b/egg/egg-dn.c
@@ -301,3 +301,88 @@ egg_dn_print_value (GQuark oid,
 
 	return dn_print_oid_value (oid, egg_oid_get_flags (oid), value);
 }
+
+static gboolean
+is_ascii_string (const gchar *string)
+{
+	const gchar *p = string;
+
+	g_return_val_if_fail (string != NULL, FALSE);
+
+	for (p = string; *p != '\0'; p++) {
+		if (!g_ascii_isspace (*p) && *p < ' ')
+			return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean
+is_printable_string (const gchar *string)
+{
+	const gchar *p = string;
+
+	g_return_val_if_fail (string != NULL, FALSE);
+
+	for (p = string; *p != '\0'; p++) {
+		if (!g_ascii_isalnum (*p) && !strchr (" '()+,-./:=?", *p))
+			return FALSE;
+	}
+
+	return TRUE;
+}
+
+void
+egg_dn_add_string_part (GNode *asn,
+                        GQuark oid,
+                        const gchar *string)
+{
+	EggBytes *bytes;
+	GNode *node;
+	GNode *value;
+	GNode *val;
+	guint flags;
+
+	g_return_if_fail (asn != NULL);
+	g_return_if_fail (oid != 0);
+	g_return_if_fail (string != NULL);
+
+	flags = egg_oid_get_flags (oid);
+	g_return_if_fail (flags & EGG_OID_PRINTABLE);
+
+	/* Add the RelativeDistinguishedName */
+	node = egg_asn1x_append (asn);
+
+	/* Add the AttributeTypeAndValue */
+	node = egg_asn1x_append (node);
+
+	egg_asn1x_set_oid_as_quark (egg_asn1x_node (node, "type", NULL), oid);
+
+	value = egg_asn1x_create_quark (pkix_asn1_tab, oid);
+
+	if (egg_asn1x_type (value) == EGG_ASN1X_CHOICE) {
+		if (is_printable_string (string))
+			val = egg_asn1x_node (value, "printableString", NULL);
+		else if (is_ascii_string (string))
+			val = egg_asn1x_node (value, "ia5String", NULL);
+		else
+			val = egg_asn1x_node (value, "utf8String", NULL);
+		egg_asn1x_set_choice (value, val);
+	} else {
+		val = value;
+	}
+
+	egg_asn1x_set_string_as_utf8 (val, g_strdup (string), g_free);
+
+	bytes = egg_asn1x_encode (value, NULL);
+	if (bytes == NULL) {
+		g_warning ("couldn't build dn string value: %s", egg_asn1x_message (value));
+		return;
+	}
+
+	if (!egg_asn1x_set_element_raw (egg_asn1x_node (node, "value", NULL), bytes))
+		g_return_if_reached ();
+
+	egg_asn1x_destroy (value);
+	egg_bytes_unref (bytes);
+}
diff --git a/egg/egg-dn.h b/egg/egg-dn.h
index 5d36d7e..08251ec 100644
--- a/egg/egg-dn.h
+++ b/egg/egg-dn.h
@@ -45,4 +45,8 @@ gboolean           egg_dn_parse                           (GNode *node,
 gchar*             egg_dn_print_value                     (GQuark oid,
                                                            EggBytes *value);
 
+void               egg_dn_add_string_part                 (GNode *node,
+                                                           GQuark oid,
+                                                           const gchar *string);
+
 #endif /* EGG_DN_H_ */
diff --git a/egg/tests/test-dn.c b/egg/tests/test-dn.c
index 530d342..929cec2 100644
--- a/egg/tests/test-dn.c
+++ b/egg/tests/test-dn.c
@@ -27,6 +27,7 @@
 #include "egg/egg-asn1x.h"
 #include "egg/egg-dn.h"
 #include "egg/egg-oid.h"
+#include "egg/egg-testing.h"
 
 #include <glib.h>
 #include <gcrypt.h>
@@ -175,6 +176,43 @@ test_read_dn_part (Test* test, gconstpointer unused)
 	g_assert (value == NULL);
 }
 
+static void
+test_add_dn_part (Test *test,
+                  gconstpointer unused)
+{
+	EggBytes *check;
+	EggBytes *dn;
+	GNode *check_dn;
+	GNode *asn;
+	GNode *node;
+
+	asn = egg_asn1x_create (pkix_asn1_tab, "Name");
+	node = egg_asn1x_node (asn, "rdnSequence", NULL);
+	egg_asn1x_set_choice (asn, node);
+	egg_dn_add_string_part (node, g_quark_from_static_string ("2.5.4.6"), "ZA");
+	egg_dn_add_string_part (node, g_quark_from_static_string ("2.5.4.8"), "Western Cape");
+	egg_dn_add_string_part (node, g_quark_from_static_string ("2.5.4.7"), "Cape Town");
+	egg_dn_add_string_part (node, g_quark_from_static_string ("2.5.4.10"), "Thawte Consulting");
+	egg_dn_add_string_part (node, g_quark_from_static_string ("2.5.4.11"), "Certification Services Division");
+	egg_dn_add_string_part (node, g_quark_from_static_string ("2.5.4.3"), "Thawte Personal Premium CA");
+	egg_dn_add_string_part (node, g_quark_from_static_string ("1.2.840.113549.1.9.1"), "personal-premium thawte com");
+
+	dn = egg_asn1x_encode (asn, NULL);
+	if (dn == NULL) {
+		g_warning ("couldn't encode dn: %s", egg_asn1x_message (asn));
+		g_assert_not_reached ();
+	}
+
+	check_dn = egg_asn1x_node (test->asn1, "tbsCertificate", "issuer", "rdnSequence", NULL);
+	check = egg_asn1x_encode (check_dn, NULL);
+	egg_asn1x_destroy (asn);
+
+	egg_assert_cmpbytes (dn, ==, egg_bytes_get_data (check), egg_bytes_get_size (check));
+
+	egg_bytes_unref (dn);
+	egg_bytes_unref (check);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -184,6 +222,7 @@ main (int argc, char **argv)
 	g_test_add ("/dn/dn_value", Test, NULL, setup, test_dn_value, teardown);
 	g_test_add ("/dn/parse_dn", Test, NULL, setup, test_parse_dn, teardown);
 	g_test_add ("/dn/read_dn_part", Test, NULL, setup, test_read_dn_part, teardown);
+	g_test_add ("/dn/add_dn_part", Test, NULL, setup, test_add_dn_part, teardown);
 
 	return g_test_run ();
 }



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