summaryrefslogtreecommitdiff
path: root/egg
diff options
context:
space:
mode:
authorStef Walter <stefw@collabora.co.uk>2011-11-17 10:51:53 +0100
committerStef Walter <stefw@collabora.co.uk>2011-11-23 09:10:51 +0100
commitb9ce2ad2d7a24aba078238ba0e2f38726a5627c1 (patch)
treefb1131fadc4f6098bbc6c6bc0bd070f0de090974 /egg
parentef4773b8f4b00ca9b4c2fa4e73e2c6523d1f7389 (diff)
egg: Add support for building simple DNs
Diffstat (limited to 'egg')
-rw-r--r--egg/egg-dn.c85
-rw-r--r--egg/egg-dn.h4
-rw-r--r--egg/tests/test-dn.c39
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 ();
}