[gnome-keyring/asn1-work: 17/18] [egg] Move the DN functionality into its own file.



commit f0033332d99e797ee3b5a1b2a1f1b155d73124d4
Author: Stef Walter <stef memberwebs com>
Date:   Wed Dec 30 23:45:08 2009 +0000

    [egg] Move the DN functionality into its own file.

 egg/Makefile.am                      |    1 +
 egg/egg-asn1.c                       |  297 ------------------------------
 egg/egg-asn1.h                       |   14 --
 egg/egg-asn1x.c                      |    2 +-
 egg/egg-dn.c                         |  336 ++++++++++++++++++++++++++++++++++
 egg/egg-dn.h                         |   43 +++++
 egg/tests/Makefile.am                |    1 +
 egg/tests/test-dn.c                  |  167 +++++++++++++++++
 egg/tests/unit-test-asn1.c           |  100 ----------
 gcr/gcr-certificate-details-widget.c |    7 +-
 gcr/gcr-certificate.c                |    9 +-
 gcr/gcr-parser.c                     |    3 +-
 pkcs11/gkm/gkm-certificate.c         |    6 +-
 pkcs11/user-store/gkm-user-storage.c |    3 +-
 14 files changed, 566 insertions(+), 423 deletions(-)
---
diff --git a/egg/Makefile.am b/egg/Makefile.am
index 0fc9654..5cb86d6 100644
--- a/egg/Makefile.am
+++ b/egg/Makefile.am
@@ -25,6 +25,7 @@ libegg_la_SOURCES = \
 	egg-buffer.c egg-buffer.h \
 	egg-cleanup.c egg-cleanup.h \
 	egg-dh.c egg-dh.h \
+	egg-dn.c egg-dn.h \
 	egg-error.h \
 	egg-hex.c egg-hex.h \
 	egg-libgcrypt.c egg-libgcrypt.h \
diff --git a/egg/egg-asn1.c b/egg/egg-asn1.c
index 3ba0bc8..641a366 100644
--- a/egg/egg-asn1.c
+++ b/egg/egg-asn1.c
@@ -815,300 +815,3 @@ egg_asn1_read_date (ASN1_TYPE asn, const gchar *part, GDate *date)
 	g_date_set_dmy (date, when.tm_mday, when.tm_mon + 1, when.tm_year + 1900);
 	return g_date_valid (date);
 }
