gck: Add debug output to GckEnumerator and bits of GckSession
authorStef Walter <stefw@collabora.co.uk>
Wed, 31 Aug 2011 07:33:11 +0000 (09:33 +0200)
committerStef Walter <stefw@collabora.co.uk>
Wed, 31 Aug 2011 07:38:24 +0000 (09:38 +0200)
 * Also fix up Gcr debugging
 * And add debugging to trust stuff.

15 files changed:
docs/reference/gck/Makefile.am
gck/Makefile.am
gck/gck-attributes.c
gck/gck-debug.c [new file with mode: 0644]
gck/gck-debug.h [new file with mode: 0644]
gck/gck-enumerator.c
gck/gck-misc.c
gck/gck-private.h
gck/gck-session.c
gck/gck.h
gck/pkcs11-trust-assertions.h [new file with mode: 0644]
gcr/Makefile.am
gcr/gcr-debug.c
gcr/gcr-debug.h
gcr/gcr-trust.c

index b53011d..cfe53cd 100644 (file)
@@ -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
index 7be70dc..f0c3544 100644 (file)
@@ -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 \
index 5a530eb..8adb05c 100644 (file)
@@ -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 (file)
index 0000000..d301fd1
--- /dev/null
@@ -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 (file)
index 0000000..9742033
--- /dev/null
@@ -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) */
index 123068e..4b50580 100644 (file)
@@ -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;
index 7f5fc32..4004954 100644 (file)
@@ -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
index f822f3d..64739a2 100644 (file)
@@ -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
  */
index 52d0a4c..0e9a50c 100644 (file)
@@ -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,
index 13e6ac3..0fe7073 100644 (file)
--- 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 (file)
index 0000000..ed8bb6b
--- /dev/null
@@ -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 */
index 65340f3..8e991eb 100644 (file)
@@ -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 \
index fe88412..1acdd5b 100644 (file)
@@ -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, }
 };
 
index 51ac345..cb92cee 100644 (file)
@@ -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);
index 6a3c8fb..7191363 100644 (file)
@@ -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);
 }