[glib-networking] gnutls: make GTlsServerConnection error out if given a bad cert



commit ee6ed146ee6cabf8c64ea3389fbaa5fea4ff2008
Author: Dan Winship <danw gnome org>
Date:   Fri Nov 18 20:25:25 2011 -0500

    gnutls: make GTlsServerConnection error out if given a bad cert
    
    GTlsServerConnection needs a certificate that has a public key, so
    make it fail g_initable_init() if it has a certificate without one.

 tls/gnutls/gtlscertificate-gnutls.c      |    6 ++++
 tls/gnutls/gtlscertificate-gnutls.h      |    1 +
 tls/gnutls/gtlsconnection-gnutls.c       |    2 +-
 tls/gnutls/gtlsserverconnection-gnutls.c |   41 +++++++++++++++++++++++++++++-
 4 files changed, 48 insertions(+), 2 deletions(-)
---
diff --git a/tls/gnutls/gtlscertificate-gnutls.c b/tls/gnutls/gtlscertificate-gnutls.c
index 9227ba2..30497e6 100644
--- a/tls/gnutls/gtlscertificate-gnutls.c
+++ b/tls/gnutls/gtlscertificate-gnutls.c
@@ -460,6 +460,12 @@ g_tls_certificate_gnutls_get_cert (GTlsCertificateGnutls *gnutls)
   return gnutls->priv->cert;
 }
 
+gboolean
+g_tls_certificate_gnutls_has_key (GTlsCertificateGnutls *gnutls)
+{
+  return gnutls->priv->have_key;
+}
+
 void
 g_tls_certificate_gnutls_copy  (GTlsCertificateGnutls *gnutls,
                                 const gchar           *interaction_id,
diff --git a/tls/gnutls/gtlscertificate-gnutls.h b/tls/gnutls/gtlscertificate-gnutls.h
index 202ed6e..981d4a7 100644
--- a/tls/gnutls/gtlscertificate-gnutls.h
+++ b/tls/gnutls/gtlscertificate-gnutls.h
@@ -53,6 +53,7 @@ void                         g_tls_certificate_gnutls_set_data        (GTlsCerti
                                                                        const gnutls_datum *datum);
 
 const gnutls_x509_crt_t      g_tls_certificate_gnutls_get_cert        (GTlsCertificateGnutls *gnutls);
+gboolean                     g_tls_certificate_gnutls_has_key         (GTlsCertificateGnutls *gnutls);
 
 void                         g_tls_certificate_gnutls_copy            (GTlsCertificateGnutls *gnutls,
                                                                        const gchar           *interaction_id,
diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c
index 065fe87..8469658 100644
--- a/tls/gnutls/gtlsconnection-gnutls.c
+++ b/tls/gnutls/gtlsconnection-gnutls.c
@@ -1159,7 +1159,7 @@ close_internal (GTlsConnectionGnutls  *gnutls,
   /* If we haven't finished the initial handshake yet, there's no
    * reason to finish it just so we can close.
    */
-  if (gnutls->priv->handshaking && !gnutls->priv->ever_handshaked)
+  if (!gnutls->priv->ever_handshaked)
     return TRUE;
 
   if (handshake_in_progress_or_failed (gnutls, blocking, cancellable, error))
diff --git a/tls/gnutls/gtlsserverconnection-gnutls.c b/tls/gnutls/gtlsserverconnection-gnutls.c
index 990946f..9360c3a 100644
--- a/tls/gnutls/gtlsserverconnection-gnutls.c
+++ b/tls/gnutls/gtlsserverconnection-gnutls.c
@@ -51,6 +51,10 @@ static void     g_tls_server_connection_gnutls_finish_handshake (GTlsConnectionG
 								 gboolean               success,
 								 GError               **inout_error);
 
+static void     g_tls_server_connection_gnutls_initable_interface_init (GInitableIface  *iface);
+static gboolean g_tls_server_connection_gnutls_initable_init (GInitable       *initable,
+							      GCancellable    *cancellable,
+							      GError         **error);
 static void g_tls_server_connection_gnutls_server_connection_interface_init (GTlsServerConnectionInterface *iface);
 
 static int g_tls_server_connection_gnutls_retrieve_function (gnutls_session_t             session,
@@ -60,9 +64,14 @@ static int g_tls_server_connection_gnutls_retrieve_function (gnutls_session_t
                                                              int                          pk_algos_length,
                                                              gnutls_retr2_st             *st);
 
+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,
+			 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+						g_tls_server_connection_gnutls_initable_interface_init)
 			 G_IMPLEMENT_INTERFACE (G_TYPE_TLS_SERVER_CONNECTION,
-						g_tls_server_connection_gnutls_server_connection_interface_init))
+						g_tls_server_connection_gnutls_server_connection_interface_init)
+)
 
 struct _GTlsServerConnectionGnutlsPrivate
 {
@@ -93,6 +102,14 @@ g_tls_server_connection_gnutls_server_connection_interface_init (GTlsServerConne
 }
 
 static void
+g_tls_server_connection_gnutls_initable_interface_init (GInitableIface  *iface)
+{
+  g_tls_server_connection_gnutls_parent_initable_iface = g_type_interface_peek_parent (iface);
+
+  iface->init = g_tls_server_connection_gnutls_initable_init;
+}
+
+static void
 g_tls_server_connection_gnutls_init (GTlsServerConnectionGnutls *gnutls)
 {
   gnutls_certificate_credentials_t creds;
@@ -103,6 +120,28 @@ g_tls_server_connection_gnutls_init (GTlsServerConnectionGnutls *gnutls)
   gnutls_certificate_set_retrieve_function (creds, g_tls_server_connection_gnutls_retrieve_function);
 }
 
+static gboolean
+g_tls_server_connection_gnutls_initable_init (GInitable       *initable,
+					      GCancellable    *cancellable,
+					      GError         **error)
+{
+  GTlsCertificate *cert;
+
+  if (!g_tls_server_connection_gnutls_parent_initable_iface->
+      init (initable, cancellable, error))
+    return FALSE;
+
+  cert = g_tls_connection_get_certificate (G_TLS_CONNECTION (initable));
+  if (cert && !g_tls_certificate_gnutls_has_key (G_TLS_CERTIFICATE_GNUTLS (cert)))
+    {
+      g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
+			   _("Certificate has no private key"));
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
 static void
 g_tls_server_connection_gnutls_get_property (GObject    *object,
 					     guint       prop_id,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]