-
-/* -------------------------------------------------------------------------------
- * Reading DN's
- */
-
-static const char HEXC[] = "0123456789ABCDEF";
-
-static gchar*
-dn_print_hex_value (const guchar *data, gsize len)
-{
-	GString *result = g_string_sized_new (len * 2 + 1);
-	gsize i;
-	
-	g_string_append_c (result, '#');
-	for (i = 0; i < len; ++i) {
-		g_string_append_c (result, HEXC[data[i] >> 4 & 0xf]);
-		g_string_append_c (result, HEXC[data[i] & 0xf]);
-	}
-	
-	return g_string_free (result, FALSE);
-}
-
-static gchar* 
-dn_print_oid_value_parsed (GQuark oid, guint flags, const guchar *data, gsize len)
-{
-	const gchar *asn_name;
-	ASN1_TYPE asn1;
-	gchar *part;
-	gchar *value;
-	gsize n_value;
-	
-	g_assert (data);
-	g_assert (len);
-	
-	asn_name = asn1_find_structure_from_oid (egg_asn1_get_pkix_asn1type (), 
-	                                         g_quark_to_string (oid));
-	g_return_val_if_fail (asn_name, NULL);
-	
-	part = g_strdup_printf ("PKIX1.%s", asn_name);
-	asn1 = egg_asn1_decode (part, data, len);
-	g_free (part);
-	
-	if (!asn1) {
-		g_message ("couldn't decode value for OID: %s", g_quark_to_string (oid));
-		return NULL;
-	}
-
-	value = (gchar*)egg_asn1_read_value (asn1, "", &n_value, NULL);
-	
-	/*
-	 * If it's a choice element, then we have to read depending
-	 * on what's there.
-	 */
-	if (value && (flags & EGG_OID_IS_CHOICE)) {
-		if (ascii_length_equals ("printableString", value, n_value - 1) ||
-			ascii_length_equals ("ia5String", value, n_value - 1 ) ||
-			ascii_length_equals ("utf8String", value, n_value - 1) ||
-			ascii_length_equals ("teletexString", value, n_value - 1)) {
-			part = value;
-			value = (gchar*)egg_asn1_read_value (asn1, part, &n_value, NULL);
-			g_free (part);
-		} else {
-			g_free (value);
-			return NULL;
-		}
-	}
-
-	if (!value) {
-		g_message ("couldn't read value for OID: %s", g_quark_to_string (oid));
-		return NULL;
-	}
-
-	/* 
-	 * Now we make sure it's UTF-8. 
-	 */
-	if (!g_utf8_validate (value, n_value, NULL)) {
-		gchar *hex = dn_print_hex_value ((guchar*)value, n_value);
-		g_free (value);
-		value = hex;
-	}
-	
-	return value;
-}
-
-static gchar*
-dn_print_oid_value (GQuark oid, guint flags, const guchar *data, gsize len)
-{
-	gchar *value;
-	
-	g_assert (data);
-	g_assert (len);
-	
-	if (flags & EGG_OID_PRINTABLE) {
-		value = dn_print_oid_value_parsed (oid, flags, data, len);
-		if (value != NULL)
-			return value;
-	}
-	
-	return dn_print_hex_value (data, len);
-}
-
-static gchar* 
-dn_parse_rdn (ASN1_TYPE asn, const gchar *part)
-{
-	const gchar *name;
-	guint flags;
-	GQuark oid;
-	gchar *path;
-	guchar *value;
-	gsize n_value;
-	gchar *display;
-	gchar *result;
-	
-	g_assert (asn);
-	g_assert (part);
-	
-	path = g_strdup_printf ("%s.type", part);
-	oid = egg_asn1_read_oid (asn, path);
-	g_free (path);
-
-	if (!oid)
-		return NULL;
-	
-	path = g_strdup_printf ("%s.value", part);
-	value = egg_asn1_read_value (asn, path, &n_value, NULL);
-	g_free (path);
-
-	flags = egg_oid_get_flags (oid);
-	name = egg_oid_get_name (oid);
-	
-	g_return_val_if_fail (value, NULL);
-	display = dn_print_oid_value (oid, flags, value, n_value);
-	
-	result = g_strconcat ((flags & EGG_OID_PRINTABLE) ? name : g_quark_to_string (oid), 
-			      "=", display, NULL);
-	g_free (display);
-	
-	return result;
-}
-
-gchar*
-egg_asn1_read_dn (ASN1_TYPE asn, const gchar *part)
-{
-	gboolean done = FALSE;
-	GString *result;
-	gchar *path;
-	gchar *rdn;
-	gint i, j;
-	
-	g_return_val_if_fail (asn, NULL);
-	g_return_val_if_fail (part, NULL);
-	
-	result = g_string_sized_new (64);
-	
-	/* Each (possibly multi valued) RDN */
-	for (i = 1; !done; ++i) {
-		
-		/* Each type=value pair of an RDN */
-		for (j = 1; TRUE; ++j) {
-			path = g_strdup_printf ("%s%s?%u.?%u", part ? part : "", 
-			                        part ? "." : "", i, j);
-			rdn = dn_parse_rdn (asn, path);
-			g_free (path);
-
-			if (!rdn) {
-				done = j == 1;
-				break;
-			}
-			
-			/* Account for multi valued RDNs */
-			if (j > 1)
-				g_string_append (result, "+");
-			else if (i > 1)
-				g_string_append (result, ", ");
-			
-			g_string_append (result, rdn);
-			g_free (rdn);
-		}
-	}
-
-	/* Returns null when string is empty */
-	return g_string_free (result, (result->len == 0));
-}
-
-gchar*
-egg_asn1_read_dn_part (ASN1_TYPE asn, const gchar *part, const gchar *match)
-{
-	gboolean done = FALSE;
-	const gchar *name;
-	guchar *value;
-	gsize n_value;
-	gchar *path;
-	GQuark oid;
-	gint i, j;
-	
-	g_return_val_if_fail (asn, NULL);
-	g_return_val_if_fail (part, NULL);
-	g_return_val_if_fail (match, NULL);
-	
-	/* Each (possibly multi valued) RDN */
-	for (i = 1; !done; ++i) {
-		
-		/* Each type=value pair of an RDN */
-		for (j = 1; TRUE; ++j) {
-			path = g_strdup_printf ("%s%s?%u.?%u.type", 
-			                        part ? part : "", 
-			                        part ? "." : "", i, j);
-			oid = egg_asn1_read_oid (asn, path);
-			g_free (path);
-
-			if (!oid) {
-				done = j == 1;
-				break;
-			}
-			
-			/* Does it match either the OID or the displayable? */
-			if (g_ascii_strcasecmp (g_quark_to_string (oid), match) != 0) {
-				name = egg_oid_get_name (oid);
-				if (!g_ascii_strcasecmp (name, match) == 0)
-					continue;
-			}
-
-			path = g_strdup_printf ("%s%s?%u.?%u.value", 
-			                        part ? part : "", 
-			                        part ? "." : "", i, j);
-			value = egg_asn1_read_value (asn, path, &n_value, NULL);
-			g_free (path);
-			
-			g_return_val_if_fail (value, NULL);
-			return dn_print_oid_value (oid, egg_oid_get_flags (oid), value, n_value);
-		}
-	}
-	
-	return NULL;
-}
-
-gboolean
-egg_asn1_dn_parse (ASN1_TYPE asn, const gchar *part, 
-                   EggAsn1DnCallback callback, gpointer user_data)
-{
-	gboolean done = FALSE;
-	gchar *path;
-	guchar *value;
-	gsize n_value;
-	GQuark oid;
-	guint i, j;
-	
-	g_return_val_if_fail (asn, FALSE);
-	
-	/* Each (possibly multi valued) RDN */
-	for (i = 1; !done; ++i) {
-		
-		/* Each type=value pair of an RDN */
-		for (j = 1; TRUE; ++j) {
-			
-			/* Dig out the type */
-			path = g_strdup_printf ("%s%s?%u.?%u.type", 
-			                        part ? part : "", 
-			                        part ? "." : "", i, j);
-			oid = egg_asn1_read_oid (asn, path);
-			g_free (path);
-
-			if (!oid) {
-				done = j == 1;
-				break;
-			}
-
-			/* Print the value as nicely as we can */
-			path = g_strdup_printf ("%s%s?%u.?%u.value", 
-			                        part ? part : "", 
-			                        part ? "." : "", i, j);
-			value = egg_asn1_read_value (asn, path, &n_value, NULL);
-			g_free (path);
-
-			if (!value) {
-				done = j == 1;
-				break;
-			}
-			
-			if (callback) 
-				(callback) (i, oid, value, n_value, user_data);
-			
-			g_free (value);
-		}
-	}
-	
-	return i > 1;
-}
-
-gchar*
-egg_asn1_dn_print_value (GQuark oid, const guchar *value, gsize n_value)
-{
-	g_return_val_if_fail (oid, NULL);
-	g_return_val_if_fail (value || !n_value, NULL);
-	
-	return dn_print_oid_value (oid, egg_oid_get_flags (oid), value, n_value);
-}
diff --git a/egg/egg-asn1.h b/egg/egg-asn1.h
index 8d1aff8..c62afde 100644
--- a/egg/egg-asn1.h
+++ b/egg/egg-asn1.h
@@ -73,22 +73,8 @@ gint               egg_asn1_element_length                (const guchar *data, g
 
 const guchar*      egg_asn1_element_content               (const guchar *data, gsize n_data, gsize *n_content);
 
-gchar*             egg_asn1_read_dn                       (ASN1_TYPE asn, const gchar *part);
-
-gchar*             egg_asn1_read_dn_part                  (ASN1_TYPE asn, const gchar *part, const gchar *match);
-
-
 glong              egg_asn1_time_parse_utc                (const gchar* value, gssize n_value);
 
 glong              egg_asn1_time_parse_general            (const gchar* value, gssize n_value);
 
-
-typedef void       (*EggAsn1DnCallback)                   (guint index, GQuark oid, const guchar *value,
-                                                           gsize n_value, gpointer user_data);
-
-gboolean           egg_asn1_dn_parse                      (ASN1_TYPE asn, const gchar *part, 
-                                                           EggAsn1DnCallback callback, gpointer user_data);
-
-gchar*             egg_asn1_dn_print_value                (GQuark oid, const guchar *value, gsize n_value);
-
 #endif /*EGG_ASN1_H_*/
diff --git a/egg/egg-asn1x.c b/egg/egg-asn1x.c
index 46f7da8..b1ecc59 100644
--- a/egg/egg-asn1x.c
+++ b/egg/egg-asn1x.c
@@ -1683,7 +1683,7 @@ anode_read_time (GNode *node, Atlv *tlv, glong *value)
 	const gchar *data;
 	gboolean ret;
 	struct tm when;
-	gint offset;
+	gint offset = 0;
 	gint flags;
 
 	flags = anode_def_flags (node);
diff --git a/egg/egg-dn.c b/egg/egg-dn.c
new file mode 100644
index 0000000..199cb6a
--- /dev/null
+++ b/egg/egg-dn.c
@@ -0,0 +1,336 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* egg-asn1.c - ASN.1 helper routines
+
+   Copyright (C) 2007 Stefan Walter
+
+   The Gnome Keyring Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Keyring Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Stef Walter <stef memberwebs com>
+*/
+
+#include "config.h"
+
+#include "egg-asn1.h"
+#include "egg-dn.h"
+#include "egg-oid.h"
+
+#include <libtasn1.h>
+
+#include <string.h>
+
+static const char HEXC[] = "0123456789ABCDEF";
+
+static gboolean
+ascii_length_equals (const gchar *str, gconstpointer data, gsize n_data)
+{
+	g_assert (str);
+	if (!data)
+		return FALSE;
+	if (strlen (str) != n_data)
+		return FALSE;
+	return strncmp (str, data, n_data) == 0;
+}
+
+static gchar*
+dn_print_hex_value (const guchar *data, gsize len)
+{
+	GString *result = g_string_sized_new (len * 2 + 1);
+	gsize i;
+
+	g_string_append_c (result, '#');
+	for (i = 0; i < len; ++i) {
+		g_string_append_c (result, HEXC[data[i] >> 4 & 0xf]);
+		g_string_append_c (result, HEXC[data[i] & 0xf]);
+	}
+
+	return g_string_free (result, FALSE);
+}
+
+static gchar*
+dn_print_oid_value_parsed (GQuark oid, guint flags, const guchar *data, gsize len)
+{
+	const gchar *asn_name;
+	ASN1_TYPE asn1;
+	gchar *part;
+	gchar *value;
+	gsize n_value;
+
+	g_assert (data);
+	g_assert (len);
+
+	asn_name = asn1_find_structure_from_oid (egg_asn1_get_pkix_asn1type (),
+	                                         g_quark_to_string (oid));
+	g_return_val_if_fail (asn_name, NULL);
+
+	part = g_strdup_printf ("PKIX1.%s", asn_name);
+	asn1 = egg_asn1_decode (part, data, len);
+	g_free (part);
+
+	if (!asn1) {
+		g_message ("couldn't decode value for OID: %s", g_quark_to_string (oid));
+		return NULL;
+	}
+
+	value = (gchar*)egg_asn1_read_value (asn1, "", &n_value, NULL);
+
+	/*
+	 * If it's a choice element, then we have to read depending
+	 * on what's there.
+	 */
+	if (value && (flags & EGG_OID_IS_CHOICE)) {
+		if (ascii_length_equals ("printableString", value, n_value - 1) ||
+			ascii_length_equals ("ia5String", value, n_value - 1 ) ||
+			ascii_length_equals ("utf8String", value, n_value - 1) ||
+			ascii_length_equals ("teletexString", value, n_value - 1)) {
+			part = value;
+			value = (gchar*)egg_asn1_read_value (asn1, part, &n_value, NULL);
+			g_free (part);
+		} else {
+			g_free (value);
+			return NULL;
+		}
+	}
+
+	if (!value) {
+		g_message ("couldn't read value for OID: %s", g_quark_to_string (oid));
+		return NULL;
+	}
+
+	/*
+	 * Now we make sure it's UTF-8.
+	 */
+	if (!g_utf8_validate (value, n_value, NULL)) {
+		gchar *hex = dn_print_hex_value ((guchar*)value, n_value);
+		g_free (value);
+		value = hex;
+	}
+
+	return value;
+}
+
+static gchar*
+dn_print_oid_value (GQuark oid, guint flags, const guchar *data, gsize len)
+{
+	gchar *value;
+
+	g_assert (data);
+	g_assert (len);
+
+	if (flags & EGG_OID_PRINTABLE) {
+		value = dn_print_oid_value_parsed (oid, flags, data, len);
+		if (value != NULL)
+			return value;
+	}
+
+	return dn_print_hex_value (data, len);
+}
+
+static gchar*
+dn_parse_rdn (ASN1_TYPE asn, const gchar *part)
+{
+	const gchar *name;
+	guint flags;
+	GQuark oid;
+	gchar *path;
+	guchar *value;
+	gsize n_value;
+	gchar *display;
+	gchar *result;
+
+	g_assert (asn);
+	g_assert (part);
+
+	path = g_strdup_printf ("%s.type", part);
+	oid = egg_asn1_read_oid (asn, path);
+	g_free (path);
+
+	if (!oid)
+		return NULL;
+
+	path = g_strdup_printf ("%s.value", part);
+	value = egg_asn1_read_value (asn, path, &n_value, NULL);
+	g_free (path);
+
+	flags = egg_oid_get_flags (oid);
+	name = egg_oid_get_name (oid);
+
+	g_return_val_if_fail (value, NULL);
+	display = dn_print_oid_value (oid, flags, value, n_value);
+
+	result = g_strconcat ((flags & EGG_OID_PRINTABLE) ? name : g_quark_to_string (oid),
+			      "=", display, NULL);
+	g_free (display);
+
+	return result;
+}
+
+gchar*
+egg_dn_read (ASN1_TYPE asn, const gchar *part)
+{
+	gboolean done = FALSE;
+	GString *result;
+	gchar *path;
+	gchar *rdn;
+	gint i, j;
+
+	g_return_val_if_fail (asn, NULL);
+	g_return_val_if_fail (part, NULL);
+
+	result = g_string_sized_new (64);
+
+	/* Each (possibly multi valued) RDN */
+	for (i = 1; !done; ++i) {
+
+		/* Each type=value pair of an RDN */
+		for (j = 1; TRUE; ++j) {
+			path = g_strdup_printf ("%s%s?%u.?%u", part ? part : "",
+			                        part ? "." : "", i, j);
+			rdn = dn_parse_rdn (asn, path);
+			g_free (path);
+
+			if (!rdn) {
+				done = j == 1;
+				break;
+			}
+
+			/* Account for multi valued RDNs */
+			if (j > 1)
+				g_string_append (result, "+");
+			else if (i > 1)
+				g_string_append (result, ", ");
+
+			g_string_append (result, rdn);
+			g_free (rdn);
+		}
+	}
+
+	/* Returns null when string is empty */
+	return g_string_free (result, (result->len == 0));
+}
+
+gchar*
+egg_dn_read_part (ASN1_TYPE asn, const gchar *part, const gchar *match)
+{
+	gboolean done = FALSE;
+	const gchar *name;
+	guchar *value;
+	gsize n_value;
+	gchar *path;
+	GQuark oid;
+	gint i, j;
+
+	g_return_val_if_fail (asn, NULL);
+	g_return_val_if_fail (part, NULL);
+	g_return_val_if_fail (match, NULL);
+
+	/* Each (possibly multi valued) RDN */
+	for (i = 1; !done; ++i) {
+
+		/* Each type=value pair of an RDN */
+		for (j = 1; TRUE; ++j) {
+			path = g_strdup_printf ("%s%s?%u.?%u.type",
+			                        part ? part : "",
+			                        part ? "." : "", i, j);
+			oid = egg_asn1_read_oid (asn, path);
+			g_free (path);
+
+			if (!oid) {
+				done = j == 1;
+				break;
+			}
+
+			/* Does it match either the OID or the displayable? */
+			if (g_ascii_strcasecmp (g_quark_to_string (oid), match) != 0) {
+				name = egg_oid_get_name (oid);
+				if (!g_ascii_strcasecmp (name, match) == 0)
+					continue;
+			}
+
+			path = g_strdup_printf ("%s%s?%u.?%u.value",
+			                        part ? part : "",
+			                        part ? "." : "", i, j);
+			value = egg_asn1_read_value (asn, path, &n_value, NULL);
+			g_free (path);
+
+			g_return_val_if_fail (value, NULL);
+			return dn_print_oid_value (oid, egg_oid_get_flags (oid), value, n_value);
+		}
+	}
+
+	return NULL;
+}
+
+gboolean
+egg_dn_parse (ASN1_TYPE asn, const gchar *part,
+              EggDnCallback callback, gpointer user_data)
+{
+	gboolean done = FALSE;
+	gchar *path;
+	guchar *value;
+	gsize n_value;
+	GQuark oid;
+	guint i, j;
+
+	g_return_val_if_fail (asn, FALSE);
+
+	/* Each (possibly multi valued) RDN */
+	for (i = 1; !done; ++i) {
+
+		/* Each type=value pair of an RDN */
+		for (j = 1; TRUE; ++j) {
+
+			/* Dig out the type */
+			path = g_strdup_printf ("%s%s?%u.?%u.type",
+			                        part ? part : "",
+			                        part ? "." : "", i, j);
+			oid = egg_asn1_read_oid (asn, path);
+			g_free (path);
+
+			if (!oid) {
+				done = j == 1;
+				break;
+			}
+
+			/* Print the value as nicely as we can */
+			path = g_strdup_printf ("%s%s?%u.?%u.value",
+			                        part ? part : "",
+			                        part ? "." : "", i, j);
+			value = egg_asn1_read_value (asn, path, &n_value, NULL);
+			g_free (path);
+
+			if (!value) {
+				done = j == 1;
+				break;
+			}
+
+			if (callback)
+				(callback) (i, oid, value, n_value, user_data);
+
+			g_free (value);
+		}
+	}
+
+	return i > 1;
+}
+
+gchar*
+egg_dn_print_value (GQuark oid, const guchar *value, gsize n_value)
+{
+	g_return_val_if_fail (oid, NULL);
+	g_return_val_if_fail (value || !n_value, NULL);
+
+	return dn_print_oid_value (oid, egg_oid_get_flags (oid), value, n_value);
+}
diff --git a/egg/egg-dn.h b/egg/egg-dn.h
new file mode 100644
index 0000000..c205ba7
--- /dev/null
+++ b/egg/egg-dn.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* egg-asn1.h - ASN.1 helper routines
+
+   Copyright (C) 2007 Stefan Walter
+
+   The Gnome Keyring Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Keyring Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Stef Walter <stef memberwebs com>
+*/
+
+#ifndef EGG_DN_H_
+#define EGG_DN_H_
+
+#include <glib.h>
+
+#include <libtasn1.h>
+
+gchar*             egg_dn_read                            (ASN1_TYPE asn, const gchar *part);
+
+gchar*             egg_dn_read_part                       (ASN1_TYPE asn, const gchar *part, const gchar *match);
+
+typedef void       (*EggDnCallback)                       (guint index, GQuark oid, const guchar *value,
+                                                           gsize n_value, gpointer user_data);
+
+gboolean           egg_dn_parse                           (ASN1_TYPE asn, const gchar *part,
+                                                           EggDnCallback callback, gpointer user_data);
+
+gchar*             egg_dn_print_value                     (GQuark oid, const guchar *value, gsize n_value);
+
+#endif /*EGG_DN_H_*/
diff --git a/egg/tests/Makefile.am b/egg/tests/Makefile.am
index e8d3b86..d42a92e 100644
--- a/egg/tests/Makefile.am
+++ b/egg/tests/Makefile.am
@@ -4,6 +4,7 @@ asn1-def-test.h: test.asn
 # Test files should be listed in order they need to run
 TESTING_FILES = \
 	unit-test-asn1.c \
+	test-dn.c \
 	unit-test-cleanup.c \
 	unit-test-hex.c \
 	unit-test-oid.c \
diff --git a/egg/tests/test-dn.c b/egg/tests/test-dn.c
new file mode 100644
index 0000000..6ad3811
--- /dev/null
+++ b/egg/tests/test-dn.c
@@ -0,0 +1,167 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* unit-test-pkix-parser.c: Test PKIX parser
+
+   Copyright (C) 2007 Stefan Walter
+
+   The Gnome Keyring Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Keyring Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Stef Walter <stef memberwebs com>
+*/
+
+#include "config.h"
+
+#include "test-suite.h"
+
+#include "egg/egg-asn1.h"
+#include "egg/egg-dn.h"
+#include "egg/egg-oid.h"
+
+#include <glib.h>
+#include <gcrypt.h>
+#include <libtasn1.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+static ASN1_TYPE asn1_cert = NULL;
+static guchar *data_cert = NULL;
+static gsize n_data_cert = 0;
+
+DEFINE_SETUP(dn_cert)
+{
+	ASN1_TYPE pkix;
+	int res;
+
+	data_cert = testing_data_read ("test-certificate-1.der", &n_data_cert);
+
+	/* We'll be catching this error later */
+	pkix = egg_asn1_get_pkix_asn1type ();
+	if (!pkix) return;
+
+	res = asn1_create_element (pkix, "PKIX1.Certificate", &asn1_cert);
+	g_assert (res == ASN1_SUCCESS);
+
+	res = asn1_der_decoding (&asn1_cert, data_cert, n_data_cert, NULL);
+	g_assert (res == ASN1_SUCCESS);
+}
+
+DEFINE_TEARDOWN(dn_cert)
+{
+	asn1_delete_structure (&asn1_cert);
+	g_free (data_cert);
+	data_cert = NULL;
+}
+
+DEFINE_TEST(read_dn)
+{
+	gchar *dn;
+
+	dn = egg_dn_read (asn1_cert, "tbsCertificate.issuer.rdnSequence");
+	g_assert (dn != NULL);
+	g_assert_cmpstr (dn, ==, "C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting, OU=Certification Services Division, CN=Thawte Personal Premium CA, EMAIL=personal-premium thawte com");
+
+	g_free (dn);
+
+	dn = egg_dn_read (asn1_cert, "tbsCertificate.nonExistant");
+	g_assert (dn == NULL);
+}
+
+DEFINE_TEST(dn_value)
+{
+	const guchar value[] = { 0x13, 0x1a, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x50, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x20, 0x43, 0x41 };
+	gsize n_value = 28;
+	GQuark oid;
+	gchar *text;
+
+	/* Some printable strings */
+	oid = g_quark_from_static_string ("2.5.4.3");
+	text = egg_dn_print_value (oid, value, n_value);
+	g_assert_cmpstr (text, ==, "Thawte Personal Premium CA");
+	g_free (text);
+
+	/* Unknown oid */
+	oid = g_quark_from_static_string ("1.1.1.1.1.1");
+	text = egg_dn_print_value (oid, value, n_value);
+	g_assert_cmpstr (text, ==, "#131A54686177746520506572736F6E616C205072656D69756D204341");
+	g_free (text);
+}
+
+static int last_index = 0;
+
+static void
+concatenate_dn (guint index, GQuark oid, const guchar *value, gsize n_value, gpointer user_data)
+{
+	GString *dn = user_data;
+	gchar *text;
+
+	g_assert (oid);
+	g_assert (value);
+	g_assert (n_value);
+
+	g_assert (index == last_index);
+	++last_index;
+
+	if (index != 1) {
+		g_string_append (dn, ", ");
+	}
+
+	g_string_append (dn, egg_oid_get_name (oid));
+	g_string_append_c (dn, '=');
+
+	text = egg_dn_print_value (oid, value, n_value);
+	g_string_append (dn, text);
+	g_free (text);
+}
+
+DEFINE_TEST(parse_dn)
+{
+	GString *dn = g_string_new ("");
+	last_index = 1;
+
+	if (!egg_dn_parse (asn1_cert, "tbsCertificate.issuer.rdnSequence", concatenate_dn, dn))
+		g_assert_not_reached ();
+
+	g_assert_cmpstr (dn->str, ==, "C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting, OU=Certification Services Division, CN=Thawte Personal Premium CA, EMAIL=personal-premium thawte com");
+	g_string_free (dn, TRUE);
+}
+
+DEFINE_TEST(read_dn_part)
+{
+	gchar *value;
+
+	value = egg_dn_read_part (asn1_cert, "tbsCertificate.issuer.rdnSequence", "CN");
+	g_assert (value != NULL);
+	g_assert_cmpstr (value, ==, "Thawte Personal Premium CA");
+	g_free (value);
+
+	value = egg_dn_read_part (asn1_cert, "tbsCertificate.issuer.rdnSequence", "2.5.4.8");
+	g_assert (value != NULL);
+	g_assert_cmpstr (value, ==, "Western Cape");
+	g_free (value);
+
+	value = egg_dn_read_part (asn1_cert, "tbsCertificate.nonExistant", "CN");
+	g_assert (value == NULL);
+
+	value = egg_dn_read_part (asn1_cert, "tbsCertificate.issuer.rdnSequence", "DC");
+	g_assert (value == NULL);
+
+	value = egg_dn_read_part (asn1_cert, "tbsCertificate.issuer.rdnSequence", "0.0.0.0");
+	g_assert (value == NULL);
+
+	value = egg_dn_read_part (asn1_cert, "tbsCertificate.issuer.rdnSequence", "2.5.4.9");
+	g_assert (value == NULL);
+}
diff --git a/egg/tests/unit-test-asn1.c b/egg/tests/unit-test-asn1.c
index 5a4d7dc..61fd605 100644
--- a/egg/tests/unit-test-asn1.c
+++ b/egg/tests/unit-test-asn1.c
@@ -380,103 +380,3 @@ DEFINE_TEST(read_date)
 	g_assert_cmpint (date.month, ==, 12);
 	g_assert_cmpint (date.year, ==, 2020);
 }
