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