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