-
-DEFINE_TEST(read_dn)
-{
-	gchar *dn;
-	
-	dn = egg_asn1_read_dn (asn1_cert, "tbsCertificate.issuer.rdnSequence");
-	g_assert (dn != NULL);
-	g_assert_cmpstr (dn, ==, "C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting, OU=Certification Services Division, CN=Thawte Personal Premium CA, EMAIL=personal-premium thawte com");
-	
-	g_free (dn);
-	
-	dn = egg_asn1_read_dn (asn1_cert, "tbsCertificate.nonExistant");
-	g_assert (dn == NULL);
-}
-
-DEFINE_TEST(dn_value)
-{
-	const guchar value[] = { 0x13, 0x1a, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x50, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x20, 0x43, 0x41 };
-	gsize n_value = 28;
-	GQuark oid;
-	gchar *text;
-	
-	/* Some printable strings */
-	oid = g_quark_from_static_string ("2.5.4.3");
-	text = egg_asn1_dn_print_value (oid, value, n_value);
-	g_assert_cmpstr (text, ==, "Thawte Personal Premium CA");
-	g_free (text);
-
-	/* Unknown oid */
-	oid = g_quark_from_static_string ("1.1.1.1.1.1");
-	text = egg_asn1_dn_print_value (oid, value, n_value);
-	g_assert_cmpstr (text, ==, "#131A54686177746520506572736F6E616C205072656D69756D204341");
-	g_free (text);
-}
-
-static int last_index = 0;
-
-static void
-concatenate_dn (guint index, GQuark oid, const guchar *value, gsize n_value, gpointer user_data)
-{
-	GString *dn = user_data;
-	gchar *text;
-	
-	g_assert (oid);
-	g_assert (value);
-	g_assert (n_value);
-	
-	g_assert (index == last_index);
-	++last_index;
-	
-	if (index != 1) {
-		g_string_append (dn, ", ");
-	}
-	
-	g_string_append (dn, egg_oid_get_name (oid));
-	g_string_append_c (dn, '=');
-	
-	text = egg_asn1_dn_print_value (oid, value, n_value);
-	g_string_append (dn, text);
-	g_free (text);
-}
-
-DEFINE_TEST(parse_dn)
-{
-	GString *dn = g_string_new ("");
-	last_index = 1;
-	
-	if (!egg_asn1_dn_parse (asn1_cert, "tbsCertificate.issuer.rdnSequence", concatenate_dn, dn))
-		g_assert_not_reached ();
-	
-	g_assert_cmpstr (dn->str, ==, "C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting, OU=Certification Services Division, CN=Thawte Personal Premium CA, EMAIL=personal-premium thawte com");
-	g_string_free (dn, TRUE);
-}
-
-DEFINE_TEST(read_dn_part)
-{
-	gchar *value;
-	
-	value = egg_asn1_read_dn_part (asn1_cert, "tbsCertificate.issuer.rdnSequence", "CN");
-	g_assert (value != NULL);
-	g_assert_cmpstr (value, ==, "Thawte Personal Premium CA");
-	g_free (value);
-
-	value = egg_asn1_read_dn_part (asn1_cert, "tbsCertificate.issuer.rdnSequence", "2.5.4.8");
-	g_assert (value != NULL);
-	g_assert_cmpstr (value, ==, "Western Cape");
-	g_free (value);
-	
-	value = egg_asn1_read_dn_part (asn1_cert, "tbsCertificate.nonExistant", "CN");
-	g_assert (value == NULL);
-
-	value = egg_asn1_read_dn_part (asn1_cert, "tbsCertificate.issuer.rdnSequence", "DC");
-	g_assert (value == NULL);
-
-	value = egg_asn1_read_dn_part (asn1_cert, "tbsCertificate.issuer.rdnSequence", "0.0.0.0");
-	g_assert (value == NULL);
-
-	value = egg_asn1_read_dn_part (asn1_cert, "tbsCertificate.issuer.rdnSequence", "2.5.4.9");
-	g_assert (value == NULL);
-}
diff --git a/gcr/gcr-certificate-details-widget.c b/gcr/gcr-certificate-details-widget.c
index 6621c16..48e6fba 100644
--- a/gcr/gcr-certificate-details-widget.c
+++ b/gcr/gcr-certificate-details-widget.c
@@ -23,6 +23,7 @@
 #include "gcr-certificate-details-widget.h"
 
 #include "egg/egg-asn1.h"
