[gnome-keyring] gck: Add debug output to GckEnumerator and bits of GckSession



commit 3aab45fee247303f4d7c5f2fd29f7cb9a7bd8d47
Author: Stef Walter <stefw collabora co uk>
Date:   Wed Aug 31 09:33:11 2011 +0200

    gck: Add debug output to GckEnumerator and bits of GckSession
    
     * Also fix up Gcr debugging
     * And add debugging to trust stuff.

 docs/reference/gck/Makefile.am |    4 +-
 gck/Makefile.am                |    2 +
 gck/gck-attributes.c           |  350 ++++++++++++++++++++++++++++++++++++++++
 gck/gck-debug.c                |  109 +++++++++++++
 gck/gck-debug.h                |   86 ++++++++++
 gck/gck-enumerator.c           |   70 +++++++--
 gck/gck-misc.c                 |   97 +++++++++++
 gck/gck-private.h              |    4 +
 gck/gck-session.c              |   27 +++-
 gck/gck.h                      |    4 +
 gck/pkcs11-trust-assertions.h  |   56 +++++++
 gcr/Makefile.am                |    3 +-
 gcr/gcr-debug.c                |    1 +
 gcr/gcr-debug.h                |    3 +-
 gcr/gcr-trust.c                |    8 +
 15 files changed, 808 insertions(+), 16 deletions(-)
---
diff --git a/docs/reference/gck/Makefile.am b/docs/reference/gck/Makefile.am
index b53011d..cfe53cd 100644
--- a/docs/reference/gck/Makefile.am
+++ b/docs/reference/gck/Makefile.am
@@ -54,10 +54,12 @@ EXTRA_HFILES=
 # Header files to ignore when scanning. Use base file name, no paths
 # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
 IGNORE_HFILES= \
+	gck-debug.h \
 	gck-private.h \
 	test-suite.h \
 	gck-mock.h \
-	gck-test.h
+	gck-test.h \
+	pkcs11-trust-assertions.h
 
 # Images to copy into HTML directory.
 # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
diff --git a/gck/Makefile.am b/gck/Makefile.am
index 7be70dc..f0c3544 100644
--- a/gck/Makefile.am
+++ b/gck/Makefile.am
@@ -21,6 +21,7 @@ INCLUDES = \
 	$(GOBJECT_CFLAGS) \
 	$(GTHREAD_CFLAGS) \
 	$(GLIB_CFLAGS) \
+	-DG_LOG_DOMAIN=\"Gck\" \
 	-DGCK_API_SUBJECT_TO_CHANGE \
 	-DP11_KIT_API_SUBJECT_TO_CHANGE \
 	-DPKCS11_REGISTRY_DIR=\"$(libdir)/pkcs11\"
@@ -34,6 +35,7 @@ libgck_ GCK_MAJOR@_la_SOURCES = \
 	gck.h gck-private.h pkcs11.h \
 	gck-attributes.c \
 	gck-call.c \
+	gck-debug.c gck-debug.h \
 	gck-dump.c \
 	gck-enumerator.c \
 	gck-misc.c \
diff --git a/gck/gck-attributes.c b/gck/gck-attributes.c
index 5a530eb..8adb05c 100644
--- a/gck/gck-attributes.c
+++ b/gck/gck-attributes.c
@@ -25,6 +25,7 @@
 
 #include "gck.h"
 #include "gck-private.h"
+#include "pkcs11-trust-assertions.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -1382,3 +1383,352 @@ _gck_attributes_commit_out (GckAttributes *attrs, CK_ULONG_PTR n_attrs)
 	*n_attrs = attrs->array->len;
 	return (CK_ATTRIBUTE_PTR)attrs->array->data;
 }
