2 * @file telepathy-tls.c
6 * Copyright (C) 2013-2018 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * TLS certificate accept/reject user interaction
31 #include <glib-object.h>
32 #include <telepathy-glib/dbus-properties-mixin.h>
33 #include <telepathy-glib/svc-channel.h>
34 #include <telepathy-glib/svc-tls.h>
35 #include <telepathy-glib/telepathy-glib.h>
37 #include "sipe-backend.h"
38 #include "sipe-common.h"
40 #include "telepathy-private.h"
42 /* TLS information required for user interaction */
43 struct _SipeTLSCertificate
;
44 struct sipe_tls_info
{
48 GStrv reference_identities
;
49 struct _SipeTLSCertificate
*certificate
;
52 /* Certificate states */
53 #define SIPE_TLS_CERTIFICATE_PENDING 0
54 #define SIPE_TLS_CERTIFICATE_REJECTED 1
55 #define SIPE_TLS_CERTIFICATE_ACCEPTED 2
59 * TLS Manager class - data structures
61 typedef struct _SipeTLSManagerClass
{
62 GObjectClass parent_class
;
63 } SipeTLSManagerClass
;
65 typedef struct _SipeTLSManager
{
74 * TLS Manager class - type macros
76 static GType
sipe_tls_manager_get_type(void);
77 #define SIPE_TYPE_TLS_MANAGER \
78 (sipe_tls_manager_get_type())
79 #define SIPE_TLS_MANAGER(obj) \
80 (G_TYPE_CHECK_INSTANCE_CAST((obj), SIPE_TYPE_TLS_MANAGER, \
84 * TLS Channel class - data structures
86 typedef struct _SipeTLSChannelClass
{
87 TpBaseChannelClass parent_class
;
88 } SipeTLSChannelClass
;
90 typedef struct _SipeTLSChannel
{
93 const struct sipe_tls_info
*tls_info
;
95 GSimpleAsyncResult
*result
;
99 * TLS Channel class - type macros
101 static GType
sipe_tls_channel_get_type(void) G_GNUC_CONST
;
102 #define SIPE_TYPE_TLS_CHANNEL \
103 (sipe_tls_channel_get_type())
104 #define SIPE_TLS_CHANNEL(obj) \
105 (G_TYPE_CHECK_INSTANCE_CAST((obj), SIPE_TYPE_TLS_CHANNEL, \
109 * TLS Certificate class - data structures
111 typedef struct _SipeTLSCertificateClass
{
112 GObjectClass parent_class
;
114 TpDBusPropertiesMixinClass dbus_props_class
;
115 } SipeTLSCertificateClass
;
117 typedef struct _SipeTLSCertificate
{
120 const struct sipe_tls_info
*tls_info
;
123 } SipeTLSCertificate
;
126 * TLS Certificate class - type macros
128 static GType
sipe_tls_certificate_get_type(void) G_GNUC_CONST
;
129 #define SIPE_TYPE_TLS_CERTIFICATE \
130 (sipe_tls_certificate_get_type())
131 #define SIPE_TLS_CERTIFICATE(obj) \
132 (G_TYPE_CHECK_INSTANCE_CAST((obj), SIPE_TYPE_TLS_CERTIFICATE, \
137 * TLS Manager class - type definition
139 static void channel_manager_iface_init(gpointer
, gpointer
);
140 G_DEFINE_TYPE_WITH_CODE(SipeTLSManager
,
143 G_IMPLEMENT_INTERFACE(TP_TYPE_CHANNEL_MANAGER
,
144 channel_manager_iface_init
);
148 * TLS Channel class - type definition
150 G_DEFINE_TYPE_WITH_CODE(SipeTLSChannel
,
152 TP_TYPE_BASE_CHANNEL
,
153 G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CHANNEL_TYPE_SERVER_TLS_CONNECTION
,
158 * TLS Certificate class - type definition
160 static void tls_certificate_iface_init(gpointer
, gpointer
);
161 G_DEFINE_TYPE_WITH_CODE (SipeTLSCertificate
,
162 sipe_tls_certificate
,
164 G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_AUTHENTICATION_TLS_CERTIFICATE
,
165 tls_certificate_iface_init
);
166 G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_DBUS_PROPERTIES
,
167 tp_dbus_properties_mixin_iface_init
);
171 * TLS Manager class - instance methods
173 static void sipe_tls_manager_constructed(GObject
*object
)
175 SipeTLSManager
*self
= SIPE_TLS_MANAGER(object
);
176 void (*chain_up
)(GObject
*) = G_OBJECT_CLASS(sipe_tls_manager_parent_class
)->constructed
;
181 self
->channels
= NULL
;
184 static void sipe_tls_manager_dispose(GObject
*object
)
186 SipeTLSManager
*self
= SIPE_TLS_MANAGER(object
);
187 void (*chain_up
)(GObject
*) = G_OBJECT_CLASS(sipe_tls_manager_parent_class
)->constructed
;
189 tp_clear_object(&self
->connection
);
195 static void sipe_tls_manager_finalize(GObject
*object
)
197 SipeTLSManager
*self
= SIPE_TLS_MANAGER(object
);
198 void (*chain_up
)(GObject
*) = G_OBJECT_CLASS(sipe_tls_manager_parent_class
)->constructed
;
199 GSList
*entry
= self
->channels
;
203 GSList
*next
= entry
->next
;
204 /* removes entry from list */
205 tp_base_channel_close(entry
->data
);
209 tp_clear_object(&self
->connection
);
217 * TLS Manager class - type implementation
219 static void sipe_tls_manager_class_init(SipeTLSManagerClass
*klass
)
221 GObjectClass
*object_class
= G_OBJECT_CLASS(klass
);
223 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSManager::class_init");
225 object_class
->constructed
= sipe_tls_manager_constructed
;
226 object_class
->dispose
= sipe_tls_manager_dispose
;
227 object_class
->finalize
= sipe_tls_manager_finalize
;
230 static void sipe_tls_manager_init(SIPE_UNUSED_PARAMETER SipeTLSManager
*self
)
232 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSManager::init");
236 * TLS Manager class - interface implementation
240 static void foreach_channel(TpChannelManager
*manager
,
241 TpExportableChannelFunc func
,
244 SipeTLSManager
*self
= SIPE_TLS_MANAGER(manager
);
247 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSManager::foreach_channel");
249 for (entry
= self
->channels
; entry
; entry
= entry
->next
)
250 func(entry
->data
, user_data
);
253 static void channel_manager_iface_init(gpointer g_iface
,
254 SIPE_UNUSED_PARAMETER gpointer iface_data
)
256 TpChannelManagerIface
*iface
= g_iface
;
258 #define IMPLEMENT(x, y) iface->x = y
259 IMPLEMENT(foreach_channel
, foreach_channel
);
260 /* These channels are not requestable. */
261 IMPLEMENT(type_foreach_channel_class
, NULL
);
262 IMPLEMENT(create_channel
, NULL
);
263 IMPLEMENT(request_channel
, NULL
);
264 IMPLEMENT(ensure_channel
, NULL
);
268 /* create new TLS manager object */
269 SipeTLSManager
*sipe_telepathy_tls_new(TpBaseConnection
*connection
)
271 SipeTLSManager
*self
= g_object_new(SIPE_TYPE_TLS_MANAGER
, NULL
);
272 self
->connection
= g_object_ref(G_OBJECT(connection
));
276 static void channel_closed_cb(SipeTLSChannel
*channel
,
277 SipeTLSManager
*self
)
279 SIPE_DEBUG_INFO("channel_closed_cb: %p", channel
);
281 self
->channels
= g_slist_remove(self
->channels
, channel
);
282 tp_channel_manager_emit_channel_closed_for_object(self
,
283 TP_EXPORTABLE_CHANNEL(channel
));
284 g_object_unref(channel
);
287 static void manager_new_channel(SipeTLSManager
*self
,
288 SipeTLSChannel
*channel
)
290 self
->channels
= g_slist_prepend(self
->channels
,
291 g_object_ref(channel
));
293 g_signal_connect(channel
,
295 G_CALLBACK(channel_closed_cb
),
298 /* emit NewChannel on the ChannelManager iface */
299 tp_channel_manager_emit_new_channel(self
,
300 TP_EXPORTABLE_CHANNEL(channel
),
305 * TLS Channel class - instance methods
308 CHANNEL_PROP_SERVER_CERTIFICATE
= 1,
309 CHANNEL_PROP_HOSTNAME
,
310 CHANNEL_PROP_REFERENCE_IDENTITIES
,
314 static void channel_get_property(GObject
*object
,
319 SipeTLSChannel
*self
= SIPE_TLS_CHANNEL(object
);
321 switch (property_id
) {
322 case CHANNEL_PROP_SERVER_CERTIFICATE
:
323 g_value_set_boxed(value
, self
->tls_info
->cert_path
);
325 case CHANNEL_PROP_HOSTNAME
:
326 g_value_set_string(value
, self
->tls_info
->hostname
);
328 case CHANNEL_PROP_REFERENCE_IDENTITIES
:
329 g_value_set_boxed(value
, self
->tls_info
->reference_identities
);
332 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, property_id
, pspec
);
337 static void channel_fill_immutable_properties(TpBaseChannel
*channel
,
338 GHashTable
*properties
)
340 TP_BASE_CHANNEL_CLASS(sipe_tls_channel_parent_class
)->fill_immutable_properties(channel
,
342 tp_dbus_properties_mixin_fill_properties_hash(G_OBJECT(channel
),
344 TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION
, "ServerCertificate",
345 TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION
, "Hostname",
346 TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION
, "ReferenceIdentities",
350 static gchar
*channel_get_object_path_suffix(TpBaseChannel
*base
)
352 return(g_strdup_printf("TLSChannel_%p", base
));
355 static void sipe_tls_channel_constructed(GObject
*object
)
357 void (*chain_up
)(GObject
*) = G_OBJECT_CLASS(sipe_tls_channel_parent_class
)->constructed
;
363 static void sipe_tls_channel_finalize(GObject
*object
)
365 SipeTLSChannel
*self
= SIPE_TLS_CHANNEL(object
);
367 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSChannel::finalize");
370 g_simple_async_result_set_error(self
->result
,
373 "The TLS channel is being destroyed");
374 g_simple_async_result_complete_in_idle(self
->result
);
375 g_clear_object(&self
->result
);
378 G_OBJECT_CLASS(sipe_tls_channel_parent_class
)->finalize(object
);
382 * TLS Channel class - type implementation
384 static void sipe_tls_channel_class_init(SipeTLSChannelClass
*klass
)
386 static TpDBusPropertiesMixinPropImpl props
[] = {
388 .name
= "ServerCertificate",
389 .getter_data
= "server-certificate",
394 .getter_data
= "hostname",
398 .name
= "ReferenceIdentities",
399 .getter_data
= "reference-identities",
406 GObjectClass
*object_class
= G_OBJECT_CLASS(klass
);
407 TpBaseChannelClass
*base_class
= TP_BASE_CHANNEL_CLASS(klass
);
410 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSChannel::class_init");
412 object_class
->constructed
= sipe_tls_channel_constructed
;
413 object_class
->finalize
= sipe_tls_channel_finalize
;
414 object_class
->get_property
= channel_get_property
;
416 base_class
->channel_type
= TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION
;
417 base_class
->target_handle_type
= TP_HANDLE_TYPE_NONE
;
418 base_class
->fill_immutable_properties
= channel_fill_immutable_properties
;
419 base_class
->get_object_path_suffix
= channel_get_object_path_suffix
;
420 base_class
->interfaces
= NULL
;
421 base_class
->close
= tp_base_channel_destroyed
;
423 ps
= g_param_spec_boxed("server-certificate",
424 "Server certificate path",
425 "The object path of the server certificate.",
426 DBUS_TYPE_G_OBJECT_PATH
,
427 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
428 g_object_class_install_property(object_class
,
429 CHANNEL_PROP_SERVER_CERTIFICATE
,
432 ps
= g_param_spec_string("hostname",
433 "The hostname to be verified",
434 "The hostname which should be certified by the server certificate.",
436 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
437 g_object_class_install_property(object_class
,
438 CHANNEL_PROP_HOSTNAME
,
441 ps
= g_param_spec_boxed("reference-identities",
442 "The various identities to check the certificate against",
443 "The server certificate identity should match one of these identities.",
445 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
446 g_object_class_install_property(object_class
,
447 CHANNEL_PROP_REFERENCE_IDENTITIES
,
450 tp_dbus_properties_mixin_implement_interface(object_class
,
451 TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_TLS_CONNECTION
,
452 tp_dbus_properties_mixin_getter_gobject_properties
,
457 static void sipe_tls_channel_init(SIPE_UNUSED_PARAMETER SipeTLSChannel
*self
)
459 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSChannel::init");
462 static void certificate_accepted_cb(SIPE_UNUSED_PARAMETER SipeTLSCertificate
*certificate
,
463 SipeTLSChannel
*self
)
465 g_simple_async_result_complete(self
->result
);
466 g_clear_object(&self
->result
);
467 tp_base_channel_close(TP_BASE_CHANNEL(self
));
470 static void certificate_rejected_cb(SIPE_UNUSED_PARAMETER SipeTLSCertificate
*certificate
,
471 SIPE_UNUSED_PARAMETER GPtrArray
*rejections
,
472 SipeTLSChannel
*self
)
474 static GQuark quark
= 0;
477 quark
= g_quark_from_static_string("server-tls-error");
479 g_simple_async_result_set_error(self
->result
,
482 "TLS certificate rejected");
483 g_simple_async_result_complete(self
->result
);
484 g_clear_object(&self
->result
);
485 tp_base_channel_close(TP_BASE_CHANNEL(self
));
488 static void channel_new_certificate(GObject
*connection
,
489 struct sipe_tls_info
*tls_info
,
490 SipeTLSChannel
*self
,
491 GAsyncReadyCallback callback
,
494 struct sipe_backend_private
*telepathy_private
= sipe_telepathy_connection_private(connection
);
496 self
->tls_info
= tls_info
;
497 self
->result
= g_simple_async_result_new(G_OBJECT(self
),
500 channel_new_certificate
);
502 g_signal_connect(tls_info
->certificate
,
504 G_CALLBACK(certificate_accepted_cb
),
507 g_signal_connect(tls_info
->certificate
,
509 G_CALLBACK(certificate_rejected_cb
),
512 manager_new_channel(telepathy_private
->tls_manager
, self
);
518 * TLS Certificate class - instance methods
521 CERTIFICATE_PROP_OBJECT_PATH
= 1,
522 CERTIFICATE_PROP_STATE
,
523 CERTIFICATE_PROP_TYPE
,
524 CERTIFICATE_PROP_CHAIN_DATA
,
525 CERTIFICATE_LAST_PROP
528 static void certificate_get_property(GObject
*object
,
533 SipeTLSCertificate
*self
= SIPE_TLS_CERTIFICATE(object
);
535 switch (property_id
) {
536 case CERTIFICATE_PROP_OBJECT_PATH
:
537 g_value_set_string(value
, self
->tls_info
->cert_path
);
539 case CERTIFICATE_PROP_STATE
:
540 g_value_set_uint(value
, self
->state
);
542 case CERTIFICATE_PROP_TYPE
:
543 g_value_set_string(value
, "x509");
545 case CERTIFICATE_PROP_CHAIN_DATA
:
546 g_value_set_boxed(value
, self
->tls_info
->cert_data
);
549 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, property_id
, pspec
);
554 static void sipe_tls_certificate_constructed(GObject
*object
)
556 SipeTLSCertificate
*self
= SIPE_TLS_CERTIFICATE(object
);
557 void (*chain_up
)(GObject
*) = G_OBJECT_CLASS(sipe_tls_certificate_parent_class
)->constructed
;
562 self
->state
= SIPE_TLS_CERTIFICATE_PENDING
;
565 static void sipe_tls_certificate_finalize(GObject
*object
)
567 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSCertificate::finalize");
569 G_OBJECT_CLASS(sipe_tls_certificate_parent_class
)->finalize(object
);
573 * TLS Certificate class - type implementation
575 static void sipe_tls_certificate_class_init(SipeTLSCertificateClass
*klass
)
577 static TpDBusPropertiesMixinPropImpl props
[] = {
580 .getter_data
= "state",
584 .name
= "CertificateType",
585 .getter_data
= "certificate-type",
589 .name
= "CertificateChainData",
590 .getter_data
= "certificate-chain-data",
597 static TpDBusPropertiesMixinIfaceImpl prop_interfaces
[] = {
599 .name
= TP_IFACE_AUTHENTICATION_TLS_CERTIFICATE
,
600 .getter
= tp_dbus_properties_mixin_getter_gobject_properties
,
608 GObjectClass
*object_class
= G_OBJECT_CLASS(klass
);
611 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSCertificate::class_init");
613 klass
->dbus_props_class
.interfaces
= prop_interfaces
;
615 object_class
->constructed
= sipe_tls_certificate_constructed
;
616 object_class
->finalize
= sipe_tls_certificate_finalize
;
617 object_class
->get_property
= certificate_get_property
;
619 ps
= g_param_spec_string("object-path",
621 "The D-Bus object path used for this object on the bus.",
623 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
624 g_object_class_install_property(object_class
,
625 CERTIFICATE_PROP_OBJECT_PATH
,
628 ps
= g_param_spec_uint("state",
629 "State of this certificate",
630 "The state of this TLS certificate.",
631 SIPE_TLS_CERTIFICATE_PENDING
,
632 SIPE_TLS_CERTIFICATE_ACCEPTED
,
633 SIPE_TLS_CERTIFICATE_PENDING
,
634 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
635 g_object_class_install_property(object_class
,
636 CERTIFICATE_PROP_STATE
,
639 ps
= g_param_spec_string("certificate-type",
640 "The certificate type",
641 "The type of this certificate.",
643 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
644 g_object_class_install_property(object_class
,
645 CERTIFICATE_PROP_TYPE
,
648 ps
= g_param_spec_boxed("certificate-chain-data",
649 "The certificate chain data",
650 "The raw DER-encoded trust chain of this certificate.",
651 TP_ARRAY_TYPE_UCHAR_ARRAY_LIST
,
652 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
653 g_object_class_install_property(object_class
,
654 CERTIFICATE_PROP_CHAIN_DATA
, ps
);
656 tp_dbus_properties_mixin_class_init(object_class
,
657 G_STRUCT_OFFSET(SipeTLSCertificateClass
, dbus_props_class
));
660 static void sipe_tls_certificate_init(SIPE_UNUSED_PARAMETER SipeTLSCertificate
*self
)
662 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSCertificate::init");
666 * TLS Certificate class - interface implementation
668 static void tls_certificate_accept(TpSvcAuthenticationTLSCertificate
*certificate
,
669 DBusGMethodInvocation
*context
)
671 SipeTLSCertificate
*self
= SIPE_TLS_CERTIFICATE(certificate
);
673 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSCertificate::accept");
675 if (self
->state
!= SIPE_TLS_CERTIFICATE_PENDING
) {
678 TP_ERROR_INVALID_ARGUMENT
,
679 "Calling Accept() on a certificate with state != PENDING "
680 "doesn't make sense."
683 dbus_g_method_return_error(context
, &error
);
687 self
->state
= SIPE_TLS_CERTIFICATE_ACCEPTED
;
688 tp_svc_authentication_tls_certificate_emit_accepted(self
);
690 tp_svc_authentication_tls_certificate_return_from_accept(context
);
693 static void tls_certificate_reject(TpSvcAuthenticationTLSCertificate
*certificate
,
694 const GPtrArray
*rejections
,
695 DBusGMethodInvocation
*context
)
697 SipeTLSCertificate
*self
= SIPE_TLS_CERTIFICATE(certificate
);
699 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSCertificate::reject");
701 if (self
->state
!= SIPE_TLS_CERTIFICATE_PENDING
) {
704 TP_ERROR_INVALID_ARGUMENT
,
705 "Calling Reject() on a certificate with state != PENDING "
706 "doesn't make sense."
709 dbus_g_method_return_error(context
, &error
);
713 self
->state
= SIPE_TLS_CERTIFICATE_REJECTED
;
715 tp_svc_authentication_tls_certificate_emit_rejected(self
, rejections
);
717 tp_svc_authentication_tls_certificate_return_from_reject(context
);
720 static void tls_certificate_iface_init(gpointer g_iface
,
721 SIPE_UNUSED_PARAMETER gpointer iface_data
)
723 TpSvcAuthenticationTLSCertificateClass
*klass
= g_iface
;
725 #define IMPLEMENT(x) \
726 tp_svc_authentication_tls_certificate_implement_##x( \
727 klass, tls_certificate_##x)
733 static void append_certificate_der(GPtrArray
*certificates
,
736 GArray
*array
= g_array_sized_new(FALSE
,
740 array
= g_array_append_vals(array
, der
->data
, der
->len
);
741 g_byte_array_unref(der
);
743 g_ptr_array_add(certificates
, array
);
746 struct sipe_tls_info
*sipe_telepathy_tls_info_new(const gchar
*hostname
,
747 GTlsCertificate
*certificate
)
749 struct sipe_tls_info
*tls_info
= NULL
;
750 GByteArray
*der
= NULL
;
752 g_object_get(certificate
, "certificate", &der
, NULL
);
754 GPtrArray
*identities
= g_ptr_array_new();
756 tls_info
= g_new0(struct sipe_tls_info
, 1);
757 tls_info
->hostname
= g_strdup(hostname
);
759 /* build GStrv of identies */
760 g_ptr_array_add(identities
, g_strdup(hostname
));
761 g_ptr_array_add(identities
, NULL
);
762 tls_info
->reference_identities
= (GStrv
) g_ptr_array_free(identities
,
765 tls_info
->cert_data
= g_ptr_array_new_full(1,
766 (GDestroyNotify
) g_array_unref
);
768 append_certificate_der(tls_info
->cert_data
, der
);
770 /* will be unref'd in loop */
771 g_object_ref(certificate
);
772 while (certificate
) {
773 GTlsCertificate
*issuer
= NULL
;
775 g_object_get(certificate
, "issuer", &issuer
, NULL
);
776 g_object_unref(certificate
);
778 /* add issuer certificate */
780 g_object_get(certificate
, "certificate", &der
, NULL
);
783 append_certificate_der(tls_info
->cert_data
, der
);
786 /* walk up the chain */
787 certificate
= issuer
;
794 void sipe_telepathy_tls_info_free(struct sipe_tls_info
*tls_info
)
796 g_object_unref(tls_info
->certificate
);
797 g_free(tls_info
->hostname
);
798 g_free(tls_info
->cert_path
);
799 g_ptr_array_unref(tls_info
->cert_data
);
800 g_strfreev(tls_info
->reference_identities
);
804 /* create new tls certificate object */
805 void sipe_telepathy_tls_verify_async(GObject
*connection
,
806 struct sipe_tls_info
*tls_info
,
807 GAsyncReadyCallback callback
,
810 /* property "connection" required by TpBaseChannel */
811 SipeTLSChannel
*channel
= g_object_new(SIPE_TYPE_TLS_CHANNEL
,
812 "connection", connection
,
814 TpBaseChannel
*base
= TP_BASE_CHANNEL(channel
);
815 SipeTLSCertificate
*certificate
= g_object_new(SIPE_TYPE_TLS_CERTIFICATE
,
817 TpDBusDaemon
*daemon
= tp_dbus_daemon_dup(NULL
);
819 tls_info
->certificate
= certificate
;
820 certificate
->tls_info
= tls_info
;
822 tp_base_channel_register(base
);
823 tls_info
->cert_path
= g_strdup_printf("%s/TLSCertificateObject",
824 tp_base_channel_get_object_path(base
));
826 /* register the certificate on the bus */
827 tp_dbus_daemon_register_object(daemon
,
830 g_object_unref(daemon
);
832 channel_new_certificate(connection
,