729c66cf1bc8e2f1aa87ba45754d6fcee25f3d00
[platform/upstream/glib-networking.git] / tls / gnutls / gtlsconnection-gnutls.c
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /*
3  * GIO - GLib Input, Output and Streaming Library
4  *
5  * Copyright 2009 Red Hat, Inc
6  * Copyright 2015, 2016 Collabora, Ltd.
7  *
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.
12  *
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.
17  *
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/>.
21  *
22  * In addition, when the library is used with OpenSSL, a special
23  * exception applies. Refer to the LICENSE_EXCEPTION file for details.
24  */
25
26 #include "config.h"
27 #include "glib.h"
28
29 #include <errno.h>
30 #include <stdarg.h>
31 #include <gnutls/dtls.h>
32 #include <gnutls/gnutls.h>
33 #include <gnutls/x509.h>
34
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"
42
43 #ifdef G_OS_WIN32
44 #include <winsock2.h>
45 #include <winerror.h>
46
47 /* It isn’t clear whether MinGW always defines EMSGSIZE. */
48 #ifndef EMSGSIZE
49 #define EMSGSIZE WSAEMSGSIZE
50 #endif
51 #endif
52
53 #include <glib/gi18n-lib.h>
54 #include <glib/gprintf.h>
55
56 /*
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
61  * construction time.
62  *
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.
68  *
69  * This abstract class implements a lot of interfaces:
70  *  • Derived from GTlsConnection (itself from GIOStream), for TLS and streaming
71  *    communications.
72  *  • Implements GDtlsConnection and GDatagramBased, for DTLS and datagram
73  *    communications.
74  *  • Implements GInitable for failable GnuTLS initialisation.
75  *
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
83  */
84
85 #include "TIZEN.h"
86
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
91 #endif
92 #define HWCLOCK_LOG(s)  {const char *str=s; prctl(PR_TASK_PERF_USER_TRACE, str, strlen(str));}
93 #endif
94
95 static ssize_t g_tls_connection_gnutls_push_func (gnutls_transport_ptr_t  transport_data,
96                                                   const void             *buf,
97                                                   size_t                  buflen);
98 static ssize_t g_tls_connection_gnutls_vec_push_func (gnutls_transport_ptr_t  transport_data,
99                                                       const giovec_t         *iov,
100                                                       int                     iovcnt);
101 static ssize_t g_tls_connection_gnutls_pull_func (gnutls_transport_ptr_t  transport_data,
102                                                   void                   *buf,
103                                                   size_t                  buflen);
104
105 static int     g_tls_connection_gnutls_pull_timeout_func (gnutls_transport_ptr_t transport_data,
106                                                           unsigned int           ms);
107
108
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,
112                                                              GError         **error);
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);
115
116 static void g_tls_connection_gnutls_init_priorities (void);
117
118 static int verify_certificate_cb (gnutls_session_t session);
119
120 static gboolean do_implicit_handshake (GTlsConnectionGnutls  *gnutls,
121                                        gint64                 timeout,
122                                        GCancellable          *cancellable,
123                                        GError               **error);
124 static gboolean finish_handshake (GTlsConnectionGnutls  *gnutls,
125                                   GTask                 *task,
126                                   GError               **error);
127
128 enum
129 {
130   PROP_0,
131   /* For this class: */
132   PROP_BASE_IO_STREAM,
133   PROP_BASE_SOCKET,
134   /* For GTlsConnection and GDtlsConnection: */
135   PROP_REQUIRE_CLOSE_NOTIFY,
136   PROP_REHANDSHAKE_MODE,
137   PROP_USE_SYSTEM_CERTDB,
138   PROP_DATABASE,
139   PROP_CERTIFICATE,
140   PROP_INTERACTION,
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,
146 #endif
147 };
148
149 typedef struct
150 {
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.
159    *
160    * Then the GTlsConnectionGnutls also has tls_istream and tls_ostream which
161    * wrap the aforementioned base streams with a TLS session.
162    *
163    * When operating in datagram mode, none of these are used.
164    */
165   GIOStream *base_io_stream;
166   GPollableInputStream *base_istream;
167   GPollableOutputStream *base_ostream;
168   GInputStream *tls_istream;
169   GOutputStream *tls_ostream;
170
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
174    * the other streams.
175    */
176   GDatagramBased *base_socket;
177
178   gnutls_certificate_credentials_t creds;
179   gnutls_session_t session;
180
181   GTlsCertificate *certificate, *peer_certificate;
182   GTlsCertificateFlags peer_certificate_errors;
183
184   GMutex verify_certificate_mutex;
185   GCond verify_certificate_condition;
186   gboolean peer_certificate_accepted;
187   gboolean peer_certificate_examined;
188
189   gboolean require_close_notify;
190   GTlsRehandshakeMode rehandshake_mode;
191   gboolean is_system_certdb;
192   GTlsDatabase *database;
193   gboolean database_is_unset;
194
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*).
199    *
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...
209    *
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.
215    */
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;
222
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;
227
228   GTlsInteraction *interaction;
229   gchar *interaction_id;
230
231 #if GLIB_CHECK_VERSION(2, 60, 0)
232   gchar **advertised_protocols;
233   gchar *negotiated_protocol;
234 #endif
235
236   GMutex        op_mutex;
237   GCancellable *waiting_for_op;
238
239   gboolean      reading;
240   gint64        read_timeout;
241   GError       *read_error;
242   GCancellable *read_cancellable;
243
244   gboolean      writing;
245   gint64        write_timeout;
246   GError       *write_error;
247   GCancellable *write_cancellable;
248 } GTlsConnectionGnutlsPrivate;
249
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 ();
259                                   );
260
261 static gint unique_interaction_id = 0;
262
263 static void
264 g_tls_connection_gnutls_init (GTlsConnectionGnutls *gnutls)
265 {
266   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
267   gint unique_id;
268
269   gnutls_certificate_allocate_credentials (&priv->creds);
270
271   g_mutex_init (&priv->verify_certificate_mutex);
272   g_cond_init (&priv->verify_certificate_condition);
273
274   priv->need_handshake = TRUE;
275
276   priv->database_is_unset = TRUE;
277   priv->is_system_certdb = TRUE;
278
279   unique_id = g_atomic_int_add (&unique_interaction_id, 1);
280   priv->interaction_id = g_strdup_printf ("gtls:%d", unique_id);
281
282   priv->waiting_for_op = g_cancellable_new ();
283   g_cancellable_cancel (priv->waiting_for_op);
284   g_mutex_init (&priv->op_mutex);
285 }
286
287 /* First field is "fallback", second is "allow unsafe rehandshaking" */
288 static gnutls_priority_t priorities[2][2];
289
290 #if ENABLE(TIZEN_TV_UPDATE_DEFAULT_PRIORITY)
291 #define DEFAULT_BASE_PRIORITY "NORMAL:%COMPAT:!VERS-SSL3.0:%LATEST_RECORD_VERSION"
292 #else
293 /* TODO: Get rid of this in favor of gnutls_set_default_priority_append()
294  * when upgrading to GnuTLS 3.6.3.
295  */
296 #define DEFAULT_BASE_PRIORITY "NORMAL:%COMPAT"
297 #endif
298
299 static void
300 g_tls_connection_gnutls_init_priorities (void)
301 {
302   const gchar *base_priority;
303   gchar *fallback_priority, *unsafe_rehandshake_priority, *fallback_unsafe_rehandshake_priority;
304   const guint *protos;
305   int ret, i, nprotos, fallback_proto;
306
307   base_priority = g_getenv ("G_TLS_GNUTLS_PRIORITY");
308   if (!base_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)
312     {
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);
317     }
318
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);
323
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++)
328     {
329       if (protos[i] < fallback_proto)
330         fallback_proto = protos[i];
331     }
332   if (fallback_proto == G_MAXUINT)
333     {
334       g_warning ("All GNUTLS protocol versions disabled?");
335       fallback_priority = g_strdup (base_priority);
336     }
337   else
338     {
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));
344     }
345   fallback_unsafe_rehandshake_priority = g_strdup_printf ("%s:%%UNSAFE_RENEGOTIATION",
346                                                           fallback_priority);
347
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);
354 }
355
356 static void
357 g_tls_connection_gnutls_set_handshake_priority (GTlsConnectionGnutls *gnutls)
358 {
359   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
360   gboolean fallback, unsafe_rehandshake;
361
362   if (G_IS_TLS_CLIENT_CONNECTION (gnutls))
363     {
364 #if defined(__GNUC__)
365 #pragma GCC diagnostic push
366 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
367 #endif
368       fallback = g_tls_client_connection_get_use_ssl3 (G_TLS_CLIENT_CONNECTION (gnutls));
369 #if defined(__GNUC__)
370 #pragma GCC diagnostic pop
371 #endif
372     }
373   else
374     fallback = FALSE;
375   unsafe_rehandshake = (priv->rehandshake_mode == G_TLS_REHANDSHAKE_UNSAFELY);
376   gnutls_priority_set (priv->session,
377                        priorities[fallback][unsafe_rehandshake]);
378 }
379
380 static gboolean
381 g_tls_connection_gnutls_is_dtls (GTlsConnectionGnutls *gnutls)
382 {
383   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
384
385   return (priv->base_socket != NULL);
386 }
387
388 static gboolean
389 g_tls_connection_gnutls_initable_init (GInitable     *initable,
390                                        GCancellable  *cancellable,
391                                        GError       **error)
392 {
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;
397   int status;
398
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);
403
404   /* Check whether to use DTLS or TLS. */
405   if (g_tls_connection_gnutls_is_dtls (gnutls))
406     flags |= GNUTLS_DATAGRAM;
407
408   gnutls_init (&priv->session, flags);
409
410   gnutls_session_set_ptr (priv->session, gnutls);
411   gnutls_session_set_verify_function (priv->session, verify_certificate_cb);
412
413   status = gnutls_credentials_set (priv->session,
414                                    GNUTLS_CRD_CERTIFICATE,
415                                    priv->creds);
416   if (status != 0)
417     {
418       g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
419                    _("Could not create TLS connection: %s"),
420                    gnutls_strerror (status));
421       return FALSE;
422     }
423
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);
431
432   /* GDatagramBased supports vectored I/O; GPollableOutputStream does not. */
433   if (priv->base_socket != NULL)
434     {
435       gnutls_transport_set_vec_push_function (priv->session,
436                                               g_tls_connection_gnutls_vec_push_func);
437     }
438
439   /* Set reasonable MTU */
440   if (flags & GNUTLS_DATAGRAM)
441     gnutls_dtls_set_mtu (priv->session, 1400);
442
443   /* Create output streams if operating in streaming mode. */
444   if (!(flags & GNUTLS_DATAGRAM))
445     {
446       priv->tls_istream = g_tls_input_stream_gnutls_new (gnutls);
447       priv->tls_ostream = g_tls_output_stream_gnutls_new (gnutls);
448     }
449
450   return TRUE;
451 }
452
453 static void
454 g_tls_connection_gnutls_finalize (GObject *object)
455 {
456   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
457   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
458
459   g_clear_object (&priv->base_io_stream);
460   g_clear_object (&priv->base_socket);
461
462   g_clear_object (&priv->tls_istream);
463   g_clear_object (&priv->tls_ostream);
464
465   if (priv->session)
466     gnutls_deinit (priv->session);
467   if (priv->creds)
468     gnutls_certificate_free_credentials (priv->creds);
469
470   g_clear_object (&priv->database);
471   g_clear_object (&priv->certificate);
472   g_clear_object (&priv->peer_certificate);
473
474   g_mutex_clear (&priv->verify_certificate_mutex);
475   g_cond_clear (&priv->verify_certificate_condition);
476
477
478   g_clear_pointer (&priv->app_data_buf, g_byte_array_unref);
479
480   g_free (priv->interaction_id);
481   g_clear_object (&priv->interaction);
482
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);
486 #endif
487
488   g_clear_error (&priv->handshake_error);
489   g_clear_error (&priv->read_error);
490   g_clear_error (&priv->write_error);
491
492   g_clear_pointer (&priv->handshake_context, g_main_context_unref);
493
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
496    * in future. */
497   g_clear_object (&priv->implicit_handshake);
498
499   g_clear_object (&priv->read_cancellable);
500   g_clear_object (&priv->write_cancellable);
501
502   g_clear_object (&priv->waiting_for_op);
503   g_mutex_clear (&priv->op_mutex);
504
505   G_OBJECT_CLASS (g_tls_connection_gnutls_parent_class)->finalize (object);
506 }
507
508 static void
509 g_tls_connection_gnutls_get_property (GObject    *object,
510                                       guint       prop_id,
511                                       GValue     *value,
512                                       GParamSpec *pspec)
513 {
514   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
515   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
516   GTlsBackend *backend;
517
518   switch (prop_id)
519     {
520     case PROP_BASE_IO_STREAM:
521       g_value_set_object (value, priv->base_io_stream);
522       break;
523
524     case PROP_BASE_SOCKET:
525       g_value_set_object (value, priv->base_socket);
526       break;
527
528     case PROP_REQUIRE_CLOSE_NOTIFY:
529       g_value_set_boolean (value, priv->require_close_notify);
530       break;
531
532     case PROP_REHANDSHAKE_MODE:
533       g_value_set_enum (value, priv->rehandshake_mode);
534       break;
535
536     case PROP_USE_SYSTEM_CERTDB:
537       g_value_set_boolean (value, priv->is_system_certdb);
538       break;
539
540     case PROP_DATABASE:
541       if (priv->database_is_unset)
542         {
543           backend = g_tls_backend_get_default ();
544           priv->database =  g_tls_backend_get_default_database (backend);
545           priv->database_is_unset = FALSE;
546         }
547       g_value_set_object (value, priv->database);
548       break;
549
550     case PROP_CERTIFICATE:
551       g_value_set_object (value, priv->certificate);
552       break;
553
554     case PROP_INTERACTION:
555       g_value_set_object (value, priv->interaction);
556       break;
557
558     case PROP_PEER_CERTIFICATE:
559       g_value_set_object (value, priv->peer_certificate);
560       break;
561
562     case PROP_PEER_CERTIFICATE_ERRORS:
563       g_value_set_flags (value, priv->peer_certificate_errors);
564       break;
565
566 #if GLIB_CHECK_VERSION(2, 60, 0)
567     case PROP_ADVERTISED_PROTOCOLS:
568       g_value_set_boxed (value, priv->advertised_protocols);
569       break;
570
571     case PROP_NEGOTIATED_PROTOCOL:
572       g_value_set_string (value, priv->negotiated_protocol);
573       break;
574 #endif
575
576     default:
577       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
578     }
579 }
580
581 static void
582 g_tls_connection_gnutls_set_property (GObject      *object,
583                                       guint         prop_id,
584                                       const GValue *value,
585                                       GParamSpec   *pspec)
586 {
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;
593
594   switch (prop_id)
595     {
596     case PROP_BASE_IO_STREAM:
597       g_assert (g_value_get_object (value) == NULL ||
598                 priv->base_socket == NULL);
599
600       if (priv->base_io_stream)
601         {
602           g_object_unref (priv->base_io_stream);
603           priv->base_istream = NULL;
604           priv->base_ostream = NULL;
605         }
606       priv->base_io_stream = g_value_dup_object (value);
607       if (!priv->base_io_stream)
608         return;
609
610       istream = g_io_stream_get_input_stream (priv->base_io_stream);
611       ostream = g_io_stream_get_output_stream (priv->base_io_stream);
612
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);
619       break;
620
621     case PROP_BASE_SOCKET:
622       g_assert (g_value_get_object (value) == NULL ||
623                 priv->base_io_stream == NULL);
624
625       g_clear_object (&priv->base_socket);
626       priv->base_socket = g_value_dup_object (value);
627       break;
628
629     case PROP_REQUIRE_CLOSE_NOTIFY:
630       priv->require_close_notify = g_value_get_boolean (value);
631       break;
632
633     case PROP_REHANDSHAKE_MODE:
634       priv->rehandshake_mode = g_value_get_enum (value);
635       break;
636
637     case PROP_USE_SYSTEM_CERTDB:
638       system_certdb = g_value_get_boolean (value);
639       if (system_certdb != priv->is_system_certdb)
640         {
641           g_clear_object (&priv->database);
642           if (system_certdb)
643             {
644               backend = g_tls_backend_get_default ();
645               priv->database = g_tls_backend_get_default_database (backend);
646             }
647           priv->is_system_certdb = system_certdb;
648           priv->database_is_unset = FALSE;
649         }
650       break;
651
652     case PROP_DATABASE:
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;
657       break;
658
659     case PROP_CERTIFICATE:
660       if (priv->certificate)
661         g_object_unref (priv->certificate);
662       priv->certificate = g_value_dup_object (value);
663       break;
664
665     case PROP_INTERACTION:
666       g_clear_object (&priv->interaction);
667       priv->interaction = g_value_dup_object (value);
668       break;
669
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);
674       break;
675 #endif
676
677     default:
678       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
679     }
680 }
681
682 gnutls_certificate_credentials_t
683 g_tls_connection_gnutls_get_credentials (GTlsConnectionGnutls *gnutls)
684 {
685   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
686
687   return priv->creds;
688 }
689
690 gnutls_session_t
691 g_tls_connection_gnutls_get_session (GTlsConnectionGnutls *gnutls)
692 {
693   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
694
695   return priv->session;
696 }
697
698 void
699 g_tls_connection_gnutls_get_certificate (GTlsConnectionGnutls  *gnutls,
700                                          gnutls_pcert_st      **pcert,
701                                          unsigned int          *pcert_length,
702                                          gnutls_privkey_t      *pkey)
703 {
704   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
705   GTlsCertificate *cert;
706
707   cert = g_tls_connection_get_certificate (G_TLS_CONNECTION (gnutls));
708
709   if (cert)
710     {
711       g_tls_certificate_gnutls_copy (G_TLS_CERTIFICATE_GNUTLS (cert),
712                                      priv->interaction_id,
713                                      pcert, pcert_length, pkey);
714     }
715   else
716     {
717       *pcert = NULL;
718       *pcert_length = 0;
719       *pkey = NULL;
720     }
721 }
722
723 typedef enum {
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;
731
732 static gboolean
733 claim_op (GTlsConnectionGnutls    *gnutls,
734           GTlsConnectionGnutlsOp   op,
735           gint64                   timeout,
736           GCancellable            *cancellable,
737           GError                 **error)
738 {
739   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
740
741  try_again:
742   if (g_cancellable_set_error_if_cancelled (cancellable, error))
743     return FALSE;
744
745   g_mutex_lock (&priv->op_mutex);
746
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)))
753     {
754       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
755                            _("Connection is closed"));
756       g_mutex_unlock (&priv->op_mutex);
757       return FALSE;
758     }
759
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)
764     {
765       if (error)
766         *error = g_error_copy (priv->handshake_error);
767       g_mutex_unlock (&priv->op_mutex);
768       return FALSE;
769     }
770
771   if (op != G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE)
772     {
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)
777         {
778           priv->need_handshake = FALSE;
779           priv->handshaking = TRUE;
780           if (!do_implicit_handshake (gnutls, timeout, cancellable, error))
781             {
782               g_mutex_unlock (&priv->op_mutex);
783               return FALSE;
784             }
785         }
786
787       if (priv->need_finish_handshake &&
788           priv->implicit_handshake)
789         {
790           GError *my_error = NULL;
791           gboolean success;
792
793           priv->need_finish_handshake = FALSE;
794
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);
800
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)))
805             {
806               g_propagate_error (error, my_error);
807               g_mutex_unlock (&priv->op_mutex);
808               return FALSE;
809             }
810
811           g_clear_error (&my_error);
812         }
813     }
814
815   if (priv->handshaking &&
816       timeout != 0 &&
817       g_main_context_is_owner (priv->handshake_context))
818     {
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.
825        */
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);
828       return FALSE;
829     }
830
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))
834     {
835       GPollFD fds[2];
836       int nfds;
837       gint64 start_time;
838       gint result = 1;  /* if the loop is never entered, it’s as if we cancelled early */
839
840       g_cancellable_reset (priv->waiting_for_op);
841
842       g_mutex_unlock (&priv->op_mutex);
843
844       if (timeout == 0)
845         {
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");
849           return FALSE;
850         }
851
852       g_cancellable_make_pollfd (priv->waiting_for_op, &fds[0]);
853       if (g_cancellable_make_pollfd (cancellable, &fds[1]))
854         nfds = 2;
855       else
856         nfds = 1;
857
858       /* Convert from microseconds to milliseconds. */
859       if (timeout != -1)
860         timeout = timeout / 1000;
861
862       /* Poll until cancellation or the timeout is reached. */
863       start_time = g_get_monotonic_time ();
864
865       while (!g_cancellable_is_cancelled (priv->waiting_for_op) &&
866              !g_cancellable_is_cancelled (cancellable))
867         {
868           result = g_poll (fds, nfds, timeout);
869
870           if (result == 0)
871             break;
872           if (result != -1 || errno != EINTR)
873             continue;
874
875           if (timeout != -1)
876             {
877               timeout -= (g_get_monotonic_time () - start_time) / 1000;
878               if (timeout < 0)
879                 timeout = 0;
880             }
881         }
882
883       if (nfds > 1)
884         g_cancellable_release_fd (cancellable);
885
886       if (result == 0)
887         {
888           g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
889                                _("Socket I/O timed out"));
890           return FALSE;
891         }
892
893       goto try_again;
894     }
895
896   if (op == G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE)
897     {
898       priv->handshaking = TRUE;
899       priv->need_handshake = FALSE;
900     }
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;
907
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;
912
913   g_mutex_unlock (&priv->op_mutex);
914   return TRUE;
915 }
916
917 static void
918 yield_op (GTlsConnectionGnutls   *gnutls,
919           GTlsConnectionGnutlsOp  op)
920 {
921   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
922
923   g_mutex_lock (&priv->op_mutex);
924
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;
933
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;
938
939   g_cancellable_cancel (priv->waiting_for_op);
940   g_mutex_unlock (&priv->op_mutex);
941 }
942
943 static void
944 begin_gnutls_io (GTlsConnectionGnutls  *gnutls,
945                  GIOCondition           direction,
946                  gint64                 timeout,
947                  GCancellable          *cancellable)
948 {
949   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
950
951   g_assert (direction & (G_IO_IN | G_IO_OUT));
952
953   if (direction & G_IO_IN)
954     {
955       priv->read_timeout = timeout;
956       priv->read_cancellable = cancellable;
957       g_clear_error (&priv->read_error);
958     }
959
960   if (direction & G_IO_OUT)
961     {
962       priv->write_timeout = timeout;
963       priv->write_cancellable = cancellable;
964       g_clear_error (&priv->write_error);
965     }
966 }
967
968 static int
969 end_gnutls_io (GTlsConnectionGnutls  *gnutls,
970                GIOCondition           direction,
971                int                    status,
972                GError               **error,
973                const char            *err_prefix);
974
975 static int
976 end_gnutls_io (GTlsConnectionGnutls  *gnutls,
977                GIOCondition           direction,
978                int                    status,
979                GError               **error,
980                const char            *err_prefix)
981 {
982   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
983   GError *my_error = NULL;
984
985   g_assert (direction & (G_IO_IN | G_IO_OUT));
986   g_assert (!error || !*error);
987
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().
993    */
994   if (status == GNUTLS_E_AGAIN ||
995       status == GNUTLS_E_WARNING_ALERT_RECEIVED)
996     return GNUTLS_E_AGAIN;
997
998   if (direction & G_IO_IN)
999     {
1000       priv->read_cancellable = NULL;
1001       if (status < 0)
1002         {
1003           my_error = priv->read_error;
1004           priv->read_error = NULL;
1005         }
1006       else
1007         g_clear_error (&priv->read_error);
1008     }
1009   if (direction & G_IO_OUT)
1010     {
1011       priv->write_cancellable = NULL;
1012       if (status < 0 && !my_error)
1013         {
1014           my_error = priv->write_error;
1015           priv->write_error = NULL;
1016         }
1017       else
1018         g_clear_error (&priv->write_error);
1019     }
1020
1021   if (status >= 0)
1022     return status;
1023
1024   if (priv->handshaking && !priv->ever_handshaked)
1025     {
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)
1031         {
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;
1036         }
1037     }
1038
1039   if (my_error)
1040     {
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);
1045       return status;
1046     }
1047   else if (status == GNUTLS_E_REHANDSHAKE)
1048     {
1049       if (priv->rehandshake_mode == G_TLS_REHANDSHAKE_NEVER)
1050         {
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;
1054         }
1055
1056       g_mutex_lock (&priv->op_mutex);
1057       if (!priv->handshaking)
1058         priv->need_handshake = TRUE;
1059       g_mutex_unlock (&priv->op_mutex);
1060       return status;
1061     }
1062   else if (status == GNUTLS_E_PREMATURE_TERMINATION)
1063     {
1064       if (priv->handshaking && !priv->ever_handshaked)
1065         {
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;
1069         }
1070       else if (priv->require_close_notify)
1071         {
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);
1075           return status;
1076         }
1077       else
1078         return 0;
1079     }
1080   else if (status == GNUTLS_E_NO_CERTIFICATE_FOUND)
1081     {
1082       g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED,
1083                            _("TLS connection peer did not send a certificate"));
1084       return status;
1085     }
1086   else if (status == GNUTLS_E_CERTIFICATE_ERROR)
1087     {
1088       g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
1089                    _("Unacceptable TLS certificate"));
1090       return status;
1091     }
1092   else if (status == GNUTLS_E_FATAL_ALERT_RECEIVED)
1093     {
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)));
1097       return status;
1098     }
1099   else if (status == GNUTLS_E_INAPPROPRIATE_FALLBACK)
1100     {
1101       g_set_error_literal (error, G_TLS_ERROR,
1102 #if GLIB_CHECK_VERSION(2, 60, 0)
1103                            G_TLS_ERROR_INAPPROPRIATE_FALLBACK,
1104 #else
1105                            G_TLS_ERROR_MISC,
1106 #endif
1107                            _("Protocol version downgrade attack detected"));
1108       return status;
1109     }
1110   else if (status == GNUTLS_E_LARGE_PACKET)
1111     {
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);
1116       return status;
1117     }
1118   else if (status == GNUTLS_E_TIMEDOUT)
1119     {
1120       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
1121                            _("The operation timed out"));
1122       return status;
1123     }
1124
1125   if (error)
1126     {
1127       *error = g_error_new (G_TLS_ERROR, G_TLS_ERROR_MISC, "%s: %s",
1128           err_prefix, gnutls_strerror (status));
1129     }
1130   return status;
1131 }
1132
1133 #define BEGIN_GNUTLS_IO(gnutls, direction, timeout, cancellable)        \
1134   begin_gnutls_io (gnutls, direction, timeout, cancellable);            \
1135   do {
1136
1137 #define END_GNUTLS_IO(gnutls, direction, ret, errmsg, err)              \
1138   } while ((ret = end_gnutls_io (gnutls, direction, ret, err, errmsg)) == GNUTLS_E_AGAIN);
1139
1140 /* Checks whether the underlying base stream or GDatagramBased meets
1141  * @condition. */
1142 static gboolean
1143 g_tls_connection_gnutls_base_check (GTlsConnectionGnutls  *gnutls,
1144                                     GIOCondition           condition)
1145 {
1146   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1147
1148   if (g_tls_connection_gnutls_is_dtls (gnutls))
1149     return g_datagram_based_condition_check (priv->base_socket,
1150                                              condition);
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);
1155   else
1156     g_assert_not_reached ();
1157 }
1158
1159 /* Checks whether the (D)TLS stream meets @condition; not the underlying base
1160  * stream or GDatagramBased. */
1161 gboolean
1162 g_tls_connection_gnutls_check (GTlsConnectionGnutls  *gnutls,
1163                                GIOCondition           condition)
1164 {
1165   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1166
1167   /* Racy, but worst case is that we just get WOULD_BLOCK back */
1168   if (priv->need_finish_handshake)
1169     return TRUE;
1170
1171   /* If a handshake or close is in progress, then tls_istream and
1172    * tls_ostream are blocked, regardless of the base stream status.
1173    */
1174   if (priv->handshaking)
1175     return FALSE;
1176
1177   if (((condition & G_IO_IN) && priv->read_closing) ||
1178       ((condition & G_IO_OUT) && priv->write_closing))
1179     return FALSE;
1180
1181   /* Defer to the base stream or GDatagramBased. */
1182   return g_tls_connection_gnutls_base_check (gnutls, condition);
1183 }
1184
1185 typedef struct {
1186   GSource               source;
1187
1188   GTlsConnectionGnutls *gnutls;
1189   /* Either a GDatagramBased (datagram mode), or a GPollableInputStream or
1190    * GPollableOutputStream (streaming mode):
1191    */
1192   GObject              *base;
1193
1194   GSource              *child_source;
1195   GIOCondition          condition;
1196
1197   gboolean              io_waiting;
1198   gboolean              op_waiting;
1199 } GTlsConnectionGnutlsSource;
1200
1201 static gboolean
1202 gnutls_source_prepare (GSource *source,
1203                        gint    *timeout)
1204 {
1205   *timeout = -1;
1206   return FALSE;
1207 }
1208
1209 static gboolean
1210 gnutls_source_check (GSource *source)
1211 {
1212   return FALSE;
1213 }
1214
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.) */
1218 static gboolean
1219 dummy_callback (gpointer data)
1220 {
1221   return G_SOURCE_CONTINUE;
1222 }
1223
1224 static void
1225 gnutls_source_sync (GTlsConnectionGnutlsSource *gnutls_source)
1226 {
1227   GTlsConnectionGnutls *gnutls = gnutls_source->gnutls;
1228   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1229   gboolean io_waiting, op_waiting;
1230
1231   /* Was the source destroyed earlier in this main context iteration? */
1232   if (g_source_is_destroyed ((GSource *)gnutls_source))
1233     return;
1234
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))
1239     op_waiting = TRUE;
1240   else
1241     op_waiting = FALSE;
1242
1243   if (!op_waiting && !priv->need_handshake &&
1244       !priv->need_finish_handshake)
1245     io_waiting = TRUE;
1246   else
1247     io_waiting = FALSE;
1248   g_mutex_unlock (&priv->op_mutex);
1249
1250   if (op_waiting == gnutls_source->op_waiting &&
1251       io_waiting == gnutls_source->io_waiting)
1252     return;
1253   gnutls_source->op_waiting = op_waiting;
1254   gnutls_source->io_waiting = io_waiting;
1255
1256   if (gnutls_source->child_source)
1257     {
1258       g_source_remove_child_source ((GSource *)gnutls_source,
1259                                     gnutls_source->child_source);
1260       g_source_unref (gnutls_source->child_source);
1261     }
1262
1263   if (op_waiting)
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);
1271   else
1272     gnutls_source->child_source = g_timeout_source_new (0);
1273
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);
1276 }
1277
1278 static gboolean
1279 gnutls_source_dispatch (GSource     *source,
1280                         GSourceFunc  callback,
1281                         gpointer     user_data)
1282 {
1283   GDatagramBasedSourceFunc datagram_based_func = (GDatagramBasedSourceFunc)callback;
1284   GPollableSourceFunc pollable_func = (GPollableSourceFunc)callback;
1285   GTlsConnectionGnutlsSource *gnutls_source = (GTlsConnectionGnutlsSource *)source;
1286   gboolean ret;
1287
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);
1291   else
1292     ret = (*pollable_func) (gnutls_source->base, user_data);
1293
1294   if (ret)
1295     gnutls_source_sync (gnutls_source);
1296
1297   return ret;
1298 }
1299
1300 static void
1301 gnutls_source_finalize (GSource *source)
1302 {
1303   GTlsConnectionGnutlsSource *gnutls_source = (GTlsConnectionGnutlsSource *)source;
1304
1305   g_object_unref (gnutls_source->gnutls);
1306   g_source_unref (gnutls_source->child_source);
1307 }
1308
1309 static gboolean
1310 g_tls_connection_gnutls_source_closure_callback (GObject  *stream,
1311                                                  gpointer  data)
1312 {
1313   GClosure *closure = data;
1314
1315   GValue param = { 0, };
1316   GValue result_value = { 0, };
1317   gboolean result;
1318
1319   g_value_init (&result_value, G_TYPE_BOOLEAN);
1320
1321   g_value_init (&param, G_TYPE_OBJECT);
1322   g_value_set_object (&param, stream);
1323
1324   g_closure_invoke (closure, &result_value, 1, &param, NULL);
1325
1326   result = g_value_get_boolean (&result_value);
1327   g_value_unset (&result_value);
1328   g_value_unset (&param);
1329
1330   return result;
1331 }
1332
1333 static gboolean
1334 g_tls_connection_gnutls_source_dtls_closure_callback (GObject  *stream,
1335                                                       GIOCondition condition,
1336                                                       gpointer  data)
1337 {
1338   GClosure *closure = data;
1339
1340   GValue param[2] = { G_VALUE_INIT, G_VALUE_INIT };
1341   GValue result_value = G_VALUE_INIT;
1342   gboolean result;
1343
1344   g_value_init (&result_value, G_TYPE_BOOLEAN);
1345
1346   g_value_init (&param[0], G_TYPE_DATAGRAM_BASED);
1347   g_value_set_object (&param[0], stream);
1348   g_value_init (&param[1], G_TYPE_IO_CONDITION);
1349   g_value_set_flags (&param[1], condition);
1350
1351   g_closure_invoke (closure, &result_value, 2, param, NULL);
1352
1353   result = g_value_get_boolean (&result_value);
1354   g_value_unset (&result_value);
1355   g_value_unset (&param[0]);
1356   g_value_unset (&param[1]);
1357
1358   return result;
1359 }
1360
1361 static GSourceFuncs gnutls_tls_source_funcs =
1362 {
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
1369 };
1370
1371 static GSourceFuncs gnutls_dtls_source_funcs =
1372 {
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
1379 };
1380
1381 GSource *
1382 g_tls_connection_gnutls_create_source (GTlsConnectionGnutls  *gnutls,
1383                                        GIOCondition           condition,
1384                                        GCancellable          *cancellable)
1385 {
1386   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1387   GSource *source, *cancellable_source;
1388   GTlsConnectionGnutlsSource *gnutls_source;
1389
1390   if (g_tls_connection_gnutls_is_dtls (gnutls))
1391     {
1392       source = g_source_new (&gnutls_dtls_source_funcs,
1393                              sizeof (GTlsConnectionGnutlsSource));
1394     }
1395   else
1396     {
1397       source = g_source_new (&gnutls_tls_source_funcs,
1398                              sizeof (GTlsConnectionGnutlsSource));
1399     }
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);
1410   else
1411     g_assert_not_reached ();
1412
1413   gnutls_source->op_waiting = (gboolean) -1;
1414   gnutls_source->io_waiting = (gboolean) -1;
1415   gnutls_source_sync (gnutls_source);
1416
1417   if (cancellable)
1418     {
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);
1423     }
1424
1425   return source;
1426 }
1427
1428 static GSource *
1429 g_tls_connection_gnutls_dtls_create_source (GDatagramBased  *datagram_based,
1430                                             GIOCondition     condition,
1431                                             GCancellable    *cancellable)
1432 {
1433   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (datagram_based);
1434
1435   return g_tls_connection_gnutls_create_source (gnutls, condition, cancellable);
1436 }
1437
1438 static GIOCondition
1439 g_tls_connection_gnutls_condition_check (GDatagramBased  *datagram_based,
1440                                          GIOCondition     condition)
1441 {
1442   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (datagram_based);
1443
1444   return (g_tls_connection_gnutls_check (gnutls, condition)) ? condition : 0;
1445 }
1446
1447 static gboolean
1448 g_tls_connection_gnutls_condition_wait (GDatagramBased  *datagram_based,
1449                                         GIOCondition     condition,
1450                                         gint64           timeout,
1451                                         GCancellable    *cancellable,
1452                                         GError         **error)
1453 {
1454   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (datagram_based);
1455   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1456   GPollFD fds[2];
1457   guint n_fds;
1458   gint result = 1;  /* if the loop is never entered, it’s as if we cancelled early */
1459   gint64 start_time;
1460
1461   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1462     return FALSE;
1463
1464   /* Convert from microseconds to milliseconds. */
1465   if (timeout != -1)
1466     timeout = timeout / 1000;
1467
1468   start_time = g_get_monotonic_time ();
1469
1470   g_cancellable_make_pollfd (priv->waiting_for_op, &fds[0]);
1471   n_fds = 1;
1472
1473   if (g_cancellable_make_pollfd (cancellable, &fds[1]))
1474     n_fds++;
1475
1476   while (!g_tls_connection_gnutls_condition_check (datagram_based, condition) &&
1477          !g_cancellable_is_cancelled (cancellable))
1478     {
1479       result = g_poll (fds, n_fds, timeout);
1480       if (result == 0)
1481         break;
1482       if (result != -1 || errno != EINTR)
1483         continue;
1484
1485       if (timeout != -1)
1486         {
1487           timeout -= (g_get_monotonic_time () - start_time) / 1000;
1488           if (timeout < 0)
1489             timeout = 0;
1490         }
1491     }
1492
1493   if (n_fds > 1)
1494     g_cancellable_release_fd (cancellable);
1495
1496   if (result == 0)
1497     {
1498       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
1499                            _("Socket I/O timed out"));
1500       return FALSE;
1501     }
1502
1503   return !g_cancellable_set_error_if_cancelled (cancellable, error);
1504 }
1505
1506 static void
1507 set_gnutls_error (GTlsConnectionGnutls *gnutls,
1508                   GError               *error)
1509 {
1510   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1511
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
1516    * that way later).
1517    */
1518
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))
1522     {
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);
1527       else
1528         gnutls_transport_set_errno (priv->session, EINTR);
1529     }
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);
1534   else
1535     gnutls_transport_set_errno (priv->session, EIO);
1536 }
1537
1538 static ssize_t
1539 g_tls_connection_gnutls_pull_func (gnutls_transport_ptr_t  transport_data,
1540                                    void                   *buf,
1541                                    size_t                  buflen)
1542 {
1543   GTlsConnectionGnutls *gnutls = transport_data;
1544   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1545   ssize_t ret;
1546
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.)
1552    */
1553   g_clear_error (&priv->read_error);
1554
1555   if (g_tls_connection_gnutls_is_dtls (gnutls))
1556     {
1557       GInputVector vector = { buf, buflen };
1558       GInputMessage message = { NULL, &vector, 1, 0, 0, NULL, NULL };
1559
1560       ret = g_datagram_based_receive_messages (priv->base_socket,
1561                                                &message, 1, 0,
1562                                                priv->handshaking ? 0 : priv->read_timeout,
1563                                                priv->read_cancellable,
1564                                                &priv->read_error);
1565
1566       if (ret > 0)
1567         ret = message.bytes_received;
1568     }
1569   else
1570     {
1571       ret = g_pollable_stream_read (G_INPUT_STREAM (priv->base_istream),
1572                                     buf, buflen,
1573                                     (priv->read_timeout != 0),
1574                                     priv->read_cancellable,
1575                                     &priv->read_error);
1576     }
1577
1578   if (ret < 0)
1579     set_gnutls_error (gnutls, priv->read_error);
1580
1581   return ret;
1582 }
1583
1584 static ssize_t
1585 g_tls_connection_gnutls_push_func (gnutls_transport_ptr_t  transport_data,
1586                                    const void             *buf,
1587                                    size_t                  buflen)
1588 {
1589   GTlsConnectionGnutls *gnutls = transport_data;
1590   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1591   ssize_t ret;
1592
1593   /* See comment in pull_func. */
1594   g_clear_error (&priv->write_error);
1595
1596   if (g_tls_connection_gnutls_is_dtls (gnutls))
1597     {
1598       GOutputVector vector = { buf, buflen };
1599       GOutputMessage message = { NULL, &vector, 1, 0, NULL, 0 };
1600
1601       ret = g_datagram_based_send_messages (priv->base_socket,
1602                                             &message, 1, 0,
1603                                             priv->write_timeout,
1604                                             priv->write_cancellable,
1605                                             &priv->write_error);
1606
1607       if (ret > 0)
1608         ret = message.bytes_sent;
1609     }
1610   else
1611     {
1612       ret = g_pollable_stream_write (G_OUTPUT_STREAM (priv->base_ostream),
1613                                      buf, buflen,
1614                                      (priv->write_timeout != 0),
1615                                      priv->write_cancellable,
1616                                      &priv->write_error);
1617     }
1618
1619   if (ret < 0)
1620     set_gnutls_error (gnutls, priv->write_error);
1621
1622   return ret;
1623 }
1624
1625 static ssize_t
1626 g_tls_connection_gnutls_vec_push_func (gnutls_transport_ptr_t  transport_data,
1627                                        const giovec_t         *iov,
1628                                        int                     iovcnt)
1629 {
1630   GTlsConnectionGnutls *gnutls = transport_data;
1631   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1632   ssize_t ret;
1633   GOutputMessage message = { NULL, };
1634   GOutputVector *vectors;
1635
1636   /* This function should only be set if we’re using base_socket. */
1637   g_assert (priv->base_socket != NULL);
1638
1639   /* See comment in pull_func. */
1640   g_clear_error (&priv->write_error);
1641
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 */
1651     {
1652       message.vectors = (GOutputVector *)iov;
1653       message.num_vectors = iovcnt;
1654     }
1655   else
1656     /* ABI is incompatible */
1657     {
1658       gint i;
1659
1660       message.vectors = g_newa (GOutputVector, iovcnt);
1661       for (i = 0; i < iovcnt; i++)
1662         {
1663           message.vectors[i].buffer = (void *)iov[i].iov_base;
1664           message.vectors[i].size = iov[i].iov_len;
1665         }
1666       message.num_vectors = iovcnt;
1667     }
1668
1669   ret = g_datagram_based_send_messages (priv->base_socket,
1670                                         &message, 1, 0,
1671                                         priv->write_timeout,
1672                                         priv->write_cancellable,
1673                                         &priv->write_error);
1674
1675   if (ret > 0)
1676     ret = message.bytes_sent;
1677   else if (ret < 0)
1678     set_gnutls_error (gnutls, priv->write_error);
1679
1680   return ret;
1681 }
1682
1683 static gboolean
1684 read_pollable_cb (GPollableInputStream *istream,
1685                   gpointer              user_data)
1686 {
1687   gboolean *read_done = user_data;
1688
1689   *read_done = TRUE;
1690
1691   return G_SOURCE_CONTINUE;
1692 }
1693
1694 static gboolean
1695 read_datagram_based_cb (GDatagramBased *datagram_based,
1696                         GIOCondition    condition,
1697                         gpointer        user_data)
1698 {
1699   gboolean *read_done = user_data;
1700
1701   *read_done = TRUE;
1702
1703   return G_SOURCE_CONTINUE;
1704 }
1705
1706 static gboolean
1707 read_timeout_cb (gpointer user_data)
1708 {
1709   gboolean *timed_out = user_data;
1710
1711   *timed_out = TRUE;
1712
1713   return G_SOURCE_REMOVE;
1714 }
1715
1716 static int
1717 g_tls_connection_gnutls_pull_timeout_func (gnutls_transport_ptr_t transport_data,
1718                                            unsigned int           ms)
1719 {
1720   GTlsConnectionGnutls *gnutls = transport_data;
1721   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1722
1723   /* Fast path. */
1724   if (g_tls_connection_gnutls_base_check (gnutls, G_IO_IN) ||
1725       g_cancellable_is_cancelled (priv->read_cancellable))
1726     return 1;
1727
1728   /* If @ms is 0, GnuTLS wants an instant response, so there’s no need to
1729    * construct and query a #GSource. */
1730   if (ms > 0)
1731     {
1732       GMainContext *ctx = NULL;
1733       GSource *read_source = NULL, *timeout_source = NULL;
1734       gboolean read_done = FALSE, timed_out = FALSE;
1735
1736       ctx = g_main_context_new ();
1737
1738       /* Create a timeout source. */
1739       timeout_source = g_timeout_source_new (ms);
1740       g_source_set_callback (timeout_source, (GSourceFunc)read_timeout_cb,
1741                              &timed_out, NULL);
1742
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))
1747         {
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,
1750                                  &read_done, NULL);
1751         }
1752       else
1753         {
1754           read_source = g_pollable_input_stream_create_source (priv->base_istream, NULL);
1755           g_source_set_callback (read_source, (GSourceFunc)read_pollable_cb,
1756                                  &read_done, NULL);
1757         }
1758
1759       g_source_attach (read_source, ctx);
1760       g_source_attach (timeout_source, ctx);
1761
1762       while (!read_done && !timed_out)
1763         g_main_context_iteration (ctx, TRUE);
1764
1765       g_source_destroy (read_source);
1766       g_source_destroy (timeout_source);
1767
1768       g_main_context_unref (ctx);
1769       g_source_unref (read_source);
1770       g_source_unref (timeout_source);
1771
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))
1776         return 1;
1777     }
1778
1779   return 0;
1780 }
1781
1782 static GTlsCertificate *
1783 get_peer_certificate_from_session (GTlsConnectionGnutls *gnutls)
1784 {
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;
1789
1790   certs = gnutls_certificate_get_peers (priv->session, &num_certs);
1791   if (!certs || !num_certs)
1792     return NULL;
1793
1794   chain = g_tls_certificate_gnutls_build_chain (certs, num_certs, GNUTLS_X509_FMT_DER);
1795   if (!chain)
1796     return NULL;
1797
1798   return G_TLS_CERTIFICATE (chain);
1799 }
1800
1801 static GTlsCertificateFlags
1802 verify_peer_certificate (GTlsConnectionGnutls *gnutls,
1803                          GTlsCertificate      *peer_certificate)
1804 {
1805   GTlsConnection *conn = G_TLS_CONNECTION (gnutls);
1806   GSocketConnectable *peer_identity;
1807   GTlsDatabase *database;
1808   GTlsCertificateFlags errors;
1809   gboolean is_client;
1810
1811   is_client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
1812
1813   if (!is_client)
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));
1817   else
1818     peer_identity = g_dtls_client_connection_get_server_identity (G_DTLS_CLIENT_CONNECTION (gnutls));
1819
1820   errors = 0;
1821
1822   database = g_tls_connection_get_database (conn);
1823   if (database == NULL)
1824     {
1825
1826 #if ENABLE(TIZEN_DLOG)
1827       TIZEN_LOGI("[Network] SSL HandShake - Unknown CA");
1828 #endif
1829
1830       errors |= G_TLS_CERTIFICATE_UNKNOWN_CA;
1831       errors |= g_tls_certificate_verify (peer_certificate, peer_identity, NULL);
1832     }
1833   else
1834     {
1835       GError *error = NULL;
1836
1837       errors |= g_tls_database_verify_chain (database, peer_certificate,
1838                                              is_client ?
1839                                              G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER :
1840                                              G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT,
1841                                              peer_identity,
1842                                              g_tls_connection_get_interaction (conn),
1843                                              G_TLS_DATABASE_VERIFY_NONE,
1844                                              NULL, &error);
1845       if (error)
1846         {
1847           g_warning ("failure verifying certificate chain: %s",
1848                      error->message);
1849           g_assert (errors != 0);
1850           g_clear_error (&error);
1851         }
1852     }
1853
1854   return errors;
1855 }
1856
1857 static void
1858 update_peer_certificate_and_compute_errors (GTlsConnectionGnutls *gnutls)
1859 {
1860   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1861
1862   /* This function must be called from the handshake context thread
1863    * (probably the main thread, NOT the handshake thread) because it
1864    * emits notifies that are application-visible.
1865    *
1866    * verify_certificate_mutex should be locked.
1867    */
1868   g_assert (priv->handshake_context);
1869   g_assert (g_main_context_is_owner (priv->handshake_context));
1870
1871   g_clear_object (&priv->peer_certificate);
1872   priv->peer_certificate_errors = 0;
1873
1874   if (gnutls_certificate_type_get (priv->session) == GNUTLS_CRT_X509)
1875     {
1876       priv->peer_certificate = get_peer_certificate_from_session (gnutls);
1877       if (priv->peer_certificate)
1878         priv->peer_certificate_errors = verify_peer_certificate (gnutls, priv->peer_certificate);
1879     }
1880
1881   g_object_notify (G_OBJECT (gnutls), "peer-certificate");
1882   g_object_notify (G_OBJECT (gnutls), "peer-certificate-errors");
1883 }
1884
1885 static gboolean
1886 accept_or_reject_peer_certificate (gpointer user_data)
1887 {
1888   GTlsConnectionGnutls *gnutls = user_data;
1889   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1890   gboolean accepted = FALSE;
1891
1892   g_assert (g_main_context_is_owner (priv->handshake_context));
1893
1894   g_mutex_lock (&priv->verify_certificate_mutex);
1895
1896   update_peer_certificate_and_compute_errors (gnutls);
1897
1898   if (G_IS_TLS_CLIENT_CONNECTION (gnutls) && priv->peer_certificate != NULL)
1899     {
1900       GTlsCertificateFlags validation_flags;
1901
1902       if (!g_tls_connection_gnutls_is_dtls (gnutls))
1903         validation_flags =
1904           g_tls_client_connection_get_validation_flags (G_TLS_CLIENT_CONNECTION (gnutls));
1905       else
1906         validation_flags =
1907           g_dtls_client_connection_get_validation_flags (G_DTLS_CLIENT_CONNECTION (gnutls));
1908
1909       if ((priv->peer_certificate_errors & validation_flags) == 0)
1910         accepted = TRUE;
1911     }
1912
1913   if (!accepted)
1914     {
1915       g_main_context_pop_thread_default (priv->handshake_context);
1916       accepted = g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls),
1917                                                            priv->peer_certificate,
1918                                                            priv->peer_certificate_errors);
1919       g_main_context_push_thread_default (priv->handshake_context);
1920     }
1921
1922   priv->peer_certificate_accepted = accepted;
1923
1924   /* This has to be the very last statement before signaling the
1925    * condition variable because otherwise the code could spuriously
1926    * wakeup and continue before we are done here.
1927    */
1928   priv->peer_certificate_examined = TRUE;
1929
1930   g_cond_signal (&priv->verify_certificate_condition);
1931   g_mutex_unlock (&priv->verify_certificate_mutex);
1932
1933   g_object_notify (G_OBJECT (gnutls), "peer-certificate");
1934   g_object_notify (G_OBJECT (gnutls), "peer-certificate-errors");
1935
1936   return G_SOURCE_REMOVE;
1937 }
1938
1939 static int
1940 verify_certificate_cb (gnutls_session_t session)
1941 {
1942   GTlsConnectionGnutls *gnutls = gnutls_session_get_ptr (session);
1943   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1944   gboolean accepted;
1945
1946   g_mutex_lock (&priv->verify_certificate_mutex);
1947   priv->peer_certificate_examined = FALSE;
1948   priv->peer_certificate_accepted = FALSE;
1949   g_mutex_unlock (&priv->verify_certificate_mutex);
1950
1951   /* Invoke the callback on the handshake context's thread. This is
1952    * necessary because we need to ensure the accept-certificate signal
1953    * is emitted on the original thread.
1954    */
1955   g_assert (priv->handshake_context);
1956   g_main_context_invoke (priv->handshake_context, accept_or_reject_peer_certificate, gnutls);
1957
1958   /* We'll block the handshake thread until the original thread has
1959    * decided whether to accept the certificate.
1960    */
1961   g_mutex_lock (&priv->verify_certificate_mutex);
1962   while (!priv->peer_certificate_examined)
1963     g_cond_wait (&priv->verify_certificate_condition, &priv->verify_certificate_mutex);
1964   accepted = priv->peer_certificate_accepted;
1965   g_mutex_unlock (&priv->verify_certificate_mutex);
1966
1967   /* Return 0 for the handshake to continue, non-zero to terminate. */
1968   return !accepted;
1969 }
1970
1971 static void
1972 handshake_thread (GTask        *task,
1973                   gpointer      object,
1974                   gpointer      task_data,
1975                   GCancellable *cancellable)
1976 {
1977   GTlsConnectionGnutls *gnutls = object;
1978   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1979   GError *error = NULL;
1980   int ret;
1981   gint64 start_time;
1982   gint64 timeout;
1983
1984   /* A timeout, in microseconds, must be provided as a gint64* task_data. */
1985   g_assert (task_data != NULL);
1986
1987   timeout = *((gint64 *)task_data);
1988   start_time = g_get_monotonic_time ();
1989   priv->started_handshake = FALSE;
1990
1991   if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE,
1992                  timeout, cancellable, &error))
1993     {
1994       g_task_return_error (task, error);
1995       return;
1996     }
1997
1998   g_clear_error (&priv->handshake_error);
1999
2000   if (priv->ever_handshaked && !priv->implicit_handshake)
2001     {
2002       if (priv->rehandshake_mode != G_TLS_REHANDSHAKE_UNSAFELY &&
2003           !gnutls_safe_renegotiation_status (priv->session))
2004         {
2005           g_task_return_new_error (task, G_TLS_ERROR, G_TLS_ERROR_MISC,
2006                                    _("Peer does not support safe renegotiation"));
2007           return;
2008         }
2009
2010       if (!G_IS_TLS_CLIENT_CONNECTION (gnutls))
2011         {
2012           /* Adjust the timeout for the next operation in the sequence. */
2013           if (timeout > 0)
2014             {
2015               unsigned int timeout_ms;
2016
2017               timeout -= (g_get_monotonic_time () - start_time);
2018               if (timeout <= 0)
2019                 timeout = 1;
2020
2021               /* Convert from microseconds to milliseconds, but ensure the timeout
2022                * remains positive. */
2023               timeout_ms = (timeout + 999) / 1000;
2024
2025               gnutls_handshake_set_timeout (priv->session, timeout_ms);
2026               gnutls_dtls_set_timeouts (priv->session, 1000 /* default */,
2027                                         timeout_ms);
2028             }
2029
2030           BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, timeout, cancellable);
2031           ret = gnutls_rehandshake (priv->session);
2032           END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret,
2033                          _("Error performing TLS handshake"), &error);
2034
2035           if (error)
2036             {
2037               g_task_return_error (task, error);
2038               return;
2039             }
2040         }
2041     }
2042
2043   priv->started_handshake = TRUE;
2044
2045   if (!priv->ever_handshaked)
2046     g_tls_connection_gnutls_set_handshake_priority (gnutls);
2047
2048   /* Adjust the timeout for the next operation in the sequence. */
2049   if (timeout > 0)
2050     {
2051       unsigned int timeout_ms;
2052
2053       timeout -= (g_get_monotonic_time () - start_time);
2054       if (timeout <= 0)
2055         timeout = 1;
2056
2057       /* Convert from microseconds to milliseconds, but ensure the timeout
2058        * remains positive. */
2059       timeout_ms = (timeout + 999) / 1000;
2060
2061       gnutls_handshake_set_timeout (priv->session, timeout_ms);
2062       gnutls_dtls_set_timeouts (priv->session, 1000 /* default */,
2063                                 timeout_ms);
2064     }
2065
2066   BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, timeout, cancellable);
2067   ret = gnutls_handshake (priv->session);
2068   if (ret == GNUTLS_E_GOT_APPLICATION_DATA)
2069     {
2070       guint8 buf[1024];
2071
2072       /* Got app data while waiting for rehandshake; buffer it and try again */
2073       ret = gnutls_record_recv (priv->session, buf, sizeof (buf));
2074       if (ret > -1)
2075         {
2076           if (!priv->app_data_buf)
2077             priv->app_data_buf = g_byte_array_new ();
2078           g_byte_array_append (priv->app_data_buf, buf, ret);
2079           ret = GNUTLS_E_AGAIN;
2080         }
2081     }
2082   END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret,
2083                  _("Error performing TLS handshake"), &error);
2084
2085   /* This calls the finish_handshake code of GTlsClientConnectionGnutls
2086    * or GTlsServerConnectionGnutls. It has nothing to do with
2087    * GTlsConnectionGnutls's own finish_handshake function, which still
2088    * needs to be called at this point.
2089    */
2090   G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->finish_handshake (gnutls, &error);
2091
2092   if (error)
2093     {
2094       g_task_return_error (task, error);
2095     }
2096   else
2097     {
2098       priv->ever_handshaked = TRUE;
2099       g_task_return_boolean (task, TRUE);
2100     }
2101 }
2102
2103 static void
2104 begin_handshake (GTlsConnectionGnutls *gnutls)
2105 {
2106 #if GLIB_CHECK_VERSION(2, 60, 0)
2107   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2108
2109 #if ENABLE(TIZEN_PERFORMANCE_TEST_LOG)
2110   HWCLOCK_LOG("[BGN] gnutls_verify_peer");
2111 #endif
2112
2113   if (priv->advertised_protocols)
2114     {
2115       gnutls_datum_t *protocols;
2116       int n_protos, i;
2117
2118       n_protos = g_strv_length (priv->advertised_protocols);
2119       protocols = g_new (gnutls_datum_t, n_protos);
2120       for (i = 0; priv->advertised_protocols[i]; i++)
2121         {
2122           protocols[i].size = strlen (priv->advertised_protocols[i]);
2123           protocols[i].data = g_memdup (priv->advertised_protocols[i], protocols[i].size);
2124         }
2125       gnutls_alpn_set_protocols (priv->session, protocols, n_protos, 0);
2126       g_free (protocols);
2127     }
2128 #endif
2129
2130 #if ENABLE(TIZEN_PERFORMANCE_TEST_LOG)
2131   HWCLOCK_LOG("[END] gnutls_verify_peer");
2132 #endif
2133
2134   G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->begin_handshake (gnutls);
2135 }
2136
2137 #if GLIB_CHECK_VERSION(2, 60, 0)
2138 static void
2139 update_negotiated_protocol (GTlsConnectionGnutls *gnutls)
2140 {
2141   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2142   gchar *orig_negotiated_protocol;
2143   gnutls_datum_t protocol;
2144
2145   /*
2146    * Preserve the prior negotiated protocol before clearing it
2147    */
2148   orig_negotiated_protocol = g_steal_pointer (&priv->negotiated_protocol);
2149
2150
2151   if (gnutls_alpn_get_selected_protocol (priv->session, &protocol) == 0 && protocol.size > 0)
2152     priv->negotiated_protocol = g_strndup ((gchar *)protocol.data, protocol.size);
2153
2154   /*
2155    * Notify only if the negotiated protocol changed
2156    */
2157   if (g_strcmp0 (orig_negotiated_protocol, priv->negotiated_protocol) != 0)
2158     g_object_notify (G_OBJECT (gnutls), "negotiated-protocol");
2159
2160   g_free (orig_negotiated_protocol);
2161 }
2162 #endif
2163
2164 static gboolean
2165 finish_handshake (GTlsConnectionGnutls  *gnutls,
2166                   GTask                 *task,
2167                   GError               **error)
2168 {
2169   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2170   g_assert (error != NULL);
2171
2172   if (gnutls_session_is_resumed (priv->session))
2173     {
2174       /* Because this session was resumed, we skipped certificate
2175        * verification on this handshake, so we missed our earlier
2176        * chance to set peer_certificate and peer_certificate_errors.
2177        * Do so here instead.
2178        *
2179        * The certificate has already been accepted, so we don't do
2180        * anything with the result here.
2181        */
2182       g_mutex_lock (&priv->verify_certificate_mutex);
2183       update_peer_certificate_and_compute_errors (gnutls);
2184       priv->peer_certificate_examined = TRUE;
2185       priv->peer_certificate_accepted = TRUE;
2186       g_mutex_unlock (&priv->verify_certificate_mutex);
2187     }
2188
2189   if (g_task_propagate_boolean (task, error) &&
2190       priv->peer_certificate && !priv->peer_certificate_accepted)
2191     {
2192       g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
2193                            _("Unacceptable TLS certificate"));
2194     }
2195
2196 #if GLIB_CHECK_VERSION(2, 60, 0)
2197   if (!*error && priv->advertised_protocols)
2198     update_negotiated_protocol (gnutls);
2199 #endif
2200
2201   if (*error && priv->started_handshake)
2202     priv->handshake_error = g_error_copy (*error);
2203
2204   return (*error == NULL);
2205 }
2206
2207 static void
2208 sync_handshake_thread_completed (GObject      *object,
2209                                  GAsyncResult *result,
2210                                  gpointer      user_data)
2211 {
2212   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
2213   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2214
2215   g_assert (g_main_context_is_owner (priv->handshake_context));
2216
2217   g_mutex_lock (&priv->op_mutex);
2218   priv->sync_handshake_completed = TRUE;
2219   g_mutex_unlock (&priv->op_mutex);
2220
2221   g_main_context_wakeup (priv->handshake_context);
2222 }
2223
2224 static void
2225 crank_sync_handshake_context (GTlsConnectionGnutls *gnutls,
2226                               GCancellable         *cancellable)
2227 {
2228   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2229
2230   /* need_finish_handshake will be set inside sync_handshake_thread_completed(),
2231    * which should only ever be invoked while iterating the handshake context
2232    * here. So need_finish_handshake should only change on this thread.
2233    */
2234   g_mutex_lock (&priv->op_mutex);
2235   priv->sync_handshake_completed = FALSE;
2236   while (!priv->sync_handshake_completed && !g_cancellable_is_cancelled (cancellable))
2237     {
2238       g_mutex_unlock (&priv->op_mutex);
2239       g_main_context_iteration (priv->handshake_context, TRUE);
2240       g_mutex_lock (&priv->op_mutex);
2241     }
2242   g_mutex_unlock (&priv->op_mutex);
2243 }
2244
2245 static gboolean
2246 g_tls_connection_gnutls_handshake (GTlsConnection   *conn,
2247                                    GCancellable     *cancellable,
2248                                    GError          **error)
2249 {
2250   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (conn);
2251   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2252   GTask *task;
2253   gboolean success;
2254   gint64 *timeout = NULL;
2255   GError *my_error = NULL;
2256
2257   g_assert (priv->handshake_context == NULL);
2258   priv->handshake_context = g_main_context_new ();
2259
2260   g_main_context_push_thread_default (priv->handshake_context);
2261
2262   begin_handshake (gnutls);
2263
2264   task = g_task_new (conn, cancellable, sync_handshake_thread_completed, NULL);
2265   g_task_set_source_tag (task, g_tls_connection_gnutls_handshake);
2266   g_task_set_return_on_cancel (task, TRUE);
2267
2268   timeout = g_new0 (gint64, 1);
2269   *timeout = -1;  /* blocking */
2270   g_task_set_task_data (task, timeout, g_free);
2271
2272   g_task_run_in_thread (task, handshake_thread);
2273   crank_sync_handshake_context (gnutls, cancellable);
2274
2275   success = finish_handshake (gnutls, task, &my_error);
2276
2277   g_main_context_pop_thread_default (priv->handshake_context);
2278   g_clear_pointer (&priv->handshake_context, g_main_context_unref);
2279   g_object_unref (task);
2280
2281   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
2282
2283   if (my_error)
2284     g_propagate_error (error, my_error);
2285   return success;
2286 }
2287
2288 static gboolean
2289 g_tls_connection_gnutls_dtls_handshake (GDtlsConnection       *conn,
2290                                         GCancellable          *cancellable,
2291                                         GError               **error)
2292 {
2293   return g_tls_connection_gnutls_handshake (G_TLS_CONNECTION (conn),
2294                                             cancellable, error);
2295 }
2296
2297 /* In the async version we use two GTasks; one to run handshake_thread() and
2298  * then call handshake_thread_completed(), and a second to call the caller's
2299  * original callback after we call finish_handshake().
2300  */
2301
2302 static void
2303 handshake_thread_completed (GObject      *object,
2304                             GAsyncResult *result,
2305                             gpointer      user_data)
2306 {
2307   GTask *caller_task = user_data;
2308   GTlsConnectionGnutls *gnutls = g_task_get_source_object (caller_task);
2309   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2310   GError *error = NULL;
2311   gboolean need_finish_handshake, success;
2312
2313   g_mutex_lock (&priv->op_mutex);
2314   if (priv->need_finish_handshake)
2315     {
2316       need_finish_handshake = TRUE;
2317       priv->need_finish_handshake = FALSE;
2318     }
2319   else
2320     need_finish_handshake = FALSE;
2321   g_mutex_unlock (&priv->op_mutex);
2322
2323   if (need_finish_handshake)
2324     {
2325       success = finish_handshake (gnutls, G_TASK (result), &error);
2326       if (success)
2327         g_task_return_boolean (caller_task, TRUE);
2328       else
2329         g_task_return_error (caller_task, error);
2330     }
2331   else if (priv->handshake_error)
2332     g_task_return_error (caller_task, g_error_copy (priv->handshake_error));
2333   else
2334     g_task_return_boolean (caller_task, TRUE);
2335
2336   g_clear_pointer (&priv->handshake_context, g_main_context_unref);
2337   g_object_unref (caller_task);
2338 }
2339
2340 static void
2341 async_handshake_thread (GTask        *task,
2342                         gpointer      object,
2343                         gpointer      task_data,
2344                         GCancellable *cancellable)
2345 {
2346   GTlsConnectionGnutls *gnutls = object;
2347   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2348
2349   handshake_thread (task, object, task_data, cancellable);
2350
2351   g_mutex_lock (&priv->op_mutex);
2352   priv->need_finish_handshake = TRUE;
2353   /* yield_op will clear handshaking too, but we don't want the
2354    * connection to be briefly "handshaking && need_finish_handshake"
2355    * after we unlock the mutex.
2356    */
2357   priv->handshaking = FALSE;
2358   g_mutex_unlock (&priv->op_mutex);
2359
2360   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
2361 }
2362
2363 static void
2364 g_tls_connection_gnutls_handshake_async (GTlsConnection       *conn,
2365                                          int                   io_priority,
2366                                          GCancellable         *cancellable,
2367                                          GAsyncReadyCallback   callback,
2368                                          gpointer              user_data)
2369 {
2370   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (G_TLS_CONNECTION_GNUTLS (conn));
2371   GTask *thread_task, *caller_task;
2372   gint64 *timeout = NULL;
2373
2374   g_assert (!priv->handshake_context);
2375   priv->handshake_context = g_main_context_ref_thread_default ();
2376
2377   caller_task = g_task_new (conn, cancellable, callback, user_data);
2378   g_task_set_source_tag (caller_task, g_tls_connection_gnutls_handshake_async);
2379   g_task_set_priority (caller_task, io_priority);
2380
2381   begin_handshake (G_TLS_CONNECTION_GNUTLS (conn));
2382
2383   thread_task = g_task_new (conn, cancellable,
2384                             handshake_thread_completed, caller_task);
2385   g_task_set_source_tag (thread_task, g_tls_connection_gnutls_handshake_async);
2386   g_task_set_priority (thread_task, io_priority);
2387
2388   timeout = g_new0 (gint64, 1);
2389   *timeout = -1;  /* blocking */
2390   g_task_set_task_data (thread_task, timeout, g_free);
2391
2392   g_task_run_in_thread (thread_task, async_handshake_thread);
2393   g_object_unref (thread_task);
2394 }
2395
2396 static gboolean
2397 g_tls_connection_gnutls_handshake_finish (GTlsConnection       *conn,
2398                                           GAsyncResult         *result,
2399                                           GError              **error)
2400 {
2401   g_return_val_if_fail (g_task_is_valid (result, conn), FALSE);
2402
2403   return g_task_propagate_boolean (G_TASK (result), error);
2404 }
2405
2406 static void
2407 g_tls_connection_gnutls_dtls_handshake_async (GDtlsConnection       *conn,
2408                                               int                    io_priority,
2409                                               GCancellable          *cancellable,
2410                                               GAsyncReadyCallback    callback,
2411                                               gpointer               user_data)
2412 {
2413   g_tls_connection_gnutls_handshake_async (G_TLS_CONNECTION (conn), io_priority,
2414                                            cancellable, callback, user_data);
2415 }
2416
2417 static gboolean
2418 g_tls_connection_gnutls_dtls_handshake_finish (GDtlsConnection       *conn,
2419                                                GAsyncResult          *result,
2420                                                GError               **error)
2421 {
2422   return g_tls_connection_gnutls_handshake_finish (G_TLS_CONNECTION (conn),
2423                                                    result, error);
2424 }
2425
2426 static gboolean
2427 do_implicit_handshake (GTlsConnectionGnutls  *gnutls,
2428                        gint64                 timeout,
2429                        GCancellable          *cancellable,
2430                        GError               **error)
2431 {
2432   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2433   gint64 *thread_timeout = NULL;
2434
2435   /* We have op_mutex */
2436
2437   g_assert (priv->handshake_context == NULL);
2438   if (timeout != 0)
2439     {
2440       priv->handshake_context = g_main_context_new ();
2441       g_main_context_push_thread_default (priv->handshake_context);
2442     }
2443   else
2444     {
2445       priv->handshake_context = g_main_context_ref_thread_default ();
2446     }
2447
2448   g_assert (priv->implicit_handshake == NULL);
2449   priv->implicit_handshake = g_task_new (gnutls, cancellable,
2450                                          timeout ? sync_handshake_thread_completed : NULL,
2451                                          NULL);
2452   g_task_set_source_tag (priv->implicit_handshake,
2453                          do_implicit_handshake);
2454
2455   thread_timeout = g_new0 (gint64, 1);
2456   g_task_set_task_data (priv->implicit_handshake,
2457                         thread_timeout, g_free);
2458
2459   begin_handshake (gnutls);
2460
2461   if (timeout != 0)
2462     {
2463       GError *my_error = NULL;
2464       gboolean success;
2465
2466       /* In the blocking case, run the handshake operation synchronously in
2467        * another thread, and delegate handling the timeout to that thread; it
2468        * should return G_IO_ERROR_TIMED_OUT iff (timeout > 0) and the operation
2469        * times out. If (timeout < 0) it should block indefinitely until the
2470        * operation is complete or errors. */
2471       *thread_timeout = timeout;
2472
2473       g_mutex_unlock (&priv->op_mutex);
2474
2475       g_task_set_return_on_cancel (priv->implicit_handshake, TRUE);
2476       g_task_run_in_thread (priv->implicit_handshake, handshake_thread);
2477
2478       crank_sync_handshake_context (gnutls, cancellable);
2479
2480       success = finish_handshake (gnutls,
2481                                   priv->implicit_handshake,
2482                                   &my_error);
2483
2484       g_main_context_pop_thread_default (priv->handshake_context);
2485       g_clear_pointer (&priv->handshake_context, g_main_context_unref);
2486       g_clear_object (&priv->implicit_handshake);
2487
2488       yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
2489
2490       g_mutex_lock (&priv->op_mutex);
2491
2492       if (my_error)
2493         g_propagate_error (error, my_error);
2494       return success;
2495     }
2496   else
2497     {
2498       /* In the non-blocking case, start the asynchronous handshake operation
2499        * and return EWOULDBLOCK to the caller, who will handle polling for
2500        * completion of the handshake and whatever operation they actually cared
2501        * about. Run the actual operation as blocking in its thread. */
2502       *thread_timeout = -1;  /* blocking */
2503
2504       g_task_run_in_thread (priv->implicit_handshake,
2505                             async_handshake_thread);
2506
2507       /* Intentionally not translated because this is not a fatal error to be
2508        * presented to the user, and to avoid this showing up in profiling. */
2509       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, "Operation would block");
2510       return FALSE;
2511     }
2512 }
2513
2514 gssize
2515 g_tls_connection_gnutls_read (GTlsConnectionGnutls  *gnutls,
2516                               void                  *buffer,
2517                               gsize                  count,
2518                               gint64                 timeout,
2519                               GCancellable          *cancellable,
2520                               GError               **error)
2521 {
2522   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2523   gssize ret;
2524
2525   if (priv->app_data_buf && !priv->handshaking)
2526     {
2527       ret = MIN (count, priv->app_data_buf->len);
2528       memcpy (buffer, priv->app_data_buf->data, ret);
2529       if (ret == priv->app_data_buf->len)
2530         g_clear_pointer (&priv->app_data_buf, g_byte_array_unref);
2531       else
2532         g_byte_array_remove_range (priv->app_data_buf, 0, ret);
2533       return ret;
2534     }
2535
2536  again:
2537   if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ,
2538                  timeout, cancellable, error))
2539     return -1;
2540
2541   BEGIN_GNUTLS_IO (gnutls, G_IO_IN, timeout, cancellable);
2542   ret = gnutls_record_recv (priv->session, buffer, count);
2543   END_GNUTLS_IO (gnutls, G_IO_IN, ret, _("Error reading data from TLS socket"), error);
2544
2545   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ);
2546
2547   if (ret >= 0)
2548     return ret;
2549   else if (ret == GNUTLS_E_REHANDSHAKE)
2550     goto again;
2551   else
2552     return -1;
2553 }
2554
2555 static gsize
2556 input_vectors_from_gnutls_datum_t (GInputVector          *vectors,
2557                                    guint                  num_vectors,
2558                                    const gnutls_datum_t  *datum)
2559 {
2560   guint i;
2561   gsize total = 0;
2562
2563   /* Copy into the receive vectors. */
2564   for (i = 0; i < num_vectors && total < datum->size; i++)
2565     {
2566       gsize count;
2567       GInputVector *vec = &vectors[i];
2568
2569       count = MIN (vec->size, datum->size - total);
2570
2571       memcpy (vec->buffer, datum->data + total, count);
2572       total += count;
2573     }
2574
2575   g_assert (total <= datum->size);
2576
2577   return total;
2578 }
2579
2580 static gssize
2581 g_tls_connection_gnutls_read_message (GTlsConnectionGnutls  *gnutls,
2582                                       GInputVector          *vectors,
2583                                       guint                  num_vectors,
2584                                       gint64                 timeout,
2585                                       GCancellable          *cancellable,
2586                                       GError               **error)
2587 {
2588   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2589   guint i;
2590   gssize ret;
2591   gnutls_packet_t packet = { 0, };
2592
2593   /* Copy data out of the app data buffer first. */
2594   if (priv->app_data_buf && !priv->handshaking)
2595     {
2596       ret = 0;
2597
2598       for (i = 0; i < num_vectors; i++)
2599         {
2600           gsize count;
2601           GInputVector *vec = &vectors[i];
2602
2603           count = MIN (vec->size, priv->app_data_buf->len);
2604           ret += count;
2605
2606           memcpy (vec->buffer, priv->app_data_buf->data, count);
2607           if (count == priv->app_data_buf->len)
2608             g_clear_pointer (&priv->app_data_buf, g_byte_array_unref);
2609           else
2610             g_byte_array_remove_range (priv->app_data_buf, 0, count);
2611         }
2612
2613       return ret;
2614     }
2615
2616  again:
2617   if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ,
2618                  timeout, cancellable, error))
2619     return -1;
2620
2621   BEGIN_GNUTLS_IO (gnutls, G_IO_IN, timeout, cancellable);
2622
2623   /* Receive the entire datagram (zero-copy). */
2624   ret = gnutls_record_recv_packet (priv->session, &packet);
2625
2626   if (ret > 0)
2627     {
2628       gnutls_datum_t data = { 0, };
2629
2630       gnutls_packet_get (packet, &data, NULL);
2631       ret = input_vectors_from_gnutls_datum_t (vectors, num_vectors, &data);
2632       gnutls_packet_deinit (packet);
2633     }
2634
2635   END_GNUTLS_IO (gnutls, G_IO_IN, ret, _("Error reading data from TLS socket"), error);
2636
2637   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ);
2638
2639   if (ret >= 0)
2640     return ret;
2641   else if (ret == GNUTLS_E_REHANDSHAKE)
2642     goto again;
2643   else
2644     return -1;
2645 }
2646
2647 static gint
2648 g_tls_connection_gnutls_receive_messages (GDatagramBased  *datagram_based,
2649                                           GInputMessage   *messages,
2650                                           guint            num_messages,
2651                                           gint             flags,
2652                                           gint64           timeout,
2653                                           GCancellable    *cancellable,
2654                                           GError         **error)
2655 {
2656   GTlsConnectionGnutls *gnutls;
2657   guint i;
2658   GError *child_error = NULL;
2659
2660   gnutls = G_TLS_CONNECTION_GNUTLS (datagram_based);
2661
2662   if (flags != G_SOCKET_MSG_NONE)
2663     {
2664       g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
2665                    _("Receive flags are not supported"));
2666       return -1;
2667     }
2668
2669   for (i = 0; i < num_messages && child_error == NULL; i++)
2670     {
2671       GInputMessage *message = &messages[i];
2672       gssize n_bytes_read;
2673
2674       n_bytes_read = g_tls_connection_gnutls_read_message (gnutls,
2675                                                            message->vectors,
2676                                                            message->num_vectors,
2677                                                            timeout,
2678                                                            cancellable,
2679                                                            &child_error);
2680
2681       if (message->address != NULL)
2682         *message->address = NULL;
2683       message->flags = G_SOCKET_MSG_NONE;
2684       if (message->control_messages != NULL)
2685         *message->control_messages = NULL;
2686       message->num_control_messages = 0;
2687
2688       if (n_bytes_read > 0)
2689         {
2690           message->bytes_received = n_bytes_read;
2691         }
2692       else if (n_bytes_read == 0)
2693         {
2694           /* EOS. */
2695           break;
2696         }
2697       else if (i > 0 &&
2698                (g_error_matches (child_error,
2699                                  G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) ||
2700                 g_error_matches (child_error,
2701                                  G_IO_ERROR, G_IO_ERROR_TIMED_OUT)))
2702         {
2703           /* Blocked or timed out after receiving some messages successfully. */
2704           g_clear_error (&child_error);
2705           break;
2706         }
2707       else
2708         {
2709           /* Error, including G_IO_ERROR_WOULD_BLOCK or G_IO_ERROR_TIMED_OUT on
2710            * the first message; or G_IO_ERROR_CANCELLED at any time. */
2711           break;
2712         }
2713     }
2714
2715   if (child_error != NULL)
2716     {
2717       g_propagate_error (error, child_error);
2718       return -1;
2719     }
2720
2721   return i;
2722 }
2723
2724 gssize
2725 g_tls_connection_gnutls_write (GTlsConnectionGnutls  *gnutls,
2726                                const void            *buffer,
2727                                gsize                  count,
2728                                gint64                 timeout,
2729                                GCancellable          *cancellable,
2730                                GError               **error)
2731 {
2732   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2733   gssize ret;
2734
2735  again:
2736   if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE,
2737                  timeout, cancellable, error))
2738     return -1;
2739
2740   BEGIN_GNUTLS_IO (gnutls, G_IO_OUT, timeout, cancellable);
2741   ret = gnutls_record_send (priv->session, buffer, count);
2742   END_GNUTLS_IO (gnutls, G_IO_OUT, ret, _("Error writing data to TLS socket"), error);
2743
2744   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE);
2745
2746   if (ret >= 0)
2747     return ret;
2748   else if (ret == GNUTLS_E_REHANDSHAKE)
2749     goto again;
2750   else
2751     return -1;
2752 }
2753
2754 static gssize
2755 g_tls_connection_gnutls_write_message (GTlsConnectionGnutls  *gnutls,
2756                                        GOutputVector         *vectors,
2757                                        guint                  num_vectors,
2758                                        gint64                 timeout,
2759                                        GCancellable          *cancellable,
2760                                        GError               **error)
2761 {
2762   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2763   gssize ret;
2764   guint i;
2765   gsize total_message_size;
2766
2767  again:
2768   if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE,
2769                  timeout, cancellable, error))
2770     return -1;
2771
2772   /* Calculate the total message size and check it’s not too big. */
2773   for (i = 0, total_message_size = 0; i < num_vectors; i++)
2774     total_message_size += vectors[i].size;
2775
2776   if (priv->base_socket != NULL &&
2777       gnutls_dtls_get_data_mtu (priv->session) < total_message_size)
2778     {
2779       char *message;
2780       guint mtu = gnutls_dtls_get_data_mtu (priv->session);
2781
2782       ret = GNUTLS_E_LARGE_PACKET;
2783       message = g_strdup_printf("%s %s",
2784                                 ngettext ("Message of size %lu byte is too large for DTLS connection",
2785                                           "Message of size %lu bytes is too large for DTLS connection", total_message_size),
2786                                 ngettext ("(maximum is %u byte)", "(maximum is %u bytes)", mtu));
2787       g_set_error (error, G_IO_ERROR, G_IO_ERROR_MESSAGE_TOO_LARGE,
2788                    message,
2789                    total_message_size,
2790                    mtu);
2791       g_free (message);
2792
2793       goto done;
2794     }
2795
2796   /* Queue up the data from all the vectors. */
2797   gnutls_record_cork (priv->session);
2798
2799   for (i = 0; i < num_vectors; i++)
2800     {
2801       ret = gnutls_record_send (priv->session,
2802                                 vectors[i].buffer, vectors[i].size);
2803
2804       if (ret < 0 || ret < vectors[i].size)
2805         {
2806           /* Uncork to restore state, then bail. The peer will receive a
2807            * truncated datagram. */
2808           break;
2809         }
2810     }
2811
2812   BEGIN_GNUTLS_IO (gnutls, G_IO_OUT, timeout, cancellable);
2813   ret = gnutls_record_uncork (priv->session, 0  /* flags */);
2814   END_GNUTLS_IO (gnutls, G_IO_OUT, ret, _("Error writing data to TLS socket"), error);
2815
2816  done:
2817   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE);
2818
2819   if (ret >= 0)
2820     return ret;
2821   else if (ret == GNUTLS_E_REHANDSHAKE)
2822     goto again;
2823   else
2824     return -1;
2825 }
2826
2827 static gint
2828 g_tls_connection_gnutls_send_messages (GDatagramBased  *datagram_based,
2829                                        GOutputMessage  *messages,
2830                                        guint            num_messages,
2831                                        gint             flags,
2832                                        gint64           timeout,
2833                                        GCancellable    *cancellable,
2834                                        GError         **error)
2835 {
2836   GTlsConnectionGnutls *gnutls;
2837   guint i;
2838   GError *child_error = NULL;
2839
2840   gnutls = G_TLS_CONNECTION_GNUTLS (datagram_based);
2841
2842   if (flags != G_SOCKET_MSG_NONE)
2843     {
2844       g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
2845                    _("Send flags are not supported"));
2846       return -1;
2847     }
2848
2849   for (i = 0; i < num_messages && child_error == NULL; i++)
2850     {
2851       GOutputMessage *message = &messages[i];
2852       gssize n_bytes_sent;
2853
2854       n_bytes_sent = g_tls_connection_gnutls_write_message (gnutls,
2855                                                             message->vectors,
2856                                                             message->num_vectors,
2857                                                             timeout,
2858                                                             cancellable,
2859                                                             &child_error);
2860
2861       if (n_bytes_sent >= 0)
2862         {
2863           message->bytes_sent = n_bytes_sent;
2864         }
2865       else if (i > 0 &&
2866                (g_error_matches (child_error,
2867                                  G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) ||
2868                 g_error_matches (child_error,
2869                                  G_IO_ERROR, G_IO_ERROR_TIMED_OUT)))
2870         {
2871           /* Blocked or timed out after sending some messages successfully. */
2872           g_clear_error (&child_error);
2873           break;
2874         }
2875       else
2876         {
2877           /* Error, including G_IO_ERROR_WOULD_BLOCK or G_IO_ERROR_TIMED_OUT
2878            * on the first message; or G_IO_ERROR_CANCELLED at any time. */
2879           break;
2880         }
2881     }
2882
2883   if (child_error != NULL)
2884     {
2885       g_propagate_error (error, child_error);
2886       return -1;
2887     }
2888
2889   return i;
2890 }
2891
2892 static GInputStream  *
2893 g_tls_connection_gnutls_get_input_stream (GIOStream *stream)
2894 {
2895   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
2896   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2897
2898   return priv->tls_istream;
2899 }
2900
2901 static GOutputStream *
2902 g_tls_connection_gnutls_get_output_stream (GIOStream *stream)
2903 {
2904   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
2905   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2906
2907   return priv->tls_ostream;
2908 }
2909
2910 gboolean
2911 g_tls_connection_gnutls_close_internal (GIOStream     *stream,
2912                                         GTlsDirection  direction,
2913                                         gint64         timeout,
2914                                         GCancellable  *cancellable,
2915                                         GError       **error)
2916 {
2917   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
2918   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2919   GTlsConnectionGnutlsOp op;
2920   gboolean success = TRUE;
2921   int ret = 0;
2922   GError *gnutls_error = NULL, *stream_error = NULL;
2923
2924   /* This can be called from g_io_stream_close(), g_input_stream_close(),
2925    * g_output_stream_close() or g_tls_connection_close(). In all cases, we only
2926    * do the gnutls_bye() for writing. The difference is how we set the flags on
2927    * this class and how the underlying stream is closed.
2928    */
2929
2930   g_return_val_if_fail (direction != G_TLS_DIRECTION_NONE, FALSE);
2931
2932   if (direction == G_TLS_DIRECTION_BOTH)
2933     op = G_TLS_CONNECTION_GNUTLS_OP_CLOSE_BOTH;
2934   else if (direction == G_TLS_DIRECTION_READ)
2935     op = G_TLS_CONNECTION_GNUTLS_OP_CLOSE_READ;
2936   else
2937     op = G_TLS_CONNECTION_GNUTLS_OP_CLOSE_WRITE;
2938
2939   if (!claim_op (gnutls, op, timeout, cancellable, error))
2940     return FALSE;
2941
2942   if (priv->ever_handshaked && !priv->write_closed &&
2943       direction & G_TLS_DIRECTION_WRITE)
2944     {
2945       BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, timeout, cancellable);
2946       ret = gnutls_bye (priv->session, GNUTLS_SHUT_WR);
2947       END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret,
2948                      _("Error performing TLS close"), &gnutls_error);
2949
2950       priv->write_closed = TRUE;
2951     }
2952
2953   if (!priv->read_closed && direction & G_TLS_DIRECTION_READ)
2954     priv->read_closed = TRUE;
2955
2956   /* Close the underlying streams. Do this even if the gnutls_bye() call failed,
2957    * as the parent GIOStream will have set its internal closed flag and hence
2958    * this implementation will never be called again. */
2959   if (priv->base_io_stream != NULL)
2960     {
2961       if (direction == G_TLS_DIRECTION_BOTH)
2962         success = g_io_stream_close (priv->base_io_stream,
2963                                      cancellable, &stream_error);
2964       else if (direction & G_TLS_DIRECTION_READ)
2965         success = g_input_stream_close (g_io_stream_get_input_stream (priv->base_io_stream),
2966                                         cancellable, &stream_error);
2967       else if (direction & G_TLS_DIRECTION_WRITE)
2968         success = g_output_stream_close (g_io_stream_get_output_stream (priv->base_io_stream),
2969                                          cancellable, &stream_error);
2970     }
2971   else if (g_tls_connection_gnutls_is_dtls (gnutls))
2972     {
2973       /* We do not close underlying #GDatagramBaseds. There is no
2974        * g_datagram_based_close() method since different datagram-based
2975        * protocols vary wildly in how they close. */
2976       success = TRUE;
2977     }
2978   else
2979     {
2980       g_assert_not_reached ();
2981     }
2982
2983   yield_op (gnutls, op);
2984
2985   /* Propagate errors. */
2986   if (ret != 0)
2987     {
2988       g_propagate_error (error, gnutls_error);
2989       g_clear_error (&stream_error);
2990     }
2991   else if (!success)
2992     {
2993       g_propagate_error (error, stream_error);
2994       g_clear_error (&gnutls_error);
2995     }
2996
2997   return success && (ret == 0);
2998 }
2999
3000 static gboolean
3001 g_tls_connection_gnutls_close (GIOStream     *stream,
3002                                GCancellable  *cancellable,
3003                                GError       **error)
3004 {
3005   return g_tls_connection_gnutls_close_internal (stream,
3006                                                  G_TLS_DIRECTION_BOTH,
3007                                                  -1,  /* blocking */
3008                                                  cancellable, error);
3009 }
3010
3011 static gboolean
3012 g_tls_connection_gnutls_dtls_shutdown (GDtlsConnection  *conn,
3013                                        gboolean          shutdown_read,
3014                                        gboolean          shutdown_write,
3015                                        GCancellable     *cancellable,
3016                                        GError          **error)
3017 {
3018   GTlsDirection direction = G_TLS_DIRECTION_NONE;
3019
3020   if (shutdown_read)
3021     direction |= G_TLS_DIRECTION_READ;
3022   if (shutdown_write)
3023     direction |= G_TLS_DIRECTION_WRITE;
3024
3025   return g_tls_connection_gnutls_close_internal (G_IO_STREAM (conn),
3026                                                  direction,
3027                                                  -1,  /* blocking */
3028                                                  cancellable, error);
3029 }
3030
3031 /* We do async close as synchronous-in-a-thread so we don't need to
3032  * implement G_IO_IN/G_IO_OUT flip-flopping just for this one case
3033  * (since handshakes are also done synchronously now).
3034  */
3035 static void
3036 close_thread (GTask        *task,
3037               gpointer      object,
3038               gpointer      task_data,
3039               GCancellable *cancellable)
3040 {
3041   GIOStream *stream = object;
3042   GTlsDirection direction;
3043   GError *error = NULL;
3044
3045   direction = GPOINTER_TO_INT (g_task_get_task_data (task));
3046
3047   if (!g_tls_connection_gnutls_close_internal (stream, direction,
3048                                                -1,  /* blocking */
3049                                                cancellable, &error))
3050     g_task_return_error (task, error);
3051   else
3052     g_task_return_boolean (task, TRUE);
3053 }
3054
3055 static void
3056 g_tls_connection_gnutls_close_internal_async (GIOStream           *stream,
3057                                               GTlsDirection        direction,
3058                                               int                  io_priority,
3059                                               GCancellable        *cancellable,
3060                                               GAsyncReadyCallback  callback,
3061                                               gpointer             user_data)
3062 {
3063   GTask *task;
3064
3065   task = g_task_new (stream, cancellable, callback, user_data);
3066   g_task_set_source_tag (task, g_tls_connection_gnutls_close_internal_async);
3067   g_task_set_priority (task, io_priority);
3068   g_task_set_task_data (task, GINT_TO_POINTER (direction), NULL);
3069   g_task_run_in_thread (task, close_thread);
3070   g_object_unref (task);
3071 }
3072
3073 static void
3074 g_tls_connection_gnutls_close_async (GIOStream           *stream,
3075                                      int                  io_priority,
3076                                      GCancellable        *cancellable,
3077                                      GAsyncReadyCallback  callback,
3078                                      gpointer             user_data)
3079 {
3080   g_tls_connection_gnutls_close_internal_async (stream, G_TLS_DIRECTION_BOTH,
3081                                                 io_priority, cancellable,
3082                                                 callback, user_data);
3083 }
3084
3085 static gboolean
3086 g_tls_connection_gnutls_close_finish (GIOStream           *stream,
3087                                       GAsyncResult        *result,
3088                                       GError             **error)
3089 {
3090   g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
3091
3092   return g_task_propagate_boolean (G_TASK (result), error);
3093 }
3094
3095 static void
3096 g_tls_connection_gnutls_dtls_shutdown_async (GDtlsConnection     *conn,
3097                                              gboolean             shutdown_read,
3098                                              gboolean             shutdown_write,
3099                                              int                  io_priority,
3100                                              GCancellable        *cancellable,
3101                                              GAsyncReadyCallback  callback,
3102                                              gpointer             user_data)
3103 {
3104   GTlsDirection direction = G_TLS_DIRECTION_NONE;
3105
3106   if (shutdown_read)
3107     direction |= G_TLS_DIRECTION_READ;
3108   if (shutdown_write)
3109     direction |= G_TLS_DIRECTION_WRITE;
3110
3111   g_tls_connection_gnutls_close_internal_async (G_IO_STREAM (conn), direction,
3112                                                 io_priority, cancellable,
3113                                                 callback, user_data);
3114 }
3115
3116 static gboolean
3117 g_tls_connection_gnutls_dtls_shutdown_finish (GDtlsConnection  *conn,
3118                                               GAsyncResult     *result,
3119                                               GError          **error)
3120 {
3121   g_return_val_if_fail (g_task_is_valid (result, conn), FALSE);
3122
3123   return g_task_propagate_boolean (G_TASK (result), error);
3124 }
3125
3126 #if GLIB_CHECK_VERSION(2, 60, 0)
3127 static void
3128 g_tls_connection_gnutls_dtls_set_advertised_protocols (GDtlsConnection     *conn,
3129                                                        const gchar * const *protocols)
3130 {
3131   g_object_set (conn, "advertised-protocols", protocols, NULL);
3132 }
3133
3134 const gchar *
3135 g_tls_connection_gnutls_dtls_get_negotiated_protocol (GDtlsConnection *conn)
3136 {
3137   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (conn);
3138   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
3139
3140   return priv->negotiated_protocol;
3141 }
3142 #endif
3143
3144 static void
3145 g_tls_connection_gnutls_class_init (GTlsConnectionGnutlsClass *klass)
3146 {
3147   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
3148   GTlsConnectionClass *connection_class = G_TLS_CONNECTION_CLASS (klass);
3149   GIOStreamClass *iostream_class = G_IO_STREAM_CLASS (klass);
3150
3151   gobject_class->get_property = g_tls_connection_gnutls_get_property;
3152   gobject_class->set_property = g_tls_connection_gnutls_set_property;
3153   gobject_class->finalize     = g_tls_connection_gnutls_finalize;
3154
3155   connection_class->handshake        = g_tls_connection_gnutls_handshake;
3156   connection_class->handshake_async  = g_tls_connection_gnutls_handshake_async;
3157   connection_class->handshake_finish = g_tls_connection_gnutls_handshake_finish;
3158
3159   iostream_class->get_input_stream  = g_tls_connection_gnutls_get_input_stream;
3160   iostream_class->get_output_stream = g_tls_connection_gnutls_get_output_stream;
3161   iostream_class->close_fn          = g_tls_connection_gnutls_close;
3162   iostream_class->close_async       = g_tls_connection_gnutls_close_async;
3163   iostream_class->close_finish      = g_tls_connection_gnutls_close_finish;
3164
3165   /* For GTlsConnection and GDtlsConnection: */
3166   g_object_class_override_property (gobject_class, PROP_BASE_IO_STREAM, "base-io-stream");
3167   g_object_class_override_property (gobject_class, PROP_BASE_SOCKET, "base-socket");
3168   g_object_class_override_property (gobject_class, PROP_REQUIRE_CLOSE_NOTIFY, "require-close-notify");
3169   g_object_class_override_property (gobject_class, PROP_REHANDSHAKE_MODE, "rehandshake-mode");
3170   g_object_class_override_property (gobject_class, PROP_USE_SYSTEM_CERTDB, "use-system-certdb");
3171   g_object_class_override_property (gobject_class, PROP_DATABASE, "database");
3172   g_object_class_override_property (gobject_class, PROP_CERTIFICATE, "certificate");
3173   g_object_class_override_property (gobject_class, PROP_INTERACTION, "interaction");
3174   g_object_class_override_property (gobject_class, PROP_PEER_CERTIFICATE, "peer-certificate");
3175   g_object_class_override_property (gobject_class, PROP_PEER_CERTIFICATE_ERRORS, "peer-certificate-errors");
3176 #if GLIB_CHECK_VERSION(2, 60, 0)
3177   g_object_class_override_property (gobject_class, PROP_ADVERTISED_PROTOCOLS, "advertised-protocols");
3178   g_object_class_override_property (gobject_class, PROP_NEGOTIATED_PROTOCOL, "negotiated-protocol");
3179 #endif
3180 }
3181
3182 static void
3183 g_tls_connection_gnutls_initable_iface_init (GInitableIface *iface)
3184 {
3185   iface->init = g_tls_connection_gnutls_initable_init;
3186 }
3187
3188 static void
3189 g_tls_connection_gnutls_dtls_connection_iface_init (GDtlsConnectionInterface *iface)
3190 {
3191   iface->handshake = g_tls_connection_gnutls_dtls_handshake;
3192   iface->handshake_async = g_tls_connection_gnutls_dtls_handshake_async;
3193   iface->handshake_finish = g_tls_connection_gnutls_dtls_handshake_finish;
3194   iface->shutdown = g_tls_connection_gnutls_dtls_shutdown;
3195   iface->shutdown_async = g_tls_connection_gnutls_dtls_shutdown_async;
3196   iface->shutdown_finish = g_tls_connection_gnutls_dtls_shutdown_finish;
3197 #if GLIB_CHECK_VERSION(2, 60, 0)
3198   iface->set_advertised_protocols = g_tls_connection_gnutls_dtls_set_advertised_protocols;
3199   iface->get_negotiated_protocol = g_tls_connection_gnutls_dtls_get_negotiated_protocol;
3200 #endif
3201 }
3202
3203 static void
3204 g_tls_connection_gnutls_datagram_based_iface_init (GDatagramBasedInterface *iface)
3205 {
3206   iface->receive_messages = g_tls_connection_gnutls_receive_messages;
3207   iface->send_messages = g_tls_connection_gnutls_send_messages;
3208   iface->create_source = g_tls_connection_gnutls_dtls_create_source;
3209   iface->condition_check = g_tls_connection_gnutls_condition_check;
3210   iface->condition_wait = g_tls_connection_gnutls_condition_wait;
3211 }
3212
3213 gboolean
3214 g_tls_connection_gnutls_request_certificate (GTlsConnectionGnutls  *gnutls,
3215                                              GError               **error)
3216 {
3217   GTlsInteractionResult res = G_TLS_INTERACTION_UNHANDLED;
3218   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
3219   GTlsInteraction *interaction;
3220   GTlsConnection *conn;
3221
3222   g_return_val_if_fail (G_IS_TLS_CONNECTION_GNUTLS (gnutls), FALSE);
3223
3224   conn = G_TLS_CONNECTION (gnutls);
3225
3226   interaction = g_tls_connection_get_interaction (conn);
3227   if (!interaction)
3228     return FALSE;
3229
3230   res = g_tls_interaction_invoke_request_certificate (interaction, conn, 0,
3231                                                       priv->read_cancellable, error);
3232   return res != G_TLS_INTERACTION_FAILED;
3233 }
3234
3235 void
3236 GTLS_DEBUG (gpointer    gnutls,
3237             const char *message,
3238             ...)
3239 {
3240   char *result = NULL;
3241   int ret;
3242
3243   g_assert (G_IS_TLS_CONNECTION (gnutls));
3244
3245   va_list args;
3246   va_start (args, message);
3247
3248   ret = g_vasprintf (&result, message, args);
3249   g_assert (ret > 0);
3250
3251   if (G_IS_TLS_CLIENT_CONNECTION (gnutls))
3252     g_printf ("CLIENT %p: ", gnutls);
3253   else if (G_IS_TLS_SERVER_CONNECTION (gnutls))
3254     g_printf ("SERVER %p: ", gnutls);
3255   else
3256     g_assert_not_reached ();
3257
3258   g_printf ("%s\n", result);
3259
3260   fflush (stdout);
3261
3262   g_free (result);
3263   va_end (args);
3264 }