Imported Upstream version 2.35.9
[platform/upstream/glib-networking.git] / tls / gnutls / gtlsconnection-gnutls.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright 2009 Red Hat, Inc
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, see
17  * <http://www.gnu.org/licenses/>.
18  */
19
20 #include "config.h"
21 #include "glib.h"
22
23 #include <errno.h>
24 #include <gnutls/gnutls.h>
25 #include <gnutls/x509.h>
26
27 #include "gtlsconnection-gnutls.h"
28 #include "gtlsbackend-gnutls.h"
29 #include "gtlscertificate-gnutls.h"
30 #include "gtlsinputstream-gnutls.h"
31 #include "gtlsoutputstream-gnutls.h"
32 #include "gtlsserverconnection-gnutls.h"
33
34 #ifdef HAVE_PKCS11
35 #include <p11-kit/pin.h>
36 #include "pkcs11/gpkcs11pin.h"
37 #endif
38
39 #include <glib/gi18n-lib.h>
40
41 static ssize_t g_tls_connection_gnutls_push_func (gnutls_transport_ptr_t  transport_data,
42                                                   const void             *buf,
43                                                   size_t                  buflen);
44 static ssize_t g_tls_connection_gnutls_pull_func (gnutls_transport_ptr_t  transport_data,
45                                                   void                   *buf,
46                                                   size_t                  buflen);
47
48 static void     g_tls_connection_gnutls_initable_iface_init (GInitableIface  *iface);
49 static gboolean g_tls_connection_gnutls_initable_init       (GInitable       *initable,
50                                                              GCancellable    *cancellable,
51                                                              GError         **error);
52
53 #ifdef HAVE_PKCS11
54 static P11KitPin*    on_pin_prompt_callback  (const char     *pinfile,
55                                               P11KitUri      *pin_uri,
56                                               const char     *pin_description,
57                                               P11KitPinFlags  pin_flags,
58                                               void           *callback_data);
59 #endif
60
61 static void g_tls_connection_gnutls_init_priorities (void);
62
63 static gboolean do_implicit_handshake (GTlsConnectionGnutls  *gnutls,
64                                        gboolean               blocking,
65                                        GCancellable          *cancellable,
66                                        GError               **error);
67 static gboolean finish_handshake (GTlsConnectionGnutls  *gnutls,
68                                   GTask                 *thread_task,
69                                   GError               **error);
70
71 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GTlsConnectionGnutls, g_tls_connection_gnutls, G_TYPE_TLS_CONNECTION,
72                                   G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
73                                                          g_tls_connection_gnutls_initable_iface_init);
74                                   g_tls_connection_gnutls_init_priorities ();
75                                   );
76
77
78 enum
79 {
80   PROP_0,
81   PROP_BASE_IO_STREAM,
82   PROP_REQUIRE_CLOSE_NOTIFY,
83   PROP_REHANDSHAKE_MODE,
84   PROP_USE_SYSTEM_CERTDB,
85   PROP_DATABASE,
86   PROP_CERTIFICATE,
87   PROP_INTERACTION,
88   PROP_PEER_CERTIFICATE,
89   PROP_PEER_CERTIFICATE_ERRORS
90 };
91
92 struct _GTlsConnectionGnutlsPrivate
93 {
94   GIOStream *base_io_stream;
95   GPollableInputStream *base_istream;
96   GPollableOutputStream *base_ostream;
97
98   gnutls_certificate_credentials creds;
99   gnutls_session session;
100
101   GTlsCertificate *certificate, *peer_certificate;
102   GTlsCertificateFlags peer_certificate_errors;
103   GTlsCertificate *peer_certificate_tmp;
104   GTlsCertificateFlags peer_certificate_errors_tmp;
105
106   gboolean require_close_notify;
107   GTlsRehandshakeMode rehandshake_mode;
108   gboolean is_system_certdb;
109   GTlsDatabase *database;
110   gboolean database_is_unset;
111
112   /* need_handshake means the next claim_op() will get diverted into
113    * an implicit handshake (unless it's an OP_HANDSHAKE or OP_CLOSE).
114    * need_finish_handshake means the next claim_op() will get diverted
115    * into finish_handshake() (unless it's an OP_CLOSE).
116    *
117    * handshaking is TRUE as soon as a handshake thread is queued. For
118    * a sync handshake it becomes FALSE after finish_handshake()
119    * completes in the calling thread, but for an async implicit
120    * handshake, it becomes FALSE (and need_finish_handshake becomes
121    * TRUE) at the end of the handshaking thread (and then the next
122    * non-close op will call finish_handshake()). We can't just wait
123    * for handshake_thread_completed() to run, because it's possible
124    * that its main loop is being blocked by a synchronous op which is
125    * waiting for handshaking to become FALSE...
126    *
127    * started_handshake indicates that the current handshake attempt
128    * got at least as far as calling gnutls_handshake() (and so any
129    * error should be copied to handshake_error and returned on all
130    * future operations). ever_handshaked indicates that TLS has
131    * been successfully negotiated at some point.
132    */
133   gboolean need_handshake, need_finish_handshake;
134   gboolean started_handshake, handshaking, ever_handshaked;
135   GTask *implicit_handshake;
136   GError *handshake_error;
137
138   gboolean closing, closed;
139
140   GInputStream *tls_istream;
141   GOutputStream *tls_ostream;
142
143   GTlsInteraction *interaction;
144   gchar *interaction_id;
145
146   GMutex        op_mutex;
147   GCancellable *waiting_for_op;
148
149   gboolean      reading;
150   gboolean      read_blocking;
151   GError       *read_error;
152   GCancellable *read_cancellable;
153
154   gboolean      writing;
155   gboolean      write_blocking;
156   GError       *write_error;
157   GCancellable *write_cancellable;
158
159 #ifndef GNUTLS_E_PREMATURE_TERMINATION
160   gboolean eof;
161 #endif
162 };
163
164 static gint unique_interaction_id = 0;
165
166 static void
167 g_tls_connection_gnutls_init (GTlsConnectionGnutls *gnutls)
168 {
169   gint unique_id;
170
171   gnutls->priv = G_TYPE_INSTANCE_GET_PRIVATE (gnutls, G_TYPE_TLS_CONNECTION_GNUTLS, GTlsConnectionGnutlsPrivate);
172
173   gnutls_certificate_allocate_credentials (&gnutls->priv->creds);
174   gnutls_certificate_set_verify_flags (gnutls->priv->creds,
175                                        GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
176
177   gnutls->priv->need_handshake = TRUE;
178
179   gnutls->priv->database_is_unset = TRUE;
180   gnutls->priv->is_system_certdb = TRUE;
181
182   unique_id = g_atomic_int_add (&unique_interaction_id, 1);
183   gnutls->priv->interaction_id = g_strdup_printf ("gtls:%d", unique_id);
184
185 #ifdef HAVE_PKCS11
186   p11_kit_pin_register_callback (gnutls->priv->interaction_id,
187                                  on_pin_prompt_callback, gnutls, NULL);
188 #endif
189
190   gnutls->priv->waiting_for_op = g_cancellable_new ();
191   g_cancellable_cancel (gnutls->priv->waiting_for_op);
192   g_mutex_init (&gnutls->priv->op_mutex);
193 }
194
195 /* First field is "ssl3 only", second is "allow unsafe rehandshaking" */
196 static gnutls_priority_t priorities[2][2];
197
198 static void
199 g_tls_connection_gnutls_init_priorities (void)
200 {
201   const gchar *base_priority;
202   gchar *ssl3_priority, *unsafe_rehandshake_priority, *ssl3_unsafe_rehandshake_priority;
203
204   base_priority = g_getenv ("G_TLS_GNUTLS_PRIORITY");
205   if (!base_priority)
206     base_priority = "NORMAL:%COMPAT";
207
208   ssl3_priority = g_strdup_printf ("%s:!VERS-TLS1.2:!VERS-TLS1.1:!VERS-TLS1.0", base_priority);
209   unsafe_rehandshake_priority = g_strdup_printf ("%s:%%UNSAFE_RENEGOTIATION", base_priority);
210   ssl3_unsafe_rehandshake_priority = g_strdup_printf ("%s:!VERS-TLS1.2:!VERS-TLS1.1:!VERS-TLS1.0:%%UNSAFE_RENEGOTIATION", base_priority);
211
212   gnutls_priority_init (&priorities[FALSE][FALSE], base_priority, NULL);
213   gnutls_priority_init (&priorities[TRUE][FALSE], ssl3_priority, NULL);
214   gnutls_priority_init (&priorities[FALSE][TRUE], unsafe_rehandshake_priority, NULL);
215   gnutls_priority_init (&priorities[TRUE][TRUE], ssl3_unsafe_rehandshake_priority, NULL);
216
217   g_free (ssl3_priority);
218   g_free (unsafe_rehandshake_priority);
219   g_free (ssl3_unsafe_rehandshake_priority);
220 }
221
222 static void
223 g_tls_connection_gnutls_set_handshake_priority (GTlsConnectionGnutls *gnutls)
224 {
225   gboolean use_ssl3, unsafe_rehandshake;
226
227   if (G_IS_TLS_CLIENT_CONNECTION (gnutls))
228     use_ssl3 = g_tls_client_connection_get_use_ssl3 (G_TLS_CLIENT_CONNECTION (gnutls));
229   else
230     use_ssl3 = FALSE;
231   unsafe_rehandshake = (gnutls->priv->rehandshake_mode == G_TLS_REHANDSHAKE_UNSAFELY);
232   gnutls_priority_set (gnutls->priv->session,
233                        priorities[use_ssl3][unsafe_rehandshake]);
234 }
235
236 static gboolean
237 g_tls_connection_gnutls_initable_init (GInitable     *initable,
238                                        GCancellable  *cancellable,
239                                        GError       **error)
240 {
241   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (initable);
242   int status;
243
244   g_return_val_if_fail (gnutls->priv->base_istream != NULL &&
245                         gnutls->priv->base_ostream != NULL, FALSE);
246
247   /* Make sure gnutls->priv->session has been initialized (it may have
248    * already been initialized by a construct-time property setter).
249    */
250   g_tls_connection_gnutls_get_session (gnutls);
251
252   status = gnutls_credentials_set (gnutls->priv->session,
253                                    GNUTLS_CRD_CERTIFICATE,
254                                    gnutls->priv->creds);
255   if (status != 0)
256     {
257       g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
258                    _("Could not create TLS connection: %s"),
259                    gnutls_strerror (status));
260       return FALSE;
261     }
262
263   /* Some servers (especially on embedded devices) use tiny keys that
264    * gnutls will reject by default. We want it to accept them.
265    */
266   gnutls_dh_set_prime_bits (gnutls->priv->session, 256);
267
268   gnutls_transport_set_push_function (gnutls->priv->session,
269                                       g_tls_connection_gnutls_push_func);
270   gnutls_transport_set_pull_function (gnutls->priv->session,
271                                       g_tls_connection_gnutls_pull_func);
272   gnutls_transport_set_ptr (gnutls->priv->session, gnutls);
273
274   gnutls->priv->tls_istream = g_tls_input_stream_gnutls_new (gnutls);
275   gnutls->priv->tls_ostream = g_tls_output_stream_gnutls_new (gnutls);
276
277   return TRUE;
278 }
279
280 static void
281 g_tls_connection_gnutls_finalize (GObject *object)
282 {
283   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
284
285   g_clear_object (&gnutls->priv->base_io_stream);
286
287   g_clear_object (&gnutls->priv->tls_istream);
288   g_clear_object (&gnutls->priv->tls_ostream);
289
290   if (gnutls->priv->session)
291     gnutls_deinit (gnutls->priv->session);
292   if (gnutls->priv->creds)
293     gnutls_certificate_free_credentials (gnutls->priv->creds);
294
295   g_clear_object (&gnutls->priv->database);
296   g_clear_object (&gnutls->priv->certificate);
297   g_clear_object (&gnutls->priv->peer_certificate);
298   g_clear_object (&gnutls->priv->peer_certificate_tmp);
299
300 #ifdef HAVE_PKCS11
301   p11_kit_pin_unregister_callback (gnutls->priv->interaction_id,
302                                    on_pin_prompt_callback, gnutls);
303 #endif
304   g_free (gnutls->priv->interaction_id);
305   g_clear_object (&gnutls->priv->interaction);
306
307   g_clear_error (&gnutls->priv->handshake_error);
308   g_clear_error (&gnutls->priv->read_error);
309   g_clear_error (&gnutls->priv->write_error);
310
311   g_clear_object (&gnutls->priv->waiting_for_op);
312   g_mutex_clear (&gnutls->priv->op_mutex);
313
314   G_OBJECT_CLASS (g_tls_connection_gnutls_parent_class)->finalize (object);
315 }
316
317 static void
318 g_tls_connection_gnutls_get_property (GObject    *object,
319                                       guint       prop_id,
320                                       GValue     *value,
321                                       GParamSpec *pspec)
322 {
323   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
324   GTlsBackend *backend;
325
326   switch (prop_id)
327     {
328     case PROP_BASE_IO_STREAM:
329       g_value_set_object (value, gnutls->priv->base_io_stream);
330       break;
331
332     case PROP_REQUIRE_CLOSE_NOTIFY:
333       g_value_set_boolean (value, gnutls->priv->require_close_notify);
334       break;
335
336     case PROP_REHANDSHAKE_MODE:
337       g_value_set_enum (value, gnutls->priv->rehandshake_mode);
338       break;
339
340     case PROP_USE_SYSTEM_CERTDB:
341       g_value_set_boolean (value, gnutls->priv->is_system_certdb);
342       break;
343
344     case PROP_DATABASE:
345       if (gnutls->priv->database_is_unset)
346         {
347           backend = g_tls_backend_get_default ();
348           gnutls->priv->database =  g_tls_backend_get_default_database (backend);
349           gnutls->priv->database_is_unset = FALSE;
350         }
351       g_value_set_object (value, gnutls->priv->database);
352       break;
353
354     case PROP_CERTIFICATE:
355       g_value_set_object (value, gnutls->priv->certificate);
356       break;
357
358     case PROP_INTERACTION:
359       g_value_set_object (value, gnutls->priv->interaction);
360       break;
361
362     case PROP_PEER_CERTIFICATE:
363       g_value_set_object (value, gnutls->priv->peer_certificate);
364       break;
365
366     case PROP_PEER_CERTIFICATE_ERRORS:
367       g_value_set_flags (value, gnutls->priv->peer_certificate_errors);
368       break;
369
370     default:
371       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
372     }
373 }
374
375 static void
376 g_tls_connection_gnutls_set_property (GObject      *object,
377                                       guint         prop_id,
378                                       const GValue *value,
379                                       GParamSpec   *pspec)
380 {
381   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
382   GInputStream *istream;
383   GOutputStream *ostream;
384   gboolean system_certdb;
385   GTlsBackend *backend;
386
387   switch (prop_id)
388     {
389     case PROP_BASE_IO_STREAM:
390       if (gnutls->priv->base_io_stream)
391         {
392           g_object_unref (gnutls->priv->base_io_stream);
393           gnutls->priv->base_istream = NULL;
394           gnutls->priv->base_ostream = NULL;
395         }
396       gnutls->priv->base_io_stream = g_value_dup_object (value);
397       if (!gnutls->priv->base_io_stream)
398         return;
399
400       istream = g_io_stream_get_input_stream (gnutls->priv->base_io_stream);
401       ostream = g_io_stream_get_output_stream (gnutls->priv->base_io_stream);
402
403       if (G_IS_POLLABLE_INPUT_STREAM (istream) &&
404           g_pollable_input_stream_can_poll (G_POLLABLE_INPUT_STREAM (istream)))
405         gnutls->priv->base_istream = G_POLLABLE_INPUT_STREAM (istream);
406       if (G_IS_POLLABLE_OUTPUT_STREAM (ostream) &&
407           g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (ostream)))
408         gnutls->priv->base_ostream = G_POLLABLE_OUTPUT_STREAM (ostream);
409       break;
410
411     case PROP_REQUIRE_CLOSE_NOTIFY:
412       gnutls->priv->require_close_notify = g_value_get_boolean (value);
413       break;
414
415     case PROP_REHANDSHAKE_MODE:
416       gnutls->priv->rehandshake_mode = g_value_get_enum (value);
417       break;
418
419     case PROP_USE_SYSTEM_CERTDB:
420       system_certdb = g_value_get_boolean (value);
421       if (system_certdb != gnutls->priv->is_system_certdb)
422         {
423           g_clear_object (&gnutls->priv->database);
424           if (system_certdb)
425             {
426               backend = g_tls_backend_get_default ();
427               gnutls->priv->database = g_tls_backend_get_default_database (backend);
428             }
429           gnutls->priv->is_system_certdb = system_certdb;
430           gnutls->priv->database_is_unset = FALSE;
431         }
432       break;
433
434     case PROP_DATABASE:
435       g_clear_object (&gnutls->priv->database);
436       gnutls->priv->database = g_value_dup_object (value);
437       gnutls->priv->is_system_certdb = FALSE;
438       gnutls->priv->database_is_unset = FALSE;
439       break;
440
441     case PROP_CERTIFICATE:
442       if (gnutls->priv->certificate)
443         g_object_unref (gnutls->priv->certificate);
444       gnutls->priv->certificate = g_value_dup_object (value);
445       break;
446
447     case PROP_INTERACTION:
448       g_clear_object (&gnutls->priv->interaction);
449       gnutls->priv->interaction = g_value_dup_object (value);
450       break;
451
452     default:
453       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
454     }
455 }
456
457 gnutls_certificate_credentials
458 g_tls_connection_gnutls_get_credentials (GTlsConnectionGnutls *gnutls)
459 {
460   return gnutls->priv->creds;
461 }
462
463 gnutls_session
464 g_tls_connection_gnutls_get_session (GTlsConnectionGnutls *gnutls)
465 {
466   /* Ideally we would initialize gnutls->priv->session from
467    * g_tls_connection_gnutls_init(), but we can't tell if it's a
468    * client or server connection at that point... And
469    * g_tls_connection_gnutls_initiable_init() is too late, because
470    * construct-time property setters may need to modify it.
471    */
472   if (!gnutls->priv->session)
473     {
474       gboolean client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
475       gnutls_init (&gnutls->priv->session, client ? GNUTLS_CLIENT : GNUTLS_SERVER);
476     }
477
478   return gnutls->priv->session;
479 }
480
481 void
482 g_tls_connection_gnutls_get_certificate (GTlsConnectionGnutls *gnutls,
483                                          gnutls_retr2_st      *st)
484 {
485   GTlsCertificate *cert;
486
487   cert = g_tls_connection_get_certificate (G_TLS_CONNECTION (gnutls));
488
489   st->cert_type = GNUTLS_CRT_X509;
490   st->ncerts = 0;
491
492   if (cert)
493       g_tls_certificate_gnutls_copy (G_TLS_CERTIFICATE_GNUTLS (cert),
494                                      gnutls->priv->interaction_id, st);
495 }
496
497 typedef enum {
498   G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE,
499   G_TLS_CONNECTION_GNUTLS_OP_READ,
500   G_TLS_CONNECTION_GNUTLS_OP_WRITE,
501   G_TLS_CONNECTION_GNUTLS_OP_CLOSE,
502 } GTlsConnectionGnutlsOp;
503
504 static gboolean
505 claim_op (GTlsConnectionGnutls    *gnutls,
506           GTlsConnectionGnutlsOp   op,
507           gboolean                 blocking,
508           GCancellable            *cancellable,
509           GError                 **error)
510 {
511  try_again:
512   if (g_cancellable_set_error_if_cancelled (cancellable, error))
513     return FALSE;
514
515   g_mutex_lock (&gnutls->priv->op_mutex);
516
517   if (gnutls->priv->closing || gnutls->priv->closed)
518     {
519       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
520                            _("Connection is closed"));
521       g_mutex_unlock (&gnutls->priv->op_mutex);
522       return FALSE;
523     }
524
525   if (gnutls->priv->handshake_error && op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE)
526     {
527       if (error)
528         *error = g_error_copy (gnutls->priv->handshake_error);
529       g_mutex_unlock (&gnutls->priv->op_mutex);
530       return FALSE;
531     }
532
533   if (op != G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE &&
534       op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE)
535     {
536       if (gnutls->priv->need_handshake)
537         {
538           gnutls->priv->need_handshake = FALSE;
539           gnutls->priv->handshaking = TRUE;
540           if (!do_implicit_handshake (gnutls, blocking, cancellable, error))
541             {
542               g_mutex_unlock (&gnutls->priv->op_mutex);
543               return FALSE;
544             }
545         }
546
547       if (gnutls->priv->need_finish_handshake)
548         {
549           GError *my_error = NULL;
550           gboolean success;
551
552           gnutls->priv->need_finish_handshake = FALSE;
553
554           g_mutex_unlock (&gnutls->priv->op_mutex);
555           success = finish_handshake (gnutls, gnutls->priv->implicit_handshake, &my_error);
556           g_clear_object (&gnutls->priv->implicit_handshake);
557           g_mutex_lock (&gnutls->priv->op_mutex);
558
559           if (!success || g_cancellable_set_error_if_cancelled (cancellable, &my_error))
560             {
561               g_propagate_error (error, my_error);
562               g_mutex_unlock (&gnutls->priv->op_mutex);
563               return FALSE;
564             }
565         }
566     }
567
568   if ((op != G_TLS_CONNECTION_GNUTLS_OP_WRITE && gnutls->priv->reading) ||
569       (op != G_TLS_CONNECTION_GNUTLS_OP_READ && gnutls->priv->writing) ||
570       (op != G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE && gnutls->priv->handshaking))
571     {
572       GPollFD fds[2];
573       int nfds;
574
575       g_cancellable_reset (gnutls->priv->waiting_for_op);
576
577       g_mutex_unlock (&gnutls->priv->op_mutex);
578
579       if (!blocking)
580         {
581           g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
582                                _("Operation would block"));
583           return FALSE;
584         }
585
586       g_cancellable_make_pollfd (gnutls->priv->waiting_for_op, &fds[0]);
587       if (g_cancellable_make_pollfd (cancellable, &fds[0]))
588         nfds = 2;
589       else
590         nfds = 1;
591       g_poll (fds, nfds, -1);
592       g_cancellable_release_fd (cancellable);
593
594       goto try_again;
595     }
596
597   if (op == G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE)
598     {
599       gnutls->priv->handshaking = TRUE;
600       gnutls->priv->need_handshake = FALSE;
601     }
602   if (op == G_TLS_CONNECTION_GNUTLS_OP_CLOSE)
603     gnutls->priv->closing = TRUE;
604
605   if (op != G_TLS_CONNECTION_GNUTLS_OP_WRITE)
606     gnutls->priv->reading = TRUE;
607   if (op != G_TLS_CONNECTION_GNUTLS_OP_READ)
608     gnutls->priv->writing = TRUE;
609
610   g_mutex_unlock (&gnutls->priv->op_mutex);
611   return TRUE;
612 }
613
614 static void
615 yield_op (GTlsConnectionGnutls   *gnutls,
616           GTlsConnectionGnutlsOp  op)
617 {
618   g_mutex_lock (&gnutls->priv->op_mutex);
619
620   if (op == G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE)
621     gnutls->priv->handshaking = FALSE;
622   if (op == G_TLS_CONNECTION_GNUTLS_OP_CLOSE)
623     gnutls->priv->closing = FALSE;
624
625   if (op != G_TLS_CONNECTION_GNUTLS_OP_WRITE)
626     gnutls->priv->reading = FALSE;
627   if (op != G_TLS_CONNECTION_GNUTLS_OP_READ)
628     gnutls->priv->writing = FALSE;
629
630   g_cancellable_cancel (gnutls->priv->waiting_for_op);
631   g_mutex_unlock (&gnutls->priv->op_mutex);
632 }
633
634 static void
635 begin_gnutls_io (GTlsConnectionGnutls  *gnutls,
636                  GIOCondition           direction,
637                  gboolean               blocking,
638                  GCancellable          *cancellable)
639 {
640   g_assert (direction & (G_IO_IN | G_IO_OUT));
641
642   if (direction & G_IO_IN)
643     {
644       gnutls->priv->read_blocking = blocking;
645       gnutls->priv->read_cancellable = cancellable;
646       g_clear_error (&gnutls->priv->read_error);
647     }
648
649   if (direction & G_IO_OUT)
650     {
651       gnutls->priv->write_blocking = blocking;
652       gnutls->priv->write_cancellable = cancellable;
653       g_clear_error (&gnutls->priv->write_error);
654     }
655 }
656
657 static int
658 end_gnutls_io (GTlsConnectionGnutls  *gnutls,
659                GIOCondition           direction,
660                int                    status,
661                const char            *errmsg,
662                GError               **error)
663 {
664   GError *my_error = NULL;
665
666   g_assert (direction & (G_IO_IN | G_IO_OUT));
667   g_assert (!error || !*error);
668
669   if (status == GNUTLS_E_AGAIN ||
670       status == GNUTLS_E_WARNING_ALERT_RECEIVED)
671     return GNUTLS_E_AGAIN;
672
673   if (direction & G_IO_IN)
674     {
675       gnutls->priv->read_cancellable = NULL;
676       if (status < 0)
677         {
678           my_error = gnutls->priv->read_error;
679           gnutls->priv->read_error = NULL;
680         }
681       else
682         g_clear_error (&gnutls->priv->read_error);
683     }
684   if (direction & G_IO_OUT)
685     {
686       gnutls->priv->write_cancellable = NULL;
687       if (status < 0 && !my_error)
688         {
689           my_error = gnutls->priv->write_error;
690           gnutls->priv->write_error = NULL;
691         }
692       else
693         g_clear_error (&gnutls->priv->write_error);
694     }
695
696   if (status >= 0)
697     return status;
698
699   if (gnutls->priv->handshaking && !gnutls->priv->ever_handshaked)
700     {
701       if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_FAILED) ||
702 #if GLIB_CHECK_VERSION (2, 35, 3)
703           g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE) ||
704 #endif
705           status == GNUTLS_E_UNEXPECTED_PACKET_LENGTH ||
706           status == GNUTLS_E_FATAL_ALERT_RECEIVED ||
707           status == GNUTLS_E_DECRYPTION_FAILED ||
708           status == GNUTLS_E_UNSUPPORTED_VERSION_PACKET)
709         {
710           g_clear_error (&my_error);
711           g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS,
712                                _("Peer failed to perform TLS handshake"));
713           return GNUTLS_E_PULL_ERROR;
714         }
715     }
716
717   if (my_error)
718     {
719       if (!g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
720         G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->failed (gnutls);
721       g_propagate_error (error, my_error);
722       return status;
723     }
724   else if (status == GNUTLS_E_REHANDSHAKE)
725     {
726       if (gnutls->priv->rehandshake_mode == G_TLS_REHANDSHAKE_NEVER)
727         {
728           g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
729                                _("Peer requested illegal TLS rehandshake"));
730           return GNUTLS_E_PULL_ERROR;
731         }
732
733       g_mutex_lock (&gnutls->priv->op_mutex);
734       if (!gnutls->priv->handshaking)
735         gnutls->priv->need_handshake = TRUE;
736       g_mutex_unlock (&gnutls->priv->op_mutex);
737       return status;
738     }
739   else if (status == GNUTLS_E_GOT_APPLICATION_DATA)
740     {
741       if (gnutls->priv->handshaking && G_IS_TLS_SERVER_CONNECTION (gnutls))
742         return GNUTLS_E_AGAIN;
743     }
744   else if (
745 #ifdef GNUTLS_E_PREMATURE_TERMINATION
746            status == GNUTLS_E_PREMATURE_TERMINATION
747 #else
748            status == GNUTLS_E_UNEXPECTED_PACKET_LENGTH && gnutls->priv->eof
749 #endif
750            )
751     {
752       if (gnutls->priv->handshaking && !gnutls->priv->ever_handshaked)
753         {
754           g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS,
755                                _("Peer failed to perform TLS handshake"));
756           return GNUTLS_E_PULL_ERROR;
757         }
758       else if (gnutls->priv->require_close_notify)
759         {
760           g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_EOF,
761                                _("TLS connection closed unexpectedly"));
762           G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->failed (gnutls);
763           return status;
764         }
765       else
766         return 0;
767     }
768   else if (status == GNUTLS_E_NO_CERTIFICATE_FOUND)
769     {
770       g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED,
771                            _("TLS connection peer did not send a certificate"));
772       return status;
773     }
774
775   if (error)
776     {
777       g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
778                    errmsg, gnutls_strerror (status));
779     }
780   return status;
781 }
782
783 #define BEGIN_GNUTLS_IO(gnutls, direction, blocking, cancellable)       \
784   begin_gnutls_io (gnutls, direction, blocking, cancellable);           \
785   do {
786
787 #define END_GNUTLS_IO(gnutls, direction, ret, errmsg, err)              \
788   } while ((ret = end_gnutls_io (gnutls, direction, ret, errmsg, err)) == GNUTLS_E_AGAIN);
789
790 gboolean
791 g_tls_connection_gnutls_check (GTlsConnectionGnutls  *gnutls,
792                                GIOCondition           condition)
793 {
794   /* Racy, but worst case is that we just get WOULD_BLOCK back */
795   if (gnutls->priv->need_finish_handshake)
796     return TRUE;
797
798   /* If a handshake or close is in progress, then tls_istream and
799    * tls_ostream are blocked, regardless of the base stream status.
800    */
801   if (gnutls->priv->handshaking || gnutls->priv->closing)
802     return FALSE;
803
804   if (condition & G_IO_IN)
805     return g_pollable_input_stream_is_readable (gnutls->priv->base_istream);
806   else
807     return g_pollable_output_stream_is_writable (gnutls->priv->base_ostream);
808 }
809
810 typedef struct {
811   GSource               source;
812
813   GTlsConnectionGnutls *gnutls;
814   GObject              *stream;
815
816   GSource              *child_source;
817   GIOCondition          condition;
818
819   gboolean              io_waiting;
820   gboolean              op_waiting;
821 } GTlsConnectionGnutlsSource;
822
823 static gboolean
824 gnutls_source_prepare (GSource *source,
825                        gint    *timeout)
826 {
827   *timeout = -1;
828   return FALSE;
829 }
830
831 static gboolean
832 gnutls_source_check (GSource *source)
833 {
834   return FALSE;
835 }
836
837 static void
838 gnutls_source_sync (GTlsConnectionGnutlsSource *gnutls_source)
839 {
840   GTlsConnectionGnutls *gnutls = gnutls_source->gnutls;
841   gboolean io_waiting, op_waiting;
842
843   g_mutex_lock (&gnutls->priv->op_mutex);
844   if (((gnutls_source->condition & G_IO_IN) && gnutls->priv->reading) ||
845       ((gnutls_source->condition & G_IO_OUT) && gnutls->priv->writing) ||
846       (gnutls->priv->handshaking && !gnutls->priv->need_finish_handshake))
847     op_waiting = TRUE;
848   else
849     op_waiting = FALSE;
850
851   if (!op_waiting && !gnutls->priv->need_handshake &&
852       !gnutls->priv->need_finish_handshake)
853     io_waiting = TRUE;
854   else
855     io_waiting = FALSE;
856   g_mutex_unlock (&gnutls->priv->op_mutex);
857
858   if (op_waiting == gnutls_source->op_waiting &&
859       io_waiting == gnutls_source->io_waiting)
860     return;
861   gnutls_source->op_waiting = op_waiting;
862   gnutls_source->io_waiting = io_waiting;
863
864   if (gnutls_source->child_source)
865     {
866       g_source_remove_child_source ((GSource *)gnutls_source,
867                                     gnutls_source->child_source);
868       g_source_unref (gnutls_source->child_source);
869     }
870
871   if (op_waiting)
872     gnutls_source->child_source = g_cancellable_source_new (gnutls->priv->waiting_for_op);
873   else if (io_waiting && G_IS_POLLABLE_INPUT_STREAM (gnutls_source->stream))
874     gnutls_source->child_source = g_pollable_input_stream_create_source (gnutls->priv->base_istream, NULL);
875   else if (io_waiting && G_IS_POLLABLE_OUTPUT_STREAM (gnutls_source->stream))
876     gnutls_source->child_source = g_pollable_output_stream_create_source (gnutls->priv->base_ostream, NULL);
877   else
878     gnutls_source->child_source = g_timeout_source_new (0);
879
880   g_source_set_dummy_callback (gnutls_source->child_source);
881   g_source_add_child_source ((GSource *)gnutls_source, gnutls_source->child_source);
882 }
883
884 static gboolean
885 gnutls_source_dispatch (GSource     *source,
886                         GSourceFunc  callback,
887                         gpointer     user_data)
888 {
889   GPollableSourceFunc func = (GPollableSourceFunc)callback;
890   GTlsConnectionGnutlsSource *gnutls_source = (GTlsConnectionGnutlsSource *)source;
891   gboolean ret;
892
893   ret = (*func) (gnutls_source->stream, user_data);
894   if (ret)
895     gnutls_source_sync (gnutls_source);
896
897   return ret;
898 }
899
900 static void
901 gnutls_source_finalize (GSource *source)
902 {
903   GTlsConnectionGnutlsSource *gnutls_source = (GTlsConnectionGnutlsSource *)source;
904
905   g_object_unref (gnutls_source->gnutls);
906   g_source_unref (gnutls_source->child_source);
907 }
908
909 static gboolean
910 g_tls_connection_gnutls_source_closure_callback (GObject  *stream,
911                                                  gpointer  data)
912 {
913   GClosure *closure = data;
914
915   GValue param = { 0, };
916   GValue result_value = { 0, };
917   gboolean result;
918
919   g_value_init (&result_value, G_TYPE_BOOLEAN);
920
921   g_value_init (&param, G_TYPE_OBJECT);
922   g_value_set_object (&param, stream);
923
924   g_closure_invoke (closure, &result_value, 1, &param, NULL);
925
926   result = g_value_get_boolean (&result_value);
927   g_value_unset (&result_value);
928   g_value_unset (&param);
929
930   return result;
931 }
932
933 static GSourceFuncs gnutls_source_funcs =
934 {
935   gnutls_source_prepare,
936   gnutls_source_check,
937   gnutls_source_dispatch,
938   gnutls_source_finalize,
939   (GSourceFunc)g_tls_connection_gnutls_source_closure_callback,
940   (GSourceDummyMarshal)g_cclosure_marshal_generic
941 };
942
943 GSource *
944 g_tls_connection_gnutls_create_source (GTlsConnectionGnutls  *gnutls,
945                                        GIOCondition           condition,
946                                        GCancellable          *cancellable)
947 {
948   GSource *source, *cancellable_source;
949   GTlsConnectionGnutlsSource *gnutls_source;
950
951   source = g_source_new (&gnutls_source_funcs, sizeof (GTlsConnectionGnutlsSource));
952   g_source_set_name (source, "GTlsConnectionGnutlsSource");
953   gnutls_source = (GTlsConnectionGnutlsSource *)source;
954   gnutls_source->gnutls = g_object_ref (gnutls);
955   gnutls_source->condition = condition;
956   if (condition & G_IO_IN)
957     gnutls_source->stream = G_OBJECT (gnutls->priv->tls_istream);
958   else if (condition & G_IO_OUT)
959     gnutls_source->stream = G_OBJECT (gnutls->priv->tls_ostream);
960
961   gnutls_source->op_waiting = (gboolean) -1;
962   gnutls_source->io_waiting = (gboolean) -1;
963   gnutls_source_sync (gnutls_source);
964
965   if (cancellable)
966     {
967       cancellable_source = g_cancellable_source_new (cancellable);
968       g_source_set_dummy_callback (cancellable_source);
969       g_source_add_child_source (source, cancellable_source);
970       g_source_unref (cancellable_source);
971     }
972
973   return source;
974 }
975
976 static void
977 set_gnutls_error (GTlsConnectionGnutls *gnutls,
978                   GError               *error)
979 {
980   /* We set EINTR rather than EAGAIN for G_IO_ERROR_WOULD_BLOCK so
981    * that GNUTLS_E_AGAIN only gets returned for gnutls-internal
982    * reasons, not for actual socket EAGAINs (and we have access
983    * to @error at the higher levels, so we can distinguish them
984    * that way later).
985    */
986
987   if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
988     gnutls_transport_set_errno (gnutls->priv->session, EINTR);
989   else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
990     gnutls_transport_set_errno (gnutls->priv->session, EINTR);
991   else
992     gnutls_transport_set_errno (gnutls->priv->session, EIO);
993 }
994
995 static ssize_t
996 g_tls_connection_gnutls_pull_func (gnutls_transport_ptr_t  transport_data,
997                                    void                   *buf,
998                                    size_t                  buflen)
999 {
1000   GTlsConnectionGnutls *gnutls = transport_data;
1001   ssize_t ret;
1002
1003   /* If gnutls->priv->read_error is non-%NULL when we're called, it means
1004    * that an error previously occurred, but gnutls decided not to
1005    * propagate it. So it's correct for us to just clear it. (Usually
1006    * this means it ignored an EAGAIN after a short read, and now
1007    * we'll return EAGAIN again, which it will obey this time.)
1008    */
1009   g_clear_error (&gnutls->priv->read_error);
1010
1011   ret = g_pollable_stream_read (G_INPUT_STREAM (gnutls->priv->base_istream),
1012                                 buf, buflen,
1013                                 gnutls->priv->read_blocking,
1014                                 gnutls->priv->read_cancellable,
1015                                 &gnutls->priv->read_error);
1016
1017   if (ret < 0)
1018     set_gnutls_error (gnutls, gnutls->priv->read_error);
1019 #ifndef GNUTLS_E_PREMATURE_TERMINATION
1020   else if (ret == 0)
1021     gnutls->priv->eof = TRUE;
1022 #endif
1023
1024   return ret;
1025 }
1026
1027 static ssize_t
1028 g_tls_connection_gnutls_push_func (gnutls_transport_ptr_t  transport_data,
1029                                    const void             *buf,
1030                                    size_t                  buflen)
1031 {
1032   GTlsConnectionGnutls *gnutls = transport_data;
1033   ssize_t ret;
1034
1035   /* See comment in pull_func. */
1036   g_clear_error (&gnutls->priv->write_error);
1037
1038   ret = g_pollable_stream_write (G_OUTPUT_STREAM (gnutls->priv->base_ostream),
1039                                  buf, buflen,
1040                                  gnutls->priv->write_blocking,
1041                                  gnutls->priv->write_cancellable,
1042                                  &gnutls->priv->write_error);
1043   if (ret < 0)
1044     set_gnutls_error (gnutls, gnutls->priv->write_error);
1045
1046   return ret;
1047 }
1048
1049
1050 static GTlsCertificate *
1051 get_peer_certificate_from_session (GTlsConnectionGnutls *gnutls)
1052 {
1053   GTlsCertificate *chain, *cert;
1054   const gnutls_datum_t *certs;
1055   unsigned int num_certs;
1056   int i;
1057
1058   certs = gnutls_certificate_get_peers (gnutls->priv->session, &num_certs);
1059   if (!certs || !num_certs)
1060     return NULL;
1061
1062   chain = NULL;
1063   for (i = num_certs - 1; i >= 0; i--)
1064     {
1065       cert = g_tls_certificate_gnutls_new (&certs[i], chain);
1066       if (chain)
1067         g_object_unref (chain);
1068       chain = cert;
1069     }
1070
1071   return chain;
1072 }
1073
1074 static GTlsCertificateFlags
1075 verify_peer_certificate (GTlsConnectionGnutls *gnutls,
1076                          GTlsCertificate      *peer_certificate)
1077 {
1078   GTlsConnection *conn = G_TLS_CONNECTION (gnutls);
1079   GSocketConnectable *peer_identity;
1080   GTlsDatabase *database;
1081   GTlsCertificateFlags errors;
1082   gboolean is_client;
1083
1084   is_client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
1085   if (is_client)
1086     peer_identity = g_tls_client_connection_get_server_identity (G_TLS_CLIENT_CONNECTION (gnutls));
1087   else
1088     peer_identity = NULL;
1089
1090   errors = 0;
1091
1092   database = g_tls_connection_get_database (conn);
1093   if (database == NULL)
1094     {
1095       errors |= G_TLS_CERTIFICATE_UNKNOWN_CA;
1096       errors |= g_tls_certificate_verify (peer_certificate, peer_identity, NULL);
1097     }
1098   else
1099     {
1100       GError *error = NULL;
1101
1102       errors |= g_tls_database_verify_chain (database, peer_certificate,
1103                                              is_client ?
1104                                              G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER :
1105                                              G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT,
1106                                              peer_identity,
1107                                              g_tls_connection_get_interaction (conn),
1108                                              G_TLS_DATABASE_VERIFY_NONE,
1109                                              NULL, &error);
1110       if (error)
1111         {
1112           g_warning ("failure verifying certificate chain: %s",
1113                      error->message);
1114           g_assert (errors != 0);
1115           g_clear_error (&error);
1116         }
1117     }
1118
1119   return errors;
1120 }
1121
1122 static void
1123 handshake_thread (GTask        *task,
1124                   gpointer      object,
1125                   gpointer      task_data,
1126                   GCancellable *cancellable)
1127 {
1128   GTlsConnectionGnutls *gnutls = object;
1129   gboolean is_client;
1130   GError *error = NULL;
1131   int ret;
1132
1133   gnutls->priv->started_handshake = FALSE;
1134
1135   if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE,
1136                  TRUE, cancellable, &error))
1137     {
1138       g_task_return_error (task, error);
1139       return;
1140     }
1141
1142   g_clear_error (&gnutls->priv->handshake_error);
1143
1144   is_client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
1145
1146   if (!is_client && gnutls->priv->ever_handshaked &&
1147       !gnutls->priv->implicit_handshake)
1148     {
1149       BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, TRUE, cancellable);
1150       ret = gnutls_rehandshake (gnutls->priv->session);
1151       END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret,
1152                      _("Error performing TLS handshake: %s"), &error);
1153
1154       if (error)
1155         {
1156           g_task_return_error (task, error);
1157           return;
1158         }
1159     }
1160
1161   gnutls->priv->started_handshake = TRUE;
1162
1163   g_clear_object (&gnutls->priv->peer_certificate);
1164   gnutls->priv->peer_certificate_errors = 0;
1165
1166   g_tls_connection_gnutls_set_handshake_priority (gnutls);
1167
1168   BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, TRUE, cancellable);
1169   ret = gnutls_handshake (gnutls->priv->session);
1170   END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret,
1171                  _("Error performing TLS handshake: %s"), &error);
1172
1173   if (ret == 0 && gnutls_certificate_type_get (gnutls->priv->session) == GNUTLS_CRT_X509)
1174     {
1175       gnutls->priv->peer_certificate_tmp = get_peer_certificate_from_session (gnutls);
1176       if (gnutls->priv->peer_certificate_tmp)
1177         gnutls->priv->peer_certificate_errors_tmp = verify_peer_certificate (gnutls, gnutls->priv->peer_certificate_tmp);
1178       else if (G_IS_TLS_CLIENT_CONNECTION (gnutls))
1179         {
1180           g_set_error_literal (&error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
1181                                _("Server did not return a valid TLS certificate"));
1182         }
1183     }
1184
1185   G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->finish_handshake (gnutls, &error);
1186
1187   if (error)
1188     {
1189       g_task_return_error (task, error);
1190     }
1191   else
1192     {
1193       gnutls->priv->ever_handshaked = TRUE;
1194       g_task_return_boolean (task, TRUE);
1195     }
1196 }
1197
1198 static gboolean
1199 accept_peer_certificate (GTlsConnectionGnutls *gnutls,
1200                          GTlsCertificate      *peer_certificate,
1201                          GTlsCertificateFlags  peer_certificate_errors)
1202 {
1203   gboolean accepted;
1204
1205   if (G_IS_TLS_CLIENT_CONNECTION (gnutls))
1206     {
1207       GTlsCertificateFlags validation_flags =
1208         g_tls_client_connection_get_validation_flags (G_TLS_CLIENT_CONNECTION (gnutls));
1209
1210       if ((peer_certificate_errors & validation_flags) == 0)
1211         accepted = TRUE;
1212       else
1213         {
1214           accepted = g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls),
1215                                                                peer_certificate,
1216                                                                peer_certificate_errors);
1217         }
1218     }
1219   else
1220     {
1221       accepted = g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls),
1222                                                            peer_certificate,
1223                                                            peer_certificate_errors);
1224     }
1225
1226   return accepted;
1227 }
1228
1229 static void
1230 begin_handshake (GTlsConnectionGnutls *gnutls)
1231 {
1232   G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->begin_handshake (gnutls);
1233 }
1234
1235 static gboolean
1236 finish_handshake (GTlsConnectionGnutls  *gnutls,
1237                   GTask                 *task,
1238                   GError               **error)
1239 {
1240   GTlsCertificate *peer_certificate;
1241   GTlsCertificateFlags peer_certificate_errors;
1242
1243   g_assert (error != NULL);
1244
1245   peer_certificate = gnutls->priv->peer_certificate_tmp;
1246   gnutls->priv->peer_certificate_tmp = NULL;
1247   peer_certificate_errors = gnutls->priv->peer_certificate_errors_tmp;
1248   gnutls->priv->peer_certificate_errors_tmp = 0;
1249
1250   if (g_task_propagate_boolean (task, error) && peer_certificate)
1251     {
1252       if (!accept_peer_certificate (gnutls, peer_certificate,
1253                                     peer_certificate_errors))
1254         {
1255           g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
1256                                _("Unacceptable TLS certificate"));
1257         }
1258
1259       gnutls->priv->peer_certificate = peer_certificate;
1260       gnutls->priv->peer_certificate_errors = peer_certificate_errors;
1261       g_object_notify (G_OBJECT (gnutls), "peer-certificate");
1262       g_object_notify (G_OBJECT (gnutls), "peer-certificate-errors");
1263     }
1264
1265   if (*error && gnutls->priv->started_handshake)
1266     gnutls->priv->handshake_error = g_error_copy (*error);
1267
1268   return (*error == NULL);
1269 }
1270
1271 static gboolean
1272 g_tls_connection_gnutls_handshake (GTlsConnection   *conn,
1273                                    GCancellable     *cancellable,
1274                                    GError          **error)
1275 {
1276   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (conn);
1277   GTask *task;
1278   gboolean success;
1279   GError *my_error = NULL;
1280
1281   task = g_task_new (conn, cancellable, NULL, NULL);
1282   begin_handshake (gnutls);
1283   g_task_run_in_thread_sync (task, handshake_thread);
1284   success = finish_handshake (gnutls, task, &my_error);
1285   g_object_unref (task);
1286
1287   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
1288
1289   if (my_error)
1290     g_propagate_error (error, my_error);
1291   return success;
1292 }
1293
1294 /* In the async version we use two GTasks; one to run handshake_thread() and
1295  * then call handshake_thread_completed(), and a second to call the caller's
1296  * original callback after we call finish_handshake().
1297  */
1298
1299 static void
1300 handshake_thread_completed (GObject      *object,
1301                             GAsyncResult *result,
1302                             gpointer      user_data)
1303 {
1304   GTask *caller_task = user_data;
1305   GTlsConnectionGnutls *gnutls = g_task_get_source_object (caller_task);
1306   GError *error = NULL;
1307   gboolean need_finish_handshake, success;
1308
1309   g_mutex_lock (&gnutls->priv->op_mutex);
1310   if (gnutls->priv->need_finish_handshake)
1311     {
1312       need_finish_handshake = TRUE;
1313       gnutls->priv->need_finish_handshake = FALSE;
1314     }
1315   else
1316     need_finish_handshake = FALSE;
1317   g_mutex_unlock (&gnutls->priv->op_mutex);
1318
1319   if (need_finish_handshake)
1320     {
1321       success = finish_handshake (gnutls, G_TASK (result), &error);
1322       if (success)
1323         g_task_return_boolean (caller_task, TRUE);
1324       else
1325         g_task_return_error (caller_task, error);
1326     }
1327   else if (gnutls->priv->handshake_error)
1328     g_task_return_error (caller_task, g_error_copy (gnutls->priv->handshake_error));
1329   else
1330     g_task_return_boolean (caller_task, TRUE);
1331
1332   g_object_unref (caller_task);
1333 }
1334
1335 static void
1336 async_handshake_thread (GTask        *task,
1337                         gpointer      object,
1338                         gpointer      task_data,
1339                         GCancellable *cancellable)
1340 {
1341   GTlsConnectionGnutls *gnutls = object;
1342
1343   handshake_thread (task, object, task_data, cancellable);
1344
1345   g_mutex_lock (&gnutls->priv->op_mutex);
1346   gnutls->priv->need_finish_handshake = TRUE;
1347   /* yield_op will clear handshaking too, but we don't want the
1348    * connection to be briefly "handshaking && need_finish_handshake"
1349    * after we unlock the mutex.
1350    */
1351   gnutls->priv->handshaking = FALSE;
1352   g_mutex_unlock (&gnutls->priv->op_mutex);
1353
1354   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
1355 }
1356
1357 static void
1358 g_tls_connection_gnutls_handshake_async (GTlsConnection       *conn,
1359                                          int                   io_priority,
1360                                          GCancellable         *cancellable,
1361                                          GAsyncReadyCallback   callback,
1362                                          gpointer              user_data)
1363 {
1364   GTask *thread_task, *caller_task;
1365
1366   caller_task = g_task_new (conn, cancellable, callback, user_data);
1367   g_task_set_priority (caller_task, io_priority);
1368
1369   begin_handshake (G_TLS_CONNECTION_GNUTLS (conn));
1370
1371   thread_task = g_task_new (conn, cancellable,
1372                             handshake_thread_completed, caller_task);
1373   g_task_set_priority (thread_task, io_priority);
1374   g_task_run_in_thread (thread_task, async_handshake_thread);
1375   g_object_unref (thread_task);
1376 }
1377
1378 static gboolean
1379 g_tls_connection_gnutls_handshake_finish (GTlsConnection       *conn,
1380                                           GAsyncResult         *result,
1381                                           GError              **error)
1382 {
1383   g_return_val_if_fail (g_task_is_valid (result, conn), FALSE);
1384
1385   return g_task_propagate_boolean (G_TASK (result), error);
1386 }
1387
1388 static gboolean
1389 do_implicit_handshake (GTlsConnectionGnutls  *gnutls,
1390                        gboolean               blocking,
1391                        GCancellable          *cancellable,
1392                        GError               **error)
1393 {
1394   /* We have op_mutex */
1395
1396   gnutls->priv->implicit_handshake = g_task_new (gnutls, cancellable, NULL, NULL);
1397
1398   begin_handshake (gnutls);
1399
1400   if (blocking)
1401     {
1402       GError *my_error = NULL;
1403       gboolean success;
1404
1405       g_mutex_unlock (&gnutls->priv->op_mutex);
1406       g_task_run_in_thread_sync (gnutls->priv->implicit_handshake,
1407                                  handshake_thread);
1408       success = finish_handshake (gnutls,
1409                                   gnutls->priv->implicit_handshake,
1410                                   &my_error);
1411       g_clear_object (&gnutls->priv->implicit_handshake);
1412       yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
1413       g_mutex_lock (&gnutls->priv->op_mutex);
1414
1415       if (my_error)
1416         g_propagate_error (error, my_error);
1417       return success;
1418     }
1419   else
1420     {
1421       g_task_run_in_thread (gnutls->priv->implicit_handshake,
1422                             async_handshake_thread);
1423
1424       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
1425                            _("Operation would block"));
1426
1427       return FALSE;
1428     }
1429 }
1430
1431 gssize
1432 g_tls_connection_gnutls_read (GTlsConnectionGnutls  *gnutls,
1433                               void                  *buffer,
1434                               gsize                  count,
1435                               gboolean               blocking,
1436                               GCancellable          *cancellable,
1437                               GError               **error)
1438 {
1439   gssize ret;
1440
1441  again:
1442   if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ,
1443                  blocking, cancellable, error))
1444     return -1;
1445
1446   BEGIN_GNUTLS_IO (gnutls, G_IO_IN, blocking, cancellable);
1447   ret = gnutls_record_recv (gnutls->priv->session, buffer, count);
1448   END_GNUTLS_IO (gnutls, G_IO_IN, ret, _("Error reading data from TLS socket: %s"), error);
1449
1450   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ);
1451
1452   if (ret >= 0)
1453     return ret;
1454   else if (ret == GNUTLS_E_REHANDSHAKE)
1455     goto again;
1456   else
1457     return -1;
1458 }
1459
1460 gssize
1461 g_tls_connection_gnutls_write (GTlsConnectionGnutls  *gnutls,
1462                                const void            *buffer,
1463                                gsize                  count,
1464                                gboolean               blocking,
1465                                GCancellable          *cancellable,
1466                                GError               **error)
1467 {
1468   gssize ret;
1469
1470  again:
1471   if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE,
1472                  blocking, cancellable, error))
1473     return -1;
1474
1475   BEGIN_GNUTLS_IO (gnutls, G_IO_OUT, blocking, cancellable);
1476   ret = gnutls_record_send (gnutls->priv->session, buffer, count);
1477   END_GNUTLS_IO (gnutls, G_IO_OUT, ret, _("Error writing data to TLS socket: %s"), error);
1478
1479   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE);
1480
1481   if (ret >= 0)
1482     return ret;
1483   else if (ret == GNUTLS_E_REHANDSHAKE)
1484     goto again;
1485   else
1486     return -1;
1487 }
1488
1489 static GInputStream  *
1490 g_tls_connection_gnutls_get_input_stream (GIOStream *stream)
1491 {
1492   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
1493
1494   return gnutls->priv->tls_istream;
1495 }
1496
1497 static GOutputStream *
1498 g_tls_connection_gnutls_get_output_stream (GIOStream *stream)
1499 {
1500   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
1501
1502   return gnutls->priv->tls_ostream;
1503 }
1504
1505 static gboolean
1506 g_tls_connection_gnutls_close (GIOStream     *stream,
1507                                GCancellable  *cancellable,
1508                                GError       **error)
1509 {
1510   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
1511   gboolean success;
1512   int ret = 0;
1513
1514   if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_CLOSE,
1515                  TRUE, cancellable, error))
1516     return FALSE;
1517
1518   if (gnutls->priv->closed)
1519     {
1520       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
1521                            _("Connection is already closed"));
1522       yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_CLOSE);
1523       return FALSE;
1524     }
1525
1526   if (gnutls->priv->ever_handshaked)
1527     {
1528       BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, TRUE, cancellable);
1529       ret = gnutls_bye (gnutls->priv->session, GNUTLS_SHUT_WR);
1530       END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret,
1531                      _("Error performing TLS close: %s"), error);
1532     }
1533
1534   gnutls->priv->closed = TRUE;
1535
1536   if (ret != 0)
1537     {
1538       yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_CLOSE);
1539       return FALSE;
1540     }
1541
1542   success = g_io_stream_close (gnutls->priv->base_io_stream,
1543                                cancellable, error);
1544   yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_CLOSE);
1545   return success;
1546 }
1547
1548 /* We do async close as synchronous-in-a-thread so we don't need to
1549  * implement G_IO_IN/G_IO_OUT flip-flopping just for this one case
1550  * (since handshakes are also done synchronously now).
1551  */
1552 static void
1553 close_thread (GTask        *task,
1554               gpointer      object,
1555               gpointer      task_data,
1556               GCancellable *cancellable)
1557 {
1558   GIOStream *stream = object;
1559   GError *error = NULL;
1560
1561   if (!g_tls_connection_gnutls_close (stream, cancellable, &error))
1562     g_task_return_error (task, error);
1563   else
1564     g_task_return_boolean (task, TRUE);
1565 }
1566
1567 static void
1568 g_tls_connection_gnutls_close_async (GIOStream           *stream,
1569                                      int                  io_priority,
1570                                      GCancellable        *cancellable,
1571                                      GAsyncReadyCallback  callback,
1572                                      gpointer             user_data)
1573 {
1574   GTask *task;
1575
1576   task = g_task_new (stream, cancellable, callback, user_data);
1577   g_task_set_priority (task, io_priority);
1578   g_task_run_in_thread (task, close_thread);
1579   g_object_unref (task);
1580 }
1581
1582 static gboolean
1583 g_tls_connection_gnutls_close_finish (GIOStream           *stream,
1584                                       GAsyncResult        *result,
1585                                       GError             **error)
1586 {
1587   g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1588
1589   return g_task_propagate_boolean (G_TASK (result), error);
1590 }
1591
1592 #ifdef HAVE_PKCS11
1593
1594 static P11KitPin*
1595 on_pin_prompt_callback (const char     *pinfile,
1596                         P11KitUri      *pin_uri,
1597                         const char     *pin_description,
1598                         P11KitPinFlags  pin_flags,
1599                         void           *callback_data)
1600 {
1601   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (callback_data);
1602   GTlsInteractionResult result;
1603   GTlsPasswordFlags flags = 0;
1604   GTlsPassword *password;
1605   P11KitPin *pin = NULL;
1606   GError *error = NULL;
1607
1608   if (!gnutls->priv->interaction)
1609     return NULL;
1610
1611   if (pin_flags & P11_KIT_PIN_FLAGS_RETRY)
1612     flags |= G_TLS_PASSWORD_RETRY;
1613   if (pin_flags & P11_KIT_PIN_FLAGS_MANY_TRIES)
1614     flags |= G_TLS_PASSWORD_MANY_TRIES;
1615   if (pin_flags & P11_KIT_PIN_FLAGS_FINAL_TRY)
1616     flags |= G_TLS_PASSWORD_FINAL_TRY;
1617
1618   password = g_pkcs11_pin_new (flags, pin_description);
1619
1620   result = g_tls_interaction_ask_password (gnutls->priv->interaction, password,
1621                                            g_cancellable_get_current (), &error);
1622
1623   switch (result)
1624     {
1625     case G_TLS_INTERACTION_FAILED:
1626       if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
1627         g_warning ("couldn't ask for password: %s", error->message);
1628       pin = NULL;
1629       break;
1630     case G_TLS_INTERACTION_UNHANDLED:
1631       pin = NULL;
1632       break;
1633     case G_TLS_INTERACTION_HANDLED:
1634       pin = g_pkcs11_pin_steal_internal (G_PKCS11_PIN (password));
1635       break;
1636     }
1637
1638   g_object_unref (password);
1639   return pin;
1640 }
1641
1642 #endif /* HAVE_PKCS11 */
1643
1644 static void
1645 g_tls_connection_gnutls_class_init (GTlsConnectionGnutlsClass *klass)
1646 {
1647   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
1648   GTlsConnectionClass *connection_class = G_TLS_CONNECTION_CLASS (klass);
1649   GIOStreamClass *iostream_class = G_IO_STREAM_CLASS (klass);
1650
1651   g_type_class_add_private (klass, sizeof (GTlsConnectionGnutlsPrivate));
1652
1653   gobject_class->get_property = g_tls_connection_gnutls_get_property;
1654   gobject_class->set_property = g_tls_connection_gnutls_set_property;
1655   gobject_class->finalize     = g_tls_connection_gnutls_finalize;
1656
1657   connection_class->handshake        = g_tls_connection_gnutls_handshake;
1658   connection_class->handshake_async  = g_tls_connection_gnutls_handshake_async;
1659   connection_class->handshake_finish = g_tls_connection_gnutls_handshake_finish;
1660
1661   iostream_class->get_input_stream  = g_tls_connection_gnutls_get_input_stream;
1662   iostream_class->get_output_stream = g_tls_connection_gnutls_get_output_stream;
1663   iostream_class->close_fn          = g_tls_connection_gnutls_close;
1664   iostream_class->close_async       = g_tls_connection_gnutls_close_async;
1665   iostream_class->close_finish      = g_tls_connection_gnutls_close_finish;
1666
1667   g_object_class_override_property (gobject_class, PROP_BASE_IO_STREAM, "base-io-stream");
1668   g_object_class_override_property (gobject_class, PROP_REQUIRE_CLOSE_NOTIFY, "require-close-notify");
1669   g_object_class_override_property (gobject_class, PROP_REHANDSHAKE_MODE, "rehandshake-mode");
1670   g_object_class_override_property (gobject_class, PROP_USE_SYSTEM_CERTDB, "use-system-certdb");
1671   g_object_class_override_property (gobject_class, PROP_DATABASE, "database");
1672   g_object_class_override_property (gobject_class, PROP_CERTIFICATE, "certificate");
1673   g_object_class_override_property (gobject_class, PROP_INTERACTION, "interaction");
1674   g_object_class_override_property (gobject_class, PROP_PEER_CERTIFICATE, "peer-certificate");
1675   g_object_class_override_property (gobject_class, PROP_PEER_CERTIFICATE_ERRORS, "peer-certificate-errors");
1676 }
1677
1678 static void
1679 g_tls_connection_gnutls_initable_iface_init (GInitableIface *iface)
1680 {
1681   iface->init = g_tls_connection_gnutls_initable_init;
1682 }