Line data Source code
1 : /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 : /* test-object.c: Test GkmObject
3 :
4 : Copyright (C) 2009 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 "mock-module.h"
26 :
27 : #include "gkm/gkm-attributes.h"
28 : #include "gkm/gkm-object.h"
29 : #include "gkm/gkm-session.h"
30 : #include "gkm/gkm-module.h"
31 : #include "gkm/gkm-transaction.h"
32 :
33 : #include "egg/egg-testing.h"
34 :
35 : #include "pkcs11i.h"
36 :
37 : typedef struct {
38 : GkmModule *module;
39 : GkmSession *session;
40 : gchar *certificate_data;
41 : gsize n_certificate_data;
42 : } Test;
43 :
44 : static void
45 7 : setup (Test* test, gconstpointer unused)
46 : {
47 7 : test->module = mock_module_initialize_and_enter ();
48 7 : test->session = mock_module_open_session (TRUE);
49 :
50 7 : if (!g_file_get_contents (SRCDIR "/pkcs11/gkm/fixtures/test-certificate-1.der", &test->certificate_data, &test->n_certificate_data, NULL))
51 0 : g_assert_not_reached ();
52 7 : }
53 :
54 : static void
55 7 : teardown (Test* test, gconstpointer unused)
56 : {
57 7 : g_free (test->certificate_data);
58 7 : mock_module_leave_and_finalize ();
59 7 : }
60 :
61 : static gboolean
62 4 : check_object_exists (CK_OBJECT_HANDLE handle, Test *test)
63 : {
64 : CK_BBOOL token;
65 4 : CK_ATTRIBUTE attr = { CKA_TOKEN, &token, sizeof (token) };
66 : CK_RV rv;
67 :
68 4 : rv = gkm_session_C_GetAttributeValue (test->session, handle, &attr, 1);
69 4 : if (rv == CKR_OBJECT_HANDLE_INVALID)
70 2 : return FALSE;
71 :
72 2 : g_assert (rv == CKR_OK);
73 2 : return TRUE;
74 : }
75 :
76 : static void
77 1 : test_create_destroy_transient (Test* test, gconstpointer unused)
78 : {
79 1 : CK_BBOOL transient = CK_TRUE;
80 1 : CK_BBOOL token = CK_TRUE;
81 1 : CK_OBJECT_CLASS klass = CKO_CERTIFICATE;
82 1 : CK_CERTIFICATE_TYPE type = CKC_X_509;
83 :
84 1 : CK_ATTRIBUTE attrs[] = {
85 : { CKA_TOKEN, &token, sizeof (token) },
86 : { CKA_GNOME_TRANSIENT, &transient, sizeof (transient) },
87 : { CKA_CLASS, &klass, sizeof (klass) },
88 : { CKA_CERTIFICATE_TYPE, &type, sizeof (type) },
89 1 : { CKA_VALUE, test->certificate_data, test->n_certificate_data },
90 : };
91 :
92 1 : CK_ATTRIBUTE lookup = { CKA_GNOME_TRANSIENT, &transient, sizeof (transient) };
93 : CK_OBJECT_HANDLE handle;
94 : CK_RV rv;
95 :
96 1 : rv = gkm_session_C_CreateObject (test->session, attrs, G_N_ELEMENTS (attrs), &handle);
97 1 : g_assert (rv == CKR_OK);
98 1 : g_assert (handle != 0);
99 :
100 1 : g_assert (check_object_exists (handle, test));
101 :
102 1 : transient = CK_FALSE;
103 1 : rv = gkm_session_C_GetAttributeValue (test->session, handle, &lookup, 1);
104 1 : g_assert (rv == CKR_OK);
105 1 : g_assert (transient == CK_TRUE);
106 :
107 1 : rv = gkm_session_C_DestroyObject (test->session, handle);
108 1 : g_assert (rv == CKR_OK);
109 :
110 1 : g_assert (!check_object_exists (handle, test));
111 1 : }
112 :
113 : static void
114 1 : test_transient_transacted_fail (Test* test, gconstpointer unused)
115 : {
116 1 : CK_BBOOL transient = CK_TRUE;
117 1 : CK_BBOOL token = CK_TRUE;
118 1 : CK_OBJECT_CLASS klass = CKO_CERTIFICATE;
119 1 : CK_CERTIFICATE_TYPE type = CKC_X_509;
120 1 : CK_ULONG invalid = 4;
121 :
122 1 : CK_ATTRIBUTE attrs[] = {
123 : { CKA_TOKEN, &token, sizeof (token) },
124 : { CKA_GNOME_TRANSIENT, &transient, sizeof (transient) },
125 : { CKA_CLASS, &klass, sizeof (klass) },
126 : { CKA_CERTIFICATE_TYPE, &type, sizeof (type) },
127 1 : { CKA_VALUE, test->certificate_data, test->n_certificate_data },
128 :
129 : /* An invalid attribute, should cause transaction to fail */
130 : { CKA_BITS_PER_PIXEL, &invalid, sizeof (invalid) }
131 : };
132 :
133 : CK_OBJECT_HANDLE handle;
134 : CK_RV rv;
135 :
136 1 : rv = gkm_session_C_CreateObject (test->session, attrs, G_N_ELEMENTS (attrs), &handle);
137 1 : g_assert (rv == CKR_ATTRIBUTE_TYPE_INVALID);
138 1 : }
139 :
140 : static void
141 1 : test_create_transient_bad_value (Test* test, gconstpointer unused)
142 : {
143 1 : CK_OBJECT_CLASS klass = CKO_CERTIFICATE;
144 1 : CK_CERTIFICATE_TYPE type = CKC_X_509;
145 :
146 1 : CK_ATTRIBUTE attrs[] = {
147 : { CKA_GNOME_TRANSIENT, NULL, 0 },
148 : { CKA_CLASS, &klass, sizeof (klass) },
149 : { CKA_CERTIFICATE_TYPE, &type, sizeof (type) },
150 1 : { CKA_VALUE, test->certificate_data, test->n_certificate_data },
151 : };
152 :
153 : CK_OBJECT_HANDLE handle;
154 : CK_RV rv;
155 :
156 : /* Can't have a non-transient object that auto-destructs */
157 1 : rv = gkm_session_C_CreateObject (test->session, attrs, G_N_ELEMENTS (attrs), &handle);
158 1 : g_assert (rv == CKR_ATTRIBUTE_VALUE_INVALID);
159 1 : }
160 :
161 : static void
162 1 : test_create_auto_destruct (Test* test, gconstpointer unused)
163 : {
164 1 : CK_BBOOL token = CK_FALSE;
165 1 : CK_OBJECT_CLASS klass = CKO_CERTIFICATE;
166 1 : CK_CERTIFICATE_TYPE type = CKC_X_509;
167 1 : CK_ULONG lifetime = 2;
168 : CK_ULONG check;
169 :
170 1 : CK_ATTRIBUTE attrs[] = {
171 : { CKA_G_DESTRUCT_AFTER, &lifetime, sizeof (lifetime) },
172 : { CKA_TOKEN, &token, sizeof (token) },
173 : { CKA_CLASS, &klass, sizeof (klass) },
174 : { CKA_CERTIFICATE_TYPE, &type, sizeof (type) },
175 1 : { CKA_VALUE, test->certificate_data, test->n_certificate_data },
176 : };
177 :
178 : CK_BBOOL transient;
179 :
180 1 : CK_ATTRIBUTE lookups[] = {
181 : { CKA_G_DESTRUCT_AFTER, &check, sizeof (check) },
182 : { CKA_GNOME_TRANSIENT, &transient, sizeof (transient) }
183 : };
184 :
185 : CK_OBJECT_HANDLE handle;
186 : CK_RV rv;
187 :
188 1 : rv = gkm_session_C_CreateObject (test->session, attrs, G_N_ELEMENTS (attrs), &handle);
189 1 : g_assert (rv == CKR_OK);
190 1 : g_assert (handle != 0);
191 :
192 1 : g_assert (check_object_exists (handle, test));
193 :
194 1 : transient = CK_FALSE;
195 1 : rv = gkm_session_C_GetAttributeValue (test->session, handle, lookups, G_N_ELEMENTS (lookups));
196 1 : g_assert (rv == CKR_OK);
197 1 : g_assert (transient == TRUE);
198 1 : g_assert (memcmp (&lifetime, &check, sizeof (lifetime)) == 0);
199 :
200 1 : mock_module_leave ();
201 1 : egg_test_wait_until (2200);
202 1 : mock_module_enter ();
203 :
204 1 : g_assert (!check_object_exists (handle, test));
205 1 : }
206 :
207 : static void
208 1 : test_create_auto_destruct_not_transient (Test* test, gconstpointer unused)
209 : {
210 1 : CK_OBJECT_CLASS klass = CKO_CERTIFICATE;
211 1 : CK_CERTIFICATE_TYPE type = CKC_X_509;
212 1 : CK_BBOOL transient = CK_FALSE;
213 1 : CK_ULONG after = 1;
214 :
215 1 : CK_ATTRIBUTE attrs[] = {
216 : { CKA_G_DESTRUCT_AFTER, &after, sizeof (after) },
217 : { CKA_GNOME_TRANSIENT, &transient, sizeof (transient) },
218 : { CKA_CLASS, &klass, sizeof (klass) },
219 : { CKA_CERTIFICATE_TYPE, &type, sizeof (type) },
220 1 : { CKA_VALUE, test->certificate_data, test->n_certificate_data },
221 : };
222 :
223 : CK_OBJECT_HANDLE handle;
224 : CK_RV rv;
225 :
226 : /* Can't have a non-transient object that auto-destructs */
227 1 : rv = gkm_session_C_CreateObject (test->session, attrs, G_N_ELEMENTS (attrs), &handle);
228 1 : g_assert (rv == CKR_TEMPLATE_INCONSISTENT);
229 1 : }
230 :
231 : static void
232 1 : test_expose (Test* test, gconstpointer unused)
233 : {
234 : CK_OBJECT_HANDLE handle;
235 : GkmManager *manager;
236 : GkmObject *check, *object;
237 :
238 1 : manager = gkm_session_get_manager (test->session);
239 1 : object = mock_module_object_new (test->session);
240 :
241 1 : handle = gkm_object_get_handle (object);
242 1 : gkm_object_expose (object, TRUE);
243 :
244 : /* Now it should have a handle, and be visible */
245 1 : check = gkm_manager_find_by_handle (manager, handle);
246 1 : g_assert (check == object);
247 :
248 1 : gkm_object_expose (object, FALSE);
249 :
250 : /* Now should be invisible */
251 1 : check = gkm_manager_find_by_handle (manager, handle);
252 1 : g_assert (check == NULL);
253 1 : }
254 :
255 : static void
256 1 : test_expose_transaction (Test* test, gconstpointer unused)
257 : {
258 : CK_OBJECT_HANDLE handle;
259 : GkmManager *manager;
260 : GkmObject *check, *object;
261 : GkmTransaction *transaction;
262 :
263 1 : manager = gkm_session_get_manager (test->session);
264 1 : object = mock_module_object_new (test->session);
265 :
266 1 : handle = gkm_object_get_handle (object);
267 1 : transaction = gkm_transaction_new ();
268 :
269 : /* Should be hidden */
270 1 : gkm_object_expose (object, FALSE);
271 1 : check = gkm_manager_find_by_handle (manager, handle);
272 1 : g_assert (check == NULL);
273 :
274 : /* Now it should have a handle, and be visible */
275 1 : gkm_object_expose_full (object, transaction, TRUE);
276 1 : check = gkm_manager_find_by_handle (manager, handle);
277 1 : g_assert (check == object);
278 :
279 1 : gkm_transaction_fail (transaction, CKR_GENERAL_ERROR);
280 1 : gkm_transaction_complete (transaction);
281 :
282 : /* Now should be invisible */
283 1 : check = gkm_manager_find_by_handle (manager, handle);
284 1 : g_assert (check == NULL);
285 :
286 1 : g_object_unref (transaction);
287 1 : }
288 :
289 : int
290 1 : main (int argc, char **argv)
291 : {
292 : #if !GLIB_CHECK_VERSION(2,35,0)
293 : g_type_init ();
294 : #endif
295 1 : g_test_init (&argc, &argv, NULL);
296 :
297 1 : g_test_add ("/gkm/object/create_destroy_transient", Test, NULL, setup, test_create_destroy_transient, teardown);
298 1 : g_test_add ("/gkm/object/transient_transacted_fail", Test, NULL, setup, test_transient_transacted_fail, teardown);
299 1 : g_test_add ("/gkm/object/create_transient_bad_value", Test, NULL, setup, test_create_transient_bad_value, teardown);
300 1 : g_test_add ("/gkm/object/create_auto_destruct", Test, NULL, setup, test_create_auto_destruct, teardown);
301 1 : g_test_add ("/gkm/object/create_auto_destruct_not_transient", Test, NULL, setup, test_create_auto_destruct_not_transient, teardown);
302 1 : g_test_add ("/gkm/object/expose", Test, NULL, setup, test_expose, teardown);
303 1 : g_test_add ("/gkm/object/expose_transaction", Test, NULL, setup, test_expose_transaction, teardown);
304 :
305 1 : return egg_tests_run_in_thread_with_loop ();
306 : }
|