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