4
* Copyright (C) 2009 Stefan Walter
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU Lesser General License as
8
* published by the Free Software Foundation; either version 2.1 of
9
* the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful, but
12
* WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General License for more details.
16
* You should have received a copy of the GNU Lesser General
17
* License along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24
#include "gck-attributes.h"
25
#include "gck-credential.h"
26
#include "gck-secret.h"
27
#include "gck-session.h"
28
#include "gck-transaction.h"
30
#include "pkcs11/pkcs11.h"
31
#include "pkcs11/pkcs11i.h"
39
struct _GckCredentialPrivate {
41
/* The object we authenticated */
44
/* Secret which created this credential */
52
G_DEFINE_TYPE (GckCredential, gck_credential, GCK_TYPE_OBJECT);
54
/* -----------------------------------------------------------------------------
59
factory_create_credential (GckSession *session, GckTransaction *transaction,
60
CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
62
CK_OBJECT_HANDLE handle;
67
GckObject *object = NULL;
70
g_return_val_if_fail (GCK_IS_TRANSACTION (transaction), NULL);
71
g_return_val_if_fail (attrs || !n_attrs, NULL);
73
/* The handle is optional */
74
if (gck_attributes_find_ulong (attrs, n_attrs, CKA_G_OBJECT, &handle)) {
75
rv = gck_session_lookup_readable_object (session, handle, &object);
77
gck_transaction_fail (transaction, rv);
84
/* The value is optional */
85
attr = gck_attributes_find (attrs, n_attrs, CKA_VALUE);
87
gck_attributes_consume (attrs, n_attrs, CKA_VALUE, CKA_G_OBJECT, G_MAXULONG);
89
module = gck_session_get_module (session);
90
manager = gck_manager_for_template (attrs, n_attrs, session);
91
rv = gck_credential_create (module, manager, object,
92
attr ? attr->pValue : NULL,
93
attr ? attr->ulValueLen : 0, &cred);
96
gck_session_complete_object_creation (session, transaction, GCK_OBJECT (cred),
97
TRUE, attrs, n_attrs);
98
return GCK_OBJECT (cred);
100
gck_transaction_fail (transaction, rv);
106
self_destruct (GckCredential *self)
108
GckTransaction *transaction;
111
g_assert (GCK_IS_CREDENTIAL (self));
113
transaction = gck_transaction_new ();
115
/* Destroy ourselves */
116
gck_object_destroy (GCK_OBJECT (self), transaction);
118
gck_transaction_complete (transaction);
119
rv = gck_transaction_get_result (transaction);
120
g_object_unref (transaction);
123
g_warning ("Couldn't destroy credential object: (code %lu)", (gulong)rv);
127
object_went_away (gpointer data, GObject *old_object)
129
GckCredential *self = data;
130
g_return_if_fail (GCK_IS_CREDENTIAL (self));
131
self->pv->object = NULL;
132
self_destruct (self);
136
clear_data (GckCredential *self)
138
if (!self->pv->user_data)
140
if (G_TYPE_IS_BOXED (self->pv->user_type))
141
g_boxed_free (self->pv->user_type, self->pv->user_data);
142
else if (G_TYPE_IS_OBJECT (self->pv->user_type))
143
g_object_unref (self->pv->user_data);
145
g_assert_not_reached ();
146
self->pv->user_data = NULL;
147
self->pv->user_type = 0;
150
/* -----------------------------------------------------------------------------
155
gck_credential_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE *attr)
157
GckCredential *self = GCK_CREDENTIAL (base);
158
CK_OBJECT_HANDLE handle;
160
switch (attr->type) {
163
return gck_attribute_set_ulong (attr, CKO_G_CREDENTIAL);
166
return gck_attribute_set_bool (attr, TRUE);
169
handle = self->pv->object ? gck_object_get_handle (self->pv->object) : 0;
170
return gck_attribute_set_ulong (attr, handle);
173
return CKR_ATTRIBUTE_SENSITIVE;
176
return GCK_OBJECT_CLASS (gck_credential_parent_class)->get_attribute (base, session, attr);
180
gck_credential_constructor (GType type, guint n_props, GObjectConstructParam *props)
182
GckCredential *self = GCK_CREDENTIAL (G_OBJECT_CLASS (gck_credential_parent_class)->constructor(type, n_props, props));
183
g_return_val_if_fail (self, NULL);
185
return G_OBJECT (self);
189
gck_credential_init (GckCredential *self)
191
self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCK_TYPE_CREDENTIAL, GckCredentialPrivate);
195
gck_credential_dispose (GObject *obj)
197
GckCredential *self = GCK_CREDENTIAL (obj);
199
if (self->pv->object)
200
g_object_weak_unref (G_OBJECT (self->pv->object), object_went_away, self);
201
self->pv->object = NULL;
205
G_OBJECT_CLASS (gck_credential_parent_class)->dispose (obj);
209
gck_credential_finalize (GObject *obj)
211
GckCredential *self = GCK_CREDENTIAL (obj);
213
g_assert (!self->pv->object);
214
g_assert (!self->pv->user_type);
215
g_assert (!self->pv->user_data);
217
G_OBJECT_CLASS (gck_credential_parent_class)->finalize (obj);
221
gck_credential_set_property (GObject *obj, guint prop_id, const GValue *value,
224
GckCredential *self = GCK_CREDENTIAL (obj);
229
object = g_value_get_object (value);
231
gck_credential_connect (self, object);
233
g_return_if_fail (!self->pv->object);
236
gck_credential_set_secret (self, g_value_get_object (value));
239
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
245
gck_credential_get_property (GObject *obj, guint prop_id, GValue *value,
248
GckCredential *self = GCK_CREDENTIAL (obj);
252
g_value_set_object (value, gck_credential_get_object (self));
255
g_value_set_object (value, gck_credential_get_secret (self));
258
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
264
gck_credential_class_init (GckCredentialClass *klass)
266
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
267
GckObjectClass *gck_class = GCK_OBJECT_CLASS (klass);
269
gck_credential_parent_class = g_type_class_peek_parent (klass);
270
g_type_class_add_private (klass, sizeof (GckCredentialPrivate));
272
gobject_class->constructor = gck_credential_constructor;
273
gobject_class->dispose = gck_credential_dispose;
274
gobject_class->finalize = gck_credential_finalize;
275
gobject_class->set_property = gck_credential_set_property;
276
gobject_class->get_property = gck_credential_get_property;
278
gck_class->get_attribute = gck_credential_real_get_attribute;
280
g_object_class_install_property (gobject_class, PROP_OBJECT,
281
g_param_spec_object ("object", "Object", "Object authenticated",
282
GCK_TYPE_OBJECT, G_PARAM_READWRITE));
284
g_object_class_install_property (gobject_class, PROP_SECRET,
285
g_param_spec_object ("secret", "Secret", "Optiontal secret",
286
GCK_TYPE_SECRET, G_PARAM_READWRITE));
289
/* -----------------------------------------------------------------------------
294
gck_credential_get_factory (void)
296
static CK_OBJECT_CLASS klass = CKO_G_CREDENTIAL;
298
static CK_ATTRIBUTE attributes[] = {
299
{ CKA_CLASS, &klass, sizeof (klass) },
302
static GckFactory factory = {
304
G_N_ELEMENTS (attributes),
305
factory_create_credential
312
gck_credential_create (GckModule *module, GckManager *manager, GckObject *object,
313
CK_UTF8CHAR_PTR pin, CK_ULONG n_pin, GckCredential **result)
316
GckSecret *secret = NULL;
319
g_return_val_if_fail (GCK_IS_MODULE (module), CKR_GENERAL_ERROR);
320
g_return_val_if_fail (!object || GCK_IS_OBJECT (object), CKR_GENERAL_ERROR);
321
g_return_val_if_fail (!manager || GCK_IS_MANAGER (manager), CKR_GENERAL_ERROR);
322
g_return_val_if_fail (result, CKR_GENERAL_ERROR);
324
secret = gck_secret_new_from_login (pin, n_pin);
325
cred = g_object_new (GCK_TYPE_CREDENTIAL,
331
g_object_unref (secret);
333
/* If we have an object, the unlock must work */
335
rv = gck_object_unlock (object, cred);
339
g_object_unref (cred);
341
/* Created credentials without object */
351
gck_credential_connect (GckCredential *self, GckObject *object)
353
g_return_if_fail (GCK_IS_CREDENTIAL (self));
354
g_return_if_fail (GCK_IS_OBJECT (object));
355
g_return_if_fail (self->pv->object == NULL);
356
g_return_if_fail (GCK_OBJECT (self) != object);
357
self->pv->object = object;
358
g_object_weak_ref (G_OBJECT (self->pv->object), object_went_away, self);
362
gck_credential_get_secret (GckCredential *self)
364
g_return_val_if_fail (GCK_IS_CREDENTIAL (self), NULL);
365
return self->pv->secret;
369
gck_credential_set_secret (GckCredential *self, GckSecret *secret)
371
g_return_if_fail (GCK_IS_CREDENTIAL (self));
374
g_return_if_fail (GCK_IS_SECRET (secret));
375
g_object_ref (secret);
377
if (self->pv->secret)
378
g_object_unref (self->pv->secret);
379
self->pv->secret = secret;
381
g_object_notify (G_OBJECT (self), "secret");
385
gck_credential_get_password (GckCredential *self, gsize *n_password)
387
g_return_val_if_fail (GCK_IS_CREDENTIAL (self), NULL);
388
g_return_val_if_fail (n_password, NULL);
390
if (!self->pv->secret) {
395
return gck_secret_get_password (self->pv->secret, n_password);
399
gck_credential_get_object (GckCredential *self)
401
g_return_val_if_fail (GCK_IS_CREDENTIAL (self), NULL);
402
return self->pv->object;
406
gck_credential_peek_data (GckCredential *self, GType type)
408
g_return_val_if_fail (GCK_IS_CREDENTIAL (self), NULL);
409
if (!self->pv->user_data)
411
g_return_val_if_fail (type == self->pv->user_type, NULL);
412
return self->pv->user_data;
416
gck_credential_pop_data (GckCredential *self, GType type)
418
gpointer data = NULL;
419
g_return_val_if_fail (GCK_IS_CREDENTIAL (self), NULL);
421
if (self->pv->user_data) {
422
g_return_val_if_fail (type == self->pv->user_type, NULL);
423
if (G_TYPE_IS_BOXED (self->pv->user_type))
424
data = g_boxed_copy (self->pv->user_type, self->pv->user_data);
425
else if (G_TYPE_IS_OBJECT (self->pv->user_type))
426
data = g_object_ref (self->pv->user_data);
428
g_assert_not_reached ();
431
gck_object_mark_used (GCK_OBJECT (self));
436
gck_credential_set_data (GckCredential *self, GType type, gpointer data)
438
g_return_if_fail (GCK_IS_CREDENTIAL (self));
441
g_return_if_fail (type);
442
g_return_if_fail (G_TYPE_IS_BOXED (type) || G_TYPE_IS_OBJECT (type));
448
self->pv->user_type = type;
449
if (G_TYPE_IS_BOXED (type))
450
self->pv->user_data = g_boxed_copy (type, data);
451
else if (G_TYPE_IS_OBJECT (type))
452
self->pv->user_data = g_object_ref (data);
454
g_assert_not_reached ();
459
gck_credential_for_each (GckSession *session, GckObject *object,
460
GckCredentialFunc func, gpointer user_data)
462
CK_OBJECT_HANDLE handle;
463
CK_OBJECT_CLASS klass;
464
CK_ATTRIBUTE attrs[2];
469
g_return_val_if_fail (GCK_IS_SESSION (session), FALSE);
470
g_return_val_if_fail (GCK_IS_OBJECT (object), FALSE);
471
g_return_val_if_fail (func, FALSE);
473
/* Do we have one right on the session */
474
cred = gck_session_get_credential (session);
475
if (cred && gck_credential_get_object (cred) == object) {
477
ret = (func) (cred, object, user_data);
478
g_object_unref (cred);
483
klass = CKO_G_CREDENTIAL;
484
attrs[0].type = CKA_CLASS;
485
attrs[0].pValue = &klass;
486
attrs[0].ulValueLen = sizeof (klass);
488
handle = gck_object_get_handle (object);
489
attrs[1].type = CKA_G_OBJECT;
490
attrs[1].pValue = &handle;
491
attrs[1].ulValueLen = sizeof (handle);
493
/* Find any on the session */
494
results = gck_manager_find_by_attributes (gck_session_get_manager (session),
495
attrs, G_N_ELEMENTS (attrs));
497
for (l = results; l; l = g_list_next (l)) {
498
g_object_ref (l->data);
499
ret = (func) (l->data, object, user_data);
500
g_object_unref (l->data);
505
g_list_free (results);
510
/* Find any in the token */
511
results = gck_manager_find_by_attributes (gck_module_get_manager (gck_session_get_module (session)),
512
attrs, G_N_ELEMENTS (attrs));
514
for (l = results; l; l = g_list_next (l)) {
515
g_object_ref (l->data);
516
ret = (func) (l->data, object, user_data);
517
g_object_unref (l->data);
522
g_list_free (results);