1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright 2009 Red Hat, Inc
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.
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.
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/>.
24 #include <gnutls/gnutls.h>
25 #include <gnutls/x509.h>
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"
35 #include <p11-kit/pin.h>
36 #include "pkcs11/gpkcs11pin.h"
39 #include <glib/gi18n-lib.h>
41 static ssize_t g_tls_connection_gnutls_push_func (gnutls_transport_ptr_t transport_data,
44 static ssize_t g_tls_connection_gnutls_pull_func (gnutls_transport_ptr_t transport_data,
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,
54 static P11KitPin* on_pin_prompt_callback (const char *pinfile,
56 const char *pin_description,
57 P11KitPinFlags pin_flags,
61 static void g_tls_connection_gnutls_init_priorities (void);
63 static gboolean do_implicit_handshake (GTlsConnectionGnutls *gnutls,
65 GCancellable *cancellable,
67 static gboolean finish_handshake (GTlsConnectionGnutls *gnutls,
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 ();
82 PROP_REQUIRE_CLOSE_NOTIFY,
83 PROP_REHANDSHAKE_MODE,
84 PROP_USE_SYSTEM_CERTDB,
88 PROP_PEER_CERTIFICATE,
89 PROP_PEER_CERTIFICATE_ERRORS
92 struct _GTlsConnectionGnutlsPrivate
94 GIOStream *base_io_stream;
95 GPollableInputStream *base_istream;
96 GPollableOutputStream *base_ostream;
98 gnutls_certificate_credentials creds;
99 gnutls_session session;
101 GTlsCertificate *certificate, *peer_certificate;
102 GTlsCertificateFlags peer_certificate_errors;
103 GTlsCertificate *peer_certificate_tmp;
104 GTlsCertificateFlags peer_certificate_errors_tmp;
106 gboolean require_close_notify;
107 GTlsRehandshakeMode rehandshake_mode;
108 gboolean is_system_certdb;
109 GTlsDatabase *database;
110 gboolean database_is_unset;
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).
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...
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.
133 gboolean need_handshake, need_finish_handshake;
134 gboolean started_handshake, handshaking, ever_handshaked;
135 GTask *implicit_handshake;
136 GError *handshake_error;
138 gboolean closing, closed;
140 GInputStream *tls_istream;
141 GOutputStream *tls_ostream;
143 GTlsInteraction *interaction;
144 gchar *interaction_id;
147 GCancellable *waiting_for_op;
150 gboolean read_blocking;
152 GCancellable *read_cancellable;
155 gboolean write_blocking;
157 GCancellable *write_cancellable;
159 #ifndef GNUTLS_E_PREMATURE_TERMINATION
164 static gint unique_interaction_id = 0;
167 g_tls_connection_gnutls_init (GTlsConnectionGnutls *gnutls)
171 gnutls->priv = G_TYPE_INSTANCE_GET_PRIVATE (gnutls, G_TYPE_TLS_CONNECTION_GNUTLS, GTlsConnectionGnutlsPrivate);
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);
177 gnutls->priv->need_handshake = TRUE;
179 gnutls->priv->database_is_unset = TRUE;
180 gnutls->priv->is_system_certdb = TRUE;
182 unique_id = g_atomic_int_add (&unique_interaction_id, 1);
183 gnutls->priv->interaction_id = g_strdup_printf ("gtls:%d", unique_id);
186 p11_kit_pin_register_callback (gnutls->priv->interaction_id,
187 on_pin_prompt_callback, gnutls, NULL);
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);
195 /* First field is "ssl3 only", second is "allow unsafe rehandshaking" */
196 static gnutls_priority_t priorities[2][2];
199 g_tls_connection_gnutls_init_priorities (void)
201 const gchar *base_priority;
202 gchar *ssl3_priority, *unsafe_rehandshake_priority, *ssl3_unsafe_rehandshake_priority;
204 base_priority = g_getenv ("G_TLS_GNUTLS_PRIORITY");
206 base_priority = "NORMAL:%COMPAT";
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);
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);
217 g_free (ssl3_priority);
218 g_free (unsafe_rehandshake_priority);
219 g_free (ssl3_unsafe_rehandshake_priority);
223 g_tls_connection_gnutls_set_handshake_priority (GTlsConnectionGnutls *gnutls)
225 gboolean use_ssl3, unsafe_rehandshake;
227 if (G_IS_TLS_CLIENT_CONNECTION (gnutls))
228 use_ssl3 = g_tls_client_connection_get_use_ssl3 (G_TLS_CLIENT_CONNECTION (gnutls));
231 unsafe_rehandshake = (gnutls->priv->rehandshake_mode == G_TLS_REHANDSHAKE_UNSAFELY);
232 gnutls_priority_set (gnutls->priv->session,
233 priorities[use_ssl3][unsafe_rehandshake]);
237 g_tls_connection_gnutls_initable_init (GInitable *initable,
238 GCancellable *cancellable,
241 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (initable);
244 g_return_val_if_fail (gnutls->priv->base_istream != NULL &&
245 gnutls->priv->base_ostream != NULL, FALSE);
247 /* Make sure gnutls->priv->session has been initialized (it may have
248 * already been initialized by a construct-time property setter).
250 g_tls_connection_gnutls_get_session (gnutls);
252 status = gnutls_credentials_set (gnutls->priv->session,
253 GNUTLS_CRD_CERTIFICATE,
254 gnutls->priv->creds);
257 g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
258 _("Could not create TLS connection: %s"),
259 gnutls_strerror (status));
263 /* Some servers (especially on embedded devices) use tiny keys that
264 * gnutls will reject by default. We want it to accept them.
266 gnutls_dh_set_prime_bits (gnutls->priv->session, 256);
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);
274 gnutls->priv->tls_istream = g_tls_input_stream_gnutls_new (gnutls);
275 gnutls->priv->tls_ostream = g_tls_output_stream_gnutls_new (gnutls);
281 g_tls_connection_gnutls_finalize (GObject *object)
283 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
285 g_clear_object (&gnutls->priv->base_io_stream);
287 g_clear_object (&gnutls->priv->tls_istream);
288 g_clear_object (&gnutls->priv->tls_ostream);
290 if (gnutls->priv->session)
291 gnutls_deinit (gnutls->priv->session);
292 if (gnutls->priv->creds)
293 gnutls_certificate_free_credentials (gnutls->priv->creds);
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);
301 p11_kit_pin_unregister_callback (gnutls->priv->interaction_id,
302 on_pin_prompt_callback, gnutls);
304 g_free (gnutls->priv->interaction_id);
305 g_clear_object (&gnutls->priv->interaction);
307 g_clear_error (&gnutls->priv->handshake_error);
308 g_clear_error (&gnutls->priv->read_error);
309 g_clear_error (&gnutls->priv->write_error);
311 g_clear_object (&gnutls->priv->waiting_for_op);
312 g_mutex_clear (&gnutls->priv->op_mutex);
314 G_OBJECT_CLASS (g_tls_connection_gnutls_parent_class)->finalize (object);
318 g_tls_connection_gnutls_get_property (GObject *object,
323 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
324 GTlsBackend *backend;
328 case PROP_BASE_IO_STREAM:
329 g_value_set_object (value, gnutls->priv->base_io_stream);
332 case PROP_REQUIRE_CLOSE_NOTIFY:
333 g_value_set_boolean (value, gnutls->priv->require_close_notify);
336 case PROP_REHANDSHAKE_MODE:
337 g_value_set_enum (value, gnutls->priv->rehandshake_mode);
340 case PROP_USE_SYSTEM_CERTDB:
341 g_value_set_boolean (value, gnutls->priv->is_system_certdb);
345 if (gnutls->priv->database_is_unset)
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;
351 g_value_set_object (value, gnutls->priv->database);
354 case PROP_CERTIFICATE:
355 g_value_set_object (value, gnutls->priv->certificate);
358 case PROP_INTERACTION:
359 g_value_set_object (value, gnutls->priv->interaction);
362 case PROP_PEER_CERTIFICATE:
363 g_value_set_object (value, gnutls->priv->peer_certificate);
366 case PROP_PEER_CERTIFICATE_ERRORS:
367 g_value_set_flags (value, gnutls->priv->peer_certificate_errors);
371 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
376 g_tls_connection_gnutls_set_property (GObject *object,
381 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
382 GInputStream *istream;
383 GOutputStream *ostream;
384 gboolean system_certdb;
385 GTlsBackend *backend;
389 case PROP_BASE_IO_STREAM:
390 if (gnutls->priv->base_io_stream)
392 g_object_unref (gnutls->priv->base_io_stream);
393 gnutls->priv->base_istream = NULL;
394 gnutls->priv->base_ostream = NULL;
396 gnutls->priv->base_io_stream = g_value_dup_object (value);
397 if (!gnutls->priv->base_io_stream)
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);
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);
411 case PROP_REQUIRE_CLOSE_NOTIFY:
412 gnutls->priv->require_close_notify = g_value_get_boolean (value);
415 case PROP_REHANDSHAKE_MODE:
416 gnutls->priv->rehandshake_mode = g_value_get_enum (value);
419 case PROP_USE_SYSTEM_CERTDB:
420 system_certdb = g_value_get_boolean (value);
421 if (system_certdb != gnutls->priv->is_system_certdb)
423 g_clear_object (&gnutls->priv->database);
426 backend = g_tls_backend_get_default ();
427 gnutls->priv->database = g_tls_backend_get_default_database (backend);
429 gnutls->priv->is_system_certdb = system_certdb;
430 gnutls->priv->database_is_unset = FALSE;
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;
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);
447 case PROP_INTERACTION:
448 g_clear_object (&gnutls->priv->interaction);
449 gnutls->priv->interaction = g_value_dup_object (value);
453 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
457 gnutls_certificate_credentials
458 g_tls_connection_gnutls_get_credentials (GTlsConnectionGnutls *gnutls)
460 return gnutls->priv->creds;
464 g_tls_connection_gnutls_get_session (GTlsConnectionGnutls *gnutls)
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.
472 if (!gnutls->priv->session)
474 gboolean client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
475 gnutls_init (&gnutls->priv->session, client ? GNUTLS_CLIENT : GNUTLS_SERVER);
478 return gnutls->priv->session;
482 g_tls_connection_gnutls_get_certificate (GTlsConnectionGnutls *gnutls,
485 GTlsCertificate *cert;
487 cert = g_tls_connection_get_certificate (G_TLS_CONNECTION (gnutls));
489 st->cert_type = GNUTLS_CRT_X509;
493 g_tls_certificate_gnutls_copy (G_TLS_CERTIFICATE_GNUTLS (cert),
494 gnutls->priv->interaction_id, st);
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;
505 claim_op (GTlsConnectionGnutls *gnutls,
506 GTlsConnectionGnutlsOp op,
508 GCancellable *cancellable,
512 if (g_cancellable_set_error_if_cancelled (cancellable, error))
515 g_mutex_lock (&gnutls->priv->op_mutex);
517 if (gnutls->priv->closing || gnutls->priv->closed)
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);
525 if (gnutls->priv->handshake_error && op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE)
528 *error = g_error_copy (gnutls->priv->handshake_error);
529 g_mutex_unlock (&gnutls->priv->op_mutex);
533 if (op != G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE &&
534 op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE)
536 if (gnutls->priv->need_handshake)
538 gnutls->priv->need_handshake = FALSE;
539 gnutls->priv->handshaking = TRUE;
540 if (!do_implicit_handshake (gnutls, blocking, cancellable, error))
542 g_mutex_unlock (&gnutls->priv->op_mutex);
547 if (gnutls->priv->need_finish_handshake)
549 GError *my_error = NULL;
552 gnutls->priv->need_finish_handshake = FALSE;
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);
559 if (!success || g_cancellable_set_error_if_cancelled (cancellable, &my_error))
561 g_propagate_error (error, my_error);
562 g_mutex_unlock (&gnutls->priv->op_mutex);
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))
575 g_cancellable_reset (gnutls->priv->waiting_for_op);
577 g_mutex_unlock (&gnutls->priv->op_mutex);
581 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
582 _("Operation would block"));
586 g_cancellable_make_pollfd (gnutls->priv->waiting_for_op, &fds[0]);
587 if (g_cancellable_make_pollfd (cancellable, &fds[0]))
591 g_poll (fds, nfds, -1);
592 g_cancellable_release_fd (cancellable);
597 if (op == G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE)
599 gnutls->priv->handshaking = TRUE;
600 gnutls->priv->need_handshake = FALSE;
602 if (op == G_TLS_CONNECTION_GNUTLS_OP_CLOSE)
603 gnutls->priv->closing = TRUE;
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;
610 g_mutex_unlock (&gnutls->priv->op_mutex);
615 yield_op (GTlsConnectionGnutls *gnutls,
616 GTlsConnectionGnutlsOp op)
618 g_mutex_lock (&gnutls->priv->op_mutex);
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;
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;
630 g_cancellable_cancel (gnutls->priv->waiting_for_op);
631 g_mutex_unlock (&gnutls->priv->op_mutex);
635 begin_gnutls_io (GTlsConnectionGnutls *gnutls,
636 GIOCondition direction,
638 GCancellable *cancellable)
640 g_assert (direction & (G_IO_IN | G_IO_OUT));
642 if (direction & G_IO_IN)
644 gnutls->priv->read_blocking = blocking;
645 gnutls->priv->read_cancellable = cancellable;
646 g_clear_error (&gnutls->priv->read_error);
649 if (direction & G_IO_OUT)
651 gnutls->priv->write_blocking = blocking;
652 gnutls->priv->write_cancellable = cancellable;
653 g_clear_error (&gnutls->priv->write_error);
658 end_gnutls_io (GTlsConnectionGnutls *gnutls,
659 GIOCondition direction,
664 GError *my_error = NULL;
666 g_assert (direction & (G_IO_IN | G_IO_OUT));
667 g_assert (!error || !*error);
669 if (status == GNUTLS_E_AGAIN ||
670 status == GNUTLS_E_WARNING_ALERT_RECEIVED)
671 return GNUTLS_E_AGAIN;
673 if (direction & G_IO_IN)
675 gnutls->priv->read_cancellable = NULL;
678 my_error = gnutls->priv->read_error;
679 gnutls->priv->read_error = NULL;
682 g_clear_error (&gnutls->priv->read_error);
684 if (direction & G_IO_OUT)
686 gnutls->priv->write_cancellable = NULL;
687 if (status < 0 && !my_error)
689 my_error = gnutls->priv->write_error;
690 gnutls->priv->write_error = NULL;
693 g_clear_error (&gnutls->priv->write_error);
699 if (gnutls->priv->handshaking && !gnutls->priv->ever_handshaked)
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) ||
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)
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;
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);
724 else if (status == GNUTLS_E_REHANDSHAKE)
726 if (gnutls->priv->rehandshake_mode == G_TLS_REHANDSHAKE_NEVER)
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;
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);
739 else if (status == GNUTLS_E_GOT_APPLICATION_DATA)
741 if (gnutls->priv->handshaking && G_IS_TLS_SERVER_CONNECTION (gnutls))
742 return GNUTLS_E_AGAIN;
745 #ifdef GNUTLS_E_PREMATURE_TERMINATION
746 status == GNUTLS_E_PREMATURE_TERMINATION
748 status == GNUTLS_E_UNEXPECTED_PACKET_LENGTH && gnutls->priv->eof
752 if (gnutls->priv->handshaking && !gnutls->priv->ever_handshaked)
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;
758 else if (gnutls->priv->require_close_notify)
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);
768 else if (status == GNUTLS_E_NO_CERTIFICATE_FOUND)
770 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED,
771 _("TLS connection peer did not send a certificate"));
777 g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
778 errmsg, gnutls_strerror (status));
783 #define BEGIN_GNUTLS_IO(gnutls, direction, blocking, cancellable) \
784 begin_gnutls_io (gnutls, direction, blocking, cancellable); \
787 #define END_GNUTLS_IO(gnutls, direction, ret, errmsg, err) \
788 } while ((ret = end_gnutls_io (gnutls, direction, ret, errmsg, err)) == GNUTLS_E_AGAIN);
791 g_tls_connection_gnutls_check (GTlsConnectionGnutls *gnutls,
792 GIOCondition condition)
794 /* Racy, but worst case is that we just get WOULD_BLOCK back */
795 if (gnutls->priv->need_finish_handshake)
798 /* If a handshake or close is in progress, then tls_istream and
799 * tls_ostream are blocked, regardless of the base stream status.
801 if (gnutls->priv->handshaking || gnutls->priv->closing)
804 if (condition & G_IO_IN)
805 return g_pollable_input_stream_is_readable (gnutls->priv->base_istream);
807 return g_pollable_output_stream_is_writable (gnutls->priv->base_ostream);
813 GTlsConnectionGnutls *gnutls;
816 GSource *child_source;
817 GIOCondition condition;
821 } GTlsConnectionGnutlsSource;
824 gnutls_source_prepare (GSource *source,
832 gnutls_source_check (GSource *source)
838 gnutls_source_sync (GTlsConnectionGnutlsSource *gnutls_source)
840 GTlsConnectionGnutls *gnutls = gnutls_source->gnutls;
841 gboolean io_waiting, op_waiting;
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))
851 if (!op_waiting && !gnutls->priv->need_handshake &&
852 !gnutls->priv->need_finish_handshake)
856 g_mutex_unlock (&gnutls->priv->op_mutex);
858 if (op_waiting == gnutls_source->op_waiting &&
859 io_waiting == gnutls_source->io_waiting)
861 gnutls_source->op_waiting = op_waiting;
862 gnutls_source->io_waiting = io_waiting;
864 if (gnutls_source->child_source)
866 g_source_remove_child_source ((GSource *)gnutls_source,
867 gnutls_source->child_source);
868 g_source_unref (gnutls_source->child_source);
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);
878 gnutls_source->child_source = g_timeout_source_new (0);
880 g_source_set_dummy_callback (gnutls_source->child_source);
881 g_source_add_child_source ((GSource *)gnutls_source, gnutls_source->child_source);
885 gnutls_source_dispatch (GSource *source,
886 GSourceFunc callback,
889 GPollableSourceFunc func = (GPollableSourceFunc)callback;
890 GTlsConnectionGnutlsSource *gnutls_source = (GTlsConnectionGnutlsSource *)source;
893 ret = (*func) (gnutls_source->stream, user_data);
895 gnutls_source_sync (gnutls_source);
901 gnutls_source_finalize (GSource *source)
903 GTlsConnectionGnutlsSource *gnutls_source = (GTlsConnectionGnutlsSource *)source;
905 g_object_unref (gnutls_source->gnutls);
906 g_source_unref (gnutls_source->child_source);
910 g_tls_connection_gnutls_source_closure_callback (GObject *stream,
913 GClosure *closure = data;
915 GValue param = { 0, };
916 GValue result_value = { 0, };
919 g_value_init (&result_value, G_TYPE_BOOLEAN);
921 g_value_init (¶m, G_TYPE_OBJECT);
922 g_value_set_object (¶m, stream);
924 g_closure_invoke (closure, &result_value, 1, ¶m, NULL);
926 result = g_value_get_boolean (&result_value);
927 g_value_unset (&result_value);
928 g_value_unset (¶m);
933 static GSourceFuncs gnutls_source_funcs =
935 gnutls_source_prepare,
937 gnutls_source_dispatch,
938 gnutls_source_finalize,
939 (GSourceFunc)g_tls_connection_gnutls_source_closure_callback,
940 (GSourceDummyMarshal)g_cclosure_marshal_generic
944 g_tls_connection_gnutls_create_source (GTlsConnectionGnutls *gnutls,
945 GIOCondition condition,
946 GCancellable *cancellable)
948 GSource *source, *cancellable_source;
949 GTlsConnectionGnutlsSource *gnutls_source;
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);
961 gnutls_source->op_waiting = (gboolean) -1;
962 gnutls_source->io_waiting = (gboolean) -1;
963 gnutls_source_sync (gnutls_source);
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);
977 set_gnutls_error (GTlsConnectionGnutls *gnutls,
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
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);
992 gnutls_transport_set_errno (gnutls->priv->session, EIO);
996 g_tls_connection_gnutls_pull_func (gnutls_transport_ptr_t transport_data,
1000 GTlsConnectionGnutls *gnutls = transport_data;
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.)
1009 g_clear_error (&gnutls->priv->read_error);
1011 ret = g_pollable_stream_read (G_INPUT_STREAM (gnutls->priv->base_istream),
1013 gnutls->priv->read_blocking,
1014 gnutls->priv->read_cancellable,
1015 &gnutls->priv->read_error);
1018 set_gnutls_error (gnutls, gnutls->priv->read_error);
1019 #ifndef GNUTLS_E_PREMATURE_TERMINATION
1021 gnutls->priv->eof = TRUE;
1028 g_tls_connection_gnutls_push_func (gnutls_transport_ptr_t transport_data,
1032 GTlsConnectionGnutls *gnutls = transport_data;
1035 /* See comment in pull_func. */
1036 g_clear_error (&gnutls->priv->write_error);
1038 ret = g_pollable_stream_write (G_OUTPUT_STREAM (gnutls->priv->base_ostream),
1040 gnutls->priv->write_blocking,
1041 gnutls->priv->write_cancellable,
1042 &gnutls->priv->write_error);
1044 set_gnutls_error (gnutls, gnutls->priv->write_error);
1050 static GTlsCertificate *
1051 get_peer_certificate_from_session (GTlsConnectionGnutls *gnutls)
1053 GTlsCertificate *chain, *cert;
1054 const gnutls_datum_t *certs;
1055 unsigned int num_certs;
1058 certs = gnutls_certificate_get_peers (gnutls->priv->session, &num_certs);
1059 if (!certs || !num_certs)
1063 for (i = num_certs - 1; i >= 0; i--)
1065 cert = g_tls_certificate_gnutls_new (&certs[i], chain);
1067 g_object_unref (chain);
1074 static GTlsCertificateFlags
1075 verify_peer_certificate (GTlsConnectionGnutls *gnutls,
1076 GTlsCertificate *peer_certificate)
1078 GTlsConnection *conn = G_TLS_CONNECTION (gnutls);
1079 GSocketConnectable *peer_identity;
1080 GTlsDatabase *database;
1081 GTlsCertificateFlags errors;
1084 is_client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
1086 peer_identity = g_tls_client_connection_get_server_identity (G_TLS_CLIENT_CONNECTION (gnutls));
1088 peer_identity = NULL;
1092 database = g_tls_connection_get_database (conn);
1093 if (database == NULL)
1095 errors |= G_TLS_CERTIFICATE_UNKNOWN_CA;
1096 errors |= g_tls_certificate_verify (peer_certificate, peer_identity, NULL);
1100 GError *error = NULL;
1102 errors |= g_tls_database_verify_chain (database, peer_certificate,
1104 G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER :
1105 G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT,
1107 g_tls_connection_get_interaction (conn),
1108 G_TLS_DATABASE_VERIFY_NONE,
1112 g_warning ("failure verifying certificate chain: %s",
1114 g_assert (errors != 0);
1115 g_clear_error (&error);
1123 handshake_thread (GTask *task,
1126 GCancellable *cancellable)
1128 GTlsConnectionGnutls *gnutls = object;
1130 GError *error = NULL;
1133 gnutls->priv->started_handshake = FALSE;
1135 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE,
1136 TRUE, cancellable, &error))
1138 g_task_return_error (task, error);
1142 g_clear_error (&gnutls->priv->handshake_error);
1144 is_client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
1146 if (!is_client && gnutls->priv->ever_handshaked &&
1147 !gnutls->priv->implicit_handshake)
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);
1156 g_task_return_error (task, error);
1161 gnutls->priv->started_handshake = TRUE;
1163 g_clear_object (&gnutls->priv->peer_certificate);
1164 gnutls->priv->peer_certificate_errors = 0;
1166 g_tls_connection_gnutls_set_handshake_priority (gnutls);
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);
1173 if (ret == 0 && gnutls_certificate_type_get (gnutls->priv->session) == GNUTLS_CRT_X509)
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))
1180 g_set_error_literal (&error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
1181 _("Server did not return a valid TLS certificate"));
1185 G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->finish_handshake (gnutls, &error);
1189 g_task_return_error (task, error);
1193 gnutls->priv->ever_handshaked = TRUE;
1194 g_task_return_boolean (task, TRUE);
1199 accept_peer_certificate (GTlsConnectionGnutls *gnutls,
1200 GTlsCertificate *peer_certificate,
1201 GTlsCertificateFlags peer_certificate_errors)
1205 if (G_IS_TLS_CLIENT_CONNECTION (gnutls))
1207 GTlsCertificateFlags validation_flags =
1208 g_tls_client_connection_get_validation_flags (G_TLS_CLIENT_CONNECTION (gnutls));
1210 if ((peer_certificate_errors & validation_flags) == 0)
1214 accepted = g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls),
1216 peer_certificate_errors);
1221 accepted = g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls),
1223 peer_certificate_errors);
1230 begin_handshake (GTlsConnectionGnutls *gnutls)
1232 G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->begin_handshake (gnutls);
1236 finish_handshake (GTlsConnectionGnutls *gnutls,
1240 GTlsCertificate *peer_certificate;
1241 GTlsCertificateFlags peer_certificate_errors;
1243 g_assert (error != NULL);
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;
1250 if (g_task_propagate_boolean (task, error) && peer_certificate)
1252 if (!accept_peer_certificate (gnutls, peer_certificate,
1253 peer_certificate_errors))
1255 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
1256 _("Unacceptable TLS certificate"));
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");
1265 if (*error && gnutls->priv->started_handshake)
1266 gnutls->priv->handshake_error = g_error_copy (*error);
1268 return (*error == NULL);
1272 g_tls_connection_gnutls_handshake (GTlsConnection *conn,
1273 GCancellable *cancellable,
1276 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (conn);
1279 GError *my_error = NULL;
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);
1287 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
1290 g_propagate_error (error, my_error);
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().
1300 handshake_thread_completed (GObject *object,
1301 GAsyncResult *result,
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;
1309 g_mutex_lock (&gnutls->priv->op_mutex);
1310 if (gnutls->priv->need_finish_handshake)
1312 need_finish_handshake = TRUE;
1313 gnutls->priv->need_finish_handshake = FALSE;
1316 need_finish_handshake = FALSE;
1317 g_mutex_unlock (&gnutls->priv->op_mutex);
1319 if (need_finish_handshake)
1321 success = finish_handshake (gnutls, G_TASK (result), &error);
1323 g_task_return_boolean (caller_task, TRUE);
1325 g_task_return_error (caller_task, error);
1327 else if (gnutls->priv->handshake_error)
1328 g_task_return_error (caller_task, g_error_copy (gnutls->priv->handshake_error));
1330 g_task_return_boolean (caller_task, TRUE);
1332 g_object_unref (caller_task);
1336 async_handshake_thread (GTask *task,
1339 GCancellable *cancellable)
1341 GTlsConnectionGnutls *gnutls = object;
1343 handshake_thread (task, object, task_data, cancellable);
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.
1351 gnutls->priv->handshaking = FALSE;
1352 g_mutex_unlock (&gnutls->priv->op_mutex);
1354 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
1358 g_tls_connection_gnutls_handshake_async (GTlsConnection *conn,
1360 GCancellable *cancellable,
1361 GAsyncReadyCallback callback,
1364 GTask *thread_task, *caller_task;
1366 caller_task = g_task_new (conn, cancellable, callback, user_data);
1367 g_task_set_priority (caller_task, io_priority);
1369 begin_handshake (G_TLS_CONNECTION_GNUTLS (conn));
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);
1379 g_tls_connection_gnutls_handshake_finish (GTlsConnection *conn,
1380 GAsyncResult *result,
1383 g_return_val_if_fail (g_task_is_valid (result, conn), FALSE);
1385 return g_task_propagate_boolean (G_TASK (result), error);
1389 do_implicit_handshake (GTlsConnectionGnutls *gnutls,
1391 GCancellable *cancellable,
1394 /* We have op_mutex */
1396 gnutls->priv->implicit_handshake = g_task_new (gnutls, cancellable, NULL, NULL);
1398 begin_handshake (gnutls);
1402 GError *my_error = NULL;
1405 g_mutex_unlock (&gnutls->priv->op_mutex);
1406 g_task_run_in_thread_sync (gnutls->priv->implicit_handshake,
1408 success = finish_handshake (gnutls,
1409 gnutls->priv->implicit_handshake,
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);
1416 g_propagate_error (error, my_error);
1421 g_task_run_in_thread (gnutls->priv->implicit_handshake,
1422 async_handshake_thread);
1424 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
1425 _("Operation would block"));
1432 g_tls_connection_gnutls_read (GTlsConnectionGnutls *gnutls,
1436 GCancellable *cancellable,
1442 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ,
1443 blocking, cancellable, error))
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);
1450 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ);
1454 else if (ret == GNUTLS_E_REHANDSHAKE)
1461 g_tls_connection_gnutls_write (GTlsConnectionGnutls *gnutls,
1465 GCancellable *cancellable,
1471 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE,
1472 blocking, cancellable, error))
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);
1479 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE);
1483 else if (ret == GNUTLS_E_REHANDSHAKE)
1489 static GInputStream *
1490 g_tls_connection_gnutls_get_input_stream (GIOStream *stream)
1492 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
1494 return gnutls->priv->tls_istream;
1497 static GOutputStream *
1498 g_tls_connection_gnutls_get_output_stream (GIOStream *stream)
1500 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
1502 return gnutls->priv->tls_ostream;
1506 g_tls_connection_gnutls_close (GIOStream *stream,
1507 GCancellable *cancellable,
1510 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
1514 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_CLOSE,
1515 TRUE, cancellable, error))
1518 if (gnutls->priv->closed)
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);
1526 if (gnutls->priv->ever_handshaked)
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);
1534 gnutls->priv->closed = TRUE;
1538 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_CLOSE);
1542 success = g_io_stream_close (gnutls->priv->base_io_stream,
1543 cancellable, error);
1544 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_CLOSE);
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).
1553 close_thread (GTask *task,
1556 GCancellable *cancellable)
1558 GIOStream *stream = object;
1559 GError *error = NULL;
1561 if (!g_tls_connection_gnutls_close (stream, cancellable, &error))
1562 g_task_return_error (task, error);
1564 g_task_return_boolean (task, TRUE);
1568 g_tls_connection_gnutls_close_async (GIOStream *stream,
1570 GCancellable *cancellable,
1571 GAsyncReadyCallback callback,
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);
1583 g_tls_connection_gnutls_close_finish (GIOStream *stream,
1584 GAsyncResult *result,
1587 g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1589 return g_task_propagate_boolean (G_TASK (result), error);
1595 on_pin_prompt_callback (const char *pinfile,
1597 const char *pin_description,
1598 P11KitPinFlags pin_flags,
1599 void *callback_data)
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;
1608 if (!gnutls->priv->interaction)
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;
1618 password = g_pkcs11_pin_new (flags, pin_description);
1620 result = g_tls_interaction_ask_password (gnutls->priv->interaction, password,
1621 g_cancellable_get_current (), &error);
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);
1630 case G_TLS_INTERACTION_UNHANDLED:
1633 case G_TLS_INTERACTION_HANDLED:
1634 pin = g_pkcs11_pin_steal_internal (G_PKCS11_PIN (password));
1638 g_object_unref (password);
1642 #endif /* HAVE_PKCS11 */
1645 g_tls_connection_gnutls_class_init (GTlsConnectionGnutlsClass *klass)
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);
1651 g_type_class_add_private (klass, sizeof (GTlsConnectionGnutlsPrivate));
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;
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;
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;
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");
1679 g_tls_connection_gnutls_initable_iface_init (GInitableIface *iface)
1681 iface->init = g_tls_connection_gnutls_initable_init;