+
+static gboolean
+_gck_attribute_is_ulong_of_type (GckAttribute *attr,
+                                 gulong attr_type)
+{
+	if (attr->type != attr_type)
+		return FALSE;
+	if (attr->length != sizeof (gulong))
+		return FALSE;
+	if (!attr->value)
+		return FALSE;
+	return TRUE;
+}
+
+static gboolean
+_gck_attribute_is_sensitive (GckAttribute *attr)
+{
+	/*
+	 * Don't print any just attribute, since they may contain
+	 * sensitive data
+	 */
+
+	switch (attr->type) {
+	#define X(x) case x: return FALSE;
+	X (CKA_CLASS)
+	X (CKA_TOKEN)
+	X (CKA_PRIVATE)
+	X (CKA_LABEL)
+	X (CKA_APPLICATION)
+	X (CKA_OBJECT_ID)
+	X (CKA_CERTIFICATE_TYPE)
+	X (CKA_ISSUER)
+	X (CKA_SERIAL_NUMBER)
+	X (CKA_AC_ISSUER)
+	X (CKA_OWNER)
+	X (CKA_ATTR_TYPES)
+	X (CKA_TRUSTED)
+	X (CKA_CERTIFICATE_CATEGORY)
+	X (CKA_JAVA_MIDP_SECURITY_DOMAIN)
+	X (CKA_URL)
+	X (CKA_HASH_OF_SUBJECT_PUBLIC_KEY)
+	X (CKA_HASH_OF_ISSUER_PUBLIC_KEY)
+	X (CKA_CHECK_VALUE)
+	X (CKA_KEY_TYPE)
+	X (CKA_SUBJECT)
+	X (CKA_ID)
+	X (CKA_SENSITIVE)
+	X (CKA_ENCRYPT)
+	X (CKA_DECRYPT)
+	X (CKA_WRAP)
+	X (CKA_UNWRAP)
+	X (CKA_SIGN)
+	X (CKA_SIGN_RECOVER)
+	X (CKA_VERIFY)
+	X (CKA_VERIFY_RECOVER)
+	X (CKA_DERIVE)
+	X (CKA_START_DATE)
+	X (CKA_END_DATE)
+	X (CKA_MODULUS_BITS)
+	X (CKA_PRIME_BITS)
+	/* X (CKA_SUBPRIME_BITS) */
+	/* X (CKA_SUB_PRIME_BITS) */
+	X (CKA_VALUE_BITS)
+	X (CKA_VALUE_LEN)
+	X (CKA_EXTRACTABLE)
+	X (CKA_LOCAL)
+	X (CKA_NEVER_EXTRACTABLE)
+	X (CKA_ALWAYS_SENSITIVE)
+	X (CKA_KEY_GEN_MECHANISM)
+	X (CKA_MODIFIABLE)
+	X (CKA_SECONDARY_AUTH)
+	X (CKA_AUTH_PIN_FLAGS)
+	X (CKA_ALWAYS_AUTHENTICATE)
+	X (CKA_WRAP_WITH_TRUSTED)
+	X (CKA_WRAP_TEMPLATE)
+	X (CKA_UNWRAP_TEMPLATE)
+	X (CKA_HW_FEATURE_TYPE)
+	X (CKA_RESET_ON_INIT)
+	X (CKA_HAS_RESET)
+	X (CKA_PIXEL_X)
+	X (CKA_PIXEL_Y)
+	X (CKA_RESOLUTION)
+	X (CKA_CHAR_ROWS)
+	X (CKA_CHAR_COLUMNS)
+	X (CKA_COLOR)
+	X (CKA_BITS_PER_PIXEL)
+	X (CKA_CHAR_SETS)
+	X (CKA_ENCODING_METHODS)
+	X (CKA_MIME_TYPES)
+	X (CKA_MECHANISM_TYPE)
+	X (CKA_REQUIRED_CMS_ATTRIBUTES)
+	X (CKA_DEFAULT_CMS_ATTRIBUTES)
+	X (CKA_SUPPORTED_CMS_ATTRIBUTES)
+	X (CKA_ALLOWED_MECHANISMS)
+	X (CKA_X_ASSERTION_TYPE)
+	X (CKA_X_CERTIFICATE_VALUE)
+	X (CKA_X_PURPOSE)
+	X (CKA_X_PEER)
+	#undef X
+	}
+
+	return TRUE;
+}
+
+static void
+_gck_format_class (GString *output,
+                   CK_OBJECT_CLASS klass)
+{
+	const gchar *string = NULL;
+
+	switch (klass) {
+	#define X(x) case x: string = #x; break;
+	X (CKO_DATA)
+	X (CKO_CERTIFICATE)
+	X (CKO_PUBLIC_KEY)
+	X (CKO_PRIVATE_KEY)
+	X (CKO_SECRET_KEY)
+	X (CKO_HW_FEATURE)
+	X (CKO_DOMAIN_PARAMETERS)
+	X (CKO_MECHANISM)
+	X (CKO_X_TRUST_ASSERTION)
+	}
+
+	if (string != NULL)
+		g_string_append (output, string);
+	else
+		g_string_append_printf (output, "0x%08lX", klass);
+}
+
+static void
+_gck_format_assertion_type (GString *output,
+                            CK_X_ASSERTION_TYPE type)
+{
+	const gchar *string = NULL;
+
+	switch (type) {
+	#define X(x) case x: string = #x; break;
+	X (CKT_X_UNTRUSTED_CERTIFICATE)
+	X (CKT_X_PINNED_CERTIFICATE)
+	X (CKT_X_ANCHORED_CERTIFICATE)
+	}
+
+	if (string != NULL)
+		g_string_append (output, string);
+	else
+		g_string_append_printf (output, "0x%08lX", type);
+}
+
+static void
+_gck_format_certificate_type (GString *output,
+                              CK_CERTIFICATE_TYPE type)
+{
+	const gchar *string = NULL;
+
+	switch (type) {
+	#define X(x) case x: string = #x; break;
+	X (CKC_X_509)
+	X (CKC_X_509_ATTR_CERT)
+	X (CKC_WTLS)
+	}
+
+	if (string != NULL)
+		g_string_append (output, string);
+	else
+		g_string_append_printf (output, "0x%08lX", type);
+}
+
+static void
+_gck_format_attribute_type (GString *output,
+                            gulong type)
+{
+	const gchar *string = NULL;
+
+	switch (type) {
+	#define X(x) case x: string = #x; break;
+	X (CKA_CLASS)
+	X (CKA_TOKEN)
+	X (CKA_PRIVATE)
+	X (CKA_LABEL)
+	X (CKA_APPLICATION)
+	X (CKA_VALUE)
+	X (CKA_OBJECT_ID)
+	X (CKA_CERTIFICATE_TYPE)
+	X (CKA_ISSUER)
+	X (CKA_SERIAL_NUMBER)
+	X (CKA_AC_ISSUER)
+	X (CKA_OWNER)
+	X (CKA_ATTR_TYPES)
+	X (CKA_TRUSTED)
+	X (CKA_CERTIFICATE_CATEGORY)
+	X (CKA_JAVA_MIDP_SECURITY_DOMAIN)
+	X (CKA_URL)
+	X (CKA_HASH_OF_SUBJECT_PUBLIC_KEY)
+	X (CKA_HASH_OF_ISSUER_PUBLIC_KEY)
+	X (CKA_CHECK_VALUE)
+	X (CKA_KEY_TYPE)
+	X (CKA_SUBJECT)
+	X (CKA_ID)
+	X (CKA_SENSITIVE)
+	X (CKA_ENCRYPT)
+	X (CKA_DECRYPT)
+	X (CKA_WRAP)
+	X (CKA_UNWRAP)
+	X (CKA_SIGN)
+	X (CKA_SIGN_RECOVER)
+	X (CKA_VERIFY)
+	X (CKA_VERIFY_RECOVER)
+	X (CKA_DERIVE)
+	X (CKA_START_DATE)
+	X (CKA_END_DATE)
+	X (CKA_MODULUS)
+	X (CKA_MODULUS_BITS)
+	X (CKA_PUBLIC_EXPONENT)
+	X (CKA_PRIVATE_EXPONENT)
+	X (CKA_PRIME_1)
+	X (CKA_PRIME_2)
+	X (CKA_EXPONENT_1)
+	X (CKA_EXPONENT_2)
+	X (CKA_COEFFICIENT)
+	X (CKA_PRIME)
+	X (CKA_SUBPRIME)
+	X (CKA_BASE)
+	X (CKA_PRIME_BITS)
+	/* X (CKA_SUBPRIME_BITS) */
+	/* X (CKA_SUB_PRIME_BITS) */
+	X (CKA_VALUE_BITS)
+	X (CKA_VALUE_LEN)
+	X (CKA_EXTRACTABLE)
+	X (CKA_LOCAL)
+	X (CKA_NEVER_EXTRACTABLE)
+	X (CKA_ALWAYS_SENSITIVE)
+	X (CKA_KEY_GEN_MECHANISM)
+	X (CKA_MODIFIABLE)
+	X (CKA_ECDSA_PARAMS)
+	/* X (CKA_EC_PARAMS) */
+	X (CKA_EC_POINT)
+	X (CKA_SECONDARY_AUTH)
+	X (CKA_AUTH_PIN_FLAGS)
+	X (CKA_ALWAYS_AUTHENTICATE)
+	X (CKA_WRAP_WITH_TRUSTED)
+	X (CKA_WRAP_TEMPLATE)
+	X (CKA_UNWRAP_TEMPLATE)
+	X (CKA_HW_FEATURE_TYPE)
+	X (CKA_RESET_ON_INIT)
+	X (CKA_HAS_RESET)
+	X (CKA_PIXEL_X)
+	X (CKA_PIXEL_Y)
+	X (CKA_RESOLUTION)
+	X (CKA_CHAR_ROWS)
+	X (CKA_CHAR_COLUMNS)
+	X (CKA_COLOR)
+	X (CKA_BITS_PER_PIXEL)
+	X (CKA_CHAR_SETS)
+	X (CKA_ENCODING_METHODS)
+	X (CKA_MIME_TYPES)
+	X (CKA_MECHANISM_TYPE)
+	X (CKA_REQUIRED_CMS_ATTRIBUTES)
+	X (CKA_DEFAULT_CMS_ATTRIBUTES)
+	X (CKA_SUPPORTED_CMS_ATTRIBUTES)
+	X (CKA_ALLOWED_MECHANISMS)
+	X (CKA_X_ASSERTION_TYPE)
+	X (CKA_X_CERTIFICATE_VALUE)
+	X (CKA_X_PURPOSE)
+	X (CKA_X_PEER)
+	#undef X
+	}
+
+	if (string != NULL)
+		g_string_append (output, string);
+	else
+		g_string_append_printf (output, "CKA_0x%08lX", type);
+}
+
+static void
+_gck_format_some_bytes (GString *output,
+                        gconstpointer bytes,
+                        gulong length)
+{
+	guchar ch;
+	const guchar *data = bytes;
+	gulong i;
+
+	if (bytes == NULL) {
+		g_string_append (output, "NULL");
+		return;
+	}
+
+	g_string_append_c (output, '\"');
+	for (i = 0; i < length && i < 128; i++) {
+		ch = data[i];
+		if (ch == '\t')
+			g_string_append (output, "\\t");
+		else if (ch == '\n')
+			g_string_append (output, "\\n");
+		else if (ch == '\r')
+			g_string_append (output, "\\r");
+		else if (ch >= 32 && ch < 127)
+			g_string_append_c (output, ch);
+		else
+			g_string_append_printf (output, "\\x%02x", ch);
+	}
+
+	if (i < length)
+		g_string_append_printf (output, "...");
+	g_string_append_c (output, '\"');
+}
+
+static void
+_gck_format_attributes (GString *output,
+                        GckAttributes *attrs)
+{
+	GckAttribute *attr;
+	guint count, i;
+
+	count = attrs->array->len;
+	g_string_append_printf (output, "(%d) [", count);
+	for (i = 0; i < count; i++) {
+		attr = &g_array_index (attrs->array, GckAttribute, i);
+		if (i > 0)
+			g_string_append_c (output, ',');
+		g_string_append (output, " { ");
+		_gck_format_attribute_type (output, attr->type);
+		g_string_append (output, " = ");
+		if (attr->length == GCK_INVALID) {
+			g_string_append_printf (output, " (-1) INVALID");
+		} else if (_gck_attribute_is_ulong_of_type (attr, CKA_CLASS)) {
+			_gck_format_class (output, *((CK_OBJECT_CLASS_PTR)attr->value));
+		} else if (_gck_attribute_is_ulong_of_type (attr, CKA_X_ASSERTION_TYPE)) {
+			_gck_format_assertion_type (output, *((CK_X_ASSERTION_TYPE *)attr->value));
+		} else if (_gck_attribute_is_ulong_of_type (attr, CKA_CERTIFICATE_TYPE)) {
+			_gck_format_certificate_type (output, *((CK_CERTIFICATE_TYPE *)attr->value));
+		} else if (_gck_attribute_is_sensitive (attr)) {
+			g_string_append_printf (output, " (%lu) NOT-PRINTED", attr->length);
+		} else {
+			g_string_append_printf (output, " (%lu) ", attr->length);
+			_gck_format_some_bytes (output, attr->value, attr->length);
+		}
+		g_string_append (output, " }");
+	}
+	g_string_append (output, " ]");
+}
+
+gchar *
+_gck_attributes_format (GckAttributes *attrs)
+{
+	GString *output = g_string_sized_new (128);
+	_gck_format_attributes (output, attrs);
+	return g_string_free (output, FALSE);
+}
diff --git a/gck/gck-debug.c b/gck/gck-debug.c
new file mode 100644
index 0000000..d301fd1
--- /dev/null
+++ b/gck/gck-debug.c
@@ -0,0 +1,109 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/*
+ * Copyright (C) 2007 Collabora Ltd.
+ * Copyright (C) 2007 Nokia Corporation
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+
+#include "gck.h"
+#include "gck-debug.h"
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "pkcs11.h"
+
+#ifdef WITH_DEBUG
+
+static GckDebugFlags current_flags = 0;
+
+static GDebugKey keys[] = {
+	{ "session", GCK_DEBUG_SESSION },
+	{ "enumerator", GCK_DEBUG_ENUMERATOR },
+	{ 0, }
+};
+
+static void
+debug_set_flags (GckDebugFlags new_flags)
+{
+	current_flags |= new_flags;
+}
+
+void
+_gck_debug_set_flags (const gchar *flags_string)
+{
+	guint nkeys;
+
+	for (nkeys = 0; keys[nkeys].value; nkeys++);
+
+	if (flags_string)
+		debug_set_flags (g_parse_debug_string (flags_string, keys, nkeys));
+}
+
+gboolean
+_gck_debug_flag_is_set (GckDebugFlags flag)
+{
+	return (flag & current_flags) != 0;
+}
+
+void
+_gck_debug_message (GckDebugFlags flag,
+                    const gchar *format,
+                    ...)
+{
+	static gsize initialized_flags = 0;
+	gchar *message;
+	va_list args;
+
+	if (g_once_init_enter (&initialized_flags)) {
+		_gck_debug_set_flags (g_getenv ("GCK_DEBUG"));
+		g_once_init_leave (&initialized_flags, 1);
+	}
+
+	va_start (args, format);
+	message = g_strdup_vprintf (format, args);
+	va_end (args);
+
+	if (flag & current_flags)
+		g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "%s", message);
+
+	g_free (message);
+}
+
+#else /* !WITH_DEBUG */
+
+gboolean
+_gck_debug_flag_is_set (GckDebugFlags flag)
+{
+	return FALSE;
+}
+
+void
+_gck_debug_message (GckDebugFlags flag,
+                    const gchar *format,
+                    ...)
+{
+}
+
+void
+_gck_debug_set_flags (const gchar *flags_string)
+{
+}
+
+#endif /* !WITH_DEBUG */
diff --git a/gck/gck-debug.h b/gck/gck-debug.h
new file mode 100644
index 0000000..9742033
--- /dev/null
+++ b/gck/gck-debug.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2007 Nokia Corporation
+ * Copyright (C) 2007-2011 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef GCK_DEBUG_H
+#define GCK_DEBUG_H
+
+#include "config.h"
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+/* Please keep this enum in sync with #keys in gck-debug.c */
+typedef enum {
+	GCK_DEBUG_SESSION = 1 << 1,
+	GCK_DEBUG_ENUMERATOR = 1 << 2,
+} GckDebugFlags;
+
+gboolean           _gck_debug_flag_is_set              (GckDebugFlags flag);
+
+void               _gck_debug_set_flags                (const gchar *flags_string);
+
+void               _gck_debug_message                  (GckDebugFlags flag,
+                                                        const gchar *format,
+                                                        ...) G_GNUC_PRINTF (2, 3);
+
+G_END_DECLS
+
+#endif /* GCK_DEBUG_H */
+
+/* -----------------------------------------------------------------------------
+ * Below this point is outside the GCK_DEBUG_H guard - so it can take effect
+ * more than once. So you can do:
+ *
+ * #define DEBUG_FLAG GCK_DEBUG_ONE_THING
+ * #include "gck-debug.h"
+ * ...
+ * DEBUG ("if we're debugging one thing");
+ * ...
+ * #undef DEBUG_FLAG
+ * #define DEBUG_FLAG GCK_DEBUG_OTHER_THING
+ * #include "gck-debug.h"
+ * ...
+ * DEBUG ("if we're debugging the other thing");
+ * ...
+ */
+
+#ifdef DEBUG_FLAG
+#ifdef WITH_DEBUG
+
+#undef _gck_debug
+#define _gck_debug(format, ...) \
+	_gck_debug_message (DEBUG_FLAG, "%s: " format, G_STRFUNC, ##__VA_ARGS__)
+
+#undef _gck_debugging
+#define _gck_debugging \
+	_gck_debug_flag_is_set (DEBUG_FLAG)
+
+#else /* !defined (WITH_DEBUG) */
+
+#undef _gck_debug
+#define _gck_debug(format, ...) \
+	do {} while (0)
+
+#undef _gck_debugging
+#define _gck_debugging 0
+
+#endif /* !defined (WITH_DEBUG) */
+
+#endif /* defined (DEBUG_FLAG) */
diff --git a/gck/gck-enumerator.c b/gck/gck-enumerator.c
index 123068e..4b50580 100644
--- a/gck/gck-enumerator.c
+++ b/gck/gck-enumerator.c
@@ -24,6 +24,8 @@
 #include "config.h"
 
 #include "gck.h"
+#define DEBUG_FLAG GCK_DEBUG_ENUMERATOR
+#include "gck-debug.h"
 #include "gck-private.h"
 
 #include <string.h>
@@ -173,9 +175,11 @@ state_modules (GckEnumeratorState *args, gboolean forward)
 
 	if (forward) {
 
-		/* There is no no more modules? */
-		if (!args->modules)
+		/* There are no more modules? */
+		if (!args->modules) {
+			_gck_debug ("no more modules, stopping enumerator");
 			return NULL;
+		}
 
 		/* Pop off the current module */
 		module = args->modules->data;
@@ -183,8 +187,14 @@ state_modules (GckEnumeratorState *args, gboolean forward)
 		args->modules = g_list_delete_link (args->modules, args->modules);
 
 		args->slots = gck_module_get_slots (module, TRUE);
-		g_object_unref (module);
 
+		if (_gck_debugging) {
+			GckModuleInfo *info = gck_module_get_info (module);
+			_gck_debug ("enumerating into module: %s", info->library_description);
+			gck_module_info_free (info);
+		}
+
+		g_object_unref (module);
 		return state_slots;
 	}
 
@@ -206,8 +216,10 @@ state_slots (GckEnumeratorState *args, gboolean forward)
 	if (forward) {
 
 		/* If there are no more slots go back to start state */
-		if (!args->slots)
+		if (!args->slots) {
+			_gck_debug ("no more slots, want next module");
 			return rewind_state (args, state_modules);
+		}
 
 		/* Pop the next slot off the stack */
 		slot = args->slots->data;
@@ -220,17 +232,22 @@ state_slots (GckEnumeratorState *args, gboolean forward)
 			return rewind_state (args, state_modules);
 		}
 
-		matched = TRUE;
-
 		/* Do we have unrecognized matches? */
 		if (args->match->any_unrecognized) {
+			_gck_debug ("token uri had unrecognized, not matching any tokens");
 			matched = FALSE;
 
 		/* Are we trying to match the slot? */
 		} else if (args->match->token_info) {
-
 			/* No match? Go to next slot */
 			matched = _gck_token_info_match (args->match->token_info, token_info);
+
+			_gck_debug ("%s token: %s", matched ? "matched" : "did not match",
+			            token_info->label);
+
+		} else {
+			_gck_debug ("matching all tokens: %s", token_info->label);
+			matched = TRUE;
 		}
 
 		if (!matched) {
@@ -284,6 +301,7 @@ state_slot (GckEnumeratorState *args, gboolean forward)
 			return rewind_state (args, state_slots);
 		}
 
+		_gck_debug ("opened %s session", flags & CKF_RW_SESSION ? "read-write" : "read-only");
 		args->session = gck_session_from_handle (args->slot, session, args->session_options);
 		return state_session;
 
@@ -316,12 +334,16 @@ state_session (GckEnumeratorState *args, gboolean forward)
 	if (forward) {
 
 		/* Don't want to authenticate? */
-		if (!args->authenticate)
+		if (!args->authenticate) {
+			_gck_debug ("no authentication necessary, skipping");
 			return state_authenticated;
+		}
 
 		/* No login necessary */
-		if ((args->token_info->flags & CKF_LOGIN_REQUIRED) == 0)
+		if ((args->token_info->flags & CKF_LOGIN_REQUIRED) == 0) {
+			_gck_debug ("no login required, skipping");
 			return state_authenticated;
+		}
 
 		/* Next check if session is logged in */
 		sinfo = gck_session_get_info (args->session);
@@ -335,10 +357,12 @@ state_session (GckEnumeratorState *args, gboolean forward)
 		    sinfo->state == CKS_RO_USER_FUNCTIONS ||
 		    sinfo->state == CKS_RW_SO_FUNCTIONS) {
 			gck_session_info_free (sinfo);
+			_gck_debug ("already logged in, skipping");
 			return state_authenticated;
 		}
 
 		gck_session_info_free (sinfo);
+		_gck_debug ("trying to log into session");
 
 		/* Try to log in */
 		n_pin = args->password ? strlen (args->password) : 0;
@@ -347,6 +371,7 @@ state_session (GckEnumeratorState *args, gboolean forward)
 
 		/* Authentication failed, ask for a password */
 		if (rv == CKR_PIN_INCORRECT) {
+			_gck_debug ("login was incorrect, want password");
 			args->want_password = TRUE;
 			return NULL;
 
@@ -387,9 +412,15 @@ state_authenticated (GckEnumeratorState *args, gboolean forward)
 
 	if (args->match->attributes) {
 		attrs = _gck_attributes_commit_out (args->match->attributes, &n_attrs);
+		if (_gck_debugging) {
+			gchar *string = _gck_attributes_format (args->match->attributes);
+			_gck_debug ("finding objects matching: %s", string);
+			g_free (string);
+		}
 	} else {
 		attrs = NULL;
 		n_attrs = 0;
+		_gck_debug ("finding all objects");
 	}
 
 	session = gck_session_get_handle (args->session);
@@ -406,12 +437,14 @@ state_authenticated (GckEnumeratorState *args, gboolean forward)
 
 			if (!args->objects)
 				args->objects = g_array_new (FALSE, TRUE, sizeof (CK_OBJECT_HANDLE));
+			_gck_debug ("matched %lu objects", count);
 			g_array_append_vals (args->objects, objects, count);
 		}
 
 		(args->funcs->C_FindObjectsFinal) (session);
 	}
 
