[glib-networking/mcatanzaro/tls-thread: 22/26] progress
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/mcatanzaro/tls-thread: 22/26] progress
- Date: Sat, 28 Dec 2019 20:45:05 +0000 (UTC)
commit 3800a80c68f827942cc9aaa769e666a34f9042a0
Author: Michael Catanzaro <mcatanzaro gnome org>
Date: Tue Dec 24 12:36:23 2019 -0600
progress
tls/base/gtlsconnection-base.c | 8 +---
tls/base/gtlsoperationsthread-base.c | 47 +++++++--------------
tls/base/gtlsoperationsthread-base.h | 9 ++--
tls/gnutls/gtlsoperationsthread-gnutls.c | 71 +++++++++++++++++++-------------
4 files changed, 65 insertions(+), 70 deletions(-)
---
diff --git a/tls/base/gtlsconnection-base.c b/tls/base/gtlsconnection-base.c
index 4391625..a770db1 100644
--- a/tls/base/gtlsconnection-base.c
+++ b/tls/base/gtlsconnection-base.c
@@ -238,9 +238,6 @@ g_tls_connection_base_initable_init (GInitable *initable,
if (!priv->thread)
return FALSE;
- if (priv->certificate)
- g_tls_operations_thread_base_set_own_certificate (priv->thread, priv->certificate);
-
if (priv->interaction)
g_tls_operations_thread_base_set_interaction (priv->thread, priv->interaction);
@@ -440,10 +437,6 @@ g_tls_connection_base_set_property (GObject *object,
if (priv->certificate)
g_object_unref (priv->certificate);
priv->certificate = g_value_dup_object (value);
-
- if (priv->thread)
- g_tls_operations_thread_base_set_own_certificate (priv->thread,
- priv->certificate);
break;
case PROP_INTERACTION:
@@ -1416,6 +1409,7 @@ handshake (GTlsConnectionBase *tls,
priv->started_handshake = TRUE;
g_tls_operations_thread_base_handshake (priv->thread,
+ priv->certificate,
(const gchar **)priv->advertised_protocols,
auth_mode,
timeout,
diff --git a/tls/base/gtlsoperationsthread-base.c b/tls/base/gtlsoperationsthread-base.c
index 46ead3b..0eecf58 100644
--- a/tls/base/gtlsoperationsthread-base.c
+++ b/tls/base/gtlsoperationsthread-base.c
@@ -81,13 +81,12 @@ typedef struct {
* instead return data from the op thread to the calling thread using the op
* struct.
*
- * TODO: some of this could move into the op struct?
+ * FIXME: what of this can move into the op struct?
*/
GMutex mutex;
- gchar *own_certificate_pem;
GTlsInteraction *interaction;
GError *interaction_error;
- gboolean missing_requested_client_certificate;
+ gboolean missing_requested_client_certificate; /* FIXME: out parameter of handshake op? */
} GTlsOperationsThreadBasePrivate;
typedef enum {
@@ -112,6 +111,7 @@ struct _HandshakeContext
typedef struct {
HandshakeContext *context;
+ GTlsCertificate *own_certificate;
gchar **advertised_protocols;
GTlsAuthenticationMode auth_mode;
gchar *negotiated_protocol;
@@ -182,33 +182,6 @@ g_tls_operations_thread_base_get_connection (GTlsOperationsThreadBase *self)
return priv->connection;
}
-void
-g_tls_operations_thread_base_set_own_certificate (GTlsOperationsThreadBase *self,
- GTlsCertificate *cert)
-{
- GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
-
- g_mutex_lock (&priv->mutex);
- g_clear_pointer (&priv->own_certificate_pem, g_free);
- g_object_get (cert,
- "certificate-pem", &priv->own_certificate_pem,
- NULL);
- g_mutex_unlock (&priv->mutex);
-}
-
-gchar *
-g_tls_operations_thread_base_get_own_certificate_pem (GTlsOperationsThreadBase *self)
-{
- GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
- gchar *copy;
-
- g_mutex_lock (&priv->mutex);
- copy = g_strdup (priv->own_certificate_pem);
- g_mutex_unlock (&priv->mutex);
-
- return copy;
-}
-
void
g_tls_operations_thread_base_set_interaction (GTlsOperationsThreadBase *self,
GTlsInteraction *interaction)
@@ -314,6 +287,7 @@ handshake_context_free (HandshakeContext *context)
static HandshakeData *
handshake_data_new (HandshakeContext *context,
+ GTlsCertificate *own_certificate,
const gchar **advertised_protocols,
GTlsAuthenticationMode mode)
{
@@ -321,6 +295,7 @@ handshake_data_new (HandshakeContext *context,
data = g_new0 (HandshakeData, 1);
data->context = context;
+ data->own_certificate = own_certificate ? g_object_ref (own_certificate) : NULL;
data->advertised_protocols = g_strdupv ((gchar **)advertised_protocols);
data->auth_mode = mode;
@@ -332,6 +307,7 @@ handshake_data_free (HandshakeData *data)
{
g_strfreev (data->advertised_protocols);
+ g_clear_object (&data->own_certificate);
g_clear_object (&data->peer_certificate);
g_assert (!data->accepted_cas);
@@ -381,6 +357,7 @@ g_tls_thread_set_server_identity_operation_new (GTlsOperationsThreadBase *thread
static GTlsThreadOperation *
g_tls_thread_handshake_operation_new (GTlsOperationsThreadBase *thread,
HandshakeContext *context,
+ GTlsCertificate *own_certificate,
GTlsConnectionBase *connection,
const gchar **advertised_protocols,
GTlsAuthenticationMode auth_mode,
@@ -398,6 +375,7 @@ g_tls_thread_handshake_operation_new (GTlsOperationsThreadBase *thread,
op->cancellable = cancellable;
op->handshake_data = handshake_data_new (context,
+ own_certificate,
advertised_protocols,
auth_mode);
@@ -719,6 +697,7 @@ g_tls_operations_thread_base_verify_certificate (GTlsOperationsThreadBase *self,
GTlsConnectionBaseStatus
g_tls_operations_thread_base_handshake (GTlsOperationsThreadBase *self,
+ GTlsCertificate *own_certificate,
const gchar **advertised_protocols,
GTlsAuthenticationMode auth_mode,
gint64 timeout,
@@ -733,6 +712,7 @@ g_tls_operations_thread_base_handshake (GTlsOperationsThreadBase *self,
GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
GTlsConnectionBaseStatus status;
GTlsThreadOperation *op;
+ GTlsCertificate *copied_cert;
HandshakeContext *context;
g_assert (!g_main_context_is_owner (priv->op_thread_context));
@@ -744,8 +724,12 @@ g_tls_operations_thread_base_handshake (GTlsOperationsThreadBase *self,
context = handshake_context_new (verify_callback,
user_data);
+ copied_cert = G_TLS_OPERATIONS_THREAD_BASE_GET_CLASS (self)->copy_certificate (self,
+ own_certificate);
+
op = g_tls_thread_handshake_operation_new (self,
context,
+ copied_cert,
priv->connection,
advertised_protocols,
auth_mode,
@@ -762,6 +746,7 @@ g_tls_operations_thread_base_handshake (GTlsOperationsThreadBase *self,
handshake_context_free (context);
g_tls_thread_operation_free (op);
+ g_object_unref (copied_cert);
return status;
}
@@ -1216,6 +1201,7 @@ process_op (GAsyncQueue *queue,
case G_TLS_THREAD_OP_HANDSHAKE:
op->result = base_class->handshake_fn (op->thread,
op->handshake_data->context,
+ op->handshake_data->own_certificate,
(const gchar **)op->handshake_data->advertised_protocols,
op->handshake_data->auth_mode,
op->timeout,
@@ -1430,7 +1416,6 @@ g_tls_operations_thread_base_finalize (GObject *object)
g_mutex_clear (&priv->mutex);
- g_clear_pointer (&priv->own_certificate_pem, g_free);
g_clear_object (&priv->interaction);
g_clear_error (&priv->interaction_error);
diff --git a/tls/base/gtlsoperationsthread-base.h b/tls/base/gtlsoperationsthread-base.h
index 3ecd5fd..7d390fa 100644
--- a/tls/base/gtlsoperationsthread-base.h
+++ b/tls/base/gtlsoperationsthread-base.h
@@ -40,6 +40,9 @@ struct _GTlsOperationsThreadBaseClass
{
GObjectClass parent_class;
+ GTlsCertificate *(*copy_certificate) (GTlsOperationsThreadBase *self,
+ GTlsCertificate *cert);
+
void (*copy_client_session_state) (GTlsOperationsThreadBase *self,
GTlsOperationsThreadBase *source);
@@ -48,6 +51,7 @@ struct _GTlsOperationsThreadBaseClass
GTlsConnectionBaseStatus (*handshake_fn) (GTlsOperationsThreadBase *self,
HandshakeContext *context,
+ GTlsCertificate *own_certificate,
const gchar **advertised_protocols,
GTlsAuthenticationMode auth_mode,
gint64 timeout,
@@ -98,10 +102,6 @@ typedef void (*GTlsSessionResumedFunc) (GTlsOperationsThreadBase *thread,
/* FIXME: remove!!! */
GTlsConnectionBase *g_tls_operations_thread_base_get_connection (GTlsOperationsThreadBase
*self);
-void g_tls_operations_thread_base_set_own_certificate (GTlsOperationsThreadBase
*self,
- GTlsCertificate
*cert);
-gchar *g_tls_operations_thread_base_get_own_certificate_pem (GTlsOperationsThreadBase
*self);
-
void g_tls_operations_thread_base_set_interaction (GTlsOperationsThreadBase
*self,
GTlsInteraction
*interaction);
GTlsInteraction *g_tls_operations_thread_base_ref_interaction (GTlsOperationsThreadBase
*self);
@@ -126,6 +126,7 @@ void g_tls_operations_thread_base_set_server_identity
const gchar
*server_identity);
GTlsConnectionBaseStatus g_tls_operations_thread_base_handshake (GTlsOperationsThreadBase
*self,
+ GTlsCertificate
*own_certificate,
const gchar
**advertised_protocols,
GTlsAuthenticationMode
auth_mode,
gint64
timeout,
diff --git a/tls/gnutls/gtlsoperationsthread-gnutls.c b/tls/gnutls/gtlsoperationsthread-gnutls.c
index 39185eb..319498a 100644
--- a/tls/gnutls/gtlsoperationsthread-gnutls.c
+++ b/tls/gnutls/gtlsoperationsthread-gnutls.c
@@ -63,15 +63,17 @@ struct _GTlsOperationsThreadGnutls {
gboolean handshaking;
gboolean ever_handshaked;
+ /* Valid only during current operation */
+ GTlsCertificate *own_certificate;
+ GTlsCertificate *peer_certificate;
GCancellable *op_cancellable;
GError *op_error;
+ /* Certificate internals, must be kept alive here. */
gnutls_pcert_st *pcert;
unsigned int pcert_length;
gnutls_privkey_t pkey;
- GTlsCertificate *peer_certificate;
-
GList *accepted_cas;
gchar *server_identity;
@@ -319,6 +321,17 @@ initialize_gnutls_priority (void)
g_warning ("Failed to set GnuTLS session priority with error beginning at %s: %s", error_pos,
gnutls_strerror (ret));
}
+static GTlsCertificate *
+g_tls_operations_thread_gnutls_copy_certificate (GTlsOperationsThreadBase *base,
+ GTlsCertificate *cert)
+{
+ /* FIXME: need a real copy to avoid sharing the certificate across threads.
+ * Copy must copy private key. Must copy ENTIRE CHAIN including issuers.
+ */
+
+ return cert ? g_object_ref (cert) : NULL;
+}
+
static void
g_tls_operations_thread_gnutls_copy_client_session_state (GTlsOperationsThreadBase *base,
GTlsOperationsThreadBase *base_source)
@@ -465,7 +478,6 @@ compute_session_id (GTlsOperationsThreadGnutls *self)
const gchar *server_hostname;
gchar *addrstr;
gchar *session_id;
- gchar *pem;
gchar *cert_hash = NULL;
iaddr = g_inet_socket_address_get_address (isaddr);
@@ -478,11 +490,17 @@ compute_session_id (GTlsOperationsThreadGnutls *self)
* that different connections to the same server can use different
* certificates.
*/
- pem = g_tls_operations_thread_base_get_own_certificate_pem (G_TLS_OPERATIONS_THREAD_BASE (self));
- if (pem)
+ if (self->own_certificate)
{
- cert_hash = g_compute_checksum_for_string (G_CHECKSUM_SHA256, pem, -1);
- g_free (pem);
+ GByteArray *der = NULL;
+ g_object_get (self->own_certificate,
+ "certificate", &der,
+ NULL);
+ if (der)
+ {
+ cert_hash = g_compute_checksum_for_data (G_CHECKSUM_SHA256, der->data, der->len);
+ g_byte_array_unref (der);
+ }
}
session_id = g_strdup_printf ("%s/%s/%d/%s", addrstr,
@@ -569,6 +587,7 @@ get_peer_certificate (GTlsOperationsThreadGnutls *self)
static GTlsConnectionBaseStatus
g_tls_operations_thread_gnutls_handshake (GTlsOperationsThreadBase *base,
HandshakeContext *context,
+ GTlsCertificate *own_certificate,
const gchar **advertised_protocols,
GTlsAuthenticationMode auth_mode,
gint64 timeout,
@@ -583,7 +602,7 @@ g_tls_operations_thread_gnutls_handshake (GTlsOperationsThreadBase *base,
gnutls_datum_t protocol;
int ret;
- g_clear_object (&self->peer_certificate);
+ self->own_certificate = g_steal_pointer (&own_certificate);
if (!self->ever_handshaked)
set_handshake_priority (self);
@@ -626,6 +645,8 @@ g_tls_operations_thread_gnutls_handshake (GTlsOperationsThreadBase *base,
self->handshaking = FALSE;
self->ever_handshaked = TRUE;
+ g_clear_object (&self->own_certificate);
+
if (gnutls_alpn_get_selected_protocol (self->session, &protocol) == 0 && protocol.size > 0)
*negotiated_protocol = g_strndup ((gchar *)protocol.data, protocol.size);
else
@@ -1209,7 +1230,7 @@ pin_request_cb (void *userdata,
}
static void
-clear_gnutls_certificate_copy (GTlsOperationsThreadGnutls *self)
+clear_own_certificate_internals (GTlsOperationsThreadGnutls *self)
{
g_tls_certificate_gnutls_copy_free (self->pcert, self->pcert_length, self->pkey);
@@ -1219,28 +1240,20 @@ clear_gnutls_certificate_copy (GTlsOperationsThreadGnutls *self)
}
static void
-get_own_certificate (GTlsOperationsThreadGnutls *self,
- gnutls_pcert_st **pcert,
- unsigned int *pcert_length,
- gnutls_privkey_t *pkey)
+get_gnutls_certificate_internals (GTlsOperationsThreadGnutls *self,
+ gnutls_pcert_st **pcert,
+ unsigned int *pcert_length,
+ gnutls_privkey_t *pkey)
{
- char *pem;
- GTlsCertificate *cert = NULL;
-
- pem = g_tls_operations_thread_base_get_own_certificate_pem (G_TLS_OPERATIONS_THREAD_BASE (self));
- if (pem)
- {
- cert = g_tls_certificate_new_from_pem (pem, -1, NULL);
- g_free (pem);
- }
+ clear_own_certificate_internals (self);
- if (cert)
+ if (self->own_certificate)
{
gnutls_privkey_t privkey;
gnutls_privkey_init (&privkey);
gnutls_privkey_set_pin_function (privkey, pin_request_cb, self);
- g_tls_certificate_gnutls_copy (G_TLS_CERTIFICATE_GNUTLS (cert),
+ g_tls_certificate_gnutls_copy (G_TLS_CERTIFICATE_GNUTLS (self->own_certificate),
self->interaction_id,
pcert, pcert_length, &privkey);
*pkey = privkey;
@@ -1289,8 +1302,8 @@ retrieve_certificate_cb (gnutls_session_t session,
self->accepted_cas = g_list_reverse (self->accepted_cas);
}
- clear_gnutls_certificate_copy (self);
- get_own_certificate (self, pcert, pcert_length, pkey);
+ clear_own_certificate_internals (self);
+ get_gnutls_certificate_internals (self, pcert, pcert_length, pkey);
if (is_client (self))
{
@@ -1300,7 +1313,7 @@ retrieve_certificate_cb (gnutls_session_t session,
if (g_tls_operations_thread_base_request_certificate (G_TLS_OPERATIONS_THREAD_BASE (self),
self->op_cancellable))
- get_own_certificate (self, pcert, pcert_length, pkey);
+ get_gnutls_certificate_internals (self, pcert, pcert_length, pkey);
if (*pcert_length == 0)
{
@@ -1437,7 +1450,7 @@ g_tls_operations_thread_gnutls_finalize (GObject *object)
g_clear_object (&self->base_iostream);
g_clear_object (&self->base_socket);
- clear_gnutls_certificate_copy (self);
+ clear_own_certificate_internals (self);
if (self->accepted_cas)
{
@@ -1446,6 +1459,7 @@ g_tls_operations_thread_gnutls_finalize (GObject *object)
}
g_assert (!self->peer_certificate);
+ g_assert (!self->own_certificate);
g_assert (!self->op_cancellable);
g_assert (!self->op_error);
@@ -1538,6 +1552,7 @@ g_tls_operations_thread_gnutls_class_init (GTlsOperationsThreadGnutlsClass *klas
gobject_class->get_property = g_tls_operations_thread_gnutls_get_property;
gobject_class->set_property = g_tls_operations_thread_gnutls_set_property;
+ base_class->copy_certificate = g_tls_operations_thread_gnutls_copy_certificate;
base_class->copy_client_session_state = g_tls_operations_thread_gnutls_copy_client_session_state;
base_class->set_server_identity = g_tls_operations_thread_gnutls_set_server_identity;
base_class->handshake_fn = g_tls_operations_thread_gnutls_handshake;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]