[glib-networking/mcatanzaro/tls-thread: 16/24] progress: clean build



commit 9327cccc5f2783cfbac8089aa4e06c4b4c35df2d
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]