[libsoup/carlosgc/connection-tls-props] message: add API to get TLS ciphersuite name and protocol version
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup/carlosgc/connection-tls-props] message: add API to get TLS ciphersuite name and protocol version
- Date: Wed, 30 Jun 2021 08:06:42 +0000 (UTC)
commit 555c23ec023a7de00950503e4955d670f50895a6
Author: Carlos Garcia Campos <cgarcia igalia com>
Date: Tue Jun 29 12:38:06 2021 +0200
message: add API to get TLS ciphersuite name and protocol version
docs/reference/libsoup-3.0-sections.txt | 2 +
libsoup/soup-connection.c | 63 +++++++++++++++
libsoup/soup-connection.h | 2 +
libsoup/soup-message.c | 135 ++++++++++++++++++++++++++++++++
libsoup/soup-message.h | 6 ++
tests/ssl-test.c | 8 ++
6 files changed, 216 insertions(+)
---
diff --git a/docs/reference/libsoup-3.0-sections.txt b/docs/reference/libsoup-3.0-sections.txt
index 15bb9b4b..e6b20324 100644
--- a/docs/reference/libsoup-3.0-sections.txt
+++ b/docs/reference/libsoup-3.0-sections.txt
@@ -32,6 +32,8 @@ soup_message_get_connection_id
soup_message_get_remote_address
soup_message_get_tls_peer_certificate
soup_message_get_tls_peer_certificate_errors
+soup_message_get_tls_protocol_version
+soup_message_get_tls_ciphersuite_name
soup_message_set_tls_client_certificate
soup_message_tls_client_certificate_password_request_complete
<SUBSECTION>
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index 3d06a870..df2e1768 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -73,6 +73,8 @@ enum {
PROP_SSL,
PROP_TLS_CERTIFICATE,
PROP_TLS_CERTIFICATE_ERRORS,
+ PROP_TLS_PROTOCOL_VERSION,
+ PROP_TLS_CIPHERSUITE_NAME,
PROP_FORCE_HTTP1,
LAST_PROPERTY
@@ -194,6 +196,12 @@ soup_connection_get_property (GObject *object, guint prop_id,
case PROP_TLS_CERTIFICATE_ERRORS:
g_value_set_flags (value, soup_connection_get_tls_certificate_errors (SOUP_CONNECTION
(object)));
break;
+ case PROP_TLS_PROTOCOL_VERSION:
+ g_value_set_enum (value, soup_connection_get_tls_protocol_version (SOUP_CONNECTION
(object)));
+ break;
+ case PROP_TLS_CIPHERSUITE_NAME:
+ g_value_set_string (value, soup_connection_get_tls_ciphersuite_name (SOUP_CONNECTION
(object)));
+ break;
case PROP_FORCE_HTTP1:
g_value_set_boolean (value, priv->force_http1);
break;
@@ -321,6 +329,21 @@ soup_connection_class_init (SoupConnectionClass *connection_class)
G_TYPE_TLS_CERTIFICATE_FLAGS, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
+ properties[PROP_TLS_PROTOCOL_VERSION] =
+ g_param_spec_enum ("tls-protocol-version",
+ "TLS Protocol Version",
+ "TLS protocol version negotiated for this connection",
+ G_TYPE_TLS_PROTOCOL_VERSION,
+ G_TLS_PROTOCOL_VERSION_UNKNOWN,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
+ properties[PROP_TLS_CIPHERSUITE_NAME] =
+ g_param_spec_string ("tls-ciphersuite-name",
+ "TLS Ciphersuite Name",
+ "Name of TLS ciphersuite negotiated for this connection",
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
properties[PROP_FORCE_HTTP1] =
g_param_spec_boolean ("force-http1",
"Force HTTP 1.x",
@@ -522,6 +545,18 @@ tls_connection_peer_certificate_changed (SoupConnection *conn)
g_object_notify_by_pspec (G_OBJECT (conn), properties[PROP_TLS_CERTIFICATE]);
}
+static void
+tls_connection_protocol_version_changed (SoupConnection *conn)
+{
+ g_object_notify_by_pspec (G_OBJECT (conn), properties[PROP_TLS_PROTOCOL_VERSION]);
+}
+
+static void
+tls_connection_ciphersuite_name_changed (SoupConnection *conn)
+{
+ g_object_notify_by_pspec (G_OBJECT (conn), properties[PROP_TLS_CIPHERSUITE_NAME]);
+}
+
static GTlsClientConnection *
new_tls_connection (SoupConnection *conn,
GSocketConnection *connection,
@@ -564,6 +599,12 @@ new_tls_connection (SoupConnection *conn,
g_signal_connect_object (tls_connection, "notify::peer-certificate",
G_CALLBACK (tls_connection_peer_certificate_changed),
conn, G_CONNECT_SWAPPED);
+ g_signal_connect_object (tls_connection, "notify::protocol-version",
+ G_CALLBACK (tls_connection_protocol_version_changed),
+ conn, G_CONNECT_SWAPPED);
+ g_signal_connect_object (tls_connection, "notify::ciphersuite-name",
+ G_CALLBACK (tls_connection_ciphersuite_name_changed),
+ conn, G_CONNECT_SWAPPED);
return tls_connection;
}
@@ -1146,6 +1187,28 @@ soup_connection_get_tls_certificate_errors (SoupConnection *conn)
return g_tls_connection_get_peer_certificate_errors (G_TLS_CONNECTION (priv->connection));
}
+GTlsProtocolVersion
+soup_connection_get_tls_protocol_version (SoupConnection *conn)
+{
+ SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn);
+
+ if (!G_IS_TLS_CONNECTION (priv->connection))
+ return G_TLS_PROTOCOL_VERSION_UNKNOWN;
+
+ return g_tls_connection_get_protocol_version (G_TLS_CONNECTION (priv->connection));
+}
+
+char *
+soup_connection_get_tls_ciphersuite_name (SoupConnection *conn)
+{
+ SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn);
+
+ if (!G_IS_TLS_CONNECTION (priv->connection))
+ return NULL;
+
+ return g_tls_connection_get_ciphersuite_name (G_TLS_CONNECTION (priv->connection));
+}
+
void
soup_connection_set_tls_client_certificate (SoupConnection *conn,
GTlsCertificate *certificate)
diff --git a/libsoup/soup-connection.h b/libsoup/soup-connection.h
index 6a369a95..9454c9d8 100644
--- a/libsoup/soup-connection.h
+++ b/libsoup/soup-connection.h
@@ -65,6 +65,8 @@ SoupClientMessageIO *soup_connection_setup_message_io (SoupConnection *conn,
GTlsCertificate *soup_connection_get_tls_certificate (SoupConnection *conn);
GTlsCertificateFlags soup_connection_get_tls_certificate_errors (SoupConnection *conn);
+GTlsProtocolVersion soup_connection_get_tls_protocol_version (SoupConnection *conn);
+char *soup_connection_get_tls_ciphersuite_name (SoupConnection *conn);
void soup_connection_request_tls_certificate (SoupConnection *conn,
GTlsConnection *connection,
GTask *task);
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index 41aed806..2b9cbdb5 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -89,6 +89,8 @@ typedef struct {
GTlsCertificate *tls_peer_certificate;
GTlsCertificateFlags tls_peer_certificate_errors;
+ GTlsProtocolVersion tls_protocol_version;
+ char *tls_ciphersuite_name;
GTlsCertificate *tls_client_certificate;
GTask *pending_tls_cert_request;
@@ -151,6 +153,8 @@ enum {
PROP_RESPONSE_HEADERS,
PROP_TLS_PEER_CERTIFICATE,
PROP_TLS_PEER_CERTIFICATE_ERRORS,
+ PROP_TLS_PROTOCOL_VERSION,
+ PROP_TLS_CIPHERSUITE_NAME,
PROP_REMOTE_ADDRESS,
PROP_PRIORITY,
PROP_SITE_FOR_COOKIES,
@@ -198,6 +202,7 @@ soup_message_finalize (GObject *object)
g_clear_pointer (&priv->first_party, g_uri_unref);
g_clear_pointer (&priv->site_for_cookies, g_uri_unref);
g_clear_pointer (&priv->metrics, soup_message_metrics_free);
+ g_clear_pointer (&priv->tls_ciphersuite_name, g_free);
g_clear_object (&priv->auth);
g_clear_object (&priv->proxy_auth);
@@ -301,6 +306,12 @@ soup_message_get_property (GObject *object, guint prop_id,
case PROP_TLS_PEER_CERTIFICATE_ERRORS:
g_value_set_flags (value, priv->tls_peer_certificate_errors);
break;
+ case PROP_TLS_PROTOCOL_VERSION:
+ g_value_set_enum (value, priv->tls_protocol_version);
+ break;
+ case PROP_TLS_CIPHERSUITE_NAME:
+ g_value_set_string (value, priv->tls_ciphersuite_name);
+ break;
case PROP_REMOTE_ADDRESS:
g_value_set_object (value, priv->remote_address);
break;
@@ -814,6 +825,33 @@ soup_message_class_init (SoupMessageClass *message_class)
G_TYPE_TLS_CERTIFICATE_FLAGS, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
+ /**
+ * SoupMessage:tls-protocol-version:
+ *
+ * The TLS protocol version negotiated for the message connection.
+ */
+ properties[PROP_TLS_PROTOCOL_VERSION] =
+ g_param_spec_enum ("tls-protocol-version",
+ "TLS Protocol Version",
+ "TLS protocol version negotiated for this connection",
+ G_TYPE_TLS_PROTOCOL_VERSION,
+ G_TLS_PROTOCOL_VERSION_UNKNOWN,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
+
+ /**
+ * SoupMessage:tls-ciphersuite-name:
+ *
+ * The Name of TLS ciphersuite negotiated for this message connection.
+ */
+ properties[PROP_TLS_CIPHERSUITE_NAME] =
+ g_param_spec_string ("tls-ciphersuite-name",
+ "TLS Ciphersuite Name",
+ "Name of TLS ciphersuite negotiated for this connection",
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
+
/**
* SoupMessage:remote-address:
*
@@ -1396,6 +1434,35 @@ soup_message_set_tls_peer_certificate (SoupMessage *msg,
g_object_notify_by_pspec (G_OBJECT (msg), properties[PROP_TLS_PEER_CERTIFICATE_ERRORS]);
}
+static void
+soup_message_set_tls_protocol_version (SoupMessage *msg,
+ GTlsProtocolVersion version)
+{
+ SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+
+ if (priv->tls_protocol_version == version)
+ return;
+
+ priv->tls_protocol_version = version;
+ g_object_notify_by_pspec (G_OBJECT (msg), properties[PROP_TLS_PROTOCOL_VERSION]);
+}
+
+static void
+soup_message_set_tls_ciphersuite_name (SoupMessage *msg,
+ char *name)
+{
+ SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+
+ if (g_strcmp0 (priv->tls_ciphersuite_name, name) == 0) {
+ g_free (name);
+ return;
+ }
+
+ g_clear_pointer (&priv->tls_ciphersuite_name, g_free);
+ priv->tls_ciphersuite_name = name;
+ g_object_notify_by_pspec (G_OBJECT (msg), properties[PROP_TLS_CIPHERSUITE_NAME]);
+}
+
static void
soup_message_set_remote_address (SoupMessage *msg,
GSocketAddress *address)
@@ -1533,6 +1600,22 @@ re_emit_tls_certificate_changed (SoupMessage *msg,
soup_connection_get_tls_certificate_errors (conn));
}
+static void
+connection_tls_protocol_version_changed (SoupMessage *msg,
+ GParamSpec *pspec,
+ SoupConnection *conn)
+{
+ soup_message_set_tls_protocol_version (msg, soup_connection_get_tls_protocol_version (conn));
+}
+
+static void
+connection_tls_ciphersuite_name_changed (SoupMessage *msg,
+ GParamSpec *pspec,
+ SoupConnection *conn)
+{
+ soup_message_set_tls_ciphersuite_name (msg, soup_connection_get_tls_ciphersuite_name (conn));
+}
+
static void
connection_remote_address_changed (SoupMessage *msg,
GParamSpec *pspec,
@@ -1575,6 +1658,8 @@ soup_message_set_connection (SoupMessage *msg,
soup_message_set_tls_peer_certificate (msg,
soup_connection_get_tls_certificate (priv->connection),
soup_connection_get_tls_certificate_errors
(priv->connection));
+ soup_message_set_tls_protocol_version (msg, soup_connection_get_tls_protocol_version (conn));
+ soup_message_set_tls_ciphersuite_name (msg, soup_connection_get_tls_ciphersuite_name (conn));
soup_message_set_remote_address (msg, soup_connection_get_remote_address (priv->connection));
if (priv->tls_client_certificate) {
@@ -1598,6 +1683,12 @@ soup_message_set_connection (SoupMessage *msg,
g_signal_connect_object (priv->connection, "notify::tls-certificate",
G_CALLBACK (re_emit_tls_certificate_changed),
msg, G_CONNECT_SWAPPED);
+ g_signal_connect_object (priv->connection, "notify::tls-protocol-version",
+ G_CALLBACK (connection_tls_protocol_version_changed),
+ msg, G_CONNECT_SWAPPED);
+ g_signal_connect_object (priv->connection, "notify::tls-ciphersuite-name",
+ G_CALLBACK (connection_tls_ciphersuite_name_changed),
+ msg, G_CONNECT_SWAPPED);
g_signal_connect_object (priv->connection, "notify::remote-address",
G_CALLBACK (connection_remote_address_changed),
msg, G_CONNECT_SWAPPED);
@@ -1699,6 +1790,8 @@ soup_message_cleanup_response (SoupMessage *msg)
if (!priv->connection) {
soup_message_set_tls_peer_certificate (msg, NULL, 0);
+ soup_message_set_tls_protocol_version (msg, G_TLS_PROTOCOL_VERSION_UNKNOWN);
+ soup_message_set_tls_ciphersuite_name (msg, NULL);
soup_message_set_remote_address (msg, NULL);
priv->last_connection_id = 0;
}
@@ -2328,6 +2421,48 @@ soup_message_get_tls_peer_certificate_errors (SoupMessage *msg)
return priv->tls_peer_certificate_errors;
}
+/**
+ * soup_message_get_tls_protocol_version:
+ * @msg: a #SoupMessage
+ *
+ * Gets the TLS protocol version negotiated for @msg's connection.
+ * If the message connection is not SSL, %G_TLS_PROTOCOL_VERSION_UNKNOWN is returned.
+ *
+ * Returns: a #GTlsProtocolVersion
+ */
+GTlsProtocolVersion
+soup_message_get_tls_protocol_version (SoupMessage *msg)
+{
+ SoupMessagePrivate *priv;
+
+ g_return_val_if_fail (SOUP_IS_MESSAGE (msg), G_TLS_PROTOCOL_VERSION_UNKNOWN);
+
+ priv = soup_message_get_instance_private (msg);
+
+ return priv->tls_protocol_version;
+}
+
+/**
+ * soup_message_get_tls_ciphersuite_name:
+ * @msg: a #SoupMessage
+ *
+ * Gets the name of the TLS ciphersuite negotiated for @msg's connection.
+ *
+ * Returns: (transfer none): the name of the TLS ciphersuite,
+ * or %NULL if @msg's connection is not SSL.
+ */
+const char *
+soup_message_get_tls_ciphersuite_name (SoupMessage *msg)
+{
+ SoupMessagePrivate *priv;
+
+ g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
+
+ priv = soup_message_get_instance_private (msg);
+
+ return priv->tls_ciphersuite_name;
+}
+
/**
* soup_message_set_tls_client_certificate:
* @msg: a #SoupMessage
diff --git a/libsoup/soup-message.h b/libsoup/soup-message.h
index 9208ec24..69b2088f 100644
--- a/libsoup/soup-message.h
+++ b/libsoup/soup-message.h
@@ -106,6 +106,12 @@ GTlsCertificate *soup_message_get_tls_peer_certificate
SOUP_AVAILABLE_IN_ALL
GTlsCertificateFlags soup_message_get_tls_peer_certificate_errors (SoupMessage *msg);
+SOUP_AVAILABLE_IN_ALL
+GTlsProtocolVersion soup_message_get_tls_protocol_version (SoupMessage *msg);
+
+SOUP_AVAILABLE_IN_ALL
+const char *soup_message_get_tls_ciphersuite_name (SoupMessage *msg);
+
SOUP_AVAILABLE_IN_ALL
void soup_message_set_tls_client_certificate (SoupMessage *msg,
GTlsCertificate
*certificate);
diff --git a/tests/ssl-test.c b/tests/ssl-test.c
index 08563515..ecd0e63e 100644
--- a/tests/ssl-test.c
+++ b/tests/ssl-test.c
@@ -72,6 +72,14 @@ do_strictness_test (gconstpointer data)
g_assert_nonnull (soup_message_get_tls_peer_certificate (msg));
flags = soup_message_get_tls_peer_certificate_errors (msg);
+ if (test->expected_status == SOUP_STATUS_OK) {
+ g_assert_cmpuint (soup_message_get_tls_protocol_version (msg), ==,
G_TLS_PROTOCOL_VERSION_TLS_1_3);
+ g_assert_cmpstr (soup_message_get_tls_ciphersuite_name (msg), ==, "TLS_AES-256-GCM_SHA384");
+ } else {
+ g_assert_cmpuint (soup_message_get_tls_protocol_version (msg), ==,
G_TLS_PROTOCOL_VERSION_UNKNOWN);
+ g_assert_null (soup_message_get_tls_ciphersuite_name (msg));
+ }
+
g_test_bug ("665182");
if (test->with_ca_list && !error)
g_assert_cmpuint (flags, ==, 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]