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 itself).
114 * need_finish_handshake means the next claim_op() will get
115 * diverted into finish_handshake().
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.)
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);
194 /* First field is "ssl3 only", second is "allow unsafe rehandshaking" */
195 static gnutls_priority_t priorities[2][2];
198 g_tls_connection_gnutls_init_priorities (void)
200 const gchar *base_priority;
201 gchar *ssl3_priority, *unsafe_rehandshake_priority, *ssl3_unsafe_rehandshake_priority;
203 base_priority = g_getenv ("G_TLS_GNUTLS_PRIORITY");
205 base_priority = "NORMAL:%COMPAT";
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);
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);
216 g_free (ssl3_priority);
217 g_free (unsafe_rehandshake_priority);
218 g_free (ssl3_unsafe_rehandshake_priority);
222 g_tls_connection_gnutls_set_handshake_priority (GTlsConnectionGnutls *gnutls)
224 gboolean use_ssl3, unsafe_rehandshake;
226 if (G_IS_TLS_CLIENT_CONNECTION (gnutls))
227 use_ssl3 = g_tls_client_connection_get_use_ssl3 (G_TLS_CLIENT_CONNECTION (gnutls));
230 unsafe_rehandshake = (gnutls->priv->rehandshake_mode == G_TLS_REHANDSHAKE_UNSAFELY);
231 gnutls_priority_set (gnutls->priv->session,
232 priorities[use_ssl3][unsafe_rehandshake]);
236 g_tls_connection_gnutls_initable_init (GInitable *initable,
237 GCancellable *cancellable,
240 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (initable);
243 g_return_val_if_fail (gnutls->priv->base_istream != NULL &&
244 gnutls->priv->base_ostream != NULL, FALSE);
246 /* Make sure gnutls->priv->session has been initialized (it may have
247 * already been initialized by a construct-time property setter).
249 g_tls_connection_gnutls_get_session (gnutls);
251 status = gnutls_credentials_set (gnutls->priv->session,
252 GNUTLS_CRD_CERTIFICATE,
253 gnutls->priv->creds);
256 g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
257 _("Could not create TLS connection: %s"),
258 gnutls_strerror (status));
262 /* Some servers (especially on embedded devices) use tiny keys that
263 * gnutls will reject by default. We want it to accept them.
265 gnutls_dh_set_prime_bits (gnutls->priv->session, 256);
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);
273 gnutls->priv->tls_istream = g_tls_input_stream_gnutls_new (gnutls);
274 gnutls->priv->tls_ostream = g_tls_output_stream_gnutls_new (gnutls);
280 g_tls_connection_gnutls_finalize (GObject *object)
282 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
284 g_clear_object (&gnutls->priv->base_io_stream);
286 g_clear_object (&gnutls->priv->tls_istream);
287 g_clear_object (&gnutls->priv->tls_ostream);
289 if (gnutls->priv->session)
290 gnutls_deinit (gnutls->priv->session);
291 if (gnutls->priv->creds)
292 gnutls_certificate_free_credentials (gnutls->priv->creds);
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);
300 p11_kit_pin_unregister_callback (gnutls->priv->interaction_id,
301 on_pin_prompt_callback, gnutls);
303 g_free (gnutls->priv->interaction_id);
304 g_clear_object (&gnutls->priv->interaction);
306 g_clear_error (&gnutls->priv->handshake_error);
307 g_clear_error (&gnutls->priv->read_error);
308 g_clear_error (&gnutls->priv->write_error);
310 g_clear_object (&gnutls->priv->waiting_for_op);
312 G_OBJECT_CLASS (g_tls_connection_gnutls_parent_class)->finalize (object);
316 g_tls_connection_gnutls_get_property (GObject *object,
321 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
322 GTlsBackend *backend;
326 case PROP_BASE_IO_STREAM:
327 g_value_set_object (value, gnutls->priv->base_io_stream);
330 case PROP_REQUIRE_CLOSE_NOTIFY:
331 g_value_set_boolean (value, gnutls->priv->require_close_notify);
334 case PROP_REHANDSHAKE_MODE:
335 g_value_set_enum (value, gnutls->priv->rehandshake_mode);
338 case PROP_USE_SYSTEM_CERTDB:
339 g_value_set_boolean (value, gnutls->priv->is_system_certdb);
343 if (gnutls->priv->database_is_unset)
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;
349 g_value_set_object (value, gnutls->priv->database);
352 case PROP_CERTIFICATE:
353 g_value_set_object (value, gnutls->priv->certificate);
356 case PROP_INTERACTION:
357 g_value_set_object (value, gnutls->priv->interaction);
360 case PROP_PEER_CERTIFICATE:
361 g_value_set_object (value, gnutls->priv->peer_certificate);
364 case PROP_PEER_CERTIFICATE_ERRORS:
365 g_value_set_flags (value, gnutls->priv->peer_certificate_errors);
369 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
374 g_tls_connection_gnutls_set_property (GObject *object,
379 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
380 GInputStream *istream;
381 GOutputStream *ostream;
382 gboolean system_certdb;
383 GTlsBackend *backend;
387 case PROP_BASE_IO_STREAM:
388 if (gnutls->priv->base_io_stream)
390 g_object_unref (gnutls->priv->base_io_stream);
391 gnutls->priv->base_istream = NULL;
392 gnutls->priv->base_ostream = NULL;
394 gnutls->priv->base_io_stream = g_value_dup_object (value);
395 if (!gnutls->priv->base_io_stream)
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);
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);
409 case PROP_REQUIRE_CLOSE_NOTIFY:
410 gnutls->priv->require_close_notify = g_value_get_boolean (value);
413 case PROP_REHANDSHAKE_MODE:
414 gnutls->priv->rehandshake_mode = g_value_get_enum (value);
417 case PROP_USE_SYSTEM_CERTDB:
418 system_certdb = g_value_get_boolean (value);
419 if (system_certdb != gnutls->priv->is_system_certdb)
421 g_clear_object (&gnutls->priv->database);
424 backend = g_tls_backend_get_default ();
425 gnutls->priv->database = g_tls_backend_get_default_database (backend);
427 gnutls->priv->is_system_certdb = system_certdb;
428 gnutls->priv->database_is_unset = FALSE;
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;
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);
445 case PROP_INTERACTION:
446 g_clear_object (&gnutls->priv->interaction);
447 gnutls->priv->interaction = g_value_dup_object (value);
451 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
455 gnutls_certificate_credentials
456 g_tls_connection_gnutls_get_credentials (GTlsConnectionGnutls *gnutls)
458 return gnutls->priv->creds;
462 g_tls_connection_gnutls_get_session (GTlsConnectionGnutls *gnutls)
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.
470 if (!gnutls->priv->session)
472 gboolean client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
473 gnutls_init (&gnutls->priv->session, client ? GNUTLS_CLIENT : GNUTLS_SERVER);
476 return gnutls->priv->session;
480 g_tls_connection_gnutls_get_certificate (GTlsConnectionGnutls *gnutls,
483 GTlsCertificate *cert;
485 cert = g_tls_connection_get_certificate (G_TLS_CONNECTION (gnutls));
487 st->cert_type = GNUTLS_CRT_X509;
491 g_tls_certificate_gnutls_copy (G_TLS_CERTIFICATE_GNUTLS (cert),
492 gnutls->priv->interaction_id, st);
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;
503 claim_op (GTlsConnectionGnutls *gnutls,
504 GTlsConnectionGnutlsOp op,
506 GCancellable *cancellable,
510 if (g_cancellable_set_error_if_cancelled (cancellable, error))
513 g_mutex_lock (&gnutls->priv->op_mutex);
515 if (gnutls->priv->closing || gnutls->priv->closed)
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);
523 if (gnutls->priv->handshake_error && op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE)
526 *error = g_error_copy (gnutls->priv->handshake_error);
527 g_mutex_unlock (&gnutls->priv->op_mutex);
531 if (op != G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE &&
532 op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE)
534 if (gnutls->priv->need_handshake)
536 gnutls->priv->need_handshake = FALSE;
537 gnutls->priv->handshaking = TRUE;
538 if (!do_implicit_handshake (gnutls, blocking, cancellable, error))
540 g_mutex_unlock (&gnutls->priv->op_mutex);
545 if (gnutls->priv->need_finish_handshake)
547 GError *my_error = NULL;
550 gnutls->priv->need_finish_handshake = FALSE;
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);
557 gnutls->priv->handshaking = FALSE;
558 if (!success || g_cancellable_set_error_if_cancelled (cancellable, &my_error))
560 g_propagate_error (error, my_error);
561 g_mutex_unlock (&gnutls->priv->op_mutex);
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))
574 g_cancellable_reset (gnutls->priv->waiting_for_op);
576 g_mutex_unlock (&gnutls->priv->op_mutex);
580 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
581 _("Operation would block"));
585 g_cancellable_make_pollfd (gnutls->priv->waiting_for_op, &fds[0]);
586 if (g_cancellable_make_pollfd (cancellable, &fds[0]))
590 g_poll (fds, nfds, -1);
591 g_cancellable_release_fd (cancellable);
596 if (op == G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE)
598 gnutls->priv->handshaking = TRUE;
599 gnutls->priv->need_handshake = FALSE;
601 if (op == G_TLS_CONNECTION_GNUTLS_OP_CLOSE)
602 gnutls->priv->closing = TRUE;
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;
609 g_mutex_unlock (&gnutls->priv->op_mutex);
614 yield_op (GTlsConnectionGnutls *gnutls,
615 GTlsConnectionGnutlsOp op)
617 g_mutex_lock (&gnutls->priv->op_mutex);
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;
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;
629 g_cancellable_cancel (gnutls->priv->waiting_for_op);
630 g_mutex_unlock (&gnutls->priv->op_mutex);
634 begin_gnutls_io (GTlsConnectionGnutls *gnutls,
635 GIOCondition direction,
637 GCancellable *cancellable)
639 g_assert (direction & (G_IO_IN | G_IO_OUT));
641 if (direction & G_IO_IN)
643 gnutls->priv->read_blocking = blocking;
644 gnutls->priv->read_cancellable = cancellable;
645 g_clear_error (&gnutls->priv->read_error);
648 if (direction & G_IO_OUT)
650 gnutls->priv->write_blocking = blocking;
651 gnutls->priv->write_cancellable = cancellable;
652 g_clear_error (&gnutls->priv->write_error);
657 end_gnutls_io (GTlsConnectionGnutls *gnutls,
658 GIOCondition direction,
663 GError *my_error = NULL;
665 g_assert (direction & (G_IO_IN | G_IO_OUT));
666 g_assert (!error || !*error);
668 if (status == GNUTLS_E_AGAIN ||
669 status == GNUTLS_E_WARNING_ALERT_RECEIVED)
670 return GNUTLS_E_AGAIN;
672 if (direction & G_IO_IN)
674 gnutls->priv->read_cancellable = NULL;
677 my_error = gnutls->priv->read_error;
678 gnutls->priv->read_error = NULL;
681 g_clear_error (&gnutls->priv->read_error);
683 if (direction & G_IO_OUT)
685 gnutls->priv->write_cancellable = NULL;
686 if (status < 0 && !my_error)
688 my_error = gnutls->priv->write_error;
689 gnutls->priv->write_error = NULL;
692 g_clear_error (&gnutls->priv->write_error);
698 if (gnutls->priv->handshaking && !gnutls->priv->ever_handshaked)
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) ||
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)
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;
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);
723 else if (status == GNUTLS_E_REHANDSHAKE)
725 if (gnutls->priv->rehandshake_mode == G_TLS_REHANDSHAKE_NEVER)
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;
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);
738 else if (status == GNUTLS_E_GOT_APPLICATION_DATA)
740 if (gnutls->priv->handshaking && G_IS_TLS_SERVER_CONNECTION (gnutls))
741 return GNUTLS_E_AGAIN;
744 #ifdef GNUTLS_E_PREMATURE_TERMINATION
745 status == GNUTLS_E_PREMATURE_TERMINATION
747 status == GNUTLS_E_UNEXPECTED_PACKET_LENGTH && gnutls->priv->eof
751 if (gnutls->priv->require_close_notify)
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);
761 else if (status == GNUTLS_E_NO_CERTIFICATE_FOUND)
763 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED,
764 _("TLS connection peer did not send a certificate"));
770 g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
771 errmsg, gnutls_strerror (status));
776 #define BEGIN_GNUTLS_IO(gnutls, direction, blocking, cancellable) \
777 begin_gnutls_io (gnutls, direction, blocking, cancellable); \
780 #define END_GNUTLS_IO(gnutls, direction, ret, errmsg, err) \
781 } while ((ret = end_gnutls_io (gnutls, direction, ret, errmsg, err)) == GNUTLS_E_AGAIN);
784 g_tls_connection_gnutls_check (GTlsConnectionGnutls *gnutls,
785 GIOCondition condition)
787 /* Racy, but worst case is that we just get WOULD_BLOCK back */
788 if (gnutls->priv->need_finish_handshake)
791 /* If a handshake or close is in progress, then tls_istream and
792 * tls_ostream are blocked, regardless of the base stream status.
794 if (gnutls->priv->handshaking || gnutls->priv->closing)
797 if (condition & G_IO_IN)
798 return g_pollable_input_stream_is_readable (gnutls->priv->base_istream);
800 return g_pollable_output_stream_is_writable (gnutls->priv->base_ostream);
806 GTlsConnectionGnutls *gnutls;
809 GSource *child_source;
810 GIOCondition condition;
814 } GTlsConnectionGnutlsSource;
817 gnutls_source_prepare (GSource *source,
825 gnutls_source_check (GSource *source)
831 gnutls_source_sync (GTlsConnectionGnutlsSource *gnutls_source)
833 GTlsConnectionGnutls *gnutls = gnutls_source->gnutls;
834 gboolean io_waiting, op_waiting;
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))
844 if (!op_waiting && !gnutls->priv->need_handshake &&
845 !gnutls->priv->need_finish_handshake)
849 g_mutex_unlock (&gnutls->priv->op_mutex);
851 if (op_waiting == gnutls_source->op_waiting &&
852 io_waiting == gnutls_source->io_waiting)
854 gnutls_source->op_waiting = op_waiting;
855 gnutls_source->io_waiting = io_waiting;
857 if (gnutls_source->child_source)
859 g_source_remove_child_source ((GSource *)gnutls_source,
860 gnutls_source->child_source);
861 g_source_unref (gnutls_source->child_source);
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);
871 gnutls_source->child_source = g_timeout_source_new (0);
873 g_source_set_dummy_callback (gnutls_source->child_source);
874 g_source_add_child_source ((GSource *)gnutls_source, gnutls_source->child_source);
878 gnutls_source_dispatch (GSource *source,
879 GSourceFunc callback,
882 GPollableSourceFunc func = (GPollableSourceFunc)callback;
883 GTlsConnectionGnutlsSource *gnutls_source = (GTlsConnectionGnutlsSource *)source;
886 ret = (*func) (gnutls_source->stream, user_data);
888 gnutls_source_sync (gnutls_source);
894 gnutls_source_finalize (GSource *source)
896 GTlsConnectionGnutlsSource *gnutls_source = (GTlsConnectionGnutlsSource *)source;
898 g_object_unref (gnutls_source->gnutls);
899 g_source_unref (gnutls_source->child_source);
903 g_tls_connection_gnutls_source_closure_callback (GObject *stream,
906 GClosure *closure = data;
908 GValue param = { 0, };
909 GValue result_value = { 0, };
912 g_value_init (&result_value, G_TYPE_BOOLEAN);
914 g_value_init (¶m, G_TYPE_OBJECT);
915 g_value_set_object (¶m, stream);
917 g_closure_invoke (closure, &result_value, 1, ¶m, NULL);
919 result = g_value_get_boolean (&result_value);
920 g_value_unset (&result_value);
921 g_value_unset (¶m);
926 static GSourceFuncs gnutls_source_funcs =
928 gnutls_source_prepare,
930 gnutls_source_dispatch,
931 gnutls_source_finalize,
932 (GSourceFunc)g_tls_connection_gnutls_source_closure_callback,
933 (GSourceDummyMarshal)g_cclosure_marshal_generic
937 g_tls_connection_gnutls_create_source (GTlsConnectionGnutls *gnutls,
938 GIOCondition condition,
939 GCancellable *cancellable)
941 GSource *source, *cancellable_source;
942 GTlsConnectionGnutlsSource *gnutls_source;
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);
954 gnutls_source->op_waiting = (gboolean) -1;
955 gnutls_source->io_waiting = (gboolean) -1;
956 gnutls_source_sync (gnutls_source);
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);
970 set_gnutls_error (GTlsConnectionGnutls *gnutls,
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
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);
985 gnutls_transport_set_errno (gnutls->priv->session, EIO);
989 g_tls_connection_gnutls_pull_func (gnutls_transport_ptr_t transport_data,
993 GTlsConnectionGnutls *gnutls = transport_data;
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.)
1002 g_clear_error (&gnutls->priv->read_error);
1004 ret = g_pollable_stream_read (G_INPUT_STREAM (gnutls->priv->base_istream),
1006 gnutls->priv->read_blocking,
1007 gnutls->priv->read_cancellable,
1008 &gnutls->priv->read_error);
1011 set_gnutls_error (gnutls, gnutls->priv->read_error);
1012 #ifndef GNUTLS_E_PREMATURE_TERMINATION
1014 gnutls->priv->eof = TRUE;
1021 g_tls_connection_gnutls_push_func (gnutls_transport_ptr_t transport_data,
1025 GTlsConnectionGnutls *gnutls = transport_data;
1028 /* See comment in pull_func. */
1029 g_clear_error (&gnutls->priv->write_error);
1031 ret = g_pollable_stream_write (G_OUTPUT_STREAM (gnutls->priv->base_ostream),
1033 gnutls->priv->write_blocking,
1034 gnutls->priv->write_cancellable,
1035 &gnutls->priv->write_error);
1037 set_gnutls_error (gnutls, gnutls->priv->write_error);
1043 static GTlsCertificate *
1044 get_peer_certificate_from_session (GTlsConnectionGnutls *gnutls)
1046 GTlsCertificate *chain, *cert;
1047 const gnutls_datum_t *certs;
1048 unsigned int num_certs;
1051 certs = gnutls_certificate_get_peers (gnutls->priv->session, &num_certs);
1052 if (!certs || !num_certs)
1056 for (i = num_certs - 1; i >= 0; i--)
1058 cert = g_tls_certificate_gnutls_new (&certs[i], chain);
1060 g_object_unref (chain);
1067 static GTlsCertificateFlags
1068 verify_peer_certificate (GTlsConnectionGnutls *gnutls,
1069 GTlsCertificate *peer_certificate)
1071 GTlsConnection *conn = G_TLS_CONNECTION (gnutls);
1072 GSocketConnectable *peer_identity;
1073 GTlsDatabase *database;
1074 GTlsCertificateFlags errors;
1077 is_client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
1079 peer_identity = g_tls_client_connection_get_server_identity (G_TLS_CLIENT_CONNECTION (gnutls));
1081 peer_identity = NULL;
1085 database = g_tls_connection_get_database (conn);
1086 if (database == NULL)
1088 errors |= G_TLS_CERTIFICATE_UNKNOWN_CA;
1089 errors |= g_tls_certificate_verify (peer_certificate, peer_identity, NULL);
1093 GError *error = NULL;
1095 errors |= g_tls_database_verify_chain (database, peer_certificate,
1097 G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER :
1098 G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT,
1100 g_tls_connection_get_interaction (conn),
1101 G_TLS_DATABASE_VERIFY_NONE,
1105 g_warning ("failure verifying certificate chain: %s",
1107 g_assert (errors != 0);
1108 g_clear_error (&error);
1116 handshake_thread (GTask *task,
1119 GCancellable *cancellable)
1121 GTlsConnectionGnutls *gnutls = object;
1123 GError *error = NULL;
1126 gnutls->priv->started_handshake = FALSE;
1128 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE,
1129 TRUE, cancellable, &error))
1131 g_task_return_error (task, error);
1135 g_clear_error (&gnutls->priv->handshake_error);
1137 is_client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
1139 if (!is_client && gnutls->priv->ever_handshaked &&
1140 !gnutls->priv->implicit_handshake)
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);
1149 g_task_return_error (task, error);
1154 gnutls->priv->started_handshake = TRUE;
1156 g_clear_object (&gnutls->priv->peer_certificate);
1157 gnutls->priv->peer_certificate_errors = 0;
1159 g_tls_connection_gnutls_set_handshake_priority (gnutls);
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);
1166 if (ret == 0 && gnutls_certificate_type_get (gnutls->priv->session) == GNUTLS_CRT_X509)
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))
1173 g_set_error_literal (&error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
1174 _("Server did not return a valid TLS certificate"));
1178 G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->finish_handshake (gnutls, &error);
1182 g_task_return_error (task, error);
1186 gnutls->priv->ever_handshaked = TRUE;
1187 g_task_return_boolean (task, TRUE);
1192 accept_peer_certificate (GTlsConnectionGnutls *gnutls,
1193 GTlsCertificate *peer_certificate,
1194 GTlsCertificateFlags peer_certificate_errors)
1198 if (G_IS_TLS_CLIENT_CONNECTION (gnutls))
1200 GTlsCertificateFlags validation_flags =
1201 g_tls_client_connection_get_validation_flags (G_TLS_CLIENT_CONNECTION (gnutls));
1203 if ((peer_certificate_errors & validation_flags) == 0)
1207 accepted = g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls),
1209 peer_certificate_errors);
1214 accepted = g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls),
1216 peer_certificate_errors);
1223 begin_handshake (GTlsConnectionGnutls *gnutls)
1225 G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->begin_handshake (gnutls);
1229 finish_handshake (GTlsConnectionGnutls *gnutls,
1233 GTlsCertificate *peer_certificate;
1234 GTlsCertificateFlags peer_certificate_errors;
1236 g_assert (error != NULL);
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;
1243 if (g_task_propagate_boolean (task, error) && peer_certificate)
1245 if (!accept_peer_certificate (gnutls, peer_certificate,
1246 peer_certificate_errors))
1248 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
1249 _("Unacceptable TLS certificate"));
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");
1258 if (*error && gnutls->priv->started_handshake)
1259 gnutls->priv->handshake_error = g_error_copy (*error);
1261 return (*error == NULL);
1265 g_tls_connection_gnutls_handshake (GTlsConnection *conn,
1266 GCancellable *cancellable,
1269 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (conn);
1272 GError *my_error = NULL;
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);
1280 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
1283 g_propagate_error (error, my_error);
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().
1293 handshake_thread_completed (GObject *object,
1294 GAsyncResult *result,
1297 GTask *caller_task = user_data;
1298 GTlsConnectionGnutls *gnutls = g_task_get_source_object (caller_task);
1299 GError *error = NULL;
1302 success = finish_handshake (gnutls, G_TASK (result), &error);
1303 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
1306 g_task_return_boolean (caller_task, TRUE);
1308 g_task_return_error (caller_task, error);
1309 g_object_unref (caller_task);
1313 g_tls_connection_gnutls_handshake_async (GTlsConnection *conn,
1315 GCancellable *cancellable,
1316 GAsyncReadyCallback callback,
1319 GTask *thread_task, *caller_task;
1321 caller_task = g_task_new (conn, cancellable, callback, user_data);
1322 g_task_set_priority (caller_task, io_priority);
1324 begin_handshake (G_TLS_CONNECTION_GNUTLS (conn));
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);
1334 g_tls_connection_gnutls_handshake_finish (GTlsConnection *conn,
1335 GAsyncResult *result,
1338 g_return_val_if_fail (g_task_is_valid (result, conn), FALSE);
1340 return g_task_propagate_boolean (G_TASK (result), error);
1344 implicit_handshake_completed (GObject *object,
1345 GAsyncResult *result,
1348 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
1350 g_mutex_lock (&gnutls->priv->op_mutex);
1351 gnutls->priv->need_finish_handshake = TRUE;
1352 g_mutex_unlock (&gnutls->priv->op_mutex);
1354 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
1358 do_implicit_handshake (GTlsConnectionGnutls *gnutls,
1360 GCancellable *cancellable,
1363 /* We have op_mutex */
1365 gnutls->priv->implicit_handshake = g_task_new (gnutls, cancellable,
1366 implicit_handshake_completed,
1369 begin_handshake (gnutls);
1373 GError *my_error = NULL;
1376 g_mutex_unlock (&gnutls->priv->op_mutex);
1377 g_task_run_in_thread_sync (gnutls->priv->implicit_handshake,
1379 success = finish_handshake (gnutls,
1380 gnutls->priv->implicit_handshake,
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);
1387 g_propagate_error (error, my_error);
1392 g_task_run_in_thread (gnutls->priv->implicit_handshake,
1395 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
1396 _("Operation would block"));
1403 g_tls_connection_gnutls_read (GTlsConnectionGnutls *gnutls,
1407 GCancellable *cancellable,
1413 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ,
1414 blocking, cancellable, error))
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);
1421 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ);
1425 else if (ret == GNUTLS_E_REHANDSHAKE)
1432 g_tls_connection_gnutls_write (GTlsConnectionGnutls *gnutls,
1436 GCancellable *cancellable,
1442 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE,
1443 blocking, cancellable, error))
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);
1450 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE);
1454 else if (ret == GNUTLS_E_REHANDSHAKE)
1460 static GInputStream *
1461 g_tls_connection_gnutls_get_input_stream (GIOStream *stream)
1463 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
1465 return gnutls->priv->tls_istream;
1468 static GOutputStream *
1469 g_tls_connection_gnutls_get_output_stream (GIOStream *stream)
1471 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
1473 return gnutls->priv->tls_ostream;
1477 g_tls_connection_gnutls_close (GIOStream *stream,
1478 GCancellable *cancellable,
1481 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
1485 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_CLOSE,
1486 TRUE, cancellable, error))
1489 if (gnutls->priv->closed)
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);
1497 if (gnutls->priv->ever_handshaked)
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);
1505 gnutls->priv->closed = TRUE;
1509 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_CLOSE);
1513 success = g_io_stream_close (gnutls->priv->base_io_stream,
1514 cancellable, error);
1515 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_CLOSE);
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).
1524 close_thread (GTask *task,
1527 GCancellable *cancellable)
1529 GIOStream *stream = object;
1530 GError *error = NULL;
1532 if (!g_tls_connection_gnutls_close (stream, cancellable, &error))
1533 g_task_return_error (task, error);
1535 g_task_return_boolean (task, TRUE);
1539 g_tls_connection_gnutls_close_async (GIOStream *stream,
1541 GCancellable *cancellable,
1542 GAsyncReadyCallback callback,
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);
1554 g_tls_connection_gnutls_close_finish (GIOStream *stream,
1555 GAsyncResult *result,
1558 g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1560 return g_task_propagate_boolean (G_TASK (result), error);
1566 on_pin_prompt_callback (const char *pinfile,
1568 const char *pin_description,
1569 P11KitPinFlags pin_flags,
1570 void *callback_data)
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;
1579 if (!gnutls->priv->interaction)
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;
1589 password = g_pkcs11_pin_new (flags, pin_description);
1591 result = g_tls_interaction_ask_password (gnutls->priv->interaction, password,
1592 g_cancellable_get_current (), &error);
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);
1601 case G_TLS_INTERACTION_UNHANDLED:
1604 case G_TLS_INTERACTION_HANDLED:
1605 pin = g_pkcs11_pin_steal_internal (G_PKCS11_PIN (password));
1609 g_object_unref (password);
1613 #endif /* HAVE_PKCS11 */
1616 g_tls_connection_gnutls_class_init (GTlsConnectionGnutlsClass *klass)
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);
1622 g_type_class_add_private (klass, sizeof (GTlsConnectionGnutlsPrivate));
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;
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;
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;
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");
1650 g_tls_connection_gnutls_initable_iface_init (GInitableIface *iface)
1652 iface->init = g_tls_connection_gnutls_initable_init;