1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* test-gck-crypto.c - the GObject PKCS#11 wrapper library
3
4 Copyright (C) 2011 Collabora Ltd.
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 <stefw@collabora.co.uk>
21 */
22
23 #include "config.h"
24
25 #include "gck/gck.h"
26 #include "gck/gck-mock.h"
27 #include "gck/gck-test.h"
28
29 #include "egg/egg-testing.h"
30
31 #include <glib.h>
32
33 #include <errno.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37
38 typedef struct {
39 GckModule *module;
40 GckSession *session;
41 GckSession *session_with_auth;
42 } Test;
43
44 static gboolean
on_discard_handle_ignore(GckSession * self,CK_OBJECT_HANDLE handle,gpointer unused)45 on_discard_handle_ignore (GckSession *self, CK_OBJECT_HANDLE handle, gpointer unused)
46 {
47 /* Don't close the handle for this session, since it's a duplicate */
48 return TRUE;
49 }
50
51 static void
setup(Test * test,gconstpointer unused)52 setup (Test *test, gconstpointer unused)
53 {
54 GError *err = NULL;
55 GList *slots;
56 GckSlot *slot;
57
58 /* Successful load */
59 test->module = gck_module_initialize (_GCK_TEST_MODULE_PATH, NULL, &err);
60 g_assert_no_error (err);
61 g_assert_true (GCK_IS_MODULE (test->module));
62 g_object_add_weak_pointer (G_OBJECT (test->module), (gpointer *)&test->module);
63
64 slots = gck_module_get_slots (test->module, TRUE);
65 g_assert_nonnull (slots);
66
67 test->session = gck_slot_open_session (slots->data, 0, NULL, &err);
68 g_assert_no_error (err);
69 g_assert_true (GCK_IS_SESSION (test->session));
70 g_object_add_weak_pointer (G_OBJECT (test->session), (gpointer *)&test->session);
71
72 slot = gck_session_get_slot (test->session);
73 g_assert_nonnull (slot);
74
75 test->session_with_auth = gck_session_from_handle (slot, gck_session_get_handle (test->session), GCK_SESSION_AUTHENTICATE);
76 g_signal_connect (test->session_with_auth, "discard-handle", G_CALLBACK (on_discard_handle_ignore), NULL);
77 g_assert_nonnull (test->session_with_auth);
78 g_object_add_weak_pointer (G_OBJECT (test->session_with_auth), (gpointer *)&test->session_with_auth);
79
80 g_object_unref (slot);
81 gck_list_unref_free (slots);
82 }
83
84 static void
teardown(Test * test,gconstpointer unused)85 teardown (Test *test, gconstpointer unused)
86 {
87 g_object_unref (test->session);
88 g_object_unref (test->module);
89 g_object_unref (test->session_with_auth);
90
91 egg_test_wait_for_gtask_thread (test->session || test->session_with_auth || test->module);
92
93 g_assert_null (test->session);
94 g_assert_null (test->session_with_auth);
95 g_assert_null (test->module);
96 }
97
98 static void
fetch_async_result(GObject * source,GAsyncResult * result,gpointer user_data)99 fetch_async_result (GObject *source, GAsyncResult *result, gpointer user_data)
100 {
101 *((GAsyncResult**)user_data) = result;
102 g_object_ref (result);
103 egg_test_wait_stop ();
104 }
105
106 static GckObject*
find_key(GckSession * session,CK_ATTRIBUTE_TYPE method,CK_MECHANISM_TYPE mech)107 find_key (GckSession *session, CK_ATTRIBUTE_TYPE method, CK_MECHANISM_TYPE mech)
108 {
109 GckBuilder builder = GCK_BUILDER_INIT;
110 GList *objects, *l;
111 GckObject *object = NULL;
112 CK_MECHANISM_TYPE_PTR mechs;
113 gboolean match;
114 gsize n_mechs;
115
116 gck_builder_add_boolean (&builder, method, TRUE);
117 objects = gck_session_find_objects (session, gck_builder_end (&builder), NULL, NULL);
118 g_assert_nonnull (objects);
119
120 for (l = objects; l; l = g_list_next (l)) {
121 if (mech) {
122 mechs = (gulong *)gck_object_get_data (l->data, CKA_ALLOWED_MECHANISMS,
123 NULL, &n_mechs, NULL);
124 g_assert_nonnull (mechs);
125 g_assert_cmpuint (n_mechs, ==, sizeof (CK_MECHANISM_TYPE));
126
127 /* We know all of them only have one allowed mech */
128 match = (*mechs != mech);
129 g_free (mechs);
130
131 if (match)
132 continue;
133 }
134 object = l->data;
135 g_object_ref (object);
136 break;
137 }
138
139 gck_list_unref_free (objects);
140 return object;
141 }
142
143 static GckObject*
find_key_with_value(GckSession * session,const gchar * value)144 find_key_with_value (GckSession *session, const gchar *value)
145 {
146 GckBuilder builder = GCK_BUILDER_INIT;
147 GList *objects;
148 GckObject *object;
149
150 gck_builder_add_string (&builder, CKA_VALUE, value);
151 objects = gck_session_find_objects (session, gck_builder_end (&builder), NULL, NULL);
152 g_assert_nonnull (objects);
153
154 object = g_object_ref (objects->data);
155 gck_list_unref_free (objects);
156 return object;
157 }
158
159 static void
check_key_with_value(GckSession * session,GckObject * key,CK_OBJECT_CLASS klass,const gchar * value)160 check_key_with_value (GckSession *session, GckObject *key, CK_OBJECT_CLASS klass, const gchar *value)
161 {
162 GckAttributes *attrs;
163 const GckAttribute *attr;
164 gulong check;
165
166 attrs = gck_object_get (key, NULL, NULL, CKA_CLASS, CKA_VALUE, GCK_INVALID);
167 g_assert_nonnull (attrs);
168
169 if (!gck_attributes_find_ulong (attrs, CKA_CLASS, &check))
170 g_assert_not_reached ();
171 g_assert_cmpuint (check, ==, klass);
172
173 attr = gck_attributes_find (attrs, CKA_VALUE);
174 g_assert_nonnull (attr);
175 g_assert_false (gck_attribute_is_invalid (attr));
176 g_assert_cmpmem (attr->value, attr->length, value, strlen (value));
177
178 gck_attributes_unref (attrs);
179 }
180
181 static gboolean
authenticate_object(GckSlot * module,GckObject * object,gchar * label,gchar ** password)182 authenticate_object (GckSlot *module, GckObject *object, gchar *label, gchar **password)
183 {
184 g_assert_true (GCK_IS_MODULE (module));
185 g_assert_true (GCK_IS_OBJECT (object));
186 g_assert_nonnull (password);
187 g_assert_null (*password);
188
189 *password = g_strdup ("booo");
190 return TRUE;
191 }
192
193 static void
test_encrypt(Test * test,gconstpointer unused)194 test_encrypt (Test *test, gconstpointer unused)
195 {
196 GckMechanism mech = { CKM_MOCK_CAPITALIZE, NULL, 0 };
197 GError *error = NULL;
198 GAsyncResult *result = NULL;
199 GckObject *key;
200 guchar *output;
201 gsize n_output;
202
203 /* Find the right key */
204 key = find_key (test->session, CKA_ENCRYPT, CKM_MOCK_CAPITALIZE);
205 g_assert_nonnull (key);
206
207 /* Simple one */
208 output = gck_session_encrypt (test->session, key, CKM_MOCK_CAPITALIZE, (const guchar*)"blah blah", 10, &n_output, NULL, &error);
209 g_assert_no_error (error);
210 g_assert_nonnull (output);
211 g_assert_cmpuint (n_output, ==, 10);
212 g_assert_cmpstr ((gchar*)output, ==, "BLAH BLAH");
213 g_free (output);
214
215 /* Asynchronous one */
216 gck_session_encrypt_async (test->session, key, &mech, (const guchar*)"second chance", 14, NULL, fetch_async_result, &result);
217
218 egg_test_wait_until (500);
219 g_assert_nonnull (result);
220
221 /* Get the result */
222 output = gck_session_encrypt_finish (test->session, result, &n_output, &error);
223 g_assert_no_error (error);
224 g_assert_nonnull (output);
225 g_assert_cmpuint (n_output, ==, 14);
226 g_assert_cmpstr ((gchar*)output, ==, "SECOND CHANCE");
227 g_free (output);
228
229 g_object_unref (result);
230 g_object_unref (key);
231 }
232
233 static void
test_decrypt(Test * test,gconstpointer unused)234 test_decrypt (Test *test, gconstpointer unused)
235 {
236 GckMechanism mech = { CKM_MOCK_CAPITALIZE, NULL, 0 };
237 GError *error = NULL;
238 GAsyncResult *result = NULL;
239 GckObject *key;
240 guchar *output;
241 gsize n_output;
242
243 /* Find the right key */
244 key = find_key (test->session, CKA_DECRYPT, CKM_MOCK_CAPITALIZE);
245 g_assert_nonnull (key);
246
247 /* Simple one */
248 output = gck_session_decrypt (test->session, key, CKM_MOCK_CAPITALIZE, (const guchar*)"FRY???", 7, &n_output, NULL, &error);
249 g_assert_no_error (error);
250 g_assert_nonnull (output);
251 g_assert_cmpuint (n_output, ==, 7);
252 g_assert_cmpstr ((gchar*)output, ==, "fry???");
253 g_free (output);
254
255 /* Asynchronous one */
256 gck_session_decrypt_async (test->session, key, &mech, (const guchar*)"FAT CHANCE", 11, NULL, fetch_async_result, &result);
257
258 egg_test_wait_until (500);
259 g_assert_nonnull (result);
260
261 /* Get the result */
262 output = gck_session_decrypt_finish (test->session, result, &n_output, &error);
263 g_assert_no_error (error);
264 g_assert_nonnull (output);
265 g_assert_cmpuint (n_output, ==, 11);
266 g_assert_cmpstr ((gchar*)output, ==, "fat chance");
267 g_free (output);
268
269 g_object_unref (result);
270 g_object_unref (key);
271 }
272
273 static void
test_login_context_specific(Test * test,gconstpointer unused)274 test_login_context_specific (Test *test, gconstpointer unused)
275 {
276 /* The test module won't let us sign without doing a login, check that */
277
278 GError *error = NULL;
279 GckObject *key;
280 guchar *output;
281 gsize n_output;
282
283 /* Find the right key */
284 key = find_key (test->session, CKA_SIGN, CKM_MOCK_PREFIX);
285 g_assert_true (GCK_IS_OBJECT (key));
286 g_object_add_weak_pointer (G_OBJECT (key), (gpointer *)&key);
287
288 /* Simple one */
289 output = gck_session_sign (test->session, key, CKM_MOCK_PREFIX, (const guchar*)"TV Monster", 11, &n_output, NULL, &error);
290 g_assert_error (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN);
291 g_assert_null (output);
292 g_error_free (error);
293
294 g_object_unref (key);
295 egg_test_wait_for_gtask_thread (key);
296 g_assert_null (key);
297 }
298
299 static void
test_sign(Test * test,gconstpointer unused)300 test_sign (Test *test, gconstpointer unused)
301 {
302 GckMechanism mech = { CKM_MOCK_PREFIX, (guchar *)"my-prefix:", 10 };
303 GError *error = NULL;
304 GAsyncResult *result = NULL;
305 GckObject *key;
306 guchar *output;
307 gsize n_output;
308
309 /* Enable auto-login on this test->session, see previous test */
310 g_signal_connect (test->module, "authenticate-object", G_CALLBACK (authenticate_object), NULL);
311
312 /* Find the right key */
313 key = find_key (test->session_with_auth, CKA_SIGN, CKM_MOCK_PREFIX);
314 g_assert_nonnull (key);
315
316 /* Simple one */
317 output = gck_session_sign (test->session_with_auth, key, CKM_MOCK_PREFIX, (const guchar*)"Labarbara", 10, &n_output, NULL, &error);
318 g_assert_no_error (error);
319 g_assert_nonnull (output);
320 g_assert_cmpuint (n_output, ==, 24);
321 g_assert_cmpstr ((gchar*)output, ==, "signed-prefix:Labarbara");
322 g_free (output);
323
324 /* Asynchronous one */
325 gck_session_sign_async (test->session_with_auth, key, &mech, (const guchar*)"Conrad", 7, NULL, fetch_async_result, &result);
326
327 egg_test_wait_until (500);
328 g_assert_nonnull (result);
329
330 /* Get the result */
331 output = gck_session_sign_finish (test->session_with_auth, result, &n_output, &error);
332 g_assert_no_error (error);
333 g_assert_nonnull (output);
334 g_assert_cmpuint (n_output, ==, 17);
335 g_assert_cmpstr ((gchar*)output, ==, "my-prefix:Conrad");
336 g_free (output);
337
338 g_object_unref (result);
339 g_object_unref (key);
340 }
341
342 static void
test_verify(Test * test,gconstpointer unused)343 test_verify (Test *test, gconstpointer unused)
344 {
345 GckMechanism mech = { CKM_MOCK_PREFIX, (guchar *)"my-prefix:", 10 };
346 GError *error = NULL;
347 GAsyncResult *result = NULL;
348 GckObject *key;
349 gboolean ret;
350
351 /* Enable auto-login on this session, shouldn't be needed */
352 g_signal_connect (test->module, "authenticate-object", G_CALLBACK (authenticate_object), NULL);
353
354 /* Find the right key */
355 key = find_key (test->session, CKA_VERIFY, CKM_MOCK_PREFIX);
356 g_assert_true (GCK_IS_OBJECT (key));
357 g_object_add_weak_pointer (G_OBJECT (key), (gpointer *)&key);
358
359 /* Simple one */
360 ret = gck_session_verify (test->session, key, CKM_MOCK_PREFIX, (const guchar*)"Labarbara", 10,
361 (const guchar*)"signed-prefix:Labarbara", 24, NULL, &error);
362 g_assert_no_error (error);
363 g_assert_true (ret);
364
365 /* Failure one */
366 ret = gck_session_verify_full (test->session, key, &mech, (const guchar*)"Labarbara", 10,
367 (const guchar*)"my-prefix:Loborboro", 20, NULL, &error);
368 g_assert_nonnull (error);
369 g_assert_false (ret);
370 g_clear_error (&error);
371
372 /* Asynchronous one */
373 gck_session_verify_async (test->session, key, &mech, (const guchar*)"Labarbara", 10,
374 (const guchar*)"my-prefix:Labarbara", 20, NULL, fetch_async_result, &result);
375 egg_test_wait_until (500);
376 g_assert_nonnull (result);
377 ret = gck_session_verify_finish (test->session, result, &error);
378 g_assert_no_error (error);
379 g_assert_true (ret);
380 g_object_unref (result);
381
382 /* Asynchronous failure */
383 result = NULL;
384 gck_session_verify_async (test->session, key, &mech, (const guchar*)"Labarbara", 10,
385 (const guchar*)"my-prefix:Labarxoro", 20, NULL, fetch_async_result, &result);
386 egg_test_wait_until (500);
387 g_assert_nonnull (result);
388 ret = gck_session_verify_finish (test->session, result, &error);
389 g_assert_nonnull (error);
390 g_assert_false (ret);
391 g_clear_error (&error);
392 g_object_unref (result);
393
394 g_object_unref (key);
395 egg_test_wait_for_gtask_thread (key);
396 g_assert_null (key);
397 }
398
399 static void
test_generate_key_pair(Test * test,gconstpointer unused)400 test_generate_key_pair (Test *test, gconstpointer unused)
401 {
402 GckMechanism mech = { CKM_MOCK_GENERATE, (guchar *)"generate", 9 };
403 GckBuilder builder = GCK_BUILDER_INIT;
404 GckAttributes *pub_attrs, *prv_attrs;
405 GError *error = NULL;
406 GAsyncResult *result = NULL;
407 GckObject *pub_key, *prv_key;
408 gboolean ret;
409
410 gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PUBLIC_KEY);
411 pub_attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
412 gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PRIVATE_KEY);
413 prv_attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
414
415 /* Full One*/
416 ret = gck_session_generate_key_pair_full (test->session, &mech, pub_attrs, prv_attrs,
417 &pub_key, &prv_key, NULL, &error);
418 g_assert_no_error (error);
419 g_assert_true (ret);
420 g_object_unref (pub_key);
421 g_object_unref (prv_key);
422
423 /* Failure one */
424 mech.type = 0;
425 pub_key = prv_key = NULL;
426 ret = gck_session_generate_key_pair_full (test->session, &mech, pub_attrs, prv_attrs,
427 &pub_key, &prv_key, NULL, &error);
428 g_assert_nonnull (error);
429 g_assert_false (ret);
430 g_clear_error (&error);
431 g_assert_null (pub_key);
432 g_assert_null (prv_key);
433
434 /* Asynchronous one */
435 mech.type = CKM_MOCK_GENERATE;
436 gck_session_generate_key_pair_async (test->session, &mech, pub_attrs, prv_attrs, NULL, fetch_async_result, &result);
437 egg_test_wait_until (500);
438 g_assert_nonnull (result);
439 ret = gck_session_generate_key_pair_finish (test->session, result, &pub_key, &prv_key, &error);
440 g_assert_no_error (error);
441 g_assert_true (ret);
442 g_object_unref (result);
443 g_object_unref (pub_key);
444 g_object_unref (prv_key);
445
446 /* Asynchronous failure */
447 result = NULL;
448 mech.type = 0;
449 pub_key = prv_key = NULL;
450 gck_session_generate_key_pair_async (test->session, &mech, pub_attrs, prv_attrs, NULL, fetch_async_result, &result);
451 egg_test_wait_until (500);
452 g_assert_nonnull (result);
453 ret = gck_session_generate_key_pair_finish (test->session, result, &pub_key, &prv_key, &error);
454 g_assert_nonnull (error);
455 g_assert_false (ret);
456 g_clear_error (&error);
457 g_object_unref (result);
458 g_assert_null (pub_key);
459 g_assert_null (prv_key);
460
461 gck_attributes_unref (pub_attrs);
462 gck_attributes_unref (prv_attrs);
463 }
464
465 static void
test_wrap_key(Test * test,gconstpointer unused)466 test_wrap_key (Test *test, gconstpointer unused)
467 {
468 GckMechanism mech = { CKM_MOCK_WRAP, (guchar *)"wrap", 4 };
469 GError *error = NULL;
470 GAsyncResult *result = NULL;
471 GckObject *wrapper, *wrapped;
472 gpointer output;
473 gsize n_output;
474
475 wrapper = find_key (test->session, CKA_WRAP, 0);
476 wrapped = find_key_with_value (test->session, "value");
477
478 /* Simple One */
479 output = gck_session_wrap_key (test->session, wrapper, CKM_MOCK_WRAP, wrapped, &n_output, NULL, &error);
480 g_assert_no_error (error);
481 g_assert_nonnull (output);
482 g_assert_cmpmem (output, n_output, "value", 5);
483 g_free (output);
484
485 /* Full One*/
486 output = gck_session_wrap_key_full (test->session, wrapper, &mech, wrapped, &n_output, NULL, &error);
487 g_assert_no_error (error);
488 g_assert_nonnull (output);
489 g_assert_cmpmem (output, n_output, "value", 5);
490 g_free (output);
491
492 /* Failure one */
493 mech.type = 0;
494 n_output = 0;
495 output = gck_session_wrap_key_full (test->session, wrapper, &mech, wrapped, &n_output, NULL, &error);
496 g_assert_nonnull (error);
497 g_assert_null (output);
498 g_clear_error (&error);
499 egg_assert_cmpsize (n_output, ==, 0);
500
501 /* Asynchronous one */
502 mech.type = CKM_MOCK_WRAP;
503 gck_session_wrap_key_async (test->session, wrapper, &mech, wrapped, NULL, fetch_async_result, &result);
504 egg_test_wait_until (500);
505 g_assert_nonnull (result);
506 output = gck_session_wrap_key_finish (test->session, result, &n_output, &error);
507 g_assert_no_error (error);
508 g_assert_nonnull (output);
509 g_assert_cmpmem (output, n_output, "value", 5);
510 g_object_unref (result);
511 g_free (output);
512
513 /* Asynchronous failure */
514 result = NULL;
515 mech.type = 0;
516 n_output = 0;
517 gck_session_wrap_key_async (test->session, wrapper, &mech, wrapped, NULL, fetch_async_result, &result);
518 egg_test_wait_until (500);
519 g_assert_nonnull (result);
520 output = gck_session_wrap_key_finish (test->session, result, &n_output, &error);
521 g_assert_nonnull (error);
522 g_assert_null (output);
523 g_clear_error (&error);
524 egg_assert_cmpsize (n_output, ==, 0);
525 g_object_unref (result);
526
527 g_object_unref (wrapper);
528 g_object_unref (wrapped);
529 }
530
531 static void
test_unwrap_key(Test * test,gconstpointer unused)532 test_unwrap_key (Test *test, gconstpointer unused)
533 {
534 GckMechanism mech = { CKM_MOCK_WRAP, (guchar *)"wrap", 4 };
535 GckBuilder builder = GCK_BUILDER_INIT;
536 GError *error = NULL;
537 GAsyncResult *result = NULL;
538 GckObject *wrapper, *unwrapped;
539 GckAttributes *attrs;
540
541 wrapper = find_key (test->session, CKA_UNWRAP, 0);
542 gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY);
543 attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
544
545 /* Full One*/
546 unwrapped = gck_session_unwrap_key_full (test->session, wrapper, &mech, (const guchar *)"special", 7, attrs, NULL, &error);
547 g_assert_no_error (error);
548 g_assert_true (GCK_IS_OBJECT (unwrapped));
549 check_key_with_value (test->session, unwrapped, CKO_SECRET_KEY, "special");
550 g_object_unref (unwrapped);
551
552 /* Failure one */
553 mech.type = 0;
554 unwrapped = gck_session_unwrap_key_full (test->session, wrapper, &mech, (const guchar *)"special", 7, attrs, NULL, &error);
555 g_assert_nonnull (error);
556 g_assert_null (unwrapped);
557 g_clear_error (&error);
558
559 /* Asynchronous one */
560 mech.type = CKM_MOCK_WRAP;
561 gck_session_unwrap_key_async (test->session, wrapper, &mech, (const guchar *)"special", 7, attrs, NULL, fetch_async_result, &result);
562 egg_test_wait_until (500);
563 g_assert_nonnull (result);
564 unwrapped = gck_session_unwrap_key_finish (test->session, result, &error);
565 g_assert_no_error (error);
566 g_assert_true (GCK_IS_OBJECT (unwrapped));
567 check_key_with_value (test->session, unwrapped, CKO_SECRET_KEY, "special");
568 g_object_unref (unwrapped);
569 g_object_unref (result);
570
571 /* Asynchronous failure */
572 result = NULL;
573 mech.type = 0;
574 gck_session_unwrap_key_async (test->session, wrapper, &mech, (const guchar *)"special", 6, attrs, NULL, fetch_async_result, &result);
575 egg_test_wait_until (500);
576 g_assert_nonnull (result);
577 unwrapped = gck_session_unwrap_key_finish (test->session, result, &error);
578 g_assert_nonnull (error);
579 g_assert_null (unwrapped);
580 g_clear_error (&error);
581 g_object_unref (result);
582
583 g_object_unref (wrapper);
584 gck_attributes_unref (attrs);
585 }
586
587 static void
test_derive_key(Test * test,gconstpointer unused)588 test_derive_key (Test *test, gconstpointer unused)
589 {
590 GckMechanism mech = { CKM_MOCK_DERIVE, (guchar *)"derive", 6 };
591 GckBuilder builder = GCK_BUILDER_INIT;
592 GError *error = NULL;
593 GAsyncResult *result = NULL;
594 GckObject *wrapper, *derived;
595 GckAttributes *attrs;
596
597 wrapper = find_key (test->session, CKA_DERIVE, 0);
598 gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY);
599 attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
600
601 /* Full One*/
602 derived = gck_session_derive_key_full (test->session, wrapper, &mech, attrs, NULL, &error);
603 g_assert_no_error (error);
604 g_assert_true (GCK_IS_OBJECT (derived));
605 check_key_with_value (test->session, derived, CKO_SECRET_KEY, "derived");
606 g_object_unref (derived);
607
608 /* Failure one */
609 mech.type = 0;
610 derived = gck_session_derive_key_full (test->session, wrapper, &mech, attrs, NULL, &error);
611 g_assert_nonnull (error);
612 g_assert_null (derived);
613 g_clear_error (&error);
614
615 /* Asynchronous one */
616 mech.type = CKM_MOCK_DERIVE;
617 gck_session_derive_key_async (test->session, wrapper, &mech, attrs, NULL, fetch_async_result, &result);
618 egg_test_wait_until (500);
619 g_assert_nonnull (result);
620 derived = gck_session_derive_key_finish (test->session, result, &error);
621 g_assert_no_error (error);
622 g_assert_true (GCK_IS_OBJECT (derived));
623 check_key_with_value (test->session, derived, CKO_SECRET_KEY, "derived");
624 g_object_unref (derived);
625 g_object_unref (result);
626
627 /* Asynchronous failure */
628 result = NULL;
629 mech.type = 0;
630 gck_session_derive_key_async (test->session, wrapper, &mech, attrs, NULL, fetch_async_result, &result);
631 egg_test_wait_until (500);
632 g_assert_nonnull (result);
633 derived = gck_session_derive_key_finish (test->session, result, &error);
634 g_assert_nonnull (error);
635 g_assert_null (derived);
636 g_clear_error (&error);
637 g_object_unref (result);
638
639 g_object_unref (wrapper);
640 gck_attributes_unref (attrs);
641 }
642
643 static void
null_log_handler(const gchar * log_domain,GLogLevelFlags log_level,const gchar * message,gpointer user_data)644 null_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
645 const gchar *message, gpointer user_data)
646 {
647
648 }
649
650 int
main(int argc,char ** argv)651 main (int argc, char **argv)
652 {
653 g_test_init (&argc, &argv, NULL);
654
655 g_set_prgname ("test-gck-crypto");
656
657 /* Suppress these messages in tests */
658 g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG,
659 null_log_handler, NULL);
660
661 g_test_add ("/gck/crypto/encrypt", Test, NULL, setup, test_encrypt, teardown);
662 g_test_add ("/gck/crypto/decrypt", Test, NULL, setup, test_decrypt, teardown);
663 g_test_add ("/gck/crypto/login_context_specific", Test, NULL, setup, test_login_context_specific, teardown);
664 g_test_add ("/gck/crypto/sign", Test, NULL, setup, test_sign, teardown);
665 g_test_add ("/gck/crypto/verify", Test, NULL, setup, test_verify, teardown);
666 g_test_add ("/gck/crypto/generate_key_pair", Test, NULL, setup, test_generate_key_pair, teardown);
667 g_test_add ("/gck/crypto/wrap_key", Test, NULL, setup, test_wrap_key, teardown);
668 g_test_add ("/gck/crypto/unwrap_key", Test, NULL, setup, test_unwrap_key, teardown);
669 g_test_add ("/gck/crypto/derive_key", Test, NULL, setup, test_derive_key, teardown);
670
671 return egg_tests_run_with_loop ();
672 }
673