diff options
author | Stef Walter <stefw@collabora.co.uk> | 2011-11-17 10:51:53 +0100 |
---|---|---|
committer | Stef Walter <stefw@collabora.co.uk> | 2011-11-23 09:10:51 +0100 |
commit | b9ce2ad2d7a24aba078238ba0e2f38726a5627c1 (patch) | |
tree | fb1131fadc4f6098bbc6c6bc0bd070f0de090974 /egg | |
parent | ef4773b8f4b00ca9b4c2fa4e73e2c6523d1f7389 (diff) |
egg: Add support for building simple DNs
Diffstat (limited to 'egg')
-rw-r--r-- | egg/egg-dn.c | 85 | ||||
-rw-r--r-- | egg/egg-dn.h | 4 | ||||
-rw-r--r-- | 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 (); } |