+#include "egg/egg-dn.h"
 #include "egg/egg-oid.h"
 #include "egg/egg-hex.h"
 
@@ -263,7 +264,7 @@ on_parsed_dn_part (guint index, GQuark oid, const guchar *value,
 		g_assert_not_reached ();
 	}
 	
-	display = egg_asn1_dn_print_value (oid, value, n_value);
+	display = egg_dn_print_value (oid, value, n_value);
 	if (display == NULL)
 		display = g_strdup ("");
 	
@@ -301,11 +302,11 @@ refresh_display (GcrCertificateDetailsWidget *self)
 	
 	/* The subject */
 	append_heading (self, _("Subject Name"));
-	egg_asn1_dn_parse (asn, "tbsCertificate.subject.rdnSequence", on_parsed_dn_part, self);
+	egg_dn_parse (asn, "tbsCertificate.subject.rdnSequence", on_parsed_dn_part, self);
 	
 	/* The Issuer */
 	append_heading (self, _("Issuer Name"));
-	egg_asn1_dn_parse (asn, "tbsCertificate.issuer.rdnSequence", on_parsed_dn_part, self);
+	egg_dn_parse (asn, "tbsCertificate.issuer.rdnSequence", on_parsed_dn_part, self);
 	
 	/* The Issued Parameters */
 	append_heading (self, _("Issued Certificate"));
