summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libsoup/soup-connection.c4
-rw-r--r--libsoup/soup-message.c9
-rw-r--r--tests/ssl-test.c54
3 files changed, 54 insertions, 13 deletions
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index 8fb9b819..24b084f4 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -1152,7 +1152,7 @@ soup_connection_set_tls_client_certificate (SoupConnection *conn,
{
SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn);
- if (G_IS_TLS_CONNECTION (priv->connection)) {
+ if (G_IS_TLS_CONNECTION (priv->connection) && certificate) {
g_tls_connection_set_certificate (G_TLS_CONNECTION (priv->connection),
certificate);
g_clear_object (&priv->tls_client_cert);
@@ -1163,7 +1163,7 @@ soup_connection_set_tls_client_certificate (SoupConnection *conn,
return;
g_clear_object (&priv->tls_client_cert);
- priv->tls_client_cert = g_object_ref (certificate);
+ priv->tls_client_cert = certificate ? g_object_ref (certificate) : NULL;
}
void
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index 0beae103..0f977816 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -2234,12 +2234,13 @@ soup_message_get_tls_peer_certificate_errors (SoupMessage *msg)
/**
* soup_message_set_tls_client_certificate:
* @msg: a #SoupMessage
- * @certificate: the #GTlsCertificate to set
+ * @certificate: (nullable): the #GTlsCertificate to set, or %NULL
*
* Sets the @certificate to be used by @msg's connection when a
* client certificate is requested during the TLS handshake.
* You can call this as a response to #SoupMessage::request-certificate
- * signal, or before the connection is started.
+ * signal, or before the connection is started. If @certificate is %NULL
+ * the handshake will continue without providing a GTlsCertificate.
* Note that the #GTlsCertificate set by this function will be ignored if
* #SoupSession::tls-interaction is not %NULL.
*/
@@ -2250,7 +2251,7 @@ soup_message_set_tls_client_certificate (SoupMessage *msg,
SoupMessagePrivate *priv;
g_return_if_fail (SOUP_IS_MESSAGE (msg));
- g_return_if_fail (G_IS_TLS_CERTIFICATE (certificate));
+ g_return_if_fail (certificate == NULL || G_IS_TLS_CERTIFICATE (certificate));
priv = soup_message_get_instance_private (msg);
if (priv->pending_tls_cert_request) {
@@ -2271,7 +2272,7 @@ soup_message_set_tls_client_certificate (SoupMessage *msg,
return;
g_clear_object (&priv->tls_client_certificate);
- priv->tls_client_certificate = g_object_ref (certificate);
+ priv->tls_client_certificate = certificate ? g_object_ref (certificate) : NULL;
}
/**
diff --git a/tests/ssl-test.c b/tests/ssl-test.c
index 47d32e26..5b41246a 100644
--- a/tests/ssl-test.c
+++ b/tests/ssl-test.c
@@ -360,6 +360,38 @@ do_tls_interaction_msg_test (gconstpointer data)
g_bytes_unref (body);
g_object_unref (msg);
+ /* Using the wrong certificate fails */
+ wrong_certificate = g_tls_certificate_new_from_files (
+ g_test_get_filename (G_TEST_DIST, "test-cert-2.pem", NULL),
+ g_test_get_filename (G_TEST_DIST, "test-key-2.pem", NULL),
+ NULL
+ );
+ g_assert_nonnull (wrong_certificate);
+ msg = soup_message_new_from_uri ("GET", uri);
+ soup_message_add_flags (msg, SOUP_MESSAGE_NEW_CONNECTION);
+ g_signal_connect (msg, "request-certificate",
+ G_CALLBACK (request_certificate_cb),
+ wrong_certificate);
+ body = soup_test_session_async_send (session, msg, NULL, &error);
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED))
+ g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED);
+ g_assert_null (body);
+ g_clear_error (&error);
+ g_object_unref (msg);
+
+ /* Passing NULL certificate fails */
+ msg = soup_message_new_from_uri ("GET", uri);
+ soup_message_add_flags (msg, SOUP_MESSAGE_NEW_CONNECTION);
+ g_signal_connect (msg, "request-certificate",
+ G_CALLBACK (request_certificate_cb),
+ NULL);
+ body = soup_test_session_async_send (session, msg, NULL, &error);
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED))
+ g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED);
+ g_clear_error (&error);
+ g_bytes_unref (body);
+ g_object_unref (msg);
+
/* request-certificate is not emitted if the certificate is set before the load */
msg = soup_message_new_from_uri ("GET", uri);
soup_message_add_flags (msg, SOUP_MESSAGE_NEW_CONNECTION);
@@ -385,19 +417,27 @@ do_tls_interaction_msg_test (gconstpointer data)
g_object_unref (msg);
/* Using the wrong certificate fails */
- wrong_certificate = g_tls_certificate_new_from_files (
- g_test_get_filename (G_TEST_DIST, "test-cert-2.pem", NULL),
- g_test_get_filename (G_TEST_DIST, "test-key-2.pem", NULL),
- NULL
- );
- g_assert_nonnull (wrong_certificate);
msg = soup_message_new_from_uri ("GET", uri);
soup_message_add_flags (msg, SOUP_MESSAGE_NEW_CONNECTION);
g_signal_connect (msg, "request-certificate",
G_CALLBACK (request_certificate_async_cb),
wrong_certificate);
body = soup_test_session_async_send (session, msg, NULL, &error);
- g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED);
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED))
+ g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED);
+ g_assert_null (body);
+ g_clear_error (&error);
+ g_object_unref (msg);
+
+ /* Passing NULL certificate fails */
+ msg = soup_message_new_from_uri ("GET", uri);
+ soup_message_add_flags (msg, SOUP_MESSAGE_NEW_CONNECTION);
+ g_signal_connect (msg, "request-certificate",
+ G_CALLBACK (request_certificate_async_cb),
+ NULL);
+ body = soup_test_session_async_send (session, msg, NULL, &error);
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED))
+ g_assert_error (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED);
g_assert_null (body);
g_clear_error (&error);
g_object_unref (msg);