1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /*
3 Copyright (C) 2010 Stefan Walter
4
5 The Gnome Keyring Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 The Gnome Keyring Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the Gnome Library; see the file COPYING.LIB. If not,
17 see <http://www.gnu.org/licenses/>.
18
19 Author: Stef Walter <stef@memberwebs.com>
20 */
21
22 #include "config.h"
23
24 #include "gcr/gcr-base.h"
25 #include "gcr/gcr-internal.h"
26
27 #include "gck/gck-mock.h"
28 #include "gck/gck-test.h"
29 #include <p11-kit/pkcs11.h>
30 #include "gck/pkcs11n.h"
31 #include "gck/pkcs11x.h"
32
33 #include "egg/egg-testing.h"
34
35 #include <glib.h>
36
37 #include <errno.h>
38
39 typedef struct {
40 CK_FUNCTION_LIST funcs;
41 GcrCertificate *certificate;
42 } Test;
43
44 static void
setup(Test * test,gconstpointer unused)45 setup (Test *test, gconstpointer unused)
46 {
47 GList *modules = NULL;
48 CK_FUNCTION_LIST_PTR f;
49 GckModule *module;
50 gchar *contents;
51 const gchar *uris[2];
52 gsize len;
53 CK_RV rv;
54
55 if (!g_file_get_contents (SRCDIR "/gcr/fixtures/der-certificate.crt", &contents, &len, NULL))
56 g_assert_not_reached ();
57 g_assert (contents);
58
59 test->certificate = gcr_simple_certificate_new ((const guchar *)contents, len);
60 g_free (contents);
61
62 rv = gck_mock_C_GetFunctionList (&f);
63 gck_assert_cmprv (rv, ==, CKR_OK);
64 memcpy (&test->funcs, f, sizeof (test->funcs));
65
66 /* Open a session */
67 rv = (test->funcs.C_Initialize) (NULL);
68 gck_assert_cmprv (rv, ==, CKR_OK);
69
70 g_assert (!modules);
71 module = gck_module_new (&test->funcs);
72 modules = g_list_prepend (modules, module);
73 gcr_pkcs11_set_modules (modules);
74 gck_list_unref_free (modules);
75
76 uris[0] = GCK_MOCK_SLOT_ONE_URI;
77 uris[1] = NULL;
78
79 gcr_pkcs11_set_trust_store_uri (GCK_MOCK_SLOT_ONE_URI);
80 gcr_pkcs11_set_trust_lookup_uris (uris);
81 }
82
83 static void
teardown(Test * test,gconstpointer unused)84 teardown (Test *test, gconstpointer unused)
85 {
86 CK_RV rv;
87
88 g_object_unref (test->certificate);
89
90 rv = (test->funcs.C_Finalize) (NULL);
91 gck_assert_cmprv (rv, ==, CKR_OK);
92
93 _gcr_uninitialize_library ();
94 }
95
96 static void
test_is_pinned_none(Test * test,gconstpointer unused)97 test_is_pinned_none (Test *test, gconstpointer unused)
98 {
99 GError *error = NULL;
100 gboolean trust;
101
102 trust = gcr_trust_is_certificate_pinned (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
103 g_assert_cmpint (trust, ==, FALSE);
104 g_assert (error == NULL);
105 }
106
107 static void
test_add_and_is_pinned(Test * test,gconstpointer unused)108 test_add_and_is_pinned (Test *test, gconstpointer unused)
109 {
110 GError *error = NULL;
111 gboolean trust;
112 gboolean ret;
113
114 trust = gcr_trust_is_certificate_pinned (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
115 g_assert_cmpint (trust, ==, FALSE);
116 g_assert (error == NULL);
117
118 ret = gcr_trust_add_pinned_certificate (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
119 g_assert (ret == TRUE);
120 g_assert (error == NULL);
121
122 trust = gcr_trust_is_certificate_pinned (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
123 g_assert_cmpint (trust, ==, TRUE);
124 g_assert (error == NULL);
125 }
126
127 static void
test_add_certificate_pinned_fail(Test * test,gconstpointer unused)128 test_add_certificate_pinned_fail (Test *test, gconstpointer unused)
129 {
130 GError *error = NULL;
131 gboolean ret;
132
133 /* Make this function fail */
134 test->funcs.C_CreateObject = gck_mock_fail_C_CreateObject;
135
136 ret = gcr_trust_add_pinned_certificate (test->certificate, GCR_PURPOSE_CLIENT_AUTH, "peer", NULL, &error);
137 g_assert (ret == FALSE);
138 g_assert_error (error, GCK_ERROR, CKR_FUNCTION_FAILED);
139 g_clear_error (&error);
140 }
141
142 static void
test_add_and_remov_pinned(Test * test,gconstpointer unused)143 test_add_and_remov_pinned (Test *test, gconstpointer unused)
144 {
145 GError *error = NULL;
146 gboolean trust;
147 gboolean ret;
148
149 ret = gcr_trust_add_pinned_certificate (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
150 g_assert (ret == TRUE);
151 g_assert (error == NULL);
152
153 trust = gcr_trust_is_certificate_pinned (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
154 g_assert_cmpint (trust, ==, TRUE);
155 g_assert (error == NULL);
156
157 ret = gcr_trust_remove_pinned_certificate (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
158 g_assert (ret == TRUE);
159 g_assert (error == NULL);
160
161 trust = gcr_trust_is_certificate_pinned (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
162 g_assert_cmpint (trust, ==, FALSE);
163 g_assert (error == NULL);
164 }
165
166 static void
fetch_async_result(GObject * source,GAsyncResult * result,gpointer user_data)167 fetch_async_result (GObject *source, GAsyncResult *result, gpointer user_data)
168 {
169 *((GAsyncResult**)user_data) = result;
170 g_object_ref (result);
171 egg_test_wait_stop ();
172 }
173
174 static void
test_add_and_is_pinned_async(Test * test,gconstpointer unused)175 test_add_and_is_pinned_async (Test *test, gconstpointer unused)
176 {
177 GAsyncResult *result = NULL;
178 GError *error = NULL;
179 gboolean trust;
180 gboolean ret;
181
182 gcr_trust_is_certificate_pinned_async (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, fetch_async_result, &result);
183 egg_test_wait_until (500);
184 g_assert (result);
185 trust = gcr_trust_is_certificate_pinned_finish (result, &error);
186 g_assert (trust == FALSE);
187 g_assert (error == NULL);
188 g_object_unref (result);
189 result = NULL;
190
191 gcr_trust_add_pinned_certificate_async (test->certificate, GCR_PURPOSE_EMAIL, "host",
192 NULL, fetch_async_result, &result);
193 egg_test_wait_until (500);
194 g_assert (result);
195 ret = gcr_trust_add_pinned_certificate_finish (result, &error);
196 g_assert (ret == TRUE);
197 g_assert (error == NULL);
198 g_object_unref (result);
199 result = NULL;
200
201 gcr_trust_is_certificate_pinned_async (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, fetch_async_result, &result);
202 egg_test_wait_until (500);
203 g_assert (result);
204 trust = gcr_trust_is_certificate_pinned_finish (result, &error);
205 g_assert (trust == TRUE);
206 g_assert (error == NULL);
207 g_object_unref (result);
208 result = NULL;
209 }
210
211 static void
test_add_and_remov_pinned_async(Test * test,gconstpointer unused)212 test_add_and_remov_pinned_async (Test *test, gconstpointer unused)
213 {
214 GAsyncResult *result = NULL;
215 GError *error = NULL;
216 gboolean trust;
217 gboolean ret;
218
219 gcr_trust_add_pinned_certificate_async (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, fetch_async_result, &result);
220 egg_test_wait_until (500);
221 g_assert (result);
222 ret = gcr_trust_add_pinned_certificate_finish (result, &error);
223 g_assert (ret == TRUE);
224 g_assert (error == NULL);
225 g_object_unref (result);
226 result = NULL;
227
228 gcr_trust_is_certificate_pinned_async (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, fetch_async_result, &result);
229 egg_test_wait_until (500);
230 g_assert (result);
231 trust = gcr_trust_is_certificate_pinned_finish (result, &error);
232 g_assert (trust == TRUE);
233 g_assert (error == NULL);
234 g_object_unref (result);
235 result = NULL;
236
237 gcr_trust_remove_pinned_certificate_async (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, fetch_async_result, &result);
238 egg_test_wait_until (500);
239 g_assert (result);
240 ret = gcr_trust_remove_pinned_certificate_finish (result, &error);
241 g_assert (ret == TRUE);
242 g_assert (error == NULL);
243 g_object_unref (result);
244 result = NULL;
245
246 gcr_trust_is_certificate_pinned_async (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, fetch_async_result, &result);
247 egg_test_wait_until (500);
248 g_assert (result);
249 trust = gcr_trust_is_certificate_pinned_finish (result, &error);
250 g_assert (trust == FALSE);
251 g_assert (error == NULL);
252 g_object_unref (result);
253 result = NULL;
254 }
255
256 static void
test_is_certificate_anchored_not(Test * test,gconstpointer unused)257 test_is_certificate_anchored_not (Test *test, gconstpointer unused)
258 {
259 GError *error = NULL;
260 gboolean ret;
261
262 ret = gcr_trust_is_certificate_anchored (test->certificate, GCR_PURPOSE_CLIENT_AUTH, NULL, &error);
263 g_assert (ret == FALSE);
264 g_assert (error == NULL);
265 }
266
267 static void
test_is_certificate_anchored_yes(Test * test,gconstpointer unused)268 test_is_certificate_anchored_yes (Test *test, gconstpointer unused)
269 {
270 GckBuilder builder = GCK_BUILDER_INIT;
271 GError *error = NULL;
272 gconstpointer der;
273 gsize n_der;
274 gboolean ret;
275
276 /* Create a certificate root trust */
277 der = gcr_certificate_get_der_data (test->certificate, &n_der);
278 gck_builder_add_data (&builder, CKA_X_CERTIFICATE_VALUE, der, n_der);
279 gck_builder_add_ulong (&builder, CKA_CLASS, CKO_X_TRUST_ASSERTION);
280 gck_builder_add_boolean (&builder, CKA_TOKEN, TRUE);
281 gck_builder_add_string (&builder, CKA_X_PURPOSE, GCR_PURPOSE_CLIENT_AUTH);
282 gck_builder_add_ulong (&builder, CKA_X_ASSERTION_TYPE, CKT_X_ANCHORED_CERTIFICATE);
283 gck_mock_module_add_object (gck_builder_end (&builder));
284
285 ret = gcr_trust_is_certificate_anchored (test->certificate, GCR_PURPOSE_CLIENT_AUTH, NULL, &error);
286 g_assert (ret == TRUE);
287 g_assert (error == NULL);
288 }
289
290 static void
test_is_certificate_anchored_async(Test * test,gconstpointer unused)291 test_is_certificate_anchored_async (Test *test, gconstpointer unused)
292 {
293 GAsyncResult *result = NULL;
294 GError *error = NULL;
295 gboolean ret;
296
297 gcr_trust_is_certificate_anchored_async (test->certificate, GCR_PURPOSE_CLIENT_AUTH, NULL, fetch_async_result, &result);
298 egg_test_wait_until (500);
299 g_assert (result);
300
301 ret = gcr_trust_is_certificate_anchored_finish (result, &error);
302 g_assert (ret == FALSE);
303 g_assert (error == NULL);
304
305 g_object_unref (result);
306 }
307
308 int
main(int argc,char ** argv)309 main (int argc, char **argv)
310 {
311 g_test_init (&argc, &argv, NULL);
312 g_set_prgname ("test-trust");
313
314 g_test_add ("/gcr/trust/is_pinned_none", Test, NULL, setup, test_is_pinned_none, teardown);
315 g_test_add ("/gcr/trust/add_and_is_pinned", Test, NULL, setup, test_add_and_is_pinned, teardown);
316 g_test_add ("/gcr/trust/add_certificate_pinned_fail", Test, NULL, setup, test_add_certificate_pinned_fail, teardown);
317 g_test_add ("/gcr/trust/add_and_remov_pinned", Test, NULL, setup, test_add_and_remov_pinned, teardown);
318 g_test_add ("/gcr/trust/add_and_is_pinned_async", Test, NULL, setup, test_add_and_is_pinned_async, teardown);
319 g_test_add ("/gcr/trust/add_and_remov_pinned_async", Test, NULL, setup, test_add_and_remov_pinned_async, teardown);
320 g_test_add ("/gcr/trust/is_certificate_anchored_not", Test, NULL, setup, test_is_certificate_anchored_not, teardown);
321 g_test_add ("/gcr/trust/is_certificate_anchored_yes", Test, NULL, setup, test_is_certificate_anchored_yes, teardown);
322 g_test_add ("/gcr/trust/is_certificate_anchored_async", Test, NULL, setup, test_is_certificate_anchored_async, teardown);
323
324 return egg_tests_run_with_loop ();
325 }
326