Migrate to openssl 3
[platform/upstream/glib-networking.git] / tls / gnutls / gtlsconnection-gnutls.c
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /*
3  * GIO - GLib Input, Output and Streaming Library
4  *
5  * Copyright 2009 Red Hat, Inc
6  * Copyright 2015, 2016 Collabora, Ltd.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General
19  * Public License along with this library; if not, see
20  * <http://www.gnu.org/licenses/>.
21  *
22  * In addition, when the library is used with OpenSSL, a special
23  * exception applies. Refer to the LICENSE_EXCEPTION file for details.
24  */
25
26 #include "config.h"
27 #include "glib.h"
28
29 #include <errno.h>
30 #include <stdarg.h>
31 #include <gnutls/dtls.h>
32 #include <gnutls/gnutls.h>
33 #include <gnutls/x509.h>
34
35 #include "gtlsconnection-gnutls.h"
36 #include "gtlsbackend-gnutls.h"
37 #include "gtlscertificate-gnutls.h"
38 #include "gtlsclientconnection-gnutls.h"
39 #include "gtlsdatabase-gnutls.h"
40 #include "gtlslog.h"
41 #include "gtlsgnutls-version.h"
42
43 #ifdef G_OS_WIN32
44 #include <winsock2.h>
45 #include <winerror.h>
46
47 /* It isn’t clear whether MinGW always defines EMSGSIZE. */
48 #ifndef EMSGSIZE
49 #define EMSGSIZE WSAEMSGSIZE
50 #endif
51 #endif
52
53 #include <glib/gi18n-lib.h>
54 #include <glib/gprintf.h>
55
56 static ssize_t g_tls_connection_gnutls_push_func (gnutls_transport_ptr_t  transport_data,
57                                                   const void             *buf,
58                                                   size_t                  buflen);
59 static ssize_t g_tls_connection_gnutls_vec_push_func (gnutls_transport_ptr_t  transport_data,
60                                                       const giovec_t         *iov,
61                                                       int                     iovcnt);
62 static ssize_t g_tls_connection_gnutls_pull_func (gnutls_transport_ptr_t  transport_data,
63                                                   void                   *buf,
64                                                   size_t                  buflen);
65
66 static int     g_tls_connection_gnutls_pull_timeout_func (gnutls_transport_ptr_t transport_data,
67                                                           unsigned int           ms);
68
69 static void g_tls_connection_gnutls_initable_iface_init (GInitableIface *iface);
70
71 static int verify_certificate_cb (gnutls_session_t session);
72
73 static gnutls_priority_t priority;
74
75 typedef struct
76 {
77   gnutls_certificate_credentials_t creds;
78   gnutls_session_t session;
79   gchar *interaction_id;
80   GCancellable *cancellable;
81 } GTlsConnectionGnutlsPrivate;
82
83 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GTlsConnectionGnutls, g_tls_connection_gnutls, G_TYPE_TLS_CONNECTION_BASE,
84                                   G_ADD_PRIVATE (GTlsConnectionGnutls);
85                                   G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
86                                                          g_tls_connection_gnutls_initable_iface_init);
87                                   );
88
89 static gint unique_interaction_id = 0;
90
91 static void
92 g_tls_connection_gnutls_init (GTlsConnectionGnutls *gnutls)
93 {
94   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
95   int unique_id;
96
97   unique_id = g_atomic_int_add (&unique_interaction_id, 1);
98   priv->interaction_id = g_strdup_printf ("gtls:%d", unique_id);
99
100   priv->cancellable = g_cancellable_new ();
101 }
102
103 static void
104 g_tls_connection_gnutls_set_handshake_priority (GTlsConnectionGnutls *gnutls)
105 {
106   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
107   int ret;
108
109   if (!priority)
110     {
111       /* initialize_gnutls_priority() previously failed and printed a warning,
112        * so no need for further warnings here.
113        */
114       return;
115     }
116
117   ret = gnutls_priority_set (priv->session, priority);
118   if (ret != GNUTLS_E_SUCCESS)
119     g_warning ("Failed to set GnuTLS session priority: %s", gnutls_strerror (ret));
120 }
121
122 static void
123 update_credentials_cb (GObject    *gobject,
124                        GParamSpec *pspec,
125                        gpointer    user_data)
126 {
127   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (gobject);
128   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
129   GTlsConnectionGnutlsClass *connection_class = G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls);
130   gnutls_certificate_credentials_t credentials;
131   GTlsDatabase *database;
132   GError *error = NULL;
133   int ret;
134
135   database = g_tls_connection_get_database (G_TLS_CONNECTION (gnutls));
136   if (database && G_IS_TLS_DATABASE_GNUTLS (database))
137     {
138       credentials = g_tls_database_gnutls_get_credentials (G_TLS_DATABASE_GNUTLS (database), &error);
139       if (!credentials)
140         {
141           g_warning ("Failed to update credentials: %s", error->message);
142           g_error_free (error);
143           return;
144         }
145     }
146   else
147     {
148       ret = gnutls_certificate_allocate_credentials (&credentials);
149       if (ret != 0)
150         {
151           g_warning ("Failed to update credentials: %s", gnutls_strerror (ret));
152           return;
153         }
154     }
155
156   ret = gnutls_credentials_set (priv->session, GNUTLS_CRD_CERTIFICATE, credentials);
157   if (ret != 0)
158     {
159       g_warning ("Failed to update credentials: %s", gnutls_strerror (ret));
160       gnutls_certificate_free_credentials (credentials);
161       return;
162     }
163
164   gnutls_certificate_free_credentials (priv->creds);
165   priv->creds = credentials;
166
167   g_assert (connection_class->update_credentials);
168   connection_class->update_credentials (gnutls, credentials);
169 }
170
171 static gboolean
172 g_tls_connection_gnutls_initable_init (GInitable     *initable,
173                                        GCancellable  *cancellable,
174                                        GError       **error)
175 {
176   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (initable);
177   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
178   GTlsDatabase *database;
179   GIOStream *base_io_stream = NULL;
180   GDatagramBased *base_socket = NULL;
181   gboolean client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
182   guint flags = client ? GNUTLS_CLIENT : GNUTLS_SERVER;
183   GError *my_error = NULL;
184   gboolean success = FALSE;
185   int ret;
186
187   g_object_get (gnutls,
188                 "base-io-stream", &base_io_stream,
189                 "base-socket", &base_socket,
190                 NULL);
191
192   /* Ensure we are in TLS mode or DTLS mode. */
193   g_return_val_if_fail (!!base_io_stream != !!base_socket, FALSE);
194
195   if (base_socket)
196     flags |= GNUTLS_DATAGRAM;
197
198   database = g_tls_connection_get_database (G_TLS_CONNECTION (gnutls));
199   if (database && G_IS_TLS_DATABASE_GNUTLS (database))
200     {
201       priv->creds = g_tls_database_gnutls_get_credentials (G_TLS_DATABASE_GNUTLS (database), &my_error);
202       if (!priv->creds)
203         {
204           g_propagate_prefixed_error (error, my_error, _("Could not create TLS connection:"));
205           goto out;
206         }
207     }
208   else
209     {
210       ret = gnutls_certificate_allocate_credentials (&priv->creds);
211       if (ret != 0)
212         {
213           g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
214                        _("Could not create TLS connection: %s"),
215                        gnutls_strerror (ret));
216           goto out;
217         }
218     }
219
220   g_signal_connect (gnutls, "notify::database", G_CALLBACK (update_credentials_cb), NULL);
221   g_signal_connect (gnutls, "notify::use-system-certdb", G_CALLBACK (update_credentials_cb), NULL);
222
223   gnutls_init (&priv->session, flags);
224
225   gnutls_session_set_ptr (priv->session, gnutls);
226   gnutls_session_set_verify_function (priv->session, verify_certificate_cb);
227
228   ret = gnutls_credentials_set (priv->session,
229                                 GNUTLS_CRD_CERTIFICATE,
230                                 priv->creds);
231   if (ret != 0)
232     {
233       g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
234                    _("Could not create TLS connection: %s"),
235                    gnutls_strerror (ret));
236       goto out;
237     }
238
239   gnutls_transport_set_push_function (priv->session,
240                                       g_tls_connection_gnutls_push_func);
241   gnutls_transport_set_pull_function (priv->session,
242                                       g_tls_connection_gnutls_pull_func);
243   gnutls_transport_set_pull_timeout_function (priv->session,
244                                               g_tls_connection_gnutls_pull_timeout_func);
245   gnutls_transport_set_ptr (priv->session, gnutls);
246
247   /* GDatagramBased supports vectored I/O; GPollableOutputStream does not. */
248   if (base_socket)
249     {
250       gnutls_transport_set_vec_push_function (priv->session,
251                                               g_tls_connection_gnutls_vec_push_func);
252     }
253
254   /* Set reasonable MTU */
255   if (flags & GNUTLS_DATAGRAM)
256     gnutls_dtls_set_mtu (priv->session, 1400);
257
258   success = TRUE;
259
260 out:
261   g_clear_object (&base_io_stream);
262   g_clear_object (&base_socket);
263
264   return success;
265 }
266
267 static void
268 g_tls_connection_gnutls_finalize (GObject *object)
269 {
270   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (object);
271   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
272
273   if (priv->session)
274     gnutls_deinit (priv->session);
275   if (priv->creds)
276     gnutls_certificate_free_credentials (priv->creds);
277
278   if (priv->cancellable)
279     {
280       g_cancellable_cancel (priv->cancellable);
281       g_clear_object (&priv->cancellable);
282     }
283
284   g_free (priv->interaction_id);
285
286   G_OBJECT_CLASS (g_tls_connection_gnutls_parent_class)->finalize (object);
287 }
288
289 gnutls_certificate_credentials_t
290 g_tls_connection_gnutls_get_credentials (GTlsConnectionGnutls *gnutls)
291 {
292   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
293
294   return priv->creds;
295 }
296
297 gnutls_session_t
298 g_tls_connection_gnutls_get_session (GTlsConnectionGnutls *gnutls)
299 {
300   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
301
302   return priv->session;
303 }
304
305 static int
306 on_pin_request (void         *userdata,
307                 int           attempt,
308                 const char   *token_url,
309                 const char   *token_label,
310                 unsigned int  callback_flags,
311                 char         *pin,
312                 size_t        pin_max)
313 {
314   GTlsConnection *connection = G_TLS_CONNECTION (userdata);
315   GTlsInteraction *interaction = g_tls_connection_get_interaction (connection);
316   GTlsPassword *password;
317   GTlsPasswordFlags password_flags = 0;
318   gchar *description;
319   int ret = -1;
320
321   if (!interaction)
322     return -1;
323
324   if (callback_flags & GNUTLS_PIN_WRONG)
325     password_flags |= G_TLS_PASSWORD_RETRY;
326   if (callback_flags & GNUTLS_PIN_COUNT_LOW)
327     password_flags |= G_TLS_PASSWORD_MANY_TRIES;
328   if (callback_flags & GNUTLS_PIN_FINAL_TRY || attempt > 5) /* Give up at some point */
329     password_flags |= G_TLS_PASSWORD_FINAL_TRY;
330
331   if (callback_flags & GNUTLS_PIN_USER)
332     password_flags |= G_TLS_PASSWORD_PKCS11_USER;
333   if (callback_flags & GNUTLS_PIN_SO)
334     password_flags |= G_TLS_PASSWORD_PKCS11_SECURITY_OFFICER;
335   if (callback_flags & GNUTLS_PIN_CONTEXT_SPECIFIC)
336     password_flags |= G_TLS_PASSWORD_PKCS11_CONTEXT_SPECIFIC;
337
338   description = g_strdup_printf (" %s (%s)", token_label, token_url);
339   password = g_tls_password_new (password_flags, description);
340   if (g_tls_connection_base_handshake_thread_ask_password (G_TLS_CONNECTION_BASE (connection), password))
341       {
342         gsize password_size;
343         const guchar *password_data = g_tls_password_get_value (password, &password_size);
344         if (password_size > pin_max - 1)
345           g_info ("PIN is larger than max PIN size");
346
347         /* Ensure NUL-termination */
348         memset (pin, 0, pin_max);
349         memcpy (pin, password_data, MIN (password_size, pin_max - 1));
350
351         ret = GNUTLS_E_SUCCESS;
352     }
353
354   g_free (description);
355   g_object_unref (password);
356   return ret;
357 }
358
359 void
360 g_tls_connection_gnutls_handshake_thread_get_certificate (GTlsConnectionGnutls  *gnutls,
361                                                           gnutls_pcert_st      **pcert,
362                                                           unsigned int          *pcert_length,
363                                                           gnutls_privkey_t      *pkey)
364 {
365   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
366   GTlsCertificate *cert;
367
368   cert = g_tls_connection_get_certificate (G_TLS_CONNECTION (gnutls));
369
370   if (cert)
371     {
372       /* Send along a pre-initialized privkey so we can handle the callback here. */
373       gnutls_privkey_t privkey;
374       gnutls_privkey_init (&privkey);
375       gnutls_privkey_set_pin_function (privkey, on_pin_request, gnutls);
376
377       g_tls_certificate_gnutls_copy (G_TLS_CERTIFICATE_GNUTLS (cert),
378                                      priv->interaction_id,
379                                      pcert, pcert_length, &privkey);
380       *pkey = privkey;
381     }
382   else
383     {
384       *pcert = NULL;
385       *pcert_length = 0;
386       *pkey = NULL;
387     }
388 }
389
390 static GTlsConnectionBaseStatus
391 end_gnutls_io (GTlsConnectionGnutls  *gnutls,
392                GIOCondition           direction,
393                int                    ret,
394                GError               **error,
395                const char            *err_prefix)
396 {
397   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
398   GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (gnutls);
399   GTlsConnectionBaseStatus status;
400   gboolean handshaking;
401   gboolean ever_handshaked;
402   GError *my_error = NULL;
403
404   /* We intentionally do not check for GNUTLS_E_INTERRUPTED here
405    * Instead, the caller may poll for the source to become ready again.
406    * (Note that GTlsOutputStreamGnutls and GTlsInputStreamGnutls inherit
407    * from GPollableOutputStream and GPollableInputStream, respectively.)
408    * See also the comment in set_gnutls_error().
409    */
410   if (ret == GNUTLS_E_AGAIN ||
411       ret == GNUTLS_E_WARNING_ALERT_RECEIVED)
412     return G_TLS_CONNECTION_BASE_TRY_AGAIN;
413
414   status = g_tls_connection_base_pop_io (tls, direction, ret >= 0, &my_error);
415   if (status == G_TLS_CONNECTION_BASE_OK ||
416       status == G_TLS_CONNECTION_BASE_WOULD_BLOCK ||
417       status == G_TLS_CONNECTION_BASE_TIMED_OUT)
418     {
419       if (my_error)
420         g_propagate_error (error, my_error);
421       return status;
422     }
423
424   g_assert (status == G_TLS_CONNECTION_BASE_ERROR);
425
426   handshaking = g_tls_connection_base_is_handshaking (tls);
427   ever_handshaked = g_tls_connection_base_ever_handshaked (tls);
428
429   if (handshaking && !ever_handshaked)
430     {
431       if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_FAILED) ||
432           g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE))
433         {
434           g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS,
435                        _("Peer failed to perform TLS handshake: %s"), my_error->message);
436           g_clear_error (&my_error);
437           return G_TLS_CONNECTION_BASE_ERROR;
438         }
439
440       if (ret == GNUTLS_E_UNEXPECTED_PACKET_LENGTH ||
441           ret == GNUTLS_E_DECRYPTION_FAILED ||
442           ret == GNUTLS_E_UNSUPPORTED_VERSION_PACKET)
443         {
444           g_clear_error (&my_error);
445           g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS,
446                        _("Peer failed to perform TLS handshake: %s"), gnutls_strerror (ret));
447           return G_TLS_CONNECTION_BASE_ERROR;
448         }
449     }
450
451   if (ret == GNUTLS_E_REHANDSHAKE)
452     return G_TLS_CONNECTION_BASE_REHANDSHAKE;
453
454   if (ret == GNUTLS_E_PREMATURE_TERMINATION)
455     {
456       if (handshaking && !ever_handshaked)
457         {
458           g_clear_error (&my_error);
459           g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS,
460                        _("Peer failed to perform TLS handshake: %s"), gnutls_strerror (ret));
461           return G_TLS_CONNECTION_BASE_ERROR;
462         }
463
464       if (g_tls_connection_get_require_close_notify (G_TLS_CONNECTION (gnutls)))
465         {
466           g_clear_error (&my_error);
467           g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_EOF,
468                                _("TLS connection closed unexpectedly"));
469           return G_TLS_CONNECTION_BASE_ERROR;
470         }
471
472       return G_TLS_CONNECTION_BASE_OK;
473     }
474
475   if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND
476 #ifdef GNUTLS_E_CERTIFICATE_REQUIRED
477            || ret == GNUTLS_E_CERTIFICATE_REQUIRED /* Added in GnuTLS 3.6.7 */
478 #endif
479           )
480     {
481       g_clear_error (&my_error);
482       g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED,
483                            _("TLS connection peer did not send a certificate"));
484       return G_TLS_CONNECTION_BASE_ERROR;
485     }
486
487   if (ret == GNUTLS_E_CERTIFICATE_ERROR)
488     {
489       g_clear_error (&my_error);
490       g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
491                            _("Unacceptable TLS certificate"));
492       return G_TLS_CONNECTION_BASE_ERROR;
493     }
494
495   if (ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
496     {
497       g_clear_error (&my_error);
498       g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
499                    _("Peer sent fatal TLS alert: %s"),
500                    gnutls_alert_get_name (gnutls_alert_get (priv->session)));
501       return G_TLS_CONNECTION_BASE_ERROR;
502     }
503
504   if (ret == GNUTLS_E_INAPPROPRIATE_FALLBACK)
505     {
506       g_clear_error (&my_error);
507       g_set_error_literal (error, G_TLS_ERROR,
508                            G_TLS_ERROR_INAPPROPRIATE_FALLBACK,
509                            _("Protocol version downgrade attack detected"));
510       return G_TLS_CONNECTION_BASE_ERROR;
511     }
512
513   if (ret == GNUTLS_E_LARGE_PACKET)
514     {
515       guint mtu = gnutls_dtls_get_data_mtu (priv->session);
516       g_clear_error (&my_error);
517       g_set_error (error, G_IO_ERROR, G_IO_ERROR_MESSAGE_TOO_LARGE,
518                    ngettext ("Message is too large for DTLS connection; maximum is %u byte",
519                              "Message is too large for DTLS connection; maximum is %u bytes", mtu), mtu);
520       return G_TLS_CONNECTION_BASE_ERROR;
521     }
522
523   if (ret == GNUTLS_E_TIMEDOUT)
524     {
525       g_clear_error (&my_error);
526       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
527                            _("The operation timed out"));
528       return G_TLS_CONNECTION_BASE_ERROR;
529     }
530
531   if (error && my_error)
532     g_propagate_error (error, my_error);
533
534   if (error && !*error)
535     {
536       *error = g_error_new (G_TLS_ERROR, G_TLS_ERROR_MISC, "%s: %s",
537                             err_prefix, gnutls_strerror (ret));
538     }
539
540   return G_TLS_CONNECTION_BASE_ERROR;
541 }
542
543 #define BEGIN_GNUTLS_IO(gnutls, direction, timeout, cancellable)        \
544   g_tls_connection_base_push_io (G_TLS_CONNECTION_BASE (gnutls),        \
545                                  direction, timeout, cancellable);      \
546   do {
547
548 #define END_GNUTLS_IO(gnutls, direction, ret, status, errmsg, err)      \
549     status = end_gnutls_io (gnutls, direction, ret, err, errmsg);       \
550   } while (status == G_TLS_CONNECTION_BASE_TRY_AGAIN);
551
552 static void
553 set_gnutls_error (GTlsConnectionGnutls *gnutls,
554                   GError               *error)
555 {
556   GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (gnutls);
557   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
558
559   /* We set EINTR rather than EAGAIN for G_IO_ERROR_WOULD_BLOCK so
560    * that GNUTLS_E_AGAIN only gets returned for gnutls-internal
561    * reasons, not for actual socket EAGAINs (and we have access
562    * to @error at the higher levels, so we can distinguish them
563    * that way later).
564    */
565
566   if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
567     gnutls_transport_set_errno (priv->session, EINTR);
568   else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
569     {
570       /* Return EAGAIN while handshaking so that GnuTLS handles retries for us
571        * internally in its handshaking code. */
572       if (g_tls_connection_base_is_dtls (tls) && g_tls_connection_base_is_handshaking (tls))
573         gnutls_transport_set_errno (priv->session, EAGAIN);
574       else
575         gnutls_transport_set_errno (priv->session, EINTR);
576     }
577   else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT))
578     gnutls_transport_set_errno (priv->session, EINTR);
579   else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_MESSAGE_TOO_LARGE))
580     gnutls_transport_set_errno (priv->session, EMSGSIZE);
581   else
582     gnutls_transport_set_errno (priv->session, EIO);
583 }
584
585 static ssize_t
586 g_tls_connection_gnutls_pull_func (gnutls_transport_ptr_t  transport_data,
587                                    void                   *buf,
588                                    size_t                  buflen)
589 {
590   GTlsConnectionBase *tls = transport_data;
591   GTlsConnectionGnutls *gnutls = transport_data;
592   ssize_t ret;
593
594   /* If read_error is nonnull when we're called, it means
595    * that an error previously occurred, but GnuTLS decided not to
596    * propagate it. So it's correct for us to just clear it. (Usually
597    * this means it ignored an EAGAIN after a short read, and now
598    * we'll return EAGAIN again, which it will obey this time.)
599    */
600   g_clear_error (g_tls_connection_base_get_read_error (tls));
601
602   if (g_tls_connection_base_is_dtls (tls))
603     {
604       GInputVector vector = { buf, buflen };
605       GInputMessage message = { NULL, &vector, 1, 0, 0, NULL, NULL };
606
607       ret = g_datagram_based_receive_messages (g_tls_connection_base_get_base_socket (tls),
608                                                &message, 1, 0,
609                                                g_tls_connection_base_is_handshaking (tls) ? 0 : g_tls_connection_base_get_read_timeout (tls),
610                                                g_tls_connection_base_get_read_cancellable (tls),
611                                                g_tls_connection_base_get_read_error (tls));
612
613       if (ret > 0)
614         ret = message.bytes_received;
615     }
616   else
617     {
618       ret = g_pollable_stream_read (G_INPUT_STREAM (g_tls_connection_base_get_base_istream (tls)),
619                                     buf, buflen,
620                                     g_tls_connection_base_get_read_timeout (tls) != 0,
621                                     g_tls_connection_base_get_read_cancellable (tls),
622                                     g_tls_connection_base_get_read_error (tls));
623     }
624
625   if (ret < 0)
626     set_gnutls_error (gnutls, *g_tls_connection_base_get_read_error (tls));
627
628   return ret;
629 }
630
631 static ssize_t
632 g_tls_connection_gnutls_push_func (gnutls_transport_ptr_t  transport_data,
633                                    const void             *buf,
634                                    size_t                  buflen)
635 {
636   GTlsConnectionBase *tls = transport_data;
637   GTlsConnectionGnutls *gnutls = transport_data;
638   ssize_t ret;
639
640   /* See comment in pull_func. */
641   g_clear_error (g_tls_connection_base_get_write_error (tls));
642
643   if (g_tls_connection_base_is_dtls (tls))
644     {
645       GOutputVector vector = { buf, buflen };
646       GOutputMessage message = { NULL, &vector, 1, 0, NULL, 0 };
647
648       ret = g_datagram_based_send_messages (g_tls_connection_base_get_base_socket (tls),
649                                             &message, 1, 0,
650                                             g_tls_connection_base_get_write_timeout (tls),
651                                             g_tls_connection_base_get_write_cancellable (tls),
652                                             g_tls_connection_base_get_write_error (tls));
653
654       if (ret > 0)
655         ret = message.bytes_sent;
656     }
657   else
658     {
659       ret = g_pollable_stream_write (G_OUTPUT_STREAM (g_tls_connection_base_get_base_ostream (tls)),
660                                      buf, buflen,
661                                      g_tls_connection_base_get_write_timeout (tls) != 0,
662                                      g_tls_connection_base_get_write_cancellable (tls),
663                                      g_tls_connection_base_get_write_error (tls));
664     }
665
666   if (ret < 0)
667     set_gnutls_error (gnutls, *g_tls_connection_base_get_write_error (tls));
668
669   return ret;
670 }
671
672 static ssize_t
673 g_tls_connection_gnutls_vec_push_func (gnutls_transport_ptr_t  transport_data,
674                                        const giovec_t         *iov,
675                                        int                     iovcnt)
676 {
677   GTlsConnectionBase *tls = transport_data;
678   GTlsConnectionGnutls *gnutls = transport_data;
679   ssize_t ret;
680   GOutputMessage message = { NULL, };
681   GOutputVector *vectors;
682
683   g_assert (g_tls_connection_base_is_dtls (tls));
684
685   /* See comment in pull_func. */
686   g_clear_error (g_tls_connection_base_get_write_error (tls));
687
688   /* this entire expression will be evaluated at compile time */
689   if (sizeof *iov == sizeof *vectors &&
690       sizeof iov->iov_base == sizeof vectors->buffer &&
691       G_STRUCT_OFFSET (giovec_t, iov_base) ==
692       G_STRUCT_OFFSET (GOutputVector, buffer) &&
693       sizeof iov->iov_len == sizeof vectors->size &&
694       G_STRUCT_OFFSET (giovec_t, iov_len) ==
695       G_STRUCT_OFFSET (GOutputVector, size))
696     /* ABI is compatible */
697     {
698       message.vectors = (GOutputVector *)iov;
699       message.num_vectors = iovcnt;
700     }
701   else
702     /* ABI is incompatible */
703     {
704       gint i;
705
706       message.vectors = g_newa (GOutputVector, iovcnt);
707       for (i = 0; i < iovcnt; i++)
708         {
709           message.vectors[i].buffer = (void *)iov[i].iov_base;
710           message.vectors[i].size = iov[i].iov_len;
711         }
712       message.num_vectors = iovcnt;
713     }
714
715   ret = g_datagram_based_send_messages (g_tls_connection_base_get_base_socket (tls),
716                                         &message, 1, 0,
717                                         g_tls_connection_base_get_write_timeout (tls),
718                                         g_tls_connection_base_get_write_cancellable (tls),
719                                         g_tls_connection_base_get_write_error (tls));
720
721   if (ret > 0)
722     ret = message.bytes_sent;
723   else if (ret < 0)
724     set_gnutls_error (gnutls, *g_tls_connection_base_get_write_error (tls));
725
726   return ret;
727 }
728
729 static gboolean
730 read_pollable_cb (GPollableInputStream *istream,
731                   gpointer              user_data)
732 {
733   gboolean *done = user_data;
734
735   *done = TRUE;
736
737   return G_SOURCE_REMOVE;
738 }
739
740 static gboolean
741 read_datagram_based_cb (GDatagramBased *datagram_based,
742                         GIOCondition    condition,
743                         gpointer        user_data)
744 {
745   gboolean *done = user_data;
746
747   *done = TRUE;
748
749   return G_SOURCE_REMOVE;
750 }
751
752 static gboolean
753 read_timeout_cb (gpointer user_data)
754 {
755   gboolean *done = user_data;
756
757   *done = TRUE;
758
759   return G_SOURCE_REMOVE;
760 }
761
762 static gboolean
763 read_cancelled_cb (GCancellable *cancellable,
764                    gpointer      user_data)
765 {
766   gboolean *done = user_data;
767
768   *done = TRUE;
769
770   return G_SOURCE_REMOVE;
771 }
772
773 static int
774 g_tls_connection_gnutls_pull_timeout_func (gnutls_transport_ptr_t transport_data,
775                                            unsigned int           ms)
776 {
777   GTlsConnectionBase *tls = transport_data;
778
779   /* Fast path. */
780   if (g_tls_connection_base_base_check (tls, G_IO_IN) ||
781       g_cancellable_is_cancelled (g_tls_connection_base_get_read_cancellable (tls)))
782     return 1;
783
784   /* If @ms is 0, GnuTLS wants an instant response, so there’s no need to
785    * construct and query a #GSource. */
786   if (ms > 0)
787     {
788       GMainContext *ctx = NULL;
789       GSource *read_source = NULL;
790       GSource *timeout_source = NULL;
791       GSource *cancellable_source = NULL;
792       gboolean done = FALSE;
793
794       ctx = g_main_context_new ();
795
796       /* Create a timeout source. */
797       timeout_source = g_timeout_source_new (ms);
798       g_source_set_callback (timeout_source, (GSourceFunc)read_timeout_cb,
799                              &done, NULL);
800
801       /* Create a read source. We cannot use g_source_set_ready_time() on this
802        * to combine it with the @timeout_source, as that could mess with the
803        * internals of the #GDatagramBased’s #GSource implementation. */
804       if (g_tls_connection_base_is_dtls (tls))
805         {
806           read_source = g_datagram_based_create_source (g_tls_connection_base_get_base_socket (tls),
807                                                         G_IO_IN, NULL);
808           g_source_set_callback (read_source, (GSourceFunc)read_datagram_based_cb,
809                                  &done, NULL);
810         }
811       else
812         {
813           read_source = g_pollable_input_stream_create_source (g_tls_connection_base_get_base_istream (tls),
814                                                                NULL);
815           g_source_set_callback (read_source, (GSourceFunc)read_pollable_cb,
816                                  &done, NULL);
817         }
818
819       cancellable_source = g_cancellable_source_new (g_tls_connection_base_get_read_cancellable (tls));
820       g_source_set_callback (cancellable_source, (GSourceFunc)read_cancelled_cb,
821                              &done, NULL);
822
823       g_source_attach (read_source, ctx);
824       g_source_attach (timeout_source, ctx);
825       g_source_attach (cancellable_source, ctx);
826
827       while (!done)
828         g_main_context_iteration (ctx, TRUE);
829
830       g_source_destroy (read_source);
831       g_source_destroy (timeout_source);
832       g_source_destroy (cancellable_source);
833
834       g_main_context_unref (ctx);
835       g_source_unref (read_source);
836       g_source_unref (timeout_source);
837       g_source_unref (cancellable_source);
838
839       /* If @read_source was dispatched due to cancellation, the resulting error
840        * will be handled in g_tls_connection_gnutls_pull_func(). */
841       if (g_tls_connection_base_base_check (tls, G_IO_IN) ||
842           g_cancellable_is_cancelled (g_tls_connection_base_get_read_cancellable (tls)))
843         return 1;
844     }
845
846   return 0;
847 }
848
849 static GTlsSafeRenegotiationStatus
850 g_tls_connection_gnutls_handshake_thread_safe_renegotiation_status (GTlsConnectionBase *tls)
851 {
852   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
853   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
854
855   return gnutls_safe_renegotiation_status (priv->session) ? G_TLS_SAFE_RENEGOTIATION_SUPPORTED_BY_PEER
856                                                           : G_TLS_SAFE_RENEGOTIATION_UNSUPPORTED;
857 }
858
859 static GTlsConnectionBaseStatus
860 g_tls_connection_gnutls_handshake_thread_request_rehandshake (GTlsConnectionBase  *tls,
861                                                               gint64               timeout,
862                                                               GCancellable        *cancellable,
863                                                               GError             **error)
864 {
865   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
866   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
867   GTlsConnectionBaseStatus status;
868   int ret;
869
870   /* On a client-side connection, gnutls_handshake() itself will start
871    * a rehandshake, so we only need to do something special here for
872    * server-side connections.
873    */
874   if (!G_IS_TLS_SERVER_CONNECTION (tls))
875     return G_TLS_CONNECTION_BASE_OK;
876
877   BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, timeout, cancellable);
878   ret = gnutls_rehandshake (priv->session);
879   END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret, status, _("Error performing TLS handshake: %s"), error);
880
881   return status;
882 }
883
884 static GTlsCertificate *
885 g_tls_connection_gnutls_retrieve_peer_certificate (GTlsConnectionBase *tls)
886 {
887   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
888   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
889   const gnutls_datum_t *certs;
890   GTlsCertificateGnutls *chain;
891   unsigned int num_certs;
892
893   if (gnutls_certificate_type_get (priv->session) != GNUTLS_CRT_X509)
894     return NULL;
895
896   certs = gnutls_certificate_get_peers (priv->session, &num_certs);
897   if (!certs || !num_certs)
898     return NULL;
899
900   chain = g_tls_certificate_gnutls_build_chain (certs, num_certs, GNUTLS_X509_FMT_DER);
901   if (!chain)
902     return NULL;
903
904   return G_TLS_CERTIFICATE (chain);
905 }
906
907 static int
908 verify_certificate_cb (gnutls_session_t session)
909 {
910   GTlsConnectionBase *tls = gnutls_session_get_ptr (session);
911
912   /* Return 0 for the handshake to continue, non-zero to terminate.
913    * Complete opposite of what OpenSSL does. */
914   return !g_tls_connection_base_handshake_thread_verify_certificate (tls);
915 }
916
917 static void
918 g_tls_connection_gnutls_prepare_handshake (GTlsConnectionBase  *tls,
919                                            gchar              **advertised_protocols)
920 {
921   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
922   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
923
924   if (advertised_protocols)
925     {
926       gnutls_datum_t *protocols;
927       int n_protos, i;
928
929       n_protos = g_strv_length (advertised_protocols);
930       protocols = g_new (gnutls_datum_t, n_protos);
931       for (i = 0; advertised_protocols[i]; i++)
932         {
933           protocols[i].size = strlen (advertised_protocols[i]);
934           protocols[i].data = (guchar *)advertised_protocols[i];
935         }
936       gnutls_alpn_set_protocols (priv->session, protocols, n_protos, 0);
937       g_free (protocols);
938     }
939 }
940
941 static GTlsConnectionBaseStatus
942 g_tls_connection_gnutls_handshake_thread_handshake (GTlsConnectionBase  *tls,
943                                                     gint64               timeout,
944                                                     GCancellable        *cancellable,
945                                                     GError             **error)
946 {
947   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
948   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
949   GTlsConnectionBaseStatus status;
950   int ret;
951
952   if (!g_tls_connection_base_ever_handshaked (tls))
953     g_tls_connection_gnutls_set_handshake_priority (gnutls);
954
955   if (timeout > 0)
956     {
957       unsigned int timeout_ms;
958
959       /* Convert from microseconds to milliseconds, but ensure the timeout
960        * remains positive. */
961       timeout_ms = (timeout + 999) / 1000;
962
963       gnutls_handshake_set_timeout (priv->session, timeout_ms);
964       gnutls_dtls_set_timeouts (priv->session, 1000 /* default */, timeout_ms);
965     }
966
967   BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, timeout, cancellable);
968   ret = gnutls_handshake (priv->session);
969   if (ret == GNUTLS_E_GOT_APPLICATION_DATA)
970     {
971       guint8 buf[1024];
972
973       /* Got app data while waiting for rehandshake; buffer it and try again */
974       ret = gnutls_record_recv (priv->session, buf, sizeof (buf));
975       if (ret > -1)
976         {
977           g_tls_connection_base_handshake_thread_buffer_application_data (tls, buf, ret);
978           ret = GNUTLS_E_AGAIN;
979         }
980     }
981   END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret, status,
982                  _("Error performing TLS handshake"), error);
983
984   return status;
985 }
986
987 static GTlsCertificateFlags
988 g_tls_connection_gnutls_verify_chain (GTlsConnectionBase       *tls,
989                                       GTlsCertificate          *chain,
990                                       const gchar              *purpose,
991                                       GSocketConnectable       *identity,
992                                       GTlsInteraction          *interaction,
993                                       GTlsDatabaseVerifyFlags   flags,
994                                       GCancellable             *cancellable,
995                                       GError                  **error)
996 {
997   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
998   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
999   GTlsCertificateFlags errors = 0;
1000   const char *hostname = NULL;
1001   char *free_hostname = NULL;
1002   GTlsDatabase *database;
1003   guint gnutls_result;
1004   int ret;
1005
1006   /* There are several different ways to perform certificate verification with
1007    * GnuTLS, but they all fall into one of two categories:
1008    *
1009    * (a) outside the context of a TLS session
1010    * (b) within the context of a TLS session
1011    *
1012    * (a) is done by g_tls_database_verify_chain() and implemented using one of
1013    * several different functions of gnutls_x509_trust_list_t, e.g.
1014    * gnutls_x509_trust_list_verify_crt2() or one of the related functions.
1015    * This is the best we can do if we have to use a GTlsDatabase that is not a
1016    * GTlsDatabaseGnutls.
1017    */
1018   database = g_tls_connection_get_database (G_TLS_CONNECTION (gnutls));
1019   if (!G_IS_TLS_DATABASE_GNUTLS (database))
1020     {
1021       return g_tls_database_verify_chain (database,
1022                                           chain,
1023                                           G_IS_TLS_CLIENT_CONNECTION (tls) ? G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER : G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT,
1024                                           identity,
1025                                           g_tls_connection_get_interaction (G_TLS_CONNECTION (tls)),
1026                                           G_TLS_DATABASE_VERIFY_NONE,
1027                                           NULL,
1028                                           error);
1029     }
1030
1031   /* Now for (b). The recommended way is gnutls_session_set_verify_cert(), but
1032    * we can't use that because that would leave no way to implement the
1033    * GTlsConnection::accept-certificate signal. The other way is to use
1034    * gnutls_certificate_verify_peers3() or one of the related functions. This
1035    * adds additional smarts that are not possible when using GTlsDatabase
1036    * directly. For example, it checks name constraints, key usage, and basic
1037    * constraints. It also checks for stapled OCSP responses. Verification will
1038    * fail if the OCSP response indicates the certificate has been revoked.
1039    * Verification will also fail if the Must-Staple flag is set but the OCSP
1040    * response is missing. Nice! This uses the gnutls_certificate_credentials_t
1041    * set on the gnutls_session_t by gnutls_credentials_set().
1042    */
1043
1044   if (G_IS_NETWORK_ADDRESS (identity))
1045     hostname = g_network_address_get_hostname (G_NETWORK_ADDRESS (identity));
1046   else if (G_IS_NETWORK_SERVICE (identity))
1047     hostname = g_network_service_get_domain (G_NETWORK_SERVICE (identity));
1048   else if (G_IS_INET_SOCKET_ADDRESS (identity))
1049     {
1050       GInetAddress *addr;
1051
1052       addr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (identity));
1053       hostname = free_hostname = g_inet_address_to_string (addr);
1054     }
1055   else if (identity)
1056     {
1057       g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
1058                    _("Cannot verify peer identity of unexpected type %s"), G_OBJECT_TYPE_NAME (identity));
1059       errors |= G_TLS_CERTIFICATE_BAD_IDENTITY;
1060     }
1061
1062   ret = gnutls_certificate_verify_peers3 (priv->session, hostname, &gnutls_result);
1063   if (ret != 0)
1064     errors |= G_TLS_CERTIFICATE_GENERIC_ERROR;
1065   else
1066     errors |= g_tls_certificate_gnutls_convert_flags (gnutls_result);
1067
1068   g_free (free_hostname);
1069   return errors;
1070 }
1071
1072 static GTlsProtocolVersion
1073 glib_protocol_version_from_gnutls (gnutls_protocol_t protocol_version)
1074 {
1075   switch (protocol_version)
1076     {
1077     case GNUTLS_SSL3:
1078       return G_TLS_PROTOCOL_VERSION_SSL_3_0;
1079     case GNUTLS_TLS1_0:
1080       return G_TLS_PROTOCOL_VERSION_TLS_1_0;
1081     case GNUTLS_TLS1_1:
1082       return G_TLS_PROTOCOL_VERSION_TLS_1_1;
1083     case GNUTLS_TLS1_2:
1084       return G_TLS_PROTOCOL_VERSION_TLS_1_2;
1085     case GNUTLS_TLS1_3:
1086       return G_TLS_PROTOCOL_VERSION_TLS_1_3;
1087     case GNUTLS_DTLS0_9:
1088       return G_TLS_PROTOCOL_VERSION_UNKNOWN;
1089     case GNUTLS_DTLS1_0:
1090       return G_TLS_PROTOCOL_VERSION_DTLS_1_0;
1091     case GNUTLS_DTLS1_2:
1092       return G_TLS_PROTOCOL_VERSION_DTLS_1_2;
1093     default:
1094       return G_TLS_PROTOCOL_VERSION_UNKNOWN;
1095     }
1096 }
1097
1098 static gchar *
1099 get_ciphersuite_name (gnutls_session_t session)
1100 {
1101   gnutls_protocol_t protocol_version = gnutls_protocol_get_version (session);
1102   char *cipher_name;
1103   char *result;
1104
1105   if (protocol_version <= GNUTLS_TLS1_2 ||
1106       (protocol_version >= GNUTLS_DTLS0_9 && protocol_version <= GNUTLS_DTLS1_2))
1107     {
1108       return g_strdup (gnutls_cipher_suite_get_name (gnutls_kx_get (session),
1109                                                      gnutls_cipher_get (session),
1110                                                      gnutls_mac_get (session)));
1111     }
1112
1113   cipher_name = g_strdup (gnutls_cipher_get_name (gnutls_cipher_get (session)));
1114   for (char *c = cipher_name; *c != '\0'; c++)
1115     {
1116       if (*c == '-')
1117         *c = '_';
1118     }
1119
1120   result = g_strdup_printf ("TLS_%s_%s",
1121                             cipher_name,
1122                             gnutls_digest_get_name (gnutls_prf_hash_get (session)));
1123   g_free (cipher_name);
1124
1125   return result;
1126 }
1127
1128 static void
1129 g_tls_connection_gnutls_complete_handshake (GTlsConnectionBase   *tls,
1130                                             gboolean              handshake_succeeded,
1131                                             gchar               **negotiated_protocol,
1132                                             GTlsProtocolVersion  *protocol_version,
1133                                             gchar               **ciphersuite_name,
1134                                             GError              **error)
1135 {
1136   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
1137   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1138   gnutls_datum_t protocol;
1139
1140   if (!handshake_succeeded)
1141     return;
1142
1143   if (gnutls_alpn_get_selected_protocol (priv->session, &protocol) == 0 &&
1144       protocol.size > 0)
1145     {
1146       g_assert (!*negotiated_protocol);
1147       *negotiated_protocol = g_strndup ((gchar *)protocol.data, protocol.size);
1148     }
1149
1150   *protocol_version = glib_protocol_version_from_gnutls (gnutls_protocol_get_version (priv->session));
1151   *ciphersuite_name = get_ciphersuite_name (priv->session);
1152 }
1153
1154 static gboolean
1155 g_tls_connection_gnutls_is_session_resumed (GTlsConnectionBase *tls)
1156 {
1157   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
1158   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1159
1160   return gnutls_session_is_resumed (priv->session);
1161 }
1162
1163 static gboolean
1164 gnutls_get_binding (GTlsConnectionGnutls      *gnutls,
1165                     GByteArray                *data,
1166                     gnutls_channel_binding_t   binding,
1167                     GError                   **error)
1168 {
1169   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1170   gnutls_datum_t cb;
1171   int ret = gnutls_session_channel_binding (priv->session, binding, &cb);
1172
1173   if (ret == GNUTLS_E_SUCCESS)
1174     {
1175       /* Older GnuTLS versions are known to return SUCCESS and empty data for TLSv1.3 tls-unique binding.
1176        * While it may look prudent to catch here that specific corner case, the empty binding data is
1177        * definitely not a SUCCESS, regardless of the version and type. */
1178       if (cb.size == 0)
1179         {
1180           g_set_error (error, G_TLS_CHANNEL_BINDING_ERROR, G_TLS_CHANNEL_BINDING_ERROR_GENERAL_ERROR,
1181                        _("Empty channel binding data indicates a bug in the TLS library implementation"));
1182           return FALSE;
1183         }
1184
1185       if (data != NULL)
1186         {
1187           g_tls_log_debug (gnutls, "binding size %d", cb.size);
1188           g_free (g_byte_array_steal (data, NULL));
1189           g_byte_array_append (data, cb.data, cb.size);
1190         }
1191       g_free (cb.data);
1192       return TRUE;
1193     }
1194
1195   switch (ret)
1196     {
1197     case GNUTLS_E_UNIMPLEMENTED_FEATURE:
1198       g_set_error (error, G_TLS_CHANNEL_BINDING_ERROR, G_TLS_CHANNEL_BINDING_ERROR_NOT_IMPLEMENTED,
1199                    _("Channel binding type is not implemented in the TLS library"));
1200       break;
1201     case GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE:
1202       g_set_error (error, G_TLS_CHANNEL_BINDING_ERROR, G_TLS_CHANNEL_BINDING_ERROR_NOT_AVAILABLE,
1203                    _("Channel binding data is not yet available"));
1204       break;
1205     default:
1206       g_set_error (error, G_TLS_CHANNEL_BINDING_ERROR, G_TLS_CHANNEL_BINDING_ERROR_GENERAL_ERROR,
1207                    "%s", gnutls_strerror (ret));
1208     }
1209   return FALSE;
1210 }
1211
1212 static gboolean
1213 gnutls_get_binding_tls_unique (GTlsConnectionGnutls  *gnutls,
1214                                GByteArray            *data,
1215                                GError               **error)
1216 {
1217   return gnutls_get_binding (gnutls, data, GNUTLS_CB_TLS_UNIQUE, error);
1218 }
1219
1220 static gboolean
1221 gnutls_get_binding_tls_server_end_point (GTlsConnectionGnutls  *gnutls,
1222                                          GByteArray            *data,
1223                                          GError               **error)
1224 {
1225 #if GTLS_GNUTLS_CHECK_VERSION(3, 7, 2)
1226   return gnutls_get_binding (gnutls, data, GNUTLS_CB_TLS_SERVER_END_POINT, error);
1227 #else
1228   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1229   const gnutls_datum_t *ders;
1230   unsigned int num_certs = 1;
1231   int ret;
1232   size_t rlen;
1233   gnutls_x509_crt_t cert;
1234   gnutls_digest_algorithm_t algo;
1235   gboolean is_client = G_IS_TLS_CLIENT_CONNECTION (gnutls);
1236
1237   ret = gnutls_certificate_type_get (priv->session);
1238   if (ret != GNUTLS_CRT_X509)
1239     {
1240       g_set_error (error, G_TLS_CHANNEL_BINDING_ERROR, G_TLS_CHANNEL_BINDING_ERROR_NOT_SUPPORTED,
1241                    _("X.509 certificate is not available on the connection"));
1242       return FALSE;
1243     }
1244
1245   if (is_client)
1246     ders = gnutls_certificate_get_peers (priv->session, &num_certs);
1247   else
1248     ders = gnutls_certificate_get_ours (priv->session);
1249
1250   if (!ders || num_certs == 0)
1251     {
1252       g_set_error (error, G_TLS_CHANNEL_BINDING_ERROR, G_TLS_CHANNEL_BINDING_ERROR_NOT_AVAILABLE,
1253                    _("X.509 certificate is not available on the connection"));
1254       return FALSE;
1255     }
1256
1257   /* This is a drill */
1258   if (!data)
1259     return TRUE;
1260
1261   /* for DER only first cert is imported, but cert will be pre-initialized */
1262   ret = gnutls_x509_crt_list_import (&cert, &num_certs, ders, GNUTLS_X509_FMT_DER, 0);
1263   if (ret < 0 || num_certs == 0)
1264     {
1265       g_set_error (error, G_TLS_CHANNEL_BINDING_ERROR, G_TLS_CHANNEL_BINDING_ERROR_NOT_AVAILABLE,
1266                    _("X.509 certificate is not available or is of unknown format: %s"),
1267                    gnutls_strerror (ret));
1268       return FALSE;
1269     }
1270
1271   /* obtain signature algorithm for the certificate - we need hashing algo from it */
1272   ret = gnutls_x509_crt_get_signature_algorithm (cert);
1273   if (ret < 0 || ret == GNUTLS_SIGN_UNKNOWN)
1274     {
1275       gnutls_x509_crt_deinit (cert);
1276       g_set_error (error, G_TLS_CHANNEL_BINDING_ERROR, G_TLS_CHANNEL_BINDING_ERROR_NOT_SUPPORTED,
1277                    _("Unable to obtain certificate signature algorithm"));
1278       return FALSE;
1279     }
1280   /* At this point we either use SHA256 as a fallback, or native algorithm */
1281   algo = gnutls_sign_get_hash_algorithm (ret);
1282   /* Cannot identify signing algorithm or weak security - let try fallback */
1283   switch (algo)
1284     {
1285     case GNUTLS_DIG_MD5:
1286     case GNUTLS_DIG_SHA1:
1287       algo = GNUTLS_DIG_SHA256;
1288       break;
1289     case GNUTLS_DIG_UNKNOWN:
1290     case GNUTLS_DIG_NULL:
1291     case GNUTLS_DIG_MD5_SHA1:
1292       g_set_error (error, G_TLS_CHANNEL_BINDING_ERROR, G_TLS_CHANNEL_BINDING_ERROR_NOT_SUPPORTED,
1293                    _("Current X.509 certificate uses unknown or unsupported signature algorithm"));
1294       gnutls_x509_crt_deinit (cert);
1295       return FALSE;
1296     default:
1297       /* no-op */
1298       algo = algo;
1299     }
1300   /* preallocate 512 bits buffer as maximum supported digest size */
1301   rlen = 64;
1302   g_byte_array_set_size (data, rlen);
1303   ret = gnutls_x509_crt_get_fingerprint (cert, algo, data->data, &rlen);
1304
1305   /* in case the future is coming on */
1306   if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
1307     {
1308       g_byte_array_set_size (data, rlen);
1309       ret = gnutls_x509_crt_get_fingerprint (cert, algo, data->data, &rlen);
1310     }
1311
1312   gnutls_x509_crt_deinit (cert);
1313   g_byte_array_set_size (data, rlen);
1314
1315   if (ret == 0)
1316     return TRUE;
1317
1318   /* Still getting error? We cannot do much here to recover */
1319   g_set_error (error, G_TLS_CHANNEL_BINDING_ERROR, G_TLS_CHANNEL_BINDING_ERROR_GENERAL_ERROR,
1320                "%s", gnutls_strerror(ret));
1321   return FALSE;
1322 #endif
1323 }
1324
1325 #if !GTLS_GNUTLS_CHECK_VERSION(3, 7, 2)
1326 #define RFC5705_LABEL_DATA "EXPORTER-Channel-Binding"
1327 #define RFC5705_LABEL_LEN 24
1328 #endif
1329
1330 /* Experimental binding for TLS1.3, see
1331  * https://datatracker.ietf.org/doc/draft-ietf-kitten-tls-channel-bindings-for-tls13 */
1332 static gboolean
1333 gnutls_get_binding_tls_exporter (GTlsConnectionGnutls  *gnutls,
1334                                  GByteArray            *data,
1335                                  GError               **error)
1336 {
1337 #if GTLS_GNUTLS_CHECK_VERSION(3, 7, 2)
1338   return gnutls_get_binding (gnutls, data, GNUTLS_CB_TLS_EXPORTER, error);
1339 #else
1340   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1341   int ret;
1342   gsize ctx_len = 0;
1343   char *context = "";
1344
1345   /* This is a drill */
1346   if (!data)
1347     return TRUE;
1348
1349   g_byte_array_set_size (data, 32);
1350   ret = gnutls_prf_rfc5705 (priv->session,
1351                             RFC5705_LABEL_LEN, RFC5705_LABEL_DATA,
1352                             ctx_len, context,
1353                             data->len, (char *)data->data);
1354
1355   if (ret == GNUTLS_E_SUCCESS)
1356     return TRUE;
1357
1358   g_set_error (error, G_TLS_CHANNEL_BINDING_ERROR, G_TLS_CHANNEL_BINDING_ERROR_GENERAL_ERROR,
1359                "%s", gnutls_strerror (ret));
1360   return FALSE;
1361 #endif
1362 }
1363
1364 static gboolean
1365 g_tls_connection_gnutls_get_channel_binding_data (GTlsConnectionBase      *tls,
1366                                                   GTlsChannelBindingType   type,
1367                                                   GByteArray              *data,
1368                                                   GError                 **error)
1369 {
1370   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
1371
1372   /* XXX: remove the cast once public enum supports exporter */
1373   switch ((int)type)
1374     {
1375     case G_TLS_CHANNEL_BINDING_TLS_UNIQUE:
1376       return gnutls_get_binding_tls_unique (gnutls, data, error);
1377       /* fall through */
1378     case G_TLS_CHANNEL_BINDING_TLS_SERVER_END_POINT:
1379       return gnutls_get_binding_tls_server_end_point (gnutls, data, error);
1380       /* fall through */
1381     case 100500:
1382       return gnutls_get_binding_tls_exporter (gnutls, data, error);
1383       /* fall through */
1384     default:
1385       /* Anyone to implement tls-unique-for-telnet? */
1386       g_set_error (error, G_TLS_CHANNEL_BINDING_ERROR, G_TLS_CHANNEL_BINDING_ERROR_NOT_IMPLEMENTED,
1387                    _("Requested channel binding type is not implemented"));
1388     }
1389   return FALSE;
1390 }
1391
1392 static GTlsConnectionBaseStatus
1393 g_tls_connection_gnutls_read (GTlsConnectionBase  *tls,
1394                               void                *buffer,
1395                               gsize                count,
1396                               gint64               timeout,
1397                               gssize              *nread,
1398                               GCancellable        *cancellable,
1399                               GError             **error)
1400 {
1401   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
1402   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1403   GTlsConnectionBaseStatus status;
1404   gssize ret;
1405
1406   BEGIN_GNUTLS_IO (gnutls, G_IO_IN, timeout, cancellable);
1407   ret = gnutls_record_recv (priv->session, buffer, count);
1408   END_GNUTLS_IO (gnutls, G_IO_IN, ret, status, _("Error reading data from TLS socket"), error);
1409
1410   *nread = MAX (ret, 0);
1411   return status;
1412 }
1413
1414 static gsize
1415 input_vectors_from_gnutls_datum_t (GInputVector         *vectors,
1416                                    guint                 num_vectors,
1417                                    const gnutls_datum_t *datum)
1418 {
1419   guint i;
1420   gsize total = 0;
1421
1422   /* Copy into the receive vectors. */
1423   for (i = 0; i < num_vectors && total < datum->size; i++)
1424     {
1425       gsize count;
1426       GInputVector *vec = &vectors[i];
1427
1428       count = MIN (vec->size, datum->size - total);
1429
1430       memcpy (vec->buffer, datum->data + total, count);
1431       total += count;
1432     }
1433
1434   g_assert (total <= datum->size);
1435
1436   return total;
1437 }
1438
1439 static GTlsConnectionBaseStatus
1440 g_tls_connection_gnutls_read_message (GTlsConnectionBase  *tls,
1441                                       GInputVector        *vectors,
1442                                       guint                num_vectors,
1443                                       gint64               timeout,
1444                                       gssize              *nread,
1445                                       GCancellable        *cancellable,
1446                                       GError             **error)
1447 {
1448   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
1449   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1450   GTlsConnectionBaseStatus status;
1451   gssize ret;
1452   gnutls_packet_t packet = { 0, };
1453
1454   BEGIN_GNUTLS_IO (gnutls, G_IO_IN, timeout, cancellable);
1455
1456   /* Receive the entire datagram (zero-copy). */
1457   ret = gnutls_record_recv_packet (priv->session, &packet);
1458
1459   if (ret > 0)
1460     {
1461       gnutls_datum_t data = { 0, };
1462
1463       gnutls_packet_get (packet, &data, NULL);
1464       ret = input_vectors_from_gnutls_datum_t (vectors, num_vectors, &data);
1465       gnutls_packet_deinit (packet);
1466     }
1467
1468   END_GNUTLS_IO (gnutls, G_IO_IN, ret, status, _("Error reading data from TLS socket"), error);
1469
1470   *nread = MAX (ret, 0);
1471   return status;
1472 }
1473
1474 static GTlsConnectionBaseStatus
1475 g_tls_connection_gnutls_write (GTlsConnectionBase  *tls,
1476                                const void          *buffer,
1477                                gsize                count,
1478                                gint64               timeout,
1479                                gssize              *nwrote,
1480                                GCancellable        *cancellable,
1481                                GError             **error)
1482 {
1483   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
1484   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1485   GTlsConnectionBaseStatus status;
1486   gssize ret;
1487
1488   BEGIN_GNUTLS_IO (gnutls, G_IO_OUT, timeout, cancellable);
1489   ret = gnutls_record_send (priv->session, buffer, count);
1490   END_GNUTLS_IO (gnutls, G_IO_OUT, ret, status, _("Error writing data to TLS socket"), error);
1491
1492   *nwrote = MAX (ret, 0);
1493   return status;
1494 }
1495
1496 static GTlsConnectionBaseStatus
1497 g_tls_connection_gnutls_write_message (GTlsConnectionBase  *tls,
1498                                        GOutputVector       *vectors,
1499                                        guint                num_vectors,
1500                                        gint64               timeout,
1501                                        gssize              *nwrote,
1502                                        GCancellable        *cancellable,
1503                                        GError             **error)
1504 {
1505   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
1506   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1507   GTlsConnectionBaseStatus status;
1508   gssize ret;
1509   guint i;
1510   gsize total_message_size;
1511
1512   /* Calculate the total message size and check it’s not too big. */
1513   for (i = 0, total_message_size = 0; i < num_vectors; i++)
1514     total_message_size += vectors[i].size;
1515
1516   if (g_tls_connection_base_is_dtls (tls) &&
1517       gnutls_dtls_get_data_mtu (priv->session) < total_message_size)
1518     {
1519       char *message;
1520       guint mtu = gnutls_dtls_get_data_mtu (priv->session);
1521
1522       message = g_strdup_printf("%s %s",
1523                                 ngettext ("Message of size %lu byte is too large for DTLS connection",
1524                                           "Message of size %lu bytes is too large for DTLS connection", total_message_size),
1525                                 ngettext ("(maximum is %u byte)", "(maximum is %u bytes)", mtu));
1526       g_set_error (error, G_IO_ERROR, G_IO_ERROR_MESSAGE_TOO_LARGE,
1527                    message,
1528                    total_message_size,
1529                    mtu);
1530       g_free (message);
1531
1532       return G_TLS_CONNECTION_BASE_ERROR;
1533     }
1534
1535   /* Queue up the data from all the vectors. */
1536   gnutls_record_cork (priv->session);
1537
1538   for (i = 0; i < num_vectors; i++)
1539     {
1540       ret = gnutls_record_send (priv->session,
1541                                 vectors[i].buffer, vectors[i].size);
1542
1543       if (ret < 0 || ret < vectors[i].size)
1544         {
1545           /* Uncork to restore state, then bail. The peer will receive a
1546            * truncated datagram. */
1547           break;
1548         }
1549     }
1550
1551   BEGIN_GNUTLS_IO (gnutls, G_IO_OUT, timeout, cancellable);
1552   ret = gnutls_record_uncork (priv->session, 0  /* flags */);
1553   END_GNUTLS_IO (gnutls, G_IO_OUT, ret, status, _("Error writing data to TLS socket"), error);
1554
1555   *nwrote = MAX (ret, 0);
1556   return status;
1557 }
1558
1559 static GTlsConnectionBaseStatus
1560 g_tls_connection_gnutls_close (GTlsConnectionBase  *tls,
1561                                gint64               timeout,
1562                                GCancellable        *cancellable,
1563                                GError             **error)
1564 {
1565   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
1566   GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
1567   GTlsConnectionBaseStatus status;
1568   int ret;
1569
1570   BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, timeout, cancellable);
1571   ret = gnutls_bye (priv->session, GNUTLS_SHUT_WR);
1572   END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret, status, _("Error performing TLS close: %s"), error);
1573
1574   return status;
1575 }
1576
1577 static void
1578 initialize_gnutls_priority (void)
1579 {
1580   const gchar *priority_override;
1581   const gchar *error_pos = NULL;
1582   int ret;
1583
1584   g_assert (!priority);
1585
1586   priority_override = g_getenv ("G_TLS_GNUTLS_PRIORITY");
1587   if (priority_override)
1588     {
1589       ret = gnutls_priority_init2 (&priority, priority_override, &error_pos, 0);
1590       if (ret != GNUTLS_E_SUCCESS)
1591         g_warning ("Failed to set GnuTLS session priority with beginning at %s: %s", error_pos, gnutls_strerror (ret));
1592       return;
1593     }
1594
1595   ret = gnutls_priority_init2 (&priority, "%COMPAT", &error_pos, GNUTLS_PRIORITY_INIT_DEF_APPEND);
1596   if (ret != GNUTLS_E_SUCCESS)
1597     g_warning ("Failed to set GnuTLS session priority with error beginning at %s: %s", error_pos, gnutls_strerror (ret));
1598 }
1599
1600 static void
1601 g_tls_connection_gnutls_class_init (GTlsConnectionGnutlsClass *klass)
1602 {
1603   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
1604   GTlsConnectionBaseClass *base_class = G_TLS_CONNECTION_BASE_CLASS (klass);
1605
1606   gobject_class->finalize                                = g_tls_connection_gnutls_finalize;
1607
1608   base_class->prepare_handshake                          = g_tls_connection_gnutls_prepare_handshake;
1609   base_class->handshake_thread_safe_renegotiation_status = g_tls_connection_gnutls_handshake_thread_safe_renegotiation_status;
1610   base_class->handshake_thread_request_rehandshake       = g_tls_connection_gnutls_handshake_thread_request_rehandshake;
1611   base_class->handshake_thread_handshake                 = g_tls_connection_gnutls_handshake_thread_handshake;
1612   base_class->retrieve_peer_certificate                  = g_tls_connection_gnutls_retrieve_peer_certificate;
1613   base_class->verify_chain                               = g_tls_connection_gnutls_verify_chain;
1614   base_class->complete_handshake                         = g_tls_connection_gnutls_complete_handshake;
1615   base_class->is_session_resumed                         = g_tls_connection_gnutls_is_session_resumed;
1616   base_class->get_channel_binding_data                   = g_tls_connection_gnutls_get_channel_binding_data;
1617   base_class->read_fn                                    = g_tls_connection_gnutls_read;
1618   base_class->read_message_fn                            = g_tls_connection_gnutls_read_message;
1619   base_class->write_fn                                   = g_tls_connection_gnutls_write;
1620   base_class->write_message_fn                           = g_tls_connection_gnutls_write_message;
1621   base_class->close_fn                                   = g_tls_connection_gnutls_close;
1622
1623   initialize_gnutls_priority ();
1624 }
1625
1626 static void
1627 g_tls_connection_gnutls_initable_iface_init (GInitableIface *iface)
1628 {
1629   iface->init = g_tls_connection_gnutls_initable_init;
1630 }