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