summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2010-10-24 11:49:45 -0400
committerRuslan N. Marchenko <me@ruff.mobi>2020-05-09 15:51:23 +0200
commit4462b5e7cac3d3ee66fd8ea403bcbe8643f3d441 (patch)
tree7803dd2eea75659e21114c4810c1ce4211e629ea
parentdae7ccae08d5f4f2ee612e0122befb1d2e578f99 (diff)
wocky-tls: specify peername at session creation time
This is how gio TLS does it, among other reasons because it lets you use the SNI extension to tell the server which certificate it should present. https://bugs.freedesktop.org/show_bug.cgi?id=31447
-rw-r--r--tests/wocky-tls-test.c2
-rw-r--r--wocky/wocky-tls-connector.c8
-rw-r--r--wocky/wocky-tls-handler.c16
-rw-r--r--wocky/wocky-tls-handler.h2
-rw-r--r--wocky/wocky-tls.c54
-rw-r--r--wocky/wocky-tls.h4
-rw-r--r--wocky/wocky.h6
7 files changed, 62 insertions, 30 deletions
diff --git a/tests/wocky-tls-test.c b/tests/wocky-tls-test.c
index 9412631..455c4a2 100644
--- a/tests/wocky-tls-test.c
+++ b/tests/wocky-tls-test.c
@@ -261,7 +261,7 @@ test_tls_handshake_rw (void)
{
ssl_test_t ssl_test = { NULL, } ;
test_data_t *test = setup_test ();
- WockyTLSSession *client = wocky_tls_session_new (test->stream->stream0);
+ WockyTLSSession *client = wocky_tls_session_new (test->stream->stream0, NULL);
WockyTLSSession *server = wocky_tls_session_server_new (
test->stream->stream1, 1024, TLS_SERVER_KEY_FILE, TLS_SERVER_CRT_FILE);
gsize expected = TEST_SSL_DATA_LEN * 5;
diff --git a/wocky/wocky-tls-connector.c b/wocky/wocky-tls-connector.c
index 5fa1fda..58e1cb6 100644
--- a/wocky/wocky-tls-connector.c
+++ b/wocky/wocky-tls-connector.c
@@ -256,7 +256,8 @@ do_handshake (WockyTLSConnector *self)
g_object_get (self->priv->connection, "base-stream", &base_stream, NULL);
g_assert (base_stream != NULL);
- self->priv->session = wocky_tls_session_new (base_stream);
+ self->priv->session = wocky_tls_session_new (base_stream,
+ self->priv->peername);
g_object_unref (base_stream);
@@ -337,7 +338,7 @@ session_handshake_cb (GObject *source,
g_object_unref (tls_conn);
wocky_tls_handler_verify_async (self->priv->handler,
- self->priv->session, self->priv->peername,
+ self->priv->session,
self->priv->extra_identities, tls_handler_verify_async_cb, self);
}
@@ -388,7 +389,8 @@ starttls_recv_cb (GObject *source,
g_object_get (self->priv->connection, "base-stream", &base_stream, NULL);
g_assert (base_stream != NULL);
- self->priv->session = wocky_tls_session_new (base_stream);
+ self->priv->session = wocky_tls_session_new (base_stream,
+ self->priv->peername);
g_object_unref (base_stream);
diff --git a/wocky/wocky-tls-handler.c b/wocky/wocky-tls-handler.c
index b3ff78f..00e813e 100644
--- a/wocky/wocky-tls-handler.c
+++ b/wocky/wocky-tls-handler.c
@@ -30,7 +30,6 @@
static void
real_verify_async (WockyTLSHandler *self,
WockyTLSSession *tls_session,
- const gchar *peername,
GStrv extra_identities,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -153,7 +152,6 @@ wocky_tls_handler_init (WockyTLSHandler *self)
static void
real_verify_async (WockyTLSHandler *self,
WockyTLSSession *tls_session,
- const gchar *peername,
GStrv extra_identities,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -161,7 +159,7 @@ real_verify_async (WockyTLSHandler *self,
GSimpleAsyncResult *result;
glong flags = WOCKY_TLS_VERIFY_NORMAL;
WockyTLSCertStatus status = WOCKY_TLS_CERT_UNKNOWN_ERROR;
- const gchar *verify_peername = NULL;
+ gchar *peername;
GStrv verify_extra_identities = NULL;
result = g_simple_async_result_new (G_OBJECT (self),
@@ -177,14 +175,13 @@ real_verify_async (WockyTLSHandler *self,
}
else
{
- verify_peername = peername;
verify_extra_identities = extra_identities;
}
- DEBUG ("Verifying certificate (peername: %s)",
- (verify_peername == NULL) ? "-" : verify_peername);
+ g_object_get (G_OBJECT (tls_session), "peername", &peername, NULL);
+ DEBUG ("Verifying certificate (peername: %s)", peername);
- wocky_tls_session_verify_peer (tls_session, verify_peername,
+ wocky_tls_session_verify_peer (tls_session,
verify_extra_identities, flags, &status);
if (status != WOCKY_TLS_CERT_OK)
@@ -238,6 +235,7 @@ real_verify_async (WockyTLSHandler *self,
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
+ g_free (peername);
return;
}
else
@@ -252,6 +250,7 @@ real_verify_async (WockyTLSHandler *self,
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
+ g_free (peername);
}
static gboolean
@@ -265,14 +264,13 @@ real_verify_finish (WockyTLSHandler *self,
void
wocky_tls_handler_verify_async (WockyTLSHandler *self,
WockyTLSSession *session,
- const gchar *peername,
GStrv extra_identities,
GAsyncReadyCallback callback,
gpointer user_data)
{
WockyTLSHandlerClass *klass = WOCKY_TLS_HANDLER_GET_CLASS (self);
- klass->verify_async_func (self, session, peername, extra_identities,
+ klass->verify_async_func (self, session, extra_identities,
callback, user_data);
}
diff --git a/wocky/wocky-tls-handler.h b/wocky/wocky-tls-handler.h
index deef6d6..ee0c950 100644
--- a/wocky/wocky-tls-handler.h
+++ b/wocky/wocky-tls-handler.h
@@ -48,7 +48,6 @@ typedef struct _WockyTLSHandlerPrivate WockyTLSHandlerPrivate;
typedef void (*WockyTLSHandlerVerifyAsyncFunc) (WockyTLSHandler *self,
WockyTLSSession *tls_session,
- const gchar *peername,
GStrv extra_identities,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -94,7 +93,6 @@ WockyTLSHandler * wocky_tls_handler_new (gboolean ignore_ssl_errors);
void wocky_tls_handler_verify_async (WockyTLSHandler *self,
WockyTLSSession *tls_session,
- const gchar *peername,
GStrv extra_identities,
GAsyncReadyCallback callback,
gpointer user_data);
diff --git a/wocky/wocky-tls.c b/wocky/wocky-tls.c
index 0fb1264..ef9a6fe 100644
--- a/wocky/wocky-tls.c
+++ b/wocky/wocky-tls.c
@@ -104,6 +104,7 @@ enum
{
PROP_S_NONE,
PROP_S_STREAM,
+ PROP_S_PEERNAME,
PROP_S_SERVER,
PROP_S_DHBITS,
PROP_S_KEYFILE,
@@ -205,6 +206,9 @@ struct _WockyTLSSession
GError *error;
gboolean async;
+ /* tls client support */
+ gchar *peername;
+
/* tls server support */
gboolean server;
gnutls_dh_params_t dh_params;
@@ -777,7 +781,6 @@ cert_names_are_valid (gnutls_x509_crt_t cert)
int
wocky_tls_session_verify_peer (WockyTLSSession *session,
- const gchar *peername,
GStrv extra_identities,
WockyTLSVerificationLevel level,
WockyTLSCertStatus *status)
@@ -855,7 +858,8 @@ wocky_tls_session_verify_peer (WockyTLSSession *session,
/* if we get this far, we have a structurally valid certificate *
* signed by _someone_: check the hostname matches the peername */
- if (peername != NULL || extra_identities != NULL)
+ if ((session->peername != NULL && level != WOCKY_TLS_VERIFY_LENIENT)
+ || extra_identities != NULL)
{
const gnutls_datum_t *peers;
guint n_peers;
@@ -883,9 +887,9 @@ wocky_tls_session_verify_peer (WockyTLSSession *session,
}
else
{
- rval = gnutls_x509_crt_check_hostname (x509, peername);
+ rval = gnutls_x509_crt_check_hostname (x509, session->peername);
DEBUG ("gnutls_x509_crt_check_hostname: %s -> %d",
- peername, rval);
+ session->peername, rval);
}
}
else
@@ -926,14 +930,12 @@ wocky_tls_session_verify_peer (WockyTLSSession *session,
if ((rval = gnutls_openpgp_crt_init (&opgp)) == GNUTLS_E_SUCCESS)
{
gnutls_openpgp_crt_import (opgp, &peers[0], GNUTLS_OPENPGP_FMT_RAW);
- rval = gnutls_openpgp_crt_check_hostname (opgp, peername);
- DEBUG ("gnutls_openpgp_crt_check_hostname: %s -> %d", peername, rval);
- if (peername != NULL)
+ if (session->peername != NULL)
{
- rval = gnutls_openpgp_crt_check_hostname (opgp, peername);
+ rval = gnutls_openpgp_crt_check_hostname (opgp, session->peername);
DEBUG ("gnutls_openpgp_crt_check_hostname: %s -> %d",
- peername, rval);
+ session->peername, rval);
}
else
{
@@ -1570,6 +1572,9 @@ wocky_tls_session_set_property (GObject *object, guint prop_id,
case PROP_S_STREAM:
session->stream = g_value_dup_object (value);
break;
+ case PROP_S_PEERNAME:
+ session->peername = g_value_dup_string (value);
+ break;
case PROP_S_SERVER:
session->server = g_value_get_boolean (value);
break;
@@ -1587,6 +1592,22 @@ wocky_tls_session_set_property (GObject *object, guint prop_id,
}
}
+static void
+wocky_tls_session_get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ WockyTLSSession *session = WOCKY_TLS_SESSION (object);
+
+ switch (prop_id)
+ {
+ case PROP_S_PEERNAME:
+ g_value_set_string (value, session->peername);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
static const char *
tls_options (void)
{
@@ -1705,6 +1726,9 @@ wocky_tls_session_dispose (GObject *object)
{
WockyTLSSession *session = WOCKY_TLS_SESSION (object);
+ g_free (session->peername);
+ session->peername = NULL;
+
g_free (session->key_file);
session->key_file = NULL;
@@ -1720,6 +1744,7 @@ wocky_tls_session_dispose (GObject *object)
static void
wocky_tls_session_class_init (GObjectClass *class)
{
+ class->get_property = wocky_tls_session_get_property;
class->set_property = wocky_tls_session_set_property;
class->constructed = wocky_tls_session_constructed;
class->finalize = wocky_tls_session_finalize;
@@ -1732,6 +1757,13 @@ wocky_tls_session_class_init (GObjectClass *class)
G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
+ g_object_class_install_property (class, PROP_S_PEERNAME,
+ g_param_spec_string ("peername", "peer name",
+ "Peer host/domain name",
+ NULL, G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
+
g_object_class_install_property (class, PROP_S_SERVER,
g_param_spec_boolean ("server", "server",
"whether this is a server",
@@ -1872,10 +1904,12 @@ wocky_tls_connection_class_init (WockyTLSConnectionClass *class)
}
WockyTLSSession *
-wocky_tls_session_new (GIOStream *stream)
+wocky_tls_session_new (GIOStream *stream,
+ const gchar *peername)
{
return g_object_new (WOCKY_TYPE_TLS_SESSION,
"base-stream", stream,
+ "peername", peername,
"server", FALSE, NULL);
}
diff --git a/wocky/wocky-tls.h b/wocky/wocky-tls.h
index a2f72e7..8df3b58 100644
--- a/wocky/wocky-tls.h
+++ b/wocky/wocky-tls.h
@@ -86,7 +86,6 @@ GType wocky_tls_connection_get_type (void);
GType wocky_tls_session_get_type (void);
int wocky_tls_session_verify_peer (WockyTLSSession *session,
- const gchar *peername,
GStrv extra_identities,
WockyTLSVerificationLevel level,
WockyTLSCertStatus *status);
@@ -110,7 +109,8 @@ wocky_tls_session_handshake_finish (WockyTLSSession *session,
void wocky_tls_session_add_ca (WockyTLSSession *session, const gchar *path);
void wocky_tls_session_add_crl (WockyTLSSession *session, const gchar *path);
-WockyTLSSession *wocky_tls_session_new (GIOStream *stream);
+WockyTLSSession *wocky_tls_session_new (GIOStream *stream,
+ const gchar *peername);
WockyTLSSession *wocky_tls_session_server_new (GIOStream *stream,
guint dhbits,
diff --git a/wocky/wocky.h b/wocky/wocky.h
index acb7a60..7bb8580 100644
--- a/wocky/wocky.h
+++ b/wocky/wocky.h
@@ -88,9 +88,9 @@
#include "wocky-xmpp-writer.h"
#undef WOCKY_H_INSIDE
-#define WOCKY_API_VER_0_0 0x0
-#define WOCKY_API_VER_0_1 (G_ENCODE_VERSION(0,1))
-#define WOCKY_API_VERSION WOCKY_API_VER_0_0
+#define WOCKY_API_VER_0_0 0x0
+#define WOCKY_API_VER_0_1 (G_ENCODE_VERSION(0,1))
+#define WOCKY_API_VERSION WOCKY_API_VER_0_1
G_BEGIN_DECLS