1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2
/* unit-test-secret-collection.c: Test the collection keyring
4
Copyright (C) 2009 Stefan Walter
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.
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.
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
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
Boston, MA 02111-1307, USA.
21
Author: Stef Walter <stef@memberwebs.com>
26
#include "run-auto-test.h"
27
#include "test-secret-module.h"
29
#include "gck-secret-data.h"
30
#include "gck-secret-collection.h"
31
#include "gck-secret-item.h"
33
#include "gck/gck-credential.h"
34
#include "gck/gck-session.h"
35
#include "gck/gck-transaction.h"
37
#include "pkcs11/pkcs11i.h"
45
static GckModule *module = NULL;
46
static GckSession *session = NULL;
47
static CK_OBJECT_HANDLE credential = 0;
48
static CK_OBJECT_HANDLE credential2 = 0;
49
static GckSecretCollection *collection = NULL;
51
DEFINE_SETUP(secret_collection)
53
CK_OBJECT_CLASS klass = CKO_G_CREDENTIAL;
56
CK_ATTRIBUTE attrs[] = {
57
{ CKA_CLASS, &klass, sizeof (klass) },
58
{ CKA_VALUE, NULL, 0 }
61
module = test_secret_module_initialize_and_enter ();
62
session = test_secret_module_open_session (TRUE);
64
collection = g_object_new (GCK_TYPE_SECRET_COLLECTION,
68
g_assert (GCK_IS_SECRET_COLLECTION (collection));
70
/* Make two credentials */
71
cred = gck_session_create_object_for_factory (session, GCK_FACTORY_CREDENTIAL, NULL,
72
attrs, G_N_ELEMENTS (attrs));
73
g_assert (cred != NULL);
74
credential = gck_object_get_handle (GCK_OBJECT (cred));
75
g_object_unref (cred);
77
cred = gck_session_create_object_for_factory (session, GCK_FACTORY_CREDENTIAL, NULL,
78
attrs, G_N_ELEMENTS (attrs));
79
g_assert (cred != NULL);
80
credential2 = gck_object_get_handle (GCK_OBJECT (cred));
81
g_object_unref (cred);
84
DEFINE_TEARDOWN(secret_collection)
87
g_object_unref (collection);
90
test_secret_module_leave_and_finalize ();
96
DEFINE_TEST(secret_collection_is_locked)
100
/* By default is locked */
101
locked = gck_secret_object_is_locked (GCK_SECRET_OBJECT (collection), session);
102
g_assert (locked == TRUE);
105
DEFINE_TEST(secret_collection_unlocked_data)
108
GckSecretData *sdata;
111
/* Create credential, which unlocks collection */
112
rv = gck_credential_create (module, gck_session_get_manager (session), GCK_OBJECT (collection), NULL, 0, &cred);
113
g_assert (rv == CKR_OK);
114
gck_session_add_session_object (session, NULL, GCK_OBJECT (cred));
115
g_object_unref (cred);
117
/* Collection should now be unlocked */
118
sdata = gck_secret_collection_unlocked_use (collection, session);
119
g_assert (GCK_IS_SECRET_DATA (sdata));
120
g_assert (!gck_secret_object_is_locked (GCK_SECRET_OBJECT (collection), session));
121
g_object_unref (sdata);
124
DEFINE_TEST(secret_collection_get_filename)
126
GckSecretCollection *other;
127
const gchar *filename;
129
other = g_object_new (GCK_TYPE_SECRET_COLLECTION,
131
"identifier", "test",
132
"filename", "/tmp/filename.keyring",
135
filename = gck_secret_collection_get_filename (other);
136
g_assert_cmpstr (filename, ==, "/tmp/filename.keyring");
138
g_object_unref (other);
141
DEFINE_TEST(secret_collection_set_filename)
143
const gchar *filename;
145
gck_secret_collection_set_filename (collection, "/tmp/filename.keyring");
147
filename = gck_secret_collection_get_filename (collection);
148
g_assert_cmpstr (filename, ==, "/tmp/filename.keyring");
151
DEFINE_TEST(secret_collection_has_item)
155
item = gck_secret_collection_new_item (collection, "testo");
156
g_assert (gck_secret_collection_has_item (collection, item));
159
DEFINE_TEST(secret_collection_load_unlock_plain)
162
GckSecretData *sdata;
167
filename = test_data_filename ("plain.keyring");
168
gck_secret_collection_set_filename (collection, filename);
171
/* Load the data in the file */
172
res = gck_secret_collection_load (collection);
173
g_assert (res == GCK_DATA_SUCCESS);
175
/* Unlock the keyring, which should load again */
176
rv = gck_credential_create (module, gck_session_get_manager (session), GCK_OBJECT (collection), NULL, 0, &cred);
177
g_assert (rv == CKR_OK);
178
gck_session_add_session_object (session, NULL, GCK_OBJECT (cred));
179
g_object_unref (cred);
181
sdata = gck_secret_collection_unlocked_use (collection, session);
182
g_assert (sdata != NULL && GCK_IS_SECRET_DATA (sdata));
183
test_secret_collection_validate (collection, sdata);
184
g_object_unref (sdata);
187
DEFINE_TEST(secret_collection_load_unlock_encrypted)
190
GckSecretData *sdata;
195
filename = test_data_filename ("encrypted.keyring");
196
gck_secret_collection_set_filename (collection, filename);
199
/* Load the data in the file */
200
res = gck_secret_collection_load (collection);
201
g_assert (res == GCK_DATA_SUCCESS);
203
/* Unlock the keyring, which should load again */
204
rv = gck_credential_create (module, gck_session_get_manager (session), GCK_OBJECT (collection),
205
(guchar*)"my-keyring-password", 19, &cred);
206
g_assert (rv == CKR_OK);
207
gck_session_add_session_object (session, NULL, GCK_OBJECT (cred));
208
g_object_unref (cred);
210
sdata = gck_secret_collection_unlocked_use (collection, session);
211
g_assert (sdata != NULL && GCK_IS_SECRET_DATA (sdata));
212
test_secret_collection_validate (collection, sdata);
213
g_object_unref (sdata);
216
DEFINE_TEST(secret_collection_load_unlock_bad_password)
223
filename = test_data_filename ("encrypted.keyring");
224
gck_secret_collection_set_filename (collection, filename);
227
/* Load the data in the file */
228
res = gck_secret_collection_load (collection);
229
g_assert (res == GCK_DATA_SUCCESS);
231
/* Unlock the keyring, which should load again */
232
rv = gck_credential_create (module, gck_session_get_manager (session), GCK_OBJECT (collection),
233
(guchar*)"wrong", 5, &cred);
234
g_assert (rv == CKR_PIN_INCORRECT);
237
DEFINE_TEST(secret_collection_unlock_without_load)
240
GckSecretData *sdata;
244
filename = test_data_filename ("encrypted.keyring");
245
gck_secret_collection_set_filename (collection, filename);
248
/* Unlock the keyring, which should load it */
249
rv = gck_credential_create (module, gck_session_get_manager (session), GCK_OBJECT (collection),
250
(guchar*)"my-keyring-password", 19, &cred);
251
g_assert (rv == CKR_OK);
252
gck_session_add_session_object (session, NULL, GCK_OBJECT (cred));
253
g_object_unref (cred);
255
sdata = gck_secret_collection_unlocked_use (collection, session);
256
g_assert (sdata != NULL && GCK_IS_SECRET_DATA (sdata));
257
test_secret_collection_validate (collection, sdata);
258
g_object_unref (sdata);
261
DEFINE_TEST(secret_collection_twice_unlock)
264
GckSecretData *sdata;
268
filename = test_data_filename ("encrypted.keyring");
269
gck_secret_collection_set_filename (collection, filename);
272
/* Unlock the keyring, which should load */
273
rv = gck_credential_create (module, gck_session_get_manager (session), GCK_OBJECT (collection),
274
(guchar*)"my-keyring-password", 19, &cred);
275
g_assert (rv == CKR_OK);
276
gck_session_add_session_object (session, NULL, GCK_OBJECT (cred));
277
g_object_unref (cred);
279
/* Unlock the keyring again, which should not reload */
280
rv = gck_credential_create (module, gck_session_get_manager (session), GCK_OBJECT (collection),
281
(guchar*)"my-keyring-password", 19, &cred);
282
g_assert (rv == CKR_OK);
283
gck_session_add_session_object (session, NULL, GCK_OBJECT (cred));
284
g_object_unref (cred);
286
sdata = gck_secret_collection_unlocked_use (collection, session);
287
g_assert (sdata != NULL && GCK_IS_SECRET_DATA (sdata));
288
test_secret_collection_validate (collection, sdata);
289
g_object_unref (sdata);
292
DEFINE_TEST(secret_collection_twice_unlock_bad_password)
295
GckSecretData *sdata;
299
filename = test_data_filename ("encrypted.keyring");
300
gck_secret_collection_set_filename (collection, filename);
303
/* Unlock the keyring, which should load */
304
rv = gck_credential_create (module, gck_session_get_manager (session), GCK_OBJECT (collection),
305
(guchar*)"my-keyring-password", 19, &cred);
306
g_assert (rv == CKR_OK);
307
gck_session_add_session_object (session, NULL, GCK_OBJECT (cred));
308
g_object_unref (cred);
310
/* Unlock the keyring again, wrong password */
311
rv = gck_credential_create (module, gck_session_get_manager (session), GCK_OBJECT (collection),
312
(guchar*)"wrong", 5, &cred);
313
g_assert (rv == CKR_PIN_INCORRECT);
315
sdata = gck_secret_collection_unlocked_use (collection, session);
316
g_assert (sdata != NULL && GCK_IS_SECRET_DATA (sdata));
317
test_secret_collection_validate (collection, sdata);
318
g_object_unref (sdata);
321
DEFINE_TEST(secret_collection_memory_unlock)
327
/* Load the data in the file */
328
res = gck_secret_collection_load (collection);
329
g_assert (res == GCK_DATA_SUCCESS);
331
/* Unlock the keyring, which should load again */
332
rv = gck_credential_create (module, gck_session_get_manager (session), GCK_OBJECT (collection),
334
g_assert (rv == CKR_OK);
335
gck_session_add_session_object (session, NULL, GCK_OBJECT (cred));
336
g_object_unref (cred);
339
DEFINE_TEST(secret_collection_memory_unlock_bad_password)
345
/* Load the data in the file */
346
res = gck_secret_collection_load (collection);
347
g_assert (res == GCK_DATA_SUCCESS);
349
/* Unlock the keyring, which should load again */
350
rv = gck_credential_create (module, gck_session_get_manager (session), GCK_OBJECT (collection),
351
(guchar*)"wrong", 5, &cred);
352
g_assert (rv == CKR_PIN_INCORRECT);
355
DEFINE_TEST(secret_collection_factory)
357
CK_OBJECT_CLASS klass = CKO_G_COLLECTION;
360
CK_ATTRIBUTE attrs[] = {
361
{ CKA_CLASS, &klass, sizeof (klass) },
362
{ CKA_LABEL, "blah", 4 },
363
{ CKA_G_CREDENTIAL, &credential, sizeof (credential) },
366
object = gck_session_create_object_for_factory (session, GCK_FACTORY_SECRET_COLLECTION, NULL,
367
attrs, G_N_ELEMENTS (attrs));
368
g_assert (object != NULL);
369
g_assert (GCK_IS_SECRET_COLLECTION (object));
371
g_assert_cmpstr (gck_secret_object_get_label (GCK_SECRET_OBJECT (object)), ==, "blah");
372
g_object_unref (object);
375
DEFINE_TEST(secret_collection_factory_unnamed)
377
CK_OBJECT_CLASS klass = CKO_G_COLLECTION;
378
const gchar *identifier;
381
CK_ATTRIBUTE attrs[] = {
382
{ CKA_CLASS, &klass, sizeof (klass) },
383
{ CKA_G_CREDENTIAL, &credential, sizeof (credential) },
386
object = gck_session_create_object_for_factory (session, GCK_FACTORY_SECRET_COLLECTION, NULL,
387
attrs, G_N_ELEMENTS (attrs));
388
g_assert (object != NULL);
389
g_assert (GCK_IS_SECRET_COLLECTION (object));
391
identifier = gck_secret_object_get_identifier (GCK_SECRET_OBJECT (object));
392
g_assert_cmpstr (identifier, !=, "");
393
g_object_unref (object);
396
DEFINE_TEST(secret_collection_factory_token)
398
CK_OBJECT_CLASS klass = CKO_G_COLLECTION;
399
const gchar *identifier;
401
CK_BBOOL token = CK_TRUE;
403
CK_ATTRIBUTE attrs[] = {
404
{ CKA_CLASS, &klass, sizeof (klass) },
405
{ CKA_TOKEN, &token, sizeof (token) },
406
{ CKA_LABEL, "blah", 4 },
407
{ CKA_G_CREDENTIAL, &credential, sizeof (credential) },
410
object = gck_session_create_object_for_factory (session, GCK_FACTORY_SECRET_COLLECTION, NULL,
411
attrs, G_N_ELEMENTS (attrs));
412
g_assert (object != NULL);
413
g_assert (GCK_IS_SECRET_COLLECTION (object));
415
identifier = gck_secret_object_get_identifier (GCK_SECRET_OBJECT (object));
416
g_assert (strstr (identifier, "blah"));
417
g_object_unref (object);
420
DEFINE_TEST(secret_collection_factory_duplicate)
422
CK_OBJECT_CLASS klass = CKO_G_COLLECTION;
423
const gchar *identifier1, *identifier2;
426
CK_ATTRIBUTE attrs[] = {
427
{ CKA_G_CREDENTIAL, &credential, sizeof (credential) },
428
{ CKA_CLASS, &klass, sizeof (klass) },
429
{ CKA_LABEL, "blah", 4 },
432
object = gck_session_create_object_for_factory (session, GCK_FACTORY_SECRET_COLLECTION, NULL,
433
attrs, G_N_ELEMENTS (attrs));
434
g_assert (object != NULL);
435
g_assert (GCK_IS_SECRET_COLLECTION (object));
437
identifier1 = gck_secret_object_get_identifier (GCK_SECRET_OBJECT (object));
438
g_assert (strstr (identifier1, "blah"));
439
g_object_unref (object);
441
/* Use second credential for second object */
442
attrs[0].pValue = &credential2;
443
object = gck_session_create_object_for_factory (session, GCK_FACTORY_SECRET_COLLECTION, NULL,
444
attrs, G_N_ELEMENTS (attrs));
445
g_assert (object != NULL);
446
g_assert (GCK_IS_SECRET_COLLECTION (object));
448
identifier2 = gck_secret_object_get_identifier (GCK_SECRET_OBJECT (object));
449
g_assert (strstr (identifier2, "blah"));
450
g_object_unref (object);
452
g_assert_cmpstr (identifier1, !=, identifier2);
455
DEFINE_TEST(secret_collection_factory_item)
457
CK_OBJECT_CLASS c_klass = CKO_G_COLLECTION;
458
CK_OBJECT_CLASS i_klass = CKO_SECRET_KEY;
459
const gchar *identifier;
461
CK_BBOOL token = CK_TRUE;
463
CK_ATTRIBUTE c_attrs[] = {
464
{ CKA_CLASS, &c_klass, sizeof (c_klass) },
465
{ CKA_TOKEN, &token, sizeof (token) },
466
{ CKA_LABEL, "three", 5 },
467
{ CKA_G_CREDENTIAL, &credential, sizeof (credential) },
470
CK_ATTRIBUTE i_attrs[] = {
471
{ CKA_G_COLLECTION, NULL, 0 }, /* Filled below */
472
{ CKA_CLASS, &i_klass, sizeof (i_klass) },
473
{ CKA_TOKEN, &token, sizeof (token) },
474
{ CKA_LABEL, "Item", 4 },
477
object = gck_session_create_object_for_factory (session, GCK_FACTORY_SECRET_COLLECTION, NULL,
478
c_attrs, G_N_ELEMENTS (c_attrs));
479
g_assert (object != NULL);
480
g_assert (GCK_IS_SECRET_COLLECTION (object));
481
identifier = gck_secret_object_get_identifier (GCK_SECRET_OBJECT (object));
482
g_object_unref (object);
484
i_attrs[0].pValue = (gpointer)identifier;
485
i_attrs[0].ulValueLen = strlen (identifier);
486
object = gck_session_create_object_for_factory (session, GCK_FACTORY_SECRET_ITEM, NULL,
487
i_attrs, G_N_ELEMENTS (i_attrs));
488
g_assert (object != NULL);
489
g_assert (GCK_IS_SECRET_ITEM (object));
490
g_object_unref (object);
493
DEFINE_TEST(secret_collection_token_remove)
495
CK_OBJECT_CLASS klass = CKO_G_COLLECTION;
496
GckTransaction *transaction;
498
CK_BBOOL token = CK_TRUE;
500
CK_ATTRIBUTE attrs[] = {
501
{ CKA_CLASS, &klass, sizeof (klass) },
502
{ CKA_TOKEN, &token, sizeof (token) },
503
{ CKA_LABEL, "blah", 4 },
504
{ CKA_G_CREDENTIAL, &credential, sizeof (credential) },
507
object = gck_session_create_object_for_factory (session, GCK_FACTORY_SECRET_COLLECTION, NULL,
508
attrs, G_N_ELEMENTS (attrs));
509
g_assert (object != NULL);
510
g_assert (GCK_IS_SECRET_COLLECTION (object));
512
transaction = gck_transaction_new ();
513
gck_module_remove_token_object (module, transaction, object);
514
g_assert (!gck_transaction_get_failed (transaction));
515
gck_transaction_complete (transaction);
516
g_object_unref (transaction);
517
g_object_unref (object);
520
DEFINE_TEST(secret_collection_token_item_remove)
522
CK_OBJECT_CLASS c_klass = CKO_G_COLLECTION;
523
CK_OBJECT_CLASS i_klass = CKO_SECRET_KEY;
524
GckTransaction *transaction;
525
const gchar *identifier;
527
CK_BBOOL token = CK_TRUE;
529
CK_ATTRIBUTE c_attrs[] = {
530
{ CKA_CLASS, &c_klass, sizeof (c_klass) },
531
{ CKA_TOKEN, &token, sizeof (token) },
532
{ CKA_LABEL, "three", 5 },
533
{ CKA_G_CREDENTIAL, &credential, sizeof (credential) },
536
CK_ATTRIBUTE i_attrs[] = {
537
{ CKA_G_COLLECTION, NULL, 0 }, /* Filled below */
538
{ CKA_CLASS, &i_klass, sizeof (i_klass) },
539
{ CKA_TOKEN, &token, sizeof (token) },
540
{ CKA_LABEL, "Item", 4 },
543
object = gck_session_create_object_for_factory (session, GCK_FACTORY_SECRET_COLLECTION, NULL,
544
c_attrs, G_N_ELEMENTS (c_attrs));
545
g_assert (object != NULL);
546
g_assert (GCK_IS_SECRET_COLLECTION (object));
547
identifier = gck_secret_object_get_identifier (GCK_SECRET_OBJECT (object));
548
g_object_unref (object);
550
i_attrs[0].pValue = (gpointer)identifier;
551
i_attrs[0].ulValueLen = strlen (identifier);
552
object = gck_session_create_object_for_factory (session, GCK_FACTORY_SECRET_ITEM, NULL,
553
i_attrs, G_N_ELEMENTS (i_attrs));
554
g_assert (object != NULL);
555
g_assert (GCK_IS_SECRET_ITEM (object));
557
transaction = gck_transaction_new ();
558
gck_module_remove_token_object (module, transaction, object);
559
g_assert (!gck_transaction_get_failed (transaction));
560
gck_transaction_complete (transaction);
561
g_object_unref (transaction);
562
g_object_unref (object);