Commit 52430fb4 authored by Dan Winship's avatar Dan Winship
Browse files

fixup! gnutls: Add support for requesting certificate via GTlsInteraction

https://bugzilla.gnome.org/show_bug.cgi?id=637257
parent 7e57450e
......@@ -61,6 +61,7 @@ struct _GTlsClientConnectionGnutlsPrivate
GBytes *session_id;
gboolean cert_requested;
GError *cert_error;
GPtrArray *accepted_cas;
};
......@@ -137,12 +138,10 @@ g_tls_client_connection_gnutls_finalize (GObject *object)
{
GTlsClientConnectionGnutls *gnutls = G_TLS_CLIENT_CONNECTION_GNUTLS (object);
if (gnutls->priv->server_identity)
g_object_unref (gnutls->priv->server_identity);
if (gnutls->priv->accepted_cas)
g_ptr_array_unref (gnutls->priv->accepted_cas);
if (gnutls->priv->session_id)
g_bytes_unref (gnutls->priv->session_id);
g_clear_object (&gnutls->priv->server_identity);
g_clear_pointer (&gnutls->priv->accepted_cas, g_ptr_array_unref);
g_clear_pointer (&gnutls->priv->session_id, g_bytes_unref);
g_clear_error (&gnutls->priv->cert_error);
G_OBJECT_CLASS (g_tls_client_connection_gnutls_parent_class)->finalize (object);
}
......@@ -262,7 +261,8 @@ g_tls_client_connection_gnutls_retrieve_function (gnutls_session_t s
if (st->ncerts == 0)
{
if (g_tls_connection_gnutls_request_certificate (conn))
g_clear_error (&gnutls->priv->cert_error);
if (g_tls_connection_gnutls_request_certificate (conn, &gnutls->priv->cert_error))
g_tls_connection_gnutls_get_certificate (conn, st);
}
......@@ -313,8 +313,16 @@ g_tls_client_connection_gnutls_finish_handshake (GTlsConnectionGnutls *conn,
gnutls->priv->cert_requested)
{
g_clear_error (inout_error);
g_set_error_literal (inout_error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED,
_("Server required TLS certificate"));
if (gnutls->priv->cert_error)
{
*inout_error = gnutls->priv->cert_error;
gnutls->priv->cert_error = NULL;
}
else
{
g_set_error_literal (inout_error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED,
_("Server required TLS certificate"));
}
}
if (gnutls->priv->session_id)
......
......@@ -1713,32 +1713,22 @@ g_tls_connection_gnutls_initable_iface_init (GInitableIface *iface)
}
gboolean
g_tls_connection_gnutls_request_certificate (GTlsConnectionGnutls *self)
g_tls_connection_gnutls_request_certificate (GTlsConnectionGnutls *self,
GError **error)
{
GTlsInteractionResult res = G_TLS_INTERACTION_UNHANDLED;
GTlsInteraction *interaction;
GTlsConnection *conn;
GError *error = NULL;
g_return_val_if_fail (G_IS_TLS_CONNECTION_GNUTLS (self), FALSE);
conn = G_TLS_CONNECTION (self);
interaction = g_tls_connection_get_interaction (conn);
if (interaction)
{
res = g_tls_interaction_invoke_request_certificate (interaction, conn, 0,
self->priv->read_cancellable, &error);
}
if (error != NULL)
{
/* Propagate the error to the handshake */
if (self->priv->reading && !self->priv->handshake_error)
g_propagate_error (&self->priv->handshake_error, error);
else
g_error_free (error);
}
if (!interaction)
return FALSE;
res = g_tls_interaction_invoke_request_certificate (interaction, conn, 0,
self->priv->read_cancellable, error);
return res != G_TLS_INTERACTION_FAILED;
}
......@@ -50,10 +50,12 @@ GType g_tls_connection_gnutls_get_type (void) G_GNUC_CONST;
gnutls_certificate_credentials_t g_tls_connection_gnutls_get_credentials (GTlsConnectionGnutls *connection);
gnutls_session_t g_tls_connection_gnutls_get_session (GTlsConnectionGnutls *connection);
void g_tls_connection_gnutls_get_certificate (GTlsConnectionGnutls *gnutls,
gnutls_retr2_st *st);
gboolean g_tls_connection_gnutls_request_certificate (GTlsConnectionGnutls *self);
void g_tls_connection_gnutls_get_certificate (GTlsConnectionGnutls *gnutls,
gnutls_retr2_st *st);
gboolean g_tls_connection_gnutls_request_certificate (GTlsConnectionGnutls *gnutls,
GError **error);
gssize g_tls_connection_gnutls_read (GTlsConnectionGnutls *gnutls,
void *buffer,
......
......@@ -603,7 +603,7 @@ test_client_auth_request_cert (TestConnection *test,
GTlsInteraction *interaction;
gboolean cas_changed;
test->database = g_tls_file_database_new (TEST_FILE ("ca-roots.pem"), &error);
test->database = g_tls_file_database_new (tls_test_file_path ("ca-roots.pem"), &error);
g_assert_no_error (error);
g_assert (test->database);
......@@ -616,7 +616,7 @@ test_client_auth_request_cert (TestConnection *test,
g_tls_connection_set_database (G_TLS_CONNECTION (test->client_connection), test->database);
/* Have the interaction return a certificate */
cert = g_tls_certificate_new_from_file (TEST_FILE ("client-and-key.pem"), &error);
cert = g_tls_certificate_new_from_file (tls_test_file_path ("client-and-key.pem"), &error);
g_assert_no_error (error);
interaction = mock_interaction_new_static_certificate (cert);
g_tls_connection_set_interaction (G_TLS_CONNECTION (test->client_connection), interaction);
......@@ -650,10 +650,9 @@ test_client_auth_request_fail (TestConnection *test,
{
GIOStream *connection;
GError *error = NULL;
GTlsCertificate *cert;
GTlsInteraction *interaction;
test->database = g_tls_file_database_new (TEST_FILE ("ca-roots.pem"), &error);
test->database = g_tls_file_database_new (tls_test_file_path ("ca-roots.pem"), &error);
g_assert_no_error (error);
g_assert (test->database);
......@@ -665,9 +664,7 @@ test_client_auth_request_fail (TestConnection *test,
g_tls_connection_set_database (G_TLS_CONNECTION (test->client_connection), test->database);
/* Have the interaction return a certificate */
cert = g_tls_certificate_new_from_file (TEST_FILE ("client-and-key.pem"), &error);
g_assert_no_error (error);
/* Have the interaction return an error */
interaction = mock_interaction_new_static_error (G_FILE_ERROR, G_FILE_ERROR_ACCES, "Request message");
g_tls_connection_set_interaction (G_TLS_CONNECTION (test->client_connection), interaction);
g_object_unref (interaction);
......@@ -683,8 +680,6 @@ test_client_auth_request_fail (TestConnection *test,
g_io_stream_close (test->server_connection, NULL, NULL);
g_io_stream_close (test->client_connection, NULL, NULL);
g_object_unref (cert);
}
static void
......
......@@ -45,6 +45,7 @@ mock_interaction_ask_password_async (GTlsInteraction *interaction,
else
g_tls_password_set_value (password, (const guchar *)self->static_password, -1);
g_task_return_boolean (task, TRUE);
g_object_unref (task);
}
static GTlsInteractionResult
......@@ -103,8 +104,11 @@ mock_interaction_request_certificate_async (GTlsInteraction *interaction,
if (self->static_error)
g_task_return_error (task, g_error_copy (self->static_error));
else
g_tls_connection_set_certificate (connection, self->static_certificate);
g_task_return_boolean (task, TRUE);
{
g_tls_connection_set_certificate (connection, self->static_certificate);
g_task_return_boolean (task, TRUE);
}
g_object_unref (task);
}
static GTlsInteractionResult
......@@ -115,11 +119,8 @@ mock_interaction_request_certificate_finish (GTlsInteraction *interaction,
g_return_val_if_fail (g_task_is_valid (result, interaction),
G_TLS_INTERACTION_UNHANDLED);
if (g_task_had_error (G_TASK (result)))
{
g_task_propagate_boolean (G_TASK (result), error);
return G_TLS_INTERACTION_FAILED;
}
if (!g_task_propagate_boolean (G_TASK (result), error))
return G_TLS_INTERACTION_FAILED;
else
return G_TLS_INTERACTION_HANDLED;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment