[glib-networking] gnutls: Update for changes to GTlsConnection:peer-certificate, etc
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking] gnutls: Update for changes to GTlsConnection:peer-certificate, etc
- Date: Tue, 7 Dec 2010 14:14:56 +0000 (UTC)
commit 4180943ce3042ed11a7ecb2cbf679450025127af
Author: Dan Winship <danw gnome org>
Date: Tue Dec 7 15:01:02 2010 +0100
gnutls: Update for changes to GTlsConnection:peer-certificate, etc
tls/gnutls/gtlsclientconnection-gnutls.c | 60 ++++++++-------------
tls/gnutls/gtlsconnection-gnutls.c | 85 +++++++++++++++++++++++++++---
tls/gnutls/gtlsconnection-gnutls.h | 6 ++-
tls/gnutls/gtlsserverconnection-gnutls.c | 40 ++++++--------
4 files changed, 123 insertions(+), 68 deletions(-)
---
diff --git a/tls/gnutls/gtlsclientconnection-gnutls.c b/tls/gnutls/gtlsclientconnection-gnutls.c
index b4f1b38..476a60b 100644
--- a/tls/gnutls/gtlsclientconnection-gnutls.c
+++ b/tls/gnutls/gtlsclientconnection-gnutls.c
@@ -50,8 +50,10 @@ static void g_tls_client_connection_gnutls_set_property (GObject *object,
static void g_tls_client_connection_gnutls_finalize (GObject *object);
static void g_tls_client_connection_gnutls_begin_handshake (GTlsConnectionGnutls *conn);
-static gboolean g_tls_client_connection_gnutls_finish_handshake (GTlsConnectionGnutls *conn,
- gboolean success,
+static gboolean g_tls_client_connection_gnutls_verify_peer (GTlsConnectionGnutls *gnutls,
+ GTlsCertificate *peer_certificate,
+ GTlsCertificateFlags *errors);
+static void g_tls_client_connection_gnutls_finish_handshake (GTlsConnectionGnutls *conn,
GError **inout_error);
static void g_tls_client_connection_gnutls_client_connection_interface_init (GTlsClientConnectionInterface *iface);
@@ -89,7 +91,8 @@ g_tls_client_connection_gnutls_class_init (GTlsClientConnectionGnutlsClass *klas
gobject_class->set_property = g_tls_client_connection_gnutls_set_property;
gobject_class->finalize = g_tls_client_connection_gnutls_finalize;
- connection_gnutls_class->begin_handshake = g_tls_client_connection_gnutls_begin_handshake;
+ connection_gnutls_class->begin_handshake = g_tls_client_connection_gnutls_begin_handshake;
+ connection_gnutls_class->verify_peer = g_tls_client_connection_gnutls_verify_peer;
connection_gnutls_class->finish_handshake = g_tls_client_connection_gnutls_finish_handshake;
g_object_class_override_property (gobject_class, PROP_VALIDATION_FLAGS, "validation-flags");
@@ -237,27 +240,32 @@ g_tls_client_connection_gnutls_retrieve_function (gnutls_session_t s
return 0;
}
+static void
+g_tls_client_connection_gnutls_begin_handshake (GTlsConnectionGnutls *conn)
+{
+ GTlsClientConnectionGnutls *gnutls = G_TLS_CLIENT_CONNECTION_GNUTLS (conn);
+
+ gnutls->priv->cert_requested = FALSE;
+}
+
static gboolean
-validate_handshake (GTlsClientConnectionGnutls *gnutls)
+g_tls_client_connection_gnutls_verify_peer (GTlsConnectionGnutls *conn_gnutls,
+ GTlsCertificate *peer_certificate,
+ GTlsCertificateFlags *errors)
{
- GTlsCertificate *peer;
- GTlsCertificateFlags errors;
+ GTlsClientConnectionGnutls *gnutls = G_TLS_CLIENT_CONNECTION_GNUTLS (conn_gnutls);
gboolean accepted;
- peer = g_tls_connection_get_peer_certificate (G_TLS_CONNECTION (gnutls));
-
- errors = g_tls_connection_gnutls_validate_peer (G_TLS_CONNECTION_GNUTLS (gnutls));
+ *errors = g_tls_connection_gnutls_validate_peer (conn_gnutls);
- if ((gnutls->priv->validation_flags & G_TLS_CERTIFICATE_BAD_IDENTITY) &&
- gnutls->priv->server_identity)
+ if (gnutls->priv->server_identity)
{
- errors |= g_tls_certificate_gnutls_verify_identity (G_TLS_CERTIFICATE_GNUTLS (peer),
- gnutls->priv->server_identity);
+ *errors |= g_tls_certificate_gnutls_verify_identity (G_TLS_CERTIFICATE_GNUTLS (peer_certificate),
+ gnutls->priv->server_identity);
}
- errors &= gnutls->priv->validation_flags;
- if (errors)
- accepted = g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls), peer, errors);
+ if (*errors & gnutls->priv->validation_flags)
+ accepted = g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls), peer_certificate, *errors);
else
accepted = TRUE;
@@ -265,30 +273,11 @@ validate_handshake (GTlsClientConnectionGnutls *gnutls)
}
static void
-g_tls_client_connection_gnutls_begin_handshake (GTlsConnectionGnutls *conn)
-{
- GTlsClientConnectionGnutls *gnutls = G_TLS_CLIENT_CONNECTION_GNUTLS (conn);
-
- gnutls->priv->cert_requested = FALSE;
-}
-
-static gboolean
g_tls_client_connection_gnutls_finish_handshake (GTlsConnectionGnutls *conn,
- gboolean success,
GError **inout_error)
{
GTlsClientConnectionGnutls *gnutls = G_TLS_CLIENT_CONNECTION_GNUTLS (conn);
- if (success)
- {
- if (validate_handshake (gnutls))
- return TRUE;
-
- g_set_error_literal (inout_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
- _("Unacceptable TLS certificate"));
- return FALSE;
- }
-
if (g_error_matches (*inout_error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS) &&
gnutls->priv->cert_requested)
{
@@ -296,5 +285,4 @@ g_tls_client_connection_gnutls_finish_handshake (GTlsConnectionGnutls *conn,
g_set_error_literal (inout_error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED,
_("Server required TLS certificate"));
}
- return FALSE;
}
diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c
index 9fab2d3..f1327f2 100644
--- a/tls/gnutls/gtlsconnection-gnutls.c
+++ b/tls/gnutls/gtlsconnection-gnutls.c
@@ -97,7 +97,10 @@ enum
PROP_BASE_IO_STREAM,
PROP_REQUIRE_CLOSE_NOTIFY,
PROP_REHANDSHAKE_MODE,
- PROP_USE_SYSTEM_CERTDB
+ PROP_USE_SYSTEM_CERTDB,
+ PROP_CERTIFICATE,
+ PROP_PEER_CERTIFICATE,
+ PROP_PEER_CERTIFICATE_ERRORS
};
struct _GTlsConnectionGnutlsPrivate
@@ -109,6 +112,9 @@ struct _GTlsConnectionGnutlsPrivate
GList *ca_list;
gnutls_certificate_credentials creds;
gnutls_session session;
+
+ GTlsCertificate *certificate, *peer_certificate;
+ GTlsCertificateFlags peer_certificate_errors;
gboolean require_close_notify;
GTlsRehandshakeMode rehandshake_mode;
gboolean use_system_certdb;
@@ -151,6 +157,9 @@ g_tls_connection_gnutls_class_init (GTlsConnectionGnutlsClass *klass)
g_object_class_override_property (gobject_class, PROP_REQUIRE_CLOSE_NOTIFY, "require-close-notify");
g_object_class_override_property (gobject_class, PROP_REHANDSHAKE_MODE, "rehandshake-mode");
g_object_class_override_property (gobject_class, PROP_USE_SYSTEM_CERTDB, "use-system-certdb");
+ g_object_class_override_property (gobject_class, PROP_CERTIFICATE, "certificate");
+ g_object_class_override_property (gobject_class, PROP_PEER_CERTIFICATE, "peer-certificate");
+ g_object_class_override_property (gobject_class, PROP_PEER_CERTIFICATE_ERRORS, "peer-certificate-errors");
}
static void
@@ -264,6 +273,11 @@ g_tls_connection_gnutls_finalize (GObject *object)
if (connection->priv->creds)
gnutls_certificate_free_credentials (connection->priv->creds);
+ if (connection->priv->certificate)
+ g_object_unref (connection->priv->certificate);
+ if (connection->priv->peer_certificate)
+ g_object_unref (connection->priv->peer_certificate);
+
if (connection->priv->error)
g_error_free (connection->priv->error);
@@ -296,6 +310,18 @@ g_tls_connection_gnutls_get_property (GObject *object,
g_value_set_boolean (value, gnutls->priv->use_system_certdb);
break;
+ case PROP_CERTIFICATE:
+ g_value_set_object (value, gnutls->priv->certificate);
+ break;
+
+ case PROP_PEER_CERTIFICATE:
+ g_value_set_object (value, gnutls->priv->peer_certificate);
+ break;
+
+ case PROP_PEER_CERTIFICATE_ERRORS:
+ g_value_set_flags (value, gnutls->priv->peer_certificate_errors);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -357,6 +383,12 @@ g_tls_connection_gnutls_set_property (GObject *object,
}
break;
+ case PROP_CERTIFICATE:
+ if (gnutls->priv->certificate)
+ g_object_unref (gnutls->priv->certificate);
+ gnutls->priv->certificate = g_value_dup_object (value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -736,6 +768,8 @@ handshake_internal (GTlsConnectionGnutls *gnutls,
GCancellable *cancellable,
GError **error)
{
+ GTlsCertificate *peer_certificate;
+ GTlsCertificateFlags peer_certificate_errors;
int ret;
if (G_IS_TLS_SERVER_CONNECTION_GNUTLS (gnutls) &&
@@ -749,10 +783,23 @@ handshake_internal (GTlsConnectionGnutls *gnutls,
return FALSE;
}
- g_tls_connection_gnutls_set_handshake_priority (gnutls);
+ if (!gnutls->priv->handshaking)
+ {
+ gnutls->priv->handshaking = TRUE;
- gnutls->priv->handshaking = TRUE;
- G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->begin_handshake (gnutls);
+ if (gnutls->priv->peer_certificate)
+ {
+ g_object_unref (gnutls->priv->peer_certificate);
+ gnutls->priv->peer_certificate = NULL;
+ gnutls->priv->peer_certificate_errors = 0;
+
+ g_object_notify (G_OBJECT (gnutls), "peer-certificate");
+ g_object_notify (G_OBJECT (gnutls), "peer-certificate-errors");
+ }
+
+ g_tls_connection_gnutls_set_handshake_priority (gnutls);
+ G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->begin_handshake (gnutls);
+ }
BEGIN_GNUTLS_IO (gnutls, blocking, cancellable);
ret = gnutls_handshake (gnutls->priv->session);
@@ -784,12 +831,36 @@ handshake_internal (GTlsConnectionGnutls *gnutls,
}
}
- g_tls_connection_set_peer_certificate (G_TLS_CONNECTION (gnutls), chain);
+ peer_certificate = chain;
}
else
- g_tls_connection_set_peer_certificate (G_TLS_CONNECTION (gnutls), NULL);
+ peer_certificate = NULL;
+
+ if (peer_certificate)
+ {
+ if (!G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->verify_peer (gnutls, peer_certificate, &peer_certificate_errors))
+ {
+ g_object_unref (peer_certificate);
+ g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
+ _("Unacceptable TLS certificate"));
+ return FALSE;
+ }
+ }
+
+ G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->finish_handshake (gnutls, error);
- return G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->finish_handshake (gnutls, ret == 0, error);
+ if (ret == 0)
+ {
+ gnutls->priv->peer_certificate = peer_certificate;
+ gnutls->priv->peer_certificate_errors = peer_certificate_errors;
+
+ g_object_notify (G_OBJECT (gnutls), "peer-certificate");
+ g_object_notify (G_OBJECT (gnutls), "peer-certificate-errors");
+
+ return TRUE;
+ }
+ else
+ return FALSE;
}
static gboolean
diff --git a/tls/gnutls/gtlsconnection-gnutls.h b/tls/gnutls/gtlsconnection-gnutls.h
index 834fc16..0e54df8 100644
--- a/tls/gnutls/gtlsconnection-gnutls.h
+++ b/tls/gnutls/gtlsconnection-gnutls.h
@@ -34,8 +34,10 @@ struct _GTlsConnectionGnutlsClass
GTlsConnectionClass parent_class;
void (*begin_handshake) (GTlsConnectionGnutls *gnutls);
- gboolean (*finish_handshake) (GTlsConnectionGnutls *gnutls,
- gboolean success,
+ gboolean (*verify_peer) (GTlsConnectionGnutls *gnutls,
+ GTlsCertificate *peer_certificate,
+ GTlsCertificateFlags *errors);
+ void (*finish_handshake) (GTlsConnectionGnutls *gnutls,
GError **inout_error);
};
diff --git a/tls/gnutls/gtlsserverconnection-gnutls.c b/tls/gnutls/gtlsserverconnection-gnutls.c
index 119f847..6e9a8bd 100644
--- a/tls/gnutls/gtlsserverconnection-gnutls.c
+++ b/tls/gnutls/gtlsserverconnection-gnutls.c
@@ -45,8 +45,10 @@ static void g_tls_server_connection_gnutls_set_property (GObject *object,
GParamSpec *pspec);
static void g_tls_server_connection_gnutls_begin_handshake (GTlsConnectionGnutls *conn);
-static gboolean g_tls_server_connection_gnutls_finish_handshake (GTlsConnectionGnutls *conn,
- gboolean success,
+static gboolean g_tls_server_connection_gnutls_verify_peer (GTlsConnectionGnutls *gnutls,
+ GTlsCertificate *peer_certificate,
+ GTlsCertificateFlags *errors);
+static void g_tls_server_connection_gnutls_finish_handshake (GTlsConnectionGnutls *conn,
GError **inout_error);
static void g_tls_server_connection_gnutls_server_connection_interface_init (GTlsServerConnectionInterface *iface);
@@ -74,7 +76,8 @@ g_tls_server_connection_gnutls_class_init (GTlsServerConnectionGnutlsClass *klas
gobject_class->get_property = g_tls_server_connection_gnutls_get_property;
gobject_class->set_property = g_tls_server_connection_gnutls_set_property;
- connection_gnutls_class->begin_handshake = g_tls_server_connection_gnutls_begin_handshake;
+ connection_gnutls_class->begin_handshake = g_tls_server_connection_gnutls_begin_handshake;
+ connection_gnutls_class->verify_peer = g_tls_server_connection_gnutls_verify_peer;
connection_gnutls_class->finish_handshake = g_tls_server_connection_gnutls_finish_handshake;
g_object_class_override_property (gobject_class, PROP_AUTHENTICATION_MODE, "authentication-mode");
@@ -167,27 +170,18 @@ g_tls_server_connection_gnutls_begin_handshake (GTlsConnectionGnutls *conn)
}
static gboolean
-g_tls_server_connection_gnutls_finish_handshake (GTlsConnectionGnutls *gnutls,
- gboolean success,
- GError **inout_error)
+g_tls_server_connection_gnutls_verify_peer (GTlsConnectionGnutls *gnutls,
+ GTlsCertificate *peer_certificate,
+ GTlsCertificateFlags *errors)
{
- GTlsCertificateFlags gtls_errors;
- GTlsCertificate *peer;
-
- if (!success)
- return FALSE;
+ *errors = g_tls_connection_gnutls_validate_peer (G_TLS_CONNECTION_GNUTLS (gnutls));
- peer = g_tls_connection_get_peer_certificate (G_TLS_CONNECTION (gnutls));
- if (peer)
- {
- gtls_errors = g_tls_connection_gnutls_validate_peer (gnutls);
- if (!g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls), peer, gtls_errors))
- {
- g_set_error_literal (inout_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
- _("Unacceptable TLS certificate"));
- return FALSE;
- }
- }
+ return g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls),
+ peer_certificate, *errors);
+}
- return TRUE;
+static void
+g_tls_server_connection_gnutls_finish_handshake (GTlsConnectionGnutls *gnutls,
+ GError **inout_error)
+{
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]