+	_gck_debug ("finding objects completed with: %s", _gck_stringize_rv (rv));
 	return state_results;
 }
 
@@ -449,13 +482,19 @@ state_results (GckEnumeratorState *args, gboolean forward)
 	while (have < args->want_objects) {
 
 		object = extract_result (args);
-		if (!object)
+		if (!object) {
+			_gck_debug ("wanted %d objects, have %d, looking for more",
+			            args->want_objects, have);
 			return rewind_state (args, state_slots);
+		}
 
 		args->results = g_list_append (args->results, object);
 		++have;
 	}
 
+	_gck_debug ("wanted %d objects, returned %d objects",
+	            args->want_objects, have);
+
 	/* We got all the results we wanted */
 	return NULL;
 }
@@ -531,6 +570,15 @@ _gck_enumerator_new (GList *modules_or_slots, guint session_options,
 	if (uri_data->attributes)
 		_gck_attributes_lock (uri_data->attributes);
 
+	if (_gck_debugging) {
+		gchar *attrs, *uri;
+		attrs = uri_data->attributes ? _gck_attributes_format (uri_data->attributes) : NULL;
+		uri = uri_data ? gck_uri_build (uri_data, GCK_URI_FOR_TOKEN | GCK_URI_FOR_MODULE) : NULL;
+		_gck_debug ("new enumerator: tokens = %s, objects = %s", uri, attrs);
+		g_free (attrs);
+		g_free (uri);
+	}
+
 	return self;
 }
 
@@ -575,6 +623,8 @@ complete_enumerate_next (EnumerateNext *args, CK_RV result)
 	if (state->want_password) {
 		g_assert (state->slot);
 
+		_gck_debug ("wants password, emitting authenticate-slot");
+
 		/* TODO: Should we be using secure memory here? */
 		g_free (state->password);
 		state->password = NULL;
diff --git a/gck/gck-misc.c b/gck/gck-misc.c
index 7f5fc32..4004954 100644
--- a/gck/gck-misc.c
+++ b/gck/gck-misc.c
@@ -106,6 +106,103 @@ gck_message_from_rv (CK_RV rv)
 	}
 }
 
+const gchar *
+_gck_stringize_rv (CK_RV rv)
+{
+	switch(rv) {
+	#define X(x) case x: return #x;
+	X (CKR_OK)
+	X (CKR_CANCEL)
+	X (CKR_HOST_MEMORY)
+	X (CKR_SLOT_ID_INVALID)
+	X (CKR_GENERAL_ERROR)
+	X (CKR_FUNCTION_FAILED)
+	X (CKR_ARGUMENTS_BAD)
+	X (CKR_NO_EVENT)
+	X (CKR_NEED_TO_CREATE_THREADS)
+	X (CKR_CANT_LOCK)
+	X (CKR_ATTRIBUTE_READ_ONLY)
+	X (CKR_ATTRIBUTE_SENSITIVE)
+	X (CKR_ATTRIBUTE_TYPE_INVALID)
+	X (CKR_ATTRIBUTE_VALUE_INVALID)
+	X (CKR_DATA_INVALID)
+	X (CKR_DATA_LEN_RANGE)
+	X (CKR_DEVICE_ERROR)
+	X (CKR_DEVICE_MEMORY)
+	X (CKR_DEVICE_REMOVED)
+	X (CKR_ENCRYPTED_DATA_INVALID)
+	X (CKR_ENCRYPTED_DATA_LEN_RANGE)
+	X (CKR_FUNCTION_CANCELED)
+	X (CKR_FUNCTION_NOT_PARALLEL)
+	X (CKR_FUNCTION_NOT_SUPPORTED)
+	X (CKR_KEY_HANDLE_INVALID)
+	X (CKR_KEY_SIZE_RANGE)
+	X (CKR_KEY_TYPE_INCONSISTENT)
+	X (CKR_KEY_NOT_NEEDED)
+	X (CKR_KEY_CHANGED)
+	X (CKR_KEY_NEEDED)
+	X (CKR_KEY_INDIGESTIBLE)
+	X (CKR_KEY_FUNCTION_NOT_PERMITTED)
+	X (CKR_KEY_NOT_WRAPPABLE)
+	X (CKR_KEY_UNEXTRACTABLE)
+	X (CKR_MECHANISM_INVALID)
+	X (CKR_MECHANISM_PARAM_INVALID)
+	X (CKR_OBJECT_HANDLE_INVALID)
+	X (CKR_OPERATION_ACTIVE)
+	X (CKR_OPERATION_NOT_INITIALIZED)
+	X (CKR_PIN_INCORRECT)
+	X (CKR_PIN_INVALID)
+	X (CKR_PIN_LEN_RANGE)
+	X (CKR_PIN_EXPIRED)
+	X (CKR_PIN_LOCKED)
+	X (CKR_SESSION_CLOSED)
+	X (CKR_SESSION_COUNT)
+	X (CKR_SESSION_HANDLE_INVALID)
+	X (CKR_SESSION_PARALLEL_NOT_SUPPORTED)
+	X (CKR_SESSION_READ_ONLY)
+	X (CKR_SESSION_EXISTS)
+	X (CKR_SESSION_READ_ONLY_EXISTS)
+	X (CKR_SESSION_READ_WRITE_SO_EXISTS)
+	X (CKR_SIGNATURE_INVALID)
+	X (CKR_SIGNATURE_LEN_RANGE)
+	X (CKR_TEMPLATE_INCOMPLETE)
+	X (CKR_TEMPLATE_INCONSISTENT)
+	X (CKR_TOKEN_NOT_PRESENT)
+	X (CKR_TOKEN_NOT_RECOGNIZED)
+	X (CKR_TOKEN_WRITE_PROTECTED)
+	X (CKR_UNWRAPPING_KEY_HANDLE_INVALID)
+	X (CKR_UNWRAPPING_KEY_SIZE_RANGE)
+	X (CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT)
+	X (CKR_USER_ALREADY_LOGGED_IN)
+	X (CKR_USER_NOT_LOGGED_IN)
+	X (CKR_USER_PIN_NOT_INITIALIZED)
+	X (CKR_USER_TYPE_INVALID)
+	X (CKR_USER_ANOTHER_ALREADY_LOGGED_IN)
+	X (CKR_USER_TOO_MANY_TYPES)
+	X (CKR_WRAPPED_KEY_INVALID)
+	X (CKR_WRAPPED_KEY_LEN_RANGE)
+	X (CKR_WRAPPING_KEY_HANDLE_INVALID)
+	X (CKR_WRAPPING_KEY_SIZE_RANGE)
+	X (CKR_WRAPPING_KEY_TYPE_INCONSISTENT)
+	X (CKR_RANDOM_SEED_NOT_SUPPORTED)
+	X (CKR_RANDOM_NO_RNG)
+	X (CKR_DOMAIN_PARAMS_INVALID)
+	X (CKR_BUFFER_TOO_SMALL)
+	X (CKR_SAVED_STATE_INVALID)
+	X (CKR_INFORMATION_SENSITIVE)
+	X (CKR_STATE_UNSAVEABLE)
+	X (CKR_CRYPTOKI_NOT_INITIALIZED)
+	X (CKR_CRYPTOKI_ALREADY_INITIALIZED)
+	X (CKR_MUTEX_BAD)
+	X (CKR_MUTEX_NOT_LOCKED)
+	X (CKR_FUNCTION_REJECTED)
+	X (CKR_VENDOR_DEFINED)
+	#undef X
+	default:
+		return "CKR_??????";
+	}
+}
+
 /**
  * SECTION:gck-misc
  * @title: Miscellaneous Functions
diff --git a/gck/gck-private.h b/gck/gck-private.h
index f822f3d..64739a2 100644
--- a/gck/gck-private.h
+++ b/gck/gck-private.h
@@ -49,6 +49,8 @@ CK_ATTRIBUTE_PTR    _gck_attributes_commit_in              (GckAttributes *attrs
 CK_ATTRIBUTE_PTR    _gck_attributes_commit_out             (GckAttributes *attrs,
                                                              CK_ULONG_PTR n_attrs);
 
+gchar *             _gck_attributes_format                 (GckAttributes *attrs);
+
 /* ----------------------------------------------------------------------------
  * MISC
  */
