1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* gck-session.h - 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 <string.h>
31
32 #include <glib/gi18n-lib.h>
33
34 /**
35 * SECTION:gck-session
36 * @title: GckSession
37 * @short_description: Represents an open PKCS11 session.
38 *
39 * Before performing any PKCS11 operations, a session must be opened. This is
40 * analogous to an open database handle, or a file handle.
41 */
42
43 /**
44 * GckSession:
45 *
46 * Represents an open PKCS11 session.
47 */
48
49 /**
50 * GckSessionOptions:
51 * @GCK_SESSION_READ_ONLY: Open session as read only
52 * @GCK_SESSION_READ_WRITE: Open sessions as read/write
53 * @GCK_SESSION_LOGIN_USER: Login as user on new sessions
54 * @GCK_SESSION_AUTHENTICATE: Authenticate as necessary
55 *
56 * Options for creating sessions.
57 */
58
59 /**
60 * GckMechanism:
61 * @type: The mechanism type
62 * @parameter: Mechanism specific data.
63 * @n_parameter: Length of mechanism specific data.
64 *
65 * Represents a mechanism used with crypto operations.
66 */
67
68 enum {
69 DISCARD_HANDLE,
70 LAST_SIGNAL
71 };
72
73 enum {
74 PROP_0,
75 PROP_MODULE,
76 PROP_HANDLE,
77 PROP_INTERACTION,
78 PROP_SLOT,
79 PROP_OPTIONS,
80 PROP_OPENING_FLAGS,
81 PROP_APP_DATA
82 };
83
84 struct _GckSessionPrivate {
85 /* Not modified after construct/init */
86 GckSlot *slot;
87 CK_SESSION_HANDLE handle;
88 GckSessionOptions options;
89 gulong opening_flags;
90 gpointer app_data;
91
92 /* Changable data locked by mutex */
93 GMutex *mutex;
94 GTlsInteraction *interaction;
95 gboolean discarded;
96 };
97
98 static void gck_session_initable_iface (GInitableIface *iface);
99
100 static void gck_session_async_initable_iface (GAsyncInitableIface *iface);
101
102 G_DEFINE_TYPE_WITH_CODE (GckSession, gck_session, G_TYPE_OBJECT,
103 G_ADD_PRIVATE (GckSession);
104 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gck_session_initable_iface);
105 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, gck_session_async_initable_iface);
106 );
107
108 static guint signals[LAST_SIGNAL] = { 0 };
109
110 /* ----------------------------------------------------------------------------
111 * OBJECT
112 */
113
114 static gboolean
gck_session_real_discard_handle(GckSession * self,CK_OBJECT_HANDLE handle)115 gck_session_real_discard_handle (GckSession *self, CK_OBJECT_HANDLE handle)
116 {
117 CK_FUNCTION_LIST_PTR funcs;
118 GckModule *module;
119 CK_RV rv;
120
121 /* The default functionality, close the handle */
122
123 module = gck_session_get_module (self);
124 g_return_val_if_fail (module != NULL, FALSE);
125
126 funcs = gck_module_get_functions (module);
127 g_return_val_if_fail (funcs, FALSE);
128
129 rv = (funcs->C_CloseSession) (handle);
130 if (rv != CKR_OK) {
131 g_warning ("couldn't close session properly: %s",
132 gck_message_from_rv (rv));
133 }
134
135 g_object_unref (module);
136 return TRUE;
137 }
138
139 static void
gck_session_init(GckSession * self)140 gck_session_init (GckSession *self)
141 {
142 self->pv = gck_session_get_instance_private (self);
143 self->pv->mutex = g_new0 (GMutex, 1);
144 g_mutex_init (self->pv->mutex);
145 }
146
147 static void
gck_session_get_property(GObject * obj,guint prop_id,GValue * value,GParamSpec * pspec)148 gck_session_get_property (GObject *obj, guint prop_id, GValue *value,
149 GParamSpec *pspec)
150 {
151 GckSession *self = GCK_SESSION (obj);
152
153 switch (prop_id) {
154 case PROP_MODULE:
155 g_value_take_object (value, gck_session_get_module (self));
156 break;
157 case PROP_HANDLE:
158 g_value_set_ulong (value, gck_session_get_handle (self));
159 break;
160 case PROP_SLOT:
161 g_value_take_object (value, gck_session_get_slot (self));
162 break;
163 case PROP_OPTIONS:
164 g_value_set_uint (value, gck_session_get_options (self));
165 break;
166 case PROP_INTERACTION:
167 g_value_take_object (value, gck_session_get_interaction (self));
168 break;
169 default:
170 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
171 break;
172 }
173 }
174
175 static void
gck_session_set_property(GObject * obj,guint prop_id,const GValue * value,GParamSpec * pspec)176 gck_session_set_property (GObject *obj, guint prop_id, const GValue *value,
177 GParamSpec *pspec)
178 {
179 GckSession *self = GCK_SESSION (obj);
180
181 /* Only valid calls are from constructor */
182
183 switch (prop_id) {
184 case PROP_HANDLE:
185 g_return_if_fail (!self->pv->handle);
186 self->pv->handle = g_value_get_ulong (value);
187 break;
188 case PROP_INTERACTION:
189 gck_session_set_interaction (self, g_value_get_object (value));
190 break;
191 case PROP_SLOT:
192 g_return_if_fail (!self->pv->slot);
193 self->pv->slot = g_value_dup_object (value);
194 g_return_if_fail (self->pv->slot);
195 break;
196 case PROP_OPTIONS:
197 g_return_if_fail (!self->pv->options);
198 self->pv->options = g_value_get_flags (value);
199 break;
200 case PROP_OPENING_FLAGS:
201 self->pv->opening_flags = g_value_get_ulong (value);
202 break;
203 case PROP_APP_DATA:
204 self->pv->app_data = g_value_get_pointer (value);
205 break;
206 default:
207 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
208 break;
209 }
210 }
211
212 static void
gck_session_constructed(GObject * obj)213 gck_session_constructed (GObject *obj)
214 {
215 GckSession *self = GCK_SESSION (obj);
216
217 G_OBJECT_CLASS (gck_session_parent_class)->constructed (obj);
218
219 self->pv->opening_flags |= CKF_SERIAL_SESSION;
220 if (self->pv->options & GCK_SESSION_READ_WRITE)
221 self->pv->opening_flags |= CKF_RW_SESSION;
222 }
223
224 static void
gck_session_dispose(GObject * obj)225 gck_session_dispose (GObject *obj)
226 {
227 GckSession *self = GCK_SESSION (obj);
228 gboolean discard = FALSE;
229 gboolean handled;
230
231 g_return_if_fail (GCK_IS_SESSION (self));
232
233 if (self->pv->handle != 0) {
234 g_mutex_lock (self->pv->mutex);
235 discard = !self->pv->discarded;
236 self->pv->discarded = TRUE;
237 g_mutex_unlock (self->pv->mutex);
238 }
239
240 if (discard) {
241 /*
242 * Let the world know that we're discarding the session
243 * handle. This allows any necessary session reuse to work.
244 */
245
246 g_signal_emit_by_name (self, "discard-handle", self->pv->handle, &handled);
247 g_return_if_fail (handled);
248 }
249
250 G_OBJECT_CLASS (gck_session_parent_class)->dispose (obj);
251 }
252
253 static void
gck_session_finalize(GObject * obj)254 gck_session_finalize (GObject *obj)
255 {
256 GckSession *self = GCK_SESSION (obj);
257
258 g_assert (self->pv->handle == 0 || self->pv->discarded);
259
260 g_clear_object (&self->pv->interaction);
261 g_clear_object (&self->pv->slot);
262
263 g_mutex_clear (self->pv->mutex);
264 g_free (self->pv->mutex);
265
266 G_OBJECT_CLASS (gck_session_parent_class)->finalize (obj);
267 }
268
269 static void
gck_session_class_init(GckSessionClass * klass)270 gck_session_class_init (GckSessionClass *klass)
271 {
272 GObjectClass *gobject_class = (GObjectClass*)klass;
273 gck_session_parent_class = g_type_class_peek_parent (klass);
274
275 gobject_class->constructed = gck_session_constructed;
276 gobject_class->get_property = gck_session_get_property;
277 gobject_class->set_property = gck_session_set_property;
278 gobject_class->dispose = gck_session_dispose;
279 gobject_class->finalize = gck_session_finalize;
280
281 klass->discard_handle = gck_session_real_discard_handle;
282
283 /**
284 * GckSession:module:
285 *
286 * The GckModule that this session is opened on.
287 */
288 g_object_class_install_property (gobject_class, PROP_MODULE,
289 g_param_spec_object ("module", "Module", "PKCS11 Module",
290 GCK_TYPE_MODULE,
291 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
292
293 /**
294 * GckSession:handle:
295 *
296 * The raw CK_SESSION_HANDLE handle of this session.
297 */
298 g_object_class_install_property (gobject_class, PROP_HANDLE,
299 g_param_spec_ulong ("handle", "Session Handle", "PKCS11 Session Handle",
300 0, G_MAXULONG, 0,
301 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
302
303 /**
304 * GckSession:slot:
305 *
306 * The GckSlot this session is opened on.
307 */
308 g_object_class_install_property (gobject_class, PROP_SLOT,
309 g_param_spec_object ("slot", "Slot that this session uses", "PKCS11 Slot",
310 GCK_TYPE_SLOT,
311 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
312
313 /**
314 * GckSession:options:
315 *
316 * The options this session was opened with.
317 */
318 g_object_class_install_property (gobject_class, PROP_OPTIONS,
319 g_param_spec_flags ("options", "Session Options", "Session Options",
320 GCK_TYPE_SESSION_OPTIONS, GCK_SESSION_READ_ONLY,
321 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
322
323 /**
324 * GckSession:interaction:
325 *
326 * Interaction object used to ask the user for pins when opening
327 * sessions. Used if the session_options of the enumerator have
328 * %GCK_SESSION_LOGIN_USER
329 */
330 g_object_class_install_property (gobject_class, PROP_INTERACTION,
331 g_param_spec_object ("interaction", "Interaction", "Interaction asking for pins",
332 G_TYPE_TLS_INTERACTION,
333 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
334
335 /**
336 * GckSession:opening-flags:
337 *
338 * Raw PKCS\#11 flags used to open the PKCS\#11 session.
339 */
340 g_object_class_install_property (gobject_class, PROP_OPENING_FLAGS,
341 g_param_spec_ulong ("opening-flags", "Opening flags", "PKCS#11 open session flags",
342 0, G_MAXULONG, 0,
343 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
344
345 /**
346 * GckSession:app-data:
347 *
348 * Raw PKCS\#11 application data used to open the PKCS\#11 session.
349 */
350 g_object_class_install_property (gobject_class, PROP_APP_DATA,
351 g_param_spec_pointer ("app-data", "App data", "PKCS#11 application data",
352 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
353
354 /**
355 * GckSession::discard-handle:
356 * @session: The session.
357 * @handle: The handle being discarded.
358 *
359 * When a GckSession is being disposed of it emits this signal to allow
360 * a session pool to pick up the handle and keep it around.
361 *
362 * If no signal handler claims the handle, then it is closed.
363 *
364 * Returns: Whether or not this handle was claimed.
365 */
366 signals[DISCARD_HANDLE] = g_signal_new ("discard-handle", GCK_TYPE_SESSION,
367 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GckSessionClass, discard_handle),
368 g_signal_accumulator_true_handled, NULL,
369 _gck_marshal_BOOLEAN__ULONG, G_TYPE_BOOLEAN, 1, G_TYPE_ULONG);
370 }
371
372 typedef struct OpenSession {
373 GckArguments base;
374 GTlsInteraction *interaction;
375 GckSlot *slot;
376 gulong flags;
377 gpointer app_data;
378 CK_NOTIFY notify;
379 gboolean auto_login;
380 CK_SESSION_HANDLE session;
381 } OpenSession;
382
383 static void
free_open_session(OpenSession * args)384 free_open_session (OpenSession *args)
385 {
386 g_clear_object (&args->interaction);
387 g_clear_object (&args->slot);
388 g_free (args);
389 }
390
391 static CK_RV
perform_open_session(OpenSession * args)392 perform_open_session (OpenSession *args)
393 {
394 GTlsInteraction *interaction;
395 CK_RV rv = CKR_OK;
396
397 /* First step, open session */
398 if (!args->session) {
399 rv = (args->base.pkcs11->C_OpenSession) (args->base.handle, args->flags,
400 args->app_data, args->notify, &args->session);
401 }
402
403 if (rv != CKR_OK || !args->auto_login)
404 return rv;
405
406 /* Compatibility, hook into GckModule signals if no interaction set */
407 if (args->interaction)
408 interaction = g_object_ref (args->interaction);
409 else
410 interaction = _gck_interaction_new (args->slot);
411
412 rv = _gck_session_authenticate_token (args->base.pkcs11, args->session,
413 args->slot, interaction, NULL);
414
415 g_object_unref (interaction);
416
417 return rv;
418 }
419
420 static gboolean
gck_session_initable_init(GInitable * initable,GCancellable * cancellable,GError ** error)421 gck_session_initable_init (GInitable *initable,
422 GCancellable *cancellable,
423 GError **error)
424 {
425 GckSession *self = GCK_SESSION (initable);
426 OpenSession args = { GCK_ARGUMENTS_INIT, 0, };
427 GckModule *module = NULL;
428 gboolean ret = FALSE;
429 gboolean want_login;
430
431 want_login = (self->pv->options & GCK_SESSION_LOGIN_USER) == GCK_SESSION_LOGIN_USER;
432
433 /* Already have a session setup? */
434 if (self->pv->handle && !want_login)
435 return TRUE;
436
437 g_object_ref (self);
438 module = gck_session_get_module (self);
439
440 /* Open a new session */
441 args.slot = self->pv->slot;
442 args.app_data = self->pv->app_data;
443 args.notify = NULL;
444 args.session = self->pv->handle;
445 args.flags = self->pv->opening_flags;
446 args.interaction = self->pv->interaction ? g_object_ref (self->pv->interaction) : NULL;
447 args.auto_login = want_login;
448
449 if (_gck_call_sync (self->pv->slot, perform_open_session, NULL, &args, cancellable, error)) {
450 self->pv->handle = args.session;
451 ret = TRUE;
452 }
453
454 g_clear_object (&args.interaction);
455 g_object_unref (module);
456 g_object_unref (self);
457
458 return ret;
459 }
460
461 static void
gck_session_initable_iface(GInitableIface * iface)462 gck_session_initable_iface (GInitableIface *iface)
463 {
464 iface->init = gck_session_initable_init;
465 }
466
467 static void
gck_session_initable_init_async(GAsyncInitable * initable,int io_priority,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)468 gck_session_initable_init_async (GAsyncInitable *initable,
469 int io_priority,
470 GCancellable *cancellable,
471 GAsyncReadyCallback callback,
472 gpointer user_data)
473 {
474 GckSession *self = GCK_SESSION (initable);
475 OpenSession *args;
476 gboolean want_login;
477 GckCall *call;
478
479 g_object_ref (self);
480
481 call = _gck_call_async_prep (self->pv->slot, perform_open_session, NULL,
482 sizeof (*args), free_open_session);
483
484 args = _gck_call_get_arguments (call);
485 want_login = (self->pv->options & GCK_SESSION_LOGIN_USER) == GCK_SESSION_LOGIN_USER;
486 args->session = self->pv->handle;
487
488 _gck_call_async_ready (call, self, cancellable, callback, user_data);
489
490 /* Already have a session setup? */
491 if (self->pv->handle && !want_login) {
492 _gck_call_async_short (call, CKR_OK);
493 g_object_unref (self);
494 return;
495 }
496
497 args->app_data = self->pv->app_data;
498 args->notify = NULL;
499 args->slot = g_object_ref (self->pv->slot);
500 args->interaction = self->pv->interaction ? g_object_ref (self->pv->interaction) : NULL;
501 args->auto_login = want_login;
502 args->flags = self->pv->opening_flags;
503
504 _gck_call_async_go (call);
505 g_object_unref (self);
506 }
507
508 static gboolean
gck_session_initable_init_finish(GAsyncInitable * initable,GAsyncResult * result,GError ** error)509 gck_session_initable_init_finish (GAsyncInitable *initable,
510 GAsyncResult *result,
511 GError **error)
512 {
513 GckSession *self = GCK_SESSION (initable);
514 gboolean ret = FALSE;
515
516 g_object_ref (self);
517
518 {
519 OpenSession *args;
520
521 if (_gck_call_basic_finish (result, error)) {
522 args = _gck_call_async_result_arguments (result, OpenSession);
523 self->pv->handle = args->session;
524 ret = TRUE;
525 }
526 }
527
528 g_object_unref (self);
529
530 return ret;
531 }
532
533 static void
gck_session_async_initable_iface(GAsyncInitableIface * iface)534 gck_session_async_initable_iface (GAsyncInitableIface *iface)
535 {
536 iface->init_async = gck_session_initable_init_async;
537 iface->init_finish = gck_session_initable_init_finish;
538 }
539
540 /* ----------------------------------------------------------------------------
541 * PUBLIC
542 */
543
544 /**
545 * GckSessionInfo:
546 * @slot_id: The handle of the PKCS11 slot that this session is opened on.
547 * @state: The user login state of the session.
548 * @flags: Various PKCS11 flags.
549 * @device_error: The last device error that occurred from an operation on this session.
550 *
551 * Information about the session. This is analogous to a CK_SESSION_INFO structure.
552 *
553 * When done with this structure, release it using gck_session_info_free().
554 */
555
G_DEFINE_BOXED_TYPE(GckSessionInfo,gck_session_info,gck_session_info_copy,gck_session_info_free)556 G_DEFINE_BOXED_TYPE (GckSessionInfo, gck_session_info,
557 gck_session_info_copy, gck_session_info_free)
558
559 /**
560 * gck_session_info_copy:
561 * @session_info: a session info structure
562 *
563 * Make a new copy of a session info structure.
564 *
565 * Returns: (transfer full): a new copy of the session info
566 */
567 GckSessionInfo *
568 gck_session_info_copy (GckSessionInfo *session_info)
569 {
570 return g_memdup (session_info, sizeof (GckSessionInfo));
571 }
572
573 /**
574 * gck_session_info_free:
575 * @session_info: Session info to free.
576 *
577 * Free the GckSessionInfo structure and all associated memory.
578 **/
579 void
gck_session_info_free(GckSessionInfo * session_info)580 gck_session_info_free (GckSessionInfo *session_info)
581 {
582 if (!session_info)
583 return;
584 g_free (session_info);
585 }
586
587 /**
588 * gck_session_from_handle:
589 * @slot: The slot which the session belongs to.
590 * @session_handle: the raw PKCS\#11 handle of the session
591 * @options: Session options. Those which are used during opening a session have no effect.
592 *
593 * Initialize a GckSession object from a raw PKCS\#11 session handle.
594 * Usually one would use the gck_slot_open_session() function to
595 * create a session.
596 *
597 * Returns: (transfer full): the new GckSession object
598 **/
599 GckSession *
gck_session_from_handle(GckSlot * slot,gulong session_handle,GckSessionOptions options)600 gck_session_from_handle (GckSlot *slot,
601 gulong session_handle,
602 GckSessionOptions options)
603 {
604 GckSession *session;
605
606 g_return_val_if_fail (GCK_IS_SLOT (slot), NULL);
607
608 session = g_object_new (GCK_TYPE_SESSION,
609 "handle", session_handle,
610 "slot", slot,
611 "options", options,
612 NULL);
613
614 return session;
615 }
616
617 /**
618 * gck_session_get_handle:
619 * @self: The session object.
620 *
621 * Get the raw PKCS\#11 session handle from a GckSession object.
622 *
623 * Return value: The raw session handle.
624 **/
625 gulong
gck_session_get_handle(GckSession * self)626 gck_session_get_handle (GckSession *self)
627 {
628 g_return_val_if_fail (GCK_IS_SESSION (self), (CK_SESSION_HANDLE)-1);
629 return self->pv->handle;
630 }
631
632 /**
633 * gck_session_get_module:
634 * @self: The session object.
635 *
636 * Get the PKCS\#11 module to which this session belongs.
637 *
638 * Returns: (transfer full): the module, which should be unreffed after use
639 **/
640 GckModule *
gck_session_get_module(GckSession * self)641 gck_session_get_module (GckSession *self)
642 {
643 g_return_val_if_fail (GCK_IS_SESSION (self), NULL);
644 return gck_slot_get_module (self->pv->slot);
645 }
646
647 /**
648 * gck_session_get_slot:
649 * @self: The session object.
650 *
651 * Get the PKCS\#11 slot to which this session belongs.
652 *
653 * Return value: (transfer full): The slot, which should be unreffed after use.
654 **/
655 GckSlot *
gck_session_get_slot(GckSession * self)656 gck_session_get_slot (GckSession *self)
657 {
658 g_return_val_if_fail (GCK_IS_SESSION (self), NULL);
659 g_return_val_if_fail (GCK_IS_SLOT (self->pv->slot), NULL);
660 return g_object_ref (self->pv->slot);
661 }
662
663 /**
664 * gck_session_get_info:
665 * @self: The session object.
666 *
667 * Get information about the session.
668 *
669 * Returns: (transfer full): the session info. Use the gck_session_info_free()
670 * to release when done
671 **/
672 GckSessionInfo*
gck_session_get_info(GckSession * self)673 gck_session_get_info (GckSession *self)
674 {
675 GckSessionInfo *sessioninfo;
676 CK_FUNCTION_LIST_PTR funcs;
677 CK_SESSION_INFO info;
678 GckModule *module;
679 CK_RV rv;
680
681 g_return_val_if_fail (GCK_IS_SESSION (self), NULL);
682
683 module = gck_session_get_module (self);
684 g_return_val_if_fail (GCK_IS_MODULE (module), NULL);
685
686 funcs = gck_module_get_functions (module);
687 g_return_val_if_fail (funcs, NULL);
688
689 memset (&info, 0, sizeof (info));
690 rv = (funcs->C_GetSessionInfo) (self->pv->handle, &info);
691
692 g_object_unref (module);
693
694 if (rv != CKR_OK) {
695 g_warning ("couldn't get session info: %s", gck_message_from_rv (rv));
696 return NULL;
697 }
698
699 sessioninfo = g_new0 (GckSessionInfo, 1);
700 sessioninfo->flags = info.flags;
701 sessioninfo->slot_id = info.slotID;
702 sessioninfo->state = info.state;
703 sessioninfo->device_error = info.ulDeviceError;
704
705 return sessioninfo;
706 }
707
708 /**
709 * gck_session_get_state:
710 * @self: the session
711 *
712 * Get the session state. The state is the various PKCS\#11 CKS_XXX flags.
713 *
714 * Returns: the session state
715 */
716 gulong
gck_session_get_state(GckSession * self)717 gck_session_get_state (GckSession *self)
718 {
719 CK_FUNCTION_LIST_PTR funcs;
720 CK_SESSION_INFO info;
721 GckModule *module;
722 CK_RV rv;
723
724 g_return_val_if_fail (GCK_IS_SESSION (self), 0);
725
726 module = gck_session_get_module (self);
727 g_return_val_if_fail (GCK_IS_MODULE (module), 0);
728
729 funcs = gck_module_get_functions (module);
730 g_return_val_if_fail (funcs, 0);
731
732 memset (&info, 0, sizeof (info));
733 rv = (funcs->C_GetSessionInfo) (self->pv->handle, &info);
734
735 g_object_unref (module);
736
737 if (rv != CKR_OK) {
738 g_warning ("couldn't get session info: %s", gck_message_from_rv (rv));
739 return 0;
740 }
741
742 return info.state;
743 }
744
745 /**
746 * gck_session_get_options:
747 * @self: The session to get options from.
748 *
749 * Get the options this session was opened with.
750 *
751 * Return value: The session options.
752 **/
753 GckSessionOptions
gck_session_get_options(GckSession * self)754 gck_session_get_options (GckSession *self)
755 {
756 g_return_val_if_fail (GCK_IS_SESSION (self), 0);
757 return self->pv->options;
758 }
759
760 /**
761 * gck_session_get_interaction:
762 * @self: the session
763 *
764 * Get the interaction object set on this session, which is used to prompt
765 * for pins and the like.
766 *
767 * Returns: (transfer full) (nullable): the interaction object, or %NULL
768 */
769 GTlsInteraction *
gck_session_get_interaction(GckSession * self)770 gck_session_get_interaction (GckSession *self)
771 {
772 g_return_val_if_fail (GCK_IS_SESSION (self), NULL);
773
774 if (self->pv->interaction)
775 return g_object_ref (self->pv->interaction);
776
777 return NULL;
778 }
779
780 /**
781 * gck_session_set_interaction:
782 * @self: the session
783 * @interaction: (nullable): the interaction or %NULL
784 *
785 * Set the interaction object on this session, which is used to prompt for
786 * pins and the like.
787 */
788 void
gck_session_set_interaction(GckSession * self,GTlsInteraction * interaction)789 gck_session_set_interaction (GckSession *self,
790 GTlsInteraction *interaction)
791 {
792 GTlsInteraction *previous;
793 g_return_if_fail (GCK_IS_SESSION (self));
794 g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
795
796 if (interaction)
797 g_object_ref (interaction);
798
799 g_mutex_lock (self->pv->mutex);
800
801 previous = self->pv->interaction;
802 self->pv->interaction = interaction;
803
804 g_mutex_unlock (self->pv->mutex);
805
806 if (previous)
807 g_object_unref (previous);
808 }
809
810 /**
811 * gck_session_open:
812 * @slot: the slot to open session on
813 * @options: session options
814 * @interaction: (nullable): optional interaction for logins or object authentication
815 * @cancellable: optional cancellation object
816 * @error: location to place error or %NULL
817 *
818 * Open a session on the slot. This call may block for an indefinite period.
819 *
820 * Returns: (transfer full): the new session
821 */
822 GckSession *
gck_session_open(GckSlot * slot,GckSessionOptions options,GTlsInteraction * interaction,GCancellable * cancellable,GError ** error)823 gck_session_open (GckSlot *slot,
824 GckSessionOptions options,
825 GTlsInteraction *interaction,
826 GCancellable *cancellable,
827 GError **error)
828 {
829 return g_initable_new (GCK_TYPE_SESSION, cancellable, error,
830 "slot", slot,
831 "interaction", interaction,
832 "options", options,
833 NULL);
834 }
835
836 /**
837 * gck_session_open_async:
838 * @slot: the slot to open session on
839 * @options: session options
840 * @interaction: (nullable): optional interaction for logins or object authentication
841 * @cancellable: optional cancellation object
842 * @callback: called when the operation completes
843 * @user_data: data to pass to callback
844 *
845 * Open a session on the slot. This call will return immediately and complete
846 * asynchronously.
847 */
848 void
gck_session_open_async(GckSlot * slot,GckSessionOptions options,GTlsInteraction * interaction,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)849 gck_session_open_async (GckSlot *slot,
850 GckSessionOptions options,
851 GTlsInteraction *interaction,
852 GCancellable *cancellable,
853 GAsyncReadyCallback callback,
854 gpointer user_data)
855 {
856 g_async_initable_new_async (GCK_TYPE_SESSION, G_PRIORITY_DEFAULT,
857 cancellable, callback, user_data,
858 "slot", slot,
859 "interaction", interaction,
860 "options", options,
861 NULL);
862 }
863
864 /**
865 * gck_session_open_finish:
866 * @result: the result passed to the callback
867 * @error: location to return an error or %NULL
868 *
869 * Get the result of an open session operation.
870 *
871 * Returns: (transfer full): the new session
872 */
873 GckSession *
gck_session_open_finish(GAsyncResult * result,GError ** error)874 gck_session_open_finish (GAsyncResult *result,
875 GError **error)
876 {
877 GObject *ret;
878 GObject *source;
879
880 source = g_async_result_get_source_object (result);
881 ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source), result, error);
882 g_object_unref (source);
883
884 return ret ? GCK_SESSION (ret) : NULL;
885 }
886
887 /* ---------------------------------------------------------------------------------------------
888 * INIT PIN
889 */
890
891 typedef struct _InitPin {
892 GckArguments base;
893 guchar *pin;
894 gsize n_pin;
895 } InitPin;
896
897
898 static void
free_init_pin(InitPin * args)899 free_init_pin (InitPin *args)
900 {
901 g_free (args->pin);
902 g_free (args);
903 }
904
905 static CK_RV
perform_init_pin(InitPin * args)906 perform_init_pin (InitPin *args)
907 {
908 return (args->base.pkcs11->C_InitPIN) (args->base.handle, (CK_BYTE_PTR)args->pin,
909 args->n_pin);
910 }
911
912 /**
913 * gck_session_init_pin:
914 * @self: Initialize PIN for this session's slot.
915 * @pin: (nullable) (array length=n_pin): the user's PIN, or %NULL for
916 * protected authentication path
917 * @n_pin: the length of the PIN
918 * @cancellable: Optional cancellation object, or %NULL.
919 * @error: A location to return an error.
920 *
921 * Initialize the user's pin on this slot that this session is opened on.
922 * According to the PKCS\#11 standards, the session must be logged in with
923 * the CKU_SO user type.
924 *
925 * This call may block for an indefinite period.
926 *
927 * Return value: Whether successful or not.
928 **/
929 gboolean
gck_session_init_pin(GckSession * self,const guchar * pin,gsize n_pin,GCancellable * cancellable,GError ** error)930 gck_session_init_pin (GckSession *self, const guchar *pin, gsize n_pin,
931 GCancellable *cancellable, GError **error)
932 {
933 InitPin args = { GCK_ARGUMENTS_INIT, (guchar*)pin, n_pin };
934 return _gck_call_sync (self, perform_init_pin, NULL, &args, cancellable, error);
935
936 }
937
938 /**
939 * gck_session_init_pin_async:
940 * @self: Initialize PIN for this session's slot.
941 * @pin: (nullable) (array length=n_pin): the user's PIN, or %NULL for protected authentication path
942 * @n_pin: the length of the PIN
943 * @cancellable: Optional cancellation object, or %NULL.
944 * @callback: Called when the operation completes.
945 * @user_data: Data to pass to the callback.
946 *
947 * Initialize the user's pin on this slot that this session is opened on.
948 * According to the PKCS\#11 standards, the session must be logged in with
949 * the CKU_SO user type.
950 *
951 * This call will return immediately and completes asynchronously.
952 **/
953 void
gck_session_init_pin_async(GckSession * self,const guchar * pin,gsize n_pin,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)954 gck_session_init_pin_async (GckSession *self, const guchar *pin, gsize n_pin,
955 GCancellable *cancellable, GAsyncReadyCallback callback,
956 gpointer user_data)
957 {
958 GckCall *call;
959 InitPin* args;
960
961 call = _gck_call_async_prep (self, perform_init_pin, NULL, sizeof (*args), free_init_pin);
962 args = _gck_call_get_arguments (call);
963
964 args->pin = pin && n_pin ? g_memdup (pin, n_pin) : NULL;
965 args->n_pin = n_pin;
966
967 _gck_call_async_ready_go (call, self, cancellable, callback, user_data);
968 }
969
970 /**
971 * gck_session_init_pin_finish:
972 * @self: The session.
973 * @result: The result passed to the callback.
974 * @error: A location to return an error.
975 *
976 * Get the result of initializing a user's PIN.
977 *
978 * Return value: Whether the operation was successful or not.
979 **/
980 gboolean
gck_session_init_pin_finish(GckSession * self,GAsyncResult * result,GError ** error)981 gck_session_init_pin_finish (GckSession *self, GAsyncResult *result, GError **error)
982 {
983 return _gck_call_basic_finish (result, error);
984 }
985
986
987 /* ---------------------------------------------------------------------------------------------
988 * SET PIN
989 */
990
991 typedef struct _SetPin {
992 GckArguments base;
993 guchar *old_pin;
994 gsize n_old_pin;
995 guchar *new_pin;
996 gsize n_new_pin;
997 } SetPin;
998
999 static void
free_set_pin(SetPin * args)1000 free_set_pin (SetPin *args)
1001 {
1002 g_free (args->old_pin);
1003 g_free (args->new_pin);
1004 g_free (args);
1005 }
1006
1007 static CK_RV
perform_set_pin(SetPin * args)1008 perform_set_pin (SetPin *args)
1009 {
1010 return (args->base.pkcs11->C_SetPIN) (args->base.handle, (CK_BYTE_PTR)args->old_pin,
1011 args->n_old_pin, args->new_pin, args->n_new_pin);
1012 }
1013
1014 /**
1015 * gck_session_set_pin:
1016 * @self: Change the PIN for this session's slot.
1017 * @old_pin: (nullable) (array length=n_old_pin): the user's old PIN, or %NULL
1018 * for protected authentication path.
1019 * @n_old_pin: The length of the PIN.
1020 * @new_pin: (nullable) (array length=n_new_pin): the user's new PIN, or %NULL
1021 * for protected authentication path
1022 * @n_new_pin: The length of the PIN.
1023 * @cancellable: Optional cancellation object, or %NULL.
1024 * @error: A location to return an error.
1025 *
1026 * Change the user's pin on this slot that this session is opened on.
1027 *
1028 * This call may block for an indefinite period.
1029 *
1030 * Return value: Whether successful or not.
1031 **/
1032 gboolean
gck_session_set_pin(GckSession * self,const guchar * old_pin,gsize n_old_pin,const guchar * new_pin,gsize n_new_pin,GCancellable * cancellable,GError ** error)1033 gck_session_set_pin (GckSession *self, const guchar *old_pin, gsize n_old_pin,
1034 const guchar *new_pin, gsize n_new_pin, GCancellable *cancellable,
1035 GError **error)
1036 {
1037 SetPin args = { GCK_ARGUMENTS_INIT, (guchar*)old_pin, n_old_pin, (guchar*)new_pin, n_new_pin };
1038 return _gck_call_sync (self, perform_set_pin, NULL, &args, cancellable, error);
1039 }
1040
1041 /**
1042 * gck_session_set_pin_async:
1043 * @self: Change the PIN for this session's slot.
1044 * @old_pin: (nullable) (array length=n_new_pin): the user's old PIN, or %NULL
1045 * for protected authentication path
1046 * @n_old_pin: the length of the old PIN
1047 * @new_pin: (nullable) (array length=n_new_pin): the user's new PIN, or %NULL
1048 * for protected authentication path
1049 * @n_new_pin: the length of the new PIN
1050 * @cancellable: Optional cancellation object, or %NULL.
1051 * @callback: Called when the operation completes.
1052 * @user_data: Data to pass to the callback.
1053 *
1054 * Change the user's pin on this slot that this session is opened on.
1055 *
1056 * This call will return immediately and completes asynchronously.
1057 **/
1058 void
gck_session_set_pin_async(GckSession * self,const guchar * old_pin,gsize n_old_pin,const guchar * new_pin,gsize n_new_pin,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1059 gck_session_set_pin_async (GckSession *self, const guchar *old_pin, gsize n_old_pin,
1060 const guchar *new_pin, gsize n_new_pin, GCancellable *cancellable,
1061 GAsyncReadyCallback callback, gpointer user_data)
1062 {
1063 SetPin* args;
1064 GckCall *call;
1065
1066 call = _gck_call_async_prep (self, perform_set_pin, NULL, sizeof (*args), free_set_pin);
1067 args = _gck_call_get_arguments (call);
1068
1069 args->old_pin = old_pin && n_old_pin ? g_memdup (old_pin, n_old_pin) : NULL;
1070 args->n_old_pin = n_old_pin;
1071 args->new_pin = new_pin && n_new_pin ? g_memdup (new_pin, n_new_pin) : NULL;
1072 args->n_new_pin = n_new_pin;
1073
1074 _gck_call_async_ready_go (call, self, cancellable, callback, user_data);
1075 }
1076
1077 /**
1078 * gck_session_set_pin_finish:
1079 * @self: The session.
1080 * @result: The result passed to the callback.
1081 * @error: A location to return an error.
1082 *
1083 * Get the result of changing a user's PIN.
1084 *
1085 * Return value: Whether the operation was successful or not.
1086 **/
1087 gboolean
gck_session_set_pin_finish(GckSession * self,GAsyncResult * result,GError ** error)1088 gck_session_set_pin_finish (GckSession *self, GAsyncResult *result, GError **error)
1089 {
1090 return _gck_call_basic_finish (result, error);
1091 }
1092
1093
1094 /* ---------------------------------------------------------------------------------------------
1095 * LOGIN
1096 */
1097
1098 typedef struct _Login {
1099 GckArguments base;
1100 gulong user_type;
1101 guchar *pin;
1102 gsize n_pin;
1103 } Login;
1104
1105 static void
free_login(Login * args)1106 free_login (Login *args)
1107 {
1108 g_free (args->pin);
1109 g_free (args);
1110 }
1111
1112 static CK_RV
perform_login(Login * args)1113 perform_login (Login *args)
1114 {
1115 return (args->base.pkcs11->C_Login) (args->base.handle, args->user_type,
1116 (CK_BYTE_PTR)args->pin, args->n_pin);
1117 }
1118
1119 /**
1120 * gck_session_login:
1121 * @self: Log in to this session.
1122 * @user_type: The type of login user.
1123 * @pin: (nullable) (array length=n_pin): the user's PIN, or %NULL for
1124 * protected authentication path
1125 * @n_pin: The length of the PIN.
1126 * @cancellable: Optional cancellation object, or %NULL.
1127 * @error: A location to return an error.
1128 *
1129 * Login the user on the session. This call may block for
1130 * an indefinite period.
1131 *
1132 * Return value: Whether successful or not.
1133 **/
1134 gboolean
gck_session_login(GckSession * self,gulong user_type,const guchar * pin,gsize n_pin,GCancellable * cancellable,GError ** error)1135 gck_session_login (GckSession *self, gulong user_type, const guchar *pin,
1136 gsize n_pin, GCancellable *cancellable, GError **error)
1137 {
1138 Login args = { GCK_ARGUMENTS_INIT, user_type, (guchar*)pin, n_pin };
1139 return _gck_call_sync (self, perform_login, NULL, &args, cancellable, error);
1140
1141 }
1142
1143 /**
1144 * gck_session_login_async:
1145 * @self: Log in to this session.
1146 * @user_type: The type of login user.
1147 * @pin: (nullable) (array length=n_pin): the user's PIN, or %NULL for
1148 * protected authentication path
1149 * @n_pin: The length of the PIN.
1150 * @cancellable: Optional cancellation object, or %NULL.
1151 * @callback: Called when the operation completes.
1152 * @user_data: Data to pass to the callback.
1153 *
1154 * Login the user on the session. This call will return
1155 * immediately and completes asynchronously.
1156 **/
1157 void
gck_session_login_async(GckSession * self,gulong user_type,const guchar * pin,gsize n_pin,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1158 gck_session_login_async (GckSession *self, gulong user_type, const guchar *pin,
1159 gsize n_pin, GCancellable *cancellable, GAsyncReadyCallback callback,
1160 gpointer user_data)
1161 {
1162 Login* args;
1163 GckCall *call;
1164
1165 call = _gck_call_async_prep (self, perform_login, NULL, sizeof (*args), free_login);
1166 args = _gck_call_get_arguments (call);
1167
1168 args->user_type = user_type;
1169 args->pin = pin && n_pin ? g_memdup (pin, n_pin) : NULL;
1170 args->n_pin = n_pin;
1171
1172 _gck_call_async_ready_go (call, self, cancellable, callback, user_data);
1173 }
1174
1175 /**
1176 * gck_session_login_finish:
1177 * @self: The session logged into.
1178 * @result: The result passed to the callback.
1179 * @error: A location to return an error.
1180 *
1181 * Get the result of a login operation.
1182 *
1183 * Return value: Whether the operation was successful or not.
1184 **/
1185 gboolean
gck_session_login_finish(GckSession * self,GAsyncResult * result,GError ** error)1186 gck_session_login_finish (GckSession *self, GAsyncResult *result, GError **error)
1187 {
1188 return _gck_call_basic_finish (result, error);
1189 }
1190
1191 typedef struct _Interactive {
1192 GckArguments base;
1193 GTlsInteraction *interaction;
1194 GCancellable *cancellable;
1195 GckSlot *token;
1196 } Interactive;
1197
1198 static void
free_interactive(Interactive * args)1199 free_interactive (Interactive *args)
1200 {
1201 g_clear_object (&args->token);
1202 g_clear_object (&args->cancellable);
1203 g_clear_object (&args->interaction);
1204 g_free (args);
1205 }
1206
1207 static CK_RV
perform_interactive(Interactive * args)1208 perform_interactive (Interactive *args)
1209 {
1210 return _gck_session_authenticate_token (args->base.pkcs11, args->base.handle,
1211 args->token, args->interaction, args->cancellable);
1212 }
1213
1214 /**
1215 * gck_session_login_interactive:
1216 * @self: session to use for login
1217 * @user_type: the type of login user
1218 * @interaction: (nullable): interaction to request PIN when necessary
1219 * @cancellable: optional cancellation object, or %NULL
1220 * @error: location to return an error
1221 *
1222 * Login the user on the session requesting the password interactively
1223 * when necessary. This call may block for an indefinite period.
1224 *
1225 * Return value: Whether successful or not.
1226 */
1227 gboolean
gck_session_login_interactive(GckSession * self,gulong user_type,GTlsInteraction * interaction,GCancellable * cancellable,GError ** error)1228 gck_session_login_interactive (GckSession *self,
1229 gulong user_type,
1230 GTlsInteraction *interaction,
1231 GCancellable *cancellable,
1232 GError **error)
1233 {
1234 Interactive args = { GCK_ARGUMENTS_INIT, interaction, cancellable, NULL, };
1235
1236 g_return_val_if_fail (GCK_IS_SESSION (self), FALSE);
1237 g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), FALSE);
1238 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1239 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1240
1241 /* TODO: For now this is all we support */
1242 g_return_val_if_fail (user_type == CKU_USER, FALSE);
1243
1244 args.token = self->pv->slot;
1245
1246 return _gck_call_sync (self, perform_interactive, NULL, &args, cancellable, error);
1247 }
1248
1249 /**
1250 * gck_session_login_interactive_async:
1251 * @self: session to use for login
1252 * @user_type: the type of login user
1253 * @interaction: (nullable): interaction to request PIN when necessary
1254 * @cancellable: optional cancellation object, or %NULL
1255 * @callback: called when the operation completes
1256 * @user_data: data to pass to the callback
1257 *
1258 * Login the user on the session prompting for passwords interactively when
1259 * necessary. This call will return immediately and completes asynchronously.
1260 **/
1261 void
gck_session_login_interactive_async(GckSession * self,gulong user_type,GTlsInteraction * interaction,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1262 gck_session_login_interactive_async (GckSession *self,
1263 gulong user_type,
1264 GTlsInteraction *interaction,
1265 GCancellable *cancellable,
1266 GAsyncReadyCallback callback,
1267 gpointer user_data)
1268 {
1269 Interactive* args;
1270 GckCall *call;
1271
1272 call = _gck_call_async_prep (self, perform_interactive, NULL, sizeof (*args), free_interactive);
1273 args = _gck_call_get_arguments (call);
1274
1275 g_return_if_fail (GCK_IS_SESSION (self));
1276 g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
1277 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1278
1279 /* TODO: For now this is all we support */
1280 g_return_if_fail (user_type == CKU_USER);
1281
1282 args->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1283 args->interaction = interaction ? g_object_ref (interaction) : NULL;
1284 args->token = g_object_ref (self->pv->slot);
1285
1286 _gck_call_async_ready_go (call, self, cancellable, callback, user_data);
1287 }
1288
1289 /**
1290 * gck_session_login_interactive_finish:
1291 * @self: the session logged into
1292 * @result: the result passed to the callback
1293 * @error: location to return an error
1294 *
1295 * Get the result of a login operation.
1296 *
1297 * Return value: Whether the operation was successful or not.
1298 **/
1299 gboolean
gck_session_login_interactive_finish(GckSession * self,GAsyncResult * result,GError ** error)1300 gck_session_login_interactive_finish (GckSession *self,
1301 GAsyncResult *result,
1302 GError **error)
1303 {
1304 g_return_val_if_fail (GCK_IS_SESSION (self), FALSE);
1305
1306 return _gck_call_basic_finish (result, error);
1307 }
1308
1309 /* LOGOUT */
1310
1311 static CK_RV
perform_logout(GckArguments * args)1312 perform_logout (GckArguments *args)
1313 {
1314 return (args->pkcs11->C_Logout) (args->handle);
1315 }
1316
1317 /**
1318 * gck_session_logout:
1319 * @self: Logout of this session.
1320 * @cancellable: Optional cancellation object, or %NULL.
1321 * @error: A location to return an error.
1322 *
1323 * Log out of the session. This call may block for an indefinite period.
1324 *
1325 * Return value: Whether the logout was successful or not.
1326 **/
1327 gboolean
gck_session_logout(GckSession * self,GCancellable * cancellable,GError ** error)1328 gck_session_logout (GckSession *self, GCancellable *cancellable, GError **error)
1329 {
1330 GckArguments args = GCK_ARGUMENTS_INIT;
1331 return _gck_call_sync (self, perform_logout, NULL, &args, cancellable, error);
1332 }
1333
1334 /**
1335 * gck_session_logout_async:
1336 * @self: Logout of this session.
1337 * @cancellable: Optional cancellation object, or %NULL.
1338 * @callback: Called when the operation completes.
1339 * @user_data: Data to pass to the callback.
1340 *
1341 * Log out of the session. This call returns immediately and completes
1342 * asynchronously.
1343 **/
1344 void
gck_session_logout_async(GckSession * self,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1345 gck_session_logout_async (GckSession *self, GCancellable *cancellable,
1346 GAsyncReadyCallback callback, gpointer user_data)
1347 {
1348 GckCall *call;
1349
1350 call = _gck_call_async_prep (self, perform_logout, NULL, 0, NULL);
1351 _gck_call_async_ready_go (call, self, cancellable, callback, user_data);
1352 }
1353
1354 /**
1355 * gck_session_logout_finish:
1356 * @self: Logout of this session.
1357 * @result: The result passed to the callback.
1358 * @error: A location to return an error.
1359 *
1360 * Get the result of logging out of a session.
1361 *
1362 * Return value: Whether the logout was successful or not.
1363 **/
1364 gboolean
gck_session_logout_finish(GckSession * self,GAsyncResult * result,GError ** error)1365 gck_session_logout_finish (GckSession *self, GAsyncResult *result, GError **error)
1366 {
1367 return _gck_call_basic_finish (result, error);
1368 }
1369
1370
1371
1372
1373 /* CREATE OBJECT */
1374
1375 typedef struct _CreateObject {
1376 GckArguments base;
1377 GckAttributes *attrs;
1378 CK_OBJECT_HANDLE object;
1379 } CreateObject;
1380
1381 static void
free_create_object(CreateObject * args)1382 free_create_object (CreateObject *args)
1383 {
1384 gck_attributes_unref (args->attrs);
1385 g_free (args);
1386 }
1387
1388 static CK_RV
perform_create_object(CreateObject * args)1389 perform_create_object (CreateObject *args)
1390 {
1391 CK_ATTRIBUTE_PTR attrs;
1392 CK_ULONG n_attrs;
1393 CK_RV rv;
1394
1395 attrs = _gck_attributes_commit_out (args->attrs, &n_attrs);
1396
1397 rv = (args->base.pkcs11->C_CreateObject) (args->base.handle,
1398 attrs, n_attrs,
1399 &args->object);
1400
1401 gchar *string = gck_attributes_to_string (args->attrs);
1402 if (rv == CKR_OK)
1403 g_debug ("created object: %s", string);
1404 else
1405 g_debug ("failed %s to create object: %s",
1406 _gck_stringize_rv (rv), string);
1407 g_free (string);
1408
1409 return rv;
1410 }
1411
1412 /**
1413 * gck_session_create_object:
1414 * @self: The session to create the object on.
1415 * @attrs: The attributes to create the object with.
1416 * @cancellable: Optional cancellation object, or %NULL.
1417 * @error: A location to return an error, or %NULL.
1418 *
1419 * Create a new PKCS\#11 object. This call may block for an
1420 * indefinite period.
1421 *
1422 * If the @attrs #GckAttributes is floating, it is consumed.
1423 *
1424 * Returns: (transfer full): the newly created object or %NULL if an error occurred
1425 **/
1426 GckObject *
gck_session_create_object(GckSession * self,GckAttributes * attrs,GCancellable * cancellable,GError ** error)1427 gck_session_create_object (GckSession *self, GckAttributes *attrs,
1428 GCancellable *cancellable, GError **error)
1429 {
1430 CreateObject args = { GCK_ARGUMENTS_INIT, attrs, 0 };
1431 gboolean ret;
1432
1433 g_return_val_if_fail (GCK_IS_SESSION (self), NULL);
1434 g_return_val_if_fail (attrs != NULL, NULL);
1435
1436 gck_attributes_ref_sink (attrs);
1437 ret = _gck_call_sync (self, perform_create_object, NULL, &args, cancellable, error);
1438 gck_attributes_unref (attrs);
1439
1440 if (!ret)
1441 return NULL;
1442
1443 return gck_object_from_handle (self, args.object);
1444 }
1445
1446 /**
1447 * gck_session_create_object_async:
1448 * @self: The session to create the object on.
1449 * @attrs: The attributes to create the object with.
1450 * @cancellable: Optional cancellation object or %NULL.
1451 * @callback: Called when the operation completes.
1452 * @user_data: Data to pass to the callback.
1453 *
1454 * Create a new PKCS\#11 object. This call will return immediately
1455 * and complete asynchronously.
1456 *
1457 * If the @attrs #GckAttributes is floating, it is consumed.
1458 **/
1459 void
gck_session_create_object_async(GckSession * self,GckAttributes * attrs,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1460 gck_session_create_object_async (GckSession *self, GckAttributes *attrs,
1461 GCancellable *cancellable, GAsyncReadyCallback callback,
1462 gpointer user_data)
1463 {
1464 GckCall *call;
1465 CreateObject *args;
1466
1467 call = _gck_call_async_prep (self, perform_create_object,
1468 NULL, sizeof (*args), free_create_object);
1469 args = _gck_call_get_arguments (call);
1470
1471 g_return_if_fail (attrs);
1472
1473 args->attrs = gck_attributes_ref_sink (attrs);
1474
1475 _gck_call_async_ready_go (call, self, cancellable, callback, user_data);
1476 }
1477
1478 /**
1479 * gck_session_create_object_finish:
1480 * @self: The session to create the object on.
1481 * @result: The result passed to the callback.
1482 * @error: A location to return an error, or %NULL.
1483 *
1484 * Get the result of creating a new PKCS\#11 object.
1485 *
1486 * Return value: (transfer full): the newly created object or %NULL if an error occurred
1487 **/
1488 GckObject *
gck_session_create_object_finish(GckSession * self,GAsyncResult * result,GError ** error)1489 gck_session_create_object_finish (GckSession *self, GAsyncResult *result, GError **error)
1490 {
1491 CreateObject *args;
1492
1493 args = _gck_call_async_result_arguments (result, CreateObject);
1494
1495 if (!_gck_call_basic_finish (result, error))
1496 return NULL;
1497 return gck_object_from_handle (self, args->object);
1498 }
1499
1500
1501
1502 /* FIND OBJECTS */
1503
1504 typedef struct _FindObjects {
1505 GckArguments base;
1506 GckAttributes *attrs;
1507 CK_OBJECT_HANDLE_PTR objects;
1508 CK_ULONG n_objects;
1509 } FindObjects;
1510
1511 static void
free_find_objects(FindObjects * args)1512 free_find_objects (FindObjects *args)
1513 {
1514 gck_attributes_unref (args->attrs);
1515 g_free (args->objects);
1516 g_free (args);
1517 }
1518
1519 static CK_RV
perform_find_objects(FindObjects * args)1520 perform_find_objects (FindObjects *args)
1521 {
1522 CK_OBJECT_HANDLE_PTR batch;
1523 CK_ULONG n_batch, n_found;
1524 CK_ATTRIBUTE_PTR attrs;
1525 CK_ULONG n_attrs;
1526 GArray *array;
1527 CK_RV rv;
1528
1529 gchar *string = gck_attributes_to_string (args->attrs);
1530 g_debug ("matching: %s", string);
1531 g_free (string);
1532
1533 attrs = _gck_attributes_commit_out (args->attrs, &n_attrs);
1534
1535 rv = (args->base.pkcs11->C_FindObjectsInit) (args->base.handle,
1536 attrs, n_attrs);
1537 if (rv != CKR_OK)
1538 return rv;
1539
1540 batch = NULL;
1541 n_found = n_batch = 4;
1542 array = g_array_new (0, 1, sizeof (CK_OBJECT_HANDLE));
1543
1544 do {
1545 /*
1546 * Reallocate and double in size:
1547 * - First time.
1548 * - Each time we found as many as batch
1549 */
1550
1551 if (n_found == n_batch) {
1552 n_batch *= 2;
1553 batch = g_realloc (batch, sizeof (CK_OBJECT_HANDLE) * n_batch);
1554 }
1555
1556 rv = (args->base.pkcs11->C_FindObjects) (args->base.handle,
1557 batch, n_batch, &n_found);
1558 if (rv != CKR_OK)
1559 break;
1560
1561 g_array_append_vals (array, batch, n_found);
1562
1563 } while (n_found > 0);
1564
1565 g_free (batch);
1566
1567 if (rv == CKR_OK) {
1568 args->n_objects = array->len;
1569 args->objects = (CK_OBJECT_HANDLE_PTR)g_array_free (array, FALSE);
1570 rv = (args->base.pkcs11->C_FindObjectsFinal) (args->base.handle);
1571 } else {
1572 args->objects = NULL;
1573 args->n_objects = 0;
1574 g_array_free (array, TRUE);
1575 }
1576
1577 return rv;
1578 }
1579
1580 /**
1581 * gck_session_find_handles:
1582 * @self: the session to find objects on
1583 * @match: the attributes to match against objects
1584 * @cancellable: optional cancellation object or %NULL
1585 * @n_handles: location to return number of handles
1586 * @error: a location to return an error or %NULL
1587 *
1588 * Find the objects matching the passed attributes. This call may
1589 * block for an indefinite period.
1590 *
1591 * If the @match #GckAttributes is floating, it is consumed.
1592 *
1593 * Returns: (transfer full) (array length=n_handles) (nullable): a list of
1594 * the matching objects, which may be empty
1595 **/
1596 gulong *
gck_session_find_handles(GckSession * self,GckAttributes * match,GCancellable * cancellable,gulong * n_handles,GError ** error)1597 gck_session_find_handles (GckSession *self,
1598 GckAttributes *match,
1599 GCancellable *cancellable,
1600 gulong *n_handles,
1601 GError **error)
1602 {
1603 FindObjects args = { GCK_ARGUMENTS_INIT, match, NULL, 0 };
1604 gulong *results = NULL;
1605
1606 g_return_val_if_fail (GCK_IS_SESSION (self), NULL);
1607 g_return_val_if_fail (match != NULL, NULL);
1608 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
1609 g_return_val_if_fail (n_handles != NULL, NULL);
1610 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1611
1612 gck_attributes_ref_sink (match);
1613 if (_gck_call_sync (self, perform_find_objects, NULL, &args, cancellable, error)) {
1614 results = args.objects;
1615 *n_handles = args.n_objects;
1616 args.objects = NULL;
1617 }
1618 gck_attributes_unref (match);
1619
1620 g_free (args.objects);
1621 return results;
1622 }
1623
1624 /**
1625 * gck_session_find_handles_async:
1626 * @self: the session to find objects on
1627 * @match: the attributes to match against the objects
1628 * @cancellable: optional cancellation object or %NULL
1629 * @callback: called when the operation completes
1630 * @user_data: data to pass to the callback
1631 *
1632 * Find the objects matching the passed attributes. This call will
1633 * return immediately and complete asynchronously.
1634 *
1635 * If the @match #GckAttributes is floating, it is consumed.
1636 **/
1637 void
gck_session_find_handles_async(GckSession * self,GckAttributes * match,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1638 gck_session_find_handles_async (GckSession *self,
1639 GckAttributes *match,
1640 GCancellable *cancellable,
1641 GAsyncReadyCallback callback,
1642 gpointer user_data)
1643 {
1644 GckCall *call;
1645 FindObjects *args;
1646
1647 g_return_if_fail (GCK_IS_SESSION (self));
1648 g_return_if_fail (match != NULL);
1649 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1650
1651 call = _gck_call_async_prep (self, perform_find_objects,
1652 NULL, sizeof (*args), free_find_objects);
1653 args = _gck_call_get_arguments (call);
1654 args->attrs = gck_attributes_ref_sink (match);
1655 _gck_call_async_ready_go (call, self, cancellable, callback, user_data);
1656 }
1657
1658 /**
1659 * gck_session_find_handles_finish:
1660 * @self: the session
1661 * @result: the asynchronous result
1662 * @n_handles: location to store number of handles returned
1663 * @error: a location to return an error on failure
1664 *
1665 * Get the result of a find handles operation.
1666 *
1667 * Returns: (transfer full) (array length=n_handles) (nullable): an array of
1668 * handles that matched, which may be empty, or %NULL on failure
1669 **/
1670 gulong *
gck_session_find_handles_finish(GckSession * self,GAsyncResult * result,gulong * n_handles,GError ** error)1671 gck_session_find_handles_finish (GckSession *self,
1672 GAsyncResult *result,
1673 gulong *n_handles,
1674 GError **error)
1675 {
1676 gulong *results = NULL;
1677 FindObjects *args;
1678
1679 g_return_val_if_fail (GCK_IS_SESSION (self), NULL);
1680 g_return_val_if_fail (n_handles != NULL, NULL);
1681 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1682
1683 args = _gck_call_async_result_arguments (result, FindObjects);
1684
1685 if (!_gck_call_basic_finish (result, error))
1686 return NULL;
1687 *n_handles = args->n_objects;
1688 results = args->objects;
1689 args->objects = NULL;
1690 return results;
1691 }
1692
1693 /**
1694 * gck_session_find_objects:
1695 * @self: The session to find objects on.
1696 * @match: the attributes to match
1697 * @cancellable: Optional cancellation object or %NULL.
1698 * @error: A location to return an error or %NULL.
1699 *
1700 * Find the objects matching the passed attributes. This call may
1701 * block for an indefinite period.
1702 *
1703 * If the @match #GckAttributes is floating, it is consumed.
1704 *
1705 * Returns: (transfer full) (element-type Gck.Object): a list of the matching
1706 * objects, which may be empty
1707 **/
1708 GList *
gck_session_find_objects(GckSession * self,GckAttributes * match,GCancellable * cancellable,GError ** error)1709 gck_session_find_objects (GckSession *self,
1710 GckAttributes *match,
1711 GCancellable *cancellable,
1712 GError **error)
1713 {
1714 GList *results = NULL;
1715 gulong *handles;
1716 gulong n_handles;
1717
1718 g_return_val_if_fail (GCK_IS_SESSION (self), NULL);
1719 g_return_val_if_fail (match != NULL, NULL);
1720 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
1721 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1722
1723 handles = gck_session_find_handles (self, match, cancellable, &n_handles, error);
1724 if (handles == NULL)
1725 return NULL;
1726
1727 results = gck_objects_from_handle_array (self, handles, n_handles);
1728 g_free (handles);
1729 return results;
1730 }
1731
1732 /**
1733 * gck_session_find_objects_async:
1734 * @self: The session to find objects on.
1735 * @match: The attributes to match.
1736 * @cancellable: Optional cancellation object or %NULL.
1737 * @callback: Called when the operation completes.
1738 * @user_data: Data to pass to the callback.
1739 *
1740 * Find the objects matching the passed attributes. This call will
1741 * return immediately and complete asynchronously.
1742 *
1743 * If the @match #GckAttributes is floating, it is consumed.
1744 **/
1745 void
gck_session_find_objects_async(GckSession * self,GckAttributes * match,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1746 gck_session_find_objects_async (GckSession *self,
1747 GckAttributes *match,
1748 GCancellable *cancellable,
1749 GAsyncReadyCallback callback,
1750 gpointer user_data)
1751 {
1752 g_return_if_fail (GCK_IS_SESSION (self));
1753 g_return_if_fail (match != NULL);
1754 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1755
1756 gck_session_find_handles_async (self, match, cancellable, callback, user_data);
1757 }
1758
1759 /**
1760 * gck_session_find_objects_finish:
1761 * @self: The session to find objects on.
1762 * @result: The attributes to match.
1763 * @error: A location to return an error.
1764 *
1765 * Get the result of a find operation.
1766 *
1767 * Returns: (transfer full) (element-type Gck.Object): a list of the matching
1768 * objects, which may be empty
1769 **/
1770 GList *
gck_session_find_objects_finish(GckSession * self,GAsyncResult * result,GError ** error)1771 gck_session_find_objects_finish (GckSession *self,
1772 GAsyncResult *result,
1773 GError **error)
1774 {
1775 GList *results = NULL;
1776 gulong *handles;
1777 gulong n_handles;
1778
1779 g_return_val_if_fail (GCK_IS_SESSION (self), NULL);
1780 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1781
1782 handles = gck_session_find_handles_finish (self, result, &n_handles, error);
1783 if (handles == NULL)
1784 return NULL;
1785
1786 results = gck_objects_from_handle_array (self, handles, n_handles);
1787 g_free (handles);
1788 return results;
1789
1790 }
1791
1792 /**
1793 * gck_session_enumerate_objects:
1794 * @self: session to enumerate objects on
1795 * @match: attributes that the objects must match, or empty for all objects
1796 *
1797 * Setup an enumerator for listing matching objects available via this session.
1798 *
1799 * If the @match #GckAttributes is floating, it is consumed.
1800 *
1801 * This call will not block but will return an enumerator immediately.
1802 *
1803 * Returns: (transfer full): a new enumerator
1804 **/
1805 GckEnumerator *
gck_session_enumerate_objects(GckSession * session,GckAttributes * match)1806 gck_session_enumerate_objects (GckSession *session,
1807 GckAttributes *match)
1808 {
1809 GckUriData *uri_data;
1810
1811 g_return_val_if_fail (match != NULL, NULL);
1812
1813 uri_data = gck_uri_data_new ();
1814 uri_data->attributes = gck_attributes_ref_sink (match);
1815
1816 return _gck_enumerator_new_for_session (session, uri_data);
1817 }
1818
1819 /* -----------------------------------------------------------------------------
1820 * KEY PAIR GENERATION
1821 */
1822
1823 typedef struct _GenerateKeyPair {
1824 GckArguments base;
1825 GckMechanism mechanism;
1826 GckAttributes *public_attrs;
1827 GckAttributes *private_attrs;
1828 CK_OBJECT_HANDLE public_key;
1829 CK_OBJECT_HANDLE private_key;
1830 } GenerateKeyPair;
1831
1832 static void
free_generate_key_pair(GenerateKeyPair * args)1833 free_generate_key_pair (GenerateKeyPair *args)
1834 {
1835 gck_attributes_unref (args->public_attrs);
1836 gck_attributes_unref (args->private_attrs);
1837 g_free (args);
1838 }
1839
1840 static CK_RV
perform_generate_key_pair(GenerateKeyPair * args)1841 perform_generate_key_pair (GenerateKeyPair *args)
1842 {
1843 CK_ATTRIBUTE_PTR pub_attrs, priv_attrs;
1844 CK_ULONG n_pub_attrs, n_priv_attrs;
1845
1846 g_assert (sizeof (CK_MECHANISM) == sizeof (GckMechanism));
1847
1848 pub_attrs = _gck_attributes_commit_out (args->public_attrs, &n_pub_attrs);
1849 priv_attrs = _gck_attributes_commit_out (args->private_attrs, &n_priv_attrs);
1850
1851 return (args->base.pkcs11->C_GenerateKeyPair) (args->base.handle,
1852 (CK_MECHANISM_PTR)&(args->mechanism),
1853 pub_attrs, n_pub_attrs,
1854 priv_attrs, n_priv_attrs,
1855 &args->public_key,
1856 &args->private_key);
1857 }
1858
1859 /**
1860 * gck_session_generate_key_pair:
1861 * @self: The session to use.
1862 * @mech_type: The mechanism type to use for key generation.
1863 * @public_attrs: Additional attributes for the generated public key.
1864 * @private_attrs: Additional attributes for the generated private key.
1865 * @public_key: (optional) (out): location to return the resulting public key
1866 * @private_key: (optional) (out): location to return the resulting private key.
1867 * @cancellable: Optional cancellation object, or %NULL.
1868 * @error: A location to return an error, or %NULL.
1869 *
1870 * Generate a new key pair of public and private keys. This call may block for an
1871 * indefinite period.
1872 *
1873 * If the @public_attrs and/or @private_attrs #GckAttributes is floating, it is
1874 * consumed.
1875 *
1876 * Return value: %TRUE if the operation succeeded.
1877 **/
1878 gboolean
gck_session_generate_key_pair(GckSession * self,gulong mech_type,GckAttributes * public_attrs,GckAttributes * private_attrs,GckObject ** public_key,GckObject ** private_key,GCancellable * cancellable,GError ** error)1879 gck_session_generate_key_pair (GckSession *self, gulong mech_type,
1880 GckAttributes *public_attrs, GckAttributes *private_attrs,
1881 GckObject **public_key, GckObject **private_key,
1882 GCancellable *cancellable, GError **error)
1883 {
1884 GckMechanism mech = { mech_type, NULL, 0 };
1885 return gck_session_generate_key_pair_full (self, &mech, public_attrs, private_attrs, public_key, private_key, cancellable, error);
1886 }
1887
1888 /**
1889 * gck_session_generate_key_pair_full:
1890 * @self: The session to use.
1891 * @mechanism: The mechanism to use for key generation.
1892 * @public_attrs: Additional attributes for the generated public key.
1893 * @private_attrs: Additional attributes for the generated private key.
1894 * @public_key: (optional) (out): a location to return the resulting public key
1895 * @private_key: (optional) (out): a location to return the resulting private key
1896 * @cancellable: Optional cancellation object, or %NULL.
1897 * @error: A location to return an error, or %NULL.
1898 *
1899 * Generate a new key pair of public and private keys. This call may block for an
1900 * indefinite period.
1901 *
1902 * If the @public_attrs and/or @private_attrs #GckAttributes is floating, it is
1903 * consumed.
1904 *
1905 * Return value: %TRUE if the operation succeeded.
1906 **/
1907 gboolean
gck_session_generate_key_pair_full(GckSession * self,GckMechanism * mechanism,GckAttributes * public_attrs,GckAttributes * private_attrs,GckObject ** public_key,GckObject ** private_key,GCancellable * cancellable,GError ** error)1908 gck_session_generate_key_pair_full (GckSession *self,
1909 GckMechanism *mechanism,
1910 GckAttributes *public_attrs,
1911 GckAttributes *private_attrs,
1912 GckObject **public_key,
1913 GckObject **private_key,
1914 GCancellable *cancellable,
1915 GError **error)
1916 {
1917 GenerateKeyPair args = { GCK_ARGUMENTS_INIT, GCK_MECHANISM_EMPTY, public_attrs, private_attrs, 0, 0 };
1918 gboolean ret;
1919
1920 g_return_val_if_fail (GCK_IS_SESSION (self), FALSE);
1921 g_return_val_if_fail (mechanism, FALSE);
1922 g_return_val_if_fail (public_attrs, FALSE);
1923 g_return_val_if_fail (private_attrs, FALSE);
1924
1925 /* Shallow copy of the mechanism structure */
1926 memcpy (&args.mechanism, mechanism, sizeof (args.mechanism));
1927
1928 gck_attributes_ref_sink (public_attrs);
1929 gck_attributes_ref_sink (private_attrs);
1930
1931 ret = _gck_call_sync (self, perform_generate_key_pair, NULL, &args, cancellable, error);
1932
1933 gck_attributes_unref (private_attrs);
1934 gck_attributes_unref (public_attrs);
1935
1936 if (!ret)
1937 return FALSE;
1938
1939 if (public_key)
1940 *public_key = gck_object_from_handle (self, args.public_key);
1941 if (private_key)
1942 *private_key = gck_object_from_handle (self, args.private_key);
1943 return TRUE;
1944 }
1945
1946 /**
1947 * gck_session_generate_key_pair_async:
1948 * @self: The session to use.
1949 * @mechanism: The mechanism to use for key generation.
1950 * @public_attrs: Additional attributes for the generated public key.
1951 * @private_attrs: Additional attributes for the generated private key.
1952 * @cancellable: Optional cancellation object or %NULL.
1953 * @callback: Called when the operation completes.
1954 * @user_data: Data to pass to the callback.
1955 *
1956 * Generate a new key pair of public and private keys. This call will
1957 * return immediately and complete asynchronously.
1958 *
1959 * If the @public_attrs and/or @private_attrs #GckAttributes is floating, it is
1960 * consumed.
1961 **/
1962 void
gck_session_generate_key_pair_async(GckSession * self,GckMechanism * mechanism,GckAttributes * public_attrs,GckAttributes * private_attrs,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1963 gck_session_generate_key_pair_async (GckSession *self, GckMechanism *mechanism,
1964 GckAttributes *public_attrs, GckAttributes *private_attrs,
1965 GCancellable *cancellable, GAsyncReadyCallback callback,
1966 gpointer user_data)
1967 {
1968 GckCall *call;
1969 GenerateKeyPair *args;
1970
1971 call = _gck_call_async_prep (self, perform_generate_key_pair,
1972 NULL, sizeof (*args), free_generate_key_pair);
1973 args = _gck_call_get_arguments (call);
1974
1975 g_return_if_fail (GCK_IS_SESSION (self));
1976 g_return_if_fail (mechanism);
1977 g_return_if_fail (public_attrs);
1978 g_return_if_fail (private_attrs);
1979
1980 /* Shallow copy of the mechanism structure */
1981 memcpy (&args->mechanism, mechanism, sizeof (args->mechanism));
1982
1983 args->public_attrs = gck_attributes_ref_sink (public_attrs);
1984 args->private_attrs = gck_attributes_ref_sink (private_attrs);
1985
1986 _gck_call_async_ready_go (call, self, cancellable, callback, user_data);
1987 }
1988
1989 /**
1990 * gck_session_generate_key_pair_finish:
1991 * @self: The session to use.
1992 * @result: The async result passed to the callback.
1993 * @public_key: (optional) (out): a location to return the resulting public key
1994 * @private_key: (optional) (out): a location to return the resulting private key
1995 * @error: A location to return an error.
1996 *
1997 * Get the result of a generate key pair operation.
1998 *
1999 * Return value: %TRUE if the operation succeeded.
2000 **/
2001 gboolean
gck_session_generate_key_pair_finish(GckSession * self,GAsyncResult * result,GckObject ** public_key,GckObject ** private_key,GError ** error)2002 gck_session_generate_key_pair_finish (GckSession *self,
2003 GAsyncResult *result,
2004 GckObject **public_key,
2005 GckObject **private_key,
2006 GError **error)
2007 {
2008 GenerateKeyPair *args;
2009
2010 g_return_val_if_fail (GCK_IS_SESSION (self), FALSE);
2011 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
2012 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2013
2014 args = _gck_call_async_result_arguments (result, GenerateKeyPair);
2015
2016 if (!_gck_call_basic_finish (result, error))
2017 return FALSE;
2018
2019 if (public_key)
2020 *public_key = gck_object_from_handle (self, args->public_key);
2021 if (private_key)
2022 *private_key = gck_object_from_handle (self, args->private_key);
2023 return TRUE;
2024 }
2025
2026 /* -----------------------------------------------------------------------------
2027 * KEY WRAPPING
2028 */
2029
2030 typedef struct _WrapKey {
2031 GckArguments base;
2032 GckMechanism mechanism;
2033 CK_OBJECT_HANDLE wrapper;
2034 CK_OBJECT_HANDLE wrapped;
2035 gpointer result;
2036 gulong n_result;
2037 } WrapKey;
2038
2039 static void
free_wrap_key(WrapKey * args)2040 free_wrap_key (WrapKey *args)
2041 {
2042 g_free (args->result);
2043 g_free (args);
2044 }
2045
2046 static CK_RV
perform_wrap_key(WrapKey * args)2047 perform_wrap_key (WrapKey *args)
2048 {
2049 CK_RV rv;
2050
2051 g_assert (sizeof (CK_MECHANISM) == sizeof (GckMechanism));
2052
2053 /* Get the length of the result */
2054 rv = (args->base.pkcs11->C_WrapKey) (args->base.handle,
2055 (CK_MECHANISM_PTR)&(args->mechanism),
2056 args->wrapper, args->wrapped,
2057 NULL, &args->n_result);
2058 if (rv != CKR_OK)
2059 return rv;
2060
2061 /* And try again with a real buffer */
2062 args->result = g_malloc0 (args->n_result);
2063 return (args->base.pkcs11->C_WrapKey) (args->base.handle,
2064 (CK_MECHANISM_PTR)&(args->mechanism),
2065 args->wrapper, args->wrapped,
2066 args->result, &args->n_result);
2067 }
2068
2069 /**
2070 * gck_session_wrap_key:
2071 * @self: The session to use.
2072 * @wrapper: The key to use for wrapping.
2073 * @mech_type: The mechanism type to use for wrapping.
2074 * @wrapped: The key to wrap.
2075 * @n_result: A location in which to return the length of the wrapped data.
2076 * @cancellable: A #GCancellable or %NULL
2077 * @error: A location to return an error, or %NULL.
2078 *
2079 * Wrap a key into a byte stream. This call may block for an
2080 * indefinite period.
2081 *
2082 * Returns: (transfer full) (array length=n_result): the wrapped data or %NULL
2083 * if the operation failed
2084 **/
2085 guchar *
gck_session_wrap_key(GckSession * self,GckObject * key,gulong mech_type,GckObject * wrapped,gsize * n_result,GCancellable * cancellable,GError ** error)2086 gck_session_wrap_key (GckSession *self, GckObject *key, gulong mech_type,
2087 GckObject *wrapped, gsize *n_result, GCancellable *cancellable, GError **error)
2088 {
2089 GckMechanism mech = { mech_type, NULL, 0 };
2090 return gck_session_wrap_key_full (self, key, &mech, wrapped, n_result, cancellable, error);
2091 }
2092
2093 /**
2094 * gck_session_wrap_key_full:
2095 * @self: The session to use.
2096 * @wrapper: The key to use for wrapping.
2097 * @mechanism: The mechanism to use for wrapping.
2098 * @wrapped: The key to wrap.
2099 * @n_result: A location in which to return the length of the wrapped data.
2100 * @cancellable: Optional cancellation object, or %NULL.
2101 * @error: A location to return an error, or %NULL.
2102 *
2103 * Wrap a key into a byte stream. This call may block for an
2104 * indefinite period.
2105 *
2106 * Returns: (transfer full) (array length=n_result): the wrapped data or %NULL
2107 * if the operation failed
2108 **/
2109 guchar *
gck_session_wrap_key_full(GckSession * self,GckObject * wrapper,GckMechanism * mechanism,GckObject * wrapped,gsize * n_result,GCancellable * cancellable,GError ** error)2110 gck_session_wrap_key_full (GckSession *self, GckObject *wrapper, GckMechanism *mechanism,
2111 GckObject *wrapped, gsize *n_result, GCancellable *cancellable,
2112 GError **error)
2113 {
2114 WrapKey args = { GCK_ARGUMENTS_INIT, GCK_MECHANISM_EMPTY, 0, 0, NULL, 0 };
2115 gboolean ret;
2116
2117 g_return_val_if_fail (GCK_IS_SESSION (self), FALSE);
2118 g_return_val_if_fail (mechanism, FALSE);
2119 g_return_val_if_fail (GCK_IS_OBJECT (wrapped), FALSE);
2120 g_return_val_if_fail (GCK_IS_OBJECT (wrapper), FALSE);
2121 g_return_val_if_fail (n_result, FALSE);
2122
2123 /* Shallow copy of the mechanism structure */
2124 memcpy (&args.mechanism, mechanism, sizeof (args.mechanism));
2125
2126 g_object_get (wrapper, "handle", &args.wrapper, NULL);
2127 g_return_val_if_fail (args.wrapper != 0, NULL);
2128 g_object_get (wrapped, "handle", &args.wrapped, NULL);
2129 g_return_val_if_fail (args.wrapped != 0, NULL);
2130
2131 ret = _gck_call_sync (self, perform_wrap_key, NULL, &args, cancellable, error);
2132
2133 if (!ret)
2134 return FALSE;
2135
2136 *n_result = args.n_result;
2137 return args.result;
2138 }
2139
2140 /**
2141 * gck_session_wrap_key_async:
2142 * @self: The session to use.
2143 * @wrapper: The key to use for wrapping.
2144 * @mechanism: The mechanism to use for wrapping.
2145 * @wrapped: The key to wrap.
2146 * @cancellable: Optional cancellation object or %NULL.
2147 * @callback: Called when the operation completes.
2148 * @user_data: Data to pass to the callback.
2149 *
2150 * Wrap a key into a byte stream. This call will
2151 * return immediately and complete asynchronously.
2152 **/
2153 void
gck_session_wrap_key_async(GckSession * self,GckObject * key,GckMechanism * mechanism,GckObject * wrapped,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)2154 gck_session_wrap_key_async (GckSession *self, GckObject *key, GckMechanism *mechanism,
2155 GckObject *wrapped, GCancellable *cancellable,
2156 GAsyncReadyCallback callback, gpointer user_data)
2157 {
2158 GckCall *call;
2159 WrapKey *args;
2160
2161 call = _gck_call_async_prep (self, perform_wrap_key,
2162 NULL, sizeof (*args), free_wrap_key);
2163 args = _gck_call_get_arguments (call);
2164
2165 g_return_if_fail (GCK_IS_SESSION (self));
2166 g_return_if_fail (mechanism);
2167 g_return_if_fail (GCK_IS_OBJECT (wrapped));
2168 g_return_if_fail (GCK_IS_OBJECT (key));
2169
2170 /* Shallow copy of the mechanism structure */
2171 memcpy (&args->mechanism, mechanism, sizeof (args->mechanism));
2172
2173 g_object_get (key, "handle", &args->wrapper, NULL);
2174 g_return_if_fail (args->wrapper != 0);
2175 g_object_get (wrapped, "handle", &args->wrapped, NULL);
2176 g_return_if_fail (args->wrapped != 0);
2177
2178 _gck_call_async_ready_go (call, self, cancellable, callback, user_data);
2179 }
2180
2181 /**
2182 * gck_session_wrap_key_finish:
2183 * @self: The session to use.
2184 * @result: The async result passed to the callback.
2185 * @n_result: A location in which to return the length of the wrapped data.
2186 * @error: A location to return an error.
2187 *
2188 * Get the result of a wrap key operation.
2189 *
2190 * Returns: (transfer full) (array length=n_result): the wrapped data or %NULL
2191 * if the operation failed
2192 **/
2193 guchar *
gck_session_wrap_key_finish(GckSession * self,GAsyncResult * result,gsize * n_result,GError ** error)2194 gck_session_wrap_key_finish (GckSession *self, GAsyncResult *result,
2195 gsize *n_result, GError **error)
2196 {
2197 WrapKey *args;
2198 gpointer ret;
2199
2200 g_return_val_if_fail (GCK_IS_SESSION (self), NULL);
2201 g_return_val_if_fail (n_result, NULL);
2202
2203 args = _gck_call_async_result_arguments (result, WrapKey);
2204
2205 if (!_gck_call_basic_finish (result, error))
2206 return NULL;
2207
2208 *n_result = args->n_result;
2209 args->n_result = 0;
2210 ret = args->result;
2211 args->result = NULL;
2212
2213 return ret;
2214 }
2215
2216 /* -----------------------------------------------------------------------------
2217 * KEY UNWRAPPING
2218 */
2219
2220 typedef struct _UnwrapKey {
2221 GckArguments base;
2222 GckMechanism mechanism;
2223 GckAttributes *attrs;
2224 CK_OBJECT_HANDLE wrapper;
2225 gconstpointer input;
2226 gulong n_input;
2227 CK_OBJECT_HANDLE unwrapped;
2228 } UnwrapKey;
2229
2230 static void
free_unwrap_key(UnwrapKey * args)2231 free_unwrap_key (UnwrapKey *args)
2232 {
2233 gck_attributes_unref (args->attrs);
2234 g_free (args);
2235 }
2236
2237 static CK_RV
perform_unwrap_key(UnwrapKey * args)2238 perform_unwrap_key (UnwrapKey *args)
2239 {
2240 CK_ATTRIBUTE_PTR attrs;
2241 CK_ULONG n_attrs;
2242
2243 g_assert (sizeof (CK_MECHANISM) == sizeof (GckMechanism));
2244
2245 attrs = _gck_attributes_commit_out (args->attrs, &n_attrs);
2246
2247 return (args->base.pkcs11->C_UnwrapKey) (args->base.handle,
2248 (CK_MECHANISM_PTR)&(args->mechanism),
2249 args->wrapper, (CK_BYTE_PTR)args->input,
2250 args->n_input, attrs, n_attrs,
2251 &args->unwrapped);
2252 }
2253
2254 /**
2255 * gck_session_unwrap_key:
2256 * @self: The session to use.
2257 * @wrapper: The key to use for unwrapping.
2258 * @mech_type: The mechanism to use for unwrapping.
2259 * @input: (array length=n_input): the wrapped data as a byte stream
2260 * @n_input: The length of the wrapped data.
2261 * @attrs: Additional attributes for the unwrapped key.
2262 * @cancellable: Optional cancellation object, or %NULL.
2263 * @error: A location to return an error, or %NULL.
2264 *
2265 * Unwrap a key from a byte stream. This call may block for an
2266 * indefinite period.
2267 *
2268 * If the @attrs #GckAttributes is floating, it is consumed.
2269 *
2270 * Returns: (transfer full): the new unwrapped key or %NULL if the
2271 * operation failed
2272 **/
2273 GckObject *
gck_session_unwrap_key(GckSession * self,GckObject * wrapper,gulong mech_type,const guchar * input,gsize n_input,GckAttributes * attrs,GCancellable * cancellable,GError ** error)2274 gck_session_unwrap_key (GckSession *self,
2275 GckObject *wrapper,
2276 gulong mech_type,
2277 const guchar *input,
2278 gsize n_input,
2279 GckAttributes *attrs,
2280 GCancellable *cancellable,
2281 GError **error)
2282 {
2283 GckMechanism mech = { mech_type, NULL, 0 };
2284 return gck_session_unwrap_key_full (self, wrapper, &mech, input, n_input, attrs, cancellable, error);
2285 }
2286
2287 /**
2288 * gck_session_unwrap_key_full:
2289 * @self: The session to use.
2290 * @wrapper: The key to use for unwrapping.
2291 * @mechanism: The mechanism to use for unwrapping.
2292 * @input: (array length=n_input): the wrapped data as a byte stream
2293 * @n_input: The length of the wrapped data.
2294 * @attrs: Additional attributes for the unwrapped key.
2295 * @cancellable: Optional cancellation object, or %NULL.
2296 * @error: A location to return an error, or %NULL.
2297 *
2298 * Unwrap a key from a byte stream. This call may block for an
2299 * indefinite period.
2300 *
2301 * If the @attrs #GckAttributes is floating, it is consumed.
2302 *
2303 * Returns: (transfer full): the new unwrapped key or %NULL if the operation
2304 * failed
2305 **/
2306 GckObject *
gck_session_unwrap_key_full(GckSession * self,GckObject * wrapper,GckMechanism * mechanism,const guchar * input,gsize n_input,GckAttributes * attrs,GCancellable * cancellable,GError ** error)2307 gck_session_unwrap_key_full (GckSession *self,
2308 GckObject *wrapper,
2309 GckMechanism *mechanism,
2310 const guchar *input,
2311 gsize n_input,
2312 GckAttributes *attrs,
2313 GCancellable *cancellable,
2314 GError **error)
2315 {
2316 UnwrapKey args = { GCK_ARGUMENTS_INIT, GCK_MECHANISM_EMPTY, attrs, 0, input, n_input, 0 };
2317 gboolean ret;
2318
2319 g_return_val_if_fail (GCK_IS_SESSION (self), FALSE);
2320 g_return_val_if_fail (GCK_IS_OBJECT (wrapper), FALSE);
2321 g_return_val_if_fail (mechanism, FALSE);
2322 g_return_val_if_fail (attrs, FALSE);
2323
2324 /* Shallow copy of the mechanism structure */
2325 memcpy (&args.mechanism, mechanism, sizeof (args.mechanism));
2326
2327 g_object_get (wrapper, "handle", &args.wrapper, NULL);
2328 g_return_val_if_fail (args.wrapper != 0, NULL);
2329
2330 gck_attributes_ref_sink (attrs);
2331
2332 ret = _gck_call_sync (self, perform_unwrap_key, NULL, &args, cancellable, error);
2333
2334 gck_attributes_unref (attrs);
2335
2336 if (!ret)
2337 return NULL;
2338
2339 return gck_object_from_handle (self, args.unwrapped);
2340 }
2341
2342 /**
2343 * gck_session_unwrap_key_async:
2344 * @self: The session to use.
2345 * @wrapper: The key to use for unwrapping.
2346 * @mechanism: The mechanism to use for unwrapping.
2347 * @input: (array length=n_input): the wrapped data as a byte stream
2348 * @n_input: The length of the wrapped data.
2349 * @attrs: Additional attributes for the unwrapped key.
2350 * @cancellable: Optional cancellation object or %NULL.
2351 * @callback: Called when the operation completes.
2352 * @user_data: Data to pass to the callback.
2353 *
2354 * Unwrap a key from a byte stream. This call will
2355 * return immediately and complete asynchronously.
2356 *
2357 * If the @attrs #GckAttributes is floating, it is consumed.
2358 **/
2359 void
gck_session_unwrap_key_async(GckSession * self,GckObject * wrapper,GckMechanism * mechanism,const guchar * input,gsize n_input,GckAttributes * attrs,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)2360 gck_session_unwrap_key_async (GckSession *self,
2361 GckObject *wrapper,
2362 GckMechanism *mechanism,
2363 const guchar *input,
2364 gsize n_input,
2365 GckAttributes *attrs,
2366 GCancellable *cancellable,
2367 GAsyncReadyCallback callback,
2368 gpointer user_data)
2369 {
2370 GckCall *call;
2371 UnwrapKey *args;
2372
2373 call = _gck_call_async_prep (self, perform_unwrap_key,
2374 NULL, sizeof (*args), free_unwrap_key);
2375 args = _gck_call_get_arguments (call);
2376
2377 g_return_if_fail (GCK_IS_SESSION (self));
2378 g_return_if_fail (GCK_IS_OBJECT (wrapper));
2379 g_return_if_fail (attrs);
2380
2381 g_object_get (wrapper, "handle", &args->wrapper, NULL);
2382 g_return_if_fail (args->wrapper != 0);
2383
2384 /* Shallow copy of the mechanism structure */
2385 memcpy (&args->mechanism, mechanism, sizeof (args->mechanism));
2386
2387 args->attrs = gck_attributes_ref_sink (attrs);
2388 args->input = input;
2389 args->n_input = n_input;
2390
2391 _gck_call_async_ready_go (call, self, cancellable, callback, user_data);
2392 }
2393
2394 /**
2395 * gck_session_unwrap_key_finish:
2396 * @self: The session to use.
2397 * @result: The async result passed to the callback.
2398 * @error: A location to return an error.
2399 *
2400 * Get the result of a unwrap key operation.
2401 *
2402 * Returns: (transfer full): the new unwrapped key or %NULL if the operation
2403 * failed.
2404 **/
2405 GckObject *
gck_session_unwrap_key_finish(GckSession * self,GAsyncResult * result,GError ** error)2406 gck_session_unwrap_key_finish (GckSession *self, GAsyncResult *result, GError **error)
2407 {
2408 UnwrapKey *args;
2409
2410 g_return_val_if_fail (GCK_IS_SESSION (self), NULL);
2411
2412 args = _gck_call_async_result_arguments (result, UnwrapKey);
2413
2414 if (!_gck_call_basic_finish (result, error))
2415 return NULL;
2416 return gck_object_from_handle (self, args->unwrapped);
2417 }
2418
2419 /* -----------------------------------------------------------------------------
2420 * KEY DERIVATION
2421 */
2422
2423 typedef struct _DeriveKey {
2424 GckArguments base;
2425 GckMechanism mechanism;
2426 GckAttributes *attrs;
2427 CK_OBJECT_HANDLE key;
2428 CK_OBJECT_HANDLE derived;
2429 } DeriveKey;
2430
2431 static void
free_derive_key(DeriveKey * args)2432 free_derive_key (DeriveKey *args)
2433 {
2434 gck_attributes_unref (args->attrs);
2435 g_free (args);
2436 }
2437
2438 static CK_RV
perform_derive_key(DeriveKey * args)2439 perform_derive_key (DeriveKey *args)
2440 {
2441 CK_ATTRIBUTE_PTR attrs;
2442 CK_ULONG n_attrs;
2443
2444 g_assert (sizeof (CK_MECHANISM) == sizeof (GckMechanism));
2445
2446 attrs = _gck_attributes_commit_out (args->attrs, &n_attrs);
2447
2448 return (args->base.pkcs11->C_DeriveKey) (args->base.handle,
2449 (CK_MECHANISM_PTR)&(args->mechanism),
2450 args->key, attrs, n_attrs,
2451 &args->derived);
2452 }
2453
2454 /**
2455 * gck_session_derive_key:
2456 * @self: The session to use.
2457 * @base: The key to derive from.
2458 * @mech_type: The mechanism to use for derivation.
2459 * @attrs: Additional attributes for the derived key.
2460 * @cancellable: Optional cancellation object, or %NULL.
2461 * @error: A location to return an error, or %NULL.
2462 *
2463 * Derive a key from another key. This call may block for an
2464 * indefinite period.
2465 *
2466 * If the @attrs #GckAttributes is floating, it is consumed.
2467 *
2468 * Returns: (transfer full): the new derived key or %NULL if the operation
2469 * failed
2470 **/
2471 GckObject *
gck_session_derive_key(GckSession * self,GckObject * base,gulong mech_type,GckAttributes * attrs,GCancellable * cancellable,GError ** error)2472 gck_session_derive_key (GckSession *self, GckObject *base, gulong mech_type,
2473 GckAttributes *attrs, GCancellable *cancellable, GError **error)
2474 {
2475 GckMechanism mech = { mech_type, NULL, 0 };
2476 return gck_session_derive_key_full (self, base, &mech, attrs, cancellable, error);
2477 }
2478
2479 /**
2480 * gck_session_derive_key_full:
2481 * @self: The session to use.
2482 * @base: The key to derive from.
2483 * @mechanism: The mechanism to use for derivation.
2484 * @attrs: Additional attributes for the derived key.
2485 * @cancellable: Optional cancellation object, or %NULL.
2486 * @error: A location to return an error, or %NULL.
2487 *
2488 * Derive a key from another key. This call may block for an
2489 * indefinite period.
2490 *
2491 * If the @attrs #GckAttributes is floating, it is consumed.
2492 *
2493 * Returns: (transfer full): the new derived key or %NULL if the operation
2494 * failed
2495 **/
2496 GckObject*
gck_session_derive_key_full(GckSession * self,GckObject * base,GckMechanism * mechanism,GckAttributes * attrs,GCancellable * cancellable,GError ** error)2497 gck_session_derive_key_full (GckSession *self, GckObject *base, GckMechanism *mechanism,
2498 GckAttributes *attrs, GCancellable *cancellable, GError **error)
2499 {
2500 DeriveKey args = { GCK_ARGUMENTS_INIT, GCK_MECHANISM_EMPTY, attrs, 0, 0 };
2501 gboolean ret;
2502
2503 g_return_val_if_fail (GCK_IS_SESSION (self), FALSE);
2504 g_return_val_if_fail (GCK_IS_OBJECT (base), FALSE);
2505 g_return_val_if_fail (mechanism, FALSE);
2506 g_return_val_if_fail (attrs, FALSE);
2507
2508 /* Shallow copy of the mechanism structure */
2509 memcpy (&args.mechanism, mechanism, sizeof (args.mechanism));
2510
2511 g_object_get (base, "handle", &args.key, NULL);
2512 g_return_val_if_fail (args.key != 0, NULL);
2513
2514 gck_attributes_ref_sink (attrs);
2515
2516 ret = _gck_call_sync (self, perform_derive_key, NULL, &args, cancellable, error);
2517
2518 gck_attributes_unref (attrs);
2519
2520 if (!ret)
2521 return NULL;
2522
2523 return gck_object_from_handle (self, args.derived);
2524 }
2525
2526 /**
2527 * gck_session_derive_key_async:
2528 * @self: The session to use.
2529 * @base: The key to derive from.
2530 * @mechanism: The mechanism to use for derivation.
2531 * @attrs: Additional attributes for the derived key.
2532 * @cancellable: Optional cancellation object or %NULL.
2533 * @callback: Called when the operation completes.
2534 * @user_data: Data to pass to the callback.
2535 *
2536 * Derive a key from another key. This call will
2537 * return immediately and complete asynchronously.
2538 *
2539 * If the @attrs #GckAttributes is floating, it is consumed.
2540 **/
2541 void
gck_session_derive_key_async(GckSession * self,GckObject * base,GckMechanism * mechanism,GckAttributes * attrs,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)2542 gck_session_derive_key_async (GckSession *self, GckObject *base, GckMechanism *mechanism,
2543 GckAttributes *attrs, GCancellable *cancellable,
2544 GAsyncReadyCallback callback, gpointer user_data)
2545 {
2546 GckCall *call;
2547 DeriveKey *args;
2548
2549 call = _gck_call_async_prep (self, perform_derive_key,
2550 NULL, sizeof (*args), free_derive_key);
2551 args = _gck_call_get_arguments (call);
2552
2553 g_return_if_fail (GCK_IS_SESSION (self));
2554 g_return_if_fail (GCK_IS_OBJECT (base));
2555 g_return_if_fail (attrs);
2556
2557 g_object_get (base, "handle", &args->key, NULL);
2558 g_return_if_fail (args->key != 0);
2559
2560 /* Shallow copy of the mechanism structure */
2561 memcpy (&args->mechanism, mechanism, sizeof (args->mechanism));
2562
2563 args->attrs = gck_attributes_ref_sink (attrs);
2564
2565 _gck_call_async_ready_go (call, self, cancellable, callback, user_data);
2566 }
2567
2568 /**
2569 * gck_session_derive_key_finish:
2570 * @self: The session to use.
2571 * @result: The async result passed to the callback.
2572 * @error: A location to return an error.
2573 *
2574 * Get the result of a derive key operation.
2575 *
2576 * Returns: (transfer full): the new derived key or %NULL if the operation
2577 * failed
2578 **/
2579 GckObject *
gck_session_derive_key_finish(GckSession * self,GAsyncResult * result,GError ** error)2580 gck_session_derive_key_finish (GckSession *self, GAsyncResult *result, GError **error)
2581 {
2582 DeriveKey *args;
2583
2584 g_return_val_if_fail (GCK_IS_SESSION (self), NULL);
2585
2586 args = _gck_call_async_result_arguments (result, DeriveKey);
2587
2588 if (!_gck_call_basic_finish (result, error))
2589 return NULL;
2590
2591 return gck_object_from_handle (self, args->derived);
2592 }
2593
2594 /* --------------------------------------------------------------------------------------------------
2595 * COMMON CRYPTO ROUTINES
2596 */
2597
2598 typedef struct _Crypt {
2599 GckArguments base;
2600
2601 /* Functions to call */
2602 CK_C_EncryptInit init_func;
2603 CK_C_Encrypt complete_func;
2604
2605 /* Interaction */
2606 GckObject *key_object;
2607 GTlsInteraction *interaction;
2608
2609 /* Input */
2610 CK_OBJECT_HANDLE key;
2611 GckMechanism mechanism;
2612 guchar *input;
2613 CK_ULONG n_input;
2614
2615 /* Output */
2616 guchar *result;
2617 CK_ULONG n_result;
2618
2619 } Crypt;
2620
2621 static CK_RV
perform_crypt(Crypt * args)2622 perform_crypt (Crypt *args)
2623 {
2624 GTlsInteraction *interaction;
2625 CK_RV rv;
2626
2627 g_assert (args);
2628 g_assert (args->init_func);
2629 g_assert (args->complete_func);
2630 g_assert (!args->result);
2631 g_assert (!args->n_result);
2632
2633 /* Initialize the crypt operation */
2634 rv = (args->init_func) (args->base.handle, (CK_MECHANISM_PTR)&(args->mechanism), args->key);
2635 if (rv != CKR_OK)
2636 return rv;
2637
2638 /* Compatibility, hook into GckModule signals if no interaction set */
2639 if (args->interaction)
2640 interaction = g_object_ref (args->interaction);
2641 else
2642 interaction = _gck_interaction_new (args->key_object);
2643
2644 rv = _gck_session_authenticate_key (args->base.pkcs11, args->base.handle,
2645 args->key_object, interaction, NULL);
2646
2647 g_object_unref (interaction);
2648
2649 if (rv != CKR_OK)
2650 return rv;
2651
2652 /* Get the length of the result */
2653 rv = (args->complete_func) (args->base.handle, args->input, args->n_input, NULL, &args->n_result);
2654 if (rv != CKR_OK)
2655 return rv;
2656
2657 /* And try again with a real buffer */
2658 args->result = g_malloc0 (args->n_result);
2659 return (args->complete_func) (args->base.handle, args->input, args->n_input, args->result, &args->n_result);
2660 }
2661
2662 static void
free_crypt(Crypt * args)2663 free_crypt (Crypt *args)
2664 {
2665 g_clear_object (&args->interaction);
2666 g_clear_object (&args->key_object);
2667
2668 g_free (args->input);
2669 g_free (args->result);
2670 g_free (args);
2671 }
2672
2673 static guchar*
crypt_sync(GckSession * self,GckObject * key,GckMechanism * mechanism,const guchar * input,gsize n_input,gsize * n_result,GCancellable * cancellable,GError ** error,CK_C_EncryptInit init_func,CK_C_Encrypt complete_func)2674 crypt_sync (GckSession *self, GckObject *key, GckMechanism *mechanism, const guchar *input,
2675 gsize n_input, gsize *n_result, GCancellable *cancellable, GError **error,
2676 CK_C_EncryptInit init_func, CK_C_Encrypt complete_func)
2677 {
2678 Crypt args;
2679
2680 g_return_val_if_fail (GCK_IS_OBJECT (key), NULL);
2681 g_return_val_if_fail (mechanism, NULL);
2682 g_return_val_if_fail (init_func, NULL);
2683 g_return_val_if_fail (complete_func, NULL);
2684
2685 memset (&args, 0, sizeof (args));
2686 g_object_get (key, "handle", &args.key, NULL);
2687 g_return_val_if_fail (args.key != 0, NULL);
2688
2689 /* Shallow copy of the mechanism structure */
2690 memcpy (&args.mechanism, mechanism, sizeof (args.mechanism));
2691
2692 /* No need to copy in this case */
2693 args.input = (guchar*)input;
2694 args.n_input = n_input;
2695
2696 args.init_func = init_func;
2697 args.complete_func = complete_func;
2698
2699 args.key_object = key;
2700 args.interaction = gck_session_get_interaction (self);
2701
2702 if (!_gck_call_sync (self, perform_crypt, NULL, &args, cancellable, error)) {
2703 g_free (args.result);
2704 args.result = NULL;
2705 } else {
2706 *n_result = args.n_result;
2707 }
2708
2709 g_clear_object (&args.interaction);
2710 return args.result;
2711 }
2712
2713 static void
crypt_async(GckSession * self,GckObject * key,GckMechanism * mechanism,const guchar * input,gsize n_input,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data,CK_C_EncryptInit init_func,CK_C_Encrypt complete_func)2714 crypt_async (GckSession *self, GckObject *key, GckMechanism *mechanism, const guchar *input,
2715 gsize n_input, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data,
2716 CK_C_EncryptInit init_func, CK_C_Encrypt complete_func)
2717 {
2718 GckCall *call;
2719 Crypt *args;
2720
2721 call = _gck_call_async_prep (self, perform_crypt, NULL, sizeof (*args), free_crypt);
2722 args = _gck_call_get_arguments (call);
2723
2724 g_return_if_fail (GCK_IS_OBJECT (key));
2725 g_return_if_fail (mechanism);
2726 g_return_if_fail (init_func);
2727 g_return_if_fail (complete_func);
2728
2729 g_object_get (key, "handle", &args->key, NULL);
2730 g_return_if_fail (args->key != 0);
2731
2732 /* Shallow copy of the mechanism structure */
2733 memcpy (&args->mechanism, mechanism, sizeof (args->mechanism));
2734
2735 args->input = input && n_input ? g_memdup (input, n_input) : NULL;
2736 args->n_input = n_input;
2737
2738 args->init_func = init_func;
2739 args->complete_func = complete_func;
2740
2741 args->key_object = g_object_ref (key);
2742 args->interaction = gck_session_get_interaction (self);
2743
2744 _gck_call_async_ready_go (call, self, cancellable, callback, user_data);
2745 }
2746
2747 static guchar*
crypt_finish(GckSession * self,GAsyncResult * result,gsize * n_result,GError ** error)2748 crypt_finish (GckSession *self, GAsyncResult *result, gsize *n_result, GError **error)
2749 {
2750 Crypt *args;
2751 guchar *res;
2752
2753 if (!_gck_call_basic_finish (result, error))
2754 return NULL;
2755 args = _gck_call_async_result_arguments (result, Crypt);
2756
2757 /* Steal the values from the results */
2758 res = args->result;
2759 args->result = NULL;
2760 *n_result = args->n_result;
2761 args->n_result = 0;
2762
2763 return res;
2764 }
2765
2766 /* --------------------------------------------------------------------------------------------------
2767 * ENCRYPT
2768 */
2769
2770 /**
2771 * gck_session_encrypt:
2772 * @self: The session.
2773 * @key: The key to encrypt with.
2774 * @mech_type: The mechanism type to use for encryption.
2775 * @input: (array length=n_input): the data to encrypt
2776 * @n_input: the length of the data to encrypt
2777 * @n_result: location to store the length of the result data
2778 * @cancellable: Optional cancellation object, or %NULL
2779 * @error: A location to place error information.
2780 *
2781 * Encrypt data in a mechanism specific manner. This call may
2782 * block for an indefinite period.
2783 *
2784 * Returns: (transfer full) (array length=n_result): the data that was encrypted,
2785 * or %NULL if an error occured.
2786 */
2787 guchar *
gck_session_encrypt(GckSession * self,GckObject * key,gulong mech_type,const guchar * input,gsize n_input,gsize * n_result,GCancellable * cancellable,GError ** error)2788 gck_session_encrypt (GckSession *self, GckObject *key, gulong mech_type, const guchar *input,
2789 gsize n_input, gsize *n_result, GCancellable *cancellable, GError **error)
2790 {
2791 GckMechanism mechanism = { mech_type, NULL, 0 };
2792 return gck_session_encrypt_full (self, key, &mechanism, input, n_input, n_result, cancellable, error);
2793 }
2794
2795 /**
2796 * gck_session_encrypt_full:
2797 * @self: The session.
2798 * @key: The key to encrypt with.
2799 * @mechanism: The mechanism type and parameters to use for encryption.
2800 * @input: (array length=n_input): the data to encrypt
2801 * @n_input: the length of the data to encrypt
2802 * @n_result: location to store the length of the result data
2803 * @cancellable: A GCancellable which can be used to cancel the operation.
2804 * @error: A location to place error information.
2805 *
2806 * Encrypt data in a mechanism specific manner. This call may
2807 * block for an indefinite period.
2808 *
2809 * Returns: (transfer full) (array length=n_result): the data that was encrypted,
2810 * or %NULL if an error occured
2811 */
2812 guchar *
gck_session_encrypt_full(GckSession * self,GckObject * key,GckMechanism * mechanism,const guchar * input,gsize n_input,gsize * n_result,GCancellable * cancellable,GError ** error)2813 gck_session_encrypt_full (GckSession *self, GckObject *key, GckMechanism *mechanism,
2814 const guchar *input, gsize n_input, gsize *n_result,
2815 GCancellable *cancellable, GError **error)
2816 {
2817 GckModule *module = NULL;
2818 CK_FUNCTION_LIST_PTR funcs;
2819 guchar *ret;
2820
2821 g_object_get (self, "module", &module, NULL);
2822 g_return_val_if_fail (module != NULL, NULL);
2823
2824 funcs = gck_module_get_functions (module);
2825 g_return_val_if_fail (module != NULL, NULL);
2826
2827 ret = crypt_sync (self, key, mechanism, input, n_input, n_result, cancellable, error,
2828 funcs->C_EncryptInit, funcs->C_Encrypt);
2829
2830 g_object_unref (module);
2831 return ret;
2832 }
2833
2834 /**
2835 * gck_session_encrypt_async:
2836 * @self: The session.
2837 * @key: The key to encrypt with.
2838 * @mechanism: The mechanism type and parameters to use for encryption.
2839 * @input: (array length=n_input): the data to encrypt
2840 * @n_input: length of the data to encrypt
2841 * @cancellable: A GCancellable which can be used to cancel the operation.
2842 * @callback: Called when the operation completes.
2843 * @user_data: A pointer to pass to the callback.
2844 *
2845 * Encrypt data in a mechanism specific manner. This call will
2846 * return immediately and complete asynchronously.
2847 **/
2848 void
gck_session_encrypt_async(GckSession * self,GckObject * key,GckMechanism * mechanism,const guchar * input,gsize n_input,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)2849 gck_session_encrypt_async (GckSession *self, GckObject *key, GckMechanism *mechanism,
2850 const guchar *input, gsize n_input, GCancellable *cancellable,
2851 GAsyncReadyCallback callback, gpointer user_data)
2852 {
2853 GckModule *module = NULL;
2854 CK_FUNCTION_LIST_PTR funcs;
2855
2856 g_object_get (self, "module", &module, NULL);
2857 g_return_if_fail (module != NULL);
2858
2859 funcs = gck_module_get_functions (module);
2860 g_return_if_fail (module != NULL);
2861
2862 crypt_async (self, key, mechanism, input, n_input, cancellable, callback, user_data,
2863 funcs->C_EncryptInit, funcs->C_Encrypt);
2864
2865 g_object_unref (module);
2866 }
2867
2868 /**
2869 * gck_session_encrypt_finish:
2870 * @self: The session.
2871 * @result: The result object passed to the callback.
2872 * @n_result: A location to store the length of the result data.
2873 * @error: A location to place error information.
2874 *
2875 * Get the result of an encryption operation.
2876 *
2877 * Returns: (transfer full) (array length=n_result): the data that was encrypted,
2878 * or %NULL if an error occurred.
2879 */
2880 guchar*
gck_session_encrypt_finish(GckSession * self,GAsyncResult * result,gsize * n_result,GError ** error)2881 gck_session_encrypt_finish (GckSession *self, GAsyncResult *result, gsize *n_result,
2882 GError **error)
2883 {
2884 return crypt_finish (self, result, n_result, error);
2885 }
2886
2887 /* --------------------------------------------------------------------------------------------------
2888 * DECRYPT
2889 */
2890
2891 /**
2892 * gck_session_decrypt:
2893 * @self: The session.
2894 * @key: The key to decrypt with.
2895 * @mech_type: The mechanism type to use for decryption.
2896 * @input: (array length=n_input): data to decrypt
2897 * @n_input: length of the data to decrypt
2898 * @n_result: location to store the length of the result data
2899 * @cancellable: Optional cancellation object, or %NULL
2900 * @error: A location to place an error.
2901 *
2902 * Decrypt data in a mechanism specific manner. This call may
2903 * block for an indefinite period.
2904 *
2905 * Returns: (transfer full) (array length=n_result): the data that was decrypted,
2906 * or %NULL if an error occured
2907 */
2908 guchar *
gck_session_decrypt(GckSession * self,GckObject * key,gulong mech_type,const guchar * input,gsize n_input,gsize * n_result,GCancellable * cancellable,GError ** error)2909 gck_session_decrypt (GckSession *self, GckObject *key, gulong mech_type, const guchar *input,
2910 gsize n_input, gsize *n_result, GCancellable *cancellable, GError **error)
2911 {
2912 GckMechanism mechanism = { mech_type, NULL, 0 };
2913 return gck_session_decrypt_full (self, key, &mechanism, input, n_input, n_result, cancellable, error);
2914 }
2915
2916 /**
2917 * gck_session_decrypt_full:
2918 * @self: The session.
2919 * @key: The key to decrypt with.
2920 * @mechanism: The mechanism type and parameters to use for decryption.
2921 * @input: (array length=n_input): data to decrypt
2922 * @n_input: length of the data to decrypt
2923 * @n_result: location to store the length of the result data
2924 * @cancellable: A GCancellable which can be used to cancel the operation.
2925 * @error: A location to place error information.
2926 *
2927 * Decrypt data in a mechanism specific manner. This call may
2928 * block for an indefinite period.
2929 *
2930 * Returns: (transfer full) (array length=n_result): the data that was decrypted,
2931 * or %NULL if an error occured
2932 */
2933 guchar *
gck_session_decrypt_full(GckSession * self,GckObject * key,GckMechanism * mechanism,const guchar * input,gsize n_input,gsize * n_result,GCancellable * cancellable,GError ** error)2934 gck_session_decrypt_full (GckSession *self, GckObject *key, GckMechanism *mechanism,
2935 const guchar *input, gsize n_input, gsize *n_result,
2936 GCancellable *cancellable, GError **error)
2937 {
2938 GckModule *module = NULL;
2939 CK_FUNCTION_LIST_PTR funcs;
2940 guchar *ret;
2941
2942 g_object_get (self, "module", &module, NULL);
2943 g_return_val_if_fail (module != NULL, NULL);
2944
2945 funcs = gck_module_get_functions (module);
2946 g_return_val_if_fail (module != NULL, NULL);
2947
2948 ret = crypt_sync (self, key, mechanism, input, n_input, n_result, cancellable, error,
2949 funcs->C_DecryptInit, funcs->C_Decrypt);
2950 g_object_unref (module);
2951 return ret;
2952 }
2953
2954 /**
2955 * gck_session_decrypt_async:
2956 * @self: The session.
2957 * @key: The key to decrypt with.
2958 * @mechanism: The mechanism type and parameters to use for decryption.
2959 * @input: (array length=n_input): data to decrypt
2960 * @n_input: length of the data to decrypt
2961 * @cancellable: A GCancellable which can be used to cancel the operation.
2962 * @callback: Called when the operation completes.
2963 * @user_data: A pointer to pass to the callback.
2964 *
2965 * Decrypt data in a mechanism specific manner. This call will
2966 * return immediately and complete asynchronously.
2967 */
2968 void
gck_session_decrypt_async(GckSession * self,GckObject * key,GckMechanism * mechanism,const guchar * input,gsize n_input,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)2969 gck_session_decrypt_async (GckSession *self, GckObject *key, GckMechanism *mechanism,
2970 const guchar *input, gsize n_input, GCancellable *cancellable,
2971 GAsyncReadyCallback callback, gpointer user_data)
2972 {
2973 GckModule *module = NULL;
2974 CK_FUNCTION_LIST_PTR funcs;
2975
2976 g_object_get (self, "module", &module, NULL);
2977 g_return_if_fail (module != NULL);
2978
2979 funcs = gck_module_get_functions (module);
2980 g_return_if_fail (module != NULL);
2981
2982 crypt_async (self, key, mechanism, input, n_input, cancellable, callback, user_data,
2983 funcs->C_DecryptInit, funcs->C_Decrypt);
2984 g_object_unref (module);
2985 }
2986
2987 /**
2988 * gck_session_decrypt_finish:
2989 * @self: The session.
2990 * @result: The result object passed to the callback.
2991 * @n_result: A location to store the length of the result data.
2992 * @error: A location to place error information.
2993 *
2994 * Get the result of an decryption operation.
2995 *
2996 * Returns: (transfer full) (array length=n_result): the data that was decrypted,
2997 * or %NULL if an error occurred
2998 */
2999 guchar*
gck_session_decrypt_finish(GckSession * self,GAsyncResult * result,gsize * n_result,GError ** error)3000 gck_session_decrypt_finish (GckSession *self, GAsyncResult *result,
3001 gsize *n_result, GError **error)
3002 {
3003 return crypt_finish (self, result, n_result, error);
3004 }
3005
3006 /* --------------------------------------------------------------------------------------------------
3007 * SIGN
3008 */
3009
3010 /**
3011 * gck_session_sign:
3012 * @self: The session.
3013 * @key: The key to sign with.
3014 * @mech_type: The mechanism type to use for signing.
3015 * @input: (array length=n_input): data to sign
3016 * @n_input: length of the data to sign
3017 * @n_result: location to store the length of the result data
3018 * @cancellable: Optional cancellation object, or %NULL
3019 * @error: A location to place an error.
3020 *
3021 * Sign data in a mechanism specific manner. This call may
3022 * block for an indefinite period.
3023 *
3024 * Returns: (transfer full) (array length=n_result): the data that was signed,
3025 * or %NULL if an error occured
3026 */
3027 guchar *
gck_session_sign(GckSession * self,GckObject * key,gulong mech_type,const guchar * input,gsize n_input,gsize * n_result,GCancellable * cancellable,GError ** error)3028 gck_session_sign (GckSession *self, GckObject *key, gulong mech_type, const guchar *input,
3029 gsize n_input, gsize *n_result, GCancellable *cancellable, GError **error)
3030 {
3031 GckMechanism mechanism = { mech_type, NULL, 0 };
3032 return gck_session_sign_full (self, key, &mechanism, input, n_input, n_result, NULL, error);
3033 }
3034
3035 /**
3036 * gck_session_sign_full:
3037 * @self: The session.
3038 * @key: The key to sign with.
3039 * @mechanism: The mechanism type and parameters to use for signing.
3040 * @input: (array length=n_input): data to sign
3041 * @n_input: length of the data to sign
3042 * @n_result: location to store the length of the result data
3043 * @cancellable: A GCancellable which can be used to cancel the operation.
3044 * @error: A location to place error information.
3045 *
3046 * Sign data in a mechanism specific manner. This call may
3047 * block for an indefinite period.
3048 *
3049 * Returns: The data that was signed, or %NULL if an error occured.
3050 */
3051 guchar*
gck_session_sign_full(GckSession * self,GckObject * key,GckMechanism * mechanism,const guchar * input,gsize n_input,gsize * n_result,GCancellable * cancellable,GError ** error)3052 gck_session_sign_full (GckSession *self, GckObject *key, GckMechanism *mechanism,
3053 const guchar *input, gsize n_input, gsize *n_result,
3054 GCancellable *cancellable, GError **error)
3055 {
3056 GckModule *module = NULL;
3057 CK_FUNCTION_LIST_PTR funcs;
3058 guchar *ret;
3059
3060 g_object_get (self, "module", &module, NULL);
3061 g_return_val_if_fail (module != NULL, NULL);
3062
3063 funcs = gck_module_get_functions (module);
3064 g_return_val_if_fail (module != NULL, NULL);
3065
3066 ret = crypt_sync (self, key, mechanism, input, n_input, n_result, cancellable, error,
3067 funcs->C_SignInit, funcs->C_Sign);
3068 g_object_unref (module);
3069 return ret;
3070 }
3071
3072 /**
3073 * gck_session_sign_async:
3074 * @self: The session.
3075 * @key: The key to sign with.
3076 * @mechanism: The mechanism type and parameters to use for signing.
3077 * @input: (array length=n_input): data to sign
3078 * @n_input: length of the data to sign
3079 * @cancellable: A GCancellable which can be used to cancel the operation.
3080 * @callback: Called when the operation completes.
3081 * @user_data: A pointer to pass to the callback.
3082 *
3083 * Sign data in a mechanism specific manner. This call will
3084 * return immediately and complete asynchronously.
3085 */
3086 void
gck_session_sign_async(GckSession * self,GckObject * key,GckMechanism * mechanism,const guchar * input,gsize n_input,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)3087 gck_session_sign_async (GckSession *self, GckObject *key, GckMechanism *mechanism,
3088 const guchar *input, gsize n_input, GCancellable *cancellable,
3089 GAsyncReadyCallback callback, gpointer user_data)
3090 {
3091 GckModule *module = NULL;
3092 CK_FUNCTION_LIST_PTR funcs;
3093
3094 g_object_get (self, "module", &module, NULL);
3095 g_return_if_fail (module != NULL);
3096
3097 funcs = gck_module_get_functions (module);
3098 g_return_if_fail (module != NULL);
3099
3100 crypt_async (self, key, mechanism, input, n_input, cancellable, callback, user_data,
3101 funcs->C_SignInit, funcs->C_Sign);
3102 g_object_unref (module);
3103 }
3104
3105 /**
3106 * gck_session_sign_finish:
3107 * @self: The session.
3108 * @result: The result object passed to the callback.
3109 * @n_result: A location to store the length of the result data.
3110 * @error: A location to place error information.
3111 *
3112 * Get the result of an signing operation.
3113 *
3114 * Returns: (transfer full) (array length=n_result): the data that was signed,
3115 * or %NULL if an error occurred
3116 */
3117 guchar *
gck_session_sign_finish(GckSession * self,GAsyncResult * result,gsize * n_result,GError ** error)3118 gck_session_sign_finish (GckSession *self, GAsyncResult *result,
3119 gsize *n_result, GError **error)
3120 {
3121 return crypt_finish (self, result, n_result, error);
3122 }
3123
3124 /* --------------------------------------------------------------------------------------------------
3125 * VERIFY
3126 */
3127
3128 typedef struct _Verify {
3129 GckArguments base;
3130
3131 /* Interaction */
3132 GckObject *key_object;
3133 GTlsInteraction *interaction;
3134
3135 /* Input */
3136 CK_OBJECT_HANDLE key;
3137 GckMechanism mechanism;
3138 guchar *input;
3139 CK_ULONG n_input;
3140 guchar *signature;
3141 CK_ULONG n_signature;
3142
3143 } Verify;
3144
3145 static CK_RV
perform_verify(Verify * args)3146 perform_verify (Verify *args)
3147 {
3148 GTlsInteraction *interaction;
3149 CK_RV rv;
3150
3151 /* Initialize the crypt operation */
3152 rv = (args->base.pkcs11->C_VerifyInit) (args->base.handle, (CK_MECHANISM_PTR)&(args->mechanism), args->key);
3153 if (rv != CKR_OK)
3154 return rv;
3155
3156 /* Compatibility, hook into GckModule signals if no interaction set */
3157 if (args->interaction)
3158 interaction = g_object_ref (args->interaction);
3159 else
3160 interaction = _gck_interaction_new (args->key_object);
3161
3162
3163 rv = _gck_session_authenticate_key (args->base.pkcs11, args->base.handle,
3164 args->key_object, interaction, NULL);
3165
3166 g_object_unref (interaction);
3167
3168 if (rv != CKR_OK)
3169 return rv;
3170
3171 /* Do the actual verify */
3172 return (args->base.pkcs11->C_Verify) (args->base.handle, args->input, args->n_input,
3173 args->signature, args->n_signature);
3174 }
3175
3176 static void
free_verify(Verify * args)3177 free_verify (Verify *args)
3178 {
3179 g_clear_object (&args->interaction);
3180 g_clear_object (&args->key_object);
3181
3182 g_free (args->input);
3183 g_free (args->signature);
3184 g_free (args);
3185 }
3186
3187 /**
3188 * gck_session_verify:
3189 * @self: The session.
3190 * @key: The key to verify with.
3191 * @mech_type: The mechanism type to use for verifying.
3192 * @input: (array length=n_input): data to verify
3193 * @n_input: length of the data to verify
3194 * @signature: (array length=n_signature): the signature
3195 * @n_signature: length of the signature
3196 * @cancellable: Optional cancellation object, or %NULL
3197 * @error: A location to place an error.
3198 *
3199 * Verify data in a mechanism specific manner. This call may
3200 * block for an indefinite period.
3201 *
3202 * Returns: %TRUE if the data verified correctly, otherwise a failure or error occurred.
3203 */
3204 gboolean
gck_session_verify(GckSession * self,GckObject * key,gulong mech_type,const guchar * input,gsize n_input,const guchar * signature,gsize n_signature,GCancellable * cancellable,GError ** error)3205 gck_session_verify (GckSession *self, GckObject *key, gulong mech_type, const guchar *input,
3206 gsize n_input, const guchar *signature, gsize n_signature, GCancellable *cancellable, GError **error)
3207 {
3208 GckMechanism mechanism = { mech_type, NULL, 0 };
3209 return gck_session_verify_full (self, key, &mechanism, input, n_input,
3210 signature, n_signature, NULL, error);
3211 }
3212
3213 /**
3214 * gck_session_verify_full:
3215 * @self: The session.
3216 * @key: The key to verify with.
3217 * @mechanism: The mechanism type and parameters to use for signing.
3218 * @input: (array length=n_input): data to verify
3219 * @n_input: the length of the data to verify
3220 * @signature: (array length=n_signature): the signature
3221 * @n_signature: length of the signature
3222 * @cancellable: A GCancellable which can be used to cancel the operation.
3223 * @error: A location to place an error.
3224 *
3225 * Verify data in a mechanism specific manner. This call may
3226 * block for an indefinite period.
3227 *
3228 * Returns: %TRUE if the data verified correctly, otherwise a failure or error occurred.
3229 */
3230 gboolean
gck_session_verify_full(GckSession * self,GckObject * key,GckMechanism * mechanism,const guchar * input,gsize n_input,const guchar * signature,gsize n_signature,GCancellable * cancellable,GError ** error)3231 gck_session_verify_full (GckSession *self, GckObject *key, GckMechanism *mechanism,
3232 const guchar *input, gsize n_input, const guchar *signature,
3233 gsize n_signature, GCancellable *cancellable, GError **error)
3234 {
3235 Verify args;
3236 gboolean ret;
3237
3238 g_return_val_if_fail (GCK_IS_OBJECT (key), FALSE);
3239 g_return_val_if_fail (mechanism, FALSE);
3240
3241 memset (&args, 0, sizeof (args));
3242 g_object_get (key, "handle", &args.key, NULL);
3243 g_return_val_if_fail (args.key != 0, FALSE);
3244
3245 /* Shallow copy of the mechanism structure */
3246 memcpy (&args.mechanism, mechanism, sizeof (args.mechanism));
3247
3248 /* No need to copy in this case */
3249 args.input = (guchar*)input;
3250 args.n_input = n_input;
3251 args.signature = (guchar*)signature;
3252 args.n_signature = n_signature;
3253
3254 args.key_object = key;
3255 args.interaction = gck_session_get_interaction (self);
3256
3257 ret = _gck_call_sync (self, perform_verify, NULL, &args, cancellable, error);
3258
3259 g_clear_object (&args.interaction);
3260
3261 return ret;
3262 }
3263
3264 /**
3265 * gck_session_verify_async:
3266 * @self: The session.
3267 * @key: The key to verify with.
3268 * @mechanism: The mechanism type and parameters to use for signing.
3269 * @input: (array length=n_input): data to verify
3270 * @n_input: the length of the data to verify
3271 * @signature: (array length=n_signature): the signature
3272 * @n_signature: the length of the signature
3273 * @cancellable: A GCancellable which can be used to cancel the operation.
3274 * @callback: Called when the operation completes.
3275 * @user_data: A pointer to pass to the callback.
3276 *
3277 * Verify data in a mechanism specific manner. This call returns
3278 * immediately and completes asynchronously.
3279 */
3280 void
gck_session_verify_async(GckSession * self,GckObject * key,GckMechanism * mechanism,const guchar * input,gsize n_input,const guchar * signature,gsize n_signature,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)3281 gck_session_verify_async (GckSession *self, GckObject *key, GckMechanism *mechanism,
3282 const guchar *input, gsize n_input, const guchar *signature,
3283 gsize n_signature, GCancellable *cancellable,
3284 GAsyncReadyCallback callback, gpointer user_data)
3285 {
3286 GckCall *call;
3287 Verify *args;
3288
3289 call = _gck_call_async_prep (self, perform_verify, NULL, sizeof (*args), free_verify);
3290 args = _gck_call_get_arguments (call);
3291
3292 g_return_if_fail (GCK_IS_OBJECT (key));
3293 g_return_if_fail (mechanism);
3294
3295 g_object_get (key, "handle", &args->key, NULL);
3296 g_return_if_fail (args->key != 0);
3297
3298 /* Shallow copy of the mechanism structure */
3299 memcpy (&args->mechanism, mechanism, sizeof (args->mechanism));
3300
3301 args->input = input && n_input ? g_memdup (input, n_input) : NULL;
3302 args->n_input = n_input;
3303 args->signature = signature && n_signature ? g_memdup (signature, n_signature) : NULL;
3304 args->n_signature = n_signature;
3305
3306 args->key_object = g_object_ref (key);
3307 args->interaction = gck_session_get_interaction (self);
3308
3309 _gck_call_async_ready_go (call, self, cancellable, callback, user_data);
3310 }
3311
3312 /**
3313 * gck_session_verify_finish:
3314 * @self: The session.
3315 * @result: The result object passed to the callback.
3316 * @error: A location to place error information.
3317 *
3318 * Get the result of an verify operation.
3319 *
3320 * Returns: %TRUE if the data verified correctly, otherwise a failure or error occurred.
3321 */
3322 gboolean
gck_session_verify_finish(GckSession * self,GAsyncResult * result,GError ** error)3323 gck_session_verify_finish (GckSession *self, GAsyncResult *result, GError **error)
3324 {
3325 return _gck_call_basic_finish (result, error);
3326 }
3327
3328 static void
update_password_for_token(GTlsPassword * password,CK_TOKEN_INFO * token_info,gboolean request_retry)3329 update_password_for_token (GTlsPassword *password,
3330 CK_TOKEN_INFO *token_info,
3331 gboolean request_retry)
3332 {
3333 GTlsPasswordFlags flags;
3334 gchar *label;
3335
3336 label = gck_string_from_chars (token_info->label, sizeof (token_info->label));
3337 g_tls_password_set_description (password, label);
3338 g_free (label);
3339
3340 flags = 0;
3341 if (request_retry)
3342 flags |= G_TLS_PASSWORD_RETRY;
3343 if (token_info && token_info->flags & CKF_USER_PIN_COUNT_LOW)
3344 flags |= G_TLS_PASSWORD_MANY_TRIES;
3345 if (token_info && token_info->flags & CKF_USER_PIN_FINAL_TRY)
3346 flags |= G_TLS_PASSWORD_FINAL_TRY;
3347 g_tls_password_set_flags (password, flags);
3348 }
3349
3350 CK_RV
_gck_session_authenticate_token(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,GckSlot * token,GTlsInteraction * interaction,GCancellable * cancellable)3351 _gck_session_authenticate_token (CK_FUNCTION_LIST_PTR funcs,
3352 CK_SESSION_HANDLE session,
3353 GckSlot *token,
3354 GTlsInteraction *interaction,
3355 GCancellable *cancellable)
3356 {
3357 CK_SESSION_INFO session_info;
3358 GTlsPassword *password = NULL;
3359 CK_TOKEN_INFO token_info;
3360 GTlsInteractionResult res;
3361 gboolean request_retry;
3362 CK_SLOT_ID slot_id;
3363 CK_BYTE_PTR pin;
3364 gsize n_pin;
3365 CK_RV rv = CKR_OK;
3366 GError *error = NULL;
3367
3368 g_assert (funcs != NULL);
3369 g_assert (GCK_IS_SLOT (token));
3370
3371 slot_id = gck_slot_get_handle (token);
3372 request_retry = FALSE;
3373
3374 do {
3375 if (g_cancellable_is_cancelled (cancellable)) {
3376 rv = CKR_FUNCTION_CANCELED;
3377 break;
3378 }
3379
3380 rv = (funcs->C_GetTokenInfo) (slot_id, &token_info);
3381 if (rv != CKR_OK) {
3382 g_warning ("couldn't get token info when logging in: %s",
3383 gck_message_from_rv (rv));
3384 break;
3385 }
3386
3387 /* No login necessary? */
3388 if ((token_info.flags & CKF_LOGIN_REQUIRED) == 0) {
3389 g_debug ("no login required for token, skipping login");
3390 rv = CKR_OK;
3391 break;
3392 }
3393
3394 /* Next check if session is logged in? */
3395 rv = (funcs->C_GetSessionInfo) (session, &session_info);
3396 if (rv != CKR_OK) {
3397 g_warning ("couldn't get session info when logging in: %s",
3398 gck_message_from_rv (rv));
3399 break;
3400 }
3401
3402 /* Already logged in? */
3403 if (session_info.state == CKS_RW_USER_FUNCTIONS ||
3404 session_info.state == CKS_RO_USER_FUNCTIONS ||
3405 session_info.state == CKS_RW_SO_FUNCTIONS) {
3406 g_debug ("already logged in, skipping login");
3407 rv = CKR_OK;
3408 break;
3409 }
3410
3411 if (token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) {
3412 g_debug ("trying to log into session: protected authentication path, no password");
3413
3414 /* No password passed for PAP */
3415 pin = NULL;
3416 n_pin = 0;
3417
3418
3419 /* Not protected auth path */
3420 } else {
3421 g_debug ("trying to log into session: want password %s",
3422 request_retry ? "login was incorrect" : "");
3423
3424 if (password == NULL)
3425 password = g_object_new (GCK_TYPE_PASSWORD, "token", token, NULL);
3426
3427 update_password_for_token (password, &token_info, request_retry);
3428
3429 if (interaction == NULL)
3430 res = G_TLS_INTERACTION_UNHANDLED;
3431
3432 else
3433 res = g_tls_interaction_invoke_ask_password (interaction,
3434 G_TLS_PASSWORD (password),
3435 NULL, &error);
3436
3437 if (res == G_TLS_INTERACTION_FAILED) {
3438 g_message ("interaction couldn't ask password: %s", error->message);
3439 rv = _gck_rv_from_error (error, CKR_USER_NOT_LOGGED_IN);
3440 g_clear_error (&error);
3441 break;
3442
3443 } else if (res == G_TLS_INTERACTION_UNHANDLED) {
3444 g_message ("couldn't authenticate: no interaction handler");
3445 rv = CKR_USER_NOT_LOGGED_IN;
3446 break;
3447 }
3448
3449 pin = (CK_BYTE_PTR)g_tls_password_get_value (password, &n_pin);
3450 }
3451
3452 /* Try to log in */
3453 rv = (funcs->C_Login) (session, CKU_USER, (CK_BYTE_PTR)pin, (CK_ULONG)n_pin);
3454
3455 /* Only one C_Login call if protected auth path */
3456 if (token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
3457 break;
3458
3459 request_retry = TRUE;
3460 } while (rv == CKR_PIN_INCORRECT);
3461
3462 g_clear_object (&password);
3463
3464 return rv;
3465 }
3466
3467 static void
update_password_for_key(GTlsPassword * password,CK_TOKEN_INFO * token_info,gboolean request_retry)3468 update_password_for_key (GTlsPassword *password,
3469 CK_TOKEN_INFO *token_info,
3470 gboolean request_retry)
3471 {
3472 GTlsPasswordFlags flags;
3473
3474 flags = 0;
3475 if (request_retry)
3476 flags |= G_TLS_PASSWORD_RETRY;
3477 if (token_info && token_info->flags & CKF_USER_PIN_COUNT_LOW)
3478 flags |= G_TLS_PASSWORD_MANY_TRIES;
3479 if (token_info && token_info->flags & CKF_USER_PIN_FINAL_TRY)
3480 flags |= G_TLS_PASSWORD_FINAL_TRY;
3481 g_tls_password_set_flags (password, flags);
3482 }
3483
3484 CK_RV
_gck_session_authenticate_key(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,GckObject * key,GTlsInteraction * interaction,GCancellable * cancellable)3485 _gck_session_authenticate_key (CK_FUNCTION_LIST_PTR funcs,
3486 CK_SESSION_HANDLE session,
3487 GckObject *key,
3488 GTlsInteraction *interaction,
3489 GCancellable *cancellable)
3490 {
3491 CK_ATTRIBUTE attrs[2];
3492 CK_SESSION_INFO session_info;
3493 CK_TOKEN_INFO token_info;
3494 GTlsPassword *password = NULL;
3495 CK_OBJECT_HANDLE handle;
3496 GTlsInteractionResult res;
3497 gboolean request_retry;
3498 GError *error = NULL;
3499 CK_BYTE_PTR pin;
3500 gsize pin_len;
3501 CK_BBOOL bvalue;
3502 gboolean got_label;
3503 CK_RV rv;
3504
3505 g_assert (funcs != NULL);
3506
3507 handle = gck_object_get_handle (key);
3508
3509 attrs[0].type = CKA_LABEL;
3510 attrs[0].pValue = NULL;
3511 attrs[0].ulValueLen = 0;
3512 attrs[1].type = CKA_ALWAYS_AUTHENTICATE;
3513 attrs[1].pValue = &bvalue;
3514 attrs[1].ulValueLen = sizeof (bvalue);
3515
3516 rv = (funcs->C_GetAttributeValue) (session, handle, attrs, 2);
3517 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
3518 bvalue = CK_FALSE;
3519
3520 } else if (rv != CKR_OK) {
3521 g_message ("couldn't check whether key requires authentication, assuming it doesn't: %s",
3522 gck_message_from_rv (rv));
3523 return CKR_OK;
3524 }
3525
3526 /* No authentication needed, on this object */
3527 if (bvalue != CK_TRUE) {
3528 g_debug ("key does not require authentication");
3529 return CKR_OK;
3530 }
3531
3532 got_label = FALSE;
3533 request_retry = FALSE;
3534
3535 do {
3536 if (g_cancellable_is_cancelled (cancellable)) {
3537 rv = CKR_FUNCTION_CANCELED;
3538 break;
3539 }
3540
3541 rv = (funcs->C_GetSessionInfo) (session, &session_info);
3542 if (rv != CKR_OK) {
3543 g_warning ("couldn't get session info when authenticating key: %s",
3544 gck_message_from_rv (rv));
3545 return rv;
3546 }
3547
3548 rv = (funcs->C_GetTokenInfo) (session_info.slotID, &token_info);
3549 if (rv != CKR_OK) {
3550 g_warning ("couldn't get token info when authenticating key: %s",
3551 gck_message_from_rv (rv));
3552 return rv;
3553 }
3554
3555 /* Protected authentication path, just use NULL passwords */
3556 if (token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) {
3557
3558 password = NULL;
3559 pin = NULL;
3560 pin_len = 0;
3561
3562 /* Need to prompt for a password */
3563 } else {
3564 g_debug ("trying to log into session: want password %s",
3565 request_retry ? "login was incorrect" : "");
3566
3567 if (password == NULL)
3568 password = g_object_new (GCK_TYPE_PASSWORD, "key", key, NULL);
3569
3570 /* Set the password */
3571 update_password_for_key (password, &token_info, request_retry);
3572
3573 /* Set the label properly */
3574 if (!got_label) {
3575 if (attrs[0].ulValueLen && attrs[0].ulValueLen != GCK_INVALID) {
3576 attrs[0].pValue = g_malloc0 (attrs[0].ulValueLen + 1);
3577 rv = (funcs->C_GetAttributeValue) (session, handle, attrs, 1);
3578 if (rv == CKR_OK) {
3579 ((gchar *)attrs[0].pValue)[attrs[0].ulValueLen] = 0;
3580 g_tls_password_set_description (password, attrs[0].pValue);
3581 }
3582 g_free (attrs[0].pValue);
3583 attrs[0].pValue = NULL;
3584 }
3585
3586 got_label = TRUE;
3587 }
3588
3589 if (interaction == NULL)
3590 res = G_TLS_INTERACTION_UNHANDLED;
3591
3592 else
3593 res = g_tls_interaction_invoke_ask_password (interaction,
3594 G_TLS_PASSWORD (password),
3595 NULL, &error);
3596
3597 if (res == G_TLS_INTERACTION_FAILED) {
3598 g_message ("interaction couldn't ask password: %s", error->message);
3599 rv = _gck_rv_from_error (error, CKR_USER_NOT_LOGGED_IN);
3600 g_clear_error (&error);
3601 break;
3602
3603 } else if (res == G_TLS_INTERACTION_UNHANDLED) {
3604 g_message ("couldn't authenticate: no interaction handler");
3605 rv = CKR_USER_NOT_LOGGED_IN;
3606 break;
3607 }
3608
3609 pin = (CK_BYTE_PTR)g_tls_password_get_value (G_TLS_PASSWORD (password), &pin_len);
3610 }
3611
3612 /* Try to log in */
3613 rv = (funcs->C_Login) (session, CKU_CONTEXT_SPECIFIC, pin, pin_len);
3614
3615 /* Only one C_Login call if protected auth path */
3616 if (token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
3617 break;
3618
3619 request_retry = TRUE;
3620 } while (rv == CKR_PIN_INCORRECT);
3621
3622 g_clear_object (&password);
3623
3624 return rv;
3625 }
3626