From 6854ac2de334708e3c2f62e36c99ea6655507d6e Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Mon, 21 Feb 2011 20:45:52 +0100 Subject: [PATCH] gck: Use p11-kit for module loading, messages, and uri parsing. --- docs/reference/gck/gck-sections.txt | 10 +- gck/Makefile.am | 3 + gck/gck-enumerator.c | 12 +- gck/gck-misc.c | 212 ++++------------- gck/gck-module.c | 131 +++++------ gck/gck-modules.c | 136 +++-------- gck/gck-private.h | 21 +- gck/gck-slot.c | 147 ++++++++---- gck/gck-uri.c | 456 ++++++++++-------------------------- gck/gck.h | 52 ++-- gck/gck.pc.in | 2 +- gck/tests/test-gck-crypto.c | 2 +- gck/tests/test-gck-enumerator.c | 64 ++--- gck/tests/test-gck-module.c | 6 +- gck/tests/test-gck-modules.c | 2 +- gck/tests/test-gck-object.c | 2 +- gck/tests/test-gck-session.c | 2 +- gck/tests/test-gck-slot.c | 2 +- gck/tests/test-gck-uri.c | 320 ++++++++++++------------- gcr/Makefile.am | 6 +- gcr/gcr-collection-model.c | 4 +- gcr/gcr-library.c | 6 +- gcr/gcr-library.h | 2 +- gcr/gcr.pc.in | 2 +- 24 files changed, 636 insertions(+), 966 deletions(-) diff --git a/docs/reference/gck/gck-sections.txt b/docs/reference/gck/gck-sections.txt index cd78d38..ed878b7 100644 --- a/docs/reference/gck/gck-sections.txt +++ b/docs/reference/gck/gck-sections.txt @@ -90,7 +90,6 @@ gck_modules_enumerate_objects gck_modules_enumerate_uri gck_modules_get_slots gck_modules_initialize_registered -gck_modules_list_registered_paths gck_modules_object_for_uri gck_modules_objects_for_uri gck_modules_token_for_uri @@ -266,11 +265,13 @@ CKR_GCK_MODULE_PROBLEM
gck-uri -GckUriInfo -GckUriParseFlags +GckUriData +GckUriFlags +gck_uri_data_new gck_uri_parse gck_uri_build -gck_uri_info_free +gck_uri_data_free +GCK_URI_BAD_PREFIX GCK_URI_ERROR gck_uri_get_error_quark @@ -300,6 +301,7 @@ GCK_TYPE_ENUMERATOR gck_list_ref_copy gck_list_unref_free gck_string_from_chars +gck_string_to_chars gck_value_to_boolean gck_value_to_ulong GCK_INVALID diff --git a/gck/Makefile.am b/gck/Makefile.am index 3aa3808..917c5e3 100644 --- a/gck/Makefile.am +++ b/gck/Makefile.am @@ -17,10 +17,12 @@ inc_HEADERS = \ INCLUDES = \ -I$(top_builddir) \ -I$(top_srcdir) \ + $(P11_KIT_CFLAGS) \ $(GOBJECT_CFLAGS) \ $(GTHREAD_CFLAGS) \ $(GLIB_CFLAGS) \ -DGCK_API_SUBJECT_TO_CHANGE \ + -DP11_KIT_API_SUBJECT_TO_CHANGE \ -DPKCS11_REGISTRY_DIR=\"$(libdir)/pkcs11\" BUILT_SOURCES = \ @@ -50,6 +52,7 @@ libgck_la_LDFLAGS = \ libgck_la_LIBADD = \ $(top_builddir)/egg/libegg-hex.la \ + $(P11_KIT_LIBS) \ $(GOBJECT_LIBS) \ $(GTHREAD_LIBS) \ $(GIO_LIBS) \ diff --git a/gck/gck-enumerator.c b/gck/gck-enumerator.c index d312197..123068e 100644 --- a/gck/gck-enumerator.c +++ b/gck/gck-enumerator.c @@ -62,7 +62,7 @@ struct _GckEnumeratorState { /* Input to enumerator */ GList *modules; - GckUriInfo *match; + GckUriData *match; guint session_options; gboolean authenticate; gchar *password; @@ -159,7 +159,7 @@ cleanup_state (GckEnumeratorState *args) if (args->match) { if (args->match->attributes) _gck_attributes_unlock (args->match->attributes); - gck_uri_info_free (args->match); + gck_uri_data_free (args->match); args->match = NULL; } } @@ -507,7 +507,7 @@ gck_enumerator_class_init (GckEnumeratorClass *klass) GckEnumerator* _gck_enumerator_new (GList *modules_or_slots, guint session_options, - GckUriInfo *uri_info) + GckUriData *uri_data) { GckEnumerator *self; GckEnumeratorState *state; @@ -527,9 +527,9 @@ _gck_enumerator_new (GList *modules_or_slots, guint session_options, state->handler = state_modules; } - state->match = uri_info; - if (uri_info->attributes) - _gck_attributes_lock (uri_info->attributes); + state->match = uri_data; + if (uri_data->attributes) + _gck_attributes_lock (uri_data->attributes); return self; } diff --git a/gck/gck-misc.c b/gck/gck-misc.c index 7511339..7f5fc32 100644 --- a/gck/gck-misc.c +++ b/gck/gck-misc.c @@ -26,6 +26,8 @@ #include "gck.h" #include "gck-private.h" +#include + #include /** @@ -99,172 +101,8 @@ gck_message_from_rv (CK_RV rv) case CKR_SESSION_PARALLEL_NOT_SUPPORTED: g_return_val_if_reached (""); - case CKR_CANCEL: - case CKR_FUNCTION_CANCELED: - return _("The operation was cancelled"); - - case CKR_HOST_MEMORY: - return _("Insufficient memory available"); - case CKR_SLOT_ID_INVALID: - return _("The specified slot ID is not valid"); - case CKR_GENERAL_ERROR: - return _("Internal error"); - case CKR_FUNCTION_FAILED: - return _("The operation failed"); - case CKR_ARGUMENTS_BAD: - return _("Invalid arguments"); - case CKR_NEED_TO_CREATE_THREADS: - return _("The module cannot create needed threads"); - case CKR_CANT_LOCK: - return _("The module cannot lock data properly"); - case CKR_ATTRIBUTE_READ_ONLY: - return _("The field is read-only"); - case CKR_ATTRIBUTE_SENSITIVE: - return _("The field is sensitive and cannot be revealed"); - case CKR_ATTRIBUTE_TYPE_INVALID: - return _("The field is invalid or does not exist"); - case CKR_ATTRIBUTE_VALUE_INVALID: - return _("Invalid value for field"); - case CKR_DATA_INVALID: - return _("The data is not valid or unrecognized"); - case CKR_DATA_LEN_RANGE: - return _("The data is too long"); - case CKR_DEVICE_ERROR: - return _("An error occurred on the device"); - case CKR_DEVICE_MEMORY: - return _("Insufficient memory available on the device"); - case CKR_DEVICE_REMOVED: - return _("The device was removed or unplugged"); - case CKR_ENCRYPTED_DATA_INVALID: - return _("The encrypted data is not valid or unrecognized"); - case CKR_ENCRYPTED_DATA_LEN_RANGE: - return _("The encrypted data is too long"); - case CKR_FUNCTION_NOT_SUPPORTED: - return _("This operation is not supported"); - case CKR_KEY_HANDLE_INVALID: - return _("The key is missing or invalid"); - case CKR_KEY_SIZE_RANGE: - return _("The key is the wrong size"); - case CKR_KEY_TYPE_INCONSISTENT: - return _("The key is of the wrong type"); - case CKR_KEY_NOT_NEEDED: - return _("No key is needed"); - case CKR_KEY_CHANGED: - return _("The key is different than before"); - case CKR_KEY_NEEDED: - return _("A key is needed"); - case CKR_KEY_INDIGESTIBLE: - return _("Cannot include the key in the digest"); - case CKR_KEY_FUNCTION_NOT_PERMITTED: - return _("This operation cannot be done with this key"); - case CKR_KEY_NOT_WRAPPABLE: - return _("The key cannot be wrapped"); - case CKR_KEY_UNEXTRACTABLE: - return _("Cannot export this key"); - case CKR_MECHANISM_INVALID: - return _("The crypto mechanism is invalid or unrecognized"); - case CKR_MECHANISM_PARAM_INVALID: - return _("The crypto mechanism has an invalid argument"); - case CKR_OBJECT_HANDLE_INVALID: - return _("The object is missing or invalid"); - case CKR_OPERATION_ACTIVE: - return _("Another operation is already taking place"); - case CKR_OPERATION_NOT_INITIALIZED: - return _("No operation is taking place"); - case CKR_PIN_INCORRECT: - return _("The password or PIN is incorrect"); - case CKR_PIN_INVALID: - return _("The password or PIN is invalid"); - case CKR_PIN_LEN_RANGE: - return _("The password or PIN is of an invalid length"); - case CKR_PIN_EXPIRED: - return _("The password or PIN has expired"); - case CKR_PIN_LOCKED: - return _("The password or PIN is locked"); - case CKR_SESSION_CLOSED: - return _("The session is closed"); - case CKR_SESSION_COUNT: - return _("Too many sessions are active"); - case CKR_SESSION_HANDLE_INVALID: - return _("The session is invalid"); - case CKR_SESSION_READ_ONLY: - return _("The session is read-only"); - case CKR_SESSION_EXISTS: - return _("An open session exists"); - case CKR_SESSION_READ_ONLY_EXISTS: - return _("A read-only session exists"); - case CKR_SESSION_READ_WRITE_SO_EXISTS: - return _("An administrator session exists"); - case CKR_SIGNATURE_INVALID: - return _("The signature is bad or corrupted"); - case CKR_SIGNATURE_LEN_RANGE: - return _("The signature is unrecognized or corrupted"); - case CKR_TEMPLATE_INCOMPLETE: - return _("Certain required fields are missing"); - case CKR_TEMPLATE_INCONSISTENT: - return _("Certain fields have invalid values"); - case CKR_TOKEN_NOT_PRESENT: - return _("The device is not present or unplugged"); - case CKR_TOKEN_NOT_RECOGNIZED: - return _("The device is invalid or unrecognizable"); - case CKR_TOKEN_WRITE_PROTECTED: - return _("The device is write protected"); - case CKR_UNWRAPPING_KEY_HANDLE_INVALID: - return _("Cannot import because the key is invalid"); - case CKR_UNWRAPPING_KEY_SIZE_RANGE: - return _("Cannot import because the key is of the wrong size"); - case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: - return _("Cannot import because the key is of the wrong type"); - case CKR_USER_ALREADY_LOGGED_IN: - return _("You are already logged in"); - case CKR_USER_NOT_LOGGED_IN: - return _("No user has logged in"); - case CKR_USER_PIN_NOT_INITIALIZED: - return _("The user's password or PIN is not set"); - case CKR_USER_TYPE_INVALID: - return _("The user is of an invalid type"); - case CKR_USER_ANOTHER_ALREADY_LOGGED_IN: - return _("Another user is already logged in"); - case CKR_USER_TOO_MANY_TYPES: - return _("Too many users of different types are logged in"); - case CKR_WRAPPED_KEY_INVALID: - return _("Cannot import an invalid key"); - case CKR_WRAPPED_KEY_LEN_RANGE: - return _("Cannot import a key of the wrong size"); - case CKR_WRAPPING_KEY_HANDLE_INVALID: - return _("Cannot export because the key is invalid"); - case CKR_WRAPPING_KEY_SIZE_RANGE: - return _("Cannot export because the key is of the wrong size"); - case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: - return _("Cannot export because the key is of the wrong type"); - case CKR_RANDOM_SEED_NOT_SUPPORTED: - return _("Unable to initialize the random number generator"); - case CKR_RANDOM_NO_RNG: - return _("No random number generator available"); - case CKR_DOMAIN_PARAMS_INVALID: - return _("The crypto mechanism has an invalid parameter"); - case CKR_BUFFER_TOO_SMALL: - return _("Not enough space to store the result"); - case CKR_SAVED_STATE_INVALID: - return _("The saved state is invalid"); - case CKR_INFORMATION_SENSITIVE: - return _("The information is sensitive and cannot be revealed"); - case CKR_STATE_UNSAVEABLE: - return _("The state cannot be saved"); - case CKR_CRYPTOKI_NOT_INITIALIZED: - return _("The module has not been initialized"); - case CKR_CRYPTOKI_ALREADY_INITIALIZED: - return _("The module has already been initialized"); - case CKR_MUTEX_BAD: - return _("Cannot lock data"); - case CKR_MUTEX_NOT_LOCKED: - return _("The data cannot be locked"); - case CKR_FUNCTION_REJECTED: - return _("The signature request was rejected by the user"); - default: - g_message ("unknown error: %lu", (gulong)rv); - return _("Unknown error"); + return p11_kit_strerror (rv); } } @@ -326,6 +164,9 @@ gck_list_ref_copy (GList *reflist) * spaces. These space padded strings are often used in PKCS\#11 * structures. * + * If the space padded string is filled with null characters then + * this function will return %NULL. + * * Return value: The null terminated string. */ gchar* @@ -336,11 +177,52 @@ gck_string_from_chars (const guchar *data, gsize max) g_return_val_if_fail (data, NULL); g_return_val_if_fail (max, NULL); + /* Means no value */ + if (!data[0]) + return NULL; + string = g_strndup ((gchar*)data, max); g_strchomp (string); return string; } +/** + * gck_string_to_chars: + * @data: The character buffer to place string into. + * @max: The maximum length of the charater buffer. + * @string: The string to place in the buffer. + * + * Create a space padded PKCS\#11 string from a null terminated string. + * The string must be shorter than the buffer or %FALSE will be + * returned. + * + * If a %NULL string is passed, then the space padded string will be + * set to zero characters. + * + * Return value: The null terminated string. + */ +gboolean +gck_string_to_chars (guchar *data, gsize max, const gchar *string) +{ + gsize len; + + g_return_val_if_fail (data, FALSE); + g_return_val_if_fail (max, FALSE); + + if (!string) { + memset (data, 0, max); + return TRUE; + } + + len = strlen (string); + if (len > max) + return FALSE; + + memset (data, ' ', max); + memcpy (data, string, len); + return TRUE; +} + guint _gck_ulong_hash (gconstpointer v) { diff --git a/gck/gck-module.c b/gck/gck-module.c index 650fac4..ccfc5fe 100644 --- a/gck/gck-module.c +++ b/gck/gck-module.c @@ -27,6 +27,8 @@ #include "gck-private.h" #include "gck-marshal.h" +#include + #include /** @@ -102,53 +104,6 @@ G_DEFINE_TYPE (GckModule, gck_module, G_TYPE_OBJECT); static guint signals[LAST_SIGNAL] = { 0 }; /* ---------------------------------------------------------------------------- - * HELPERS - */ - -static CK_RV -create_mutex (void **mutex) -{ - if (!mutex) - return CKR_ARGUMENTS_BAD; - - if (!g_thread_supported ()) { - g_warning ("cannot create pkcs11 mutex, threading has not been initialized"); - return CKR_GENERAL_ERROR; - } - - *mutex = g_mutex_new (); - g_return_val_if_fail (*mutex, CKR_GENERAL_ERROR); - return CKR_OK; -} - -static CK_RV -destroy_mutex (void *mutex) -{ - if (!mutex) - return CKR_MUTEX_BAD; - g_mutex_free ((GMutex*)mutex); - return CKR_OK; -} - -static CK_RV -lock_mutex (void *mutex) -{ - if (!mutex) - return CKR_MUTEX_BAD; - g_mutex_lock ((GMutex*)mutex); - return CKR_OK; -} - -static CK_RV -unlock_mutex (void *mutex) -{ - if (!mutex) - return CKR_MUTEX_BAD; - g_mutex_unlock ((GMutex*)mutex); - return CKR_OK; -} - -/* ---------------------------------------------------------------------------- * INTERNAL */ @@ -289,7 +244,7 @@ gck_module_dispose (GObject *obj) /* Must be careful when accessing funcs */ if (finalize) { - rv = (self->pv->funcs->C_Finalize) (NULL); + rv = p11_kit_finalize_module (self->pv->funcs); if (rv != CKR_OK) { g_warning ("C_Finalize on module '%s' failed: %s", self->pv->path, gck_message_from_rv (rv)); @@ -419,8 +374,7 @@ gck_module_info_free (GckModuleInfo *module_info) /** * gck_module_initialize: * @path: The file system path to the PKCS\#11 module to load. - * @reserved: Extra arguments for the PKCS\#11 module, should usually be NULL. - * @reserved_options: No options are currently available. + * @flags: No options are currently available. * @error: A location to store an error resulting from a failed load. * * Load and initialize a PKCS\#11 module represented by a GckModule object. @@ -428,8 +382,7 @@ gck_module_info_free (GckModuleInfo *module_info) * Return value: The loaded PKCS\#11 module or NULL if failed. **/ GckModule* -gck_module_initialize (const gchar *path, gpointer reserved, guint reserved_options, - GError **error) +gck_module_initialize (const gchar *path, guint flags, GError **error) { CK_C_GetFunctionList get_function_list; CK_FUNCTION_LIST_PTR funcs; @@ -468,16 +421,8 @@ gck_module_initialize (const gchar *path, gpointer reserved, guint reserved_opti self = g_object_new (GCK_TYPE_MODULE, "functions", funcs, "path", path, NULL); self->pv->module = module; - memset (&self->pv->init_args, 0, sizeof (self->pv->init_args)); - self->pv->init_args.flags = CKF_OS_LOCKING_OK; - self->pv->init_args.CreateMutex = create_mutex; - self->pv->init_args.DestroyMutex = destroy_mutex; - self->pv->init_args.LockMutex = lock_mutex; - self->pv->init_args.UnlockMutex = unlock_mutex; - self->pv->init_args.pReserved = reserved; - /* Now initialize the module */ - rv = (self->pv->funcs->C_Initialize) (&self->pv->init_args); + rv = p11_kit_initialize_module (self->pv->funcs); if (rv != CKR_OK) { g_set_error (error, GCK_ERROR, rv, "Couldn't initialize module: %s", gck_message_from_rv (rv)); @@ -492,7 +437,7 @@ gck_module_initialize (const gchar *path, gpointer reserved, guint reserved_opti /** * gck_module_new: * @funcs: Initialized PKCS\#11 function list pointer - * @reserved_options: Must be zero + * @flags: Must be zero * * Create a GckModule representing a PKCS\#11 module. It is assumed that * this the module is already initialized. In addition it will not be @@ -501,12 +446,20 @@ gck_module_initialize (const gchar *path, gpointer reserved, guint reserved_opti * Return value: The new PKCS\#11 module. **/ GckModule* -gck_module_new (CK_FUNCTION_LIST_PTR funcs, guint reserved_options) +gck_module_new (CK_FUNCTION_LIST_PTR funcs, guint flags) { g_return_val_if_fail (funcs, NULL); return g_object_new (GCK_TYPE_MODULE, "functions", funcs, NULL); } +GckModule* +_gck_module_new_initialized (CK_FUNCTION_LIST_PTR funcs, guint reserved_options) +{ + GckModule *module = gck_module_new (funcs, reserved_options); + module->pv->initialized = TRUE; /* As if we initialized it */ + return module; +} + /** * gck_module_equal: * @module1: A pointer to the first GckModule @@ -554,6 +507,44 @@ gck_module_hash (gconstpointer module) return g_direct_hash (self->pv->funcs); } +GckModuleInfo* +_gck_module_info_from_pkcs11 (CK_INFO_PTR info) +{ + GckModuleInfo *modinfo; + + modinfo = g_new0 (GckModuleInfo, 1); + modinfo->flags = info->flags; + modinfo->library_description = gck_string_from_chars (info->libraryDescription, + sizeof (info->libraryDescription)); + modinfo->manufacturer_id = gck_string_from_chars (info->manufacturerID, + sizeof (info->manufacturerID)); + modinfo->library_version_major = info->libraryVersion.major; + modinfo->library_version_minor = info->libraryVersion.minor; + modinfo->pkcs11_version_major = info->cryptokiVersion.major; + modinfo->pkcs11_version_minor = info->cryptokiVersion.minor; + + return modinfo; +} + +void +_gck_module_info_to_pkcs11 (GckModuleInfo* module_info, CK_INFO_PTR info) +{ + info->flags = module_info->flags; + if (!gck_string_to_chars (info->libraryDescription, + sizeof (info->libraryDescription), + module_info->library_description)) + g_return_if_reached (); + if (!gck_string_to_chars (info->manufacturerID, + sizeof (info->manufacturerID), + module_info->manufacturer_id)) + g_return_if_reached (); + + info->libraryVersion.major = module_info->library_version_major; + info->libraryVersion.minor = module_info->library_version_minor; + info->cryptokiVersion.major = module_info->pkcs11_version_major; + info->cryptokiVersion.minor = module_info->pkcs11_version_minor; +} + /** * gck_module_get_info: * @self: The module to get info for. @@ -565,7 +556,6 @@ gck_module_hash (gconstpointer module) GckModuleInfo* gck_module_get_info (GckModule *self) { - GckModuleInfo *modinfo; CK_INFO info; CK_RV rv; @@ -579,18 +569,7 @@ gck_module_get_info (GckModule *self) return NULL; } - modinfo = g_new0 (GckModuleInfo, 1); - modinfo->flags = info.flags; - modinfo->library_description = gck_string_from_chars (info.libraryDescription, - sizeof (info.libraryDescription)); - modinfo->manufacturer_id = gck_string_from_chars (info.manufacturerID, - sizeof (info.manufacturerID)); - modinfo->library_version_major = info.libraryVersion.major; - modinfo->library_version_minor = info.libraryVersion.minor; - modinfo->pkcs11_version_major = info.cryptokiVersion.major; - modinfo->pkcs11_version_minor = info.cryptokiVersion.minor; - - return modinfo; + return _gck_module_info_from_pkcs11 (&info); } /** diff --git a/gck/gck-modules.c b/gck/gck-modules.c index 3c20250..9bd9e6e 100644 --- a/gck/gck-modules.c +++ b/gck/gck-modules.c @@ -27,7 +27,10 @@ #include "gck-private.h" #include "gck-marshal.h" +#include + #include +#include /** * SECTION:gck-modules @@ -39,103 +42,38 @@ */ /** - * gck_modules_list_registered_paths: - * @error: A location to store an error, on failure - * - * Get the paths for all registered modules. - * - * Returns: An array of module paths, should be freed with g_strfreev(). - */ -gchar** -gck_modules_list_registered_paths (GError **error) -{ - GError *err = NULL; - const gchar *name; - gchar *path; - GDir *dir; - GArray *paths; - - g_return_val_if_fail (!error || !*error, NULL); - - /* We use this below */ - if (!error) - error = &err; - - paths = g_array_new (TRUE, TRUE, sizeof (gchar*)); - - dir = g_dir_open (PKCS11_REGISTRY_DIR, 0, error); - - if (dir == NULL) { - if (g_error_matches (*error, G_FILE_ERROR, G_FILE_ERROR_NOENT) || - g_error_matches (*error, G_FILE_ERROR, G_FILE_ERROR_NOTDIR)) { - g_clear_error (error); - return (gchar**)g_array_free (paths, FALSE); - } else { - g_array_free (paths, TRUE); - g_clear_error (&err); - return NULL; - } - } - - for (;;) { - name = g_dir_read_name (dir); - if (!name) - break; - - /* HACK: libtool can bite my shiny metal ass */ - if (g_str_has_suffix (name, ".la")) - continue; - - path = g_build_filename (PKCS11_REGISTRY_DIR, name, NULL); - if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) - g_array_append_val (paths, path); - else - g_free (path); - } - - g_dir_close (dir); - - return (gchar**)g_array_free (paths, FALSE); -} - -/** * gck_modules_initialize_registered: - * @reserved_options: Module options + * @flags: reserved options set to zero. * - * Initialize all the registered modules. + * Load and initialize all the registered modules. * - * Returns: A list of #GckModule objects, which should be freed by - * gck_list_unref_free(). + * Returns: A newly allocated list of GckModule objects, which should + * be released with gck_list_unref_free(). */ GList* -gck_modules_initialize_registered (guint reserved_options) +gck_modules_initialize_registered (guint flags) { - GError *err = NULL; - gchar **paths, **p; GckModule *module; GList *results = NULL; + CK_FUNCTION_LIST_PTR *modules, *funcs; + CK_RV rv; - paths = gck_modules_list_registered_paths (&err); - if (!paths && err) { - g_warning ("couldn't list registered PKCS#11 module paths: %s", - err && err->message ? err->message : ""); - g_clear_error (&err); + rv = p11_kit_initialize_registered (); + if (rv != CKR_OK) { + g_warning ("couldn't initialize registered PKCS#11 modules: %s", + gck_message_from_rv (rv)); return NULL; } - for (p = paths; *p; ++p) { - module = gck_module_initialize (*p, NULL, 0, &err); - if (module) { - results = g_list_prepend (results, module); + modules = p11_kit_registered_modules (); - } else { - g_warning ("couldn't load PKCS#11 module: %s: %s", - *p, err && err->message ? err->message : ""); - g_clear_error (&err); - } + for (funcs = modules; *funcs; ++funcs) { + module = _gck_module_new_initialized (*funcs, 0); + results = g_list_prepend (results, module); } - g_strfreev (paths); + free (modules); + return results; } @@ -177,14 +115,14 @@ gck_modules_get_slots (GList *modules, gboolean token_present) GckEnumerator* gck_modules_enumerate_objects (GList *modules, GckAttributes *attrs, guint session_options) { - GckUriInfo *uri_info; + GckUriData *uri_data; g_return_val_if_fail (attrs, NULL); - uri_info = _gck_uri_info_new (); - uri_info->attributes = gck_attributes_ref (attrs); + uri_data = gck_uri_data_new (); + uri_data->attributes = gck_attributes_ref (attrs); - return _gck_enumerator_new (modules, session_options, uri_info); + return _gck_enumerator_new (modules, session_options, uri_data); } /** @@ -203,21 +141,21 @@ gck_modules_token_for_uri (GList *modules, const gchar *uri, GError **error) { GckTokenInfo *token_info; GckSlot *result = NULL; - GckUriInfo *uri_info; + GckUriData *uri_data; GckModuleInfo *module_info; GList *slots; GList *m, *s; gboolean matched; - uri_info = gck_uri_parse (uri, GCK_URI_PARSE_TOKEN, error); - if (uri_info == NULL) + uri_data = gck_uri_parse (uri, GCK_URI_CONTEXT_TOKEN, error); + if (uri_data == NULL) return NULL; - if (!uri_info->any_unrecognized) { + if (!uri_data->any_unrecognized) { for (m = modules; result == NULL && m != NULL; m = g_list_next (m)) { - if (uri_info->module_info) { + if (uri_data->module_info) { module_info = gck_module_get_info (m->data); - matched = _gck_module_info_match (uri_info->module_info, module_info); + matched = _gck_module_info_match (uri_data->module_info, module_info); gck_module_info_free (module_info); if (!matched) continue; @@ -225,11 +163,11 @@ gck_modules_token_for_uri (GList *modules, const gchar *uri, GError **error) slots = gck_module_get_slots (m->data, TRUE); for (s = slots; result == NULL && s != NULL; s = g_list_next (s)) { - if (!uri_info->token_info) { + if (!uri_data->token_info) { result = g_object_ref (s->data); } else { token_info = gck_slot_get_token_info (s->data); - if (token_info && _gck_token_info_match (uri_info->token_info, token_info)) + if (token_info && _gck_token_info_match (uri_data->token_info, token_info)) result = g_object_ref (s->data); gck_token_info_free (token_info); } @@ -238,7 +176,7 @@ gck_modules_token_for_uri (GList *modules, const gchar *uri, GError **error) } } - gck_uri_info_free (uri_info); + gck_uri_data_free (uri_data); return result; } @@ -330,12 +268,12 @@ GckEnumerator* gck_modules_enumerate_uri (GList *modules, const gchar *uri, guint session_options, GError **error) { - GckUriInfo *uri_info; + GckUriData *uri_data; - uri_info = gck_uri_parse (uri, GCK_URI_PARSE_OBJECT, error); - if (uri_info == NULL) + uri_data = gck_uri_parse (uri, GCK_URI_CONTEXT_OBJECT, error); + if (uri_data == NULL) return NULL; /* Takes ownership of uri_info */ - return _gck_enumerator_new (modules, session_options, uri_info); + return _gck_enumerator_new (modules, session_options, uri_data); } diff --git a/gck/gck-private.h b/gck/gck-private.h index 544c4d6..615a226 100644 --- a/gck/gck-private.h +++ b/gck/gck-private.h @@ -62,6 +62,9 @@ gboolean _gck_ulong_equal (gconstpointer v1, * MODULE */ +GckModule* _gck_module_new_initialized (CK_FUNCTION_LIST_PTR funcs, + guint reserved_options); + gboolean _gck_module_fire_authenticate_slot (GckModule *module, GckSlot *slot, gchar *label, @@ -72,6 +75,11 @@ gboolean _gck_module_fire_authenticate_object (GckModule *module, gchar *label, gchar **password); +GckModuleInfo* _gck_module_info_from_pkcs11 (CK_INFO_PTR info); + +void _gck_module_info_to_pkcs11 (GckModuleInfo* module_info, + CK_INFO_PTR info); + gboolean _gck_module_info_match (GckModuleInfo *match, GckModuleInfo *module_info); @@ -81,20 +89,19 @@ gboolean _gck_module_info_match (GckModuleInfo *matc GckEnumerator* _gck_enumerator_new (GList *modules, guint session_options, - GckUriInfo *uri_info); + GckUriData *uri_data); /* ---------------------------------------------------------------------------- * SLOT */ -gboolean _gck_token_info_match (GckTokenInfo *match, - GckTokenInfo *info); +GckTokenInfo* _gck_token_info_from_pkcs11 (CK_TOKEN_INFO_PTR info); -/* ---------------------------------------------------------------------------- - * URI - */ +void _gck_token_info_to_pkcs11 (GckTokenInfo *token_info, + CK_TOKEN_INFO_PTR info); -GckUriInfo* _gck_uri_info_new (void); +gboolean _gck_token_info_match (GckTokenInfo *match, + GckTokenInfo *info); /* ---------------------------------------------------------------------------- * CALL diff --git a/gck/gck-slot.c b/gck/gck-slot.c index f86119d..9d789ae 100644 --- a/gck/gck-slot.c +++ b/gck/gck-slot.c @@ -554,6 +554,105 @@ gck_slot_get_info (GckSlot *self) return slotinfo; } +GckTokenInfo* +_gck_token_info_from_pkcs11 (CK_TOKEN_INFO_PTR info) +{ + GckTokenInfo *token_info; + gchar *string; + struct tm tm; + + token_info = g_new0 (GckTokenInfo, 1); + token_info->label = gck_string_from_chars (info->label, sizeof (info->label)); + token_info->model = gck_string_from_chars (info->model, sizeof (info->model)); + token_info->manufacturer_id = gck_string_from_chars (info->manufacturerID, + sizeof (info->manufacturerID)); + token_info->serial_number = gck_string_from_chars (info->serialNumber, + sizeof (info->serialNumber)); + token_info->flags = info->flags; + token_info->max_session_count = info->ulMaxSessionCount; + token_info->session_count = info->ulSessionCount; + token_info->max_rw_session_count = info->ulMaxRwSessionCount; + token_info->rw_session_count = info->ulRwSessionCount; + token_info->max_pin_len = info->ulMaxPinLen; + token_info->min_pin_len = info->ulMinPinLen; + token_info->total_public_memory = info->ulTotalPublicMemory; + token_info->total_private_memory = info->ulTotalPrivateMemory; + token_info->free_private_memory = info->ulFreePrivateMemory; + token_info->free_public_memory = info->ulFreePublicMemory; + token_info->hardware_version_major = info->hardwareVersion.major; + token_info->hardware_version_minor = info->hardwareVersion.minor; + token_info->firmware_version_major = info->firmwareVersion.major; + token_info->firmware_version_minor = info->firmwareVersion.minor; + + /* Parse the time into seconds since epoch */ + if (info->flags & CKF_CLOCK_ON_TOKEN) { + string = g_strndup ((gchar*)info->utcTime, MIN (14, sizeof (info->utcTime))); + if (!strptime (string, "%Y%m%d%H%M%S", &tm)) + token_info->utc_time = -1; + else + token_info->utc_time = timegm (&tm); + g_free (string); + } else { + token_info->utc_time = -1; + } + + return token_info; +} + +void +_gck_token_info_to_pkcs11 (GckTokenInfo *token_info, CK_TOKEN_INFO_PTR info) +{ + gchar buffer[64]; + struct tm tm; + time_t tim; + gsize len; + + if (!gck_string_to_chars (info->label, + sizeof (info->label), + token_info->label)) + g_return_if_reached (); + if (!gck_string_to_chars (info->model, + sizeof (info->model), + token_info->model)) + g_return_if_reached (); + if (!gck_string_to_chars (info->manufacturerID, + sizeof (info->manufacturerID), + token_info->manufacturer_id)) + g_return_if_reached (); + if (!gck_string_to_chars (info->serialNumber, + sizeof (info->serialNumber), + token_info->serial_number)) + g_return_if_reached (); + + info->flags = token_info->flags; + info->ulMaxSessionCount = token_info->max_session_count; + info->ulSessionCount = token_info->session_count; + info->ulMaxRwSessionCount = token_info->max_rw_session_count; + info->ulRwSessionCount = token_info->rw_session_count; + info->ulMaxPinLen = token_info->max_pin_len; + info->ulMinPinLen = token_info->min_pin_len; + info->ulTotalPublicMemory = token_info->total_public_memory; + info->ulTotalPrivateMemory = token_info->total_private_memory; + info->ulFreePrivateMemory = token_info->free_private_memory; + info->ulFreePublicMemory = token_info->free_public_memory; + info->hardwareVersion.major = token_info->hardware_version_major; + info->hardwareVersion.minor = token_info->hardware_version_minor; + info->firmwareVersion.major = token_info->firmware_version_major; + info->firmwareVersion.minor = token_info->firmware_version_minor; + + /* Parse the time into seconds since epoch */ + if (token_info->flags & CKF_CLOCK_ON_TOKEN) { + tim = token_info->utc_time; + if (!gmtime_r (&tim, &tm)) + g_return_if_reached (); + len = strftime (buffer, sizeof (buffer), "%Y%m%d%H%M%S", &tm); + g_return_if_fail (len == sizeof (info->utcTime)); + memcpy (info->utcTime, buffer, sizeof (info->utcTime)); + } else { + memset (info->utcTime, 0, sizeof (info->utcTime)); + } +} + /** * gck_slot_get_token_info: * @self: The slot to get info for. @@ -569,10 +668,7 @@ gck_slot_get_token_info (GckSlot *self) CK_SLOT_ID handle = (CK_SLOT_ID)-1; CK_FUNCTION_LIST_PTR funcs; GckModule *module = NULL; - GckTokenInfo *tokeninfo; CK_TOKEN_INFO info; - gchar *string; - struct tm tm; CK_RV rv; g_return_val_if_fail (GCK_IS_SLOT (self), NULL); @@ -593,42 +689,7 @@ gck_slot_get_token_info (GckSlot *self) return NULL; } - tokeninfo = g_new0 (GckTokenInfo, 1); - tokeninfo->label = gck_string_from_chars (info.label, sizeof (info.label)); - tokeninfo->model = gck_string_from_chars (info.model, sizeof (info.model)); - tokeninfo->manufacturer_id = gck_string_from_chars (info.manufacturerID, - sizeof (info.manufacturerID)); - tokeninfo->serial_number = gck_string_from_chars (info.serialNumber, - sizeof (info.serialNumber)); - tokeninfo->flags = info.flags; - tokeninfo->max_session_count = info.ulMaxSessionCount; - tokeninfo->session_count = info.ulSessionCount; - tokeninfo->max_rw_session_count = info.ulMaxRwSessionCount; - tokeninfo->rw_session_count = info.ulRwSessionCount; - tokeninfo->max_pin_len = info.ulMaxPinLen; - tokeninfo->min_pin_len = info.ulMinPinLen; - tokeninfo->total_public_memory = info.ulTotalPublicMemory; - tokeninfo->total_private_memory = info.ulTotalPrivateMemory; - tokeninfo->free_private_memory = info.ulFreePrivateMemory; - tokeninfo->free_public_memory = info.ulFreePublicMemory; - tokeninfo->hardware_version_major = info.hardwareVersion.major; - tokeninfo->hardware_version_minor = info.hardwareVersion.minor; - tokeninfo->firmware_version_major = info.firmwareVersion.major; - tokeninfo->firmware_version_minor = info.firmwareVersion.minor; - - /* Parse the time into seconds since epoch */ - if (info.flags & CKF_CLOCK_ON_TOKEN) { - string = g_strndup ((gchar*)info.utcTime, MIN (14, sizeof (info.utcTime))); - if (!strptime (string, "%Y%m%d%H%M%S", &tm)) - tokeninfo->utc_time = -1; - else - tokeninfo->utc_time = timegm (&tm); - g_free (string); - } else { - tokeninfo->utc_time = -1; - } - - return tokeninfo; + return _gck_token_info_from_pkcs11 (&info); } /** @@ -788,14 +849,14 @@ gck_slot_has_flags (GckSlot *self, gulong flags) GckEnumerator* gck_slots_enumerate_objects (GList *slots, GckAttributes *attrs, guint session_options) { - GckUriInfo *uri_info; + GckUriData *uri_data; g_return_val_if_fail (attrs, NULL); - uri_info = _gck_uri_info_new (); - uri_info->attributes = gck_attributes_ref (attrs); + uri_data = gck_uri_data_new (); + uri_data->attributes = gck_attributes_ref (attrs); - return _gck_enumerator_new (slots, session_options, uri_info); + return _gck_enumerator_new (slots, session_options, uri_data); } diff --git a/gck/gck-uri.c b/gck/gck-uri.c index e4c5082..12e535b 100644 --- a/gck/gck-uri.c +++ b/gck/gck-uri.c @@ -29,9 +29,10 @@ #include -#include +#include -#include "egg/egg-hex.h" +#include +#include /** * SECTION:gck-uri @@ -56,7 +57,7 @@ **/ /** - * GckUriInfo: + * GckUriData: * @any_unrecognized: whether any parts of the PKCS\#11 URI were unsupported or unrecognized. * @module_info: information about the PKCS\#11 modules matching the URI. * @token_info: information about the PKCS\#11 tokens matching the URI. @@ -71,11 +72,11 @@ */ /** - * GckUriParseFlags: - * @GCK_URI_PARSE_MODULE: the URI will be used to match modules. - * @GCK_URI_PARSE_TOKEN: the URI will be used to match tokens. - * @GCK_URI_PARSE_OBJECT: the URI will be used to match objects. - * @GCK_URI_PARSE_ANY: parse all recognized components of the URI. + * GckUriFlags: + * @GCK_URI_CONTEXT_MODULE: the URI will be used to match modules. + * @GCK_URI_CONTEXT_TOKEN: the URI will be used to match tokens. + * @GCK_URI_CONTEXT_OBJECT: the URI will be used to match objects. + * @GCK_URI_CONTEXT_ANY: parse all recognized components of the URI. * * Which context the PKCS\#11 URI will be used in. */ @@ -103,380 +104,165 @@ gck_uri_get_error_quark (void) return domain; } -GckUriInfo* -_gck_uri_info_new (void) -{ - return g_slice_new0 (GckUriInfo); -} - -static gint -parse_string_attribute (const gchar *name, const gchar *start, const gchar *end, - GckAttributes *attrs, GError **error) -{ - gchar *value; - gint res = 0; - - g_assert (name); - g_assert (start); - g_assert (end); - - if (!g_str_equal (name, "object") && !g_str_equal (name, "objecttype")) - return 0; - - value = g_uri_unescape_segment (start, end, ""); - if (value == NULL) { - g_set_error (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING, - _("The URI has invalid syntax. The '%s' field encoding is invalid."), name); - return -1; - } - - if (g_str_equal (name, "object")) { - gck_attributes_add_string (attrs, CKA_LABEL, value); - res = 1; - - } else if (g_str_equal (name, "objecttype")) { - - res = 1; - if (g_str_equal (value, "cert")) - gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_CERTIFICATE); - else if (g_str_equal (value, "public")) - gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_PUBLIC_KEY); - else if (g_str_equal (value, "private")) - gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_PRIVATE_KEY); - else if (g_str_equal (value, "secretkey")) - gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_SECRET_KEY); - else if (g_str_equal (value, "data")) - gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_DATA); - else { - g_message ("ignoring unsupported value for '%s'", value); - res = 0; - } - } else { - g_assert_not_reached (); - } - - g_free (value); - return res; -} - -static gint -parse_binary_attribute (const gchar *name, const gchar *start, const gchar *end, - GckAttributes *attrs, GError **error) -{ - guchar *data; - gsize n_data; - - g_assert (name); - g_assert (start); - g_assert (end); - g_assert (attrs); - - if (!g_str_equal (name, "id")) - return 0; - - /* - * TODO: This requires some work. We're not yet sure about the actual - * encoding that's supported here. - */ - - g_assert (end >= start); - data = egg_hex_decode_full (start, end - start, ':', 1, &n_data); - if (data == NULL) { - g_set_error (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING, - _("The URI has invalid syntax. The '%s' field encoding is invalid."), name); - return -1; - } - - gck_attributes_add_data (attrs, CKA_ID, data, n_data); - g_free (data); - return 1; -} - -static gint -parse_token_attribute (const gchar *name, const gchar *start, const gchar *end, - GckTokenInfo *token, GError **error) -{ - gchar **value; - gchar *string; - - g_assert (name); - g_assert (start); - g_assert (end); - g_assert (token); - - if (g_str_equal (name, "model")) - value = &(token->model); - else if (g_str_equal (name, "manufacturer")) - value = &(token->manufacturer_id); - else if (g_str_equal (name, "serial")) - value = &(token->serial_number); - else if (g_str_equal (name, "token")) - value = &(token->label); - else - return 0; - - string = g_uri_unescape_segment (start, end, ""); - if (string == NULL) { - g_set_error (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING, - _("The URI has invalid syntax. The '%s' field encoding is invalid."), name); - return -1; - } - - g_free (*value); - *value = string; - - return 1; -} - -static gint -parse_library_attribute (const gchar *name, const gchar *start, const gchar *end, - GckModuleInfo *library, GError **error) +/** + * gck_uri_new: + * + * Allocate a new GckUriData structure. None of the fields + * will be set. + * + * Returns: A newly allocated GckUriData, free with gck_uri_data_free(). + */ +GckUriData* +gck_uri_data_new (void) { - gchar **value; - gchar *string; - - g_assert (name); - g_assert (start); - g_assert (end); - g_assert (library); - - if (g_str_equal (name, "library-description")) - value = &(library->library_description); - else if (g_str_equal (name, "library-manufacturer")) - value = &(library->manufacturer_id); - else - return 0; - - string = g_uri_unescape_segment (start, end, ""); - if (string == NULL) { - g_set_error (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING, - _("The URI has invalid syntax. The '%s' field encoding is invalid."), name); - return -1; - } - - g_free (*value); - *value = string; - - return 1; + return g_slice_new0 (GckUriData); } /** * gck_uri_parse: - * @uri: the URI to parse. + * @string: the URI to parse. * @flags: the context in which the URI will be used. * @error: a #GError, or %NULL. * * Parse a PKCS\#11 URI for use in a given context. * * The result will contain the fields that are relevant for - * the given context. See #GckUriInfo for more info. + * the given context. See #GckUriData for more info. * Other fields will be set to %NULL. * - * Return value: a newly allocated #GckUriInfo, which should be freed with + * Return value: a newly allocated #GckUriData, which should be freed with * gck_uri_info_free(). */ -GckUriInfo* -gck_uri_parse (const gchar *uri, GckUriParseFlags flags, GError **error) +GckUriData* +gck_uri_parse (const gchar *string, GckUriFlags flags, GError **error) { - const gchar *spos, *epos; - gchar *key = NULL; - gboolean ret = FALSE; - GckUriInfo *uri_info = NULL; + GckUriData *uri_data = NULL; + CK_ATTRIBUTE_PTR attrs; + CK_ULONG i, n_attrs; + P11KitUri *p11_uri; gint res; - g_return_val_if_fail (uri, FALSE); + g_return_val_if_fail (string, FALSE); g_return_val_if_fail (!error || !*error, FALSE); - if (!g_str_has_prefix (uri, URI_PREFIX)) { - g_set_error_literal (error, GCK_URI_ERROR, GCK_URI_BAD_PREFIX, - _("The URI does not have the 'pkcs11' scheme.")); - goto cleanup; - } - - uri += N_URI_PREFIX; - - uri_info = _gck_uri_info_new (); - if ((flags & GCK_URI_PARSE_MODULE) == GCK_URI_PARSE_MODULE) - uri_info->module_info = g_new0 (GckModuleInfo, 1); - if ((flags & GCK_URI_PARSE_TOKEN) == GCK_URI_PARSE_TOKEN) - uri_info->token_info = g_new0 (GckTokenInfo, 1); - if ((flags & GCK_URI_PARSE_OBJECT) == GCK_URI_PARSE_OBJECT) - uri_info->attributes = gck_attributes_new (); - - for (;;) { - spos = strchr (uri, ';'); - if (spos == NULL) { - spos = uri + strlen (uri); - g_assert (*spos == '\0'); - if (spos == uri) - break; - } + p11_uri = p11_kit_uri_new (); + if (!p11_uri) + g_error ("failed to allocate P11KitUri"); - epos = strchr (uri, '='); - if (epos == NULL || spos == uri || epos == uri || epos >= spos) { + res = p11_kit_uri_parse (string, flags, p11_uri); + if (res != P11_KIT_URI_OK) { + p11_kit_uri_free (p11_uri); + switch (res) { + case P11_KIT_URI_NO_MEMORY: + g_error ("failed to allocate memory in p11_kit_uri_parse()"); + break; + case P11_KIT_URI_BAD_ENCODING: + g_set_error (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING, + _("The URI has invalid encoding.")); + break; + case P11_KIT_URI_BAD_SCHEME: + g_set_error_literal (error, GCK_URI_ERROR, GCK_URI_BAD_SCHEME, + _("The URI has does not have the 'pkcs11' scheme.")); + break; + case P11_KIT_URI_BAD_SYNTAX: g_set_error_literal (error, GCK_URI_ERROR, GCK_URI_BAD_SYNTAX, - "The URI has invalid syntax. It must consist of key=value pairs."); - goto cleanup; - } - - g_free (key); - key = g_strndup (uri, epos - uri); - epos++; - - res = 0; - if (uri_info->attributes) - res = parse_string_attribute (key, epos, spos, uri_info->attributes, error); - if (res == 0 && uri_info->attributes) - res = parse_binary_attribute (key, epos, spos, uri_info->attributes, error); - if (res == 0 && uri_info->token_info) - res = parse_token_attribute (key, epos, spos, uri_info->token_info, error); - if (res == 0 && uri_info->module_info) - res = parse_library_attribute (key, epos, spos, uri_info->module_info, error); - if (res < 0) - goto cleanup; - if (res == 0) { - g_message ("Ignoring unrecognized or unsupported field '%s'", key); - uri_info->any_unrecognized = TRUE; - } - - if (*spos == '\0') + _("The URI has bad syntax.")); + break; + case P11_KIT_URI_BAD_VERSION: + g_set_error_literal (error, GCK_URI_ERROR, GCK_URI_BAD_SYNTAX, + _("The URI has a bad version number.")); break; - uri = spos + 1; + case P11_KIT_URI_NOT_FOUND: + g_assert_not_reached (); + break; + }; + return NULL; } - ret = TRUE; - -cleanup: - if (!ret) { - gck_uri_info_free (uri_info); - uri_info = NULL; + /* Convert it to a GckUri */ + uri_data = gck_uri_data_new (); + if ((flags & GCK_URI_CONTEXT_MODULE) == GCK_URI_CONTEXT_MODULE) + uri_data->module_info = _gck_module_info_from_pkcs11 (p11_kit_uri_get_module_info (p11_uri)); + if ((flags & GCK_URI_CONTEXT_TOKEN) == GCK_URI_CONTEXT_TOKEN) + uri_data->token_info = _gck_token_info_from_pkcs11 (p11_kit_uri_get_token_info (p11_uri)); + if ((flags & GCK_URI_CONTEXT_OBJECT) == GCK_URI_CONTEXT_OBJECT) { + attrs = p11_kit_uri_get_attributes (p11_uri, &n_attrs); + uri_data->attributes = gck_attributes_new (); + for (i = 0; i < n_attrs; ++i) + gck_attributes_add (uri_data->attributes, (GckAttribute*)&attrs[i]); } + uri_data->any_unrecognized = p11_kit_uri_any_unrecognized (p11_uri); - g_free (key); - return uri_info; -} - -static void -build_string_attribute (const gchar *name, const gchar *value, - GString *result, gboolean *first) -{ - gchar *segment; - - g_assert (first); - g_assert (result); - g_assert (name); - - if (!value) - return; - - segment = g_uri_escape_string (value, "", FALSE); - if (!*first) - g_string_append_c (result, ';'); - *first = FALSE; - - g_string_append (result, name); - g_string_append_c (result, '='); - g_string_append (result, segment); - g_free (segment); -} - -static void -build_binary_attribute (const gchar *name, gconstpointer data, gsize n_data, - GString *result, gboolean *first) -{ - gchar *segment; - - g_assert (first); - g_assert (result); - g_assert (name); - g_assert (!n_data || data); - - segment = egg_hex_encode_full (data, n_data, FALSE, ':', 1); - if (!*first) - g_string_append_c (result, ';'); - *first = FALSE; - - g_string_append (result, name); - g_string_append_c (result, '='); - g_string_append (result, segment); - g_free (segment); + p11_kit_uri_free (p11_uri); + return uri_data; } /** * gck_uri_build: - * @uri_info: the info to build the URI from. + * @uri_data: the info to build the URI from. + * @flags: The context that the URI is for * - * Build a PKCS\#11 URI. Any set fields of @uri_info will be used to build - * the URI. + * Build a PKCS\#11 URI. The various parts relevant to the flags + * specified will be used to build the URI. * * Return value: a newly allocated string containing a PKCS\#11 URI. */ gchar* -gck_uri_build (GckUriInfo *uri_info) +gck_uri_build (GckUriData *uri_data, GckUriFlags flags) { GckAttribute *attr; - GString *result; - gchar *value; - gulong klass; - gboolean first = TRUE; - - g_return_val_if_fail (uri_info, NULL); - - result = g_string_new (URI_PREFIX); - - if (uri_info->module_info) { - build_string_attribute ("library-description", uri_info->module_info->library_description, result, &first); - build_string_attribute ("library-manufacturer", uri_info->module_info->manufacturer_id, result, &first); - } - - if (uri_info->token_info) { - build_string_attribute ("model", uri_info->token_info->model, result, &first); - build_string_attribute ("manufacturer", uri_info->token_info->manufacturer_id, result, &first); - build_string_attribute ("serial", uri_info->token_info->serial_number, result, &first); - build_string_attribute ("token", uri_info->token_info->label, result, &first); - } - - if (uri_info->attributes) { - if (gck_attributes_find_string (uri_info->attributes, CKA_LABEL, &value)) { - build_string_attribute ("object", value, result, &first); - g_free (value); - } - if (gck_attributes_find_ulong (uri_info->attributes, CKA_CLASS, &klass)) { - if (klass == CKO_CERTIFICATE) - build_string_attribute ("objecttype", "cert", result, &first); - else if (klass == CKO_PUBLIC_KEY) - build_string_attribute ("objecttype", "public", result, &first); - else if (klass == CKO_PRIVATE_KEY) - build_string_attribute ("objecttype", "private", result, &first); - else if (klass == CKO_SECRET_KEY) - build_string_attribute ("objecttype", "secretkey", result, &first); - else if (klass == CKO_DATA) - build_string_attribute ("objecttype", "data", result, &first); + P11KitUri *p11_uri = 0; + gchar *string; + int res; + guint i; + + g_return_val_if_fail (uri_data, NULL); + + p11_uri = p11_kit_uri_new (); + + if ((flags & GCK_URI_CONTEXT_MODULE) == GCK_URI_CONTEXT_MODULE && uri_data->module_info) + _gck_module_info_to_pkcs11 (uri_data->module_info, + p11_kit_uri_get_module_info (p11_uri)); + if ((flags & GCK_URI_CONTEXT_TOKEN) == GCK_URI_CONTEXT_TOKEN && uri_data->token_info) + _gck_token_info_to_pkcs11 (uri_data->token_info, + p11_kit_uri_get_token_info (p11_uri)); + if ((flags & GCK_URI_CONTEXT_OBJECT) == GCK_URI_CONTEXT_OBJECT && uri_data->attributes) { + for (i = 0; i < gck_attributes_count (uri_data->attributes); ++i) { + attr = gck_attributes_at (uri_data->attributes, i); + res = p11_kit_uri_set_attribute (p11_uri, (CK_ATTRIBUTE_PTR)attr); + if (res == P11_KIT_URI_NO_MEMORY) + g_error ("failed to allocate memory in p11_kit_uri_set_attribute()"); + else if (res != P11_KIT_URI_NOT_FOUND && res != P11_KIT_URI_OK) + g_return_val_if_reached (NULL); } - attr = gck_attributes_find (uri_info->attributes, CKA_ID); - if (attr != NULL) - build_binary_attribute ("id", attr->value, attr->length, result, &first); } - return g_string_free (result, FALSE); + res = p11_kit_uri_format (p11_uri, flags & GCK_URI_CONTEXT_ANY, &string); + if (res == P11_KIT_URI_NO_MEMORY) + g_error ("failed to allocate memory in p11_kit_uri_format()"); + else if (res != P11_KIT_URI_OK) + g_return_val_if_reached (NULL); + + p11_kit_uri_free (p11_uri); + return string; } /** - * gck_uri_info_free: - * @uri_info: URI info to free. + * gck_uri_data_free: + * @uri_data: URI data to free. * - * Free a #GckUriInfo. + * Free a #GckUriData. */ void -gck_uri_info_free (GckUriInfo *uri_info) +gck_uri_data_free (GckUriData *uri_data) { - if (uri_info) { - if (uri_info->attributes) - gck_attributes_unref (uri_info->attributes); - if (uri_info->module_info) - gck_module_info_free (uri_info->module_info); - if (uri_info->token_info) - gck_token_info_free (uri_info->token_info); - g_slice_free (GckUriInfo, uri_info); + if (uri_data) { + if (uri_data->attributes) + gck_attributes_unref (uri_data->attributes); + if (uri_data->module_info) + gck_module_info_free (uri_data->module_info); + if (uri_data->token_info) + gck_token_info_free (uri_data->token_info); + g_slice_free (GckUriData, uri_data); } } diff --git a/gck/gck.h b/gck/gck.h index 61bd780..4679526 100644 --- a/gck/gck.h +++ b/gck/gck.h @@ -56,7 +56,12 @@ void gck_list_unref_free (GList *reflist); const gchar* gck_message_from_rv (CK_RV rv); -gchar* gck_string_from_chars (const guchar *data, gsize max); +gboolean gck_string_to_chars (guchar *data, + gsize max, + const gchar *string); + +gchar* gck_string_from_chars (const guchar *data, + gsize max); typedef gpointer (*GckAllocator) (gpointer data, gsize length); @@ -292,11 +297,10 @@ struct _GckModuleClass { GType gck_module_get_type (void) G_GNUC_CONST; GckModule* gck_module_new (CK_FUNCTION_LIST_PTR funcs, - guint reserved_options); + guint flags); GckModule* gck_module_initialize (const gchar *path, - gpointer reserved, - guint reserved_options, + guint flags, GError **error); gboolean gck_module_equal (gconstpointer module1, @@ -313,9 +317,7 @@ GckModuleInfo* gck_module_get_info (GckModule *self); GList* gck_module_get_slots (GckModule *self, gboolean token_present); -gchar** gck_modules_list_registered_paths (GError **error); - -GList* gck_modules_initialize_registered (guint reserved_options); +GList* gck_modules_initialize_registered (guint flags); GList* gck_modules_get_slots (GList *modules, gboolean token_present); @@ -1114,19 +1116,24 @@ GckAttributes* gck_object_get_template_finish (GckObject *self, */ enum { - GCK_URI_BAD_PREFIX = 1, - GCK_URI_BAD_ENCODING = 2, - GCK_URI_BAD_SYNTAX = 3 + GCK_URI_BAD_SCHEME = 1, + GCK_URI_BAD_ENCODING, + GCK_URI_BAD_SYNTAX, + GCK_URI_BAD_VERSION, + GCK_URI_NOT_FOUND }; +#define GCK_URI_BAD_PREFIX GCK_URI_BAD_SCHEME + +/* WARNING: Don't modify these without syncing with p11-kit */ typedef enum { - GCK_URI_PARSE_MODULE = (1 << 1), - GCK_URI_PARSE_TOKEN = (1 << 2) | GCK_URI_PARSE_MODULE, - GCK_URI_PARSE_OBJECT = (1 << 3) | GCK_URI_PARSE_TOKEN, - GCK_URI_PARSE_ANY = 0xFFFFFFFF, -} GckUriParseFlags; + GCK_URI_CONTEXT_MODULE = (1 << 1), + GCK_URI_CONTEXT_TOKEN = (1 << 2) | GCK_URI_CONTEXT_MODULE, + GCK_URI_CONTEXT_OBJECT = (1 << 3) | GCK_URI_CONTEXT_TOKEN, + GCK_URI_CONTEXT_ANY = 0x00000FFF, +} GckUriFlags; -typedef struct _GckUriInfo { +typedef struct _GckUriData { gboolean any_unrecognized; GckModuleInfo *module_info; GckTokenInfo *token_info; @@ -1134,19 +1141,22 @@ typedef struct _GckUriInfo { /*< private >*/ gpointer dummy[4]; -} GckUriInfo; +} GckUriData; #define GCK_URI_ERROR (gck_uri_get_error_quark ()) GQuark gck_uri_get_error_quark (void); -gchar* gck_uri_build (GckUriInfo *uri_info); +GckUriData* gck_uri_data_new (void); + +gchar* gck_uri_build (GckUriData *uri_data, + GckUriFlags flags); -GckUriInfo* gck_uri_parse (const gchar *uri, - GckUriParseFlags flags, +GckUriData* gck_uri_parse (const gchar *string, + GckUriFlags flags, GError **error); -void gck_uri_info_free (GckUriInfo *uri_info); +void gck_uri_data_free (GckUriData *uri_data); G_END_DECLS diff --git a/gck/gck.pc.in b/gck/gck.pc.in index 9d1e6fa..ef6f5a4 100644 --- a/gck/gck.pc.in +++ b/gck/gck.pc.in @@ -9,6 +9,6 @@ sysconfdir=@sysconfdir@ Name: gck Description: GObject bindings for PKCS#11 Version: @VERSION@ -Requires: glib-2.0 +Requires: glib-2.0 p11-kit-1 Libs: -L${libdir} -lgck Cflags: -I${includedir}/gck diff --git a/gck/tests/test-gck-crypto.c b/gck/tests/test-gck-crypto.c index 208673f..300b132 100644 --- a/gck/tests/test-gck-crypto.c +++ b/gck/tests/test-gck-crypto.c @@ -57,7 +57,7 @@ setup (Test *test, gconstpointer unused) GckSlot *slot; /* Successful load */ - test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", NULL, 0, &err); + test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", 0, &err); g_assert_no_error (err); g_assert (GCK_IS_MODULE (test->module)); diff --git a/gck/tests/test-gck-enumerator.c b/gck/tests/test-gck-enumerator.c index 83458f0..e9fcaa6 100644 --- a/gck/tests/test-gck-enumerator.c +++ b/gck/tests/test-gck-enumerator.c @@ -48,7 +48,7 @@ setup (Test *test, gconstpointer unused) GError *err = NULL; /* Successful load */ - test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", NULL, 0, &err); + test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", 0, &err); g_assert_no_error (err); g_assert (GCK_IS_MODULE (test->module)); @@ -68,11 +68,11 @@ teardown (Test *test, gconstpointer unused) static void test_create (Test *test, gconstpointer unused) { - GckUriInfo *uri_info; + GckUriData *uri_data; GckEnumerator *en; - uri_info = _gck_uri_info_new (); - en = _gck_enumerator_new (test->modules, 0, uri_info); + uri_data = gck_uri_data_new (); + en = _gck_enumerator_new (test->modules, 0, uri_data); g_assert (GCK_IS_ENUMERATOR (en)); g_object_unref (en); } @@ -80,13 +80,13 @@ test_create (Test *test, gconstpointer unused) static void test_create_slots (Test *test, gconstpointer unused) { - GckUriInfo *uri_info; + GckUriData *uri_data; GckEnumerator *en; GList *slots; - uri_info = _gck_uri_info_new (); + uri_data = gck_uri_data_new (); slots = gck_module_get_slots (test->module, FALSE); - en = _gck_enumerator_new (slots, 0, uri_info); + en = _gck_enumerator_new (slots, 0, uri_data); g_assert (GCK_IS_ENUMERATOR (en)); g_object_unref (en); gck_list_unref_free (slots); @@ -95,13 +95,13 @@ test_create_slots (Test *test, gconstpointer unused) static void test_next (Test *test, gconstpointer unused) { - GckUriInfo *uri_info; + GckUriData *uri_data; GError *error = NULL; GckEnumerator *en; GckObject *obj; - uri_info = _gck_uri_info_new (); - en = _gck_enumerator_new (test->modules, 0, uri_info); + uri_data = gck_uri_data_new (); + en = _gck_enumerator_new (test->modules, 0, uri_data); g_assert (GCK_IS_ENUMERATOR (en)); obj = gck_enumerator_next (en, NULL, &error); @@ -114,15 +114,15 @@ test_next (Test *test, gconstpointer unused) static void test_next_slots (Test *test, gconstpointer unused) { - GckUriInfo *uri_info; + GckUriData *uri_data; GError *error = NULL; GList *slots = NULL; GckEnumerator *en; GckObject *obj; - uri_info = _gck_uri_info_new (); + uri_data = gck_uri_data_new (); slots = gck_module_get_slots (test->module, FALSE); - en = _gck_enumerator_new (slots, 0, uri_info); + en = _gck_enumerator_new (slots, 0, uri_data); g_assert (GCK_IS_ENUMERATOR (en)); obj = gck_enumerator_next (en, NULL, &error); @@ -136,13 +136,13 @@ test_next_slots (Test *test, gconstpointer unused) static void test_next_and_resume (Test *test, gconstpointer unused) { - GckUriInfo *uri_info; + GckUriData *uri_data; GError *error = NULL; GckEnumerator *en; GckObject *obj, *obj2; - uri_info = _gck_uri_info_new (); - en = _gck_enumerator_new (test->modules, 0, uri_info); + uri_data = gck_uri_data_new (); + en = _gck_enumerator_new (test->modules, 0, uri_data); g_assert (GCK_IS_ENUMERATOR (en)); obj = gck_enumerator_next (en, NULL, &error); @@ -163,13 +163,13 @@ test_next_and_resume (Test *test, gconstpointer unused) static void test_next_n (Test *test, gconstpointer unused) { - GckUriInfo *uri_info; + GckUriData *uri_data; GError *error = NULL; GckEnumerator *en; GList *objects, *l; - uri_info = _gck_uri_info_new (); - en = _gck_enumerator_new (test->modules, 0, uri_info); + uri_data = gck_uri_data_new (); + en = _gck_enumerator_new (test->modules, 0, uri_data); g_assert (GCK_IS_ENUMERATOR (en)); objects = gck_enumerator_next_n (en, -1, NULL, &error); @@ -193,14 +193,14 @@ fetch_async_result (GObject *source, GAsyncResult *result, gpointer user_data) static void test_next_async (Test *test, gconstpointer unused) { - GckUriInfo *uri_info; + GckUriData *uri_data; GAsyncResult *result = NULL; GError *error = NULL; GckEnumerator *en; GList *objects, *l; - uri_info = _gck_uri_info_new (); - en = _gck_enumerator_new (test->modules, 0, uri_info); + uri_data = gck_uri_data_new (); + en = _gck_enumerator_new (test->modules, 0, uri_data); g_assert (GCK_IS_ENUMERATOR (en)); gck_enumerator_next_async (en, -1, NULL, fetch_async_result, &result); @@ -221,15 +221,15 @@ test_next_async (Test *test, gconstpointer unused) static void test_attributes (Test *test, gconstpointer unused) { - GckUriInfo *uri_info; + GckUriData *uri_data; GError *error = NULL; GckEnumerator *en; GList *objects; - uri_info = _gck_uri_info_new (); - uri_info->attributes = gck_attributes_new (); - gck_attributes_add_string (uri_info->attributes, CKA_LABEL, "Private Capitalize Key"); - en = _gck_enumerator_new (test->modules, 0, uri_info); + uri_data = gck_uri_data_new (); + uri_data->attributes = gck_attributes_new (); + gck_attributes_add_string (uri_data->attributes, CKA_LABEL, "Private Capitalize Key"); + en = _gck_enumerator_new (test->modules, 0, uri_data); g_assert (GCK_IS_ENUMERATOR (en)); objects = gck_enumerator_next_n (en, -1, NULL, &error); @@ -244,15 +244,15 @@ test_attributes (Test *test, gconstpointer unused) static void test_token_match (Test *test, gconstpointer unused) { - GckUriInfo *uri_info; + GckUriData *uri_data; GError *error = NULL; GckEnumerator *en; GList *objects; - uri_info = _gck_uri_info_new (); - uri_info->token_info = g_new0 (GckTokenInfo, 1); - uri_info->token_info->label = g_strdup ("Invalid token name"); - en = _gck_enumerator_new (test->modules, 0, uri_info); + uri_data = gck_uri_data_new (); + uri_data->token_info = g_new0 (GckTokenInfo, 1); + uri_data->token_info->label = g_strdup ("Invalid token name"); + en = _gck_enumerator_new (test->modules, 0, uri_data); g_assert (GCK_IS_ENUMERATOR (en)); objects = gck_enumerator_next_n (en, -1, NULL, &error); diff --git a/gck/tests/test-gck-module.c b/gck/tests/test-gck-module.c index 4e6a337..5a6d524 100644 --- a/gck/tests/test-gck-module.c +++ b/gck/tests/test-gck-module.c @@ -40,7 +40,7 @@ setup (Test *test, gconstpointer unused) GError *err = NULL; /* Successful load */ - test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", NULL, 0, &err); + test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", 0, &err); g_assert_no_error (err); g_assert (test->module); } @@ -58,14 +58,14 @@ test_invalid_modules (Test *test, gconstpointer unused) GError *err = NULL; /* Shouldn't be able to load modules */ - invalid = gck_module_initialize ("blah-blah-non-existant", NULL, 0, &err); + invalid = gck_module_initialize ("blah-blah-non-existant", 0, &err); g_assert (invalid == NULL); g_assert_error (err, GCK_ERROR, CKR_GCK_MODULE_PROBLEM); g_clear_error (&err); /* Shouldn't be able to load any file successfully */ - invalid = gck_module_initialize ("/usr/lib/libm.so", NULL, 0, &err); + invalid = gck_module_initialize ("/usr/lib/libm.so", 0, &err); g_assert (invalid == NULL); g_assert_error (err, GCK_ERROR, CKR_GCK_MODULE_PROBLEM); } diff --git a/gck/tests/test-gck-modules.c b/gck/tests/test-gck-modules.c index 3b38d05..d3105fd 100644 --- a/gck/tests/test-gck-modules.c +++ b/gck/tests/test-gck-modules.c @@ -48,7 +48,7 @@ setup (Test *test, gconstpointer unused) GError *err = NULL; /* Successful load */ - module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", NULL, 0, &err); + module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", 0, &err); g_assert_no_error (err); g_assert (GCK_IS_MODULE (module)); diff --git a/gck/tests/test-gck-object.c b/gck/tests/test-gck-object.c index 672a102..b2a19ff 100644 --- a/gck/tests/test-gck-object.c +++ b/gck/tests/test-gck-object.c @@ -50,7 +50,7 @@ setup (Test *test, gconstpointer unused) GList *slots; /* Successful load */ - test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", NULL, 0, &err); + test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", 0, &err); g_assert_no_error (err); g_assert (GCK_IS_MODULE (test->module)); diff --git a/gck/tests/test-gck-session.c b/gck/tests/test-gck-session.c index 356819b..c401645 100644 --- a/gck/tests/test-gck-session.c +++ b/gck/tests/test-gck-session.c @@ -48,7 +48,7 @@ setup (Test *test, gconstpointer unused) GList *slots; /* Successful load */ - test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", NULL, 0, &err); + test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", 0, &err); g_assert_no_error (err); g_assert (GCK_IS_MODULE (test->module)); diff --git a/gck/tests/test-gck-slot.c b/gck/tests/test-gck-slot.c index 8a61479..d03db98 100644 --- a/gck/tests/test-gck-slot.c +++ b/gck/tests/test-gck-slot.c @@ -43,7 +43,7 @@ setup (Test *test, gconstpointer unused) GList *slots; /* Successful load */ - test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", NULL, 0, &err); + test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", 0, &err); g_assert_no_error (err); g_assert (GCK_IS_MODULE (test->module)); diff --git a/gck/tests/test-gck-uri.c b/gck/tests/test-gck-uri.c index 8483ed9..732f2da 100644 --- a/gck/tests/test-gck-uri.c +++ b/gck/tests/test-gck-uri.c @@ -36,30 +36,30 @@ static void test_parse (void) { GError *error = NULL; - GckUriInfo *uri_info; + GckUriData *uri_data; - uri_info = gck_uri_parse ("pkcs11:", GCK_URI_PARSE_MODULE, &error); - g_assert (uri_info != NULL); + uri_data = gck_uri_parse ("pkcs11:", GCK_URI_CONTEXT_MODULE, &error); + g_assert (uri_data != NULL); g_assert_no_error (error); - g_assert (uri_info->attributes == NULL); - g_assert (uri_info->token_info == NULL); + g_assert (uri_data->attributes == NULL); + g_assert (uri_data->token_info == NULL); - g_assert (uri_info->module_info != NULL); - g_assert (uri_info->module_info->library_description == NULL); - g_assert (uri_info->module_info->manufacturer_id == NULL); + g_assert (uri_data->module_info != NULL); + g_assert (uri_data->module_info->library_description == NULL); + g_assert (uri_data->module_info->manufacturer_id == NULL); - gck_uri_info_free (uri_info); + gck_uri_data_free (uri_data); } static void test_parse_bad_scheme (void) { GError *error = NULL; - GckUriInfo *uri_info; + GckUriData *uri_data; - uri_info = gck_uri_parse ("http:\\example.com\test", GCK_URI_PARSE_ANY, &error); - g_assert (uri_info == NULL); + uri_data = gck_uri_parse ("http:\\example.com\test", GCK_URI_CONTEXT_ANY, &error); + g_assert (uri_data == NULL); g_assert_error (error, GCK_URI_ERROR, GCK_URI_BAD_PREFIX); g_error_free (error); } @@ -68,45 +68,45 @@ static void test_parse_with_label (void) { GError *error = NULL; - GckUriInfo *uri_info; + GckUriData *uri_data; gchar *value; - uri_info = gck_uri_parse ("pkcs11:object=Test%20Label", GCK_URI_PARSE_ANY, &error); - g_assert (uri_info != NULL); - g_assert (uri_info->attributes != NULL); + uri_data = gck_uri_parse ("pkcs11:object=Test%20Label", GCK_URI_CONTEXT_ANY, &error); + g_assert (uri_data != NULL); + g_assert (uri_data->attributes != NULL); - if (!gck_attributes_find_string (uri_info->attributes, CKA_LABEL, &value)) + if (!gck_attributes_find_string (uri_data->attributes, CKA_LABEL, &value)) g_assert_not_reached (); g_assert_cmpstr (value, ==, "Test Label"); g_free (value); - gck_uri_info_free (uri_info); + gck_uri_data_free (uri_data); } static void test_parse_with_label_and_klass (void) { GError *error = NULL; - GckUriInfo *uri_info; + GckUriData *uri_data; gchar *value; gulong klass; - uri_info = gck_uri_parse ("pkcs11:object=Test%20Label;objecttype=cert", GCK_URI_PARSE_ANY, &error); - g_assert (uri_info); - g_assert (uri_info->attributes); + uri_data = gck_uri_parse ("pkcs11:object=Test%20Label;objecttype=cert", GCK_URI_CONTEXT_ANY, &error); + g_assert (uri_data); + g_assert (uri_data->attributes); - if (!gck_attributes_find_string (uri_info->attributes, CKA_LABEL, &value)) + if (!gck_attributes_find_string (uri_data->attributes, CKA_LABEL, &value)) g_assert_not_reached (); - if (!gck_attributes_find_ulong (uri_info->attributes, CKA_CLASS, &klass)) + if (!gck_attributes_find_ulong (uri_data->attributes, CKA_CLASS, &klass)) g_assert_not_reached (); g_assert_cmpstr (value, ==, "Test Label"); g_assert (klass == CKO_CERTIFICATE); g_free (value); - gck_uri_info_free (uri_info); + gck_uri_data_free (uri_data); } static void @@ -114,29 +114,29 @@ test_parse_with_id (void) { GError *error = NULL; GckAttribute *attr; - GckUriInfo *uri_info; + GckUriData *uri_data; - uri_info = gck_uri_parse ("pkcs11:id=54:45:53:54", GCK_URI_PARSE_OBJECT, &error); - g_assert (uri_info != NULL); - g_assert (uri_info->attributes != NULL); + uri_data = gck_uri_parse ("pkcs11:id=%54%45%53%54%00", GCK_URI_CONTEXT_OBJECT, &error); + g_assert (uri_data != NULL); + g_assert (uri_data->attributes != NULL); - attr = gck_attributes_find (uri_info->attributes, CKA_ID); + attr = gck_attributes_find (uri_data->attributes, CKA_ID); g_assert (attr); g_assert (attr->value); - g_assert (attr->length == 4); - g_assert (memcmp (attr->value, "TEST", 4) == 0); + g_assert (attr->length == 5); + g_assert (memcmp (attr->value, "TEST", 5) == 0); - gck_uri_info_free (uri_info); + gck_uri_data_free (uri_data); } static void test_parse_with_bad_string_encoding (void) { GError *error = NULL; - GckUriInfo *uri_info; + GckUriData *uri_data; - uri_info = gck_uri_parse ("pkcs11:object=Test%", GCK_URI_PARSE_OBJECT, &error); - g_assert (uri_info == NULL); + uri_data = gck_uri_parse ("pkcs11:object=Test%", GCK_URI_CONTEXT_OBJECT, &error); + g_assert (uri_data == NULL); g_assert_error (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING); g_error_free (error); } @@ -145,9 +145,9 @@ static void test_parse_with_bad_binary_encoding (void) { GError *error = NULL; - GckUriInfo *uri_info; - uri_info = gck_uri_parse ("pkcs11:id=xxxxx", GCK_URI_PARSE_ANY, &error); - g_assert (!uri_info); + GckUriData *uri_data; + uri_data = gck_uri_parse ("pkcs11:id=%%", GCK_URI_CONTEXT_ANY, &error); + g_assert (!uri_data); g_assert_error (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING); g_error_free (error); } @@ -156,28 +156,28 @@ static void test_parse_with_token (void) { GError *error = NULL; - GckUriInfo *uri_info = NULL; - - uri_info = gck_uri_parse ("pkcs11:token=Token%20Label;serial=3333;model=Deluxe;manufacturer=Me", - GCK_URI_PARSE_TOKEN, &error); - - g_assert (uri_info); - g_assert (uri_info->token_info); - g_assert_cmpstr (uri_info->token_info->label, ==, "Token Label"); - g_assert_cmpstr (uri_info->token_info->serial_number, ==, "3333"); - g_assert_cmpstr (uri_info->token_info->model, ==, "Deluxe"); - g_assert_cmpstr (uri_info->token_info->manufacturer_id, ==, "Me"); - gck_uri_info_free (uri_info); + GckUriData *uri_data = NULL; + + uri_data = gck_uri_parse ("pkcs11:token=Token%20Label;serial=3333;model=Deluxe;manufacturer=Me", + GCK_URI_CONTEXT_TOKEN, &error); + + g_assert (uri_data); + g_assert (uri_data->token_info); + g_assert_cmpstr (uri_data->token_info->label, ==, "Token Label"); + g_assert_cmpstr (uri_data->token_info->serial_number, ==, "3333"); + g_assert_cmpstr (uri_data->token_info->model, ==, "Deluxe"); + g_assert_cmpstr (uri_data->token_info->manufacturer_id, ==, "Me"); + gck_uri_data_free (uri_data); } static void test_parse_with_token_bad_encoding (void) { GError *error = NULL; - GckUriInfo *uri_info; + GckUriData *uri_data; - uri_info = gck_uri_parse ("pkcs11:token=Token%", GCK_URI_PARSE_TOKEN, &error); - g_assert (!uri_info); + uri_data = gck_uri_parse ("pkcs11:token=Token%", GCK_URI_CONTEXT_TOKEN, &error); + g_assert (!uri_data); g_assert_error (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING); g_error_free (error); } @@ -186,10 +186,10 @@ static void test_parse_with_bad_syntax (void) { GError *error = NULL; - GckUriInfo *uri_info; + GckUriData *uri_data; - uri_info = gck_uri_parse ("pkcs11:token", GCK_URI_PARSE_ANY, &error); - g_assert (uri_info == NULL); + uri_data = gck_uri_parse ("pkcs11:token", GCK_URI_CONTEXT_ANY, &error); + g_assert (uri_data == NULL); g_assert (g_error_matches (error, GCK_URI_ERROR, GCK_URI_BAD_SYNTAX)); g_error_free (error); } @@ -198,26 +198,26 @@ static void test_parse_with_library (void) { GError *error = NULL; - GckUriInfo *uri_info = NULL; + GckUriData *uri_data = NULL; - uri_info = gck_uri_parse ("pkcs11:library-description=The%20Library;library-manufacturer=Me", - GCK_URI_PARSE_MODULE, &error); + uri_data = gck_uri_parse ("pkcs11:library-description=The%20Library;library-manufacturer=Me", + GCK_URI_CONTEXT_MODULE, &error); - g_assert (uri_info); - g_assert (uri_info->module_info); - g_assert_cmpstr (uri_info->module_info->manufacturer_id, ==, "Me"); - g_assert_cmpstr (uri_info->module_info->library_description, ==, "The Library"); - gck_uri_info_free (uri_info); + g_assert (uri_data); + g_assert (uri_data->module_info); + g_assert_cmpstr (uri_data->module_info->manufacturer_id, ==, "Me"); + g_assert_cmpstr (uri_data->module_info->library_description, ==, "The Library"); + gck_uri_data_free (uri_data); } static void test_parse_with_library_bad_encoding (void) { GError *error = NULL; - GckUriInfo *uri_info; + GckUriData *uri_data; - uri_info = gck_uri_parse ("pkcs11:library-description=Library%", GCK_URI_PARSE_MODULE, &error); - g_assert (!uri_info); + uri_data = gck_uri_parse ("pkcs11:library-description=Library%", GCK_URI_CONTEXT_MODULE, &error); + g_assert (!uri_data); g_assert_error (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING); g_error_free (error); } @@ -225,11 +225,11 @@ test_parse_with_library_bad_encoding (void) static void test_build_empty (void) { - GckUriInfo uri_info; + GckUriData uri_data; gchar *uri; - memset (&uri_info, 0, sizeof (uri_info)); - uri = gck_uri_build (&uri_info); + memset (&uri_data, 0, sizeof (uri_data)); + uri = gck_uri_build (&uri_data, 0); g_assert_cmpstr (uri, ==, "pkcs11:"); g_free (uri); } @@ -238,27 +238,27 @@ static void test_build_with_token_info (void) { gchar *uri = NULL; - GckUriInfo uri_info; - GckUriInfo *check; + GckUriData uri_data; + GckUriData *check; - memset (&uri_info, 0, sizeof (uri_info)); - uri_info.token_info = g_new0 (GckTokenInfo, 1); - uri_info.token_info->label = g_strdup ("The Label"); - uri_info.token_info->serial_number = g_strdup ("44444"); - uri_info.token_info->manufacturer_id = g_strdup ("Me"); - uri_info.token_info->model = g_strdup ("Deluxe"); + memset (&uri_data, 0, sizeof (uri_data)); + uri_data.token_info = g_new0 (GckTokenInfo, 1); + uri_data.token_info->label = g_strdup ("The Label"); + uri_data.token_info->serial_number = g_strdup ("44444"); + uri_data.token_info->manufacturer_id = g_strdup ("Me"); + uri_data.token_info->model = g_strdup ("Deluxe"); - uri = gck_uri_build (&uri_info); + uri = gck_uri_build (&uri_data, GCK_URI_CONTEXT_TOKEN); g_assert (uri); - check = gck_uri_parse (uri, GCK_URI_PARSE_TOKEN, NULL); + check = gck_uri_parse (uri, GCK_URI_CONTEXT_TOKEN, NULL); g_assert (check); g_assert (check->token_info); - g_assert (_gck_token_info_match (uri_info.token_info, check->token_info)); + g_assert (_gck_token_info_match (uri_data.token_info, check->token_info)); - gck_token_info_free (uri_info.token_info); - gck_uri_info_free (check); + gck_token_info_free (uri_data.token_info); + gck_uri_data_free (check); g_assert (g_str_has_prefix (uri, "pkcs11:")); g_assert (strstr (uri, "token=The%20Label")); @@ -273,20 +273,20 @@ static void test_build_with_token_null_info (void) { gchar *uri = NULL; - GckUriInfo uri_info; + GckUriData uri_data; - memset (&uri_info, 0, sizeof (uri_info)); - uri_info.token_info = g_new0 (GckTokenInfo, 1); - uri_info.token_info->label = g_strdup ("The Label"); + memset (&uri_data, 0, sizeof (uri_data)); + uri_data.token_info = g_new0 (GckTokenInfo, 1); + uri_data.token_info->label = g_strdup ("The Label"); - uri = gck_uri_build (&uri_info); + uri = gck_uri_build (&uri_data, GCK_URI_CONTEXT_TOKEN); g_assert (uri); g_assert (g_str_has_prefix (uri, "pkcs11:")); g_assert (strstr (uri, "token=The%20Label")); g_assert (!strstr (uri, "serial=")); - gck_token_info_free (uri_info.token_info); + gck_token_info_free (uri_data.token_info); g_free (uri); } @@ -294,21 +294,21 @@ static void test_build_with_token_empty_info (void) { gchar *uri = NULL; - GckUriInfo uri_info; + GckUriData uri_data; - memset (&uri_info, 0, sizeof (uri_info)); - uri_info.token_info = g_new0 (GckTokenInfo, 1); - uri_info.token_info->label = g_strdup ("The Label"); - uri_info.token_info->serial_number = g_strdup (""); + memset (&uri_data, 0, sizeof (uri_data)); + uri_data.token_info = g_new0 (GckTokenInfo, 1); + uri_data.token_info->label = g_strdup ("The Label"); + uri_data.token_info->serial_number = g_strdup (""); - uri = gck_uri_build (&uri_info); + uri = gck_uri_build (&uri_data, GCK_URI_CONTEXT_TOKEN); g_assert (uri); g_assert (g_str_has_prefix (uri, "pkcs11:")); g_assert (strstr (uri, "token=The%20Label")); g_assert (strstr (uri, "serial=")); - gck_token_info_free (uri_info.token_info); + gck_token_info_free (uri_data.token_info); g_free (uri); } @@ -316,24 +316,24 @@ static void test_build_with_attributes (void) { gchar *uri = NULL; - GckUriInfo uri_info; - GckUriInfo *check; + GckUriData uri_data; + GckUriData *check; gchar *string; gulong value; GckAttribute *attr; - memset (&uri_info, 0, sizeof (uri_info)); - uri_info.attributes = gck_attributes_new (); - gck_attributes_add_string (uri_info.attributes, CKA_LABEL, "The Label"); - gck_attributes_add_ulong (uri_info.attributes, CKA_CLASS, CKO_DATA); - gck_attributes_add_data (uri_info.attributes, CKA_ID, "TEST", 4); + memset (&uri_data, 0, sizeof (uri_data)); + uri_data.attributes = gck_attributes_new (); + gck_attributes_add_string (uri_data.attributes, CKA_LABEL, "The Label"); + gck_attributes_add_ulong (uri_data.attributes, CKA_CLASS, CKO_DATA); + gck_attributes_add_data (uri_data.attributes, CKA_ID, "TEST", 5); - uri = gck_uri_build (&uri_info); + uri = gck_uri_build (&uri_data, GCK_URI_CONTEXT_OBJECT); g_assert (uri); - gck_attributes_unref (uri_info.attributes); + gck_attributes_unref (uri_data.attributes); - check = gck_uri_parse (uri, GCK_URI_PARSE_ANY, NULL); + check = gck_uri_parse (uri, GCK_URI_CONTEXT_ANY, NULL); g_assert (check); g_assert (check->attributes); @@ -347,15 +347,15 @@ test_build_with_attributes (void) attr = gck_attributes_find (check->attributes, CKA_ID); g_assert (attr); - g_assert (attr->length == 4); - g_assert (memcmp (attr->value, "TEST", 4) == 0); + g_assert (attr->length == 5); + g_assert (memcmp (attr->value, "TEST", 5) == 0); - gck_uri_info_free (check); + gck_uri_data_free (check); g_assert (g_str_has_prefix (uri, "pkcs11:")); g_assert (strstr (uri, "object=The%20Label")); g_assert (strstr (uri, "objecttype=data")); - g_assert (strstr (uri, "id=54:45:53:54")); + g_assert (strstr (uri, "id=TEST%00")); g_free (uri); } @@ -363,148 +363,148 @@ test_build_with_attributes (void) static void test_parse_private_key (void) { - GckUriInfo *uri_info; + GckUriData *uri_data; GError *error = NULL; gulong klass; - uri_info = gck_uri_parse ("pkcs11:objecttype=private", GCK_URI_PARSE_OBJECT, &error); - g_assert (uri_info); + uri_data = gck_uri_parse ("pkcs11:objecttype=private", GCK_URI_CONTEXT_OBJECT, &error); + g_assert (uri_data); g_assert_no_error (error); - g_assert (uri_info->attributes); - if (!gck_attributes_find_ulong (uri_info->attributes, CKA_CLASS, &klass)) + g_assert (uri_data->attributes); + if (!gck_attributes_find_ulong (uri_data->attributes, CKA_CLASS, &klass)) g_assert_not_reached (); gck_assert_cmpulong (klass, ==, CKO_PRIVATE_KEY); - gck_uri_info_free (uri_info); + gck_uri_data_free (uri_data); } static void test_parse_secret_key (void) { - GckUriInfo *uri_info; + GckUriData *uri_data; GError *error = NULL; gulong klass; - uri_info = gck_uri_parse ("pkcs11:objecttype=secretkey", GCK_URI_PARSE_OBJECT, &error); - g_assert (uri_info); + uri_data = gck_uri_parse ("pkcs11:objecttype=secretkey", GCK_URI_CONTEXT_OBJECT, &error); + g_assert (uri_data); g_assert_no_error (error); - g_assert (uri_info->attributes); - if (!gck_attributes_find_ulong (uri_info->attributes, CKA_CLASS, &klass)) + g_assert (uri_data->attributes); + if (!gck_attributes_find_ulong (uri_data->attributes, CKA_CLASS, &klass)) g_assert_not_reached (); gck_assert_cmpulong (klass, ==, CKO_SECRET_KEY); - gck_uri_info_free (uri_info); + gck_uri_data_free (uri_data); } static void test_parse_unknown_objecttype (void) { - GckUriInfo *uri_info; + GckUriData *uri_data; GError *error = NULL; gulong klass; - uri_info = gck_uri_parse ("pkcs11:objecttype=unknown", GCK_URI_PARSE_OBJECT, &error); - g_assert (uri_info); + uri_data = gck_uri_parse ("pkcs11:objecttype=unknown", GCK_URI_CONTEXT_OBJECT, &error); + g_assert (uri_data); g_assert_no_error (error); - g_assert (uri_info->attributes); - g_assert (uri_info->any_unrecognized == TRUE); - if (gck_attributes_find_ulong (uri_info->attributes, CKA_CLASS, &klass)) + g_assert (uri_data->attributes); + g_assert (uri_data->any_unrecognized == TRUE); + if (gck_attributes_find_ulong (uri_data->attributes, CKA_CLASS, &klass)) g_assert_not_reached (); - gck_uri_info_free (uri_info); + gck_uri_data_free (uri_data); } static void test_build_objecttype_cert (void) { - GckUriInfo *uri_info; + GckUriData *uri_data; gchar *uri; - uri_info = _gck_uri_info_new (); - uri_info->attributes = gck_attributes_new (); - gck_attributes_add_ulong (uri_info->attributes, CKA_CLASS, CKO_CERTIFICATE); + uri_data = gck_uri_data_new (); + uri_data->attributes = gck_attributes_new (); + gck_attributes_add_ulong (uri_data->attributes, CKA_CLASS, CKO_CERTIFICATE); - uri = gck_uri_build (uri_info); + uri = gck_uri_build (uri_data, GCK_URI_CONTEXT_OBJECT); g_assert (uri); g_assert (strstr (uri, "objecttype=cert")); - gck_uri_info_free (uri_info); + gck_uri_data_free (uri_data); g_free (uri); } static void test_build_objecttype_private (void) { - GckUriInfo *uri_info; + GckUriData *uri_data; gchar *uri; - uri_info = _gck_uri_info_new (); - uri_info->attributes = gck_attributes_new (); - gck_attributes_add_ulong (uri_info->attributes, CKA_CLASS, CKO_PRIVATE_KEY); + uri_data = gck_uri_data_new (); + uri_data->attributes = gck_attributes_new (); + gck_attributes_add_ulong (uri_data->attributes, CKA_CLASS, CKO_PRIVATE_KEY); - uri = gck_uri_build (uri_info); + uri = gck_uri_build (uri_data, GCK_URI_CONTEXT_OBJECT); g_assert (uri); g_assert (strstr (uri, "objecttype=private")); - gck_uri_info_free (uri_info); + gck_uri_data_free (uri_data); g_free (uri); } static void test_build_objecttype_public (void) { - GckUriInfo *uri_info; + GckUriData *uri_data; gchar *uri; - uri_info = _gck_uri_info_new (); - uri_info->attributes = gck_attributes_new (); - gck_attributes_add_ulong (uri_info->attributes, CKA_CLASS, CKO_PUBLIC_KEY); + uri_data = gck_uri_data_new (); + uri_data->attributes = gck_attributes_new (); + gck_attributes_add_ulong (uri_data->attributes, CKA_CLASS, CKO_PUBLIC_KEY); - uri = gck_uri_build (uri_info); + uri = gck_uri_build (uri_data, GCK_URI_CONTEXT_OBJECT); g_assert (uri); g_assert (strstr (uri, "objecttype=public")); - gck_uri_info_free (uri_info); + gck_uri_data_free (uri_data); g_free (uri); } static void test_build_objecttype_secret (void) { - GckUriInfo *uri_info; + GckUriData *uri_data; gchar *uri; - uri_info = _gck_uri_info_new (); - uri_info->attributes = gck_attributes_new (); - gck_attributes_add_ulong (uri_info->attributes, CKA_CLASS, CKO_SECRET_KEY); + uri_data = gck_uri_data_new (); + uri_data->attributes = gck_attributes_new (); + gck_attributes_add_ulong (uri_data->attributes, CKA_CLASS, CKO_SECRET_KEY); - uri = gck_uri_build (uri_info); + uri = gck_uri_build (uri_data, GCK_URI_CONTEXT_OBJECT); g_assert (uri); g_assert (strstr (uri, "objecttype=secretkey")); - gck_uri_info_free (uri_info); + gck_uri_data_free (uri_data); g_free (uri); } static void test_build_with_library (void) { - GckUriInfo *uri_info; + GckUriData *uri_data; gchar *uri; - uri_info = _gck_uri_info_new (); - uri_info->module_info = g_new0 (GckModuleInfo, 1); - uri_info->module_info->library_description = g_strdup ("The Description"); + uri_data = gck_uri_data_new (); + uri_data->module_info = g_new0 (GckModuleInfo, 1); + uri_data->module_info->library_description = g_strdup ("The Description"); - uri = gck_uri_build (uri_info); + uri = gck_uri_build (uri_data, GCK_URI_CONTEXT_MODULE); g_assert (uri); g_assert (strstr (uri, "library-description=The%20Description")); - gck_uri_info_free (uri_info); + gck_uri_data_free (uri_data); g_free (uri); } diff --git a/gcr/Makefile.am b/gcr/Makefile.am index 24aa95e..880f5fc 100644 --- a/gcr/Makefile.am +++ b/gcr/Makefile.am @@ -63,7 +63,8 @@ INCLUDES = \ $(GOBJECT_CFLAGS) \ $(GLIB_CFLAGS) \ $(LIBGCRYPT_CFLAGS) \ - $(LIBTASN1_CFLAGS) + $(LIBTASN1_CFLAGS) \ + $(P11_KIT_CFLAGS) BUILT_SOURCES = \ gcr-marshal.c gcr-marshal.h @@ -129,7 +130,8 @@ libgcr@GCR_VERSION_SUFFIX@_la_LIBADD = \ $(GOBJECT_LIBS) \ $(GLIB_LIBS) \ $(LIBGCRYPT_LIBS) \ - $(GTK_LIBS) + $(GTK_LIBS) \ + $(P11_KIT_LIBS) noinst_LTLIBRARIES = $(TESTABLE_LIB) libgcr_testable_la_SOURCES = diff --git a/gcr/gcr-collection-model.c b/gcr/gcr-collection-model.c index 1192a37..1e99b58 100644 --- a/gcr/gcr-collection-model.c +++ b/gcr/gcr-collection-model.c @@ -45,8 +45,8 @@ * * Each row can have a selected state, which is represented by a boolean column. * The selected state can be toggled with gcr_collection_model_toggle_selected() - * or set with gcr_collection_model_set_selected() and retrieved with - * gcr_collection_model_get_selected(). + * or set with gcr_collection_model_set_selected_objects() and retrieved with + * gcr_collection_model_get_selected_objects(). * * To determine which object a row represents and vice versa, use the * gcr_collection_model_iter_for_object() or gcr_collection_model_object_for_iter() diff --git a/gcr/gcr-library.c b/gcr/gcr-library.c index acfcff3..c3e8b67 100644 --- a/gcr/gcr-library.c +++ b/gcr/gcr-library.c @@ -270,7 +270,7 @@ gcr_pkcs11_add_module (GckModule *module) /** * gcr_pkcs11_add_module_from_file: * @module_path: the full file path of the PKCS\#11 module - * @init_params: initialization string for the module, or NULL + * @unused: unused * @error: a #GError or NULL * * Initialize a PKCS\#11 module and add it to the modules that are @@ -284,7 +284,7 @@ gcr_pkcs11_add_module (GckModule *module) * Returns: whether the module was sucessfully added. */ gboolean -gcr_pkcs11_add_module_from_file (const gchar *module_path, const gchar *init_params, +gcr_pkcs11_add_module_from_file (const gchar *module_path, gpointer unused, GError **error) { GckModule *module; @@ -292,7 +292,7 @@ gcr_pkcs11_add_module_from_file (const gchar *module_path, const gchar *init_par g_return_val_if_fail (module_path, FALSE); g_return_val_if_fail (!error || !*error, FALSE); - module = gck_module_initialize (module_path, (gpointer)init_params, 0, error); + module = gck_module_initialize (module_path, 0, error); if (module == NULL) return FALSE; diff --git a/gcr/gcr-library.h b/gcr/gcr-library.h index 61317aa..de0f44d 100644 --- a/gcr/gcr-library.h +++ b/gcr/gcr-library.h @@ -39,7 +39,7 @@ void gcr_pkcs11_set_modules (GList *modules); void gcr_pkcs11_add_module (GckModule *module); gboolean gcr_pkcs11_add_module_from_file (const gchar *module_path, - const gchar *init_params, + gpointer unused, GError **error); GList* gcr_pkcs11_get_trust_lookup_slots (void); diff --git a/gcr/gcr.pc.in b/gcr/gcr.pc.in index 5ba32d5..5f08eec 100644 --- a/gcr/gcr.pc.in +++ b/gcr/gcr.pc.in @@ -11,6 +11,6 @@ pkcs11standalonedir=@pkcs11standalonedir@ Name: gcr@GCR_VERSION_SUFFIX@ Description: GObject and GUI library for high level crypto parsing and display Version: @VERSION@ -Requires: glib-2.0 gtk+-@GTK_API_VERSION@ libtasn1 gck-0 +Requires: glib-2.0 gtk+-@GTK_API_VERSION@ libtasn1 gck-0 p11-kit-1 Libs: -L${libdir} -lgcr@GCR_VERSION_SUFFIX@ Cflags: -I${includedir}/gcr@GCR_VERSION_SUFFIX@ -- 2.7.4