@@ -58,6 +60,8 @@ guint               _gck_ulong_hash                        (gconstpointer v);
 gboolean            _gck_ulong_equal                       (gconstpointer v1,
                                                              gconstpointer v2);
 
+const gchar *       _gck_stringize_rv                      (CK_RV rv);
+
 /* ----------------------------------------------------------------------------
  * MODULE
  */
diff --git a/gck/gck-session.c b/gck/gck-session.c
index 52d0a4c..0e9a50c 100644
--- a/gck/gck-session.c
+++ b/gck/gck-session.c
@@ -24,6 +24,8 @@
 #include "config.h"
 
 #include "gck.h"
+#define DEBUG_FLAG GCK_DEBUG_SESSION
+#include "gck-debug.h"
 #include "gck-marshal.h"
 #include "gck-private.h"
 
@@ -852,12 +854,25 @@ perform_create_object (CreateObject *args)
 {
 	CK_ATTRIBUTE_PTR attrs;
 	CK_ULONG n_attrs;
+	CK_RV rv;
 
 	attrs = _gck_attributes_commit_out (args->attrs, &n_attrs);
 
-	return (args->base.pkcs11->C_CreateObject) (args->base.handle,
-	                                            attrs, n_attrs,
-	                                            &args->object);
+	rv = (args->base.pkcs11->C_CreateObject) (args->base.handle,
+	                                          attrs, n_attrs,
+	                                          &args->object);
+
+	if (_gck_debugging) {
+		gchar *string = _gck_attributes_format (args->attrs);
+		if (rv == CKR_OK)
+			_gck_debug ("created object: %s", string);
+		else
+			_gck_debug ("failed %s to create object: %s",
+			            _gck_stringize_rv (rv), string);
+		g_free (string);
+	}
+
+	return rv;
 }
 
 /**
@@ -970,6 +985,12 @@ perform_find_objects (FindObjects *args)
 	GArray *array;
 	CK_RV rv;
 
+	if (_gck_debugging) {
+		gchar *string = _gck_attributes_format (args->attrs);
+		_gck_debug ("matching: %s", string);
+		g_free (string);
+	}
+
 	attrs = _gck_attributes_commit_out (args->attrs, &n_attrs);
 
 	rv = (args->base.pkcs11->C_FindObjectsInit) (args->base.handle,
diff --git a/gck/gck.h b/gck/gck.h
index 13e6ac3..0fe7073 100644
--- a/gck/gck.h
+++ b/gck/gck.h
@@ -345,6 +345,10 @@ GckSlot*              gck_modules_token_for_uri               (GList *modules,
                                                                const gchar *uri,
                                                                GError **error);
 
+GList *               gck_modules_tokens_for_uri              (GList *modules,
+                                                               const gchar *uri,
+                                                               GError **error);
+
 GckObject*            gck_modules_object_for_uri              (GList *modules,
                                                                const gchar *uri,
                                                                guint session_options,
diff --git a/gck/pkcs11-trust-assertions.h b/gck/pkcs11-trust-assertions.h
new file mode 100644
index 0000000..ed8bb6b
--- /dev/null
+++ b/gck/pkcs11-trust-assertions.h
@@ -0,0 +1,56 @@
+/*
+ * pkcs11x.h
+ *  Copyright 2010 Collabora, Ltd
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+/*
+ * The latest version of this file is at:
+ *
+ * git://thewalter.net/git/pkcs11-trust-assertions
+ *
+ * or viewable on the web at:
+ *
+ * http://thewalter.net/git/cgit.cgi/pkcs11-trust-assertions/tree/pkcs11-trust-assertions.h
+ *
+ */
+
+#ifndef PKCS11_TRUST_ASSERTIONS_H
+#define PKCS11_TRUST_ASSERTIONS_H
+
+#include <p11-kit/pkcs11.h>
+
+#define CKA_XDG   (CKA_VENDOR_DEFINED | 0x58444700UL /* XDG0 */ )
+#define CKO_XDG   (CKA_VENDOR_DEFINED | 0x58444700UL /* XDG0 */ )
+
+/* -------------------------------------------------------------------
+ * TRUST ASSERTIONS
+ */
+
+#define CKO_X_TRUST_ASSERTION                    (CKO_XDG + 100)
+
+#define CKA_X_ASSERTION_TYPE                     (CKA_XDG + 1)
+
+#define CKA_X_CERTIFICATE_VALUE                  (CKA_XDG + 2)
+
+#define CKA_X_PURPOSE                            (CKA_XDG + 3)
+
+#define CKA_X_PEER                               (CKA_XDG + 4)
+
+typedef CK_ULONG CK_X_ASSERTION_TYPE;
+
+#define CKT_X_UNTRUSTED_CERTIFICATE              1UL
+
+#define CKT_X_PINNED_CERTIFICATE                 2UL
+
+#define CKT_X_ANCHORED_CERTIFICATE               3UL
+
+#endif /* PKCS11_TRUST_ASSERTIONS_H */
diff --git a/gcr/Makefile.am b/gcr/Makefile.am
index 4bed971..7d0404a 100644
--- a/gcr/Makefile.am
+++ b/gcr/Makefile.am
@@ -70,7 +70,8 @@ INCLUDES = \
 	$(GLIB_CFLAGS) \
 	$(LIBGCRYPT_CFLAGS) \
 	$(LIBTASN1_CFLAGS) \
