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