Line data Source code
1 : /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 : /* unit-test-memory-test->store.c: Test memory test->store functionality
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 : <http://www.gnu.org/licenses/>.
19 :
20 : Author: Stef Walter <stef@memberwebs.com>
21 : */
22 :
23 : #include "config.h"
24 :
25 : #include <stdlib.h>
26 : #include <stdio.h>
27 : #include <string.h>
28 : #include <unistd.h>
29 :
30 : #include "mock-module.h"
31 :
32 : #include "egg/egg-secure-memory.h"
33 : #include "gkm/gkm-object.h"
34 : #include "gkm/gkm-memory-store.h"
35 : #include "gkm/gkm-transaction.h"
36 :
37 : typedef struct {
38 : GkmModule *module;
39 : GkmStore *store;
40 : GkmObject *object;
41 : GkmTransaction *transaction;
42 : guchar buffer[1024];
43 : } Test;
44 :
45 : static CK_RV
46 8 : check_validator (GkmObject *obj, CK_ATTRIBUTE_PTR attr)
47 : {
48 : const gchar *data;
49 : guint i;
50 :
51 8 : g_assert (attr);
52 8 : g_assert (attr->type == CKA_LABEL);
53 :
54 : /* Test that the whole string is ascii and lower case */
55 8 : data = attr->pValue;
56 51 : for (i = 0; i < attr->ulValueLen; ++i) {
57 44 : if (!g_ascii_isprint(data[i]) || !g_ascii_islower (data[i]))
58 1 : return CKR_ATTRIBUTE_VALUE_INVALID;
59 : }
60 :
61 7 : return CKR_OK;
62 : }
63 :
64 : static void
65 15 : setup (Test *test, gconstpointer unused)
66 : {
67 : CK_ATTRIBUTE attr;
68 15 : CK_ULONG twentyfour = 24;
69 :
70 15 : test->module = mock_module_initialize_and_enter ();
71 :
72 15 : attr.type = CKA_LABEL;
73 15 : attr.pValue = "label";
74 15 : attr.ulValueLen = 5;
75 :
76 15 : test->store = GKM_STORE (gkm_memory_store_new ());
77 :
78 15 : gkm_store_register_schema (test->store, &attr, check_validator, 0);
79 15 : g_assert (gkm_store_lookup_schema (test->store, CKA_LABEL, NULL));
80 :
81 15 : attr.type = CKA_VALUE;
82 15 : attr.pValue = NULL;
83 15 : attr.ulValueLen = 0;
84 :
85 15 : gkm_store_register_schema (test->store, &attr, NULL, GKM_STORE_IS_SENSITIVE);
86 :
87 15 : attr.type = CKA_BITS_PER_PIXEL;
88 15 : attr.pValue = &twentyfour;
89 15 : attr.ulValueLen = sizeof (twentyfour);
90 :
91 15 : gkm_store_register_schema (test->store, &attr, NULL, GKM_STORE_IS_INTERNAL);
92 :
93 15 : test->object = g_object_new (GKM_TYPE_OBJECT, "module", test->module, NULL);
94 :
95 15 : test->transaction = gkm_transaction_new ();
96 15 : }
97 :
98 : static void
99 15 : teardown (Test *test, gconstpointer unused)
100 : {
101 15 : g_object_unref (test->store);
102 15 : test->store = NULL;
103 :
104 15 : g_object_unref (test->transaction);
105 15 : test->transaction = NULL;
106 :
107 15 : if (test->object != NULL)
108 14 : g_object_unref (test->object);
109 15 : test->object = NULL;
110 :
111 15 : mock_module_leave_and_finalize ();
112 15 : test->module = NULL;
113 15 : }
114 :
115 : static void
116 1 : test_get_attribute_default (Test *test, gconstpointer unused)
117 : {
118 : CK_ATTRIBUTE attr;
119 : CK_RV rv;
120 :
121 1 : attr.type = CKA_LABEL;
122 1 : attr.pValue = NULL;
123 1 : rv = gkm_store_get_attribute (test->store, test->object, &attr);
124 1 : g_assert (rv == CKR_OK);
125 1 : g_assert (attr.ulValueLen == 5);
126 1 : attr.pValue = test->buffer;
127 1 : rv = gkm_store_get_attribute (test->store, test->object, &attr);
128 1 : g_assert (rv == CKR_OK);
129 1 : g_assert (attr.ulValueLen == 5);
130 1 : g_assert (memcmp (attr.pValue, "label", 5) == 0);
131 1 : }
132 :
133 : static void
134 1 : test_read_value_default (Test *test, gconstpointer unused)
135 : {
136 : gconstpointer value;
137 : gsize n_value;
138 :
139 1 : value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value);
140 1 : g_assert (value);
141 1 : g_assert (n_value == 5);
142 1 : g_assert (memcmp (value, "label", 5) == 0);
143 :
144 1 : value = gkm_store_read_value (test->store, test->object, CKA_BITS_PER_PIXEL, &n_value);
145 1 : g_assert (value);
146 1 : g_assert (n_value == sizeof (CK_ULONG));
147 1 : g_assert (*((CK_ULONG_PTR)value) == 24);
148 1 : }
149 :
150 : static void
151 1 : test_read_string (Test *test, gconstpointer unused)
152 : {
153 : gchar *str;
154 :
155 1 : str = gkm_store_read_string (test->store, test->object, CKA_LABEL);
156 1 : g_assert_cmpstr (str, ==, "label");
157 1 : g_free (str);
158 1 : }
159 :
160 : static void
161 1 : test_get_invalid (Test *test, gconstpointer unused)
162 : {
163 : CK_ATTRIBUTE attr;
164 : CK_RV rv;
165 :
166 1 : attr.type = CKA_APPLICATION;
167 1 : attr.pValue = NULL;
168 1 : attr.ulValueLen = 0;
169 :
170 1 : rv = gkm_store_get_attribute (test->store, test->object, &attr);
171 1 : g_assert (rv == CKR_ATTRIBUTE_TYPE_INVALID);
172 1 : }
173 :
174 : static void
175 1 : test_get_sensitive (Test *test, gconstpointer unused)
176 : {
177 : CK_ATTRIBUTE attr;
178 : CK_RV rv;
179 :
180 1 : attr.type = CKA_VALUE;
181 1 : attr.pValue = NULL;
182 1 : attr.ulValueLen = 0;
183 :
184 1 : rv = gkm_store_get_attribute (test->store, test->object, &attr);
185 1 : g_assert (rv == CKR_ATTRIBUTE_SENSITIVE);
186 1 : }
187 :
188 : static void
189 1 : test_get_internal (Test *test, gconstpointer unused)
190 : {
191 : CK_ATTRIBUTE attr;
192 : CK_RV rv;
193 :
194 1 : attr.type = CKA_BITS_PER_PIXEL;
195 1 : attr.pValue = NULL;
196 1 : attr.ulValueLen = 0;
197 :
198 1 : rv = gkm_store_get_attribute (test->store, test->object, &attr);
199 1 : g_assert (rv == CKR_ATTRIBUTE_TYPE_INVALID);
200 1 : }
201 :
202 : static void
203 1 : test_set_invalid (Test *test, gconstpointer unused)
204 : {
205 : CK_ATTRIBUTE attr;
206 :
207 1 : attr.type = CKA_APPLICATION;
208 1 : attr.pValue = "me";
209 1 : attr.ulValueLen = 2;
210 :
211 1 : gkm_store_set_attribute (test->store, test->transaction, test->object, &attr);
212 1 : g_assert (gkm_transaction_get_result (test->transaction) == CKR_ATTRIBUTE_TYPE_INVALID);
213 1 : }
214 :
215 : static void
216 1 : test_set_internal (Test *test, gconstpointer unused)
217 : {
218 : CK_ATTRIBUTE attr;
219 1 : CK_ULONG five = 5;
220 :
221 1 : attr.type = CKA_BITS_PER_PIXEL;
222 1 : attr.pValue = &five;
223 1 : attr.ulValueLen = sizeof (five);
224 :
225 1 : gkm_store_set_attribute (test->store, test->transaction, test->object, &attr);
226 1 : g_assert (gkm_transaction_get_result (test->transaction) == CKR_ATTRIBUTE_TYPE_INVALID);
227 1 : }
228 :
229 : static void
230 1 : test_set_get_attribute (Test *test, gconstpointer unused)
231 : {
232 : CK_ATTRIBUTE attr;
233 : CK_RV rv;
234 :
235 1 : attr.type = CKA_LABEL;
236 1 : attr.pValue = "booyah";
237 1 : attr.ulValueLen = 6;
238 :
239 1 : gkm_store_set_attribute (test->store, test->transaction, test->object, &attr);
240 :
241 1 : gkm_transaction_complete (test->transaction);
242 1 : g_assert (gkm_transaction_get_result (test->transaction) == CKR_OK);
243 :
244 1 : attr.pValue = test->buffer;
245 1 : attr.ulValueLen = 1024;
246 1 : rv = gkm_store_get_attribute (test->store, test->object, &attr);
247 1 : g_assert (rv == CKR_OK);
248 1 : g_assert (attr.ulValueLen == 6);
249 1 : g_assert (memcmp (attr.pValue, "booyah", 6) == 0);
250 1 : }
251 :
252 : static void
253 1 : test_write_read_value (Test *test, gconstpointer unused)
254 : {
255 : CK_ATTRIBUTE attr;
256 1 : CK_ULONG five = 5;
257 : gconstpointer value;
258 : gsize n_value;
259 :
260 1 : attr.type = CKA_BITS_PER_PIXEL;
261 1 : attr.pValue = &five;
262 1 : attr.ulValueLen = sizeof (five);
263 :
264 1 : gkm_store_write_value (test->store, test->transaction, test->object, &attr);
265 :
266 1 : gkm_transaction_complete (test->transaction);
267 1 : g_assert (gkm_transaction_get_result (test->transaction) == CKR_OK);
268 :
269 1 : value = gkm_store_read_value (test->store, test->object, CKA_BITS_PER_PIXEL, &n_value);
270 1 : g_assert (value);
271 1 : g_assert (n_value == sizeof (five));
272 1 : g_assert (memcmp (value, &five, sizeof (five)) == 0);
273 1 : }
274 :
275 : static void
276 1 : test_set_no_validate (Test *test, gconstpointer unused)
277 : {
278 : CK_ATTRIBUTE attr;
279 :
280 1 : attr.type = CKA_LABEL;
281 1 : attr.pValue = "CAPITALS";
282 1 : attr.ulValueLen = 8;
283 :
284 1 : gkm_store_set_attribute (test->store, test->transaction, test->object, &attr);
285 1 : g_assert (gkm_transaction_get_failed (test->transaction));
286 :
287 1 : gkm_transaction_complete (test->transaction);
288 1 : g_assert (gkm_transaction_get_result (test->transaction) == CKR_ATTRIBUTE_VALUE_INVALID);
289 1 : }
290 :
291 : static void
292 1 : test_set_transaction_default (Test *test, gconstpointer unused)
293 : {
294 : CK_ATTRIBUTE attr;
295 : gconstpointer value;
296 : gsize n_value;
297 :
298 :
299 1 : attr.type = CKA_LABEL;
300 1 : attr.pValue = "another";
301 1 : attr.ulValueLen = 7;
302 :
303 : /* Change the attribute */
304 1 : gkm_store_set_attribute (test->store, test->transaction, test->object, &attr);
305 1 : g_assert (gkm_transaction_get_failed (test->transaction) == FALSE);
306 :
307 : /* Should get new value */
308 1 : value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value);
309 1 : g_assert (value && n_value == attr.ulValueLen);
310 1 : g_assert (memcmp (attr.pValue, value, n_value) == 0);
311 :
312 : /* Fail for some arbitrary reason */
313 1 : gkm_transaction_fail (test->transaction, CKR_ATTRIBUTE_VALUE_INVALID);
314 :
315 : /* Value should not have changed yet */
316 1 : value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value);
317 1 : g_assert (value && n_value == attr.ulValueLen);
318 1 : g_assert (memcmp (attr.pValue, value, n_value) == 0);
319 :
320 : /* Now complete the test->transaction */
321 1 : gkm_transaction_complete (test->transaction);
322 1 : g_assert (gkm_transaction_get_failed (test->transaction) == TRUE);
323 :
324 : /* Value should now have changed, back to default */
325 1 : value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value);
326 1 : g_assert (value && n_value == 5);
327 1 : g_assert (memcmp (value, "label", 5) == 0);
328 1 : }
329 :
330 : static void
331 1 : test_set_transaction_revert_first (Test *test, gconstpointer unused)
332 : {
333 : CK_ATTRIBUTE attr, prev;
334 : gconstpointer value;
335 : gsize n_value;
336 :
337 1 : prev.type = CKA_LABEL;
338 1 : prev.pValue = "numberone";
339 1 : prev.ulValueLen = 9;
340 :
341 : /* Change the attribute */
342 1 : gkm_store_set_attribute (test->store, test->transaction, test->object, &prev);
343 1 : gkm_transaction_complete (test->transaction);
344 1 : g_assert (gkm_transaction_get_failed (test->transaction) == FALSE);
345 :
346 : /* Value should be new value */
347 1 : value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value);
348 1 : g_assert (value && n_value == prev.ulValueLen);
349 1 : g_assert (memcmp (prev.pValue, value, n_value) == 0);
350 :
351 : /* A new test->transaction */
352 1 : g_object_unref (test->transaction);
353 1 : test->transaction = gkm_transaction_new ();
354 :
355 1 : attr.type = CKA_LABEL;
356 1 : attr.pValue = "second";
357 1 : attr.ulValueLen = 6;
358 :
359 1 : gkm_store_set_attribute (test->store, test->transaction, test->object, &attr);
360 1 : g_assert (gkm_transaction_get_failed (test->transaction) == FALSE);
361 :
362 : /* Should get new value */
363 1 : value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value);
364 1 : g_assert (value && n_value == attr.ulValueLen);
365 1 : g_assert (memcmp (attr.pValue, value, n_value) == 0);
366 :
367 1 : attr.type = CKA_LABEL;
368 1 : attr.pValue = "third";
369 1 : attr.ulValueLen = 5;
370 :
371 1 : gkm_store_set_attribute (test->store, test->transaction, test->object, &attr);
372 1 : g_assert (gkm_transaction_get_failed (test->transaction) == FALSE);
373 :
374 : /* Should get new value */
375 1 : value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value);
376 1 : g_assert (value && n_value == attr.ulValueLen);
377 1 : g_assert (memcmp (attr.pValue, value, n_value) == 0);
378 :
379 : /* Fail for some arbitrary reason */
380 1 : gkm_transaction_fail (test->transaction, CKR_ATTRIBUTE_VALUE_INVALID);
381 :
382 : /* Value should not have changed yet */
383 1 : value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value);
384 1 : g_assert (value && n_value == attr.ulValueLen);
385 1 : g_assert (memcmp (attr.pValue, value, n_value) == 0);
386 :
387 : /* Now complete the test->transaction */
388 1 : gkm_transaction_complete (test->transaction);
389 1 : g_assert (gkm_transaction_get_failed (test->transaction) == TRUE);
390 :
391 : /* Value should now have changed, back to default */
392 1 : value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value);
393 1 : g_assert (value && n_value == prev.ulValueLen);
394 1 : g_assert (memcmp (prev.pValue, value, n_value) == 0);
395 1 : }
396 :
397 : static void
398 2 : notify_attribute (GkmObject *obj, CK_ATTRIBUTE_TYPE type, gpointer data)
399 : {
400 2 : g_assert (type == CKA_LABEL);
401 2 : g_assert (data);
402 :
403 2 : *((CK_ATTRIBUTE_TYPE*)data) = type;
404 2 : }
405 :
406 : static void
407 1 : test_set_notifies (Test *test, gconstpointer unused)
408 : {
409 : CK_ATTRIBUTE attr;
410 1 : CK_ATTRIBUTE_TYPE type = 0;
411 :
412 1 : attr.type = CKA_LABEL;
413 1 : attr.pValue = "valid";
414 1 : attr.ulValueLen = 5;
415 :
416 1 : g_signal_connect (test->object, "notify-attribute", G_CALLBACK (notify_attribute), &type);
417 :
418 1 : gkm_store_set_attribute (test->store, test->transaction, test->object, &attr);
419 :
420 : /* We should have been notified that the attribute changed at this point */
421 1 : g_assert (type == CKA_LABEL);
422 :
423 : /* Reset for next notify */
424 1 : type = 0;
425 :
426 : /* Fail for some arbitrary reason */
427 1 : gkm_transaction_fail (test->transaction, CKR_ATTRIBUTE_VALUE_INVALID);
428 :
429 : /* We should not have been notified yet */
430 1 : g_assert (type == 0);
431 :
432 : /* Now complete the test->transaction */
433 1 : gkm_transaction_complete (test->transaction);
434 1 : g_assert (gkm_transaction_get_failed (test->transaction) == TRUE);
435 :
436 : /* Now we should have been notified that this changed back */
437 1 : g_assert (type == CKA_LABEL);
438 1 : }
439 :
440 : static void
441 1 : test_set_object_gone_first (Test *test, gconstpointer unused)
442 : {
443 : CK_ATTRIBUTE attr;
444 :
445 1 : attr.type = CKA_LABEL;
446 1 : attr.pValue = "valid";
447 1 : attr.ulValueLen = 5;
448 :
449 1 : gkm_store_set_attribute (test->store, test->transaction, test->object, &attr);
450 1 : gkm_transaction_complete (test->transaction);
451 1 : g_assert (gkm_transaction_get_result (test->transaction) == CKR_OK);
452 :
453 : /* This tests memory test->store internal tracking */
454 1 : g_object_unref (test->object);
455 1 : test->object = NULL;
456 1 : }
457 :
458 : int
459 1 : main (int argc, char **argv)
460 : {
461 : #if !GLIB_CHECK_VERSION(2,35,0)
462 : g_type_init ();
463 : #endif
464 1 : g_test_init (&argc, &argv, NULL);
465 :
466 1 : g_test_add ("/gkm/memory-test->store/get_attribute_default", Test, NULL, setup, test_get_attribute_default, teardown);
467 1 : g_test_add ("/gkm/memory-test->store/read_value_default", Test, NULL, setup, test_read_value_default, teardown);
468 1 : g_test_add ("/gkm/memory-test->store/read_string", Test, NULL, setup, test_read_string, teardown);
469 1 : g_test_add ("/gkm/memory-test->store/get_invalid", Test, NULL, setup, test_get_invalid, teardown);
470 1 : g_test_add ("/gkm/memory-test->store/get_sensitive", Test, NULL, setup, test_get_sensitive, teardown);
471 1 : g_test_add ("/gkm/memory-test->store/get_internal", Test, NULL, setup, test_get_internal, teardown);
472 1 : g_test_add ("/gkm/memory-test->store/set_invalid", Test, NULL, setup, test_set_invalid, teardown);
473 1 : g_test_add ("/gkm/memory-test->store/set_internal", Test, NULL, setup, test_set_internal, teardown);
474 1 : g_test_add ("/gkm/memory-test->store/set_get_attribute", Test, NULL, setup, test_set_get_attribute, teardown);
475 1 : g_test_add ("/gkm/memory-test->store/write_read_value", Test, NULL, setup, test_write_read_value, teardown);
476 1 : g_test_add ("/gkm/memory-test->store/set_no_validate", Test, NULL, setup, test_set_no_validate, teardown);
477 1 : g_test_add ("/gkm/memory-test->store/set_transaction_default", Test, NULL, setup, test_set_transaction_default, teardown);
478 1 : g_test_add ("/gkm/memory-test->store/set_transaction_revert_first", Test, NULL, setup, test_set_transaction_revert_first, teardown);
479 1 : g_test_add ("/gkm/memory-test->store/set_notifies", Test, NULL, setup, test_set_notifies, teardown);
480 1 : g_test_add ("/gkm/memory-test->store/set_object_gone_first", Test, NULL, setup, test_set_object_gone_first, teardown);
481 :
482 1 : return g_test_run ();
483 : }
|