1 /*
2 * gnome-keyring
3 *
4 * Copyright (C) 2008 Stefan Walter
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "config.h"
21
22 #include "gcr-deprecated-base.h"
23 #include "gcr-internal.h"
24 #include "gcr-library.h"
25 #include "gcr-types.h"
26
27 #include "egg/egg-error.h"
28 #include "egg/egg-libgcrypt.h"
29 #include "egg/egg-secure-memory.h"
30
31 #include <p11-kit/p11-kit.h>
32
33 #include <gck/gck.h>
34
35 #include <gcrypt.h>
36
37 #include <glib/gi18n-lib.h>
38
39 /**
40 * SECTION:gcr-library
41 * @title: Library Utilities
42 * @short_description: Library utilities such as version checks
43 *
44 * Basic library utilities such as version checks.
45 */
46
47 /**
48 * GCR_CHECK_VERSION:
49 * @major: the major version to check for
50 * @minor: the minor version to check for
51 * @micro: the micro version to check for
52 *
53 * Checks the version of the Gcr libarry that is being compiled
54 * against.
55 *
56 * <example>
57 * <title>Checking the version of the Gcr library</title>
58 * <programlisting>
59 * #if !GCR_CHECK_VERSION (3, 0, 0)
60 * #warning Old Gcr version, disabling functionality
61 * #endif
62 * </programlisting>
63 * </example>
64 *
65 * Returns: %TRUE if the version of the Gcr header files
66 * is the same as or newer than the passed-in version.
67 */
68
69 /**
70 * GCR_MAJOR_VERSION:
71 *
72 * The major version number of the Gcr library.
73 */
74
75 /**
76 * GCR_MINOR_VERSION:
77 *
78 * The minor version number of the Gcr library.
79 */
80
81 /**
82 * GCR_MICRO_VERSION:
83 *
84 * The micro version number of the Gcr library.
85 */
86
87 /**
88 * SECTION:gcr-pkcs11
89 * @title: Library PKCS#11
90 * @short_description: functions for manipulating GCR library global settings.
91 *
92 * Manage or lookup various global aspesct and settings of the library.
93 *
94 * The GCR library maintains a global list of PKCS\#11 modules to use for
95 * its various lookups and storage operations. Each module is represented by
96 * a GckModule object. You can examine this list by using
97 * gcr_pkcs11_get_modules().
98 *
99 * The list is configured automatically by looking for system installed
100 * PKCS\#11 modules. It's not not normally necessary to modify this list. But
101 * if you have special needs, you can use the gcr_pkcs11_set_modules() and
102 * gcr_pkcs11_add_module() to do so.
103 *
104 * Trust assertions are stored and looked up in specific PKCS\#11 slots.
105 * You can examine this list with gcr_pkcs11_get_trust_lookup_slots()
106 */
107
108 /**
109 * SECTION:gcr-private
110 * @title: Private declarations
111 * @short_description: private declarations to supress warnings.
112 *
113 * This section is only here to supress warnings, and should not be displayed.
114 */
115
116 G_LOCK_DEFINE_STATIC (modules);
117 static GList *all_modules = NULL;
118 static gboolean initialized_modules = FALSE;
119
120 G_LOCK_DEFINE_STATIC (uris);
121 static gboolean initialized_uris = FALSE;
122 static gchar *trust_store_uri = NULL;
123 static gchar **trust_lookup_uris = NULL;
124
125 /* -----------------------------------------------------------------------------
126 * ERRORS
127 */
128
129 GQuark
gcr_data_error_get_domain(void)130 gcr_data_error_get_domain (void)
131 {
132 static GQuark domain = 0;
133 if (domain == 0)
134 domain = g_quark_from_static_string ("gcr-parser-error");
135 return domain;
136 }
137
138 GQuark
gcr_error_get_domain(void)139 gcr_error_get_domain (void)
140 {
141 static GQuark domain = 0;
142 if (domain == 0)
143 domain = g_quark_from_static_string ("gcr-error");
144 return domain;
145 }
146
147 /* -----------------------------------------------------------------------------
148 * INITIALIZATION
149 */
150
151 void
_gcr_uninitialize_library(void)152 _gcr_uninitialize_library (void)
153 {
154 G_LOCK (modules);
155
156 gck_list_unref_free (all_modules);
157 all_modules = NULL;
158 initialized_modules = FALSE;
159
160 G_UNLOCK (modules);
161
162 G_LOCK (uris);
163
164 initialized_uris = FALSE;
165 g_free (trust_store_uri);
166 trust_store_uri = NULL;
167 g_strfreev (trust_lookup_uris);
168 trust_lookup_uris = NULL;
169
170 G_UNLOCK (uris);
171 }
172 void
_gcr_initialize_library(void)173 _gcr_initialize_library (void)
174 {
175 static gint gcr_initialize = 0;
176
177 if (g_atomic_int_add (&gcr_initialize, 1) == 0)
178 return;
179
180 /* Initialize the libgcrypt library if needed */
181 egg_libgcrypt_initialize ();
182
183 g_debug ("initialized library");
184 }
185
186 static void
initialize_uris(void)187 initialize_uris (void)
188 {
189 GPtrArray *uris;
190 GList *l;
191 gchar *uri;
192 gchar *debug;
193
194 if (initialized_uris)
195 return;
196
197 if (!initialized_modules) {
198 g_debug ("modules not initialized");
199 return;
200 }
201
202 G_LOCK (uris);
203
204 if (!initialized_uris) {
205 /* Ask for the global x-trust-store option */
206 trust_store_uri = p11_kit_config_option (NULL, "x-trust-store");
207 for (l = all_modules; !trust_store_uri && l != NULL; l = g_list_next (l)) {
208 trust_store_uri = p11_kit_config_option (gck_module_get_functions (l->data),
209 "x-trust-store");
210 }
211
212 uris = g_ptr_array_new ();
213 uri = p11_kit_config_option (NULL, "x-trust-lookup");
214 if (uri != NULL)
215 g_ptr_array_add (uris, uri);
216 for (l = all_modules; l != NULL; l = g_list_next (l)) {
217 uri = p11_kit_config_option (gck_module_get_functions (l->data),
218 "x-trust-lookup");
219 if (uri != NULL)
220 g_ptr_array_add (uris, uri);
221 }
222 g_ptr_array_add (uris, NULL);
223
224 trust_lookup_uris = (gchar**)g_ptr_array_free (uris, FALSE);
225
226 g_debug ("trust store uri is: %s", trust_store_uri);
227 debug = g_strjoinv (" ", trust_lookup_uris);
228 g_debug ("trust lookup uris are: %s", debug);
229 g_free (debug);
230
231 initialized_uris = TRUE;
232 }
233
234 G_UNLOCK (uris);
235 }
236
237 static void
on_initialize_registered(GObject * object,GAsyncResult * result,gpointer user_data)238 on_initialize_registered (GObject *object,
239 GAsyncResult *result,
240 gpointer user_data)
241 {
242 GTask *task = G_TASK (user_data);
243 GError *error = NULL;
244 GList *results;
245
246 results = gck_modules_initialize_registered_finish (result, &error);
247 if (error != NULL) {
248 g_debug ("failed %s", error->message);
249 g_task_return_error (task, g_steal_pointer (&error));
250 g_clear_object (&task);
251 return;
252 }
253
254 G_LOCK (modules);
255 if (!initialized_modules) {
256 all_modules = g_list_concat (all_modules, results);
257 results = NULL;
258 initialized_modules = TRUE;
259 }
260 G_UNLOCK (modules);
261
262 gck_list_unref_free (results);
263
264 g_debug ("completed initialize of registered modules");
265 g_task_return_boolean (task, TRUE);
266 g_clear_object (&task);
267 }
268
269 /**
270 * gcr_pkcs11_initialize_async:
271 * @cancellable: (nullable): optional cancellable used to cancel the operation
272 * @callback: callback which will be called when the operation completes
273 * @user_data: data passed to the callback
274 *
275 * Asynchronously initialize the registered PKCS\#11 modules.
276 */
277 void
gcr_pkcs11_initialize_async(GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)278 gcr_pkcs11_initialize_async (GCancellable *cancellable,
279 GAsyncReadyCallback callback,
280 gpointer user_data)
281 {
282 GTask *task;
283
284 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
285
286 task = g_task_new (NULL, cancellable, callback, user_data);
287 g_task_set_source_tag (task, gcr_pkcs11_initialize_async);
288
289 if (initialized_modules) {
290 g_debug ("already initialized, no need to async");
291 g_task_return_boolean (task, TRUE);
292 } else {
293 gck_modules_initialize_registered_async (cancellable,
294 on_initialize_registered,
295 g_steal_pointer (&task));
296 g_debug ("starting initialize of registered modules");
297 }
298
299 g_clear_object (&task);
300 }
301
302 /**
303 * gcr_pkcs11_initialize_finish:
304 * @result: the asynchronous result
305 * @error: location to place an error on failure
306 *
307 * Complete the asynchronous operation to initialize the registered PKCS\#11
308 * modules.
309 *
310 * Returns: whether the operation was successful or not.
311 */
312 gboolean
gcr_pkcs11_initialize_finish(GAsyncResult * result,GError ** error)313 gcr_pkcs11_initialize_finish (GAsyncResult *result,
314 GError **error)
315 {
316 g_return_val_if_fail (g_task_is_valid (result, NULL), FALSE);
317
318 return g_task_propagate_boolean (G_TASK (result), error);
319 }
320
321 /**
322 * gcr_pkcs11_initialize:
323 * @cancellable: optional cancellable used to cancel the operation
324 * @error: location to place an error on failure
325 *
326 * Asynchronously initialize the registered PKCS\#11 modules.
327 *
328 * Returns: whether the operation was successful or not.
329 */
330
331 gboolean
gcr_pkcs11_initialize(GCancellable * cancellable,GError ** error)332 gcr_pkcs11_initialize (GCancellable *cancellable,
333 GError **error)
334 {
335 GList *results;
336 GError *err = NULL;
337
338 if (initialized_modules)
339 return TRUE;
340
341 results = gck_modules_initialize_registered (cancellable, &err);
342 if (err == NULL) {
343
344 g_debug ("registered module initialize succeeded: %d modules",
345 g_list_length (results));
346
347 G_LOCK (modules);
348
349 if (!initialized_modules) {
350 all_modules = g_list_concat (all_modules, results);
351 results = NULL;
352 initialized_modules = TRUE;
353 }
354
355 G_UNLOCK (modules);
356
357 } else {
358 g_debug ("registered module initialize failed: %s", err->message);
359 g_propagate_error (error, err);
360 }
361
362 gck_list_unref_free (results);
363 return (err == NULL);
364 }
365
366 /**
367 * gcr_pkcs11_get_modules:
368 *
369 * List all the PKCS\#11 modules that are used by the GCR library.
370 * Each module is a #GckModule object.
371 *
372 * An empty list of modules will be returned if gcr_pkcs11_set_modules(),
373 * or gcr_pkcs11_initialize() has not yet run.
374 *
375 * When done with the list, free it with gck_list_unref_free().
376 *
377 * Returns: (transfer full) (element-type Gck.Module): a newly allocated list
378 * of #GckModule objects
379 */
380 GList*
gcr_pkcs11_get_modules(void)381 gcr_pkcs11_get_modules (void)
382 {
383 if (!initialized_modules)
384 g_debug ("pkcs11 not yet initialized");
385 else if (!all_modules)
386 g_debug ("no modules loaded");
387 return gck_list_ref_copy (all_modules);
388 }
389
390 /**
391 * gcr_pkcs11_set_modules:
392 * @modules: (element-type Gck.Module): a list of #GckModule
393 *
394 * Set the list of PKCS\#11 modules that are used by the GCR library.
395 * Each module in the list is a #GckModule object.
396 *
397 * It is not normally necessary to call this function. The available
398 * PKCS\#11 modules installed on the system are automatically loaded
399 * by the GCR library.
400 */
401 void
gcr_pkcs11_set_modules(GList * modules)402 gcr_pkcs11_set_modules (GList *modules)
403 {
404 GList *l;
405
406 for (l = modules; l; l = g_list_next (l))
407 g_return_if_fail (GCK_IS_MODULE (l->data));
408
409 modules = gck_list_ref_copy (modules);
410 gck_list_unref_free (all_modules);
411 all_modules = modules;
412 initialized_modules = TRUE;
413 }
414
415 /**
416 * gcr_pkcs11_add_module:
417 * @module: a #GckModule
418 *
419 * Add a #GckModule to the list of PKCS\#11 modules that are used by the
420 * GCR library.
421 *
422 * It is not normally necessary to call this function. The available
423 * PKCS\#11 modules installed on the system are automatically loaded
424 * by the GCR library.
425 */
426 void
gcr_pkcs11_add_module(GckModule * module)427 gcr_pkcs11_add_module (GckModule *module)
428 {
429 g_return_if_fail (GCK_IS_MODULE (module));
430 all_modules = g_list_append (all_modules, g_object_ref (module));
431 }
432
433 /**
434 * gcr_pkcs11_add_module_from_file:
435 * @module_path: the full file path of the PKCS\#11 module
436 * @unused: unused
437 * @error: a #GError or %NULL
438 *
439 * Initialize a PKCS\#11 module and add it to the modules that are
440 * used by the GCR library. Note that is an error to initialize the same
441 * PKCS\#11 module twice.
442 *
443 * It is not normally necessary to call this function. The available
444 * PKCS\#11 modules installed on the system are automatically loaded
445 * by the GCR library.
446 *
447 * Returns: whether the module was sucessfully added.
448 */
449 gboolean
gcr_pkcs11_add_module_from_file(const gchar * module_path,gpointer unused,GError ** error)450 gcr_pkcs11_add_module_from_file (const gchar *module_path, gpointer unused,
451 GError **error)
452 {
453 GckModule *module;
454 GError *err = NULL;
455
456 g_return_val_if_fail (module_path, FALSE);
457 g_return_val_if_fail (!error || !*error, FALSE);
458
459 module = gck_module_initialize (module_path, NULL, &err);
460 if (module == NULL) {
461 g_debug ("initializing module failed: %s: %s",
462 module_path, err->message);
463 g_propagate_error (error, err);
464 return FALSE;
465 }
466
467 gcr_pkcs11_add_module (module);
468
469 g_debug ("initialized and added module: %s", module_path);
470 g_object_unref (module);
471 return TRUE;
472 }
473
474 /**
475 * gcr_pkcs11_get_trust_store_slot:
476 *
477 * Selects an appropriate PKCS\#11 slot to store trust assertions. The slot
478 * to use is normally configured automatically by the system.
479 *
480 * This will only return a valid result after the gcr_pkcs11_initialize()
481 * method has been called.
482 *
483 * When done with the #GckSlot, use g_object_unref() to release it.
484 *
485 * Returns: (transfer full) (nullable): the #GckSlot to use for trust
486 * assertions, or null if not initialized or no appropriate
487 * trust store could be found.
488 */
489 GckSlot *
gcr_pkcs11_get_trust_store_slot(void)490 gcr_pkcs11_get_trust_store_slot (void)
491 {
492 GckSlot *slot;
493 GError *error = NULL;
494
495 if (!initialized_modules)
496 return NULL;
497
498 initialize_uris ();
499 if (!trust_store_uri) {
500 g_warning ("no slot available for storing assertions");
501 return NULL;
502 }
503
504 slot = gck_modules_token_for_uri (all_modules, trust_store_uri, &error);
505 if (!slot) {
506 if (error) {
507 g_warning ("error finding slot to store trust assertions: %s: %s",
508 trust_store_uri, egg_error_message (error));
509 g_clear_error (&error);
510 } else {
511 g_debug ("no trust store slot found");
512 }
513 }
514
515 return slot;
516 }
517
518 /**
519 * gcr_pkcs11_get_trust_lookup_slots:
520 *
521 * List all the PKCS\#11 slots that are used by the GCR library for lookup
522 * of trust assertions. Each slot is a #GckSlot object.
523 *
524 * This will return an empty list if the gcr_pkcs11_initialize() function has
525 * not yet been called.
526 *
527 * When done with the list, free it with gck_list_unref_free().
528 *
529 * Returns: (transfer full) (element-type Gck.Slot): a list of #GckSlot
530 * objects to use for lookup of trust, or the empty list if not
531 * initialized or no appropriate trust stores could be found.
532 */
533 GList*
gcr_pkcs11_get_trust_lookup_slots(void)534 gcr_pkcs11_get_trust_lookup_slots (void)
535 {
536 GList *results = NULL;
537 GError *error = NULL;
538 gchar **uri;
539
540 if (!initialized_modules)
541 return NULL;
542
543 initialize_uris ();
544 if (!trust_lookup_uris) {
545 g_warning ("no slots available for assertion lookup");
546 return NULL;
547 }
548
549 for (uri = trust_lookup_uris; uri && *uri; ++uri) {
550 results = g_list_concat (results, gck_modules_tokens_for_uri (all_modules, *uri, &error));
551 if (error != NULL) {
552 g_warning ("error finding slot for trust assertions: %s: %s",
553 *uri, egg_error_message (error));
554 g_clear_error (&error);
555 }
556 }
557
558 if (results == NULL)
559 g_debug ("no trust lookup slots found");
560
561 return results;
562 }
563
564 /**
565 * gcr_pkcs11_get_trust_store_uri:
566 *
567 * Get the PKCS\#11 URI that is used to identify which slot to use for
568 * storing trust storage.
569 *
570 * Returns: (nullable): the uri which identifies trust storage slot
571 */
572 const gchar*
gcr_pkcs11_get_trust_store_uri(void)573 gcr_pkcs11_get_trust_store_uri (void)
574 {
575 initialize_uris ();
576 return trust_store_uri;
577 }
578
579 /**
580 * gcr_pkcs11_set_trust_store_uri:
581 * @pkcs11_uri: (nullable): the uri which identifies trust storage slot
582 *
583 * Set the PKCS\#11 URI that is used to identify which slot to use for
584 * storing trust assertions.
585 *
586 * It is not normally necessary to call this function. The relevant
587 * PKCS\#11 slot is automatically configured by the GCR library.
588 */
589 void
gcr_pkcs11_set_trust_store_uri(const gchar * pkcs11_uri)590 gcr_pkcs11_set_trust_store_uri (const gchar *pkcs11_uri)
591 {
592 G_LOCK (uris);
593
594 g_free (trust_store_uri);
595 trust_store_uri = g_strdup (pkcs11_uri);
596 initialized_uris = TRUE;
597
598 G_UNLOCK (uris);
599 }
600
601
602 /**
603 * gcr_pkcs11_get_trust_lookup_uris:
604 *
605 * Get the PKCS\#11 URIs that are used to identify which slots to use for
606 * lookup trust assertions.
607 *
608 * Returns: (nullable) (transfer none): the uri which identifies trust storage slot
609 */
610 const gchar **
gcr_pkcs11_get_trust_lookup_uris(void)611 gcr_pkcs11_get_trust_lookup_uris (void)
612 {
613 initialize_uris ();
614 return (const gchar **)trust_lookup_uris;
615 }
616
617 /**
618 * gcr_pkcs11_set_trust_lookup_uris:
619 * @pkcs11_uris: (nullable): the uris which identifies trust lookup slots
620 *
621 * Set the PKCS\#11 URIs that are used to identify which slots to use for
622 * lookup of trust assertions.
623 *
624 * It is not normally necessary to call this function. The relevant
625 * PKCS\#11 slots are automatically configured by the GCR library.
626 */
627 void
gcr_pkcs11_set_trust_lookup_uris(const gchar ** pkcs11_uris)628 gcr_pkcs11_set_trust_lookup_uris (const gchar **pkcs11_uris)
629 {
630 G_LOCK (uris);
631
632 g_strfreev (trust_lookup_uris);
633 trust_lookup_uris = g_strdupv ((gchar**)pkcs11_uris);
634 initialized_uris = TRUE;
635
636 G_UNLOCK (uris);
637 }
638