1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
3 * GIO - GLib Input, Output and Streaming Library
5 * Copyright 2009 Red Hat, Inc
6 * Copyright 2015, 2016 Collabora, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library 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 GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General
19 * Public License along with this library; if not, see
20 * <http://www.gnu.org/licenses/>.
22 * In addition, when the library is used with OpenSSL, a special
23 * exception applies. Refer to the LICENSE_EXCEPTION file for details.
31 #include <gnutls/dtls.h>
32 #include <gnutls/gnutls.h>
33 #include <gnutls/x509.h>
35 #include "gtlsconnection-gnutls.h"
36 #include "gtlsbackend-gnutls.h"
37 #include "gtlscertificate-gnutls.h"
38 #include "gtlsclientconnection-gnutls.h"
39 #include "gtlsinputstream-gnutls.h"
40 #include "gtlsoutputstream-gnutls.h"
41 #include "gtlsserverconnection-gnutls.h"
47 /* It isn’t clear whether MinGW always defines EMSGSIZE. */
49 #define EMSGSIZE WSAEMSGSIZE
53 #include <glib/gi18n-lib.h>
54 #include <glib/gprintf.h>
57 * GTlsConnectionGnutls is the base abstract implementation of TLS and DTLS
58 * support, for both the client and server side of a connection. The choice
59 * between TLS and DTLS is made by setting the base-io-stream or
60 * base-socket properties — exactly one of them must be set at
63 * Client and server specific code is in the GTlsClientConnectionGnutls and
64 * GTlsServerConnectionGnutls concrete subclasses, although the line about where
65 * code is put is a little blurry, and there are various places in
66 * GTlsConnectionGnutls which check G_IS_TLS_CLIENT_CONNECTION(self) to switch
67 * to a client-only code path.
69 * This abstract class implements a lot of interfaces:
70 * • Derived from GTlsConnection (itself from GIOStream), for TLS and streaming
72 * • Implements GDtlsConnection and GDatagramBased, for DTLS and datagram
74 * • Implements GInitable for failable GnuTLS initialisation.
76 * The GTlsClientConnectionGnutls and GTlsServerConnectionGnutls subclasses are
77 * both derived from GTlsConnectionGnutls (and hence GIOStream), and both
78 * implement the relevant TLS and DTLS interfaces:
79 * • GTlsClientConnection
80 * • GDtlsClientConnection
81 * • GTlsServerConnection
82 * • GDtlsServerConnection
87 #if ENABLE(TIZEN_PERFORMANCE_TEST_LOG)
88 #include <sys/prctl.h>
89 #ifndef PR_TASK_PERF_USER_TRACE
90 #define PR_TASK_PERF_USER_TRACE 666
92 #define HWCLOCK_LOG(s) {const char *str=s; prctl(PR_TASK_PERF_USER_TRACE, str, strlen(str));}
95 static ssize_t g_tls_connection_gnutls_push_func (gnutls_transport_ptr_t transport_data,
98 static ssize_t g_tls_connection_gnutls_vec_push_func (gnutls_transport_ptr_t transport_data,
101 static ssize_t g_tls_connection_gnutls_pull_func (gnutls_transport_ptr_t transport_data,
105 static int g_tls_connection_gnutls_pull_timeout_func (gnutls_transport_ptr_t transport_data,
109 static void g_tls_connection_gnutls_initable_iface_init (GInitableIface *iface);
110 static gboolean g_tls_connection_gnutls_initable_init (GInitable *initable,
111 GCancellable *cancellable,
113 static void g_tls_connection_gnutls_dtls_connection_iface_init (GDtlsConnectionInterface *iface);
114 static void g_tls_connection_gnutls_datagram_based_iface_init (GDatagramBasedInterface *iface);
116 static void g_tls_connection_gnutls_init_priorities (void);
118 static int verify_certificate_cb (gnutls_session_t session);
120 static gboolean do_implicit_handshake (GTlsConnectionGnutls *gnutls,
122 GCancellable *cancellable,
124 static gboolean finish_handshake (GTlsConnectionGnutls *gnutls,
131 /* For this class: */
134 /* For GTlsConnection and GDtlsConnection: */
135 PROP_REQUIRE_CLOSE_NOTIFY,
136 PROP_REHANDSHAKE_MODE,
137 PROP_USE_SYSTEM_CERTDB,
141 PROP_PEER_CERTIFICATE,
142 PROP_PEER_CERTIFICATE_ERRORS,
143 #if GLIB_CHECK_VERSION(2, 60, 0)
144 PROP_ADVERTISED_PROTOCOLS,
145 PROP_NEGOTIATED_PROTOCOL,
151 /* When operating in stream mode, as a GTlsConnection. These are
152 * mutually-exclusive with base_socket. There are two different
153 * GIOStreams here: (a) base_io_stream and (b) the GTlsConnectionGnutls
154 * itself. base_io_stream is the GIOStream used to create the GTlsConnection,
155 * and corresponds to the GTlsConnection::base-io-stream property.
156 * base_istream and base_ostream are the GInputStream and GOutputStream,
157 * respectively, of base_io_stream. These are for the underlying sockets that
158 * don't know about TLS.
160 * Then the GTlsConnectionGnutls also has tls_istream and tls_ostream which
161 * wrap the aforementioned base streams with a TLS session.
163 * When operating in datagram mode, none of these are used.
165 GIOStream *base_io_stream;
166 GPollableInputStream *base_istream;
167 GPollableOutputStream *base_ostream;
168 GInputStream *tls_istream;
169 GOutputStream *tls_ostream;
171 /* When operating in datagram mode, as a GDtlsConnection, the
172 * GTlsConnectionGnutls is itself the DTLS GDatagramBased. It uses base_socket
173 * for the underlying I/O. It is mutually-exclusive with base_io_stream and
176 GDatagramBased *base_socket;
178 gnutls_certificate_credentials_t creds;
179 gnutls_session_t session;
181 GTlsCertificate *certificate, *peer_certificate;
182 GTlsCertificateFlags peer_certificate_errors;
184 GMutex verify_certificate_mutex;
185 GCond verify_certificate_condition;
186 gboolean peer_certificate_accepted;
187 gboolean peer_certificate_examined;
189 gboolean require_close_notify;
190 GTlsRehandshakeMode rehandshake_mode;
191 gboolean is_system_certdb;
192 GTlsDatabase *database;
193 gboolean database_is_unset;
195 /* need_handshake means the next claim_op() will get diverted into
196 * an implicit handshake (unless it's an OP_HANDSHAKE or OP_CLOSE*).
197 * need_finish_handshake means the next claim_op() will get diverted
198 * into finish_handshake() (unless it's an OP_CLOSE*).
200 * handshaking is TRUE as soon as a handshake thread is queued. For
201 * a sync handshake it becomes FALSE after finish_handshake()
202 * completes in the calling thread, but for an async implicit
203 * handshake, it becomes FALSE (and need_finish_handshake becomes
204 * TRUE) at the end of the handshaking thread (and then the next
205 * non-close op will call finish_handshake()). We can't just wait
206 * for handshake_thread_completed() to run, because it's possible
207 * that its main loop is being blocked by a synchronous op which is
208 * waiting for handshaking to become FALSE...
210 * started_handshake indicates that the current handshake attempt
211 * got at least as far as calling gnutls_handshake() (and so any
212 * error should be copied to handshake_error and returned on all
213 * future operations). ever_handshaked indicates that TLS has
214 * been successfully negotiated at some point.
216 gboolean need_handshake, need_finish_handshake, sync_handshake_completed;
217 gboolean started_handshake, handshaking, ever_handshaked;
218 GMainContext *handshake_context;
219 GTask *implicit_handshake;
220 GError *handshake_error;
221 GByteArray *app_data_buf;
223 /* read_closed means the read direction has closed; write_closed similarly.
224 * If (and only if) both are set, the entire GTlsConnection is closed. */
225 gboolean read_closing, read_closed;
226 gboolean write_closing, write_closed;
228 GTlsInteraction *interaction;
229 gchar *interaction_id;
231 #if GLIB_CHECK_VERSION(2, 60, 0)
232 gchar **advertised_protocols;
233 gchar *negotiated_protocol;
237 GCancellable *waiting_for_op;
242 GCancellable *read_cancellable;
245 gint64 write_timeout;
247 GCancellable *write_cancellable;
248 } GTlsConnectionGnutlsPrivate;
250 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GTlsConnectionGnutls, g_tls_connection_gnutls, G_TYPE_TLS_CONNECTION,
251 G_ADD_PRIVATE (GTlsConnectionGnutls);
252 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
253 g_tls_connection_gnutls_initable_iface_init);
254 G_IMPLEMENT_INTERFACE (G_TYPE_DATAGRAM_BASED,
255 g_tls_connection_gnutls_datagram_based_iface_init);
256 G_IMPLEMENT_INTERFACE (G_TYPE_DTLS_CONNECTION,
257 g_tls_connection_gnutls_dtls_connection_iface_init);
258 g_tls_connection_gnutls_init_priorities ();
261 static gint unique_interaction_id = 0;
264 g_tls_connection_gnutls_init (GTlsConnectionGnutls *gnutls)
266 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
269 gnutls_certificate_allocate_credentials (&priv->creds);
271 g_mutex_init (&priv->verify_certificate_mutex);
272 g_cond_init (&priv->verify_certificate_condition);
274 priv->need_handshake = TRUE;
276 priv->database_is_unset = TRUE;
277 priv->is_system_certdb = TRUE;
279 unique_id = g_atomic_int_add (&unique_interaction_id, 1);
280 priv->interaction_id = g_strdup_printf ("gtls:%d", unique_id);
282 priv->waiting_for_op = g_cancellable_new ();
283 g_cancellable_cancel (priv->waiting_for_op);
284 g_mutex_init (&priv->op_mutex);
287 /* First field is "fallback", second is "allow unsafe rehandshaking" */
288 static gnutls_priority_t priorities[2][2];
290 #if ENABLE(TIZEN_TV_UPDATE_DEFAULT_PRIORITY)
291 #define DEFAULT_BASE_PRIORITY "NORMAL:%COMPAT:!VERS-SSL3.0:%LATEST_RECORD_VERSION"
293 /* TODO: Get rid of this in favor of gnutls_set_default_priority_append()
294 * when upgrading to GnuTLS 3.6.3.
296 #define DEFAULT_BASE_PRIORITY "NORMAL:%COMPAT"
300 g_tls_connection_gnutls_init_priorities (void)
302 const gchar *base_priority;
303 gchar *fallback_priority, *unsafe_rehandshake_priority, *fallback_unsafe_rehandshake_priority;
305 int ret, i, nprotos, fallback_proto;
307 base_priority = g_getenv ("G_TLS_GNUTLS_PRIORITY");
309 base_priority = DEFAULT_BASE_PRIORITY;
310 ret = gnutls_priority_init (&priorities[FALSE][FALSE], base_priority, NULL);
311 if (ret == GNUTLS_E_INVALID_REQUEST)
313 g_warning ("G_TLS_GNUTLS_PRIORITY is invalid; ignoring!");
314 base_priority = DEFAULT_BASE_PRIORITY;
315 ret = gnutls_priority_init (&priorities[FALSE][FALSE], base_priority, NULL);
316 g_warn_if_fail (ret == 0);
319 unsafe_rehandshake_priority = g_strdup_printf ("%s:%%UNSAFE_RENEGOTIATION", base_priority);
320 ret = gnutls_priority_init (&priorities[FALSE][TRUE], unsafe_rehandshake_priority, NULL);
321 g_warn_if_fail (ret == 0);
322 g_free (unsafe_rehandshake_priority);
324 /* Figure out the lowest SSl/TLS version supported by base_priority */
325 nprotos = gnutls_priority_protocol_list (priorities[FALSE][FALSE], &protos);
326 fallback_proto = G_MAXUINT;
327 for (i = 0; i < nprotos; i++)
329 if (protos[i] < fallback_proto)
330 fallback_proto = protos[i];
332 if (fallback_proto == G_MAXUINT)
334 g_warning ("All GNUTLS protocol versions disabled?");
335 fallback_priority = g_strdup (base_priority);
339 /* %COMPAT is intentionally duplicated here, to ensure it gets added for
340 * the fallback even if the default priority has been changed. */
341 fallback_priority = g_strdup_printf ("%s:%%COMPAT:!VERS-TLS-ALL:+VERS-%s:%%FALLBACK_SCSV",
342 DEFAULT_BASE_PRIORITY,
343 gnutls_protocol_get_name (fallback_proto));
345 fallback_unsafe_rehandshake_priority = g_strdup_printf ("%s:%%UNSAFE_RENEGOTIATION",
348 ret = gnutls_priority_init (&priorities[TRUE][FALSE], fallback_priority, NULL);
349 g_warn_if_fail (ret == 0);
350 ret = gnutls_priority_init (&priorities[TRUE][TRUE], fallback_unsafe_rehandshake_priority, NULL);
351 g_warn_if_fail (ret == 0);
352 g_free (fallback_priority);
353 g_free (fallback_unsafe_rehandshake_priority);
357 g_tls_connection_gnutls_set_handshake_priority (GTlsConnectionGnutls *gnutls)
359 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
360 gboolean fallback, unsafe_rehandshake;
362 if (G_IS_TLS_CLIENT_CONNECTION (gnutls))
364 #if defined(__GNUC__)
365 #pragma GCC diagnostic push
366 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
368 fallback = g_tls_client_connection_get_use_ssl3 (G_TLS_CLIENT_CONNECTION (gnutls));
369 #if defined(__GNUC__)
370 #pragma GCC diagnostic pop
375 unsafe_rehandshake = (priv->rehandshake_mode == G_TLS_REHANDSHAKE_UNSAFELY);
376 gnutls_priority_set (priv->session,
377 priorities[fallback][unsafe_rehandshake]);
381 g_tls_connection_gnutls_is_dtls (GTlsConnectionGnutls *gnutls)
383 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
385 return (priv->base_socket != NULL);
389 g_tls_connection_gnutls_initable_init (GInitable *initable,
390 GCancellable *cancellable,
393 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (initable);
394 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
395 gboolean client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
396 guint flags = client ? GNUTLS_CLIENT : GNUTLS_SERVER;
399 g_return_val_if_fail ((priv->base_istream == NULL) ==
400 (priv->base_ostream == NULL), FALSE);
401 g_return_val_if_fail ((priv->base_socket == NULL) !=
402 (priv->base_istream == NULL), FALSE);
404 /* Check whether to use DTLS or TLS. */
405 if (g_tls_connection_gnutls_is_dtls (gnutls))
406 flags |= GNUTLS_DATAGRAM;
408 gnutls_init (&priv->session, flags);
410 gnutls_session_set_ptr (priv->session, gnutls);
411 gnutls_session_set_verify_function (priv->session, verify_certificate_cb);
413 status = gnutls_credentials_set (priv->session,
414 GNUTLS_CRD_CERTIFICATE,
418 g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
419 _("Could not create TLS connection: %s"),
420 gnutls_strerror (status));
424 gnutls_transport_set_push_function (priv->session,
425 g_tls_connection_gnutls_push_func);
426 gnutls_transport_set_pull_function (priv->session,
427 g_tls_connection_gnutls_pull_func);
428 gnutls_transport_set_pull_timeout_function (priv->session,
429 g_tls_connection_gnutls_pull_timeout_func);
430 gnutls_transport_set_ptr (priv->session, gnutls);
432 /* GDatagramBased supports vectored I/O; GPollableOutputStream does not. */
433 if (priv->base_socket != NULL)
435 gnutls_transport_set_vec_push_function (priv->session,
436 g_tls_connection_gnutls_vec_push_func);
439 /* Set reasonable MTU */
440 if (flags & GNUTLS_DATAGRAM)
441 gnutls_dtls_set_mtu (priv->session, 1400);
443 /* Create output streams if operating in streaming mode. */
444 if (!(flags & GNUTLS_DATAGRAM))
446 priv->tls_istream = g_tls_input_stream_gnutls_new (gnutls);
447 priv->tls_ostream = g_tls_output_stream_gnutls_new (gnutls);
454 g_tls_connection_gnutls_finalize (GObject *object)
456 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
457 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
459 g_clear_object (&priv->base_io_stream);
460 g_clear_object (&priv->base_socket);
462 g_clear_object (&priv->tls_istream);
463 g_clear_object (&priv->tls_ostream);
466 gnutls_deinit (priv->session);
468 gnutls_certificate_free_credentials (priv->creds);
470 g_clear_object (&priv->database);
471 g_clear_object (&priv->certificate);
472 g_clear_object (&priv->peer_certificate);
474 g_mutex_clear (&priv->verify_certificate_mutex);
475 g_cond_clear (&priv->verify_certificate_condition);
478 g_clear_pointer (&priv->app_data_buf, g_byte_array_unref);
480 g_free (priv->interaction_id);
481 g_clear_object (&priv->interaction);
483 #if GLIB_CHECK_VERSION(2, 60, 0)
484 g_clear_pointer (&priv->advertised_protocols, g_strfreev);
485 g_clear_pointer (&priv->negotiated_protocol, g_free);
488 g_clear_error (&priv->handshake_error);
489 g_clear_error (&priv->read_error);
490 g_clear_error (&priv->write_error);
492 g_clear_pointer (&priv->handshake_context, g_main_context_unref);
494 /* This must always be NULL here, as it holds a reference to @gnutls as
495 * its source object. However, we clear it anyway just in case this changes
497 g_clear_object (&priv->implicit_handshake);
499 g_clear_object (&priv->read_cancellable);
500 g_clear_object (&priv->write_cancellable);
502 g_clear_object (&priv->waiting_for_op);
503 g_mutex_clear (&priv->op_mutex);
505 G_OBJECT_CLASS (g_tls_connection_gnutls_parent_class)->finalize (object);
509 g_tls_connection_gnutls_get_property (GObject *object,
514 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
515 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
516 GTlsBackend *backend;
520 case PROP_BASE_IO_STREAM:
521 g_value_set_object (value, priv->base_io_stream);
524 case PROP_BASE_SOCKET:
525 g_value_set_object (value, priv->base_socket);
528 case PROP_REQUIRE_CLOSE_NOTIFY:
529 g_value_set_boolean (value, priv->require_close_notify);
532 case PROP_REHANDSHAKE_MODE:
533 g_value_set_enum (value, priv->rehandshake_mode);
536 case PROP_USE_SYSTEM_CERTDB:
537 g_value_set_boolean (value, priv->is_system_certdb);
541 if (priv->database_is_unset)
543 backend = g_tls_backend_get_default ();
544 priv->database = g_tls_backend_get_default_database (backend);
545 priv->database_is_unset = FALSE;
547 g_value_set_object (value, priv->database);
550 case PROP_CERTIFICATE:
551 g_value_set_object (value, priv->certificate);
554 case PROP_INTERACTION:
555 g_value_set_object (value, priv->interaction);
558 case PROP_PEER_CERTIFICATE:
559 g_value_set_object (value, priv->peer_certificate);
562 case PROP_PEER_CERTIFICATE_ERRORS:
563 g_value_set_flags (value, priv->peer_certificate_errors);
566 #if GLIB_CHECK_VERSION(2, 60, 0)
567 case PROP_ADVERTISED_PROTOCOLS:
568 g_value_set_boxed (value, priv->advertised_protocols);
571 case PROP_NEGOTIATED_PROTOCOL:
572 g_value_set_string (value, priv->negotiated_protocol);
577 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
582 g_tls_connection_gnutls_set_property (GObject *object,
587 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
588 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
589 GInputStream *istream;
590 GOutputStream *ostream;
591 gboolean system_certdb;
592 GTlsBackend *backend;
596 case PROP_BASE_IO_STREAM:
597 g_assert (g_value_get_object (value) == NULL ||
598 priv->base_socket == NULL);
600 if (priv->base_io_stream)
602 g_object_unref (priv->base_io_stream);
603 priv->base_istream = NULL;
604 priv->base_ostream = NULL;
606 priv->base_io_stream = g_value_dup_object (value);
607 if (!priv->base_io_stream)
610 istream = g_io_stream_get_input_stream (priv->base_io_stream);
611 ostream = g_io_stream_get_output_stream (priv->base_io_stream);
613 if (G_IS_POLLABLE_INPUT_STREAM (istream) &&
614 g_pollable_input_stream_can_poll (G_POLLABLE_INPUT_STREAM (istream)))
615 priv->base_istream = G_POLLABLE_INPUT_STREAM (istream);
616 if (G_IS_POLLABLE_OUTPUT_STREAM (ostream) &&
617 g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (ostream)))
618 priv->base_ostream = G_POLLABLE_OUTPUT_STREAM (ostream);
621 case PROP_BASE_SOCKET:
622 g_assert (g_value_get_object (value) == NULL ||
623 priv->base_io_stream == NULL);
625 g_clear_object (&priv->base_socket);
626 priv->base_socket = g_value_dup_object (value);
629 case PROP_REQUIRE_CLOSE_NOTIFY:
630 priv->require_close_notify = g_value_get_boolean (value);
633 case PROP_REHANDSHAKE_MODE:
634 priv->rehandshake_mode = g_value_get_enum (value);
637 case PROP_USE_SYSTEM_CERTDB:
638 system_certdb = g_value_get_boolean (value);
639 if (system_certdb != priv->is_system_certdb)
641 g_clear_object (&priv->database);
644 backend = g_tls_backend_get_default ();
645 priv->database = g_tls_backend_get_default_database (backend);
647 priv->is_system_certdb = system_certdb;
648 priv->database_is_unset = FALSE;
653 g_clear_object (&priv->database);
654 priv->database = g_value_dup_object (value);
655 priv->is_system_certdb = FALSE;
656 priv->database_is_unset = FALSE;
659 case PROP_CERTIFICATE:
660 if (priv->certificate)
661 g_object_unref (priv->certificate);
662 priv->certificate = g_value_dup_object (value);
665 case PROP_INTERACTION:
666 g_clear_object (&priv->interaction);
667 priv->interaction = g_value_dup_object (value);
670 #if GLIB_CHECK_VERSION(2, 60, 0)
671 case PROP_ADVERTISED_PROTOCOLS:
672 g_clear_pointer (&priv->advertised_protocols, g_strfreev);
673 priv->advertised_protocols = g_value_dup_boxed (value);
678 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
682 gnutls_certificate_credentials_t
683 g_tls_connection_gnutls_get_credentials (GTlsConnectionGnutls *gnutls)
685 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
691 g_tls_connection_gnutls_get_session (GTlsConnectionGnutls *gnutls)
693 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
695 return priv->session;
699 g_tls_connection_gnutls_get_certificate (GTlsConnectionGnutls *gnutls,
700 gnutls_pcert_st **pcert,
701 unsigned int *pcert_length,
702 gnutls_privkey_t *pkey)
704 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
705 GTlsCertificate *cert;
707 cert = g_tls_connection_get_certificate (G_TLS_CONNECTION (gnutls));
711 g_tls_certificate_gnutls_copy (G_TLS_CERTIFICATE_GNUTLS (cert),
712 priv->interaction_id,
713 pcert, pcert_length, pkey);
724 G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE,
725 G_TLS_CONNECTION_GNUTLS_OP_READ,
726 G_TLS_CONNECTION_GNUTLS_OP_WRITE,
727 G_TLS_CONNECTION_GNUTLS_OP_CLOSE_READ,
728 G_TLS_CONNECTION_GNUTLS_OP_CLOSE_WRITE,
729 G_TLS_CONNECTION_GNUTLS_OP_CLOSE_BOTH,
730 } GTlsConnectionGnutlsOp;
733 claim_op (GTlsConnectionGnutls *gnutls,
734 GTlsConnectionGnutlsOp op,
736 GCancellable *cancellable,
739 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
742 if (g_cancellable_set_error_if_cancelled (cancellable, error))
745 g_mutex_lock (&priv->op_mutex);
747 if (((op == G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE ||
748 op == G_TLS_CONNECTION_GNUTLS_OP_READ) &&
749 (priv->read_closing || priv->read_closed)) ||
750 ((op == G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE ||
751 op == G_TLS_CONNECTION_GNUTLS_OP_WRITE) &&
752 (priv->write_closing || priv->write_closed)))
754 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
755 _("Connection is closed"));
756 g_mutex_unlock (&priv->op_mutex);
760 if (priv->handshake_error &&
761 op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE_BOTH &&
762 op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE_READ &&
763 op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE_WRITE)
766 *error = g_error_copy (priv->handshake_error);
767 g_mutex_unlock (&priv->op_mutex);
771 if (op != G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE)
773 if (op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE_BOTH &&
774 op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE_READ &&
775 op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE_WRITE &&
776 priv->need_handshake)
778 priv->need_handshake = FALSE;
779 priv->handshaking = TRUE;
780 if (!do_implicit_handshake (gnutls, timeout, cancellable, error))
782 g_mutex_unlock (&priv->op_mutex);
787 if (priv->need_finish_handshake &&
788 priv->implicit_handshake)
790 GError *my_error = NULL;
793 priv->need_finish_handshake = FALSE;
795 g_mutex_unlock (&priv->op_mutex);
796 success = finish_handshake (gnutls, priv->implicit_handshake, &my_error);
797 g_clear_object (&priv->implicit_handshake);
798 g_clear_pointer (&priv->handshake_context, g_main_context_unref);
799 g_mutex_lock (&priv->op_mutex);
801 if (op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE_BOTH &&
802 op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE_READ &&
803 op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE_WRITE &&
804 (!success || g_cancellable_set_error_if_cancelled (cancellable, &my_error)))
806 g_propagate_error (error, my_error);
807 g_mutex_unlock (&priv->op_mutex);
811 g_clear_error (&my_error);
815 if (priv->handshaking &&
817 g_main_context_is_owner (priv->handshake_context))
819 /* Cannot perform a blocking operation during a handshake on the
820 * same thread that triggered the handshake. The only way this can
821 * occur is if the application is doing something weird in its
822 * accept-certificate callback. Allowing a blocking op would stall
823 * the handshake (forever, if there's no timeout). Even a close
824 * op would deadlock here.
826 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Cannot perform blocking operation during TLS handshake"));
827 g_mutex_unlock (&priv->op_mutex);
831 if ((op != G_TLS_CONNECTION_GNUTLS_OP_WRITE && priv->reading) ||
832 (op != G_TLS_CONNECTION_GNUTLS_OP_READ && priv->writing) ||
833 (op != G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE && priv->handshaking))
838 gint result = 1; /* if the loop is never entered, it’s as if we cancelled early */
840 g_cancellable_reset (priv->waiting_for_op);
842 g_mutex_unlock (&priv->op_mutex);
846 /* Intentionally not translated because this is not a fatal error to be
847 * presented to the user, and to avoid this showing up in profiling. */
848 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, "Operation would block");
852 g_cancellable_make_pollfd (priv->waiting_for_op, &fds[0]);
853 if (g_cancellable_make_pollfd (cancellable, &fds[1]))
858 /* Convert from microseconds to milliseconds. */
860 timeout = timeout / 1000;
862 /* Poll until cancellation or the timeout is reached. */
863 start_time = g_get_monotonic_time ();
865 while (!g_cancellable_is_cancelled (priv->waiting_for_op) &&
866 !g_cancellable_is_cancelled (cancellable))
868 result = g_poll (fds, nfds, timeout);
872 if (result != -1 || errno != EINTR)
877 timeout -= (g_get_monotonic_time () - start_time) / 1000;
884 g_cancellable_release_fd (cancellable);
888 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
889 _("Socket I/O timed out"));
896 if (op == G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE)
898 priv->handshaking = TRUE;
899 priv->need_handshake = FALSE;
901 if (op == G_TLS_CONNECTION_GNUTLS_OP_CLOSE_BOTH ||
902 op == G_TLS_CONNECTION_GNUTLS_OP_CLOSE_READ)
903 priv->read_closing = TRUE;
904 if (op == G_TLS_CONNECTION_GNUTLS_OP_CLOSE_BOTH ||
905 op == G_TLS_CONNECTION_GNUTLS_OP_CLOSE_WRITE)
906 priv->write_closing = TRUE;
908 if (op != G_TLS_CONNECTION_GNUTLS_OP_WRITE)
909 priv->reading = TRUE;
910 if (op != G_TLS_CONNECTION_GNUTLS_OP_READ)
911 priv->writing = TRUE;
913 g_mutex_unlock (&priv->op_mutex);
918 yield_op (GTlsConnectionGnutls *gnutls,
919 GTlsConnectionGnutlsOp op)
921 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
923 g_mutex_lock (&priv->op_mutex);
925 if (op == G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE)
926 priv->handshaking = FALSE;
927 if (op == G_TLS_CONNECTION_GNUTLS_OP_CLOSE_BOTH ||
928 op == G_TLS_CONNECTION_GNUTLS_OP_CLOSE_READ)
929 priv->read_closing = FALSE;
930 if (op == G_TLS_CONNECTION_GNUTLS_OP_CLOSE_BOTH ||
931 op == G_TLS_CONNECTION_GNUTLS_OP_CLOSE_WRITE)
932 priv->write_closing = FALSE;
934 if (op != G_TLS_CONNECTION_GNUTLS_OP_WRITE)
935 priv->reading = FALSE;
936 if (op != G_TLS_CONNECTION_GNUTLS_OP_READ)
937 priv->writing = FALSE;
939 g_cancellable_cancel (priv->waiting_for_op);
940 g_mutex_unlock (&priv->op_mutex);
944 begin_gnutls_io (GTlsConnectionGnutls *gnutls,
945 GIOCondition direction,
947 GCancellable *cancellable)
949 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
951 g_assert (direction & (G_IO_IN | G_IO_OUT));
953 if (direction & G_IO_IN)
955 priv->read_timeout = timeout;
956 priv->read_cancellable = cancellable;
957 g_clear_error (&priv->read_error);
960 if (direction & G_IO_OUT)
962 priv->write_timeout = timeout;
963 priv->write_cancellable = cancellable;
964 g_clear_error (&priv->write_error);
969 end_gnutls_io (GTlsConnectionGnutls *gnutls,
970 GIOCondition direction,
973 const char *err_prefix);
976 end_gnutls_io (GTlsConnectionGnutls *gnutls,
977 GIOCondition direction,
980 const char *err_prefix)
982 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
983 GError *my_error = NULL;
985 g_assert (direction & (G_IO_IN | G_IO_OUT));
986 g_assert (!error || !*error);
988 /* We intentionally do not check for GNUTLS_E_INTERRUPTED here
989 * Instead, the caller may poll for the source to become ready again.
990 * (Note that GTlsOutputStreamGnutls and GTlsInputStreamGnutls inherit
991 * from GPollableOutputStream and GPollableInputStream, respectively.)
992 * See also the comment in set_gnutls_error().
994 if (status == GNUTLS_E_AGAIN ||
995 status == GNUTLS_E_WARNING_ALERT_RECEIVED)
996 return GNUTLS_E_AGAIN;
998 if (direction & G_IO_IN)
1000 priv->read_cancellable = NULL;
1003 my_error = priv->read_error;
1004 priv->read_error = NULL;
1007 g_clear_error (&priv->read_error);
1009 if (direction & G_IO_OUT)
1011 priv->write_cancellable = NULL;
1012 if (status < 0 && !my_error)
1014 my_error = priv->write_error;
1015 priv->write_error = NULL;
1018 g_clear_error (&priv->write_error);
1024 if (priv->handshaking && !priv->ever_handshaked)
1026 if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_FAILED) ||
1027 g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE) ||
1028 status == GNUTLS_E_UNEXPECTED_PACKET_LENGTH ||
1029 status == GNUTLS_E_DECRYPTION_FAILED ||
1030 status == GNUTLS_E_UNSUPPORTED_VERSION_PACKET)
1032 g_clear_error (&my_error);
1033 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS,
1034 _("Peer failed to perform TLS handshake"));
1035 return GNUTLS_E_PULL_ERROR;
1041 if (!g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) &&
1042 !g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT))
1043 G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->failed (gnutls);
1044 g_propagate_error (error, my_error);
1047 else if (status == GNUTLS_E_REHANDSHAKE)
1049 if (priv->rehandshake_mode == G_TLS_REHANDSHAKE_NEVER)
1051 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
1052 _("Peer requested illegal TLS rehandshake"));
1053 return GNUTLS_E_PULL_ERROR;
1056 g_mutex_lock (&priv->op_mutex);
1057 if (!priv->handshaking)
1058 priv->need_handshake = TRUE;
1059 g_mutex_unlock (&priv->op_mutex);
1062 else if (status == GNUTLS_E_PREMATURE_TERMINATION)
1064 if (priv->handshaking && !priv->ever_handshaked)
1066 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS,
1067 _("Peer failed to perform TLS handshake"));
1068 return GNUTLS_E_PULL_ERROR;
1070 else if (priv->require_close_notify)
1072 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_EOF,
1073 _("TLS connection closed unexpectedly"));
1074 G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->failed (gnutls);
1080 else if (status == GNUTLS_E_NO_CERTIFICATE_FOUND)
1082 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED,
1083 _("TLS connection peer did not send a certificate"));
1086 else if (status == GNUTLS_E_CERTIFICATE_ERROR)
1088 g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
1089 _("Unacceptable TLS certificate"));
1092 else if (status == GNUTLS_E_FATAL_ALERT_RECEIVED)
1094 g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
1095 _("Peer sent fatal TLS alert: %s"),
1096 gnutls_alert_get_name (gnutls_alert_get (priv->session)));
1099 else if (status == GNUTLS_E_INAPPROPRIATE_FALLBACK)
1101 g_set_error_literal (error, G_TLS_ERROR,
1102 #if GLIB_CHECK_VERSION(2, 60, 0)
1103 G_TLS_ERROR_INAPPROPRIATE_FALLBACK,
1107 _("Protocol version downgrade attack detected"));
1110 else if (status == GNUTLS_E_LARGE_PACKET)
1112 guint mtu = gnutls_dtls_get_data_mtu (priv->session);
1113 g_set_error (error, G_IO_ERROR, G_IO_ERROR_MESSAGE_TOO_LARGE,
1114 ngettext ("Message is too large for DTLS connection; maximum is %u byte",
1115 "Message is too large for DTLS connection; maximum is %u bytes", mtu), mtu);
1118 else if (status == GNUTLS_E_TIMEDOUT)
1120 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
1121 _("The operation timed out"));
1127 *error = g_error_new (G_TLS_ERROR, G_TLS_ERROR_MISC, "%s: %s",
1128 err_prefix, gnutls_strerror (status));
1133 #define BEGIN_GNUTLS_IO(gnutls, direction, timeout, cancellable) \
1134 begin_gnutls_io (gnutls, direction, timeout, cancellable); \
1137 #define END_GNUTLS_IO(gnutls, direction, ret, errmsg, err) \
1138 } while ((ret = end_gnutls_io (gnutls, direction, ret, err, errmsg)) == GNUTLS_E_AGAIN);
1140 /* Checks whether the underlying base stream or GDatagramBased meets
1143 g_tls_connection_gnutls_base_check (GTlsConnectionGnutls *gnutls,
1144 GIOCondition condition)
1146 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1148 if (g_tls_connection_gnutls_is_dtls (gnutls))
1149 return g_datagram_based_condition_check (priv->base_socket,
1151 else if (condition & G_IO_IN)
1152 return g_pollable_input_stream_is_readable (priv->base_istream);
1153 else if (condition & G_IO_OUT)
1154 return g_pollable_output_stream_is_writable (priv->base_ostream);
1156 g_assert_not_reached ();
1159 /* Checks whether the (D)TLS stream meets @condition; not the underlying base
1160 * stream or GDatagramBased. */
1162 g_tls_connection_gnutls_check (GTlsConnectionGnutls *gnutls,
1163 GIOCondition condition)
1165 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1167 /* Racy, but worst case is that we just get WOULD_BLOCK back */
1168 if (priv->need_finish_handshake)
1171 /* If a handshake or close is in progress, then tls_istream and
1172 * tls_ostream are blocked, regardless of the base stream status.
1174 if (priv->handshaking)
1177 if (((condition & G_IO_IN) && priv->read_closing) ||
1178 ((condition & G_IO_OUT) && priv->write_closing))
1181 /* Defer to the base stream or GDatagramBased. */
1182 return g_tls_connection_gnutls_base_check (gnutls, condition);
1188 GTlsConnectionGnutls *gnutls;
1189 /* Either a GDatagramBased (datagram mode), or a GPollableInputStream or
1190 * GPollableOutputStream (streaming mode):
1194 GSource *child_source;
1195 GIOCondition condition;
1197 gboolean io_waiting;
1198 gboolean op_waiting;
1199 } GTlsConnectionGnutlsSource;
1202 gnutls_source_prepare (GSource *source,
1210 gnutls_source_check (GSource *source)
1215 /* Use a custom dummy callback instead of g_source_set_dummy_callback(), as that
1216 * uses a GClosure and is slow. (The GClosure is necessary to deal with any
1217 * function prototype.) */
1219 dummy_callback (gpointer data)
1221 return G_SOURCE_CONTINUE;
1225 gnutls_source_sync (GTlsConnectionGnutlsSource *gnutls_source)
1227 GTlsConnectionGnutls *gnutls = gnutls_source->gnutls;
1228 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1229 gboolean io_waiting, op_waiting;
1231 /* Was the source destroyed earlier in this main context iteration? */
1232 if (g_source_is_destroyed ((GSource *)gnutls_source))
1235 g_mutex_lock (&priv->op_mutex);
1236 if (((gnutls_source->condition & G_IO_IN) && priv->reading) ||
1237 ((gnutls_source->condition & G_IO_OUT) && priv->writing) ||
1238 (priv->handshaking && !priv->need_finish_handshake))
1243 if (!op_waiting && !priv->need_handshake &&
1244 !priv->need_finish_handshake)
1248 g_mutex_unlock (&priv->op_mutex);
1250 if (op_waiting == gnutls_source->op_waiting &&
1251 io_waiting == gnutls_source->io_waiting)
1253 gnutls_source->op_waiting = op_waiting;
1254 gnutls_source->io_waiting = io_waiting;
1256 if (gnutls_source->child_source)
1258 g_source_remove_child_source ((GSource *)gnutls_source,
1259 gnutls_source->child_source);
1260 g_source_unref (gnutls_source->child_source);
1264 gnutls_source->child_source = g_cancellable_source_new (priv->waiting_for_op);
1265 else if (io_waiting && G_IS_DATAGRAM_BASED (gnutls_source->base))
1266 gnutls_source->child_source = g_datagram_based_create_source (priv->base_socket, gnutls_source->condition, NULL);
1267 else if (io_waiting && G_IS_POLLABLE_INPUT_STREAM (gnutls_source->base))
1268 gnutls_source->child_source = g_pollable_input_stream_create_source (priv->base_istream, NULL);
1269 else if (io_waiting && G_IS_POLLABLE_OUTPUT_STREAM (gnutls_source->base))
1270 gnutls_source->child_source = g_pollable_output_stream_create_source (priv->base_ostream, NULL);
1272 gnutls_source->child_source = g_timeout_source_new (0);
1274 g_source_set_callback (gnutls_source->child_source, dummy_callback, NULL, NULL);
1275 g_source_add_child_source ((GSource *)gnutls_source, gnutls_source->child_source);
1279 gnutls_source_dispatch (GSource *source,
1280 GSourceFunc callback,
1283 GDatagramBasedSourceFunc datagram_based_func = (GDatagramBasedSourceFunc)callback;
1284 GPollableSourceFunc pollable_func = (GPollableSourceFunc)callback;
1285 GTlsConnectionGnutlsSource *gnutls_source = (GTlsConnectionGnutlsSource *)source;
1288 if (G_IS_DATAGRAM_BASED (gnutls_source->base))
1289 ret = (*datagram_based_func) (G_DATAGRAM_BASED (gnutls_source->base),
1290 gnutls_source->condition, user_data);
1292 ret = (*pollable_func) (gnutls_source->base, user_data);
1295 gnutls_source_sync (gnutls_source);
1301 gnutls_source_finalize (GSource *source)
1303 GTlsConnectionGnutlsSource *gnutls_source = (GTlsConnectionGnutlsSource *)source;
1305 g_object_unref (gnutls_source->gnutls);
1306 g_source_unref (gnutls_source->child_source);
1310 g_tls_connection_gnutls_source_closure_callback (GObject *stream,
1313 GClosure *closure = data;
1315 GValue param = { 0, };
1316 GValue result_value = { 0, };
1319 g_value_init (&result_value, G_TYPE_BOOLEAN);
1321 g_value_init (¶m, G_TYPE_OBJECT);
1322 g_value_set_object (¶m, stream);
1324 g_closure_invoke (closure, &result_value, 1, ¶m, NULL);
1326 result = g_value_get_boolean (&result_value);
1327 g_value_unset (&result_value);
1328 g_value_unset (¶m);
1334 g_tls_connection_gnutls_source_dtls_closure_callback (GObject *stream,
1335 GIOCondition condition,
1338 GClosure *closure = data;
1340 GValue param[2] = { G_VALUE_INIT, G_VALUE_INIT };
1341 GValue result_value = G_VALUE_INIT;
1344 g_value_init (&result_value, G_TYPE_BOOLEAN);
1346 g_value_init (¶m[0], G_TYPE_DATAGRAM_BASED);
1347 g_value_set_object (¶m[0], stream);
1348 g_value_init (¶m[1], G_TYPE_IO_CONDITION);
1349 g_value_set_flags (¶m[1], condition);
1351 g_closure_invoke (closure, &result_value, 2, param, NULL);
1353 result = g_value_get_boolean (&result_value);
1354 g_value_unset (&result_value);
1355 g_value_unset (¶m[0]);
1356 g_value_unset (¶m[1]);
1361 static GSourceFuncs gnutls_tls_source_funcs =
1363 gnutls_source_prepare,
1364 gnutls_source_check,
1365 gnutls_source_dispatch,
1366 gnutls_source_finalize,
1367 (GSourceFunc)g_tls_connection_gnutls_source_closure_callback,
1368 (GSourceDummyMarshal)g_cclosure_marshal_generic
1371 static GSourceFuncs gnutls_dtls_source_funcs =
1373 gnutls_source_prepare,
1374 gnutls_source_check,
1375 gnutls_source_dispatch,
1376 gnutls_source_finalize,
1377 (GSourceFunc)g_tls_connection_gnutls_source_dtls_closure_callback,
1378 (GSourceDummyMarshal)g_cclosure_marshal_generic
1382 g_tls_connection_gnutls_create_source (GTlsConnectionGnutls *gnutls,
1383 GIOCondition condition,
1384 GCancellable *cancellable)
1386 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1387 GSource *source, *cancellable_source;
1388 GTlsConnectionGnutlsSource *gnutls_source;
1390 if (g_tls_connection_gnutls_is_dtls (gnutls))
1392 source = g_source_new (&gnutls_dtls_source_funcs,
1393 sizeof (GTlsConnectionGnutlsSource));
1397 source = g_source_new (&gnutls_tls_source_funcs,
1398 sizeof (GTlsConnectionGnutlsSource));
1400 g_source_set_name (source, "GTlsConnectionGnutlsSource");
1401 gnutls_source = (GTlsConnectionGnutlsSource *)source;
1402 gnutls_source->gnutls = g_object_ref (gnutls);
1403 gnutls_source->condition = condition;
1404 if (g_tls_connection_gnutls_is_dtls (gnutls))
1405 gnutls_source->base = G_OBJECT (gnutls);
1406 else if (priv->tls_istream != NULL && condition & G_IO_IN)
1407 gnutls_source->base = G_OBJECT (priv->tls_istream);
1408 else if (priv->tls_ostream != NULL && condition & G_IO_OUT)
1409 gnutls_source->base = G_OBJECT (priv->tls_ostream);
1411 g_assert_not_reached ();
1413 gnutls_source->op_waiting = (gboolean) -1;
1414 gnutls_source->io_waiting = (gboolean) -1;
1415 gnutls_source_sync (gnutls_source);
1419 cancellable_source = g_cancellable_source_new (cancellable);
1420 g_source_set_dummy_callback (cancellable_source);
1421 g_source_add_child_source (source, cancellable_source);
1422 g_source_unref (cancellable_source);
1429 g_tls_connection_gnutls_dtls_create_source (GDatagramBased *datagram_based,
1430 GIOCondition condition,
1431 GCancellable *cancellable)
1433 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (datagram_based);
1435 return g_tls_connection_gnutls_create_source (gnutls, condition, cancellable);
1439 g_tls_connection_gnutls_condition_check (GDatagramBased *datagram_based,
1440 GIOCondition condition)
1442 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (datagram_based);
1444 return (g_tls_connection_gnutls_check (gnutls, condition)) ? condition : 0;
1448 g_tls_connection_gnutls_condition_wait (GDatagramBased *datagram_based,
1449 GIOCondition condition,
1451 GCancellable *cancellable,
1454 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (datagram_based);
1455 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1458 gint result = 1; /* if the loop is never entered, it’s as if we cancelled early */
1461 if (g_cancellable_set_error_if_cancelled (cancellable, error))
1464 /* Convert from microseconds to milliseconds. */
1466 timeout = timeout / 1000;
1468 start_time = g_get_monotonic_time ();
1470 g_cancellable_make_pollfd (priv->waiting_for_op, &fds[0]);
1473 if (g_cancellable_make_pollfd (cancellable, &fds[1]))
1476 while (!g_tls_connection_gnutls_condition_check (datagram_based, condition) &&
1477 !g_cancellable_is_cancelled (cancellable))
1479 result = g_poll (fds, n_fds, timeout);
1482 if (result != -1 || errno != EINTR)
1487 timeout -= (g_get_monotonic_time () - start_time) / 1000;
1494 g_cancellable_release_fd (cancellable);
1498 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
1499 _("Socket I/O timed out"));
1503 return !g_cancellable_set_error_if_cancelled (cancellable, error);
1507 set_gnutls_error (GTlsConnectionGnutls *gnutls,
1510 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1512 /* We set EINTR rather than EAGAIN for G_IO_ERROR_WOULD_BLOCK so
1513 * that GNUTLS_E_AGAIN only gets returned for gnutls-internal
1514 * reasons, not for actual socket EAGAINs (and we have access
1515 * to @error at the higher levels, so we can distinguish them
1519 if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
1520 gnutls_transport_set_errno (priv->session, EINTR);
1521 else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
1523 /* Return EAGAIN while handshaking so that GnuTLS handles retries for us
1524 * internally in its handshaking code. */
1525 if (priv->base_socket && priv->handshaking)
1526 gnutls_transport_set_errno (priv->session, EAGAIN);
1528 gnutls_transport_set_errno (priv->session, EINTR);
1530 else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT))
1531 gnutls_transport_set_errno (priv->session, EINTR);
1532 else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_MESSAGE_TOO_LARGE))
1533 gnutls_transport_set_errno (priv->session, EMSGSIZE);
1535 gnutls_transport_set_errno (priv->session, EIO);
1539 g_tls_connection_gnutls_pull_func (gnutls_transport_ptr_t transport_data,
1543 GTlsConnectionGnutls *gnutls = transport_data;
1544 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1547 /* If priv->read_error is non-%NULL when we're called, it means
1548 * that an error previously occurred, but gnutls decided not to
1549 * propagate it. So it's correct for us to just clear it. (Usually
1550 * this means it ignored an EAGAIN after a short read, and now
1551 * we'll return EAGAIN again, which it will obey this time.)
1553 g_clear_error (&priv->read_error);
1555 if (g_tls_connection_gnutls_is_dtls (gnutls))
1557 GInputVector vector = { buf, buflen };
1558 GInputMessage message = { NULL, &vector, 1, 0, 0, NULL, NULL };
1560 ret = g_datagram_based_receive_messages (priv->base_socket,
1562 priv->handshaking ? 0 : priv->read_timeout,
1563 priv->read_cancellable,
1567 ret = message.bytes_received;
1571 ret = g_pollable_stream_read (G_INPUT_STREAM (priv->base_istream),
1573 (priv->read_timeout != 0),
1574 priv->read_cancellable,
1579 set_gnutls_error (gnutls, priv->read_error);
1585 g_tls_connection_gnutls_push_func (gnutls_transport_ptr_t transport_data,
1589 GTlsConnectionGnutls *gnutls = transport_data;
1590 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1593 /* See comment in pull_func. */
1594 g_clear_error (&priv->write_error);
1596 if (g_tls_connection_gnutls_is_dtls (gnutls))
1598 GOutputVector vector = { buf, buflen };
1599 GOutputMessage message = { NULL, &vector, 1, 0, NULL, 0 };
1601 ret = g_datagram_based_send_messages (priv->base_socket,
1603 priv->write_timeout,
1604 priv->write_cancellable,
1605 &priv->write_error);
1608 ret = message.bytes_sent;
1612 ret = g_pollable_stream_write (G_OUTPUT_STREAM (priv->base_ostream),
1614 (priv->write_timeout != 0),
1615 priv->write_cancellable,
1616 &priv->write_error);
1620 set_gnutls_error (gnutls, priv->write_error);
1626 g_tls_connection_gnutls_vec_push_func (gnutls_transport_ptr_t transport_data,
1627 const giovec_t *iov,
1630 GTlsConnectionGnutls *gnutls = transport_data;
1631 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1633 GOutputMessage message = { NULL, };
1634 GOutputVector *vectors;
1636 /* This function should only be set if we’re using base_socket. */
1637 g_assert (priv->base_socket != NULL);
1639 /* See comment in pull_func. */
1640 g_clear_error (&priv->write_error);
1642 /* this entire expression will be evaluated at compile time */
1643 if (sizeof *iov == sizeof *vectors &&
1644 sizeof iov->iov_base == sizeof vectors->buffer &&
1645 G_STRUCT_OFFSET (giovec_t, iov_base) ==
1646 G_STRUCT_OFFSET (GOutputVector, buffer) &&
1647 sizeof iov->iov_len == sizeof vectors->size &&
1648 G_STRUCT_OFFSET (giovec_t, iov_len) ==
1649 G_STRUCT_OFFSET (GOutputVector, size))
1650 /* ABI is compatible */
1652 message.vectors = (GOutputVector *)iov;
1653 message.num_vectors = iovcnt;
1656 /* ABI is incompatible */
1660 message.vectors = g_newa (GOutputVector, iovcnt);
1661 for (i = 0; i < iovcnt; i++)
1663 message.vectors[i].buffer = (void *)iov[i].iov_base;
1664 message.vectors[i].size = iov[i].iov_len;
1666 message.num_vectors = iovcnt;
1669 ret = g_datagram_based_send_messages (priv->base_socket,
1671 priv->write_timeout,
1672 priv->write_cancellable,
1673 &priv->write_error);
1676 ret = message.bytes_sent;
1678 set_gnutls_error (gnutls, priv->write_error);
1684 read_pollable_cb (GPollableInputStream *istream,
1687 gboolean *read_done = user_data;
1691 return G_SOURCE_CONTINUE;
1695 read_datagram_based_cb (GDatagramBased *datagram_based,
1696 GIOCondition condition,
1699 gboolean *read_done = user_data;
1703 return G_SOURCE_CONTINUE;
1707 read_timeout_cb (gpointer user_data)
1709 gboolean *timed_out = user_data;
1713 return G_SOURCE_REMOVE;
1717 g_tls_connection_gnutls_pull_timeout_func (gnutls_transport_ptr_t transport_data,
1720 GTlsConnectionGnutls *gnutls = transport_data;
1721 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1724 if (g_tls_connection_gnutls_base_check (gnutls, G_IO_IN) ||
1725 g_cancellable_is_cancelled (priv->read_cancellable))
1728 /* If @ms is 0, GnuTLS wants an instant response, so there’s no need to
1729 * construct and query a #GSource. */
1732 GMainContext *ctx = NULL;
1733 GSource *read_source = NULL, *timeout_source = NULL;
1734 gboolean read_done = FALSE, timed_out = FALSE;
1736 ctx = g_main_context_new ();
1738 /* Create a timeout source. */
1739 timeout_source = g_timeout_source_new (ms);
1740 g_source_set_callback (timeout_source, (GSourceFunc)read_timeout_cb,
1743 /* Create a read source. We cannot use g_source_set_ready_time() on this
1744 * to combine it with the @timeout_source, as that could mess with the
1745 * internals of the #GDatagramBased’s #GSource implementation. */
1746 if (g_tls_connection_gnutls_is_dtls (gnutls))
1748 read_source = g_datagram_based_create_source (priv->base_socket, G_IO_IN, NULL);
1749 g_source_set_callback (read_source, (GSourceFunc)read_datagram_based_cb,
1754 read_source = g_pollable_input_stream_create_source (priv->base_istream, NULL);
1755 g_source_set_callback (read_source, (GSourceFunc)read_pollable_cb,
1759 g_source_attach (read_source, ctx);
1760 g_source_attach (timeout_source, ctx);
1762 while (!read_done && !timed_out)
1763 g_main_context_iteration (ctx, TRUE);
1765 g_source_destroy (read_source);
1766 g_source_destroy (timeout_source);
1768 g_main_context_unref (ctx);
1769 g_source_unref (read_source);
1770 g_source_unref (timeout_source);
1772 /* If @read_source was dispatched due to cancellation, the resulting error
1773 * will be handled in g_tls_connection_gnutls_pull_func(). */
1774 if (g_tls_connection_gnutls_base_check (gnutls, G_IO_IN) ||
1775 g_cancellable_is_cancelled (priv->read_cancellable))
1782 static GTlsCertificate *
1783 get_peer_certificate_from_session (GTlsConnectionGnutls *gnutls)
1785 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1786 const gnutls_datum_t *certs;
1787 GTlsCertificateGnutls *chain;
1788 unsigned int num_certs;
1790 certs = gnutls_certificate_get_peers (priv->session, &num_certs);
1791 if (!certs || !num_certs)
1794 chain = g_tls_certificate_gnutls_build_chain (certs, num_certs, GNUTLS_X509_FMT_DER);
1798 return G_TLS_CERTIFICATE (chain);
1801 static GTlsCertificateFlags
1802 verify_peer_certificate (GTlsConnectionGnutls *gnutls,
1803 GTlsCertificate *peer_certificate)
1805 GTlsConnection *conn = G_TLS_CONNECTION (gnutls);
1806 GSocketConnectable *peer_identity;
1807 GTlsDatabase *database;
1808 GTlsCertificateFlags errors;
1811 is_client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
1814 peer_identity = NULL;
1815 else if (!g_tls_connection_gnutls_is_dtls (gnutls))
1816 peer_identity = g_tls_client_connection_get_server_identity (G_TLS_CLIENT_CONNECTION (gnutls));
1818 peer_identity = g_dtls_client_connection_get_server_identity (G_DTLS_CLIENT_CONNECTION (gnutls));
1822 database = g_tls_connection_get_database (conn);
1823 if (database == NULL)
1825 errors |= G_TLS_CERTIFICATE_UNKNOWN_CA;
1826 errors |= g_tls_certificate_verify (peer_certificate, peer_identity, NULL);
1830 GError *error = NULL;
1832 errors |= g_tls_database_verify_chain (database, peer_certificate,
1834 G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER :
1835 G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT,
1837 g_tls_connection_get_interaction (conn),
1838 G_TLS_DATABASE_VERIFY_NONE,
1842 g_warning ("failure verifying certificate chain: %s",
1844 g_assert (errors != 0);
1845 g_clear_error (&error);
1853 update_peer_certificate_and_compute_errors (GTlsConnectionGnutls *gnutls)
1855 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1857 /* This function must be called from the handshake context thread
1858 * (probably the main thread, NOT the handshake thread) because it
1859 * emits notifies that are application-visible.
1861 * verify_certificate_mutex should be locked.
1863 g_assert (priv->handshake_context);
1864 g_assert (g_main_context_is_owner (priv->handshake_context));
1866 g_clear_object (&priv->peer_certificate);
1867 priv->peer_certificate_errors = 0;
1869 if (gnutls_certificate_type_get (priv->session) == GNUTLS_CRT_X509)
1871 priv->peer_certificate = get_peer_certificate_from_session (gnutls);
1872 if (priv->peer_certificate)
1873 priv->peer_certificate_errors = verify_peer_certificate (gnutls, priv->peer_certificate);
1876 g_object_notify (G_OBJECT (gnutls), "peer-certificate");
1877 g_object_notify (G_OBJECT (gnutls), "peer-certificate-errors");
1881 accept_or_reject_peer_certificate (gpointer user_data)
1883 GTlsConnectionGnutls *gnutls = user_data;
1884 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1885 gboolean accepted = FALSE;
1887 g_assert (g_main_context_is_owner (priv->handshake_context));
1889 g_mutex_lock (&priv->verify_certificate_mutex);
1891 update_peer_certificate_and_compute_errors (gnutls);
1893 if (G_IS_TLS_CLIENT_CONNECTION (gnutls) && priv->peer_certificate != NULL)
1895 GTlsCertificateFlags validation_flags;
1897 if (!g_tls_connection_gnutls_is_dtls (gnutls))
1899 g_tls_client_connection_get_validation_flags (G_TLS_CLIENT_CONNECTION (gnutls));
1902 g_dtls_client_connection_get_validation_flags (G_DTLS_CLIENT_CONNECTION (gnutls));
1904 if ((priv->peer_certificate_errors & validation_flags) == 0)
1910 g_main_context_pop_thread_default (priv->handshake_context);
1911 accepted = g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls),
1912 priv->peer_certificate,
1913 priv->peer_certificate_errors);
1914 g_main_context_push_thread_default (priv->handshake_context);
1917 priv->peer_certificate_accepted = accepted;
1919 /* This has to be the very last statement before signaling the
1920 * condition variable because otherwise the code could spuriously
1921 * wakeup and continue before we are done here.
1923 priv->peer_certificate_examined = TRUE;
1925 g_cond_signal (&priv->verify_certificate_condition);
1926 g_mutex_unlock (&priv->verify_certificate_mutex);
1928 g_object_notify (G_OBJECT (gnutls), "peer-certificate");
1929 g_object_notify (G_OBJECT (gnutls), "peer-certificate-errors");
1931 return G_SOURCE_REMOVE;
1935 verify_certificate_cb (gnutls_session_t session)
1937 GTlsConnectionGnutls *gnutls = gnutls_session_get_ptr (session);
1938 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1941 g_mutex_lock (&priv->verify_certificate_mutex);
1942 priv->peer_certificate_examined = FALSE;
1943 priv->peer_certificate_accepted = FALSE;
1944 g_mutex_unlock (&priv->verify_certificate_mutex);
1946 /* Invoke the callback on the handshake context's thread. This is
1947 * necessary because we need to ensure the accept-certificate signal
1948 * is emitted on the original thread.
1950 g_assert (priv->handshake_context);
1951 g_main_context_invoke (priv->handshake_context, accept_or_reject_peer_certificate, gnutls);
1953 /* We'll block the handshake thread until the original thread has
1954 * decided whether to accept the certificate.
1956 g_mutex_lock (&priv->verify_certificate_mutex);
1957 while (!priv->peer_certificate_examined)
1958 g_cond_wait (&priv->verify_certificate_condition, &priv->verify_certificate_mutex);
1959 accepted = priv->peer_certificate_accepted;
1960 g_mutex_unlock (&priv->verify_certificate_mutex);
1962 /* Return 0 for the handshake to continue, non-zero to terminate. */
1967 handshake_thread (GTask *task,
1970 GCancellable *cancellable)
1972 GTlsConnectionGnutls *gnutls = object;
1973 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1974 GError *error = NULL;
1979 /* A timeout, in microseconds, must be provided as a gint64* task_data. */
1980 g_assert (task_data != NULL);
1982 timeout = *((gint64 *)task_data);
1983 start_time = g_get_monotonic_time ();
1984 priv->started_handshake = FALSE;
1986 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE,
1987 timeout, cancellable, &error))
1989 g_task_return_error (task, error);
1993 g_clear_error (&priv->handshake_error);
1995 if (priv->ever_handshaked && !priv->implicit_handshake)
1997 if (priv->rehandshake_mode != G_TLS_REHANDSHAKE_UNSAFELY &&
1998 !gnutls_safe_renegotiation_status (priv->session))
2000 g_task_return_new_error (task, G_TLS_ERROR, G_TLS_ERROR_MISC,
2001 _("Peer does not support safe renegotiation"));
2005 if (!G_IS_TLS_CLIENT_CONNECTION (gnutls))
2007 /* Adjust the timeout for the next operation in the sequence. */
2010 unsigned int timeout_ms;
2012 timeout -= (g_get_monotonic_time () - start_time);
2016 /* Convert from microseconds to milliseconds, but ensure the timeout
2017 * remains positive. */
2018 timeout_ms = (timeout + 999) / 1000;
2020 gnutls_handshake_set_timeout (priv->session, timeout_ms);
2021 gnutls_dtls_set_timeouts (priv->session, 1000 /* default */,
2025 BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, timeout, cancellable);
2026 ret = gnutls_rehandshake (priv->session);
2027 END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret,
2028 _("Error performing TLS handshake"), &error);
2032 g_task_return_error (task, error);
2038 priv->started_handshake = TRUE;
2040 if (!priv->ever_handshaked)
2041 g_tls_connection_gnutls_set_handshake_priority (gnutls);
2043 /* Adjust the timeout for the next operation in the sequence. */
2046 unsigned int timeout_ms;
2048 timeout -= (g_get_monotonic_time () - start_time);
2052 /* Convert from microseconds to milliseconds, but ensure the timeout
2053 * remains positive. */
2054 timeout_ms = (timeout + 999) / 1000;
2056 gnutls_handshake_set_timeout (priv->session, timeout_ms);
2057 gnutls_dtls_set_timeouts (priv->session, 1000 /* default */,
2061 BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, timeout, cancellable);
2062 ret = gnutls_handshake (priv->session);
2063 if (ret == GNUTLS_E_GOT_APPLICATION_DATA)
2067 /* Got app data while waiting for rehandshake; buffer it and try again */
2068 ret = gnutls_record_recv (priv->session, buf, sizeof (buf));
2071 if (!priv->app_data_buf)
2072 priv->app_data_buf = g_byte_array_new ();
2073 g_byte_array_append (priv->app_data_buf, buf, ret);
2074 ret = GNUTLS_E_AGAIN;
2077 END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret,
2078 _("Error performing TLS handshake"), &error);
2080 /* This calls the finish_handshake code of GTlsClientConnectionGnutls
2081 * or GTlsServerConnectionGnutls. It has nothing to do with
2082 * GTlsConnectionGnutls's own finish_handshake function, which still
2083 * needs to be called at this point.
2085 G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->finish_handshake (gnutls, &error);
2089 g_task_return_error (task, error);
2093 priv->ever_handshaked = TRUE;
2094 g_task_return_boolean (task, TRUE);
2099 begin_handshake (GTlsConnectionGnutls *gnutls)
2101 #if GLIB_CHECK_VERSION(2, 60, 0)
2102 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2104 #if ENABLE(TIZEN_PERFORMANCE_TEST_LOG)
2105 HWCLOCK_LOG("[BGN] gnutls_verify_peer");
2108 if (priv->advertised_protocols)
2110 gnutls_datum_t *protocols;
2113 n_protos = g_strv_length (priv->advertised_protocols);
2114 protocols = g_new (gnutls_datum_t, n_protos);
2115 for (i = 0; priv->advertised_protocols[i]; i++)
2117 protocols[i].size = strlen (priv->advertised_protocols[i]);
2118 protocols[i].data = g_memdup (priv->advertised_protocols[i], protocols[i].size);
2120 gnutls_alpn_set_protocols (priv->session, protocols, n_protos, 0);
2125 #if ENABLE(TIZEN_PERFORMANCE_TEST_LOG)
2126 HWCLOCK_LOG("[END] gnutls_verify_peer");
2129 G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->begin_handshake (gnutls);
2132 #if GLIB_CHECK_VERSION(2, 60, 0)
2134 update_negotiated_protocol (GTlsConnectionGnutls *gnutls)
2136 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2137 gchar *orig_negotiated_protocol;
2138 gnutls_datum_t protocol;
2141 * Preserve the prior negotiated protocol before clearing it
2143 orig_negotiated_protocol = g_steal_pointer (&priv->negotiated_protocol);
2146 if (gnutls_alpn_get_selected_protocol (priv->session, &protocol) == 0 && protocol.size > 0)
2147 priv->negotiated_protocol = g_strndup ((gchar *)protocol.data, protocol.size);
2150 * Notify only if the negotiated protocol changed
2152 if (g_strcmp0 (orig_negotiated_protocol, priv->negotiated_protocol) != 0)
2153 g_object_notify (G_OBJECT (gnutls), "negotiated-protocol");
2155 g_free (orig_negotiated_protocol);
2160 finish_handshake (GTlsConnectionGnutls *gnutls,
2164 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2165 g_assert (error != NULL);
2167 if (gnutls_session_is_resumed (priv->session))
2169 /* Because this session was resumed, we skipped certificate
2170 * verification on this handshake, so we missed our earlier
2171 * chance to set peer_certificate and peer_certificate_errors.
2172 * Do so here instead.
2174 * The certificate has already been accepted, so we don't do
2175 * anything with the result here.
2177 g_mutex_lock (&priv->verify_certificate_mutex);
2178 update_peer_certificate_and_compute_errors (gnutls);
2179 priv->peer_certificate_examined = TRUE;
2180 priv->peer_certificate_accepted = TRUE;
2181 g_mutex_unlock (&priv->verify_certificate_mutex);
2184 if (g_task_propagate_boolean (task, error) &&
2185 priv->peer_certificate && !priv->peer_certificate_accepted)
2187 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
2188 _("Unacceptable TLS certificate"));
2191 #if GLIB_CHECK_VERSION(2, 60, 0)
2192 if (!*error && priv->advertised_protocols)
2193 update_negotiated_protocol (gnutls);
2196 if (*error && priv->started_handshake)
2197 priv->handshake_error = g_error_copy (*error);
2199 return (*error == NULL);
2203 sync_handshake_thread_completed (GObject *object,
2204 GAsyncResult *result,
2207 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
2208 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2210 g_assert (g_main_context_is_owner (priv->handshake_context));
2212 g_mutex_lock (&priv->op_mutex);
2213 priv->sync_handshake_completed = TRUE;
2214 g_mutex_unlock (&priv->op_mutex);
2216 g_main_context_wakeup (priv->handshake_context);
2220 crank_sync_handshake_context (GTlsConnectionGnutls *gnutls,
2221 GCancellable *cancellable)
2223 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2225 /* need_finish_handshake will be set inside sync_handshake_thread_completed(),
2226 * which should only ever be invoked while iterating the handshake context
2227 * here. So need_finish_handshake should only change on this thread.
2229 g_mutex_lock (&priv->op_mutex);
2230 priv->sync_handshake_completed = FALSE;
2231 while (!priv->sync_handshake_completed && !g_cancellable_is_cancelled (cancellable))
2233 g_mutex_unlock (&priv->op_mutex);
2234 g_main_context_iteration (priv->handshake_context, TRUE);
2235 g_mutex_lock (&priv->op_mutex);
2237 g_mutex_unlock (&priv->op_mutex);
2241 g_tls_connection_gnutls_handshake (GTlsConnection *conn,
2242 GCancellable *cancellable,
2245 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (conn);
2246 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2249 gint64 *timeout = NULL;
2250 GError *my_error = NULL;
2252 g_assert (priv->handshake_context == NULL);
2253 priv->handshake_context = g_main_context_new ();
2255 g_main_context_push_thread_default (priv->handshake_context);
2257 begin_handshake (gnutls);
2259 task = g_task_new (conn, cancellable, sync_handshake_thread_completed, NULL);
2260 g_task_set_source_tag (task, g_tls_connection_gnutls_handshake);
2261 g_task_set_return_on_cancel (task, TRUE);
2263 timeout = g_new0 (gint64, 1);
2264 *timeout = -1; /* blocking */
2265 g_task_set_task_data (task, timeout, g_free);
2267 g_task_run_in_thread (task, handshake_thread);
2268 crank_sync_handshake_context (gnutls, cancellable);
2270 success = finish_handshake (gnutls, task, &my_error);
2272 g_main_context_pop_thread_default (priv->handshake_context);
2273 g_clear_pointer (&priv->handshake_context, g_main_context_unref);
2274 g_object_unref (task);
2276 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
2279 g_propagate_error (error, my_error);
2284 g_tls_connection_gnutls_dtls_handshake (GDtlsConnection *conn,
2285 GCancellable *cancellable,
2288 return g_tls_connection_gnutls_handshake (G_TLS_CONNECTION (conn),
2289 cancellable, error);
2292 /* In the async version we use two GTasks; one to run handshake_thread() and
2293 * then call handshake_thread_completed(), and a second to call the caller's
2294 * original callback after we call finish_handshake().
2298 handshake_thread_completed (GObject *object,
2299 GAsyncResult *result,
2302 GTask *caller_task = user_data;
2303 GTlsConnectionGnutls *gnutls = g_task_get_source_object (caller_task);
2304 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2305 GError *error = NULL;
2306 gboolean need_finish_handshake, success;
2308 g_mutex_lock (&priv->op_mutex);
2309 if (priv->need_finish_handshake)
2311 need_finish_handshake = TRUE;
2312 priv->need_finish_handshake = FALSE;
2315 need_finish_handshake = FALSE;
2316 g_mutex_unlock (&priv->op_mutex);
2318 if (need_finish_handshake)
2320 success = finish_handshake (gnutls, G_TASK (result), &error);
2322 g_task_return_boolean (caller_task, TRUE);
2324 g_task_return_error (caller_task, error);
2326 else if (priv->handshake_error)
2327 g_task_return_error (caller_task, g_error_copy (priv->handshake_error));
2329 g_task_return_boolean (caller_task, TRUE);
2331 g_clear_pointer (&priv->handshake_context, g_main_context_unref);
2332 g_object_unref (caller_task);
2336 async_handshake_thread (GTask *task,
2339 GCancellable *cancellable)
2341 GTlsConnectionGnutls *gnutls = object;
2342 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2344 handshake_thread (task, object, task_data, cancellable);
2346 g_mutex_lock (&priv->op_mutex);
2347 priv->need_finish_handshake = TRUE;
2348 /* yield_op will clear handshaking too, but we don't want the
2349 * connection to be briefly "handshaking && need_finish_handshake"
2350 * after we unlock the mutex.
2352 priv->handshaking = FALSE;
2353 g_mutex_unlock (&priv->op_mutex);
2355 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
2359 g_tls_connection_gnutls_handshake_async (GTlsConnection *conn,
2361 GCancellable *cancellable,
2362 GAsyncReadyCallback callback,
2365 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (G_TLS_CONNECTION_GNUTLS (conn));
2366 GTask *thread_task, *caller_task;
2367 gint64 *timeout = NULL;
2369 g_assert (!priv->handshake_context);
2370 priv->handshake_context = g_main_context_ref_thread_default ();
2372 caller_task = g_task_new (conn, cancellable, callback, user_data);
2373 g_task_set_source_tag (caller_task, g_tls_connection_gnutls_handshake_async);
2374 g_task_set_priority (caller_task, io_priority);
2376 begin_handshake (G_TLS_CONNECTION_GNUTLS (conn));
2378 thread_task = g_task_new (conn, cancellable,
2379 handshake_thread_completed, caller_task);
2380 g_task_set_source_tag (thread_task, g_tls_connection_gnutls_handshake_async);
2381 g_task_set_priority (thread_task, io_priority);
2383 timeout = g_new0 (gint64, 1);
2384 *timeout = -1; /* blocking */
2385 g_task_set_task_data (thread_task, timeout, g_free);
2387 g_task_run_in_thread (thread_task, async_handshake_thread);
2388 g_object_unref (thread_task);
2392 g_tls_connection_gnutls_handshake_finish (GTlsConnection *conn,
2393 GAsyncResult *result,
2396 g_return_val_if_fail (g_task_is_valid (result, conn), FALSE);
2398 return g_task_propagate_boolean (G_TASK (result), error);
2402 g_tls_connection_gnutls_dtls_handshake_async (GDtlsConnection *conn,
2404 GCancellable *cancellable,
2405 GAsyncReadyCallback callback,
2408 g_tls_connection_gnutls_handshake_async (G_TLS_CONNECTION (conn), io_priority,
2409 cancellable, callback, user_data);
2413 g_tls_connection_gnutls_dtls_handshake_finish (GDtlsConnection *conn,
2414 GAsyncResult *result,
2417 return g_tls_connection_gnutls_handshake_finish (G_TLS_CONNECTION (conn),
2422 do_implicit_handshake (GTlsConnectionGnutls *gnutls,
2424 GCancellable *cancellable,
2427 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2428 gint64 *thread_timeout = NULL;
2430 /* We have op_mutex */
2432 g_assert (priv->handshake_context == NULL);
2435 priv->handshake_context = g_main_context_new ();
2436 g_main_context_push_thread_default (priv->handshake_context);
2440 priv->handshake_context = g_main_context_ref_thread_default ();
2443 g_assert (priv->implicit_handshake == NULL);
2444 priv->implicit_handshake = g_task_new (gnutls, cancellable,
2445 timeout ? sync_handshake_thread_completed : NULL,
2447 g_task_set_source_tag (priv->implicit_handshake,
2448 do_implicit_handshake);
2450 thread_timeout = g_new0 (gint64, 1);
2451 g_task_set_task_data (priv->implicit_handshake,
2452 thread_timeout, g_free);
2454 begin_handshake (gnutls);
2458 GError *my_error = NULL;
2461 /* In the blocking case, run the handshake operation synchronously in
2462 * another thread, and delegate handling the timeout to that thread; it
2463 * should return G_IO_ERROR_TIMED_OUT iff (timeout > 0) and the operation
2464 * times out. If (timeout < 0) it should block indefinitely until the
2465 * operation is complete or errors. */
2466 *thread_timeout = timeout;
2468 g_mutex_unlock (&priv->op_mutex);
2470 g_task_set_return_on_cancel (priv->implicit_handshake, TRUE);
2471 g_task_run_in_thread (priv->implicit_handshake, handshake_thread);
2473 crank_sync_handshake_context (gnutls, cancellable);
2475 success = finish_handshake (gnutls,
2476 priv->implicit_handshake,
2479 g_main_context_pop_thread_default (priv->handshake_context);
2480 g_clear_pointer (&priv->handshake_context, g_main_context_unref);
2481 g_clear_object (&priv->implicit_handshake);
2483 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
2485 g_mutex_lock (&priv->op_mutex);
2488 g_propagate_error (error, my_error);
2493 /* In the non-blocking case, start the asynchronous handshake operation
2494 * and return EWOULDBLOCK to the caller, who will handle polling for
2495 * completion of the handshake and whatever operation they actually cared
2496 * about. Run the actual operation as blocking in its thread. */
2497 *thread_timeout = -1; /* blocking */
2499 g_task_run_in_thread (priv->implicit_handshake,
2500 async_handshake_thread);
2502 /* Intentionally not translated because this is not a fatal error to be
2503 * presented to the user, and to avoid this showing up in profiling. */
2504 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, "Operation would block");
2510 g_tls_connection_gnutls_read (GTlsConnectionGnutls *gnutls,
2514 GCancellable *cancellable,
2517 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2520 if (priv->app_data_buf && !priv->handshaking)
2522 ret = MIN (count, priv->app_data_buf->len);
2523 memcpy (buffer, priv->app_data_buf->data, ret);
2524 if (ret == priv->app_data_buf->len)
2525 g_clear_pointer (&priv->app_data_buf, g_byte_array_unref);
2527 g_byte_array_remove_range (priv->app_data_buf, 0, ret);
2532 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ,
2533 timeout, cancellable, error))
2536 BEGIN_GNUTLS_IO (gnutls, G_IO_IN, timeout, cancellable);
2537 ret = gnutls_record_recv (priv->session, buffer, count);
2538 END_GNUTLS_IO (gnutls, G_IO_IN, ret, _("Error reading data from TLS socket"), error);
2540 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ);
2544 else if (ret == GNUTLS_E_REHANDSHAKE)
2551 input_vectors_from_gnutls_datum_t (GInputVector *vectors,
2553 const gnutls_datum_t *datum)
2558 /* Copy into the receive vectors. */
2559 for (i = 0; i < num_vectors && total < datum->size; i++)
2562 GInputVector *vec = &vectors[i];
2564 count = MIN (vec->size, datum->size - total);
2566 memcpy (vec->buffer, datum->data + total, count);
2570 g_assert (total <= datum->size);
2576 g_tls_connection_gnutls_read_message (GTlsConnectionGnutls *gnutls,
2577 GInputVector *vectors,
2580 GCancellable *cancellable,
2583 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2586 gnutls_packet_t packet = { 0, };
2588 /* Copy data out of the app data buffer first. */
2589 if (priv->app_data_buf && !priv->handshaking)
2593 for (i = 0; i < num_vectors; i++)
2596 GInputVector *vec = &vectors[i];
2598 count = MIN (vec->size, priv->app_data_buf->len);
2601 memcpy (vec->buffer, priv->app_data_buf->data, count);
2602 if (count == priv->app_data_buf->len)
2603 g_clear_pointer (&priv->app_data_buf, g_byte_array_unref);
2605 g_byte_array_remove_range (priv->app_data_buf, 0, count);
2612 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ,
2613 timeout, cancellable, error))
2616 BEGIN_GNUTLS_IO (gnutls, G_IO_IN, timeout, cancellable);
2618 /* Receive the entire datagram (zero-copy). */
2619 ret = gnutls_record_recv_packet (priv->session, &packet);
2623 gnutls_datum_t data = { 0, };
2625 gnutls_packet_get (packet, &data, NULL);
2626 ret = input_vectors_from_gnutls_datum_t (vectors, num_vectors, &data);
2627 gnutls_packet_deinit (packet);
2630 END_GNUTLS_IO (gnutls, G_IO_IN, ret, _("Error reading data from TLS socket"), error);
2632 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ);
2636 else if (ret == GNUTLS_E_REHANDSHAKE)
2643 g_tls_connection_gnutls_receive_messages (GDatagramBased *datagram_based,
2644 GInputMessage *messages,
2648 GCancellable *cancellable,
2651 GTlsConnectionGnutls *gnutls;
2653 GError *child_error = NULL;
2655 gnutls = G_TLS_CONNECTION_GNUTLS (datagram_based);
2657 if (flags != G_SOCKET_MSG_NONE)
2659 g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
2660 _("Receive flags are not supported"));
2664 for (i = 0; i < num_messages && child_error == NULL; i++)
2666 GInputMessage *message = &messages[i];
2667 gssize n_bytes_read;
2669 n_bytes_read = g_tls_connection_gnutls_read_message (gnutls,
2671 message->num_vectors,
2676 if (message->address != NULL)
2677 *message->address = NULL;
2678 message->flags = G_SOCKET_MSG_NONE;
2679 if (message->control_messages != NULL)
2680 *message->control_messages = NULL;
2681 message->num_control_messages = 0;
2683 if (n_bytes_read > 0)
2685 message->bytes_received = n_bytes_read;
2687 else if (n_bytes_read == 0)
2693 (g_error_matches (child_error,
2694 G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) ||
2695 g_error_matches (child_error,
2696 G_IO_ERROR, G_IO_ERROR_TIMED_OUT)))
2698 /* Blocked or timed out after receiving some messages successfully. */
2699 g_clear_error (&child_error);
2704 /* Error, including G_IO_ERROR_WOULD_BLOCK or G_IO_ERROR_TIMED_OUT on
2705 * the first message; or G_IO_ERROR_CANCELLED at any time. */
2710 if (child_error != NULL)
2712 g_propagate_error (error, child_error);
2720 g_tls_connection_gnutls_write (GTlsConnectionGnutls *gnutls,
2724 GCancellable *cancellable,
2727 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2731 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE,
2732 timeout, cancellable, error))
2735 BEGIN_GNUTLS_IO (gnutls, G_IO_OUT, timeout, cancellable);
2736 ret = gnutls_record_send (priv->session, buffer, count);
2737 END_GNUTLS_IO (gnutls, G_IO_OUT, ret, _("Error writing data to TLS socket"), error);
2739 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE);
2743 else if (ret == GNUTLS_E_REHANDSHAKE)
2750 g_tls_connection_gnutls_write_message (GTlsConnectionGnutls *gnutls,
2751 GOutputVector *vectors,
2754 GCancellable *cancellable,
2757 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2760 gsize total_message_size;
2763 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE,
2764 timeout, cancellable, error))
2767 /* Calculate the total message size and check it’s not too big. */
2768 for (i = 0, total_message_size = 0; i < num_vectors; i++)
2769 total_message_size += vectors[i].size;
2771 if (priv->base_socket != NULL &&
2772 gnutls_dtls_get_data_mtu (priv->session) < total_message_size)
2775 guint mtu = gnutls_dtls_get_data_mtu (priv->session);
2777 ret = GNUTLS_E_LARGE_PACKET;
2778 message = g_strdup_printf("%s %s",
2779 ngettext ("Message of size %lu byte is too large for DTLS connection",
2780 "Message of size %lu bytes is too large for DTLS connection", total_message_size),
2781 ngettext ("(maximum is %u byte)", "(maximum is %u bytes)", mtu));
2782 g_set_error (error, G_IO_ERROR, G_IO_ERROR_MESSAGE_TOO_LARGE,
2791 /* Queue up the data from all the vectors. */
2792 gnutls_record_cork (priv->session);
2794 for (i = 0; i < num_vectors; i++)
2796 ret = gnutls_record_send (priv->session,
2797 vectors[i].buffer, vectors[i].size);
2799 if (ret < 0 || ret < vectors[i].size)
2801 /* Uncork to restore state, then bail. The peer will receive a
2802 * truncated datagram. */
2807 BEGIN_GNUTLS_IO (gnutls, G_IO_OUT, timeout, cancellable);
2808 ret = gnutls_record_uncork (priv->session, 0 /* flags */);
2809 END_GNUTLS_IO (gnutls, G_IO_OUT, ret, _("Error writing data to TLS socket"), error);
2812 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE);
2816 else if (ret == GNUTLS_E_REHANDSHAKE)
2823 g_tls_connection_gnutls_send_messages (GDatagramBased *datagram_based,
2824 GOutputMessage *messages,
2828 GCancellable *cancellable,
2831 GTlsConnectionGnutls *gnutls;
2833 GError *child_error = NULL;
2835 gnutls = G_TLS_CONNECTION_GNUTLS (datagram_based);
2837 if (flags != G_SOCKET_MSG_NONE)
2839 g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
2840 _("Send flags are not supported"));
2844 for (i = 0; i < num_messages && child_error == NULL; i++)
2846 GOutputMessage *message = &messages[i];
2847 gssize n_bytes_sent;
2849 n_bytes_sent = g_tls_connection_gnutls_write_message (gnutls,
2851 message->num_vectors,
2856 if (n_bytes_sent >= 0)
2858 message->bytes_sent = n_bytes_sent;
2861 (g_error_matches (child_error,
2862 G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) ||
2863 g_error_matches (child_error,
2864 G_IO_ERROR, G_IO_ERROR_TIMED_OUT)))
2866 /* Blocked or timed out after sending some messages successfully. */
2867 g_clear_error (&child_error);
2872 /* Error, including G_IO_ERROR_WOULD_BLOCK or G_IO_ERROR_TIMED_OUT
2873 * on the first message; or G_IO_ERROR_CANCELLED at any time. */
2878 if (child_error != NULL)
2880 g_propagate_error (error, child_error);
2887 static GInputStream *
2888 g_tls_connection_gnutls_get_input_stream (GIOStream *stream)
2890 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
2891 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2893 return priv->tls_istream;
2896 static GOutputStream *
2897 g_tls_connection_gnutls_get_output_stream (GIOStream *stream)
2899 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
2900 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2902 return priv->tls_ostream;
2906 g_tls_connection_gnutls_close_internal (GIOStream *stream,
2907 GTlsDirection direction,
2909 GCancellable *cancellable,
2912 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
2913 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2914 GTlsConnectionGnutlsOp op;
2915 gboolean success = TRUE;
2917 GError *gnutls_error = NULL, *stream_error = NULL;
2919 /* This can be called from g_io_stream_close(), g_input_stream_close(),
2920 * g_output_stream_close() or g_tls_connection_close(). In all cases, we only
2921 * do the gnutls_bye() for writing. The difference is how we set the flags on
2922 * this class and how the underlying stream is closed.
2925 g_return_val_if_fail (direction != G_TLS_DIRECTION_NONE, FALSE);
2927 if (direction == G_TLS_DIRECTION_BOTH)
2928 op = G_TLS_CONNECTION_GNUTLS_OP_CLOSE_BOTH;
2929 else if (direction == G_TLS_DIRECTION_READ)
2930 op = G_TLS_CONNECTION_GNUTLS_OP_CLOSE_READ;
2932 op = G_TLS_CONNECTION_GNUTLS_OP_CLOSE_WRITE;
2934 if (!claim_op (gnutls, op, timeout, cancellable, error))
2937 if (priv->ever_handshaked && !priv->write_closed &&
2938 direction & G_TLS_DIRECTION_WRITE)
2940 BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, timeout, cancellable);
2941 ret = gnutls_bye (priv->session, GNUTLS_SHUT_WR);
2942 END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret,
2943 _("Error performing TLS close"), &gnutls_error);
2945 priv->write_closed = TRUE;
2948 if (!priv->read_closed && direction & G_TLS_DIRECTION_READ)
2949 priv->read_closed = TRUE;
2951 /* Close the underlying streams. Do this even if the gnutls_bye() call failed,
2952 * as the parent GIOStream will have set its internal closed flag and hence
2953 * this implementation will never be called again. */
2954 if (priv->base_io_stream != NULL)
2956 if (direction == G_TLS_DIRECTION_BOTH)
2957 success = g_io_stream_close (priv->base_io_stream,
2958 cancellable, &stream_error);
2959 else if (direction & G_TLS_DIRECTION_READ)
2960 success = g_input_stream_close (g_io_stream_get_input_stream (priv->base_io_stream),
2961 cancellable, &stream_error);
2962 else if (direction & G_TLS_DIRECTION_WRITE)
2963 success = g_output_stream_close (g_io_stream_get_output_stream (priv->base_io_stream),
2964 cancellable, &stream_error);
2966 else if (g_tls_connection_gnutls_is_dtls (gnutls))
2968 /* We do not close underlying #GDatagramBaseds. There is no
2969 * g_datagram_based_close() method since different datagram-based
2970 * protocols vary wildly in how they close. */
2975 g_assert_not_reached ();
2978 yield_op (gnutls, op);
2980 /* Propagate errors. */
2983 g_propagate_error (error, gnutls_error);
2984 g_clear_error (&stream_error);
2988 g_propagate_error (error, stream_error);
2989 g_clear_error (&gnutls_error);
2992 return success && (ret == 0);
2996 g_tls_connection_gnutls_close (GIOStream *stream,
2997 GCancellable *cancellable,
3000 return g_tls_connection_gnutls_close_internal (stream,
3001 G_TLS_DIRECTION_BOTH,
3003 cancellable, error);
3007 g_tls_connection_gnutls_dtls_shutdown (GDtlsConnection *conn,
3008 gboolean shutdown_read,
3009 gboolean shutdown_write,
3010 GCancellable *cancellable,
3013 GTlsDirection direction = G_TLS_DIRECTION_NONE;
3016 direction |= G_TLS_DIRECTION_READ;
3018 direction |= G_TLS_DIRECTION_WRITE;
3020 return g_tls_connection_gnutls_close_internal (G_IO_STREAM (conn),
3023 cancellable, error);
3026 /* We do async close as synchronous-in-a-thread so we don't need to
3027 * implement G_IO_IN/G_IO_OUT flip-flopping just for this one case
3028 * (since handshakes are also done synchronously now).
3031 close_thread (GTask *task,
3034 GCancellable *cancellable)
3036 GIOStream *stream = object;
3037 GTlsDirection direction;
3038 GError *error = NULL;
3040 direction = GPOINTER_TO_INT (g_task_get_task_data (task));
3042 if (!g_tls_connection_gnutls_close_internal (stream, direction,
3044 cancellable, &error))
3045 g_task_return_error (task, error);
3047 g_task_return_boolean (task, TRUE);
3051 g_tls_connection_gnutls_close_internal_async (GIOStream *stream,
3052 GTlsDirection direction,
3054 GCancellable *cancellable,
3055 GAsyncReadyCallback callback,
3060 task = g_task_new (stream, cancellable, callback, user_data);
3061 g_task_set_source_tag (task, g_tls_connection_gnutls_close_internal_async);
3062 g_task_set_priority (task, io_priority);
3063 g_task_set_task_data (task, GINT_TO_POINTER (direction), NULL);
3064 g_task_run_in_thread (task, close_thread);
3065 g_object_unref (task);
3069 g_tls_connection_gnutls_close_async (GIOStream *stream,
3071 GCancellable *cancellable,
3072 GAsyncReadyCallback callback,
3075 g_tls_connection_gnutls_close_internal_async (stream, G_TLS_DIRECTION_BOTH,
3076 io_priority, cancellable,
3077 callback, user_data);
3081 g_tls_connection_gnutls_close_finish (GIOStream *stream,
3082 GAsyncResult *result,
3085 g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
3087 return g_task_propagate_boolean (G_TASK (result), error);
3091 g_tls_connection_gnutls_dtls_shutdown_async (GDtlsConnection *conn,
3092 gboolean shutdown_read,
3093 gboolean shutdown_write,
3095 GCancellable *cancellable,
3096 GAsyncReadyCallback callback,
3099 GTlsDirection direction = G_TLS_DIRECTION_NONE;
3102 direction |= G_TLS_DIRECTION_READ;
3104 direction |= G_TLS_DIRECTION_WRITE;
3106 g_tls_connection_gnutls_close_internal_async (G_IO_STREAM (conn), direction,
3107 io_priority, cancellable,
3108 callback, user_data);
3112 g_tls_connection_gnutls_dtls_shutdown_finish (GDtlsConnection *conn,
3113 GAsyncResult *result,
3116 g_return_val_if_fail (g_task_is_valid (result, conn), FALSE);
3118 return g_task_propagate_boolean (G_TASK (result), error);
3121 #if GLIB_CHECK_VERSION(2, 60, 0)
3123 g_tls_connection_gnutls_dtls_set_advertised_protocols (GDtlsConnection *conn,
3124 const gchar * const *protocols)
3126 g_object_set (conn, "advertised-protocols", protocols, NULL);
3130 g_tls_connection_gnutls_dtls_get_negotiated_protocol (GDtlsConnection *conn)
3132 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (conn);
3133 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
3135 return priv->negotiated_protocol;
3140 g_tls_connection_gnutls_class_init (GTlsConnectionGnutlsClass *klass)
3142 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
3143 GTlsConnectionClass *connection_class = G_TLS_CONNECTION_CLASS (klass);
3144 GIOStreamClass *iostream_class = G_IO_STREAM_CLASS (klass);
3146 gobject_class->get_property = g_tls_connection_gnutls_get_property;
3147 gobject_class->set_property = g_tls_connection_gnutls_set_property;
3148 gobject_class->finalize = g_tls_connection_gnutls_finalize;
3150 connection_class->handshake = g_tls_connection_gnutls_handshake;
3151 connection_class->handshake_async = g_tls_connection_gnutls_handshake_async;
3152 connection_class->handshake_finish = g_tls_connection_gnutls_handshake_finish;
3154 iostream_class->get_input_stream = g_tls_connection_gnutls_get_input_stream;
3155 iostream_class->get_output_stream = g_tls_connection_gnutls_get_output_stream;
3156 iostream_class->close_fn = g_tls_connection_gnutls_close;
3157 iostream_class->close_async = g_tls_connection_gnutls_close_async;
3158 iostream_class->close_finish = g_tls_connection_gnutls_close_finish;
3160 /* For GTlsConnection and GDtlsConnection: */
3161 g_object_class_override_property (gobject_class, PROP_BASE_IO_STREAM, "base-io-stream");
3162 g_object_class_override_property (gobject_class, PROP_BASE_SOCKET, "base-socket");
3163 g_object_class_override_property (gobject_class, PROP_REQUIRE_CLOSE_NOTIFY, "require-close-notify");
3164 g_object_class_override_property (gobject_class, PROP_REHANDSHAKE_MODE, "rehandshake-mode");
3165 g_object_class_override_property (gobject_class, PROP_USE_SYSTEM_CERTDB, "use-system-certdb");
3166 g_object_class_override_property (gobject_class, PROP_DATABASE, "database");
3167 g_object_class_override_property (gobject_class, PROP_CERTIFICATE, "certificate");
3168 g_object_class_override_property (gobject_class, PROP_INTERACTION, "interaction");
3169 g_object_class_override_property (gobject_class, PROP_PEER_CERTIFICATE, "peer-certificate");
3170 g_object_class_override_property (gobject_class, PROP_PEER_CERTIFICATE_ERRORS, "peer-certificate-errors");
3171 #if GLIB_CHECK_VERSION(2, 60, 0)
3172 g_object_class_override_property (gobject_class, PROP_ADVERTISED_PROTOCOLS, "advertised-protocols");
3173 g_object_class_override_property (gobject_class, PROP_NEGOTIATED_PROTOCOL, "negotiated-protocol");
3178 g_tls_connection_gnutls_initable_iface_init (GInitableIface *iface)
3180 iface->init = g_tls_connection_gnutls_initable_init;
3184 g_tls_connection_gnutls_dtls_connection_iface_init (GDtlsConnectionInterface *iface)
3186 iface->handshake = g_tls_connection_gnutls_dtls_handshake;
3187 iface->handshake_async = g_tls_connection_gnutls_dtls_handshake_async;
3188 iface->handshake_finish = g_tls_connection_gnutls_dtls_handshake_finish;
3189 iface->shutdown = g_tls_connection_gnutls_dtls_shutdown;
3190 iface->shutdown_async = g_tls_connection_gnutls_dtls_shutdown_async;
3191 iface->shutdown_finish = g_tls_connection_gnutls_dtls_shutdown_finish;
3192 #if GLIB_CHECK_VERSION(2, 60, 0)
3193 iface->set_advertised_protocols = g_tls_connection_gnutls_dtls_set_advertised_protocols;
3194 iface->get_negotiated_protocol = g_tls_connection_gnutls_dtls_get_negotiated_protocol;
3199 g_tls_connection_gnutls_datagram_based_iface_init (GDatagramBasedInterface *iface)
3201 iface->receive_messages = g_tls_connection_gnutls_receive_messages;
3202 iface->send_messages = g_tls_connection_gnutls_send_messages;
3203 iface->create_source = g_tls_connection_gnutls_dtls_create_source;
3204 iface->condition_check = g_tls_connection_gnutls_condition_check;
3205 iface->condition_wait = g_tls_connection_gnutls_condition_wait;
3209 g_tls_connection_gnutls_request_certificate (GTlsConnectionGnutls *gnutls,
3212 GTlsInteractionResult res = G_TLS_INTERACTION_UNHANDLED;
3213 GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
3214 GTlsInteraction *interaction;
3215 GTlsConnection *conn;
3217 g_return_val_if_fail (G_IS_TLS_CONNECTION_GNUTLS (gnutls), FALSE);
3219 conn = G_TLS_CONNECTION (gnutls);
3221 interaction = g_tls_connection_get_interaction (conn);
3225 res = g_tls_interaction_invoke_request_certificate (interaction, conn, 0,
3226 priv->read_cancellable, error);
3227 return res != G_TLS_INTERACTION_FAILED;
3231 GTLS_DEBUG (gpointer gnutls,
3232 const char *message,
3235 char *result = NULL;
3238 g_assert (G_IS_TLS_CONNECTION (gnutls));
3241 va_start (args, message);
3243 ret = g_vasprintf (&result, message, args);
3246 if (G_IS_TLS_CLIENT_CONNECTION (gnutls))
3247 g_printf ("CLIENT %p: ", gnutls);
3248 else if (G_IS_TLS_SERVER_CONNECTION (gnutls))
3249 g_printf ("SERVER %p: ", gnutls);
3251 g_assert_not_reached ();
3253 g_printf ("%s\n", result);