Add tizen dlog for debugging
[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       errors |= G_TLS_CERTIFICATE_UNKNOWN_CA;
1826       errors |= g_tls_certificate_verify (peer_certificate, peer_identity, NULL);
1827     }
1828   else
1829     {
1830       GError *error = NULL;
1831
1832       errors |= g_tls_database_verify_chain (database, peer_certificate,
1833                                              is_client ?
1834                                              G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER :
1835                                              G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT,
1836                                              peer_identity,
1837                                              g_tls_connection_get_interaction (conn),
1838                                              G_TLS_DATABASE_VERIFY_NONE,
1839                                              NULL, &error);
1840       if (error)
1841         {
1842           g_warning ("failure verifying certificate chain: %s",
1843                      error->message);
1844           g_assert (errors != 0);
1845           g_clear_error (&error);
1846         }
1847     }
1848
1849   return errors;
1850 }
1851
1852 static void
1853 update_peer_certificate_and_compute_errors (GTlsConnectionGnutls *gnutls)
1854 {
1855   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1856
1857   /* This function must be called from the handshake context thread
1858    * (probably the main thread, NOT the handshake thread) because it
1859    * emits notifies that are application-visible.
1860    *
1861    * verify_certificate_mutex should be locked.
1862    */
1863   g_assert (priv->handshake_context);
1864   g_assert (g_main_context_is_owner (priv->handshake_context));
1865
1866   g_clear_object (&priv->peer_certificate);
1867   priv->peer_certificate_errors = 0;
1868
1869   if (gnutls_certificate_type_get (priv->session) == GNUTLS_CRT_X509)
1870     {
1871       priv->peer_certificate = get_peer_certificate_from_session (gnutls);
1872       if (priv->peer_certificate)
1873         priv->peer_certificate_errors = verify_peer_certificate (gnutls, priv->peer_certificate);
1874     }
1875
1876   g_object_notify (G_OBJECT (gnutls), "peer-certificate");
1877   g_object_notify (G_OBJECT (gnutls), "peer-certificate-errors");
1878 }
1879
1880 static gboolean
1881 accept_or_reject_peer_certificate (gpointer user_data)
1882 {
1883   GTlsConnectionGnutls *gnutls = user_data;
1884   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1885   gboolean accepted = FALSE;
1886
1887   g_assert (g_main_context_is_owner (priv->handshake_context));
1888
1889   g_mutex_lock (&priv->verify_certificate_mutex);
1890
1891   update_peer_certificate_and_compute_errors (gnutls);
1892
1893   if (G_IS_TLS_CLIENT_CONNECTION (gnutls) && priv->peer_certificate != NULL)
1894     {
1895       GTlsCertificateFlags validation_flags;
1896
1897       if (!g_tls_connection_gnutls_is_dtls (gnutls))
1898         validation_flags =
1899           g_tls_client_connection_get_validation_flags (G_TLS_CLIENT_CONNECTION (gnutls));
1900       else
1901         validation_flags =
1902           g_dtls_client_connection_get_validation_flags (G_DTLS_CLIENT_CONNECTION (gnutls));
1903
1904       if ((priv->peer_certificate_errors & validation_flags) == 0)
1905         accepted = TRUE;
1906     }
1907
1908   if (!accepted)
1909     {
1910       g_main_context_pop_thread_default (priv->handshake_context);
1911       accepted = g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls),
1912                                                            priv->peer_certificate,
1913                                                            priv->peer_certificate_errors);
1914       g_main_context_push_thread_default (priv->handshake_context);
1915     }
1916
1917   priv->peer_certificate_accepted = accepted;
1918
1919   /* This has to be the very last statement before signaling the
1920    * condition variable because otherwise the code could spuriously
1921    * wakeup and continue before we are done here.
1922    */
1923   priv->peer_certificate_examined = TRUE;
1924
1925   g_cond_signal (&priv->verify_certificate_condition);
1926   g_mutex_unlock (&priv->verify_certificate_mutex);
1927
1928   g_object_notify (G_OBJECT (gnutls), "peer-certificate");
1929   g_object_notify (G_OBJECT (gnutls), "peer-certificate-errors");
1930
1931   return G_SOURCE_REMOVE;
1932 }
1933
1934 static int
1935 verify_certificate_cb (gnutls_session_t session)
1936 {
1937   GTlsConnectionGnutls *gnutls = gnutls_session_get_ptr (session);
1938   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1939   gboolean accepted;
1940
1941   g_mutex_lock (&priv->verify_certificate_mutex);
1942   priv->peer_certificate_examined = FALSE;
1943   priv->peer_certificate_accepted = FALSE;
1944   g_mutex_unlock (&priv->verify_certificate_mutex);
1945
1946   /* Invoke the callback on the handshake context's thread. This is
1947    * necessary because we need to ensure the accept-certificate signal
1948    * is emitted on the original thread.
1949    */
1950   g_assert (priv->handshake_context);
1951   g_main_context_invoke (priv->handshake_context, accept_or_reject_peer_certificate, gnutls);
1952
1953   /* We'll block the handshake thread until the original thread has
1954    * decided whether to accept the certificate.
1955    */
1956   g_mutex_lock (&priv->verify_certificate_mutex);
1957   while (!priv->peer_certificate_examined)
1958     g_cond_wait (&priv->verify_certificate_condition, &priv->verify_certificate_mutex);
1959   accepted = priv->peer_certificate_accepted;
1960   g_mutex_unlock (&priv->verify_certificate_mutex);
1961
1962   /* Return 0 for the handshake to continue, non-zero to terminate. */
1963   return !accepted;
1964 }
1965
1966 static void
1967 handshake_thread (GTask        *task,
1968                   gpointer      object,
1969                   gpointer      task_data,
1970                   GCancellable *cancellable)
1971 {
1972   GTlsConnectionGnutls *gnutls = object;
1973   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1974   GError *error = NULL;
1975   int ret;
1976   gint64 start_time;
1977   gint64 timeout;
1978
1979   /* A timeout, in microseconds, must be provided as a gint64* task_data. */
1980   g_assert (task_data != NULL);
1981
1982   timeout = *((gint64 *)task_data);
1983   start_time = g_get_monotonic_time ();
1984   priv->started_handshake = FALSE;
1985
1986   if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE,
1987                  timeout, cancellable, &error))
1988     {
1989       g_task_return_error (task, error);
1990       return;
1991     }
1992
1993   g_clear_error (&priv->handshake_error);
1994
1995   if (priv->ever_handshaked && !priv->implicit_handshake)
1996     {
1997       if (priv->rehandshake_mode != G_TLS_REHANDSHAKE_UNSAFELY &&
1998           !gnutls_safe_renegotiation_status (priv->session))
1999         {
2000           g_task_return_new_error (task, G_TLS_ERROR, G_TLS_ERROR_MISC,
2001                                    _("Peer does not support safe renegotiation"));
2002           return;
2003         }
2004
2005       if (!G_IS_TLS_CLIENT_CONNECTION (gnutls))
2006         {
2007           /* Adjust the timeout for the next operation in the sequence. */
2008           if (timeout > 0)
2009             {
2010               unsigned int timeout_ms;
2011
2012               timeout -= (g_get_monotonic_time () - start_time);
2013               if (timeout <= 0)
2014                 timeout = 1;
2015
2016               /* Convert from microseconds to milliseconds, but ensure the timeout
2017                * remains positive. */
2018               timeout_ms = (timeout + 999) / 1000;
2019
2020               gnutls_handshake_set_timeout (priv->session, timeout_ms);
2021               gnutls_dtls_set_timeouts (priv->session, 1000 /* default */,
2022                                         timeout_ms);
2023             }
2024
2025           BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, timeout, cancellable);
2026           ret = gnutls_rehandshake (priv->session);
2027           END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret,
2028                          _("Error performing TLS handshake"), &error);
2029
2030           if (error)
2031             {
2032               g_task_return_error (task, error);
2033               return;
2034             }
2035         }
2036     }
2037
2038   priv->started_handshake = TRUE;
2039
2040   if (!priv->ever_handshaked)
2041     g_tls_connection_gnutls_set_handshake_priority (gnutls);
2042
2043   /* Adjust the timeout for the next operation in the sequence. */
2044   if (timeout > 0)
2045     {
2046       unsigned int timeout_ms;
2047
2048       timeout -= (g_get_monotonic_time () - start_time);
2049       if (timeout <= 0)
2050         timeout = 1;
2051
2052       /* Convert from microseconds to milliseconds, but ensure the timeout
2053        * remains positive. */
2054       timeout_ms = (timeout + 999) / 1000;
2055
2056       gnutls_handshake_set_timeout (priv->session, timeout_ms);
2057       gnutls_dtls_set_timeouts (priv->session, 1000 /* default */,
2058                                 timeout_ms);
2059     }
2060
2061   BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, timeout, cancellable);
2062   ret = gnutls_handshake (priv->session);
2063   if (ret == GNUTLS_E_GOT_APPLICATION_DATA)
2064     {
2065       guint8 buf[1024];
2066
2067       /* Got app data while waiting for rehandshake; buffer it and try again */
2068       ret = gnutls_record_recv (priv->session, buf, sizeof (buf));
2069       if (ret > -1)
2070         {
2071           if (!priv->app_data_buf)
2072             priv->app_data_buf = g_byte_array_new ();
2073           g_byte_array_append (priv->app_data_buf, buf, ret);
2074           ret = GNUTLS_E_AGAIN;
2075         }
2076     }
2077   END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret,
2078                  _("Error performing TLS handshake"), &error);
2079
2080   /* This calls the finish_handshake code of GTlsClientConnectionGnutls
2081    * or GTlsServerConnectionGnutls. It has nothing to do with
2082    * GTlsConnectionGnutls's own finish_handshake function, which still
2083    * needs to be called at this point.
2084    */
2085   G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->finish_handshake (gnutls, &error);
2086
2087   if (error)
2088     {
2089       g_task_return_error (task, error);
2090     }
2091   else
2092     {
2093       priv->ever_handshaked = TRUE;
2094       g_task_return_boolean (task, TRUE);
2095     }
2096 }
2097
2098 static void
2099 begin_handshake (GTlsConnectionGnutls *gnutls)
2100 {
2101 #if GLIB_CHECK_VERSION(2, 60, 0)
2102   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2103
2104 #if ENABLE(TIZEN_PERFORMANCE_TEST_LOG)
2105   HWCLOCK_LOG("[BGN] gnutls_verify_peer");
2106 #endif
2107
2108   if (priv->advertised_protocols)
2109     {
2110       gnutls_datum_t *protocols;
2111       int n_protos, i;
2112
2113       n_protos = g_strv_length (priv->advertised_protocols);
2114       protocols = g_new (gnutls_datum_t, n_protos);
2115       for (i = 0; priv->advertised_protocols[i]; i++)
2116         {
2117           protocols[i].size = strlen (priv->advertised_protocols[i]);
2118           protocols[i].data = g_memdup (priv->advertised_protocols[i], protocols[i].size);
2119         }
2120       gnutls_alpn_set_protocols (priv->session, protocols, n_protos, 0);
2121       g_free (protocols);
2122     }
2123 #endif
2124
2125 #if ENABLE(TIZEN_PERFORMANCE_TEST_LOG)
2126   HWCLOCK_LOG("[END] gnutls_verify_peer");
2127 #endif
2128
2129   G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->begin_handshake (gnutls);
2130 }
2131
2132 #if GLIB_CHECK_VERSION(2, 60, 0)
2133 static void
2134 update_negotiated_protocol (GTlsConnectionGnutls *gnutls)
2135 {
2136   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2137   gchar *orig_negotiated_protocol;
2138   gnutls_datum_t protocol;
2139
2140   /*
2141    * Preserve the prior negotiated protocol before clearing it
2142    */
2143   orig_negotiated_protocol = g_steal_pointer (&priv->negotiated_protocol);
2144
2145
2146   if (gnutls_alpn_get_selected_protocol (priv->session, &protocol) == 0 && protocol.size > 0)
2147     priv->negotiated_protocol = g_strndup ((gchar *)protocol.data, protocol.size);
2148
2149   /*
2150    * Notify only if the negotiated protocol changed
2151    */
2152   if (g_strcmp0 (orig_negotiated_protocol, priv->negotiated_protocol) != 0)
2153     g_object_notify (G_OBJECT (gnutls), "negotiated-protocol");
2154
2155   g_free (orig_negotiated_protocol);
2156 }
2157 #endif
2158
2159 static gboolean
2160 finish_handshake (GTlsConnectionGnutls  *gnutls,
2161                   GTask                 *task,
2162                   GError               **error)
2163 {
2164   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2165   g_assert (error != NULL);
2166
2167   if (gnutls_session_is_resumed (priv->session))
2168     {
2169       /* Because this session was resumed, we skipped certificate
2170        * verification on this handshake, so we missed our earlier
2171        * chance to set peer_certificate and peer_certificate_errors.
2172        * Do so here instead.
2173        *
2174        * The certificate has already been accepted, so we don't do
2175        * anything with the result here.
2176        */
2177       g_mutex_lock (&priv->verify_certificate_mutex);
2178       update_peer_certificate_and_compute_errors (gnutls);
2179       priv->peer_certificate_examined = TRUE;
2180       priv->peer_certificate_accepted = TRUE;
2181       g_mutex_unlock (&priv->verify_certificate_mutex);
2182     }
2183
2184   if (g_task_propagate_boolean (task, error) &&
2185       priv->peer_certificate && !priv->peer_certificate_accepted)
2186     {
2187       g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
2188                            _("Unacceptable TLS certificate"));
2189     }
2190
2191 #if GLIB_CHECK_VERSION(2, 60, 0)
2192   if (!*error && priv->advertised_protocols)
2193     update_negotiated_protocol (gnutls);
2194 #endif
2195
2196   if (*error && priv->started_handshake)
2197     priv->handshake_error = g_error_copy (*error);
2198
2199   return (*error == NULL);
2200 }
2201
2202 static void
2203 sync_handshake_thread_completed (GObject      *object,
2204                                  GAsyncResult *result,
2205                                  gpointer      user_data)
2206 {
2207   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
2208   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2209
2210   g_assert (g_main_context_is_owner (priv->handshake_context));
2211
2212   g_mutex_lock (&priv->op_mutex);
2213   priv->sync_handshake_completed = TRUE;
2214   g_mutex_unlock (&priv->op_mutex);
2215
2216   g_main_context_wakeup (priv->handshake_context);
2217 }
2218
2219 static void
2220 crank_sync_handshake_context (GTlsConnectionGnutls *gnutls,
2221                               GCancellable         *cancellable)
2222 {
2223   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2224
2225   /* need_finish_handshake will be set inside sync_handshake_thread_completed(),
2226    * which should only ever be invoked while iterating the handshake context
2227    * here. So need_finish_handshake should only change on this thread.
2228    */
2229   g_mutex_lock (&priv->op_mutex);
2230   priv->sync_handshake_completed = FALSE;
2231   while (!priv->sync_handshake_completed && !g_cancellable_is_cancelled (cancellable))
2232     {
2233       g_mutex_unlock (&priv->op_mutex);
2234       g_main_context_iteration (priv->handshake_context, TRUE);
2235       g_mutex_lock (&priv->op_mutex);
2236     }
2237   g_mutex_unlock (&priv->op_mutex);
2238 }
2239
2240 static gboolean
2241 g_tls_connection_gnutls_handshake (GTlsConnection   *conn,
2242                                    GCancellable     *cancellable,
2243                                    GError          **error)
2244 {
2245   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (conn);
2246   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2247   GTask *task;
2248   gboolean success;
2249   gint64 *timeout = NULL;
2250   GError *my_error = NULL;
2251
2252   g_assert (priv->handshake_context == NULL);
2253   priv->handshake_context = g_main_context_new ();
2254
2255   g_main_context_push_thread_default (priv->handshake_context);
2256
2257   begin_handshake (gnutls);
2258
2259   task = g_task_new (conn, cancellable, sync_handshake_thread_completed, NULL);
2260   g_task_set_source_tag (task, g_tls_connection_gnutls_handshake);
2261   g_task_set_return_on_cancel (task, TRUE);
2262
2263   timeout = g_new0 (gint64, 1);
2264   *timeout = -1;  /* blocking */
2265   g_task_set_task_data (task, timeout, g_free);
2266
2267   g_task_run_in_thread (task, handshake_thread);
2268   crank_sync_handshake_context (gnutls, cancellable);
2269
2270   success = finish_handshake (gnutls, task, &my_error);
2271
2272   g_main_context_pop_thread_default (priv->handshake_context);
2273   g_clear_pointer (&priv->handshake_context, g_main_context_unref);
2274   g_object_unref (task);
2275
2276   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
2277
2278   if (my_error)
2279     g_propagate_error (error, my_error);
2280   return success;
2281 }
2282
2283 static gboolean
2284 g_tls_connection_gnutls_dtls_handshake (GDtlsConnection       *conn,
2285                                         GCancellable          *cancellable,
2286                                         GError               **error)
2287 {
2288   return g_tls_connection_gnutls_handshake (G_TLS_CONNECTION (conn),
2289                                             cancellable, error);
2290 }
2291
2292 /* In the async version we use two GTasks; one to run handshake_thread() and
2293  * then call handshake_thread_completed(), and a second to call the caller's
2294  * original callback after we call finish_handshake().
2295  */
2296
2297 static void
2298 handshake_thread_completed (GObject      *object,
2299                             GAsyncResult *result,
2300                             gpointer      user_data)
2301 {
2302   GTask *caller_task = user_data;
2303   GTlsConnectionGnutls *gnutls = g_task_get_source_object (caller_task);
2304   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2305   GError *error = NULL;
2306   gboolean need_finish_handshake, success;
2307
2308   g_mutex_lock (&priv->op_mutex);
2309   if (priv->need_finish_handshake)
2310     {
2311       need_finish_handshake = TRUE;
2312       priv->need_finish_handshake = FALSE;
2313     }
2314   else
2315     need_finish_handshake = FALSE;
2316   g_mutex_unlock (&priv->op_mutex);
2317
2318   if (need_finish_handshake)
2319     {
2320       success = finish_handshake (gnutls, G_TASK (result), &error);
2321       if (success)
2322         g_task_return_boolean (caller_task, TRUE);
2323       else
2324         g_task_return_error (caller_task, error);
2325     }
2326   else if (priv->handshake_error)
2327     g_task_return_error (caller_task, g_error_copy (priv->handshake_error));
2328   else
2329     g_task_return_boolean (caller_task, TRUE);
2330
2331   g_clear_pointer (&priv->handshake_context, g_main_context_unref);
2332   g_object_unref (caller_task);
2333 }
2334
2335 static void
2336 async_handshake_thread (GTask        *task,
2337                         gpointer      object,
2338                         gpointer      task_data,
2339                         GCancellable *cancellable)
2340 {
2341   GTlsConnectionGnutls *gnutls = object;
2342   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2343
2344   handshake_thread (task, object, task_data, cancellable);
2345
2346   g_mutex_lock (&priv->op_mutex);
2347   priv->need_finish_handshake = TRUE;
2348   /* yield_op will clear handshaking too, but we don't want the
2349    * connection to be briefly "handshaking && need_finish_handshake"
2350    * after we unlock the mutex.
2351    */
2352   priv->handshaking = FALSE;
2353   g_mutex_unlock (&priv->op_mutex);
2354
2355   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
2356 }
2357
2358 static void
2359 g_tls_connection_gnutls_handshake_async (GTlsConnection       *conn,
2360                                          int                   io_priority,
2361                                          GCancellable         *cancellable,
2362                                          GAsyncReadyCallback   callback,
2363                                          gpointer              user_data)
2364 {
2365   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (G_TLS_CONNECTION_GNUTLS (conn));
2366   GTask *thread_task, *caller_task;
2367   gint64 *timeout = NULL;
2368
2369   g_assert (!priv->handshake_context);
2370   priv->handshake_context = g_main_context_ref_thread_default ();
2371
2372   caller_task = g_task_new (conn, cancellable, callback, user_data);
2373   g_task_set_source_tag (caller_task, g_tls_connection_gnutls_handshake_async);
2374   g_task_set_priority (caller_task, io_priority);
2375
2376   begin_handshake (G_TLS_CONNECTION_GNUTLS (conn));
2377
2378   thread_task = g_task_new (conn, cancellable,
2379                             handshake_thread_completed, caller_task);
2380   g_task_set_source_tag (thread_task, g_tls_connection_gnutls_handshake_async);
2381   g_task_set_priority (thread_task, io_priority);
2382
2383   timeout = g_new0 (gint64, 1);
2384   *timeout = -1;  /* blocking */
2385   g_task_set_task_data (thread_task, timeout, g_free);
2386
2387   g_task_run_in_thread (thread_task, async_handshake_thread);
2388   g_object_unref (thread_task);
2389 }
2390
2391 static gboolean
2392 g_tls_connection_gnutls_handshake_finish (GTlsConnection       *conn,
2393                                           GAsyncResult         *result,
2394                                           GError              **error)
2395 {
2396   g_return_val_if_fail (g_task_is_valid (result, conn), FALSE);
2397
2398   return g_task_propagate_boolean (G_TASK (result), error);
2399 }
2400
2401 static void
2402 g_tls_connection_gnutls_dtls_handshake_async (GDtlsConnection       *conn,
2403                                               int                    io_priority,
2404                                               GCancellable          *cancellable,
2405                                               GAsyncReadyCallback    callback,
2406                                               gpointer               user_data)
2407 {
2408   g_tls_connection_gnutls_handshake_async (G_TLS_CONNECTION (conn), io_priority,
2409                                            cancellable, callback, user_data);
2410 }
2411
2412 static gboolean
2413 g_tls_connection_gnutls_dtls_handshake_finish (GDtlsConnection       *conn,
2414                                                GAsyncResult          *result,
2415                                                GError               **error)
2416 {
2417   return g_tls_connection_gnutls_handshake_finish (G_TLS_CONNECTION (conn),
2418                                                    result, error);
2419 }
2420
2421 static gboolean
2422 do_implicit_handshake (GTlsConnectionGnutls  *gnutls,
2423                        gint64                 timeout,
2424                        GCancellable          *cancellable,
2425                        GError               **error)
2426 {
2427   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2428   gint64 *thread_timeout = NULL;
2429
2430   /* We have op_mutex */
2431
2432   g_assert (priv->handshake_context == NULL);
2433   if (timeout != 0)
2434     {
2435       priv->handshake_context = g_main_context_new ();
2436       g_main_context_push_thread_default (priv->handshake_context);
2437     }
2438   else
2439     {
2440       priv->handshake_context = g_main_context_ref_thread_default ();
2441     }
2442
2443   g_assert (priv->implicit_handshake == NULL);
2444   priv->implicit_handshake = g_task_new (gnutls, cancellable,
2445                                          timeout ? sync_handshake_thread_completed : NULL,
2446                                          NULL);
2447   g_task_set_source_tag (priv->implicit_handshake,
2448                          do_implicit_handshake);
2449
2450   thread_timeout = g_new0 (gint64, 1);
2451   g_task_set_task_data (priv->implicit_handshake,
2452                         thread_timeout, g_free);
2453
2454   begin_handshake (gnutls);
2455
2456   if (timeout != 0)
2457     {
2458       GError *my_error = NULL;
2459       gboolean success;
2460
2461       /* In the blocking case, run the handshake operation synchronously in
2462        * another thread, and delegate handling the timeout to that thread; it
2463        * should return G_IO_ERROR_TIMED_OUT iff (timeout > 0) and the operation
2464        * times out. If (timeout < 0) it should block indefinitely until the
2465        * operation is complete or errors. */
2466       *thread_timeout = timeout;
2467
2468       g_mutex_unlock (&priv->op_mutex);
2469
2470       g_task_set_return_on_cancel (priv->implicit_handshake, TRUE);
2471       g_task_run_in_thread (priv->implicit_handshake, handshake_thread);
2472
2473       crank_sync_handshake_context (gnutls, cancellable);
2474
2475       success = finish_handshake (gnutls,
2476                                   priv->implicit_handshake,
2477                                   &my_error);
2478
2479       g_main_context_pop_thread_default (priv->handshake_context);
2480       g_clear_pointer (&priv->handshake_context, g_main_context_unref);
2481       g_clear_object (&priv->implicit_handshake);
2482
2483       yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
2484
2485       g_mutex_lock (&priv->op_mutex);
2486
2487       if (my_error)
2488         g_propagate_error (error, my_error);
2489       return success;
2490     }
2491   else
2492     {
2493       /* In the non-blocking case, start the asynchronous handshake operation
2494        * and return EWOULDBLOCK to the caller, who will handle polling for
2495        * completion of the handshake and whatever operation they actually cared
2496        * about. Run the actual operation as blocking in its thread. */
2497       *thread_timeout = -1;  /* blocking */
2498
2499       g_task_run_in_thread (priv->implicit_handshake,
2500                             async_handshake_thread);
2501
2502       /* Intentionally not translated because this is not a fatal error to be
2503        * presented to the user, and to avoid this showing up in profiling. */
2504       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, "Operation would block");
2505       return FALSE;
2506     }
2507 }
2508
2509 gssize
2510 g_tls_connection_gnutls_read (GTlsConnectionGnutls  *gnutls,
2511                               void                  *buffer,
2512                               gsize                  count,
2513                               gint64                 timeout,
2514                               GCancellable          *cancellable,
2515                               GError               **error)
2516 {
2517   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2518   gssize ret;
2519
2520   if (priv->app_data_buf && !priv->handshaking)
2521     {
2522       ret = MIN (count, priv->app_data_buf->len);
2523       memcpy (buffer, priv->app_data_buf->data, ret);
2524       if (ret == priv->app_data_buf->len)
2525         g_clear_pointer (&priv->app_data_buf, g_byte_array_unref);
2526       else
2527         g_byte_array_remove_range (priv->app_data_buf, 0, ret);
2528       return ret;
2529     }
2530
2531  again:
2532   if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ,
2533                  timeout, cancellable, error))
2534     return -1;
2535
2536   BEGIN_GNUTLS_IO (gnutls, G_IO_IN, timeout, cancellable);
2537   ret = gnutls_record_recv (priv->session, buffer, count);
2538   END_GNUTLS_IO (gnutls, G_IO_IN, ret, _("Error reading data from TLS socket"), error);
2539
2540   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ);
2541
2542   if (ret >= 0)
2543     return ret;
2544   else if (ret == GNUTLS_E_REHANDSHAKE)
2545     goto again;
2546   else
2547     return -1;
2548 }
2549
2550 static gsize
2551 input_vectors_from_gnutls_datum_t (GInputVector          *vectors,
2552                                    guint                  num_vectors,
2553                                    const gnutls_datum_t  *datum)
2554 {
2555   guint i;
2556   gsize total = 0;
2557
2558   /* Copy into the receive vectors. */
2559   for (i = 0; i < num_vectors && total < datum->size; i++)
2560     {
2561       gsize count;
2562       GInputVector *vec = &vectors[i];
2563
2564       count = MIN (vec->size, datum->size - total);
2565
2566       memcpy (vec->buffer, datum->data + total, count);
2567       total += count;
2568     }
2569
2570   g_assert (total <= datum->size);
2571
2572   return total;
2573 }
2574
2575 static gssize
2576 g_tls_connection_gnutls_read_message (GTlsConnectionGnutls  *gnutls,
2577                                       GInputVector          *vectors,
2578                                       guint                  num_vectors,
2579                                       gint64                 timeout,
2580                                       GCancellable          *cancellable,
2581                                       GError               **error)
2582 {
2583   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2584   guint i;
2585   gssize ret;
2586   gnutls_packet_t packet = { 0, };
2587
2588   /* Copy data out of the app data buffer first. */
2589   if (priv->app_data_buf && !priv->handshaking)
2590     {
2591       ret = 0;
2592
2593       for (i = 0; i < num_vectors; i++)
2594         {
2595           gsize count;
2596           GInputVector *vec = &vectors[i];
2597
2598           count = MIN (vec->size, priv->app_data_buf->len);
2599           ret += count;
2600
2601           memcpy (vec->buffer, priv->app_data_buf->data, count);
2602           if (count == priv->app_data_buf->len)
2603             g_clear_pointer (&priv->app_data_buf, g_byte_array_unref);
2604           else
2605             g_byte_array_remove_range (priv->app_data_buf, 0, count);
2606         }
2607
2608       return ret;
2609     }
2610
2611  again:
2612   if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ,
2613                  timeout, cancellable, error))
2614     return -1;
2615
2616   BEGIN_GNUTLS_IO (gnutls, G_IO_IN, timeout, cancellable);
2617
2618   /* Receive the entire datagram (zero-copy). */
2619   ret = gnutls_record_recv_packet (priv->session, &packet);
2620
2621   if (ret > 0)
2622     {
2623       gnutls_datum_t data = { 0, };
2624
2625       gnutls_packet_get (packet, &data, NULL);
2626       ret = input_vectors_from_gnutls_datum_t (vectors, num_vectors, &data);
2627       gnutls_packet_deinit (packet);
2628     }
2629
2630   END_GNUTLS_IO (gnutls, G_IO_IN, ret, _("Error reading data from TLS socket"), error);
2631
2632   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ);
2633
2634   if (ret >= 0)
2635     return ret;
2636   else if (ret == GNUTLS_E_REHANDSHAKE)
2637     goto again;
2638   else
2639     return -1;
2640 }
2641
2642 static gint
2643 g_tls_connection_gnutls_receive_messages (GDatagramBased  *datagram_based,
2644                                           GInputMessage   *messages,
2645                                           guint            num_messages,
2646                                           gint             flags,
2647                                           gint64           timeout,
2648                                           GCancellable    *cancellable,
2649                                           GError         **error)
2650 {
2651   GTlsConnectionGnutls *gnutls;
2652   guint i;
2653   GError *child_error = NULL;
2654
2655   gnutls = G_TLS_CONNECTION_GNUTLS (datagram_based);
2656
2657   if (flags != G_SOCKET_MSG_NONE)
2658     {
2659       g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
2660                    _("Receive flags are not supported"));
2661       return -1;
2662     }
2663
2664   for (i = 0; i < num_messages && child_error == NULL; i++)
2665     {
2666       GInputMessage *message = &messages[i];
2667       gssize n_bytes_read;
2668
2669       n_bytes_read = g_tls_connection_gnutls_read_message (gnutls,
2670                                                            message->vectors,
2671                                                            message->num_vectors,
2672                                                            timeout,
2673                                                            cancellable,
2674                                                            &child_error);
2675
2676       if (message->address != NULL)
2677         *message->address = NULL;
2678       message->flags = G_SOCKET_MSG_NONE;
2679       if (message->control_messages != NULL)
2680         *message->control_messages = NULL;
2681       message->num_control_messages = 0;
2682
2683       if (n_bytes_read > 0)
2684         {
2685           message->bytes_received = n_bytes_read;
2686         }
2687       else if (n_bytes_read == 0)
2688         {
2689           /* EOS. */
2690           break;
2691         }
2692       else if (i > 0 &&
2693                (g_error_matches (child_error,
2694                                  G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) ||
2695                 g_error_matches (child_error,
2696                                  G_IO_ERROR, G_IO_ERROR_TIMED_OUT)))
2697         {
2698           /* Blocked or timed out after receiving some messages successfully. */
2699           g_clear_error (&child_error);
2700           break;
2701         }
2702       else
2703         {
2704           /* Error, including G_IO_ERROR_WOULD_BLOCK or G_IO_ERROR_TIMED_OUT on
2705            * the first message; or G_IO_ERROR_CANCELLED at any time. */
2706           break;
2707         }
2708     }
2709
2710   if (child_error != NULL)
2711     {
2712       g_propagate_error (error, child_error);
2713       return -1;
2714     }
2715
2716   return i;
2717 }
2718
2719 gssize
2720 g_tls_connection_gnutls_write (GTlsConnectionGnutls  *gnutls,
2721                                const void            *buffer,
2722                                gsize                  count,
2723                                gint64                 timeout,
2724                                GCancellable          *cancellable,
2725                                GError               **error)
2726 {
2727   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2728   gssize ret;
2729
2730  again:
2731   if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE,
2732                  timeout, cancellable, error))
2733     return -1;
2734
2735   BEGIN_GNUTLS_IO (gnutls, G_IO_OUT, timeout, cancellable);
2736   ret = gnutls_record_send (priv->session, buffer, count);
2737   END_GNUTLS_IO (gnutls, G_IO_OUT, ret, _("Error writing data to TLS socket"), error);
2738
2739   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE);
2740
2741   if (ret >= 0)
2742     return ret;
2743   else if (ret == GNUTLS_E_REHANDSHAKE)
2744     goto again;
2745   else
2746     return -1;
2747 }
2748
2749 static gssize
2750 g_tls_connection_gnutls_write_message (GTlsConnectionGnutls  *gnutls,
2751                                        GOutputVector         *vectors,
2752                                        guint                  num_vectors,
2753                                        gint64                 timeout,
2754                                        GCancellable          *cancellable,
2755                                        GError               **error)
2756 {
2757   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2758   gssize ret;
2759   guint i;
2760   gsize total_message_size;
2761
2762  again:
2763   if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE,
2764                  timeout, cancellable, error))
2765     return -1;
2766
2767   /* Calculate the total message size and check it’s not too big. */
2768   for (i = 0, total_message_size = 0; i < num_vectors; i++)
2769     total_message_size += vectors[i].size;
2770
2771   if (priv->base_socket != NULL &&
2772       gnutls_dtls_get_data_mtu (priv->session) < total_message_size)
2773     {
2774       char *message;
2775       guint mtu = gnutls_dtls_get_data_mtu (priv->session);
2776
2777       ret = GNUTLS_E_LARGE_PACKET;
2778       message = g_strdup_printf("%s %s",
2779                                 ngettext ("Message of size %lu byte is too large for DTLS connection",
2780                                           "Message of size %lu bytes is too large for DTLS connection", total_message_size),
2781                                 ngettext ("(maximum is %u byte)", "(maximum is %u bytes)", mtu));
2782       g_set_error (error, G_IO_ERROR, G_IO_ERROR_MESSAGE_TOO_LARGE,
2783                    message,
2784                    total_message_size,
2785                    mtu);
2786       g_free (message);
2787
2788       goto done;
2789     }
2790
2791   /* Queue up the data from all the vectors. */
2792   gnutls_record_cork (priv->session);
2793
2794   for (i = 0; i < num_vectors; i++)
2795     {
2796       ret = gnutls_record_send (priv->session,
2797                                 vectors[i].buffer, vectors[i].size);
2798
2799       if (ret < 0 || ret < vectors[i].size)
2800         {
2801           /* Uncork to restore state, then bail. The peer will receive a
2802            * truncated datagram. */
2803           break;
2804         }
2805     }
2806
2807   BEGIN_GNUTLS_IO (gnutls, G_IO_OUT, timeout, cancellable);
2808   ret = gnutls_record_uncork (priv->session, 0  /* flags */);
2809   END_GNUTLS_IO (gnutls, G_IO_OUT, ret, _("Error writing data to TLS socket"), error);
2810
2811  done:
2812   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE);
2813
2814   if (ret >= 0)
2815     return ret;
2816   else if (ret == GNUTLS_E_REHANDSHAKE)
2817     goto again;
2818   else
2819     return -1;
2820 }
2821
2822 static gint
2823 g_tls_connection_gnutls_send_messages (GDatagramBased  *datagram_based,
2824                                        GOutputMessage  *messages,
2825                                        guint            num_messages,
2826                                        gint             flags,
2827                                        gint64           timeout,
2828                                        GCancellable    *cancellable,
2829                                        GError         **error)
2830 {
2831   GTlsConnectionGnutls *gnutls;
2832   guint i;
2833   GError *child_error = NULL;
2834
2835   gnutls = G_TLS_CONNECTION_GNUTLS (datagram_based);
2836
2837   if (flags != G_SOCKET_MSG_NONE)
2838     {
2839       g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
2840                    _("Send flags are not supported"));
2841       return -1;
2842     }
2843
2844   for (i = 0; i < num_messages && child_error == NULL; i++)
2845     {
2846       GOutputMessage *message = &messages[i];
2847       gssize n_bytes_sent;
2848
2849       n_bytes_sent = g_tls_connection_gnutls_write_message (gnutls,
2850                                                             message->vectors,
2851                                                             message->num_vectors,
2852                                                             timeout,
2853                                                             cancellable,
2854                                                             &child_error);
2855
2856       if (n_bytes_sent >= 0)
2857         {
2858           message->bytes_sent = n_bytes_sent;
2859         }
2860       else if (i > 0 &&
2861                (g_error_matches (child_error,
2862                                  G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) ||
2863                 g_error_matches (child_error,
2864                                  G_IO_ERROR, G_IO_ERROR_TIMED_OUT)))
2865         {
2866           /* Blocked or timed out after sending some messages successfully. */
2867           g_clear_error (&child_error);
2868           break;
2869         }
2870       else
2871         {
2872           /* Error, including G_IO_ERROR_WOULD_BLOCK or G_IO_ERROR_TIMED_OUT
2873            * on the first message; or G_IO_ERROR_CANCELLED at any time. */
2874           break;
2875         }
2876     }
2877
2878   if (child_error != NULL)
2879     {
2880       g_propagate_error (error, child_error);
2881       return -1;
2882     }
2883
2884   return i;
2885 }
2886
2887 static GInputStream  *
2888 g_tls_connection_gnutls_get_input_stream (GIOStream *stream)
2889 {
2890   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
2891   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2892
2893   return priv->tls_istream;
2894 }
2895
2896 static GOutputStream *
2897 g_tls_connection_gnutls_get_output_stream (GIOStream *stream)
2898 {
2899   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
2900   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2901
2902   return priv->tls_ostream;
2903 }
2904
2905 gboolean
2906 g_tls_connection_gnutls_close_internal (GIOStream     *stream,
2907                                         GTlsDirection  direction,
2908                                         gint64         timeout,
2909                                         GCancellable  *cancellable,
2910                                         GError       **error)
2911 {
2912   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
2913   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
2914   GTlsConnectionGnutlsOp op;
2915   gboolean success = TRUE;
2916   int ret = 0;
2917   GError *gnutls_error = NULL, *stream_error = NULL;
2918
2919   /* This can be called from g_io_stream_close(), g_input_stream_close(),
2920    * g_output_stream_close() or g_tls_connection_close(). In all cases, we only
2921    * do the gnutls_bye() for writing. The difference is how we set the flags on
2922    * this class and how the underlying stream is closed.
2923    */
2924
2925   g_return_val_if_fail (direction != G_TLS_DIRECTION_NONE, FALSE);
2926
2927   if (direction == G_TLS_DIRECTION_BOTH)
2928     op = G_TLS_CONNECTION_GNUTLS_OP_CLOSE_BOTH;
2929   else if (direction == G_TLS_DIRECTION_READ)
2930     op = G_TLS_CONNECTION_GNUTLS_OP_CLOSE_READ;
2931   else
2932     op = G_TLS_CONNECTION_GNUTLS_OP_CLOSE_WRITE;
2933
2934   if (!claim_op (gnutls, op, timeout, cancellable, error))
2935     return FALSE;
2936
2937   if (priv->ever_handshaked && !priv->write_closed &&
2938       direction & G_TLS_DIRECTION_WRITE)
2939     {
2940       BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, timeout, cancellable);
2941       ret = gnutls_bye (priv->session, GNUTLS_SHUT_WR);
2942       END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret,
2943                      _("Error performing TLS close"), &gnutls_error);
2944
2945       priv->write_closed = TRUE;
2946     }
2947
2948   if (!priv->read_closed && direction & G_TLS_DIRECTION_READ)
2949     priv->read_closed = TRUE;
2950
2951   /* Close the underlying streams. Do this even if the gnutls_bye() call failed,
2952    * as the parent GIOStream will have set its internal closed flag and hence
2953    * this implementation will never be called again. */
2954   if (priv->base_io_stream != NULL)
2955     {
2956       if (direction == G_TLS_DIRECTION_BOTH)
2957         success = g_io_stream_close (priv->base_io_stream,
2958                                      cancellable, &stream_error);
2959       else if (direction & G_TLS_DIRECTION_READ)
2960         success = g_input_stream_close (g_io_stream_get_input_stream (priv->base_io_stream),
2961                                         cancellable, &stream_error);
2962       else if (direction & G_TLS_DIRECTION_WRITE)
2963         success = g_output_stream_close (g_io_stream_get_output_stream (priv->base_io_stream),
2964                                          cancellable, &stream_error);
2965     }
2966   else if (g_tls_connection_gnutls_is_dtls (gnutls))
2967     {
2968       /* We do not close underlying #GDatagramBaseds. There is no
2969        * g_datagram_based_close() method since different datagram-based
2970        * protocols vary wildly in how they close. */
2971       success = TRUE;
2972     }
2973   else
2974     {
2975       g_assert_not_reached ();
2976     }
2977
2978   yield_op (gnutls, op);
2979
2980   /* Propagate errors. */
2981   if (ret != 0)
2982     {
2983       g_propagate_error (error, gnutls_error);
2984       g_clear_error (&stream_error);
2985     }
2986   else if (!success)
2987     {
2988       g_propagate_error (error, stream_error);
2989       g_clear_error (&gnutls_error);
2990     }
2991
2992   return success && (ret == 0);
2993 }
2994
2995 static gboolean
2996 g_tls_connection_gnutls_close (GIOStream     *stream,
2997                                GCancellable  *cancellable,
2998                                GError       **error)
2999 {
3000   return g_tls_connection_gnutls_close_internal (stream,
3001                                                  G_TLS_DIRECTION_BOTH,
3002                                                  -1,  /* blocking */
3003                                                  cancellable, error);
3004 }
3005
3006 static gboolean
3007 g_tls_connection_gnutls_dtls_shutdown (GDtlsConnection  *conn,
3008                                        gboolean          shutdown_read,
3009                                        gboolean          shutdown_write,
3010                                        GCancellable     *cancellable,
3011                                        GError          **error)
3012 {
3013   GTlsDirection direction = G_TLS_DIRECTION_NONE;
3014
3015   if (shutdown_read)
3016     direction |= G_TLS_DIRECTION_READ;
3017   if (shutdown_write)
3018     direction |= G_TLS_DIRECTION_WRITE;
3019
3020   return g_tls_connection_gnutls_close_internal (G_IO_STREAM (conn),
3021                                                  direction,
3022                                                  -1,  /* blocking */
3023                                                  cancellable, error);
3024 }
3025
3026 /* We do async close as synchronous-in-a-thread so we don't need to
3027  * implement G_IO_IN/G_IO_OUT flip-flopping just for this one case
3028  * (since handshakes are also done synchronously now).
3029  */
3030 static void
3031 close_thread (GTask        *task,
3032               gpointer      object,
3033               gpointer      task_data,
3034               GCancellable *cancellable)
3035 {
3036   GIOStream *stream = object;
3037   GTlsDirection direction;
3038   GError *error = NULL;
3039
3040   direction = GPOINTER_TO_INT (g_task_get_task_data (task));
3041
3042   if (!g_tls_connection_gnutls_close_internal (stream, direction,
3043                                                -1,  /* blocking */
3044                                                cancellable, &error))
3045     g_task_return_error (task, error);
3046   else
3047     g_task_return_boolean (task, TRUE);
3048 }
3049
3050 static void
3051 g_tls_connection_gnutls_close_internal_async (GIOStream           *stream,
3052                                               GTlsDirection        direction,
3053                                               int                  io_priority,
3054                                               GCancellable        *cancellable,
3055                                               GAsyncReadyCallback  callback,
3056                                               gpointer             user_data)
3057 {
3058   GTask *task;
3059
3060   task = g_task_new (stream, cancellable, callback, user_data);
3061   g_task_set_source_tag (task, g_tls_connection_gnutls_close_internal_async);
3062   g_task_set_priority (task, io_priority);
3063   g_task_set_task_data (task, GINT_TO_POINTER (direction), NULL);
3064   g_task_run_in_thread (task, close_thread);
3065   g_object_unref (task);
3066 }
3067
3068 static void
3069 g_tls_connection_gnutls_close_async (GIOStream           *stream,
3070                                      int                  io_priority,
3071                                      GCancellable        *cancellable,
3072                                      GAsyncReadyCallback  callback,
3073                                      gpointer             user_data)
3074 {
3075   g_tls_connection_gnutls_close_internal_async (stream, G_TLS_DIRECTION_BOTH,
3076                                                 io_priority, cancellable,
3077                                                 callback, user_data);
3078 }
3079
3080 static gboolean
3081 g_tls_connection_gnutls_close_finish (GIOStream           *stream,
3082                                       GAsyncResult        *result,
3083                                       GError             **error)
3084 {
3085   g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
3086
3087   return g_task_propagate_boolean (G_TASK (result), error);
3088 }
3089
3090 static void
3091 g_tls_connection_gnutls_dtls_shutdown_async (GDtlsConnection     *conn,
3092                                              gboolean             shutdown_read,
3093                                              gboolean             shutdown_write,
3094                                              int                  io_priority,
3095                                              GCancellable        *cancellable,
3096                                              GAsyncReadyCallback  callback,
3097                                              gpointer             user_data)
3098 {
3099   GTlsDirection direction = G_TLS_DIRECTION_NONE;
3100
3101   if (shutdown_read)
3102     direction |= G_TLS_DIRECTION_READ;
3103   if (shutdown_write)
3104     direction |= G_TLS_DIRECTION_WRITE;
3105
3106   g_tls_connection_gnutls_close_internal_async (G_IO_STREAM (conn), direction,
3107                                                 io_priority, cancellable,
3108                                                 callback, user_data);
3109 }
3110
3111 static gboolean
3112 g_tls_connection_gnutls_dtls_shutdown_finish (GDtlsConnection  *conn,
3113                                               GAsyncResult     *result,
3114                                               GError          **error)
3115 {
3116   g_return_val_if_fail (g_task_is_valid (result, conn), FALSE);
3117
3118   return g_task_propagate_boolean (G_TASK (result), error);
3119 }
3120
3121 #if GLIB_CHECK_VERSION(2, 60, 0)
3122 static void
3123 g_tls_connection_gnutls_dtls_set_advertised_protocols (GDtlsConnection     *conn,
3124                                                        const gchar * const *protocols)
3125 {
3126   g_object_set (conn, "advertised-protocols", protocols, NULL);
3127 }
3128
3129 const gchar *
3130 g_tls_connection_gnutls_dtls_get_negotiated_protocol (GDtlsConnection *conn)
3131 {
3132   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (conn);
3133   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
3134
3135   return priv->negotiated_protocol;
3136 }
3137 #endif
3138
3139 static void
3140 g_tls_connection_gnutls_class_init (GTlsConnectionGnutlsClass *klass)
3141 {
3142   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
3143   GTlsConnectionClass *connection_class = G_TLS_CONNECTION_CLASS (klass);
3144   GIOStreamClass *iostream_class = G_IO_STREAM_CLASS (klass);
3145
3146   gobject_class->get_property = g_tls_connection_gnutls_get_property;
3147   gobject_class->set_property = g_tls_connection_gnutls_set_property;
3148   gobject_class->finalize     = g_tls_connection_gnutls_finalize;
3149
3150   connection_class->handshake        = g_tls_connection_gnutls_handshake;
3151   connection_class->handshake_async  = g_tls_connection_gnutls_handshake_async;
3152   connection_class->handshake_finish = g_tls_connection_gnutls_handshake_finish;
3153
3154   iostream_class->get_input_stream  = g_tls_connection_gnutls_get_input_stream;
3155   iostream_class->get_output_stream = g_tls_connection_gnutls_get_output_stream;
3156   iostream_class->close_fn          = g_tls_connection_gnutls_close;
3157   iostream_class->close_async       = g_tls_connection_gnutls_close_async;
3158   iostream_class->close_finish      = g_tls_connection_gnutls_close_finish;
3159
3160   /* For GTlsConnection and GDtlsConnection: */
3161   g_object_class_override_property (gobject_class, PROP_BASE_IO_STREAM, "base-io-stream");
3162   g_object_class_override_property (gobject_class, PROP_BASE_SOCKET, "base-socket");
3163   g_object_class_override_property (gobject_class, PROP_REQUIRE_CLOSE_NOTIFY, "require-close-notify");
3164   g_object_class_override_property (gobject_class, PROP_REHANDSHAKE_MODE, "rehandshake-mode");
3165   g_object_class_override_property (gobject_class, PROP_USE_SYSTEM_CERTDB, "use-system-certdb");
3166   g_object_class_override_property (gobject_class, PROP_DATABASE, "database");
3167   g_object_class_override_property (gobject_class, PROP_CERTIFICATE, "certificate");
3168   g_object_class_override_property (gobject_class, PROP_INTERACTION, "interaction");
3169   g_object_class_override_property (gobject_class, PROP_PEER_CERTIFICATE, "peer-certificate");
3170   g_object_class_override_property (gobject_class, PROP_PEER_CERTIFICATE_ERRORS, "peer-certificate-errors");
3171 #if GLIB_CHECK_VERSION(2, 60, 0)
3172   g_object_class_override_property (gobject_class, PROP_ADVERTISED_PROTOCOLS, "advertised-protocols");
3173   g_object_class_override_property (gobject_class, PROP_NEGOTIATED_PROTOCOL, "negotiated-protocol");
3174 #endif
3175 }
3176
3177 static void
3178 g_tls_connection_gnutls_initable_iface_init (GInitableIface *iface)
3179 {
3180   iface->init = g_tls_connection_gnutls_initable_init;
3181 }
3182
3183 static void
3184 g_tls_connection_gnutls_dtls_connection_iface_init (GDtlsConnectionInterface *iface)
3185 {
3186   iface->handshake = g_tls_connection_gnutls_dtls_handshake;
3187   iface->handshake_async = g_tls_connection_gnutls_dtls_handshake_async;
3188   iface->handshake_finish = g_tls_connection_gnutls_dtls_handshake_finish;
3189   iface->shutdown = g_tls_connection_gnutls_dtls_shutdown;
3190   iface->shutdown_async = g_tls_connection_gnutls_dtls_shutdown_async;
3191   iface->shutdown_finish = g_tls_connection_gnutls_dtls_shutdown_finish;
3192 #if GLIB_CHECK_VERSION(2, 60, 0)
3193   iface->set_advertised_protocols = g_tls_connection_gnutls_dtls_set_advertised_protocols;
3194   iface->get_negotiated_protocol = g_tls_connection_gnutls_dtls_get_negotiated_protocol;
3195 #endif
3196 }
3197
3198 static void
3199 g_tls_connection_gnutls_datagram_based_iface_init (GDatagramBasedInterface *iface)
3200 {
3201   iface->receive_messages = g_tls_connection_gnutls_receive_messages;
3202   iface->send_messages = g_tls_connection_gnutls_send_messages;
3203   iface->create_source = g_tls_connection_gnutls_dtls_create_source;
3204   iface->condition_check = g_tls_connection_gnutls_condition_check;
3205   iface->condition_wait = g_tls_connection_gnutls_condition_wait;
3206 }
3207
3208 gboolean
3209 g_tls_connection_gnutls_request_certificate (GTlsConnectionGnutls  *gnutls,
3210                                              GError               **error)
3211 {
3212   GTlsInteractionResult res = G_TLS_INTERACTION_UNHANDLED;
3213   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
3214   GTlsInteraction *interaction;
3215   GTlsConnection *conn;
3216
3217   g_return_val_if_fail (G_IS_TLS_CONNECTION_GNUTLS (gnutls), FALSE);
3218
3219   conn = G_TLS_CONNECTION (gnutls);
3220
3221   interaction = g_tls_connection_get_interaction (conn);
3222   if (!interaction)
3223     return FALSE;
3224
3225   res = g_tls_interaction_invoke_request_certificate (interaction, conn, 0,
3226                                                       priv->read_cancellable, error);
3227   return res != G_TLS_INTERACTION_FAILED;
3228 }
3229
3230 void
3231 GTLS_DEBUG (gpointer    gnutls,
3232             const char *message,
3233             ...)
3234 {
3235   char *result = NULL;
3236   int ret;
3237
3238   g_assert (G_IS_TLS_CONNECTION (gnutls));
3239
3240   va_list args;
3241   va_start (args, message);
3242
3243   ret = g_vasprintf (&result, message, args);
3244   g_assert (ret > 0);
3245
3246   if (G_IS_TLS_CLIENT_CONNECTION (gnutls))
3247     g_printf ("CLIENT %p: ", gnutls);
3248   else if (G_IS_TLS_SERVER_CONNECTION (gnutls))
3249     g_printf ("SERVER %p: ", gnutls);
3250   else
3251     g_assert_not_reached ();
3252
3253   g_printf ("%s\n", result);
3254
3255   fflush (stdout);
3256
3257   g_free (result);
3258   va_end (args);
3259 }