-	$(P11_KIT_CFLAGS)
+	$(P11_KIT_CFLAGS) \
+	-DG_LOG_DOMAIN=\"Gcr\"
 
 BUILT_SOURCES = \
 	gcr-marshal.c gcr-marshal.h \
diff --git a/gcr/gcr-debug.c b/gcr/gcr-debug.c
index fe88412..1acdd5b 100644
--- a/gcr/gcr-debug.c
+++ b/gcr/gcr-debug.c
@@ -40,6 +40,7 @@ static GDebugKey keys[] = {
 	{ "certificate-chain", GCR_DEBUG_CERTIFICATE_CHAIN },
 	{ "parse", GCR_DEBUG_PARSE },
 	{ "gnupg", GCR_DEBUG_GNUPG },
+	{ "trust", GCR_DEBUG_TRUST },
 	{ 0, }
 };
 
diff --git a/gcr/gcr-debug.h b/gcr/gcr-debug.h
index 51ac345..cb92cee 100644
--- a/gcr/gcr-debug.h
+++ b/gcr/gcr-debug.h
@@ -31,7 +31,8 @@ typedef enum {
 	GCR_DEBUG_LIBRARY = 1 << 1,
 	GCR_DEBUG_CERTIFICATE_CHAIN = 1 << 2,
 	GCR_DEBUG_PARSE = 1 << 3,
-	GCR_DEBUG_GNUPG = 1 << 4
+	GCR_DEBUG_GNUPG = 1 << 4,
+	GCR_DEBUG_TRUST = 1 << 5
 } GcrDebugFlags;
 
 gboolean           _gcr_debug_flag_is_set              (GcrDebugFlags flag);