diff --git a/gcr/gcr-certificate.c b/gcr/gcr-certificate.c
index 55abc68..5d8d6c8 100644
--- a/gcr/gcr-certificate.c
+++ b/gcr/gcr-certificate.c
@@ -25,6 +25,7 @@
 #include "gcr-certificate.h"
 
 #include "egg/egg-asn1.h"
+#include "egg/egg-dn.h"
 #include "egg/egg-hex.h"
 
 #include <string.h>
@@ -319,7 +320,7 @@ gcr_certificate_get_issuer_part (GcrCertificate *self, const char *part)
 	info = certificate_info_load (self);
 	g_return_val_if_fail (info, NULL);
 	
-	return egg_asn1_read_dn_part (info->asn1, "tbsCertificate.issuer.rdnSequence", part);
+	return egg_dn_read_part (info->asn1, "tbsCertificate.issuer.rdnSequence", part);
 }
 
 /**
@@ -344,7 +345,7 @@ gcr_certificate_get_issuer_dn (GcrCertificate *self)
 	info = certificate_info_load (self);
 	g_return_val_if_fail (info, NULL);
 	
-	return egg_asn1_read_dn (info->asn1, "tbsCertificate.issuer.rdnSequence"); 
+	return egg_dn_read (info->asn1, "tbsCertificate.issuer.rdnSequence");
 }
 
 /**
@@ -390,7 +391,7 @@ gcr_certificate_get_subject_part (GcrCertificate *self, const char *part)
 	info = certificate_info_load (self);
 	g_return_val_if_fail (info, NULL);
 	
-	return egg_asn1_read_dn_part (info->asn1, "tbsCertificate.subject.rdnSequence", part); 
+	return egg_dn_read_part (info->asn1, "tbsCertificate.subject.rdnSequence", part);
 }
 
 /**
@@ -415,7 +416,7 @@ gcr_certificate_get_subject_dn (GcrCertificate *self)
 	info = certificate_info_load (self);
 	g_return_val_if_fail (info, NULL);
 	
-	return egg_asn1_read_dn (info->asn1, "tbsCertificate.issuer.rdnSequence"); 	
+	return egg_dn_read (info->asn1, "tbsCertificate.issuer.rdnSequence");
 }
 
 /**
diff --git a/gcr/gcr-parser.c b/gcr/gcr-parser.c
index f9c97f9..f3b597c 100644
--- a/gcr/gcr-parser.c
+++ b/gcr/gcr-parser.c
@@ -29,6 +29,7 @@
 #include "gcr-types.h"
 
 #include "egg/egg-asn1.h"
+#include "egg/egg-dn.h"
 #include "egg/egg-openssl.h"
 #include "egg/egg-secure-memory.h"
 #include "egg/egg-symkey.h"
@@ -623,7 +624,7 @@ parse_der_certificate (GcrParser *self, const guchar *data, gsize n_data)
 	parsed_clear (self, CKO_CERTIFICATE);
 	parsed_ulong (self, CKA_CERTIFICATE_TYPE, CKC_X_509);
 
-	name = egg_asn1_read_dn_part (asn, "tbsCertificate.subject.rdnSequence", "CN");
+	name = egg_dn_read_part (asn, "tbsCertificate.subject.rdnSequence", "CN");
 	asn1_delete_structure (&asn);
 		
 	if (name != NULL) {
diff --git a/pkcs11/gkm/gkm-certificate.c b/pkcs11/gkm/gkm-certificate.c
index 5c5b9d0..0db7327 100644
--- a/pkcs11/gkm/gkm-certificate.c
+++ b/pkcs11/gkm/gkm-certificate.c
@@ -36,6 +36,8 @@
 #include "gkm-transaction.h"
 #include "gkm-util.h"
 
+#include "egg/egg-dn.h"
+
 #include "pkcs11/pkcs11.h"
 #include "pkcs11/pkcs11g.h"
 
@@ -730,11 +732,11 @@ gkm_certificate_get_label (GkmCertificate *self)
 		g_return_val_if_fail (self->pv->asn1, "");
 
 		/* Look for the CN in the certificate */
