]> git.0d.be Git - empathy.git/blob - tests/empathy-tls-test.c
Merge remote-tracking branch 'jonny/ft'
[empathy.git] / tests / empathy-tls-test.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 #include <libempathy/empathy-tls-certificate.h>
6 #include <libempathy/empathy-tls-verifier.h>
7 #include "test-helper.h"
8
9 #include <gcr/gcr.h>
10
11 #include <gnutls/gnutls.h>
12
13 #include <telepathy-glib/dbus-properties-mixin.h>
14 #include <telepathy-glib/enums.h>
15 #include <telepathy-glib/interfaces.h>
16 #include <telepathy-glib/svc-tls.h>
17 #include <telepathy-glib/svc-generic.h>
18 #include <telepathy-glib/telepathy-glib.h>
19
20 #define MOCK_TLS_CERTIFICATE_PATH "/mock/certificate"
21
22 /* Forward decl */
23 GType mock_tls_certificate_get_type (void);
24
25 #define MOCK_TLS_CERTIFICATE(obj) \
26   (G_TYPE_CHECK_INSTANCE_CAST((obj), mock_tls_certificate_get_type (), \
27     MockTLSCertificate))
28
29 typedef struct _MockTLSCertificate {
30   GObject parent;
31   guint state;
32   GPtrArray *rejections;
33   gchar *cert_type;
34   GPtrArray *cert_data;
35 } MockTLSCertificate;
36
37 typedef struct _MockTLSCertificateClass {
38   GObjectClass parent;
39   TpDBusPropertiesMixinClass dbus_props_class;
40 } MockTLSCertificateClass;
41
42 enum {
43   PROP_0,
44   PROP_STATE,
45   PROP_REJECTIONS,
46   PROP_CERTIFICATE_TYPE,
47   PROP_CERTIFICATE_CHAIN_DATA
48 };
49
50 static void mock_tls_certificate_iface_init (gpointer, gpointer);
51
52 G_DEFINE_TYPE_WITH_CODE(MockTLSCertificate, mock_tls_certificate, G_TYPE_OBJECT,
53         G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_AUTHENTICATION_TLS_CERTIFICATE,
54                 mock_tls_certificate_iface_init)
55         G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
56                 tp_dbus_properties_mixin_iface_init)
57 )
58
59 static void
60 mock_tls_certificate_init (MockTLSCertificate *self)
61 {
62   self->state = TP_TLS_CERTIFICATE_STATE_PENDING;
63   self->cert_type = g_strdup ("x509");
64   self->cert_data = g_ptr_array_new_with_free_func((GDestroyNotify) g_array_unref);
65   self->rejections = g_ptr_array_new ();
66 }
67
68 static void
69 mock_tls_certificate_get_property (GObject *object,
70         guint property_id,
71         GValue *value,
72         GParamSpec *pspec)
73 {
74   MockTLSCertificate *self = MOCK_TLS_CERTIFICATE (object);
75
76   switch (property_id)
77     {
78     case PROP_STATE:
79       g_value_set_uint (value, self->state);
80       break;
81     case PROP_REJECTIONS:
82       g_value_set_boxed (value, self->rejections);
83       break;
84     case PROP_CERTIFICATE_TYPE:
85       g_value_set_string (value, self->cert_type);
86       break;
87     case PROP_CERTIFICATE_CHAIN_DATA:
88       g_value_set_boxed (value, self->cert_data);
89       break;
90     default:
91       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
92       break;
93   }
94 }
95
96 static void
97 mock_tls_certificate_finalize (GObject *object)
98 {
99   MockTLSCertificate *self = MOCK_TLS_CERTIFICATE (object);
100
101   tp_clear_boxed (TP_ARRAY_TYPE_TLS_CERTIFICATE_REJECTION_LIST,
102       &self->rejections);
103   g_free (self->cert_type);
104   self->cert_type = NULL;
105   g_ptr_array_unref (self->cert_data);
106   self->cert_data = NULL;
107
108   G_OBJECT_CLASS (mock_tls_certificate_parent_class)->finalize (object);
109 }
110
111 static void
112 mock_tls_certificate_class_init (MockTLSCertificateClass *klass)
113 {
114   GObjectClass *oclass = G_OBJECT_CLASS (klass);
115   GParamSpec *pspec;
116
117   static TpDBusPropertiesMixinPropImpl object_props[] = {
118           { "State", "state", NULL },
119           { "Rejections", "rejections", NULL },
120           { "CertificateType", "certificate-type", NULL },
121           { "CertificateChainData", "certificate-chain-data", NULL },
122           { NULL }
123   };
124
125   static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
126     { TP_IFACE_AUTHENTICATION_TLS_CERTIFICATE,
127       tp_dbus_properties_mixin_getter_gobject_properties,
128       NULL,
129       object_props,
130     },
131     { NULL }
132   };
133
134   oclass->get_property = mock_tls_certificate_get_property;
135   oclass->finalize = mock_tls_certificate_finalize;
136
137   pspec = g_param_spec_uint ("state",
138       "State of this certificate",
139       "The state of this TLS certificate.",
140       0, NUM_TP_TLS_CERTIFICATE_STATES - 1,
141       TP_TLS_CERTIFICATE_STATE_PENDING,
142       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
143   g_object_class_install_property (oclass, PROP_STATE, pspec);
144
145   pspec = g_param_spec_boxed ("rejections",
146       "The reject reasons",
147       "The reasons why this TLS certificate has been rejected",
148       TP_ARRAY_TYPE_TLS_CERTIFICATE_REJECTION_LIST,
149       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
150   g_object_class_install_property (oclass, PROP_REJECTIONS, pspec);
151
152   pspec = g_param_spec_string ("certificate-type",
153       "The certificate type",
154       "The type of this certificate.",
155       NULL,
156       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
157   g_object_class_install_property (oclass, PROP_CERTIFICATE_TYPE, pspec);
158
159   pspec = g_param_spec_boxed ("certificate-chain-data",
160       "The certificate chain data",
161       "The raw PEM-encoded trust chain of this certificate.",
162       TP_ARRAY_TYPE_UCHAR_ARRAY_LIST,
163       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
164   g_object_class_install_property (oclass, PROP_CERTIFICATE_CHAIN_DATA, pspec);
165
166   klass->dbus_props_class.interfaces = prop_interfaces;
167   tp_dbus_properties_mixin_class_init (oclass,
168       G_STRUCT_OFFSET (MockTLSCertificateClass, dbus_props_class));
169 }
170
171 static void
172 mock_tls_certificate_accept (TpSvcAuthenticationTLSCertificate *base,
173         DBusGMethodInvocation *context)
174 {
175   MockTLSCertificate *self = MOCK_TLS_CERTIFICATE (base);
176   self->state = TP_TLS_CERTIFICATE_STATE_ACCEPTED;
177   tp_svc_authentication_tls_certificate_emit_accepted (self);
178   tp_svc_authentication_tls_certificate_return_from_accept (context);
179 }
180
181 static void
182 mock_tls_certificate_reject (TpSvcAuthenticationTLSCertificate *base,
183         const GPtrArray *in_Rejections,
184         DBusGMethodInvocation *context)
185 {
186   MockTLSCertificate *self = MOCK_TLS_CERTIFICATE (base);
187   self->state = TP_TLS_CERTIFICATE_STATE_REJECTED;
188   tp_svc_authentication_tls_certificate_emit_rejected (self, in_Rejections);
189   tp_svc_authentication_tls_certificate_return_from_reject (context);
190 }
191
192 static void
193 mock_tls_certificate_iface_init (gpointer g_iface,
194         gpointer iface_data)
195 {
196   TpSvcAuthenticationTLSCertificateClass *klass =
197     (TpSvcAuthenticationTLSCertificateClass*)g_iface;
198
199   tp_svc_authentication_tls_certificate_implement_accept (klass,
200       mock_tls_certificate_accept);
201   tp_svc_authentication_tls_certificate_implement_reject (klass,
202       mock_tls_certificate_reject);
203 }
204
205 #if 0
206 static void
207 mock_tls_certificate_assert_rejected (MockTLSCertificate *self,
208         EmpTLSCertificateRejectReason reason)
209 {
210   GValueArray *rejection;
211   EmpTLSCertificateRejectReason rejection_reason;
212   gchar *rejection_error;
213   GHashTable *rejection_details;
214   guint i;
215
216   g_assert (self->state == TP_TLS_CERTIFICATE_STATE_REJECTED);
217   g_assert (self->rejections);
218   g_assert (self->rejections->len > 0);
219
220   for (i = 0; i < self->rejections->len; ++i)
221     {
222       rejection = g_ptr_array_index (self->rejections, i);
223       tp_value_array_unpack (rejection, 3,
224               G_TYPE_UINT, &rejection_reason,
225               G_TYPE_STRING, &rejection_error,
226               TP_HASH_TYPE_STRING_VARIANT_MAP, &rejection_details,
227               NULL);
228       g_free (rejection_error);
229       g_hash_table_unref (rejection_details);
230
231       if (rejection_reason == reason)
232         return;
233     }
234
235   g_assert ("Certificate was not rejected for right reason" && 0);
236 }
237 #endif
238
239 static MockTLSCertificate*
240 mock_tls_certificate_new_and_register (TpDBusDaemon *dbus,
241         const gchar *path,
242         ...)
243 {
244   MockTLSCertificate *cert;
245   GError *error = NULL;
246   gchar *filename, *contents;
247   GArray *der;
248   gsize length;
249   va_list va;
250
251   cert = g_object_new (mock_tls_certificate_get_type (), NULL);
252
253   va_start (va, path);
254   while (path != NULL) {
255       filename = g_build_filename (g_getenv ("EMPATHY_SRCDIR"),
256               "tests", "certificates", path, NULL);
257       g_file_get_contents (filename, &contents, &length, &error);
258       g_assert_no_error (error);
259
260       der = g_array_sized_new (TRUE, TRUE, sizeof (guchar), length);
261       g_array_append_vals (der, contents, length);
262       g_ptr_array_add (cert->cert_data, der);
263
264       g_free (contents);
265       g_free (filename);
266
267       path = va_arg (va, gchar*);
268   }
269   va_end (va);
270
271   tp_dbus_daemon_register_object (dbus, MOCK_TLS_CERTIFICATE_PATH, cert);
272   return cert;
273 }
274
275 /* ----------------------------------------------------------------------------
276  * TESTS
277  */
278
279 typedef struct {
280   GMainLoop *loop;
281   TpDBusDaemon *dbus;
282   const gchar *dbus_name;
283   MockTLSCertificate *mock;
284   EmpathyTLSCertificate *cert;
285   GAsyncResult *result;
286 } Test;
287
288 static void
289 setup (Test *test, gconstpointer data)
290 {
291   GError *error = NULL;
292   test->loop = g_main_loop_new (NULL, FALSE);
293
294   test->dbus = tp_dbus_daemon_dup (&error);
295   g_assert_no_error (error);
296
297   test->dbus_name = tp_dbus_daemon_get_unique_name (test->dbus);
298
299   test->result = NULL;
300   test->cert = NULL;
301
302   /* No PKCS#11 modules by default, tests add them */
303   gcr_pkcs11_set_modules (NULL);
304 }
305
306 static void
307 teardown (Test *test, gconstpointer data)
308 {
309   test->dbus_name = NULL;
310
311   if (test->mock)
312     {
313       tp_dbus_daemon_unregister_object (test->dbus, test->mock);
314       g_object_unref (test->mock);
315       test->mock = NULL;
316     }
317
318   if (test->result)
319     g_object_unref (test->result);
320   test->result = NULL;
321
322   if (test->cert)
323     g_object_unref (test->cert);
324   test->cert = NULL;
325
326   g_main_loop_unref (test->loop);
327   test->loop = NULL;
328
329   g_object_unref (test->dbus);
330   test->dbus = NULL;
331 }
332
333 static void
334 add_pkcs11_module_for_testing (Test *test,
335         const gchar *filename,
336         const gchar *subdir)
337 {
338   GError *error = NULL;
339   gchar *args, *path, *directory;
340   gchar *standalone, *error_output;
341   gint exit_status;
342
343   directory = g_build_filename (g_getenv ("EMPATHY_SRCDIR"),
344           "tests", "certificates", subdir, NULL);
345
346   /*
347    * Lookup the directory for standalone pkcs11 modules installed by
348    * gnome-keyring. We use these for testing our implementation.
349    */
350   g_spawn_command_line_sync ("pkg-config --variable=pkcs11standalonedir gcr-3",
351           &standalone, &error_output, &exit_status, &error);
352   g_assert_no_error (error);
353   if (exit_status != 0)
354     {
355       g_warning ("couldn't determine standalone pkcs11 module directory: %d: %s",
356               exit_status, error_output);
357       g_assert_not_reached ();
358     }
359
360   g_strstrip (standalone);
361   args = g_strdup_printf ("directory=\"%s\"", directory);
362   path = g_build_filename (standalone, filename, NULL);
363   gcr_pkcs11_add_module_from_file (path, args, &error);
364   g_assert_no_error (error);
365
366   g_free (directory);
367   g_free (standalone);
368   g_free (error_output);
369   g_free (args);
370   g_free (path);
371 }
372
373 static void
374 fetch_callback_result (GObject *object,
375         GAsyncResult *res,
376         gpointer user_data)
377 {
378   Test *test = user_data;
379   g_assert (!test->result);
380   test->result = g_object_ref (res);
381   g_main_loop_quit (test->loop);
382 }
383
384 static void
385 ensure_certificate_proxy (Test *test)
386 {
387   GError *error = NULL;
388
389   if (test->cert)
390     return;
391
392   /* Create and prepare a certificate */
393   test->cert = empathy_tls_certificate_new (test->dbus, test->dbus_name,
394           MOCK_TLS_CERTIFICATE_PATH, &error);
395   g_assert_no_error (error);
396   empathy_tls_certificate_prepare_async (test->cert, fetch_callback_result, test);
397   g_main_loop_run (test->loop);
398   empathy_tls_certificate_prepare_finish (test->cert, test->result, &error);
399   g_assert_no_error (error);
400
401   /* Clear for any future async stuff */
402   g_object_unref (test->result);
403   test->result = NULL;
404 }
405
406 /* A simple test to make sure the test infrastructure is working */
407 static void
408 test_certificate_mock_basics (Test *test,
409         gconstpointer data G_GNUC_UNUSED)
410 {
411   GError *error = NULL;
412
413   test->mock = mock_tls_certificate_new_and_register (test->dbus,
414           "dhansak-collabora.cer", NULL);
415
416   ensure_certificate_proxy (test);
417
418   empathy_tls_certificate_accept_async (test->cert, fetch_callback_result, test);
419   g_main_loop_run (test->loop);
420   empathy_tls_certificate_accept_finish (test->cert, test->result, &error);
421   g_assert_no_error (error);
422
423   g_assert (test->mock->state == TP_TLS_CERTIFICATE_STATE_ACCEPTED);
424 }
425
426 static void
427 test_certificate_verify_success_with_pkcs11_lookup (Test *test,
428         gconstpointer data G_GNUC_UNUSED)
429 {
430   EmpTLSCertificateRejectReason reason = 0;
431   GError *error = NULL;
432   EmpathyTLSVerifier *verifier;
433   const gchar *reference_identities[] = {
434     "www.collabora.co.uk",
435     NULL
436   };
437
438   /*
439    * In this test the mock TLS connection only has one certificate
440    * not a full certificat echain. The root anchor certificate is
441    * retrieved from PKCS#11 storage.
442    */
443
444   test->mock = mock_tls_certificate_new_and_register (test->dbus,
445           "dhansak-collabora.cer", NULL);
446
447   /* We add the collabora directory with the collabora root */
448   add_pkcs11_module_for_testing (test, "gkm-roots-store-standalone.so",
449           "collabora-ca");
450
451   ensure_certificate_proxy (test);
452
453   verifier = empathy_tls_verifier_new (test->cert, "www.collabora.co.uk",
454       reference_identities);
455   empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test);
456   g_main_loop_run (test->loop);
457   if (!empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
458           NULL, &error))
459     g_assert_not_reached ();
460
461   /* Yay the verification was a success! */
462
463   g_clear_error (&error);
464   g_object_unref (verifier);
465 }
466
467 static void
468 test_certificate_verify_success_with_full_chain (Test *test,
469         gconstpointer data G_GNUC_UNUSED)
470 {
471   EmpTLSCertificateRejectReason reason = 0;
472   GError *error = NULL;
473   EmpathyTLSVerifier *verifier;
474   const gchar *reference_identities[] = {
475     "www.collabora.co.uk",
476     NULL
477   };
478
479   /*
480    * In this test the mock TLS connection has a full certificate
481    * chain. We look for an anchor certificate in the chain.
482    */
483
484   test->mock = mock_tls_certificate_new_and_register (test->dbus,
485           "dhansak-collabora.cer", "collabora-ca/collabora-ca.cer", NULL);
486
487   /* We add the collabora directory with the collabora root */
488   add_pkcs11_module_for_testing (test, "gkm-roots-store-standalone.so",
489           "collabora-ca");
490
491   ensure_certificate_proxy (test);
492
493   verifier = empathy_tls_verifier_new (test->cert, "www.collabora.co.uk",
494       reference_identities);
495   empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test);
496   g_main_loop_run (test->loop);
497   if (!empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
498           NULL, &error))
499     g_assert_not_reached ();
500
501   /* Yay the verification was a success! */
502
503   g_clear_error (&error);
504   g_object_unref (verifier);
505 }
506
507 static void
508 test_certificate_verify_root_not_found (Test *test,
509         gconstpointer data G_GNUC_UNUSED)
510 {
511   EmpTLSCertificateRejectReason reason = 0;
512   GError *error = NULL;
513   EmpathyTLSVerifier *verifier;
514   const gchar *reference_identities[] = {
515     "www.collabora.co.uk",
516     NULL
517   };
518
519   test->mock = mock_tls_certificate_new_and_register (test->dbus,
520           "dhansak-collabora.cer", NULL);
521
522   /* Note that we're not adding any place to find root certs */
523
524   ensure_certificate_proxy (test);
525
526   verifier = empathy_tls_verifier_new (test->cert, "www.collabora.co.uk",
527       reference_identities);
528   empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test);
529   g_main_loop_run (test->loop);
530
531   if (empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
532           NULL, &error))
533     g_assert_not_reached ();
534
535   /* And it should say we're self-signed (oddly enough) */
536   g_assert_cmpuint (reason, ==, EMP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED);
537
538   g_clear_error (&error);
539   g_object_unref (verifier);
540 }
541
542 static void
543 test_certificate_verify_root_not_anchored (Test *test,
544         gconstpointer data G_GNUC_UNUSED)
545 {
546   EmpTLSCertificateRejectReason reason = 0;
547   GError *error = NULL;
548   EmpathyTLSVerifier *verifier;
549   const gchar *reference_identities[] = {
550     "www.collabora.co.uk",
551     NULL
552   };
553
554   test->mock = mock_tls_certificate_new_and_register (test->dbus,
555           "dhansak-collabora.cer", "collabora-ca/collabora-ca.cer", NULL);
556
557   /* Note that we're not adding any place to find root certs */
558
559   ensure_certificate_proxy (test);
560
561   verifier = empathy_tls_verifier_new (test->cert, "www.collabora.co.uk",
562       reference_identities);
563   empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test);
564   g_main_loop_run (test->loop);
565
566   if (empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
567           NULL, &error))
568     g_assert_not_reached ();
569
570   /* And it should say we're self-signed (oddly enough) */
571   g_assert_cmpuint (reason, ==, EMP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED);
572
573   g_clear_error (&error);
574   g_object_unref (verifier);
575 }
576
577 static void
578 test_certificate_verify_identities_invalid (Test *test,
579         gconstpointer data G_GNUC_UNUSED)
580 {
581   EmpTLSCertificateRejectReason reason = 0;
582   GError *error = NULL;
583   EmpathyTLSVerifier *verifier;
584   const gchar *reference_identities[] = {
585     "invalid.host.name",
586     NULL
587   };
588
589   test->mock = mock_tls_certificate_new_and_register (test->dbus,
590           "dhansak-collabora.cer", "collabora-ca/collabora-ca.cer", NULL);
591
592   /* We add the collabora directory with the collabora root */
593   add_pkcs11_module_for_testing (test, "gkm-roots-store-standalone.so",
594           "collabora-ca");
595
596   ensure_certificate_proxy (test);
597
598   verifier = empathy_tls_verifier_new (test->cert, "invalid.host.name",
599       reference_identities);
600   empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test);
601   g_main_loop_run (test->loop);
602
603   if (empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
604           NULL, &error))
605     g_assert_not_reached ();
606
607   /* And it should say we're self-signed (oddly enough) */
608   g_assert_cmpuint (reason, ==, EMP_TLS_CERTIFICATE_REJECT_REASON_HOSTNAME_MISMATCH);
609
610   g_clear_error (&error);
611   g_object_unref (verifier);
612 }
613
614 static void
615 test_certificate_verify_uses_reference_identities (Test *test,
616         gconstpointer data G_GNUC_UNUSED)
617 {
618   EmpTLSCertificateRejectReason reason = 0;
619   GError *error = NULL;
620   EmpathyTLSVerifier *verifier;
621   const gchar *reference_identities[] = {
622     "invalid.host.name",
623     NULL
624   };
625
626   test->mock = mock_tls_certificate_new_and_register (test->dbus,
627           "dhansak-collabora.cer", "collabora-ca/collabora-ca.cer", NULL);
628
629   /* We add the collabora directory with the collabora root */
630   add_pkcs11_module_for_testing (test, "gkm-roots-store-standalone.so",
631           "collabora-ca");
632
633   ensure_certificate_proxy (test);
634
635   /* Should be using the reference_identities and not host name for checks */
636   verifier = empathy_tls_verifier_new (test->cert, "www.collabora.co.uk",
637       reference_identities);
638   empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test);
639   g_main_loop_run (test->loop);
640
641   if (empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
642           NULL, &error))
643     g_assert_not_reached ();
644
645   /* And it should say we're self-signed (oddly enough) */
646   g_assert_cmpuint (reason, ==, EMP_TLS_CERTIFICATE_REJECT_REASON_HOSTNAME_MISMATCH);
647
648   g_clear_error (&error);
649   g_object_unref (verifier);
650 }
651
652 int
653 main (int argc,
654     char **argv)
655 {
656   int result;
657
658   test_init (argc, argv);
659   gnutls_global_init ();
660
661   g_test_add ("/tls/certificate_basics", Test, NULL,
662           setup, test_certificate_mock_basics, teardown);
663   g_test_add ("/tls/certificate_verify_success_with_pkcs11_lookup", Test, NULL,
664           setup, test_certificate_verify_success_with_pkcs11_lookup, teardown);
665   g_test_add ("/tls/certificate_verify_success_with_full_chain", Test, NULL,
666           setup, test_certificate_verify_success_with_full_chain, teardown);
667   g_test_add ("/tls/certificate_verify_root_not_found", Test, NULL,
668           setup, test_certificate_verify_root_not_found, teardown);
669   g_test_add ("/tls/certificate_verify_root_not_anchored", Test, NULL,
670           setup, test_certificate_verify_root_not_anchored, teardown);
671   g_test_add ("/tls/certificate_verify_identities_invalid", Test, NULL,
672           setup, test_certificate_verify_identities_invalid, teardown);
673   g_test_add ("/tls/certificate_verify_uses_reference_identities", Test, NULL,
674           setup, test_certificate_verify_uses_reference_identities, teardown);
675
676   result = g_test_run ();
677   test_deinit ();
678   return result;
679 }