1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* gck-module.c - the GObject PKCS#11 wrapper library
3 
4    Copyright (C) 2008, Stefan Walter
5 
6    The Gnome Keyring Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Library General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10 
11    The Gnome Keyring Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Library General Public License for more details.
15 
16    You should have received a copy of the GNU Library General Public
17    License along with the Gnome Library; see the file COPYING.LIB.  If not,
18    see <http://www.gnu.org/licenses/>.
19 
20    Author: Stef Walter <nielsen@memberwebs.com>
21 */
22 
23 #include "config.h"
24 
25 #include "gck.h"
26 #include "gck-private.h"
27 
28 #include "gck/gck-marshal.h"
29 
30 #include <glib/gi18n-lib.h>
31 
32 #define P11_KIT_FUTURE_UNSTABLE_API 1
33 #include <p11-kit/p11-kit.h>
34 
35 #include <string.h>
36 
37 /**
38  * SECTION:gck-module
39  * @title: GckModule
40  * @short_description: A loaded and initialized PKCS\#11 module.
41  *
42  * A GckModule object holds a loaded PKCS\#11 module. A PKCS\#11 module is a shared library.
43  *
44  * You can load and initialize a PKCS\#11 module with the gck_module_initialize() call. If you already
45  * have a loaded and initialized module that you'd like to use with the various gck functions, then
46  * you can use gck_module_new().
47  */
48 
49 /**
50  * GckModule:
51  *
52  * Holds a loaded and initialized PKCS\#11 module.
53  */
54 
55 /**
56  * GckModuleInfo:
57  * @pkcs11_version_major: The major version of the module.
58  * @pkcs11_version_minor: The minor version of the module.
59  * @manufacturer_id: The module manufacturer.
60  * @flags: The module PKCS&num;11 flags.
61  * @library_description: The module description.
62  * @library_version_major: The major version of the library.
63  * @library_version_minor: The minor version of the library.
64  *
65  * Holds information about the PKCS&num;11 module.
66  *
67  * This structure corresponds to CK_MODULE_INFO in the PKCS\#11 standard. The
68  * strings are %NULL terminated for easier use.
69  *
70  * Use gck_module_info_free() to release this structure when done with it.
71  */
72 
73 /*
74  * MT safe
75  *
76  * The only thing that can change after object initialization in
77  * a GckModule is the finalized flag, which can be set
78  * to 1 in dispose.
79  */
80 
81 enum {
82 	PROP_0,
83 	PROP_PATH,
84 	PROP_FUNCTIONS
85 };
86 
87 enum {
88 	AUTHENTICATE_SLOT,
89 	AUTHENTICATE_OBJECT,
90 	LAST_SIGNAL
91 };
92 
93 struct _GckModulePrivate {
94 	gchar *path;
95 	gboolean initialized;
96 	CK_FUNCTION_LIST_PTR funcs;
97 	CK_C_INITIALIZE_ARGS init_args;
98 
99 	/* Modified atomically */
100 	gint finalized;
101 };
102 
103 G_DEFINE_TYPE_WITH_PRIVATE (GckModule, gck_module, G_TYPE_OBJECT);
104 
105 static guint signals[LAST_SIGNAL] = { 0 };
106 
107 /* ----------------------------------------------------------------------------
108  * OBJECT
109  */
110 
111 static gboolean
gck_module_real_authenticate_slot(GckModule * module,GckSlot * self,gchar * label,gchar ** password)112 gck_module_real_authenticate_slot (GckModule *module, GckSlot *self, gchar *label, gchar **password)
113 {
114 	return FALSE;
115 }
116 
117 static gboolean
gck_module_real_authenticate_object(GckModule * module,GckObject * object,gchar * label,gchar ** password)118 gck_module_real_authenticate_object (GckModule *module, GckObject *object, gchar *label, gchar **password)
119 {
120 	return FALSE;
121 }
122 
123 static void
gck_module_init(GckModule * self)124 gck_module_init (GckModule *self)
125 {
126 	self->pv = gck_module_get_instance_private (self);
127 }
128 
129 static void
gck_module_get_property(GObject * obj,guint prop_id,GValue * value,GParamSpec * pspec)130 gck_module_get_property (GObject *obj, guint prop_id, GValue *value,
131                           GParamSpec *pspec)
132 {
133 	GckModule *self = GCK_MODULE (obj);
134 
135 	switch (prop_id) {
136 	case PROP_PATH:
137 		g_value_set_string (value, gck_module_get_path (self));
138 		break;
139 	case PROP_FUNCTIONS:
140 		g_value_set_pointer (value, gck_module_get_functions (self));
141 		break;
142 	}
143 }
144 
145 static void
gck_module_set_property(GObject * obj,guint prop_id,const GValue * value,GParamSpec * pspec)146 gck_module_set_property (GObject *obj, guint prop_id, const GValue *value,
147                           GParamSpec *pspec)
148 {
149 	GckModule *self = GCK_MODULE (obj);
150 
151 	/* Only allowed during initialization */
152 	switch (prop_id) {
153 	case PROP_PATH:
154 		g_return_if_fail (!self->pv->path);
155 		self->pv->path = g_value_dup_string (value);
156 		break;
157 	case PROP_FUNCTIONS:
158 		g_return_if_fail (!self->pv->funcs);
159 		self->pv->funcs = g_value_get_pointer (value);
160 		break;
161 	}
162 }
163 
164 static void
gck_module_dispose(GObject * obj)165 gck_module_dispose (GObject *obj)
166 {
167 	GckModule *self = GCK_MODULE (obj);
168 	gboolean finalize = FALSE;
169 	CK_RV rv;
170 
171 	if (self->pv->initialized && self->pv->funcs) {
172 		if (g_atomic_int_compare_and_exchange (&self->pv->finalized, 0, 1))
173 			finalize = TRUE;
174 	}
175 
176 	/* Must be careful when accessing funcs */
177 	if (finalize) {
178 		rv = p11_kit_module_finalize (self->pv->funcs);
179 		if (rv != CKR_OK) {
180 			g_warning ("C_Finalize on module '%s' failed: %s",
181 			           self->pv->path, gck_message_from_rv (rv));
182 		}
183 	}
184 
185 	G_OBJECT_CLASS (gck_module_parent_class)->dispose (obj);
186 }
187 
188 static void
gck_module_finalize(GObject * obj)189 gck_module_finalize (GObject *obj)
190 {
191 	GckModule *self = GCK_MODULE (obj);
192 
193 	if (self->pv->initialized && self->pv->funcs)
194 		p11_kit_module_release (self->pv->funcs);
195 	self->pv->funcs = NULL;
196 
197 	g_free (self->pv->path);
198 	self->pv->path = NULL;
199 
200 	G_OBJECT_CLASS (gck_module_parent_class)->finalize (obj);
201 }
202 
203 
204 static void
gck_module_class_init(GckModuleClass * klass)205 gck_module_class_init (GckModuleClass *klass)
206 {
207 	GObjectClass *gobject_class = (GObjectClass*)klass;
208 	gck_module_parent_class = g_type_class_peek_parent (klass);
209 
210 	gobject_class->get_property = gck_module_get_property;
211 	gobject_class->set_property = gck_module_set_property;
212 	gobject_class->dispose = gck_module_dispose;
213 	gobject_class->finalize = gck_module_finalize;
214 
215 	klass->authenticate_object = gck_module_real_authenticate_object;
216 	klass->authenticate_slot = gck_module_real_authenticate_slot;
217 
218 	/**
219 	 * GckModule:path:
220 	 *
221 	 * The PKCS&num;11 module file path.
222 	 *
223 	 * This may be set to NULL if this object was created from an already
224 	 * initialized module via the gck_module_new() function.
225 	 */
226 	g_object_class_install_property (gobject_class, PROP_PATH,
227 		g_param_spec_string ("path", "Module Path", "Path to the PKCS11 Module",
228 		                     NULL,
229 		                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
230 
231 	/**
232 	 * GckModule:functions:
233 	 *
234 	 * The raw PKCS&num;11 function list for the module.
235 	 *
236 	 * This points to a CK_FUNCTION_LIST structure.
237 	 */
238 	g_object_class_install_property (gobject_class, PROP_FUNCTIONS,
239 		g_param_spec_pointer ("functions", "Function List", "PKCS11 Function List",
240 		                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
241 
242 	/**
243 	 * GckModule::authenticate-slot:
244 	 * @module: The module
245 	 * @slot: The slot to be authenticated.
246 	 * @string: A displayable label which describes the object.
247 	 * @password: A gchar** where a password should be returned.
248 	 *
249 	 * Use gck_session_set_interaction() instead of connecting to this signal.
250 	 *
251 	 * Deprecated: Since 3.4
252 	 */
253 	signals[AUTHENTICATE_SLOT] = g_signal_new ("authenticate-slot", GCK_TYPE_MODULE,
254 			G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GckModuleClass, authenticate_slot),
255 			g_signal_accumulator_true_handled, NULL, _gck_marshal_BOOLEAN__OBJECT_STRING_POINTER,
256 			G_TYPE_BOOLEAN, 3, GCK_TYPE_SLOT, G_TYPE_STRING, G_TYPE_POINTER);
257 
258 	/**
259 	 * GckModule::authenticate-object:
260 	 * @module: The module.
261 	 * @object: The object to be authenticated.
262 	 * @label: A displayable label which describes the object.
263 	 * @password: A gchar** where a password should be returned.
264 	 *
265 	 * Use gck_session_set_interaction() instead of connecting to this signal.
266 	 *
267 	 * Deprecated: Since 3.4
268 	 */
269 	signals[AUTHENTICATE_OBJECT] = g_signal_new ("authenticate-object", GCK_TYPE_MODULE,
270 			G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GckModuleClass, authenticate_object),
271 			g_signal_accumulator_true_handled, NULL, _gck_marshal_BOOLEAN__OBJECT_STRING_POINTER,
272 			G_TYPE_BOOLEAN, 3, GCK_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_POINTER);
273 }
274 
G_DEFINE_BOXED_TYPE(GckModuleInfo,gck_module_info,gck_module_info_copy,gck_module_info_free)275 G_DEFINE_BOXED_TYPE (GckModuleInfo, gck_module_info,
276                      gck_module_info_copy, gck_module_info_free)
277 
278 /**
279  * gck_module_info_copy:
280  * @module_info: a module info
281  *
282  * Make a copy of the module info.
283  *
284  * Returns: (transfer full): a newly allocated copy module info
285  */
286 GckModuleInfo *
287 gck_module_info_copy (GckModuleInfo *module_info)
288 {
289 	if (module_info == NULL)
290 		return NULL;
291 
292 	module_info = g_memdup (module_info, sizeof (GckModuleInfo));
293 	module_info->manufacturer_id = g_strdup (module_info->manufacturer_id);
294 	module_info->library_description = g_strdup (module_info->library_description);
295 	return module_info;
296 
297 }
298 
299 /**
300  * gck_module_info_free:
301  * @module_info: The module info to free, or %NULL.
302  *
303  * Free a GckModuleInfo structure.
304  **/
305 void
gck_module_info_free(GckModuleInfo * module_info)306 gck_module_info_free (GckModuleInfo *module_info)
307 {
308 	if (!module_info)
309 		return;
310 	g_free (module_info->library_description);
311 	g_free (module_info->manufacturer_id);
312 	g_free (module_info);
313 }
314 
315 typedef struct {
316 	GckArguments base;
317 	gchar *path;
318 	GckModule *result;
319 	GError *error;
320 } Initialize;
321 
322 static CK_RV
perform_initialize(Initialize * args)323 perform_initialize (Initialize *args)
324 {
325 	CK_FUNCTION_LIST_PTR funcs;
326 	GckModule *result;
327 	CK_RV rv;
328 
329 	funcs = p11_kit_module_load (args->path, P11_KIT_MODULE_CRITICAL);
330 	if (funcs == NULL) {
331 		g_set_error (&args->error, GCK_ERROR, (int)CKR_GCK_MODULE_PROBLEM,
332 		             _("Error loading PKCS#11 module: %s"), p11_kit_message ());
333 		return CKR_GCK_MODULE_PROBLEM;
334 	}
335 
336 	result = g_object_new (GCK_TYPE_MODULE,
337 	                       "functions", funcs,
338 	                       "path", args->path,
339 	                       NULL);
340 
341 	/* Now initialize the module */
342 	rv = p11_kit_module_initialize (funcs);
343 	if (rv != CKR_OK) {
344 		p11_kit_module_release (funcs);
345 		g_set_error (&args->error, GCK_ERROR, rv,
346 		             _("Couldn’t initialize PKCS#11 module: %s"),
347 		             gck_message_from_rv (rv));
348 		g_object_unref (result);
349 		return rv;
350 	}
351 
352 	result->pv->initialized = TRUE;
353 	args->result = result;
354 	return CKR_OK;
355 }
356 
357 static void
free_initialize(Initialize * args)358 free_initialize (Initialize *args)
359 {
360 	g_free (args->path);
361 	g_clear_error (&args->error);
362 	g_clear_object (&args->result);
363 	g_free (args);
364 }
365 
366 /**
367  * gck_module_initialize:
368  * @path: The file system path to the PKCS\#11 module to load.
369  * @cancellable: (nullable): optional cancellation object
370  * @error: A location to store an error resulting from a failed load.
371  *
372  * Load and initialize a PKCS\#11 module represented by a GckModule object.
373  *
374  * Return value: (transfer full): The loaded PKCS\#11 module or %NULL if failed.
375  **/
376 GckModule*
gck_module_initialize(const gchar * path,GCancellable * cancellable,GError ** error)377 gck_module_initialize (const gchar *path,
378                        GCancellable *cancellable,
379                        GError **error)
380 {
381 	Initialize args = { GCK_ARGUMENTS_INIT, 0,  };
382 
383 	g_return_val_if_fail (path != NULL, NULL);
384 	g_return_val_if_fail (!error || !*error, NULL);
385 
386 	args.path = g_strdup (path);
387 
388 	if (!_gck_call_sync (NULL, perform_initialize, NULL, &args, cancellable, error)) {
389 
390 		/* A custom error from perform_initialize */
391 		if (args.error) {
392 			g_clear_error (error);
393 			g_propagate_error (error, args.error);
394 			args.error = NULL;
395 		}
396 	}
397 
398 	g_free (args.path);
399 	g_clear_error (&args.error);
400 	return args.result;
401 }
402 
403 /**
404  * gck_module_initialize_async:
405  * @path: the file system path to the PKCS\#11 module to load
406  * @cancellable: (nullable): optional cancellation object
407  * @callback: a callback which will be called when the operation completes
408  * @user_data: data to pass to the callback
409  *
410  * Asynchronously load and initialize a PKCS\#11 module represented by a
411  * #GckModule object.
412  **/
413 void
gck_module_initialize_async(const gchar * path,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)414 gck_module_initialize_async (const gchar *path,
415                              GCancellable *cancellable,
416                              GAsyncReadyCallback callback,
417                              gpointer user_data)
418 {
419 	Initialize *args;
420 	GckCall *call;
421 
422 	g_return_if_fail (path != NULL);
423 
424 	call =  _gck_call_async_prep (NULL, perform_initialize, NULL,
425 	                              sizeof (*args), free_initialize);
426 	args = _gck_call_get_arguments (call);
427 	args->path = g_strdup (path);
428 
429 	_gck_call_async_ready_go (call, NULL, cancellable, callback, user_data);
430 }
431 
432 /**
433  * gck_module_initialize_finish:
434  * @result: the asynchronous result
435  * @error: location to place an error on failure
436  *
437  * Finishes the asynchronous initialize operation.
438  *
439  * Returns: (transfer full) (nullable): The initialized module, or %NULL
440  */
441 GckModule *
gck_module_initialize_finish(GAsyncResult * result,GError ** error)442 gck_module_initialize_finish (GAsyncResult *result,
443                               GError **error)
444 {
445 	GckModule *module = NULL;
446 	Initialize *args;
447 
448 	args = _gck_call_async_result_arguments (result, Initialize);
449 	if (_gck_call_basic_finish (result, error)) {
450 		module = args->result;
451 		args->result = NULL;
452 
453 	} else {
454 		/* A custom error from perform_initialize */
455 		if (args->error) {
456 			g_clear_error (error);
457 			g_propagate_error (error, args->error);
458 			args->error = NULL;
459 		}
460 	}
461 
462 	return module;
463 }
464 
465 /**
466  * gck_module_new: (skip)
467  * @funcs: Initialized PKCS\#11 function list pointer
468  *
469  * Create a GckModule representing a PKCS\#11 module. It is assumed that
470  * this the module is already initialized. In addition it will not be
471  * finalized when complete.
472  *
473  * Return value: The new PKCS\#11 module.
474  **/
475 GckModule*
gck_module_new(CK_FUNCTION_LIST_PTR funcs)476 gck_module_new (CK_FUNCTION_LIST_PTR funcs)
477 {
478 	g_return_val_if_fail (funcs != NULL, NULL);
479 	return g_object_new (GCK_TYPE_MODULE, "functions", funcs, NULL);
480 }
481 
482 GckModule*
_gck_module_new_initialized(CK_FUNCTION_LIST_PTR funcs)483 _gck_module_new_initialized (CK_FUNCTION_LIST_PTR funcs)
484 {
485 	GckModule *module = gck_module_new (funcs);
486 	module->pv->initialized = TRUE; /* As if we initialized it */
487 	return module;
488 }
489 
490 /**
491  * gck_module_equal:
492  * @module1: (type Gck.Module): a pointer to the first #GckModule
493  * @module2: (type Gck.Module): a pointer to the second #GckModule
494  *
495  * Checks equality of two modules. Two GckModule objects can point to the same
496  * underlying PKCS\#11 module.
497  *
498  * Return value: %TRUE if module1 and module2 are equal.
499  *               %FALSE if either is not a GckModule.
500  **/
501 gboolean
gck_module_equal(gconstpointer module1,gconstpointer module2)502 gck_module_equal (gconstpointer module1, gconstpointer module2)
503 {
504 	GckModule *mod1, *mod2;
505 
506 	if (module1 == module2)
507 		return TRUE;
508 	if (!GCK_IS_MODULE (module1) || !GCK_IS_MODULE (module2))
509 		return FALSE;
510 
511 	mod1 = GCK_MODULE (module1);
512 	mod2 = GCK_MODULE (module2);
513 
514 	return mod1->pv->funcs == mod2->pv->funcs;
515 }
516 
517 /**
518  * gck_module_hash:
519  * @module: (type Gck.Module): a pointer to a #GckModule
520  *
521  * Create a hash value for the GckModule.
522  *
523  * This function is intended for easily hashing a GckModule to add to
524  * a GHashTable or similar data structure.
525  *
526  * Return value: An integer that can be used as a hash value, or 0 if invalid.
527  **/
528 guint
gck_module_hash(gconstpointer module)529 gck_module_hash (gconstpointer module)
530 {
531 	GckModule *self;
532 
533 	g_return_val_if_fail (GCK_IS_MODULE (module), 0);
534 	self = GCK_MODULE (module);
535 	return g_direct_hash (self->pv->funcs);
536 }
537 
538 GckModuleInfo*
_gck_module_info_from_pkcs11(CK_INFO_PTR info)539 _gck_module_info_from_pkcs11 (CK_INFO_PTR info)
540 {
541 	GckModuleInfo *modinfo;
542 
543 	modinfo = g_new0 (GckModuleInfo, 1);
544 	modinfo->flags = info->flags;
545 	modinfo->library_description = gck_string_from_chars (info->libraryDescription,
546 	                                                       sizeof (info->libraryDescription));
547 	modinfo->manufacturer_id = gck_string_from_chars (info->manufacturerID,
548 	                                                   sizeof (info->manufacturerID));
549 	modinfo->library_version_major = info->libraryVersion.major;
550 	modinfo->library_version_minor = info->libraryVersion.minor;
551 	modinfo->pkcs11_version_major = info->cryptokiVersion.major;
552 	modinfo->pkcs11_version_minor = info->cryptokiVersion.minor;
553 
554 	return modinfo;
555 }
556 
557 void
_gck_module_info_to_pkcs11(GckModuleInfo * module_info,CK_INFO_PTR info)558 _gck_module_info_to_pkcs11 (GckModuleInfo* module_info, CK_INFO_PTR info)
559 {
560 	info->flags = module_info->flags;
561 	if (!gck_string_to_chars (info->libraryDescription,
562 	                          sizeof (info->libraryDescription),
563 	                          module_info->library_description))
564 		g_return_if_reached ();
565 	if (!gck_string_to_chars (info->manufacturerID,
566 	                          sizeof (info->manufacturerID),
567 	                          module_info->manufacturer_id))
568 		g_return_if_reached ();
569 
570 	info->libraryVersion.major = module_info->library_version_major;
571 	info->libraryVersion.minor = module_info->library_version_minor;
572 	info->cryptokiVersion.major = module_info->pkcs11_version_major;
573 	info->cryptokiVersion.minor = module_info->pkcs11_version_minor;
574 }
575 
576 /**
577  * gck_module_get_info:
578  * @self: The module to get info for.
579  *
580  * Get the info about a PKCS\#11 module.
581  *
582  * Returns: (transfer full): the module info; release this with gck_module_info_free()
583  **/
584 GckModuleInfo*
gck_module_get_info(GckModule * self)585 gck_module_get_info (GckModule *self)
586 {
587 	CK_INFO info;
588 	CK_RV rv;
589 
590 	g_return_val_if_fail (GCK_IS_MODULE (self), NULL);
591 	g_return_val_if_fail (self->pv->funcs, NULL);
592 
593 	memset (&info, 0, sizeof (info));
594 	rv = (self->pv->funcs->C_GetInfo (&info));
595 	if (rv != CKR_OK) {
596 		g_warning ("couldn't get module info: %s", gck_message_from_rv (rv));
597 		return NULL;
598 	}
599 
600 	return _gck_module_info_from_pkcs11 (&info);
601 }
602 
603 /**
604  * gck_module_get_slots:
605  * @self: The module for which to get the slots.
606  * @token_present: Whether to limit only to slots with a token present.
607  *
608  * Get the GckSlot objects for a given module.
609  *
610  * Return value: (element-type Gck.Slot) (transfer full): The possibly empty
611  *               list of slots. Release this with gck_list_unref_free().
612  */
613 GList*
gck_module_get_slots(GckModule * self,gboolean token_present)614 gck_module_get_slots (GckModule *self, gboolean token_present)
615 {
616 	CK_SLOT_ID_PTR slot_list;
617 	CK_ULONG count, i;
618 	GList *result;
619 	CK_RV rv;
620 
621 	g_return_val_if_fail (GCK_IS_MODULE (self), NULL);
622 	g_return_val_if_fail (self->pv->funcs, NULL);
623 
624 	rv = (self->pv->funcs->C_GetSlotList) (token_present ? CK_TRUE : CK_FALSE, NULL, &count);
625 	if (rv != CKR_OK) {
626 		g_warning ("couldn't get slot count: %s", gck_message_from_rv (rv));
627 		return NULL;
628 	}
629 
630 	if (!count)
631 		return NULL;
632 
633 	slot_list = g_new (CK_SLOT_ID, count);
634 	rv = (self->pv->funcs->C_GetSlotList) (token_present ? CK_TRUE : CK_FALSE, slot_list, &count);
635 	if (rv != CKR_OK) {
636 		g_warning ("couldn't get slot list: %s", gck_message_from_rv (rv));
637 		g_free (slot_list);
638 		return NULL;
639 	}
640 
641 	result = NULL;
642 	for (i = 0; i < count; ++i) {
643 		result = g_list_prepend (result, g_object_new (GCK_TYPE_SLOT,
644 		                                               "handle", slot_list[i],
645 		                                               "module", self, NULL));
646 	}
647 
648 	g_free (slot_list);
649 	return g_list_reverse (result);
650 }
651 
652 /**
653  * gck_module_get_path:
654  * @self: The module for which to get the path.
655  *
656  * Get the file path of this module. This may not be an absolute path, and
657  * usually reflects the path passed to gck_module_initialize().
658  *
659  * Return value: The path, do not modify or free this value.
660  **/
661 const gchar*
gck_module_get_path(GckModule * self)662 gck_module_get_path (GckModule *self)
663 {
664 	g_return_val_if_fail (GCK_IS_MODULE (self), NULL);
665 	return self->pv->path;
666 }
667 
668 /**
669  * gck_module_get_functions: (skip)
670  * @self: The module for which to get the function list.
671  *
672  * Get the PKCS\#11 function list for the module.
673  *
674  * Return value: The function list, do not modify this structure.
675  **/
676 CK_FUNCTION_LIST_PTR
gck_module_get_functions(GckModule * self)677 gck_module_get_functions (GckModule *self)
678 {
679 	g_return_val_if_fail (GCK_IS_MODULE (self), NULL);
680 	return self->pv->funcs;
681 }
682 
683 /**
684  * gck_module_match:
685  * @self: the module to match
686  * @uri: the uri to match against the module
687  *
688  * Check whether the PKCS\#11 URI matches the module
689  *
690  * Returns: whether the URI matches or not
691  */
692 gboolean
gck_module_match(GckModule * self,GckUriData * uri)693 gck_module_match (GckModule *self,
694                   GckUriData *uri)
695 {
696 	gboolean match = TRUE;
697 	GckModuleInfo *info;
698 
699 	g_return_val_if_fail (GCK_IS_MODULE (self), FALSE);
700 	g_return_val_if_fail (uri != NULL, FALSE);
701 
702 	if (uri->any_unrecognized)
703 		match = FALSE;
704 
705 	if (match && uri->module_info) {
706 		info = gck_module_get_info (self);
707 		match = _gck_module_info_match (uri->module_info, info);
708 		gck_module_info_free (info);
709 	}
710 
711 	return match;
712 }
713