-		label = egg_asn1_read_dn_part (self->pv->asn1, "tbsCertificate.subject.rdnSequence", "cn");
+		label = egg_dn_read_part (self->pv->asn1, "tbsCertificate.subject.rdnSequence", "cn");
 
 		/* Otherwise use the full DN */
 		if (!label)
-			label = egg_asn1_read_dn (self->pv->asn1, "tbsCertificate.subject.rdnSequence");
+			label = egg_dn_read (self->pv->asn1, "tbsCertificate.subject.rdnSequence");
 
 		if (!label)
 			label = g_strdup (_("Unnamed Certificate"));
diff --git a/pkcs11/user-store/gkm-user-storage.c b/pkcs11/user-store/gkm-user-storage.c
index 46b8ed1..6cd8399 100644
--- a/pkcs11/user-store/gkm-user-storage.c
+++ b/pkcs11/user-store/gkm-user-storage.c
@@ -34,6 +34,7 @@
 #include "gkm/gkm-serializable.h"
 #include "gkm/gkm-util.h"
 
+#include "egg/egg-dn.h"
 #include "egg/egg-error.h"
 #include "egg/egg-hex.h"
 
@@ -141,7 +142,7 @@ name_for_subject (const guchar *subject, gsize n_subject)
 	asn = egg_asn1_decode ("PKIX1.Name", subject, n_subject);
 	g_return_val_if_fail (asn, NULL);
 
-	name = egg_asn1_read_dn_part (asn, "rdnSequence", "CN");
+	name = egg_dn_read_part (asn, "rdnSequence", "CN");
 	asn1_delete_structure (&asn);
 
 	return name;



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