[glib-networking/mcatanzaro/tls-thread: 10/24] progress
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/mcatanzaro/tls-thread: 10/24] progress
- Date: Sat, 28 Dec 2019 21:04:18 +0000 (UTC)
commit 03ef9e07e2af450bfefb7a0542f4810153ac6e66
Author: Michael Catanzaro <mcatanzaro gnome org>
Date: Sat Dec 21 19:40:57 2019 -0600
progress
tls/base/gtlsconnection-base.c | 10 +-
tls/base/gtlsoperationsthread-base.c | 13 ++-
tls/base/gtlsoperationsthread-base.h | 2 +
tls/gnutls/gtlsclientconnection-gnutls.c | 1 -
tls/gnutls/gtlsconnection-gnutls.c | 8 --
tls/gnutls/gtlsoperationsthread-gnutls.c | 186 ++++++++++++++++++-------------
tls/gnutls/gtlsserverconnection-gnutls.c | 88 ++++-----------
7 files changed, 154 insertions(+), 154 deletions(-)
---
diff --git a/tls/base/gtlsconnection-base.c b/tls/base/gtlsconnection-base.c
index a3d8262..9b493dc 100644
--- a/tls/base/gtlsconnection-base.c
+++ b/tls/base/gtlsconnection-base.c
@@ -1418,6 +1418,7 @@ handshake (GTlsConnectionBase *tls,
GError **error)
{
GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+ GTlsAuthenticationMode auth_mode = G_TLS_AUTHENTICATION_NONE;
g_tls_log_debug (tls, "TLS handshake starts");
@@ -1447,8 +1448,15 @@ handshake (GTlsConnectionBase *tls,
return TRUE;
}
+ if (G_IS_TLS_SERVER_CONNECTION (tls))
+ {
+ g_object_get (tls,
+ "authentication-mode", &auth_mode,
+ NULL);
+ }
+
priv->started_handshake = TRUE;
- g_tls_operations_thread_base_handshake (priv->thread, priv->advertised_protocols, timeout, cancellable,
error);
+ g_tls_operations_thread_base_handshake (priv->thread, (const gchar **)priv->advertised_protocols,
auth_mode, timeout, cancellable, error);
priv->need_handshake = FALSE;
if (error && *error)
diff --git a/tls/base/gtlsoperationsthread-base.c b/tls/base/gtlsoperationsthread-base.c
index 339aa65..32959e7 100644
--- a/tls/base/gtlsoperationsthread-base.c
+++ b/tls/base/gtlsoperationsthread-base.c
@@ -96,11 +96,10 @@ typedef struct {
GTlsOperationsThreadBase *thread;
GTlsConnectionBase *connection; /* FIXME: threadsafety nightmare, not OK */
- union {
- GTlsOperationsThreadBase *source; /* for copy client session state */
- gchar *server_identity; /* for set server identity */
- gchar **advertised_protocols; /* for handshake */
- };
+ GTlsOperationsThreadBase *source; /* for copy client session state */
+ gchar *server_identity; /* for set server identity */
+ gchar **advertised_protocols; /* for handshake */
+ GTlsAuthenticationMode auth_mode; /* for handshake */
union {
void *data; /* for read/write */
@@ -170,6 +169,7 @@ g_tls_thread_copy_client_session_state_operation_new (GTlsOperationsThreadBase *
return op;
}
+/* FIXME: dumb, move this into handshake operation as is done for authentication mode */
static GTlsThreadOperation *
g_tls_thread_set_server_identity_operation_new (GTlsOperationsThreadBase *thread,
GTlsConnectionBase *connection,
@@ -193,6 +193,7 @@ static GTlsThreadOperation *
g_tls_thread_handshake_operation_new (GTlsOperationsThreadBase *thread,
GTlsConnectionBase *connection,
const gchar **advertised_protocols,
+ GTlsAuthenticationMode auth_mode,
gint64 timeout,
GCancellable *cancellable)
{
@@ -204,6 +205,7 @@ g_tls_thread_handshake_operation_new (GTlsOperationsThreadBase *thread,
op->thread = thread;
op->connection = connection;
op->advertised_protocols = g_strdupv ((gchar **)advertised_protocols);
+ op->auth_mode = auth_mode;
op->timeout = timeout;
op->cancellable = cancellable;
@@ -870,6 +872,7 @@ process_op (GAsyncQueue *queue,
case G_TLS_THREAD_OP_HANDSHAKE:
op->result = base_class->handshake_fn (op->thread,
(const gchar **)op->advertised_protocols,
+ op->auth_mode,
op->timeout,
op->cancellable,
&op->error);
diff --git a/tls/base/gtlsoperationsthread-base.h b/tls/base/gtlsoperationsthread-base.h
index b69d207..039f3b5 100644
--- a/tls/base/gtlsoperationsthread-base.h
+++ b/tls/base/gtlsoperationsthread-base.h
@@ -45,6 +45,7 @@ struct _GTlsOperationsThreadBaseClass
GTlsConnectionBaseStatus (*handshake_fn) (GTlsOperationsThreadBase *self,
const gchar **advertised_protocols,
+ GTlsAuthenticationMode auth_mode,
gint64 timeout,
GCancellable *cancellable,
GError **error);
@@ -102,6 +103,7 @@ void g_tls_operations_thread_base_set_server_identity
GTlsConnectionBaseStatus g_tls_operations_thread_base_handshake (GTlsOperationsThreadBase
*self,
const gchar
**advertised_protocols,
+ GTlsAuthenticationMode
auth_mode,
gint64
timeout,
GCancellable
*cancellable,
GError
**error);
diff --git a/tls/gnutls/gtlsclientconnection-gnutls.c b/tls/gnutls/gtlsclientconnection-gnutls.c
index 6e55ea4..4a8c549 100644
--- a/tls/gnutls/gtlsclientconnection-gnutls.c
+++ b/tls/gnutls/gtlsclientconnection-gnutls.c
@@ -141,7 +141,6 @@ g_tls_client_connection_gnutls_initable_init (GInitable *initable,
creds = g_tls_connection_gnutls_get_credentials (G_TLS_CONNECTION_GNUTLS (gnutls));
gnutls_certificate_set_retrieve_function2 (creds,
g_tls_client_connection_gnutls_handshake_thread_retrieve_function);
-
hostname = get_server_identity (G_TLS_CLIENT_CONNECTION_GNUTLS (gnutls));
if (hostname)
g_tls_operations_thread_base_set_server_identity (thread, hostname);
diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c
index d1a6b68..1c49fd1 100644
--- a/tls/gnutls/gtlsconnection-gnutls.c
+++ b/tls/gnutls/gtlsconnection-gnutls.c
@@ -136,14 +136,6 @@ g_tls_connection_gnutls_finalize (GObject *object)
G_OBJECT_CLASS (g_tls_connection_gnutls_parent_class)->finalize (object);
}
-gnutls_certificate_credentials_t
-g_tls_connection_gnutls_get_credentials (GTlsConnectionGnutls *gnutls)
-{
- GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
-
- return priv->creds; /* FIXME: get via op thread? */
-}
-
static int
on_pin_request (void *userdata,
int attempt,
diff --git a/tls/gnutls/gtlsoperationsthread-gnutls.c b/tls/gnutls/gtlsoperationsthread-gnutls.c
index 2b9e959..9d25cd9 100644
--- a/tls/gnutls/gtlsoperationsthread-gnutls.c
+++ b/tls/gnutls/gtlsoperationsthread-gnutls.c
@@ -94,6 +94,12 @@ is_client (GTlsOperationsThreadGnutls *self)
return self->init_flags & GNUTLS_CLIENT;
}
+static inline gboolean
+is_server (GTlsOperationsThreadGnutls *self)
+{
+ return self->init_flags & GNUTLS_SERVER;
+}
+
static GTlsConnectionBaseStatus
end_gnutls_io (GTlsOperationsThreadGnutls *self,
GIOCondition direction,
@@ -281,18 +287,6 @@ initialize_gnutls_priority (void)
g_warning ("Failed to set GnuTLS session priority with error beginning at %s: %s", error_pos,
gnutls_strerror (ret));
}
-static void
-set_handshake_priority (GTlsOperationsThreadGnutls *self)
-{
- int ret;
-
- g_assert (priority);
-
- ret = gnutls_priority_set (self->session, priority);
- if (ret != GNUTLS_E_SUCCESS)
- g_warning ("Failed to set GnuTLS session priority: %s", gnutls_strerror (ret));
-}
-
static void
compute_session_id (GTlsOperationsThreadGnutls *self)
{
@@ -371,6 +365,88 @@ compute_session_id (GTlsOperationsThreadGnutls *self)
}
}
+static void
+g_tls_operations_thread_gnutls_copy_client_session_state (GTlsOperationsThreadBase *base,
+ GTlsOperationsThreadBase *base_source)
+{
+ GTlsOperationsThreadGnutls *self = G_TLS_OPERATIONS_THREAD_GNUTLS (base);
+ GTlsOperationsThreadGnutls *source = G_TLS_OPERATIONS_THREAD_GNUTLS (base_source);
+
+ /* Precondition: source has handshaked, conn has not. */
+ g_return_if_fail (!self->session_id);
+ g_return_if_fail (source->session_id);
+
+ /* Prefer to use a new session ticket, if possible. */
+ self->session_data = g_tls_backend_gnutls_lookup_session_data (source->session_id);
+
+ if (!self->session_data && source->session_data)
+ {
+ /* If it's not possible, we'll try to reuse the old ticket, even though
+ * this is a privacy risk since TLS 1.3. Applications should not use this
+ * function unless they need us to try as hard as possible to resume a
+ * session, even at the cost of privacy.
+ */
+ self->session_data = g_bytes_ref (source->session_data);
+ }
+
+ self->session_data_override = !!self->session_data;
+}
+
+static void
+g_tls_operations_thread_gnutls_set_server_identity (GTlsOperationsThreadBase *base,
+ const gchar *server_identity)
+{
+ GTlsOperationsThreadGnutls *self = G_TLS_OPERATIONS_THREAD_GNUTLS (base);
+ gchar *normalized_hostname;
+ size_t len;
+
+ g_assert (is_client (self));
+
+ normalized_hostname = g_strdup (server_identity);
+ len = strlen (server_identity);
+
+ if (server_identity[len - 1] == '.')
+ {
+ normalized_hostname[len - 1] = '\0';
+ len--;
+ }
+
+ gnutls_server_name_set (self->session, GNUTLS_NAME_DNS,
+ normalized_hostname, len);
+
+ g_clear_pointer (&self->server_identity, g_free);
+ self->server_identity = g_steal_pointer (&normalized_hostname);
+}
+
+static void
+set_handshake_priority (GTlsOperationsThreadGnutls *self)
+{
+ int ret;
+
+ g_assert (priority);
+
+ ret = gnutls_priority_set (self->session, priority);
+ if (ret != GNUTLS_E_SUCCESS)
+ g_warning ("Failed to set GnuTLS session priority: %s", gnutls_strerror (ret));
+}
+
+static void
+set_handshake_timeout (GTlsOperationsThreadGnutls *self,
+ gint64 timeout)
+{
+ unsigned int timeout_ms;
+
+ /* Convert from microseconds to milliseconds, but ensure the timeout
+ * remains positive.
+ */
+ timeout_ms = (timeout + 999) / 1000;
+
+ if (is_dtls (self))
+ gnutls_dtls_set_timeouts (self->session, 1000 /* default */, timeout_ms);
+ else
+ gnutls_handshake_set_timeout (self->session, timeout_ms);
+}
+
static void
set_advertised_protocols (GTlsOperationsThreadGnutls *self,
const gchar **advertised_protocols)
@@ -418,64 +494,32 @@ set_session_data (GTlsOperationsThreadGnutls *self)
}
static void
-g_tls_operations_thread_gnutls_copy_client_session_state (GTlsOperationsThreadBase *base,
- GTlsOperationsThreadBase *base_source)
+set_authentication_mode (GTlsOperationsThreadGnutls *self,
+ GTlsAuthenticationMode auth_mode)
{
- GTlsOperationsThreadGnutls *self = G_TLS_OPERATIONS_THREAD_GNUTLS (base);
- GTlsOperationsThreadGnutls *source = G_TLS_OPERATIONS_THREAD_GNUTLS (base_source);
+ gnutls_certificate_request_t req = GNUTLS_CERT_IGNORE;
- /* Precondition: source has handshaked, conn has not. */
- g_return_if_fail (!self->session_id);
- g_return_if_fail (source->session_id);
+ g_assert (is_server (self));
- /* Prefer to use a new session ticket, if possible. */
- self->session_data = g_tls_backend_gnutls_lookup_session_data (source->session_id);
-
- if (!self->session_data && source->session_data)
+ switch (auth_mode)
{
- /* If it's not possible, we'll try to reuse the old ticket, even though
- * this is a privacy risk since TLS 1.3. Applications should not use this
- * function unless they need us to try as hard as possible to resume a
- * session, even at the cost of privacy.
- */
- self->session_data = g_bytes_ref (source->session_data);
- }
-
- self->session_data_override = !!self->session_data;
-}
-
-static void
-g_tls_operations_thread_gnutls_set_server_identity (GTlsOperationsThreadBase *base,
- const gchar *server_identity)
-{
- GTlsOperationsThreadGnutls *self = G_TLS_OPERATIONS_THREAD_GNUTLS (base);
- gchar *normalized_hostname;
- size_t len;
-
- /* This function sets the SNI hostname, which the client uses to tell the
- * server which vhost it's connecting to. Clients only!
- */
- g_assert (is_client (self));
-
- normalized_hostname = g_strdup (server_identity);
- len = strlen (server_identity);
-
- if (server_identity[len - 1] == '.')
- {
- normalized_hostname[len - 1] = '\0';
- len--;
+ case G_TLS_AUTHENTICATION_REQUESTED:
+ req = GNUTLS_CERT_REQUEST;
+ break;
+ case G_TLS_AUTHENTICATION_REQUIRED:
+ req = GNUTLS_CERT_REQUIRE;
+ break;
+ default:
+ break;
}
- gnutls_server_name_set (self->session, GNUTLS_NAME_DNS,
- normalized_hostname, len);
-
- g_clear_pointer (&self->server_identity, g_free);
- self->server_identity = g_steal_pointer (&normalized_hostname);
+ gnutls_certificate_server_set_request (self->session, req);
}
static GTlsConnectionBaseStatus
g_tls_operations_thread_gnutls_handshake (GTlsOperationsThreadBase *base,
const gchar **advertised_protocols,
+ GTlsAuthenticationMode auth_mode,
gint64 timeout,
GCancellable *cancellable,
GError **error)
@@ -491,17 +535,7 @@ g_tls_operations_thread_gnutls_handshake (GTlsOperationsThreadBase *base,
set_handshake_priority (self);
if (timeout > 0)
- {
- unsigned int timeout_ms;
-
- /* Convert from microseconds to milliseconds, but ensure the timeout
- * remains positive.
- */
- timeout_ms = (timeout + 999) / 1000;
-
- gnutls_handshake_set_timeout (self->session, timeout_ms);
- gnutls_dtls_set_timeouts (self->session, 1000 /* default */, timeout_ms);
- }
+ set_handshake_timeout (self, timeout);
if (advertised_protocols)
set_advertised_protocols (self, advertised_protocols);
@@ -509,6 +543,9 @@ g_tls_operations_thread_gnutls_handshake (GTlsOperationsThreadBase *base,
if (is_client (self))
set_session_data (self);
+ if (is_server (self))
+ set_authentication_mode (self, auth_mode);
+
self->handshaking = TRUE;
BEGIN_GNUTLS_IO (self, G_IO_IN | G_IO_OUT, cancellable);
@@ -685,7 +722,8 @@ g_tls_operations_thread_gnutls_write_message (GTlsOperationsThreadBase *base,
if (ret < 0 || ret < vectors[i].size)
{
/* Uncork to restore state, then bail. The peer will receive a
- * truncated datagram. */
+ * truncated datagram.
+ */
break;
}
}
@@ -848,11 +886,9 @@ g_tls_operations_thread_gnutls_vec_push_func (gnutls_transport_ptr_t transport_
/* this entire expression will be evaluated at compile time */
if (sizeof *iov == sizeof *vectors &&
sizeof iov->iov_base == sizeof vectors->buffer &&
- G_STRUCT_OFFSET (giovec_t, iov_base) ==
- G_STRUCT_OFFSET (GOutputVector, buffer) &&
+ G_STRUCT_OFFSET (giovec_t, iov_base) == G_STRUCT_OFFSET (GOutputVector, buffer) &&
sizeof iov->iov_len == sizeof vectors->size &&
- G_STRUCT_OFFSET (giovec_t, iov_len) ==
- G_STRUCT_OFFSET (GOutputVector, size))
+ G_STRUCT_OFFSET (giovec_t, iov_len) == G_STRUCT_OFFSET (GOutputVector, size))
/* ABI is compatible */
{
message.vectors = (GOutputVector *)iov;
diff --git a/tls/gnutls/gtlsserverconnection-gnutls.c b/tls/gnutls/gtlsserverconnection-gnutls.c
index 090b57d..8a44285 100644
--- a/tls/gnutls/gtlsserverconnection-gnutls.c
+++ b/tls/gnutls/gtlsserverconnection-gnutls.c
@@ -55,15 +55,6 @@ static void g_tls_server_connection_gnutls_initable_interface_init (GInitabl
static void g_tls_server_connection_gnutls_server_connection_interface_init (GTlsServerConnectionInterface
*iface);
-static int g_tls_server_connection_gnutls_handshake_thread_retrieve_function (gnutls_session_t
session,
- const gnutls_datum_t
*req_ca_rdn,
- int
nreqs,
- const gnutls_pk_algorithm_t
*pk_algos,
- int
pk_algos_length,
- gnutls_pcert_st
**pcert,
- unsigned int
*pcert_length,
- gnutls_privkey_t
*pkey);
-
static GInitableIface *g_tls_server_connection_gnutls_parent_initable_iface;
G_DEFINE_TYPE_WITH_CODE (GTlsServerConnectionGnutls, g_tls_server_connection_gnutls,
G_TYPE_TLS_CONNECTION_GNUTLS,
@@ -100,6 +91,30 @@ g_tls_server_connection_gnutls_finalize (GObject *object)
G_OBJECT_CLASS (g_tls_server_connection_gnutls_parent_class)->finalize (object);
}
+static int
+g_tls_server_connection_gnutls_handshake_thread_retrieve_function (gnutls_session_t session,
+ const gnutls_datum_t *req_ca_rdn,
+ int nreqs,
+ const gnutls_pk_algorithm_t *pk_algos,
+ int
pk_algos_length,
+ gnutls_pcert_st **pcert,
+ unsigned int
*pcert_length,
+ gnutls_privkey_t *pkey)
+{
+ GTlsServerConnectionGnutls *gnutls = G_TLS_SERVER_CONNECTION_GNUTLS (gnutls_transport_get_ptr (session));
+
+ clear_gnutls_certificate_copy (gnutls);
+
+ g_tls_connection_gnutls_handshake_thread_get_certificate (G_TLS_CONNECTION_GNUTLS (gnutls),
+ pcert, pcert_length, pkey);
+
+ gnutls->pcert = *pcert;
+ gnutls->pcert_length = *pcert_length;
+ gnutls->pkey = *pkey;
+
+ return 0;
+}
+
static gboolean
g_tls_server_connection_gnutls_initable_init (GInitable *initable,
GCancellable *cancellable,
@@ -166,70 +181,15 @@ g_tls_server_connection_gnutls_set_property (GObject *object,
}
}
-static int
-g_tls_server_connection_gnutls_handshake_thread_retrieve_function (gnutls_session_t session,
- const gnutls_datum_t *req_ca_rdn,
- int nreqs,
- const gnutls_pk_algorithm_t *pk_algos,
- int
pk_algos_length,
- gnutls_pcert_st **pcert,
- unsigned int
*pcert_length,
- gnutls_privkey_t *pkey)
-{
- GTlsServerConnectionGnutls *gnutls = G_TLS_SERVER_CONNECTION_GNUTLS (gnutls_transport_get_ptr (session));
-
- clear_gnutls_certificate_copy (gnutls);
-
- g_tls_connection_gnutls_handshake_thread_get_certificate (G_TLS_CONNECTION_GNUTLS (gnutls),
- pcert, pcert_length, pkey);
-
- gnutls->pcert = *pcert;
- gnutls->pcert_length = *pcert_length;
- gnutls->pkey = *pkey;
-
- return 0;
-}
-
-static void
-g_tls_server_connection_gnutls_prepare_handshake (GTlsConnectionBase *tls,
- gchar **advertised_protocols)
-{
- GTlsServerConnectionGnutls *gnutls = G_TLS_SERVER_CONNECTION_GNUTLS (tls);
- gnutls_session_t session;
- gnutls_certificate_request_t req_mode;
-
- switch (gnutls->authentication_mode)
- {
- case G_TLS_AUTHENTICATION_REQUESTED:
- req_mode = GNUTLS_CERT_REQUEST;
- break;
- case G_TLS_AUTHENTICATION_REQUIRED:
- req_mode = GNUTLS_CERT_REQUIRE;
- break;
- case G_TLS_AUTHENTICATION_NONE:
- default:
- req_mode = GNUTLS_CERT_IGNORE;
- break;
- }
-
- session = g_tls_connection_gnutls_get_session (G_TLS_CONNECTION_GNUTLS (tls));
- gnutls_certificate_server_set_request (session, req_mode);
-
- G_TLS_CONNECTION_BASE_CLASS (g_tls_server_connection_gnutls_parent_class)->prepare_handshake (tls,
advertised_protocols);
-}
-
static void
g_tls_server_connection_gnutls_class_init (GTlsServerConnectionGnutlsClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GTlsConnectionBaseClass *base_class = G_TLS_CONNECTION_BASE_CLASS (klass);
gobject_class->finalize = g_tls_server_connection_gnutls_finalize;
gobject_class->get_property = g_tls_server_connection_gnutls_get_property;
gobject_class->set_property = g_tls_server_connection_gnutls_set_property;
- base_class->prepare_handshake = g_tls_server_connection_gnutls_prepare_handshake;
-
g_object_class_override_property (gobject_class, PROP_AUTHENTICATION_MODE, "authentication-mode");
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]