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 gboolean require_close_notify;
104 GTlsRehandshakeMode rehandshake_mode;
105 gboolean is_system_certdb;
106 GTlsDatabase *database;
107 gboolean database_is_unset;
109 /* need_handshake means the next claim_op() will get diverted into
110 * an implicit handshake (unless it's an OP_HANDSHAKE itself).
111 * need_finish_handshake means the next claim_op() will get
112 * diverted into finish_handshake().
114 * handshaking is TRUE as soon as a handshake thread is queued.
115 * Normally it becomes FALSE after finish_handshake() completes. For
116 * an implicit handshake, but in the case of an async implicit
117 * handshake, it becomes FALSE at the end of handshake_thread(),
118 * (and then the next read/write op will call finish_handshake()).
119 * This is because we don't want to call finish_handshake() (and
120 * possibly emit signals) if the caller is not actually in a TLS op
121 * at the time. (Eg, if they're waiting to try a nonblocking call
122 * again, we don't want to emit the signal until they do.)
124 * started_handshake indicates that the current handshake attempt
125 * got at least as far as calling gnutls_handshake() (and so any
126 * error should be copied to handshake_error and returned on all
127 * future operations). ever_handshaked indicates that TLS has
128 * been successfully negotiated at some point.
130 gboolean need_handshake, need_finish_handshake;
131 gboolean started_handshake, handshaking, ever_handshaked;
132 GTask *implicit_handshake;
133 GError *handshake_error;
135 gboolean closing, closed;
137 GInputStream *tls_istream;
138 GOutputStream *tls_ostream;
140 GTlsInteraction *interaction;
141 gchar *interaction_id;
144 GCancellable *waiting_for_op;
147 gboolean read_blocking;
149 GCancellable *read_cancellable;
152 gboolean write_blocking;
154 GCancellable *write_cancellable;
156 #ifndef GNUTLS_E_PREMATURE_TERMINATION
161 static gint unique_interaction_id = 0;
164 g_tls_connection_gnutls_init (GTlsConnectionGnutls *gnutls)
168 gnutls->priv = G_TYPE_INSTANCE_GET_PRIVATE (gnutls, G_TYPE_TLS_CONNECTION_GNUTLS, GTlsConnectionGnutlsPrivate);
170 gnutls_certificate_allocate_credentials (&gnutls->priv->creds);
171 gnutls_certificate_set_verify_flags (gnutls->priv->creds,
172 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
174 gnutls->priv->need_handshake = TRUE;
176 gnutls->priv->database_is_unset = TRUE;
177 gnutls->priv->is_system_certdb = TRUE;
179 unique_id = g_atomic_int_add (&unique_interaction_id, 1);
180 gnutls->priv->interaction_id = g_strdup_printf ("gtls:%d", unique_id);
183 p11_kit_pin_register_callback (gnutls->priv->interaction_id,
184 on_pin_prompt_callback, gnutls, NULL);
187 gnutls->priv->waiting_for_op = g_cancellable_new ();
188 g_cancellable_cancel (gnutls->priv->waiting_for_op);
191 /* First field is "ssl3 only", second is "allow unsafe rehandshaking" */
192 static gnutls_priority_t priorities[2][2];
195 g_tls_connection_gnutls_init_priorities (void)
197 const gchar *base_priority;
198 gchar *ssl3_priority, *unsafe_rehandshake_priority, *ssl3_unsafe_rehandshake_priority;
200 base_priority = g_getenv ("G_TLS_GNUTLS_PRIORITY");
202 base_priority = "NORMAL:%COMPAT";
204 ssl3_priority = g_strdup_printf ("%s:!VERS-TLS1.2:!VERS-TLS1.1:!VERS-TLS1.0", base_priority);
205 unsafe_rehandshake_priority = g_strdup_printf ("%s:%%UNSAFE_RENEGOTIATION", base_priority);
206 ssl3_unsafe_rehandshake_priority = g_strdup_printf ("%s:!VERS-TLS1.2:!VERS-TLS1.1:!VERS-TLS1.0:%%UNSAFE_RENEGOTIATION", base_priority);
208 gnutls_priority_init (&priorities[FALSE][FALSE], base_priority, NULL);
209 gnutls_priority_init (&priorities[TRUE][FALSE], ssl3_priority, NULL);
210 gnutls_priority_init (&priorities[FALSE][TRUE], unsafe_rehandshake_priority, NULL);
211 gnutls_priority_init (&priorities[TRUE][TRUE], ssl3_unsafe_rehandshake_priority, NULL);
213 g_free (ssl3_priority);
214 g_free (unsafe_rehandshake_priority);
215 g_free (ssl3_unsafe_rehandshake_priority);
219 g_tls_connection_gnutls_set_handshake_priority (GTlsConnectionGnutls *gnutls)
221 gboolean use_ssl3, unsafe_rehandshake;
223 if (G_IS_TLS_CLIENT_CONNECTION (gnutls))
224 use_ssl3 = g_tls_client_connection_get_use_ssl3 (G_TLS_CLIENT_CONNECTION (gnutls));
227 unsafe_rehandshake = (gnutls->priv->rehandshake_mode == G_TLS_REHANDSHAKE_UNSAFELY);
228 gnutls_priority_set (gnutls->priv->session,
229 priorities[use_ssl3][unsafe_rehandshake]);
233 g_tls_connection_gnutls_initable_init (GInitable *initable,
234 GCancellable *cancellable,
237 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (initable);
240 g_return_val_if_fail (gnutls->priv->base_istream != NULL &&
241 gnutls->priv->base_ostream != NULL, FALSE);
243 /* Make sure gnutls->priv->session has been initialized (it may have
244 * already been initialized by a construct-time property setter).
246 g_tls_connection_gnutls_get_session (gnutls);
248 status = gnutls_credentials_set (gnutls->priv->session,
249 GNUTLS_CRD_CERTIFICATE,
250 gnutls->priv->creds);
253 g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
254 _("Could not create TLS connection: %s"),
255 gnutls_strerror (status));
259 /* Some servers (especially on embedded devices) use tiny keys that
260 * gnutls will reject by default. We want it to accept them.
262 gnutls_dh_set_prime_bits (gnutls->priv->session, 256);
264 gnutls_transport_set_push_function (gnutls->priv->session,
265 g_tls_connection_gnutls_push_func);
266 gnutls_transport_set_pull_function (gnutls->priv->session,
267 g_tls_connection_gnutls_pull_func);
268 gnutls_transport_set_ptr (gnutls->priv->session, gnutls);
270 gnutls->priv->tls_istream = g_tls_input_stream_gnutls_new (gnutls);
271 gnutls->priv->tls_ostream = g_tls_output_stream_gnutls_new (gnutls);
277 g_tls_connection_gnutls_finalize (GObject *object)
279 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
281 g_clear_object (&gnutls->priv->base_io_stream);
283 g_clear_object (&gnutls->priv->tls_istream);
284 g_clear_object (&gnutls->priv->tls_ostream);
286 if (gnutls->priv->session)
287 gnutls_deinit (gnutls->priv->session);
288 if (gnutls->priv->creds)
289 gnutls_certificate_free_credentials (gnutls->priv->creds);
291 g_clear_object (&gnutls->priv->database);
292 g_clear_object (&gnutls->priv->certificate);
293 g_clear_object (&gnutls->priv->peer_certificate);
296 p11_kit_pin_unregister_callback (gnutls->priv->interaction_id,
297 on_pin_prompt_callback, gnutls);
299 g_free (gnutls->priv->interaction_id);
300 g_clear_object (&gnutls->priv->interaction);
302 g_clear_error (&gnutls->priv->handshake_error);
303 g_clear_error (&gnutls->priv->read_error);
304 g_clear_error (&gnutls->priv->write_error);
306 g_clear_object (&gnutls->priv->waiting_for_op);
308 G_OBJECT_CLASS (g_tls_connection_gnutls_parent_class)->finalize (object);
312 g_tls_connection_gnutls_get_property (GObject *object,
317 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
318 GTlsBackend *backend;
322 case PROP_BASE_IO_STREAM:
323 g_value_set_object (value, gnutls->priv->base_io_stream);
326 case PROP_REQUIRE_CLOSE_NOTIFY:
327 g_value_set_boolean (value, gnutls->priv->require_close_notify);
330 case PROP_REHANDSHAKE_MODE:
331 g_value_set_enum (value, gnutls->priv->rehandshake_mode);
334 case PROP_USE_SYSTEM_CERTDB:
335 g_value_set_boolean (value, gnutls->priv->is_system_certdb);
339 if (gnutls->priv->database_is_unset)
341 backend = g_tls_backend_get_default ();
342 gnutls->priv->database = g_tls_backend_get_default_database (backend);
343 gnutls->priv->database_is_unset = FALSE;
345 g_value_set_object (value, gnutls->priv->database);
348 case PROP_CERTIFICATE:
349 g_value_set_object (value, gnutls->priv->certificate);
352 case PROP_INTERACTION:
353 g_value_set_object (value, gnutls->priv->interaction);
356 case PROP_PEER_CERTIFICATE:
357 g_value_set_object (value, gnutls->priv->peer_certificate);
360 case PROP_PEER_CERTIFICATE_ERRORS:
361 g_value_set_flags (value, gnutls->priv->peer_certificate_errors);
365 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
370 g_tls_connection_gnutls_set_property (GObject *object,
375 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
376 GInputStream *istream;
377 GOutputStream *ostream;
378 gboolean system_certdb;
379 GTlsBackend *backend;
383 case PROP_BASE_IO_STREAM:
384 if (gnutls->priv->base_io_stream)
386 g_object_unref (gnutls->priv->base_io_stream);
387 gnutls->priv->base_istream = NULL;
388 gnutls->priv->base_ostream = NULL;
390 gnutls->priv->base_io_stream = g_value_dup_object (value);
391 if (!gnutls->priv->base_io_stream)
394 istream = g_io_stream_get_input_stream (gnutls->priv->base_io_stream);
395 ostream = g_io_stream_get_output_stream (gnutls->priv->base_io_stream);
397 if (G_IS_POLLABLE_INPUT_STREAM (istream) &&
398 g_pollable_input_stream_can_poll (G_POLLABLE_INPUT_STREAM (istream)))
399 gnutls->priv->base_istream = G_POLLABLE_INPUT_STREAM (istream);
400 if (G_IS_POLLABLE_OUTPUT_STREAM (ostream) &&
401 g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (ostream)))
402 gnutls->priv->base_ostream = G_POLLABLE_OUTPUT_STREAM (ostream);
405 case PROP_REQUIRE_CLOSE_NOTIFY:
406 gnutls->priv->require_close_notify = g_value_get_boolean (value);
409 case PROP_REHANDSHAKE_MODE:
410 gnutls->priv->rehandshake_mode = g_value_get_enum (value);
413 case PROP_USE_SYSTEM_CERTDB:
414 system_certdb = g_value_get_boolean (value);
415 if (system_certdb != gnutls->priv->is_system_certdb)
417 g_clear_object (&gnutls->priv->database);
420 backend = g_tls_backend_get_default ();
421 gnutls->priv->database = g_tls_backend_get_default_database (backend);
423 gnutls->priv->is_system_certdb = system_certdb;
424 gnutls->priv->database_is_unset = FALSE;
429 g_clear_object (&gnutls->priv->database);
430 gnutls->priv->database = g_value_dup_object (value);
431 gnutls->priv->is_system_certdb = FALSE;
432 gnutls->priv->database_is_unset = FALSE;
435 case PROP_CERTIFICATE:
436 if (gnutls->priv->certificate)
437 g_object_unref (gnutls->priv->certificate);
438 gnutls->priv->certificate = g_value_dup_object (value);
441 case PROP_INTERACTION:
442 g_clear_object (&gnutls->priv->interaction);
443 gnutls->priv->interaction = g_value_dup_object (value);
447 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
451 gnutls_certificate_credentials
452 g_tls_connection_gnutls_get_credentials (GTlsConnectionGnutls *gnutls)
454 return gnutls->priv->creds;
458 g_tls_connection_gnutls_get_session (GTlsConnectionGnutls *gnutls)
460 /* Ideally we would initialize gnutls->priv->session from
461 * g_tls_connection_gnutls_init(), but we can't tell if it's a
462 * client or server connection at that point... And
463 * g_tls_connection_gnutls_initiable_init() is too late, because
464 * construct-time property setters may need to modify it.
466 if (!gnutls->priv->session)
468 gboolean client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
469 gnutls_init (&gnutls->priv->session, client ? GNUTLS_CLIENT : GNUTLS_SERVER);
472 return gnutls->priv->session;
476 g_tls_connection_gnutls_get_certificate (GTlsConnectionGnutls *gnutls,
479 GTlsCertificate *cert;
481 cert = g_tls_connection_get_certificate (G_TLS_CONNECTION (gnutls));
483 st->cert_type = GNUTLS_CRT_X509;
487 g_tls_certificate_gnutls_copy (G_TLS_CERTIFICATE_GNUTLS (cert),
488 gnutls->priv->interaction_id, st);
492 G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE,
493 G_TLS_CONNECTION_GNUTLS_OP_READ,
494 G_TLS_CONNECTION_GNUTLS_OP_WRITE,
495 G_TLS_CONNECTION_GNUTLS_OP_CLOSE,
496 } GTlsConnectionGnutlsOp;
499 claim_op (GTlsConnectionGnutls *gnutls,
500 GTlsConnectionGnutlsOp op,
502 GCancellable *cancellable,
506 if (g_cancellable_set_error_if_cancelled (cancellable, error))
509 g_mutex_lock (&gnutls->priv->op_mutex);
511 if (gnutls->priv->closing || gnutls->priv->closed)
513 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
514 _("Connection is closed"));
515 g_mutex_unlock (&gnutls->priv->op_mutex);
519 if (gnutls->priv->handshake_error && op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE)
522 *error = g_error_copy (gnutls->priv->handshake_error);
523 g_mutex_unlock (&gnutls->priv->op_mutex);
527 if (op != G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE &&
528 op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE)
530 if (gnutls->priv->need_handshake)
532 gnutls->priv->need_handshake = FALSE;
533 gnutls->priv->handshaking = TRUE;
534 if (!do_implicit_handshake (gnutls, blocking, cancellable, error))
536 g_mutex_unlock (&gnutls->priv->op_mutex);
541 if (gnutls->priv->need_finish_handshake)
543 GError *my_error = NULL;
546 gnutls->priv->need_finish_handshake = FALSE;
548 g_mutex_unlock (&gnutls->priv->op_mutex);
549 success = finish_handshake (gnutls, gnutls->priv->implicit_handshake, &my_error);
550 g_clear_object (&gnutls->priv->implicit_handshake);
551 g_mutex_lock (&gnutls->priv->op_mutex);
553 gnutls->priv->handshaking = FALSE;
554 if (!success || g_cancellable_set_error_if_cancelled (cancellable, &my_error))
556 g_propagate_error (error, my_error);
557 g_mutex_unlock (&gnutls->priv->op_mutex);
563 if ((op != G_TLS_CONNECTION_GNUTLS_OP_WRITE && gnutls->priv->reading) ||
564 (op != G_TLS_CONNECTION_GNUTLS_OP_READ && gnutls->priv->writing) ||
565 (op != G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE && gnutls->priv->handshaking))
570 g_cancellable_reset (gnutls->priv->waiting_for_op);
572 g_mutex_unlock (&gnutls->priv->op_mutex);
576 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
577 _("Operation would block"));
581 g_cancellable_make_pollfd (gnutls->priv->waiting_for_op, &fds[0]);
582 if (g_cancellable_make_pollfd (cancellable, &fds[0]))
586 g_poll (fds, nfds, -1);
587 g_cancellable_release_fd (cancellable);
592 if (op == G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE)
594 gnutls->priv->handshaking = TRUE;
595 gnutls->priv->need_handshake = FALSE;
597 if (op == G_TLS_CONNECTION_GNUTLS_OP_CLOSE)
598 gnutls->priv->closing = TRUE;
600 if (op != G_TLS_CONNECTION_GNUTLS_OP_WRITE)
601 gnutls->priv->reading = TRUE;
602 if (op != G_TLS_CONNECTION_GNUTLS_OP_READ)
603 gnutls->priv->writing = TRUE;
605 g_mutex_unlock (&gnutls->priv->op_mutex);
610 yield_op (GTlsConnectionGnutls *gnutls,
611 GTlsConnectionGnutlsOp op)
613 g_mutex_lock (&gnutls->priv->op_mutex);
615 if (op == G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE)
616 gnutls->priv->handshaking = FALSE;
617 if (op == G_TLS_CONNECTION_GNUTLS_OP_CLOSE)
618 gnutls->priv->closing = FALSE;
620 if (op != G_TLS_CONNECTION_GNUTLS_OP_WRITE)
621 gnutls->priv->reading = FALSE;
622 if (op != G_TLS_CONNECTION_GNUTLS_OP_READ)
623 gnutls->priv->writing = FALSE;
625 g_cancellable_cancel (gnutls->priv->waiting_for_op);
626 g_mutex_unlock (&gnutls->priv->op_mutex);
630 begin_gnutls_io (GTlsConnectionGnutls *gnutls,
631 GIOCondition direction,
633 GCancellable *cancellable)
635 g_assert (direction & (G_IO_IN | G_IO_OUT));
637 if (direction & G_IO_IN)
639 gnutls->priv->read_blocking = blocking;
640 gnutls->priv->read_cancellable = cancellable;
641 g_clear_error (&gnutls->priv->read_error);
644 if (direction & G_IO_OUT)
646 gnutls->priv->write_blocking = blocking;
647 gnutls->priv->write_cancellable = cancellable;
648 g_clear_error (&gnutls->priv->write_error);
653 end_gnutls_io (GTlsConnectionGnutls *gnutls,
654 GIOCondition direction,
659 GError *my_error = NULL;
661 g_assert (direction & (G_IO_IN | G_IO_OUT));
662 g_assert (!error || !*error);
664 if (status == GNUTLS_E_AGAIN ||
665 status == GNUTLS_E_WARNING_ALERT_RECEIVED)
666 return GNUTLS_E_AGAIN;
668 if (direction & G_IO_IN)
670 gnutls->priv->read_cancellable = NULL;
673 my_error = gnutls->priv->read_error;
674 gnutls->priv->read_error = NULL;
677 g_clear_error (&gnutls->priv->read_error);
679 if (direction & G_IO_OUT)
681 gnutls->priv->write_cancellable = NULL;
682 if (status < 0 && !my_error)
684 my_error = gnutls->priv->write_error;
685 gnutls->priv->write_error = NULL;
688 g_clear_error (&gnutls->priv->write_error);
694 if (gnutls->priv->handshaking && !gnutls->priv->ever_handshaked)
696 if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_FAILED) ||
697 #if GLIB_CHECK_VERSION (2, 35, 3)
698 g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE) ||
700 status == GNUTLS_E_UNEXPECTED_PACKET_LENGTH ||
701 status == GNUTLS_E_FATAL_ALERT_RECEIVED ||
702 status == GNUTLS_E_DECRYPTION_FAILED ||
703 status == GNUTLS_E_UNSUPPORTED_VERSION_PACKET)
705 g_clear_error (&my_error);
706 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS,
707 _("Peer failed to perform TLS handshake"));
708 return GNUTLS_E_PULL_ERROR;
714 if (!g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
715 G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->failed (gnutls);
716 g_propagate_error (error, my_error);
719 else if (status == GNUTLS_E_REHANDSHAKE)
721 if (gnutls->priv->rehandshake_mode == G_TLS_REHANDSHAKE_NEVER)
723 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
724 _("Peer requested illegal TLS rehandshake"));
725 return GNUTLS_E_PULL_ERROR;
728 g_mutex_lock (&gnutls->priv->op_mutex);
729 if (!gnutls->priv->handshaking)
730 gnutls->priv->need_handshake = TRUE;
731 g_mutex_unlock (&gnutls->priv->op_mutex);
734 else if (status == GNUTLS_E_GOT_APPLICATION_DATA)
736 if (gnutls->priv->handshaking && G_IS_TLS_SERVER_CONNECTION (gnutls))
737 return GNUTLS_E_AGAIN;
740 #ifdef GNUTLS_E_PREMATURE_TERMINATION
741 status == GNUTLS_E_PREMATURE_TERMINATION
743 status == GNUTLS_E_UNEXPECTED_PACKET_LENGTH && gnutls->priv->eof
747 if (gnutls->priv->require_close_notify)
749 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_EOF,
750 _("TLS connection closed unexpectedly"));
751 G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->failed (gnutls);
757 else if (status == GNUTLS_E_NO_CERTIFICATE_FOUND)
759 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED,
760 _("TLS connection peer did not send a certificate"));
766 g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
767 errmsg, gnutls_strerror (status));
772 #define BEGIN_GNUTLS_IO(gnutls, direction, blocking, cancellable) \
773 begin_gnutls_io (gnutls, direction, blocking, cancellable); \
776 #define END_GNUTLS_IO(gnutls, direction, ret, errmsg, err) \
777 } while ((ret = end_gnutls_io (gnutls, direction, ret, errmsg, err)) == GNUTLS_E_AGAIN);
780 g_tls_connection_gnutls_check (GTlsConnectionGnutls *gnutls,
781 GIOCondition condition)
783 /* Racy, but worst case is that we just get WOULD_BLOCK back */
784 if (gnutls->priv->need_finish_handshake)
787 /* If a handshake or close is in progress, then tls_istream and
788 * tls_ostream are blocked, regardless of the base stream status.
790 if (gnutls->priv->handshaking || gnutls->priv->closing)
793 if (condition & G_IO_IN)
794 return g_pollable_input_stream_is_readable (gnutls->priv->base_istream);
796 return g_pollable_output_stream_is_writable (gnutls->priv->base_ostream);
802 GTlsConnectionGnutls *gnutls;
805 GSource *child_source;
806 GIOCondition condition;
810 } GTlsConnectionGnutlsSource;
813 gnutls_source_prepare (GSource *source,
821 gnutls_source_check (GSource *source)
827 gnutls_source_sync (GTlsConnectionGnutlsSource *gnutls_source)
829 GTlsConnectionGnutls *gnutls = gnutls_source->gnutls;
830 gboolean io_waiting, op_waiting;
832 g_mutex_lock (&gnutls->priv->op_mutex);
833 if (((gnutls_source->condition & G_IO_IN) && gnutls->priv->reading) ||
834 ((gnutls_source->condition & G_IO_OUT) && gnutls->priv->writing) ||
835 (gnutls->priv->handshaking && !gnutls->priv->need_finish_handshake))
840 if (!op_waiting && !gnutls->priv->need_handshake &&
841 !gnutls->priv->need_finish_handshake)
845 g_mutex_unlock (&gnutls->priv->op_mutex);
847 if (op_waiting == gnutls_source->op_waiting &&
848 io_waiting == gnutls_source->io_waiting)
850 gnutls_source->op_waiting = op_waiting;
851 gnutls_source->io_waiting = io_waiting;
853 if (gnutls_source->child_source)
855 g_source_remove_child_source ((GSource *)gnutls_source,
856 gnutls_source->child_source);
857 g_source_unref (gnutls_source->child_source);
861 gnutls_source->child_source = g_cancellable_source_new (gnutls->priv->waiting_for_op);
862 else if (io_waiting && G_IS_POLLABLE_INPUT_STREAM (gnutls_source->stream))
863 gnutls_source->child_source = g_pollable_input_stream_create_source (gnutls->priv->base_istream, NULL);
864 else if (io_waiting && G_IS_POLLABLE_OUTPUT_STREAM (gnutls_source->stream))
865 gnutls_source->child_source = g_pollable_output_stream_create_source (gnutls->priv->base_ostream, NULL);
867 gnutls_source->child_source = g_timeout_source_new (0);
869 g_source_set_dummy_callback (gnutls_source->child_source);
870 g_source_add_child_source ((GSource *)gnutls_source, gnutls_source->child_source);
874 gnutls_source_dispatch (GSource *source,
875 GSourceFunc callback,
878 GPollableSourceFunc func = (GPollableSourceFunc)callback;
879 GTlsConnectionGnutlsSource *gnutls_source = (GTlsConnectionGnutlsSource *)source;
882 ret = (*func) (gnutls_source->stream, user_data);
884 gnutls_source_sync (gnutls_source);
890 gnutls_source_finalize (GSource *source)
892 GTlsConnectionGnutlsSource *gnutls_source = (GTlsConnectionGnutlsSource *)source;
894 g_object_unref (gnutls_source->gnutls);
895 g_source_unref (gnutls_source->child_source);
899 g_tls_connection_gnutls_source_closure_callback (GObject *stream,
902 GClosure *closure = data;
904 GValue param = { 0, };
905 GValue result_value = { 0, };
908 g_value_init (&result_value, G_TYPE_BOOLEAN);
910 g_value_init (¶m, G_TYPE_OBJECT);
911 g_value_set_object (¶m, stream);
913 g_closure_invoke (closure, &result_value, 1, ¶m, NULL);
915 result = g_value_get_boolean (&result_value);
916 g_value_unset (&result_value);
917 g_value_unset (¶m);
922 static GSourceFuncs gnutls_source_funcs =
924 gnutls_source_prepare,
926 gnutls_source_dispatch,
927 gnutls_source_finalize,
928 (GSourceFunc)g_tls_connection_gnutls_source_closure_callback,
929 (GSourceDummyMarshal)g_cclosure_marshal_generic
933 g_tls_connection_gnutls_create_source (GTlsConnectionGnutls *gnutls,
934 GIOCondition condition,
935 GCancellable *cancellable)
937 GSource *source, *cancellable_source;
938 GTlsConnectionGnutlsSource *gnutls_source;
940 source = g_source_new (&gnutls_source_funcs, sizeof (GTlsConnectionGnutlsSource));
941 g_source_set_name (source, "GTlsConnectionGnutlsSource");
942 gnutls_source = (GTlsConnectionGnutlsSource *)source;
943 gnutls_source->gnutls = g_object_ref (gnutls);
944 gnutls_source->condition = condition;
945 if (condition & G_IO_IN)
946 gnutls_source->stream = G_OBJECT (gnutls->priv->tls_istream);
947 else if (condition & G_IO_OUT)
948 gnutls_source->stream = G_OBJECT (gnutls->priv->tls_ostream);
950 gnutls_source->op_waiting = (gboolean) -1;
951 gnutls_source->io_waiting = (gboolean) -1;
952 gnutls_source_sync (gnutls_source);
956 cancellable_source = g_cancellable_source_new (cancellable);
957 g_source_set_dummy_callback (cancellable_source);
958 g_source_add_child_source (source, cancellable_source);
959 g_source_unref (cancellable_source);
966 set_gnutls_error (GTlsConnectionGnutls *gnutls,
969 /* We set EINTR rather than EAGAIN for G_IO_ERROR_WOULD_BLOCK so
970 * that GNUTLS_E_AGAIN only gets returned for gnutls-internal
971 * reasons, not for actual socket EAGAINs (and we have access
972 * to @error at the higher levels, so we can distinguish them
976 if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
977 gnutls_transport_set_errno (gnutls->priv->session, EINTR);
978 else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
979 gnutls_transport_set_errno (gnutls->priv->session, EINTR);
981 gnutls_transport_set_errno (gnutls->priv->session, EIO);
985 g_tls_connection_gnutls_pull_func (gnutls_transport_ptr_t transport_data,
989 GTlsConnectionGnutls *gnutls = transport_data;
992 /* If gnutls->priv->read_error is non-%NULL when we're called, it means
993 * that an error previously occurred, but gnutls decided not to
994 * propagate it. So it's correct for us to just clear it. (Usually
995 * this means it ignored an EAGAIN after a short read, and now
996 * we'll return EAGAIN again, which it will obey this time.)
998 g_clear_error (&gnutls->priv->read_error);
1000 ret = g_pollable_stream_read (G_INPUT_STREAM (gnutls->priv->base_istream),
1002 gnutls->priv->read_blocking,
1003 gnutls->priv->read_cancellable,
1004 &gnutls->priv->read_error);
1007 set_gnutls_error (gnutls, gnutls->priv->read_error);
1008 #ifndef GNUTLS_E_PREMATURE_TERMINATION
1010 gnutls->priv->eof = TRUE;
1017 g_tls_connection_gnutls_push_func (gnutls_transport_ptr_t transport_data,
1021 GTlsConnectionGnutls *gnutls = transport_data;
1024 /* See comment in pull_func. */
1025 g_clear_error (&gnutls->priv->write_error);
1027 ret = g_pollable_stream_write (G_OUTPUT_STREAM (gnutls->priv->base_ostream),
1029 gnutls->priv->write_blocking,
1030 gnutls->priv->write_cancellable,
1031 &gnutls->priv->write_error);
1033 set_gnutls_error (gnutls, gnutls->priv->write_error);
1039 handshake_thread (GTask *task,
1042 GCancellable *cancellable)
1044 GTlsConnectionGnutls *gnutls = object;
1046 GError *error = NULL;
1049 gnutls->priv->started_handshake = FALSE;
1051 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE,
1052 TRUE, cancellable, &error))
1054 g_task_return_error (task, error);
1058 g_clear_error (&gnutls->priv->handshake_error);
1060 is_client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
1062 if (!is_client && gnutls->priv->ever_handshaked &&
1063 !gnutls->priv->implicit_handshake)
1065 BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, TRUE, cancellable);
1066 ret = gnutls_rehandshake (gnutls->priv->session);
1067 END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret,
1068 _("Error performing TLS handshake: %s"), &error);
1072 g_task_return_error (task, error);
1077 gnutls->priv->started_handshake = TRUE;
1079 g_clear_object (&gnutls->priv->peer_certificate);
1080 gnutls->priv->peer_certificate_errors = 0;
1082 g_tls_connection_gnutls_set_handshake_priority (gnutls);
1084 BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, TRUE, cancellable);
1085 ret = gnutls_handshake (gnutls->priv->session);
1086 END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret,
1087 _("Error performing TLS handshake: %s"), &error);
1091 g_task_return_error (task, error);
1095 gnutls->priv->ever_handshaked = TRUE;
1096 g_task_return_boolean (task, TRUE);
1100 static GTlsCertificate *
1101 get_peer_certificate_from_session (GTlsConnectionGnutls *gnutls)
1103 GTlsCertificate *chain, *cert;
1104 const gnutls_datum_t *certs;
1105 unsigned int num_certs;
1108 certs = gnutls_certificate_get_peers (gnutls->priv->session, &num_certs);
1109 if (!certs || !num_certs)
1113 for (i = num_certs - 1; i >= 0; i--)
1115 cert = g_tls_certificate_gnutls_new (&certs[i], chain);
1117 g_object_unref (chain);
1124 static GTlsCertificateFlags
1125 verify_peer_certificate (GTlsConnectionGnutls *gnutls,
1126 GTlsCertificate *peer_certificate)
1128 GTlsConnection *conn = G_TLS_CONNECTION (gnutls);
1129 GSocketConnectable *peer_identity;
1130 GTlsDatabase *database;
1131 GTlsCertificateFlags errors;
1134 is_client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
1136 peer_identity = g_tls_client_connection_get_server_identity (G_TLS_CLIENT_CONNECTION (gnutls));
1138 peer_identity = NULL;
1142 database = g_tls_connection_get_database (conn);
1143 if (database == NULL)
1145 errors |= G_TLS_CERTIFICATE_UNKNOWN_CA;
1146 errors |= g_tls_certificate_verify (peer_certificate, peer_identity, NULL);
1150 GError *error = NULL;
1152 errors |= g_tls_database_verify_chain (database, peer_certificate,
1154 G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER :
1155 G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT,
1157 g_tls_connection_get_interaction (conn),
1158 G_TLS_DATABASE_VERIFY_NONE,
1162 g_warning ("failure verifying certificate chain: %s",
1164 g_assert (errors != 0);
1165 g_clear_error (&error);
1173 accept_peer_certificate (GTlsConnectionGnutls *gnutls,
1174 GTlsCertificate *peer_certificate,
1175 GTlsCertificateFlags peer_certificate_errors)
1179 if (G_IS_TLS_CLIENT_CONNECTION (gnutls))
1181 GTlsCertificateFlags validation_flags =
1182 g_tls_client_connection_get_validation_flags (G_TLS_CLIENT_CONNECTION (gnutls));
1184 if ((peer_certificate_errors & validation_flags) == 0)
1188 accepted = g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls),
1190 peer_certificate_errors);
1195 accepted = g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls),
1197 peer_certificate_errors);
1204 begin_handshake (GTlsConnectionGnutls *gnutls)
1206 G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->begin_handshake (gnutls);
1210 finish_handshake (GTlsConnectionGnutls *gnutls,
1214 GTlsCertificate *peer_certificate;
1215 GTlsCertificateFlags peer_certificate_errors;
1217 g_assert (error != NULL);
1219 if (g_task_propagate_boolean (task, error) &&
1220 gnutls_certificate_type_get (gnutls->priv->session) == GNUTLS_CRT_X509)
1221 peer_certificate = get_peer_certificate_from_session (gnutls);
1223 peer_certificate = NULL;
1225 if (peer_certificate)
1227 peer_certificate_errors = verify_peer_certificate (gnutls, peer_certificate);
1228 if (!accept_peer_certificate (gnutls, peer_certificate,
1229 peer_certificate_errors))
1231 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
1232 _("Unacceptable TLS certificate"));
1235 gnutls->priv->peer_certificate = peer_certificate;
1236 gnutls->priv->peer_certificate_errors = peer_certificate_errors;
1237 g_object_notify (G_OBJECT (gnutls), "peer-certificate");
1238 g_object_notify (G_OBJECT (gnutls), "peer-certificate-errors");
1240 else if (error && !*error && G_IS_TLS_CLIENT_CONNECTION (gnutls))
1242 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
1243 _("Server did not return a valid TLS certificate"));
1246 G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->finish_handshake (gnutls, error);
1248 if (*error && gnutls->priv->started_handshake)
1249 gnutls->priv->handshake_error = g_error_copy (*error);
1251 return (*error == NULL);
1255 g_tls_connection_gnutls_handshake (GTlsConnection *conn,
1256 GCancellable *cancellable,
1259 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (conn);
1262 GError *my_error = NULL;
1264 task = g_task_new (conn, cancellable, NULL, NULL);
1265 begin_handshake (gnutls);
1266 g_task_run_in_thread_sync (task, handshake_thread);
1267 success = finish_handshake (gnutls, task, &my_error);
1268 g_object_unref (task);
1270 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
1273 g_propagate_error (error, my_error);
1277 /* In the async version we use two GTasks; one to run handshake_thread() and
1278 * then call handshake_thread_completed(), and a second to call the caller's
1279 * original callback after we call finish_handshake().
1283 handshake_thread_completed (GObject *object,
1284 GAsyncResult *result,
1287 GTask *caller_task = user_data;
1288 GTlsConnectionGnutls *gnutls = g_task_get_source_object (caller_task);
1289 GError *error = NULL;
1292 success = finish_handshake (gnutls, G_TASK (result), &error);
1293 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
1296 g_task_return_boolean (caller_task, TRUE);
1298 g_task_return_error (caller_task, error);
1299 g_object_unref (caller_task);
1303 g_tls_connection_gnutls_handshake_async (GTlsConnection *conn,
1305 GCancellable *cancellable,
1306 GAsyncReadyCallback callback,
1309 GTask *thread_task, *caller_task;
1311 caller_task = g_task_new (conn, cancellable, callback, user_data);
1312 g_task_set_priority (caller_task, io_priority);
1314 begin_handshake (G_TLS_CONNECTION_GNUTLS (conn));
1316 thread_task = g_task_new (conn, cancellable,
1317 handshake_thread_completed, caller_task);
1318 g_task_set_priority (thread_task, io_priority);
1319 g_task_run_in_thread (thread_task, handshake_thread);
1320 g_object_unref (thread_task);
1324 g_tls_connection_gnutls_handshake_finish (GTlsConnection *conn,
1325 GAsyncResult *result,
1328 g_return_val_if_fail (g_task_is_valid (result, conn), FALSE);
1330 return g_task_propagate_boolean (G_TASK (result), error);
1334 implicit_handshake_completed (GObject *object,
1335 GAsyncResult *result,
1338 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
1340 g_mutex_lock (&gnutls->priv->op_mutex);
1341 gnutls->priv->need_finish_handshake = TRUE;
1342 g_mutex_unlock (&gnutls->priv->op_mutex);
1344 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
1348 do_implicit_handshake (GTlsConnectionGnutls *gnutls,
1350 GCancellable *cancellable,
1353 /* We have op_mutex */
1355 gnutls->priv->implicit_handshake = g_task_new (gnutls, cancellable,
1356 implicit_handshake_completed,
1359 begin_handshake (gnutls);
1363 GError *my_error = NULL;
1366 g_mutex_unlock (&gnutls->priv->op_mutex);
1367 g_task_run_in_thread_sync (gnutls->priv->implicit_handshake,
1369 success = finish_handshake (gnutls,
1370 gnutls->priv->implicit_handshake,
1372 g_clear_object (&gnutls->priv->implicit_handshake);
1373 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
1374 g_mutex_lock (&gnutls->priv->op_mutex);
1377 g_propagate_error (error, my_error);
1382 g_task_run_in_thread (gnutls->priv->implicit_handshake,
1385 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
1386 _("Operation would block"));
1393 g_tls_connection_gnutls_read (GTlsConnectionGnutls *gnutls,
1397 GCancellable *cancellable,
1403 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ,
1404 blocking, cancellable, error))
1407 BEGIN_GNUTLS_IO (gnutls, G_IO_IN, blocking, cancellable);
1408 ret = gnutls_record_recv (gnutls->priv->session, buffer, count);
1409 END_GNUTLS_IO (gnutls, G_IO_IN, ret, _("Error reading data from TLS socket: %s"), error);
1411 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ);
1415 else if (ret == GNUTLS_E_REHANDSHAKE)
1422 g_tls_connection_gnutls_write (GTlsConnectionGnutls *gnutls,
1426 GCancellable *cancellable,
1432 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE,
1433 blocking, cancellable, error))
1436 BEGIN_GNUTLS_IO (gnutls, G_IO_OUT, blocking, cancellable);
1437 ret = gnutls_record_send (gnutls->priv->session, buffer, count);
1438 END_GNUTLS_IO (gnutls, G_IO_OUT, ret, _("Error writing data to TLS socket: %s"), error);
1440 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE);
1444 else if (ret == GNUTLS_E_REHANDSHAKE)
1450 static GInputStream *
1451 g_tls_connection_gnutls_get_input_stream (GIOStream *stream)
1453 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
1455 return gnutls->priv->tls_istream;
1458 static GOutputStream *
1459 g_tls_connection_gnutls_get_output_stream (GIOStream *stream)
1461 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
1463 return gnutls->priv->tls_ostream;
1467 g_tls_connection_gnutls_close (GIOStream *stream,
1468 GCancellable *cancellable,
1471 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
1475 if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_CLOSE,
1476 TRUE, cancellable, error))
1479 if (gnutls->priv->closed)
1481 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
1482 _("Connection is already closed"));
1483 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_CLOSE);
1487 if (gnutls->priv->ever_handshaked)
1489 BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, TRUE, cancellable);
1490 ret = gnutls_bye (gnutls->priv->session, GNUTLS_SHUT_WR);
1491 END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret,
1492 _("Error performing TLS close: %s"), error);
1495 gnutls->priv->closed = TRUE;
1499 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_CLOSE);
1503 success = g_io_stream_close (gnutls->priv->base_io_stream,
1504 cancellable, error);
1505 yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_CLOSE);
1509 /* We do async close as synchronous-in-a-thread so we don't need to
1510 * implement G_IO_IN/G_IO_OUT flip-flopping just for this one case
1511 * (since handshakes are also done synchronously now).
1514 close_thread (GTask *task,
1517 GCancellable *cancellable)
1519 GIOStream *stream = object;
1520 GError *error = NULL;
1522 if (!g_tls_connection_gnutls_close (stream, cancellable, &error))
1523 g_task_return_error (task, error);
1525 g_task_return_boolean (task, TRUE);
1529 g_tls_connection_gnutls_close_async (GIOStream *stream,
1531 GCancellable *cancellable,
1532 GAsyncReadyCallback callback,
1537 task = g_task_new (stream, cancellable, callback, user_data);
1538 g_task_set_priority (task, io_priority);
1539 g_task_run_in_thread (task, close_thread);
1540 g_object_unref (task);
1544 g_tls_connection_gnutls_close_finish (GIOStream *stream,
1545 GAsyncResult *result,
1548 g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1550 return g_task_propagate_boolean (G_TASK (result), error);
1556 on_pin_prompt_callback (const char *pinfile,
1558 const char *pin_description,
1559 P11KitPinFlags pin_flags,
1560 void *callback_data)
1562 GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (callback_data);
1563 GTlsInteractionResult result;
1564 GTlsPasswordFlags flags = 0;
1565 GTlsPassword *password;
1566 P11KitPin *pin = NULL;
1567 GError *error = NULL;
1569 if (!gnutls->priv->interaction)
1572 if (pin_flags & P11_KIT_PIN_FLAGS_RETRY)
1573 flags |= G_TLS_PASSWORD_RETRY;
1574 if (pin_flags & P11_KIT_PIN_FLAGS_MANY_TRIES)
1575 flags |= G_TLS_PASSWORD_MANY_TRIES;
1576 if (pin_flags & P11_KIT_PIN_FLAGS_FINAL_TRY)
1577 flags |= G_TLS_PASSWORD_FINAL_TRY;
1579 password = g_pkcs11_pin_new (flags, pin_description);
1581 result = g_tls_interaction_ask_password (gnutls->priv->interaction, password,
1582 g_cancellable_get_current (), &error);
1586 case G_TLS_INTERACTION_FAILED:
1587 if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
1588 g_warning ("couldn't ask for password: %s", error->message);
1591 case G_TLS_INTERACTION_UNHANDLED:
1594 case G_TLS_INTERACTION_HANDLED:
1595 pin = g_pkcs11_pin_steal_internal (G_PKCS11_PIN (password));
1599 g_object_unref (password);
1603 #endif /* HAVE_PKCS11 */
1606 g_tls_connection_gnutls_class_init (GTlsConnectionGnutlsClass *klass)
1608 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
1609 GTlsConnectionClass *connection_class = G_TLS_CONNECTION_CLASS (klass);
1610 GIOStreamClass *iostream_class = G_IO_STREAM_CLASS (klass);
1612 g_type_class_add_private (klass, sizeof (GTlsConnectionGnutlsPrivate));
1614 gobject_class->get_property = g_tls_connection_gnutls_get_property;
1615 gobject_class->set_property = g_tls_connection_gnutls_set_property;
1616 gobject_class->finalize = g_tls_connection_gnutls_finalize;
1618 connection_class->handshake = g_tls_connection_gnutls_handshake;
1619 connection_class->handshake_async = g_tls_connection_gnutls_handshake_async;
1620 connection_class->handshake_finish = g_tls_connection_gnutls_handshake_finish;
1622 iostream_class->get_input_stream = g_tls_connection_gnutls_get_input_stream;
1623 iostream_class->get_output_stream = g_tls_connection_gnutls_get_output_stream;
1624 iostream_class->close_fn = g_tls_connection_gnutls_close;
1625 iostream_class->close_async = g_tls_connection_gnutls_close_async;
1626 iostream_class->close_finish = g_tls_connection_gnutls_close_finish;
1628 g_object_class_override_property (gobject_class, PROP_BASE_IO_STREAM, "base-io-stream");
1629 g_object_class_override_property (gobject_class, PROP_REQUIRE_CLOSE_NOTIFY, "require-close-notify");
1630 g_object_class_override_property (gobject_class, PROP_REHANDSHAKE_MODE, "rehandshake-mode");
1631 g_object_class_override_property (gobject_class, PROP_USE_SYSTEM_CERTDB, "use-system-certdb");
1632 g_object_class_override_property (gobject_class, PROP_DATABASE, "database");
1633 g_object_class_override_property (gobject_class, PROP_CERTIFICATE, "certificate");
1634 g_object_class_override_property (gobject_class, PROP_INTERACTION, "interaction");
1635 g_object_class_override_property (gobject_class, PROP_PEER_CERTIFICATE, "peer-certificate");
1636 g_object_class_override_property (gobject_class, PROP_PEER_CERTIFICATE_ERRORS, "peer-certificate-errors");
1640 g_tls_connection_gnutls_initable_iface_init (GInitableIface *iface)
1642 iface->init = g_tls_connection_gnutls_initable_init;