[glib-networking/mcatanzaro/gnutls3.6] Rework GnuTLS priority string generation...
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/mcatanzaro/gnutls3.6] Rework GnuTLS priority string generation...
- Date: Thu, 14 Nov 2019 16:55:59 +0000 (UTC)
commit 01efebf6a10d2f96cb1f04b7fa80089d64c299e6
Author: Michael Catanzaro <mcatanzaro gnome org>
Date: Sat Oct 26 17:02:56 2019 -0500
Rework GnuTLS priority string generation...
...and drop support for unsafe renegotiation and protocol version
fallback, both of which are already deprecated and haven't been needed
for several years.
In particular, this allows us to stop hardcoding the NORMAL priority and
append to the default priority instead, which makes no difference on
most distros but is important for Fedora and RHEL, where we have to use
the Fedora/RHEL-specific @SYSTEM@ priority instead of NORMAL. This means
we can stop patching glib-networking downstream to change NORMAL to
@SYSTEM@.
OpenSSL should like this too, since it never supported either of these
properties, and since this allows removing the protocol version fallback
test that it never passed.
tls/base/gtlsconnection-base.c | 3 +-
tls/gnutls/gtlsconnection-gnutls.c | 119 +++++++++++--------------------------
tls/tests/connection.c | 62 -------------------
3 files changed, 35 insertions(+), 149 deletions(-)
---
diff --git a/tls/base/gtlsconnection-base.c b/tls/base/gtlsconnection-base.c
index 6b6b6f2..aa83d8f 100644
--- a/tls/base/gtlsconnection-base.c
+++ b/tls/base/gtlsconnection-base.c
@@ -1376,8 +1376,7 @@ handshake_thread (GTask *task,
{
GTlsConnectionBaseStatus status;
- if (priv->rehandshake_mode != G_TLS_REHANDSHAKE_UNSAFELY &&
- tls_class->handshake_thread_safe_renegotiation_status (tls) !=
G_TLS_SAFE_RENEGOTIATION_SUPPORTED_BY_PEER)
+ if (tls_class->handshake_thread_safe_renegotiation_status (tls) !=
G_TLS_SAFE_RENEGOTIATION_SUPPORTED_BY_PEER)
{
g_task_return_new_error (task, G_TLS_ERROR, G_TLS_ERROR_MISC,
_("Peer does not support safe renegotiation"));
diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c
index 86c4839..b06c99e 100644
--- a/tls/gnutls/gtlsconnection-gnutls.c
+++ b/tls/gnutls/gtlsconnection-gnutls.c
@@ -65,10 +65,10 @@ static int g_tls_connection_gnutls_pull_timeout_func (gnutls_transport_ptr_t
static void g_tls_connection_gnutls_initable_iface_init (GInitableIface *iface);
-static void g_tls_connection_gnutls_init_priorities (void);
-
static int verify_certificate_cb (gnutls_session_t session);
+static gnutls_priority_t priority;
+
typedef struct
{
gnutls_certificate_credentials_t creds;
@@ -81,7 +81,6 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GTlsConnectionGnutls, g_tls_connection_gnutls,
G_ADD_PRIVATE (GTlsConnectionGnutls);
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
g_tls_connection_gnutls_initable_iface_init);
- g_tls_connection_gnutls_init_priorities ();
);
static gint unique_interaction_id = 0;
@@ -100,93 +99,17 @@ g_tls_connection_gnutls_init (GTlsConnectionGnutls *gnutls)
priv->cancellable = g_cancellable_new ();
}
-/* First field is "fallback", second is "allow unsafe rehandshaking" */
-static gnutls_priority_t priorities[2][2];
-
-/* TODO: Get rid of this in favor of gnutls_set_default_priority_append()
- * when upgrading to GnuTLS 3.6.3.
- */
-#define DEFAULT_BASE_PRIORITY "NORMAL:%COMPAT:-VERS-TLS1.1:-VERS-TLS1.0"
-
-static void
-g_tls_connection_gnutls_init_priorities (void)
-{
- const gchar *base_priority;
- gchar *fallback_priority, *unsafe_rehandshake_priority, *fallback_unsafe_rehandshake_priority;
- const guint *protos;
- int ret, i, nprotos, fallback_proto;
-
- base_priority = g_getenv ("G_TLS_GNUTLS_PRIORITY");
- if (!base_priority)
- base_priority = DEFAULT_BASE_PRIORITY;
- ret = gnutls_priority_init (&priorities[FALSE][FALSE], base_priority, NULL);
- if (ret == GNUTLS_E_INVALID_REQUEST)
- {
- g_warning ("G_TLS_GNUTLS_PRIORITY is invalid; ignoring!");
- base_priority = DEFAULT_BASE_PRIORITY;
- ret = gnutls_priority_init (&priorities[FALSE][FALSE], base_priority, NULL);
- g_warn_if_fail (ret == 0);
- }
-
- unsafe_rehandshake_priority = g_strdup_printf ("%s:%%UNSAFE_RENEGOTIATION", base_priority);
- ret = gnutls_priority_init (&priorities[FALSE][TRUE], unsafe_rehandshake_priority, NULL);
- g_warn_if_fail (ret == 0);
- g_free (unsafe_rehandshake_priority);
-
- /* Figure out the lowest SSl/TLS version supported by base_priority */
- nprotos = gnutls_priority_protocol_list (priorities[FALSE][FALSE], &protos);
- fallback_proto = G_MAXUINT;
- for (i = 0; i < nprotos; i++)
- {
- if (protos[i] < fallback_proto)
- fallback_proto = protos[i];
- }
- if (fallback_proto == G_MAXUINT)
- {
- g_warning ("All GNUTLS protocol versions disabled?");
- fallback_priority = g_strdup (base_priority);
- }
- else
- {
- /* %COMPAT is intentionally duplicated here, to ensure it gets added for
- * the fallback even if the default priority has been changed. */
- fallback_priority = g_strdup_printf ("%s:%%COMPAT:!VERS-TLS-ALL:+VERS-%s:%%FALLBACK_SCSV",
- DEFAULT_BASE_PRIORITY,
- gnutls_protocol_get_name (fallback_proto));
- }
- fallback_unsafe_rehandshake_priority = g_strdup_printf ("%s:%%UNSAFE_RENEGOTIATION",
- fallback_priority);
-
- ret = gnutls_priority_init (&priorities[TRUE][FALSE], fallback_priority, NULL);
- g_warn_if_fail (ret == 0);
- ret = gnutls_priority_init (&priorities[TRUE][TRUE], fallback_unsafe_rehandshake_priority, NULL);
- g_warn_if_fail (ret == 0);
- g_free (fallback_priority);
- g_free (fallback_unsafe_rehandshake_priority);
-}
-
static void
g_tls_connection_gnutls_set_handshake_priority (GTlsConnectionGnutls *gnutls)
{
GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
- gboolean fallback, unsafe_rehandshake;
+ int ret;
- if (G_IS_TLS_CLIENT_CONNECTION (gnutls))
- {
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
- fallback = g_tls_client_connection_get_use_ssl3 (G_TLS_CLIENT_CONNECTION (gnutls));
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
- }
- else
- fallback = FALSE;
- unsafe_rehandshake = g_tls_connection_get_rehandshake_mode (G_TLS_CONNECTION (gnutls)) ==
G_TLS_REHANDSHAKE_UNSAFELY;
- gnutls_priority_set (priv->session,
- priorities[fallback][unsafe_rehandshake]);
+ g_assert (priority);
+
+ ret = gnutls_priority_set (priv->session, priority);
+ if (ret != GNUTLS_E_SUCCESS)
+ g_warning ("Failed to set GnuTLS session priority: %s", gnutls_strerror (ret));
}
static gboolean
@@ -1186,6 +1109,30 @@ g_tls_connection_gnutls_close (GTlsConnectionBase *tls,
return status;
}
+static void
+initialize_gnutls_priority (void)
+{
+ const gchar *priority_override;
+ const gchar *error_pos = NULL;
+ int ret;
+
+ g_assert (!priority);
+
+ priority_override = g_getenv ("G_TLS_GNUTLS_PRIORITY");
+ if (priority_override)
+ {
+ ret = gnutls_priority_init2 (&priority, priority_override, &error_pos, 0);
+ if (ret != GNUTLS_E_SUCCESS)
+ g_warning ("Failed to set GnuTLS session priority with beginning at %s: %s", error_pos,
gnutls_strerror (ret));
+ return;
+ }
+
+ /* TODO: Generally we should expect GnuTLS to define appropriate security levels. */
+ ret = gnutls_priority_init2 (&priority, "%COMPAT:-VERS-TLS1.1:-VERS-TLS1.0", &error_pos,
GNUTLS_PRIORITY_INIT_DEF_APPEND);
+ if (ret != GNUTLS_E_SUCCESS)
+ g_warning ("Failed to set GnuTLS session priority with error beginning at %s: %s", error_pos,
gnutls_strerror (ret));
+}
+
static void
g_tls_connection_gnutls_class_init (GTlsConnectionGnutlsClass *klass)
{
@@ -1206,6 +1153,8 @@ g_tls_connection_gnutls_class_init (GTlsConnectionGnutlsClass *klass)
base_class->write_fn = g_tls_connection_gnutls_write;
base_class->write_message_fn = g_tls_connection_gnutls_write_message;
base_class->close_fn = g_tls_connection_gnutls_close;
+
+ initialize_gnutls_priority ();
}
static void
diff --git a/tls/tests/connection.c b/tls/tests/connection.c
index 719845b..9677cee 100644
--- a/tls/tests/connection.c
+++ b/tls/tests/connection.c
@@ -2127,66 +2127,6 @@ test_async_implicit_handshake (TestConnection *test, gconstpointer data)
test->client_connection = NULL;
}
-static void
-quit_on_handshake_complete (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- TestConnection *test = user_data;
- GError *error = NULL;
-
- g_tls_connection_handshake_finish (G_TLS_CONNECTION (object), result, &error);
- g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS);
- g_error_free (error);
-
- g_main_loop_quit (test->loop);
- return;
-}
-
-static void
-test_fallback (TestConnection *test,
- gconstpointer data)
-{
- GIOStream *connection;
- GTlsConnection *tlsconn;
- GError *error = NULL;
-
-#ifdef BACKEND_IS_OPENSSL
- g_test_skip ("this needs more research on openssl");
- return;
-#endif
-
- connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_NONE);
- test->client_connection = g_tls_client_connection_new (connection, NULL, &error);
- g_assert_no_error (error);
- tlsconn = G_TLS_CONNECTION (test->client_connection);
- g_object_unref (connection);
-
- g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (test->client_connection),
- 0);
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
- g_tls_client_connection_set_use_ssl3 (G_TLS_CLIENT_CONNECTION (test->client_connection),
- TRUE);
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
-
- g_tls_connection_handshake_async (tlsconn, G_PRIORITY_DEFAULT, NULL,
- quit_on_handshake_complete, test);
- g_main_loop_run (test->loop);
- wait_until_server_finished (test);
-
- /* The server should detect a protocol downgrade attack and terminate the connection.
- */
- g_assert_error (test->server_error, G_TLS_ERROR, G_TLS_ERROR_INAPPROPRIATE_FALLBACK);
-
- g_io_stream_close (test->client_connection, NULL, &error);
- g_assert_no_error (error);
-}
-
static void
handshake_completed (GObject *object,
GAsyncResult *result,
@@ -2615,8 +2555,6 @@ main (int argc,
setup_connection, test_async_implicit_handshake, teardown_connection);
g_test_add ("/tls/" BACKEND "/connection/output-stream-close", TestConnection, NULL,
setup_connection, test_output_stream_close, teardown_connection);
- g_test_add ("/tls/" BACKEND "/connection/fallback", TestConnection, NULL,
- setup_connection, test_fallback, teardown_connection);
g_test_add ("/tls/" BACKEND "/connection/garbage-database", TestConnection, NULL,
setup_connection, test_garbage_database, teardown_connection);
g_test_add ("/tls/" BACKEND "/connection/readwrite-after-connection-destroyed", TestConnection, NULL,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]