[glib-networking/mcatanzaro/tls-thread: 18/26] progress: clean build
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/mcatanzaro/tls-thread: 18/26] progress: clean build
- Date: Sat, 28 Dec 2019 20:44:45 +0000 (UTC)
commit f64322c0ff82861a34459e0179cf24e94a06d0b1
Author: Michael Catanzaro <mcatanzaro gnome org>
Date: Mon Dec 23 13:57:02 2019 -0600
progress: clean build
tls/base/gtlsoperationsthread-base.c | 79 ++++++++++++++++++++++++++------
tls/base/gtlsoperationsthread-base.h | 1 +
tls/gnutls/gtlscertificate-gnutls.c | 4 +-
tls/gnutls/gtlscertificate-gnutls.h | 2 +-
tls/gnutls/gtlsoperationsthread-gnutls.c | 49 +++++++++++++-------
5 files changed, 103 insertions(+), 32 deletions(-)
---
diff --git a/tls/base/gtlsoperationsthread-base.c b/tls/base/gtlsoperationsthread-base.c
index 2f17ca3..bb135f8 100644
--- a/tls/base/gtlsoperationsthread-base.c
+++ b/tls/base/gtlsoperationsthread-base.c
@@ -106,7 +106,7 @@ struct _HandshakeContext
{
GMainContext *caller_context;
GTlsVerifyCertificateFunc verify_callback;
- gboolean certificate_verified;
+ gboolean certificate_verified; /* FIXME: remove and track is_session_resumed instead */
gpointer user_data;
};
@@ -631,38 +631,91 @@ g_tls_operations_thread_base_set_server_identity (GTlsOperationsThreadBase *self
g_tls_thread_operation_free (op);
}
-#if 0
+typedef struct {
+ GTlsOperationsThreadBase *thread;
+ GTlsCertificate *peer_certificate;
+ HandshakeContext *context;
+
+ gboolean result;
+ gboolean complete;
+ GMutex mutex;
+ GCond condition;
+} VerifyCertificateData;
+
+static VerifyCertificateData *
+verify_certificate_data_new (GTlsOperationsThreadBase *thread,
+ GTlsCertificate *peer_certificate,
+ HandshakeContext *context)
+{
+ VerifyCertificateData *data;
+
+ data = g_new0 (VerifyCertificateData, 1);
+ data->thread = g_object_ref (thread);
+ data->peer_certificate = g_object_ref (peer_certificate);
+ data->context = context;
+
+ g_mutex_init (&data->mutex);
+ g_cond_init (&data->condition);
+
+ return data;
+}
+
+static void
+verify_certificate_data_free (VerifyCertificateData *data)
+{
+ g_object_unref (data->thread);
+ g_object_unref (data->peer_certificate);
+
+ g_mutex_clear (&data->mutex);
+ g_cond_clear (&data->condition);
+
+ g_free (data);
+}
+
static gboolean
-invoke_verify_certificate_callback_cb (gpointer user_data)
+execute_verify_certificate_callback_cb (VerifyCertificateData *data)
{
+ data->result = data->context->verify_callback (data->thread,
+ data->peer_certificate,
+ data->context->user_data);
+
+ g_mutex_lock (&data->mutex);
+ data->complete = TRUE;
+ g_mutex_unlock (&data->mutex);
+ return G_SOURCE_REMOVE;
}
-#endif
gboolean
g_tls_operations_thread_base_verify_certificate (GTlsOperationsThreadBase *self,
+ GTlsCertificate *peer_certificate,
HandshakeContext *context)
{
-#if 0
GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
+ VerifyCertificateData *data;
gboolean accepted;
g_assert (g_main_context_is_owner (priv->op_thread_context));
+ data = verify_certificate_data_new (self, peer_certificate, context);
+
/* Invoke the caller's callback on the calling thread, not the op thread. */
- g_main_context_invoke (context->caller_context, accept_or_reject_peer_certificate, tls);
+ g_main_context_invoke (context->caller_context,
+ (GSourceFunc)execute_verify_certificate_callback_cb,
+ data);
/* Block the op thread until the calling thread's callback finishes. */
- g_mutex_lock (&priv->verify_certificate_mutex);
- while (!priv->peer_certificate_examined)
- g_cond_wait (&priv->verify_certificate_condition, &priv->verify_certificate_mutex);
- accepted = priv->peer_certificate_accepted;
- g_mutex_unlock (&priv->verify_certificate_mutex);
+ g_mutex_lock (&data->mutex);
+ while (!data->complete)
+ g_cond_wait (&data->condition, &data->mutex);
+ g_mutex_unlock (&data->mutex);
+
+ context->certificate_verified = TRUE; /* FIXME: not good, not accurate */
+ accepted = data->result;
- context->certificate_verified = TRUE;
+ verify_certificate_data_free (data);
return accepted;
-#endif
}
GTlsConnectionBaseStatus
diff --git a/tls/base/gtlsoperationsthread-base.h b/tls/base/gtlsoperationsthread-base.h
index 299a35f..3ecd5fd 100644
--- a/tls/base/gtlsoperationsthread-base.h
+++ b/tls/base/gtlsoperationsthread-base.h
@@ -116,6 +116,7 @@ gboolean g_tls_operations_thread_base_get_is_missing_requested_
(GTlsOperationsThreadBase
*self);
gboolean g_tls_operations_thread_base_verify_certificate (GTlsOperationsThreadBase
*self,
+ GTlsCertificate
*peer_certificate,
HandshakeContext
*context);
void g_tls_operations_thread_base_copy_client_session_state (GTlsOperationsThreadBase
*self,
diff --git a/tls/gnutls/gtlscertificate-gnutls.c b/tls/gnutls/gtlscertificate-gnutls.c
index 3def092..c812231 100644
--- a/tls/gnutls/gtlscertificate-gnutls.c
+++ b/tls/gnutls/gtlscertificate-gnutls.c
@@ -749,7 +749,7 @@ error:
return NULL;
}
-GTlsCertificateGnutls *
+GTlsCertificate *
g_tls_certificate_gnutls_build_chain (const gnutls_datum_t *certs,
guint num_certs,
gnutls_x509_crt_fmt_t format)
@@ -811,5 +811,5 @@ g_tls_certificate_gnutls_build_chain (const gnutls_datum_t *certs,
gnutls_x509_crt_deinit (gnutls_certs[i]);
g_free (gnutls_certs);
- return result;
+ return G_TLS_CERTIFICATE (result);
}
diff --git a/tls/gnutls/gtlscertificate-gnutls.h b/tls/gnutls/gtlscertificate-gnutls.h
index 838f7db..2d33180 100644
--- a/tls/gnutls/gtlscertificate-gnutls.h
+++ b/tls/gnutls/gtlscertificate-gnutls.h
@@ -66,7 +66,7 @@ void g_tls_certificate_gnutls_set_issuer (GTlsCerti
GTlsCertificateGnutls* g_tls_certificate_gnutls_steal_issuer (GTlsCertificateGnutls *gnutls);
-GTlsCertificateGnutls* g_tls_certificate_gnutls_build_chain (const gnutls_datum_t *certs,
+GTlsCertificate * g_tls_certificate_gnutls_build_chain (const gnutls_datum_t *certs,
guint num_certs,
gnutls_x509_crt_fmt_t format);
diff --git a/tls/gnutls/gtlsoperationsthread-gnutls.c b/tls/gnutls/gtlsoperationsthread-gnutls.c
index 297f4ce..d0185f6 100644
--- a/tls/gnutls/gtlsoperationsthread-gnutls.c
+++ b/tls/gnutls/gtlsoperationsthread-gnutls.c
@@ -70,6 +70,8 @@ struct _GTlsOperationsThreadGnutls {
unsigned int pcert_length;
gnutls_privkey_t pkey;
+ GTlsCertificate *peer_certificate;
+
GList *accepted_cas;
gchar *server_identity;
@@ -537,6 +539,22 @@ set_authentication_mode (GTlsOperationsThreadGnutls *self,
gnutls_certificate_server_set_request (self->session, req);
}
+static GTlsCertificate *
+get_peer_certificate (GTlsOperationsThreadGnutls *self)
+{
+ const gnutls_datum_t *certs;
+ unsigned int num_certs;
+
+ if (gnutls_certificate_type_get (self->session) == GNUTLS_CRT_X509)
+ {
+ certs = gnutls_certificate_get_peers (self->session, &num_certs);
+ if (certs && num_certs > 0)
+ return g_tls_certificate_gnutls_build_chain (certs, num_certs, GNUTLS_X509_FMT_DER);
+ }
+
+ return NULL;
+}
+
static GTlsConnectionBaseStatus
g_tls_operations_thread_gnutls_handshake (GTlsOperationsThreadBase *base,
HandshakeContext *context,
@@ -551,12 +569,11 @@ g_tls_operations_thread_gnutls_handshake (GTlsOperationsThreadBase *base,
{
GTlsOperationsThreadGnutls *self = G_TLS_OPERATIONS_THREAD_GNUTLS (base);
GTlsConnectionBaseStatus status;
- GTlsCertificateGnutls *chain;
- const gnutls_datum_t *certs;
- unsigned int num_certs;
gnutls_datum_t protocol;
int ret;
+ g_clear_object (&self->peer_certificate);
+
if (!self->ever_handshaked)
set_handshake_priority (self);
@@ -605,17 +622,9 @@ g_tls_operations_thread_gnutls_handshake (GTlsOperationsThreadBase *base,
*accepted_cas = g_list_copy (self->accepted_cas);
- *peer_certificate = NULL;
- if (gnutls_certificate_type_get (self->session) == GNUTLS_CRT_X509)
- {
- certs = gnutls_certificate_get_peers (self->session, &num_certs);
- if (certs && num_certs > 0)
- {
- chain = g_tls_certificate_gnutls_build_chain (certs, num_certs, GNUTLS_X509_FMT_DER);
- if (chain)
- *peer_certificate = G_TLS_CERTIFICATE (chain);
- }
- }
+ if (!self->peer_certificate)
+ self->peer_certificate = get_peer_certificate (self);
+ *peer_certificate = g_steal_pointer (&self->peer_certificate);
return status;
}
@@ -1109,12 +1118,18 @@ static int
verify_certificate_cb (gnutls_session_t session)
{
GTlsOperationsThreadGnutls *self = gnutls_session_get_ptr (session);
+ gboolean accepted;
+
+ g_assert (!self->peer_certificate);
+ self->peer_certificate = get_peer_certificate (self);
+ accepted = g_tls_operations_thread_base_verify_certificate (G_TLS_OPERATIONS_THREAD_BASE (self),
+ self->peer_certificate,
+ self->handshake_context);
/* Return 0 for the handshake to continue, non-zero to terminate.
* Complete opposite of what OpenSSL does.
*/
- return !g_tls_operations_thread_base_verify_certificate (G_TLS_OPERATIONS_THREAD_BASE (self),
- self->handshake_context);
+ return !accepted;
}
static int
@@ -1415,6 +1430,8 @@ g_tls_operations_thread_gnutls_finalize (GObject *object)
self->accepted_cas = NULL;
}
+ g_assert (!self->peer_certificate);
+
g_assert (!self->op_cancellable);
g_assert (!self->op_error);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]