Branch data Line data Source code
1 : : /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 : : /*
3 : : Copyright (C) 2010 Collabora Ltd
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 <stefw@collabora.co.uk>
20 : : */
21 : :
22 : : #include "config.h"
23 : :
24 : : #include "gcr/gcr.h"
25 : : #include "gcr/gcr-internal.h"
26 : :
27 : : #include "egg/egg-asn1x.h"
28 : : #include "egg/egg-asn1-defs.h"
29 : : #include "egg/egg-testing.h"
30 : :
31 : : #include "gck/gck-mock.h"
32 : : #include "gck/gck-test.h"
33 : : #include <p11-kit/pkcs11.h>
34 : : #include "gck/pkcs11x.h"
35 : :
36 : : #include <glib.h>
37 : :
38 : : #include <errno.h>
39 : : #include <string.h>
40 : :
41 : : /* ---------------------------------------------------------------------------
42 : : * A Mock certificate that checks that it's always called on the
43 : : * same thread. A GcrCertificate implemented on top of a non-thread-safe
44 : : * crypto library would require this behavior.
45 : : */
46 : :
47 : : GType mock_certificate_get_type (void);
48 : :
49 : : #define MOCK_CERTIFICATE(obj) \
50 : : (G_TYPE_CHECK_INSTANCE_CAST ((obj), mock_certificate_get_type (), MockCertificate))
51 : :
52 : : typedef struct _MockCertificate {
53 : : GObject parent;
54 : : GThread *created_on;
55 : : gpointer data;
56 : : gsize n_data;
57 : : } MockCertificate;
58 : :
59 : : typedef struct _MockCertificateClass {
60 : : GObjectClass parent_class;
61 : : } MockCertificateClass;
62 : :
63 : : static void mock_certificate_iface (GcrCertificateIface *iface);
64 [ + + + - : 210 : G_DEFINE_TYPE_WITH_CODE (MockCertificate, mock_certificate, G_TYPE_OBJECT,
+ + ]
65 : : G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, mock_certificate_iface);
66 : : );
67 : :
68 : : static void
69 : 75 : mock_certificate_init (MockCertificate *self)
70 : : {
71 : 75 : self->created_on = g_thread_self ();
72 : 75 : }
73 : :
74 : : static void
75 : 75 : mock_certificate_finalize (GObject *obj)
76 : : {
77 : 75 : MockCertificate *self = MOCK_CERTIFICATE (obj);
78 [ - + ]: 75 : g_assert (self->created_on == g_thread_self ());
79 : 75 : g_free (self->data);
80 : 75 : G_OBJECT_CLASS (mock_certificate_parent_class)->finalize (obj);
81 : 75 : }
82 : :
83 : : static void
84 : 1 : mock_certificate_class_init (MockCertificateClass *klass)
85 : : {
86 : 1 : GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
87 : 1 : gobject_class->finalize = mock_certificate_finalize;
88 : 1 : gobject_class->get_property = gcr_certificate_mixin_get_property;
89 : 1 : gcr_certificate_mixin_class_init (gobject_class);
90 : 1 : }
91 : :
92 : : static gconstpointer
93 : 58 : mock_certificate_real_get_der_data (GcrCertificate *base, gsize *n_data)
94 : : {
95 : 58 : MockCertificate *self = MOCK_CERTIFICATE (base);
96 [ - + ]: 58 : g_assert (self->created_on == g_thread_self ());
97 : 58 : *n_data = self->n_data;
98 : 58 : return self->data;
99 : : }
100 : :
101 : : static void
102 : 1 : mock_certificate_iface (GcrCertificateIface *iface)
103 : : {
104 : 1 : iface->get_der_data = (gpointer)mock_certificate_real_get_der_data;
105 : 1 : }
106 : :
107 : : static GcrCertificate*
108 : 75 : mock_certificate_new (gconstpointer data, gsize n_data)
109 : : {
110 : 75 : MockCertificate *self = g_object_new (mock_certificate_get_type (), NULL);
111 : 75 : self->data = g_memdup2 (data, n_data);
112 : 75 : self->n_data = n_data;
113 [ - + ]: 75 : g_assert (self->created_on == g_thread_self ());
114 : 75 : return GCR_CERTIFICATE (self);
115 : : }
116 : :
117 : : /* ----------------------------------------------------------------------------
118 : : * TESTS
119 : : */
120 : :
121 : : typedef struct {
122 : : /* A self signed certificate */
123 : : GcrCertificate *cert_self;
124 : :
125 : : /* Simple CA + issued */
126 : : GcrCertificate *cert_ca;
127 : : GcrCertificate *cert_signed;
128 : :
129 : : /* Root + intermediate + issued */
130 : : GcrCertificate *cert_root;
131 : : GcrCertificate *cert_inter;
132 : : GcrCertificate *cert_host;
133 : :
134 : : CK_FUNCTION_LIST funcs;
135 : : } Test;
136 : :
137 : : static void
138 : 15 : setup (Test *test, gconstpointer unused)
139 : : {
140 : 15 : GList *modules = NULL;
141 : : CK_FUNCTION_LIST_PTR f;
142 : : gchar *contents;
143 : : gsize n_contents;
144 : : const gchar *uris[2];
145 : : CK_RV rv;
146 : : GckModule *module;
147 : :
148 : 15 : rv = gck_mock_C_GetFunctionList (&f);
149 [ - + ]: 15 : gck_assert_cmprv (rv, ==, CKR_OK);
150 : 15 : memcpy (&test->funcs, f, sizeof (test->funcs));
151 : :
152 : : /* Open a session */
153 : 15 : rv = (test->funcs.C_Initialize) (NULL);
154 [ - + ]: 15 : gck_assert_cmprv (rv, ==, CKR_OK);
155 : :
156 [ - + ]: 15 : g_assert (!modules);
157 : 15 : module = gck_module_new (&test->funcs);
158 : 15 : modules = g_list_prepend (modules, module);
159 : 15 : gcr_pkcs11_set_modules (modules);
160 : 15 : uris[0] = GCK_MOCK_SLOT_ONE_URI;
161 : 15 : uris[1] = NULL;
162 : 15 : gcr_pkcs11_set_trust_lookup_uris (uris);
163 : 15 : gcr_pkcs11_set_trust_store_uri (GCK_MOCK_SLOT_ONE_URI);
164 [ + - + - ]: 15 : g_clear_list (&modules, g_object_unref);
165 : :
166 : : /* A self-signed certificate */
167 [ - + ]: 15 : if (!g_file_get_contents (SRCDIR "/gcr/fixtures/der-certificate.crt", &contents, &n_contents, NULL))
168 : 0 : g_assert_not_reached ();
169 : 15 : test->cert_self = gcr_simple_certificate_new ((const guchar *)contents, n_contents);
170 : 15 : g_free (contents);
171 : :
172 : : /* A signed certificate */
173 [ - + ]: 15 : if (!g_file_get_contents (SRCDIR "/gcr/fixtures/dhansak-collabora.cer", &contents, &n_contents, NULL))
174 : 0 : g_assert_not_reached ();
175 : 15 : test->cert_signed = mock_certificate_new (contents, n_contents);
176 : 15 : g_free (contents);
177 : :
178 : : /* The signer for the above certificate */
179 [ - + ]: 15 : if (!g_file_get_contents (SRCDIR "/gcr/fixtures/collabora-ca.cer", &contents, &n_contents, NULL))
180 : 0 : g_assert_not_reached ();
181 : 15 : test->cert_ca = mock_certificate_new (contents, n_contents);
182 : 15 : g_free (contents);
183 : :
184 : : /* A root CA */
185 [ - + ]: 15 : if (!g_file_get_contents (SRCDIR "/gcr/fixtures/startcom-ca.cer", &contents, &n_contents, NULL))
186 : 0 : g_assert_not_reached ();
187 : 15 : test->cert_root = mock_certificate_new (contents, n_contents);
188 : 15 : g_free (contents);
189 : :
190 : : /* An intermediate */
191 [ - + ]: 15 : if (!g_file_get_contents (SRCDIR "/gcr/fixtures/startcom-intermediate.cer", &contents, &n_contents, NULL))
192 : 0 : g_assert_not_reached ();
193 : 15 : test->cert_inter = mock_certificate_new (contents, n_contents);
194 : 15 : g_free (contents);
195 : :
196 : : /* Signed by above intermediate */
197 [ - + ]: 15 : if (!g_file_get_contents (SRCDIR "/gcr/fixtures/jabber-server.cer", &contents, &n_contents, NULL))
198 : 0 : g_assert_not_reached ();
199 : 15 : test->cert_host = mock_certificate_new (contents, n_contents);
200 : 15 : g_free (contents);
201 : 15 : }
202 : :
203 : : static void
204 : 5 : add_certificate_to_module (GcrCertificate *certificate)
205 : : {
206 : 5 : GckBuilder builder = GCK_BUILDER_INIT;
207 : : gconstpointer data;
208 : : gsize n_data, n_subject;
209 : : gpointer subject;
210 : :
211 : 5 : data = gcr_certificate_get_der_data (certificate, &n_data);
212 [ - + ]: 5 : g_assert (data);
213 : :
214 : 5 : subject = gcr_certificate_get_subject_raw (certificate, &n_subject);
215 [ - + ]: 5 : g_assert (subject);
216 : :
217 : : /* Add a certificate to the module */
218 : 5 : gck_builder_add_data (&builder, CKA_VALUE, data, n_data);
219 : 5 : gck_builder_add_ulong (&builder, CKA_CLASS, CKO_CERTIFICATE);
220 : 5 : gck_builder_add_ulong (&builder, CKA_CERTIFICATE_TYPE, CKC_X_509);
221 : 5 : gck_builder_add_data (&builder, CKA_SUBJECT, subject, n_subject);
222 : 5 : gck_mock_module_add_object (gck_builder_end (&builder));
223 : :
224 : 5 : g_free (subject);
225 : 5 : }
226 : :
227 : : static void
228 : 3 : add_anchor_to_module (GcrCertificate *certificate, const gchar *purpose)
229 : : {
230 : 3 : GckBuilder builder = GCK_BUILDER_INIT;
231 : : gconstpointer data;
232 : : gsize n_data;
233 : :
234 : 3 : data = gcr_certificate_get_der_data (certificate, &n_data);
235 [ - + ]: 3 : g_assert (data);
236 : :
237 : : /* And add a pinned certificate for the signed certificate */
238 : 3 : gck_builder_add_data (&builder, CKA_X_CERTIFICATE_VALUE, data, n_data);
239 : 3 : gck_builder_add_ulong (&builder, CKA_CLASS, CKO_X_TRUST_ASSERTION);
240 : 3 : gck_builder_add_ulong (&builder, CKA_X_ASSERTION_TYPE, CKT_X_ANCHORED_CERTIFICATE);
241 : 3 : gck_builder_add_string (&builder, CKA_X_PURPOSE, purpose);
242 : 3 : gck_mock_module_add_object (gck_builder_end (&builder));
243 : 3 : }
244 : :
245 : : static void
246 : 1 : add_pinned_to_module (GcrCertificate *certificate, const gchar *purpose, const gchar *host)
247 : : {
248 : 1 : GckBuilder builder = GCK_BUILDER_INIT;
249 : : gconstpointer data;
250 : : gsize n_data;
251 : :
252 : 1 : data = gcr_certificate_get_der_data (certificate, &n_data);
253 [ - + ]: 1 : g_assert (data);
254 : :
255 : : /* And add a pinned certificate for the signed certificate */
256 : 1 : gck_builder_add_data (&builder, CKA_X_CERTIFICATE_VALUE, data, n_data);
257 : 1 : gck_builder_add_ulong (&builder, CKA_CLASS, CKO_X_TRUST_ASSERTION);
258 : 1 : gck_builder_add_ulong (&builder, CKA_X_ASSERTION_TYPE, CKT_X_PINNED_CERTIFICATE);
259 : 1 : gck_builder_add_string (&builder, CKA_X_PURPOSE, purpose);
260 : 1 : gck_builder_add_string (&builder, CKA_X_PEER, host);
261 : 1 : gck_mock_module_add_object (gck_builder_end (&builder));
262 : 1 : }
263 : :
264 : : void
265 : 75 : on_toggle_notify (gpointer data,
266 : : GObject *object,
267 : : gboolean is_last_ref)
268 : : {
269 : 75 : gboolean *last_ref = data;
270 : :
271 : 75 : *last_ref = is_last_ref;
272 : 75 : }
273 : :
274 : : static void
275 : 75 : wait_for_object_finalized (GObject *object)
276 : : {
277 : 75 : gpointer weak_object = object;
278 : 75 : gboolean last_ref = FALSE;
279 : :
280 : : /* GTask may release the object later than us as per GNOME/glib#1346,
281 : : * causing the test to fail when checking in which thread the objects
282 : : * are finalized. To ensure that the order is preserved we need then
283 : : * to wait that the GTask releases its last reference before we do.
284 : : */
285 : 75 : g_object_add_weak_pointer (object, &weak_object);
286 : 75 : g_object_add_toggle_ref (object, on_toggle_notify, &last_ref);
287 : 75 : g_object_unref (object);
288 [ - + ]: 75 : egg_test_wait_for_gtask_thread (!last_ref);
289 : :
290 : 75 : g_object_remove_toggle_ref (object, on_toggle_notify, &last_ref);
291 [ - + ]: 75 : g_assert_null (weak_object);
292 : 75 : }
293 : :
294 : : static void
295 : 15 : teardown (Test *test, gconstpointer unused)
296 : : {
297 : : CK_RV rv;
298 : :
299 : 15 : g_object_unref (test->cert_self);
300 : 15 : wait_for_object_finalized (G_OBJECT (test->cert_signed));
301 : 15 : wait_for_object_finalized (G_OBJECT (test->cert_ca));
302 : 15 : wait_for_object_finalized (G_OBJECT (test->cert_host));
303 : 15 : wait_for_object_finalized (G_OBJECT (test->cert_inter));
304 : 15 : wait_for_object_finalized (G_OBJECT (test->cert_root));
305 : :
306 : 15 : rv = (test->funcs.C_Finalize) (NULL);
307 [ - + ]: 15 : gck_assert_cmprv (rv, ==, CKR_OK);
308 : :
309 : 15 : _gcr_uninitialize_library ();
310 : 15 : }
311 : :
312 : : static void
313 : 1 : test_new (Test *test, gconstpointer unused)
314 : : {
315 : : GcrCertificateChain *chain;
316 : :
317 : 1 : chain = gcr_certificate_chain_new ();
318 : :
319 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
320 : : GCR_CERTIFICATE_CHAIN_UNKNOWN);
321 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 0);
322 : :
323 [ - + ]: 1 : g_assert (gcr_certificate_chain_get_endpoint (chain) == NULL);
324 : :
325 : 1 : g_object_unref (chain);
326 : 1 : }
327 : :
328 : : static void
329 : 1 : test_new_with_cert (Test *test, gconstpointer unused)
330 : : {
331 : : GcrCertificateChain *chain;
332 : : GcrCertificate *check;
333 : : guint status, length;
334 : :
335 : 1 : chain = gcr_certificate_chain_new ();
336 : 1 : gcr_certificate_chain_add (chain, test->cert_signed);
337 : 1 : gcr_certificate_chain_add (chain, test->cert_ca);
338 : :
339 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
340 : : GCR_CERTIFICATE_CHAIN_UNKNOWN);
341 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
342 : :
343 : 1 : status = G_MAXUINT;
344 : 1 : length = 0;
345 : 1 : g_object_get (chain, "status", &status, "length", &length, NULL);
346 [ - + ]: 1 : g_assert_cmpuint (status, ==, GCR_CERTIFICATE_CHAIN_UNKNOWN);
347 [ - + ]: 1 : g_assert_cmpuint (length, ==, 2);
348 : :
349 : 1 : check = gcr_certificate_chain_get_certificate (chain, 1);
350 [ - + ]: 1 : g_assert (check == test->cert_ca);
351 : :
352 : : /* Not yet completed */
353 : 1 : check = gcr_certificate_chain_get_anchor (chain);
354 [ - + ]: 1 : g_assert (check == NULL);
355 : :
356 : 1 : check = gcr_certificate_chain_get_endpoint (chain);
357 [ - + ]: 1 : g_assert (check == test->cert_signed);
358 : :
359 : 1 : g_object_unref (chain);
360 : 1 : }
361 : :
362 : : static void
363 : 1 : test_selfsigned (Test *test, gconstpointer unused)
364 : : {
365 : : GcrCertificateChain *chain;
366 : 1 : GError *error = NULL;
367 : :
368 : 1 : chain = gcr_certificate_chain_new ();
369 : :
370 : : /* Add a self-signed certificate */
371 : 1 : gcr_certificate_chain_add (chain, test->cert_self);
372 : :
373 [ - + ]: 1 : if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
374 : : NULL, 0, NULL, &error))
375 : 0 : g_assert_not_reached ();
376 [ - + ]: 1 : g_assert_no_error (error);
377 : :
378 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
379 : : GCR_CERTIFICATE_CHAIN_SELFSIGNED);
380 : :
381 : 1 : g_object_unref (chain);
382 : 1 : }
383 : :
384 : : static void
385 : 1 : test_incomplete (Test *test, gconstpointer unused)
386 : : {
387 : : GcrCertificateChain *chain;
388 : 1 : GError *error = NULL;
389 : :
390 : 1 : chain = gcr_certificate_chain_new ();
391 : :
392 : : /* Add a signed certificate */
393 : 1 : gcr_certificate_chain_add (chain, test->cert_signed);
394 : :
395 [ - + ]: 1 : if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
396 : : NULL, 0, NULL, &error))
397 : 0 : g_assert_not_reached ();
398 [ - + ]: 1 : g_assert_no_error (error);
399 : :
400 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
401 : : GCR_CERTIFICATE_CHAIN_INCOMPLETE);
402 : :
403 : 1 : g_object_unref (chain);
404 : 1 : }
405 : :
406 : : static void
407 : 1 : test_empty (Test *test, gconstpointer unused)
408 : : {
409 : : GcrCertificateChain *chain;
410 : 1 : GError *error = NULL;
411 : :
412 : 1 : chain = gcr_certificate_chain_new ();
413 : :
414 : : /* Add no certificate */
415 : :
416 [ - + ]: 1 : if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
417 : : NULL, 0, NULL, &error))
418 : 0 : g_assert_not_reached ();
419 [ - + ]: 1 : g_assert_no_error (error);
420 : :
421 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
422 : : GCR_CERTIFICATE_CHAIN_UNKNOWN);
423 : :
424 : 1 : g_object_unref (chain);
425 : 1 : }
426 : :
427 : : static void
428 : 1 : test_trim_extras (Test *test, gconstpointer unused)
429 : : {
430 : : GcrCertificateChain *chain;
431 : 1 : GError *error = NULL;
432 : :
433 : 1 : chain = gcr_certificate_chain_new ();
434 : :
435 : : /* Add two unrelated certificates */
436 : 1 : gcr_certificate_chain_add (chain, test->cert_self);
437 : 1 : gcr_certificate_chain_add (chain, test->cert_signed);
438 : :
439 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
440 : :
441 [ - + ]: 1 : if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
442 : : NULL, 0, NULL, &error))
443 : 0 : g_assert_not_reached ();
444 [ - + ]: 1 : g_assert_no_error (error);
445 : :
446 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
447 : : GCR_CERTIFICATE_CHAIN_SELFSIGNED);
448 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
449 : :
450 : 1 : g_object_unref (chain);
451 : 1 : }
452 : :
453 : : static void
454 : 2 : fetch_async_result (GObject *source, GAsyncResult *result, gpointer user_data)
455 : : {
456 : 2 : *((GAsyncResult**)user_data) = result;
457 : 2 : g_object_ref (result);
458 : 2 : egg_test_wait_stop ();
459 : 2 : }
460 : :
461 : : static void
462 : 1 : test_complete_async (Test *test, gconstpointer unused)
463 : : {
464 : : GcrCertificateChain *chain;
465 : 1 : GError *error = NULL;
466 : 1 : GAsyncResult *result = NULL;
467 : :
468 : 1 : chain = gcr_certificate_chain_new ();
469 : :
470 : : /* Add a whole bunch of certificates */
471 : 1 : gcr_certificate_chain_add (chain, test->cert_signed);
472 : 1 : gcr_certificate_chain_add (chain, test->cert_ca);
473 : 1 : gcr_certificate_chain_add (chain, test->cert_self);
474 : :
475 : 1 : gcr_certificate_chain_build_async (chain, GCR_PURPOSE_CLIENT_AUTH,
476 : : NULL, 0, NULL, fetch_async_result, &result);
477 : 1 : egg_test_wait_until (500);
478 [ - + ]: 1 : if (!gcr_certificate_chain_build_finish (chain, result, &error))
479 : 0 : g_assert_not_reached ();
480 [ - + ]: 1 : g_assert_no_error (error);
481 : 1 : g_object_unref (result);
482 : :
483 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
484 : : GCR_CERTIFICATE_CHAIN_SELFSIGNED);
485 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
486 : :
487 : 1 : g_object_unref (chain);
488 : 1 : }
489 : :
490 : : static void
491 : 1 : test_with_anchor (Test *test, gconstpointer unused)
492 : : {
493 : : GcrCertificateChain *chain;
494 : 1 : GError *error = NULL;
495 : :
496 : 1 : chain = gcr_certificate_chain_new ();
497 : :
498 : : /* Two certificates in chain with ca trust anchor */
499 : 1 : gcr_certificate_chain_add (chain, test->cert_signed);
500 : 1 : gcr_certificate_chain_add (chain, test->cert_ca);
501 : 1 : add_anchor_to_module (test->cert_ca, GCR_PURPOSE_CLIENT_AUTH);
502 : :
503 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
504 : :
505 [ - + ]: 1 : if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
506 : : NULL, 0, NULL, &error))
507 : 0 : g_assert_not_reached ();
508 [ - + ]: 1 : g_assert_no_error (error);
509 : :
510 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
511 : : GCR_CERTIFICATE_CHAIN_ANCHORED);
512 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
513 [ - + ]: 1 : g_assert (gcr_certificate_chain_get_anchor (chain) == test->cert_ca);
514 : :
515 : 1 : g_object_unref (chain);
516 : 1 : }
517 : :
518 : : static void
519 : 1 : test_with_anchor_and_lookup_ca (Test *test, gconstpointer unused)
520 : : {
521 : : GcrCertificateChain *chain;
522 : 1 : GError *error = NULL;
523 : :
524 : 1 : chain = gcr_certificate_chain_new ();
525 : :
526 : : /* One signed certificate, with CA in pkcs11, and trust anchor */
527 : 1 : gcr_certificate_chain_add (chain, test->cert_signed);
528 : 1 : add_certificate_to_module (test->cert_ca);
529 : 1 : add_anchor_to_module (test->cert_ca, GCR_PURPOSE_CLIENT_AUTH);
530 : :
531 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
532 : :
533 [ - + ]: 1 : if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
534 : : NULL, 0, NULL, &error))
535 : 0 : g_assert_not_reached ();
536 [ - + ]: 1 : g_assert_no_error (error);
537 : :
538 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
539 : : GCR_CERTIFICATE_CHAIN_ANCHORED);
540 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
541 [ - + ]: 1 : g_assert (gcr_certificate_chain_get_anchor (chain) != NULL);
542 : :
543 : 1 : g_object_unref (chain);
544 : 1 : }
545 : :
546 : : static void
547 : 1 : test_with_pinned (Test *test, gconstpointer unused)
548 : : {
549 : : GcrCertificateChain *chain;
550 : 1 : GError *error = NULL;
551 : :
552 : 1 : chain = gcr_certificate_chain_new ();
553 : :
554 : : /* One certificate, and add CA to pkcs11 */
555 : 1 : gcr_certificate_chain_add (chain, test->cert_signed);
556 : 1 : gcr_certificate_chain_add (chain, test->cert_ca);
557 : 1 : add_pinned_to_module (test->cert_signed, GCR_PURPOSE_CLIENT_AUTH, "pinned.example.com");
558 : :
559 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
560 : :
561 : : /* But we don't allow the lookup to happen */
562 [ - + ]: 1 : if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
563 : : "pinned.example.com", 0, NULL, &error))
564 : 0 : g_assert_not_reached ();
565 [ - + ]: 1 : g_assert_no_error (error);
566 : :
567 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
568 : : GCR_CERTIFICATE_CHAIN_PINNED);
569 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
570 [ - + ]: 1 : g_assert (gcr_certificate_chain_get_anchor (chain) == NULL);
571 : :
572 : 1 : g_object_unref (chain);
573 : 1 : }
574 : :
575 : : static void
576 : 1 : test_without_lookups (Test *test, gconstpointer unused)
577 : : {
578 : : GcrCertificateChain *chain;
579 : 1 : GError *error = NULL;
580 : :
581 : 1 : chain = gcr_certificate_chain_new ();
582 : :
583 : : /* One certificate, and add CA to pkcs11 */
584 : 1 : gcr_certificate_chain_add (chain, test->cert_signed);
585 : 1 : add_certificate_to_module (test->cert_ca);
586 : :
587 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
588 : :
589 : : /* But we don't allow the lookup to happen */
590 [ - + ]: 1 : if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
591 : : NULL, GCR_CERTIFICATE_CHAIN_NO_LOOKUPS,
592 : : NULL, &error))
593 : 0 : g_assert_not_reached ();
594 [ - + ]: 1 : g_assert_no_error (error);
595 : :
596 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
597 : : GCR_CERTIFICATE_CHAIN_INCOMPLETE);
598 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
599 [ - + ]: 1 : g_assert (gcr_certificate_chain_get_anchor (chain) == NULL);
600 : :
601 : 1 : g_object_unref (chain);
602 : 1 : }
603 : :
604 : : static void
605 : 1 : test_with_lookup_error (Test *test, gconstpointer unused)
606 : : {
607 : : GcrCertificateChain *chain;
608 : 1 : GError *error = NULL;
609 : :
610 : : /* Make the lookup fail */
611 : 1 : test->funcs.C_GetAttributeValue = gck_mock_fail_C_GetAttributeValue;
612 : :
613 : 1 : chain = gcr_certificate_chain_new ();
614 : :
615 : : /* Two certificates in chain with ca trust anchor */
616 : 1 : gcr_certificate_chain_add (chain, test->cert_signed);
617 : 1 : add_certificate_to_module (test->cert_ca);
618 : :
619 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
620 : :
621 [ - + ]: 1 : if (gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
622 : : NULL, 0, NULL, &error))
623 : 0 : g_assert_not_reached ();
624 [ + - + - : 1 : g_assert_error (error, GCK_ERROR, CKR_FUNCTION_FAILED);
- + ]
625 : 1 : g_clear_error (&error);
626 : :
627 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
628 : : GCR_CERTIFICATE_CHAIN_UNKNOWN);
629 : :
630 : 1 : g_object_unref (chain);
631 : 1 : }
632 : :
633 : : static void
634 : 1 : test_wrong_order_anchor (Test *test, gconstpointer unused)
635 : : {
636 : : GcrCertificateChain *chain;
637 : 1 : GError *error = NULL;
638 : :
639 : 1 : chain = gcr_certificate_chain_new ();
640 : :
641 : : /* Two certificates in chain with ca trust anchor */
642 : 1 : gcr_certificate_chain_add (chain, test->cert_host);
643 : 1 : gcr_certificate_chain_add (chain, test->cert_root);
644 : 1 : gcr_certificate_chain_add (chain, test->cert_inter);
645 : 1 : add_anchor_to_module (test->cert_root, GCR_PURPOSE_CLIENT_AUTH);
646 : :
647 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 3);
648 : :
649 [ - + ]: 1 : if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
650 : : NULL, 0, NULL, &error))
651 : 0 : g_assert_not_reached ();
652 [ - + ]: 1 : g_assert_no_error (error);
653 : :
654 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
655 : : GCR_CERTIFICATE_CHAIN_ANCHORED);
656 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 3);
657 [ - + ]: 1 : g_assert (gcr_certificate_chain_get_anchor (chain) == test->cert_root);
658 : :
659 : 1 : g_object_unref (chain);
660 : 1 : }
661 : :
662 : : static void
663 : 1 : test_with_anchor_error (Test *test, gconstpointer unused)
664 : : {
665 : : GcrCertificateChain *chain;
666 : 1 : GError *error = NULL;
667 : :
668 : : /* Make the lookup fail */
669 : 1 : test->funcs.C_GetAttributeValue = gck_mock_fail_C_GetAttributeValue;
670 : :
671 : 1 : chain = gcr_certificate_chain_new ();
672 : :
673 : : /* Two certificates in chain with ca trust anchor */
674 : 1 : gcr_certificate_chain_add (chain, test->cert_signed);
675 : 1 : add_certificate_to_module (test->cert_ca);
676 : :
677 [ - + ]: 1 : if (gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
678 : : NULL, 0, NULL, &error))
679 : 0 : g_assert_not_reached ();
680 [ + - + - : 1 : g_assert_error (error, GCK_ERROR, CKR_FUNCTION_FAILED);
- + ]
681 : 1 : g_clear_error (&error);
682 : :
683 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
684 : : GCR_CERTIFICATE_CHAIN_UNKNOWN);
685 : :
686 : 1 : g_object_unref (chain);
687 : 1 : }
688 : :
689 : : static void
690 : 1 : test_with_anchor_error_async (Test *test, gconstpointer unused)
691 : : {
692 : : GcrCertificateChain *chain;
693 : 1 : GError *error = NULL;
694 : : GAsyncResult *result;
695 : :
696 : : /* Make the lookup fail */
697 : 1 : test->funcs.C_GetAttributeValue = gck_mock_fail_C_GetAttributeValue;
698 : :
699 : 1 : chain = gcr_certificate_chain_new ();
700 : :
701 : : /* Two certificates in chain with ca trust anchor */
702 : 1 : gcr_certificate_chain_add (chain, test->cert_signed);
703 : 1 : add_certificate_to_module (test->cert_ca);
704 : :
705 : 1 : gcr_certificate_chain_build_async (chain, GCR_PURPOSE_CLIENT_AUTH,
706 : : NULL, 0, NULL, fetch_async_result, &result);
707 : 1 : egg_test_wait_until (500);
708 [ - + ]: 1 : if (gcr_certificate_chain_build_finish (chain, result, &error))
709 : 0 : g_assert_not_reached ();
710 [ + - + - : 1 : g_assert_error (error, GCK_ERROR, CKR_FUNCTION_FAILED);
- + ]
711 : 1 : g_clear_error (&error);
712 : 1 : g_object_unref (result);
713 : :
714 [ - + ]: 1 : g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
715 : : GCR_CERTIFICATE_CHAIN_UNKNOWN);
716 : :
717 : 1 : g_object_unref (chain);
718 : 1 : }
719 : :
720 : : int
721 : 1 : main (int argc, char **argv)
722 : : {
723 : 1 : g_test_init (&argc, &argv, NULL);
724 : 1 : g_set_prgname ("test-certificate-chain");
725 : :
726 : 1 : g_test_add ("/gcr/certificate-chain/new", Test, NULL, setup, test_new, teardown);
727 : 1 : g_test_add ("/gcr/certificate-chain/new_with_cert", Test, NULL, setup, test_new_with_cert, teardown);
728 : 1 : g_test_add ("/gcr/certificate-chain/selfsigned", Test, NULL, setup, test_selfsigned, teardown);
729 : 1 : g_test_add ("/gcr/certificate-chain/incomplete", Test, NULL, setup, test_incomplete, teardown);
730 : 1 : g_test_add ("/gcr/certificate-chain/empty", Test, NULL, setup, test_empty, teardown);
731 : 1 : g_test_add ("/gcr/certificate-chain/trim_extras", Test, NULL, setup, test_trim_extras, teardown);
732 : 1 : g_test_add ("/gcr/certificate-chain/complete_async", Test, NULL, setup, test_complete_async, teardown);
733 : 1 : g_test_add ("/gcr/certificate-chain/with_anchor", Test, NULL, setup, test_with_anchor, teardown);
734 : 1 : g_test_add ("/gcr/certificate-chain/with_anchor_and_lookup_ca", Test, NULL, setup, test_with_anchor_and_lookup_ca, teardown);
735 : 1 : g_test_add ("/gcr/certificate-chain/with_pinned", Test, NULL, setup, test_with_pinned, teardown);
736 : 1 : g_test_add ("/gcr/certificate-chain/without_lookups", Test, NULL, setup, test_without_lookups, teardown);
737 : 1 : g_test_add ("/gcr/certificate-chain/wrong_order_anchor", Test, NULL, setup, test_wrong_order_anchor, teardown);
738 : 1 : g_test_add ("/gcr/certificate-chain/with_lookup_error", Test, NULL, setup, test_with_lookup_error, teardown);
739 : 1 : g_test_add ("/gcr/certificate-chain/with_anchor_error", Test, NULL, setup, test_with_anchor_error, teardown);
740 : 1 : g_test_add ("/gcr/certificate-chain/with_anchor_error_async", Test, NULL, setup, test_with_anchor_error_async, teardown);
741 : :
742 : 1 : return egg_tests_run_with_loop ();
743 : : }
|