diff --git a/gcr/gcr-trust.c b/gcr/gcr-trust.c
index 6a3c8fb..7191363 100644
--- a/gcr/gcr-trust.c
+++ b/gcr/gcr-trust.c
@@ -24,6 +24,8 @@
 #include "config.h"
 
 #include "gcr.h"
+#define DEBUG_FLAG GCR_DEBUG_TRUST
+#include "gcr-debug.h"
 #include "gcr-types.h"
 #include "gcr-internal.h"
 #include "gcr-library.h"
@@ -163,6 +165,8 @@ perform_is_certificate_pinned (GckAttributes *search,
 		return FALSE;
 
 	slots = gcr_pkcs11_get_trust_lookup_slots ();
+	_gcr_debug ("searching for pinned certificate in %d slots",
+	            g_list_length (slots));
 	en = gck_slots_enumerate_objects (slots, search, 0);
 	gck_list_unref_free (slots);
 
@@ -172,6 +176,7 @@ perform_is_certificate_pinned (GckAttributes *search,
 	if (object)
 		g_object_unref (object);
 
+	_gcr_debug ("%s certificate anchor", object ? "found" : "did not find");
 	return (object != NULL);
 }
 
@@ -734,6 +739,8 @@ perform_is_certificate_anchored (GckAttributes *attrs,
 		return FALSE;
 
 	slots = gcr_pkcs11_get_trust_lookup_slots ();
+	_gcr_debug ("searching for certificate anchor in %d slots",
+	            g_list_length (slots));
 	en = gck_slots_enumerate_objects (slots, attrs, 0);
 	gck_list_unref_free (slots);
 
@@ -743,6 +750,7 @@ perform_is_certificate_anchored (GckAttributes *attrs,
 	if (object != NULL)
 		g_object_unref (object);
 
+	_gcr_debug ("%s certificate anchor", object ? "found" : "did not find");
 	return (object != NULL);
 }
 



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