diff --git a/docs/reference/gio/gio-sections-common.txt b/docs/reference/gio/gio-sections-common.txt index ece7d5db1..9cdc4ba66 100644 --- a/docs/reference/gio/gio-sections-common.txt +++ b/docs/reference/gio/gio-sections-common.txt @@ -3667,16 +3667,19 @@ GTlsChannelBindingError GTlsAuthenticationMode GTlsCertificateFlags +GTlsProtocolVersion G_TYPE_TLS_AUTHENTICATION_MODE G_TYPE_TLS_CERTIFICATE_FLAGS G_TYPE_TLS_CHANNEL_BINDING_ERROR G_TYPE_TLS_ERROR +G_TYPE_TLS_PROTOCOL_VERSION g_tls_authentication_mode_get_type g_tls_certificate_flags_get_type g_tls_channel_binding_error_get_type g_tls_channel_binding_error_quark g_tls_error_get_type +g_tls_protocol_version_get_type
@@ -3758,6 +3761,8 @@ g_tls_connection_get_database g_tls_connection_set_database g_tls_connection_get_interaction g_tls_connection_set_interaction +g_tls_connection_get_protocol_version +g_tls_connection_get_ciphersuite_name g_tls_connection_handshake g_tls_connection_handshake_async @@ -3952,6 +3957,8 @@ g_dtls_connection_get_database g_dtls_connection_set_database g_dtls_connection_get_interaction g_dtls_connection_set_interaction +g_dtls_connection_get_protocol_version +g_dtls_connection_get_ciphersuite_name g_dtls_connection_handshake g_dtls_connection_handshake_async diff --git a/gio/gdtlsconnection.c b/gio/gdtlsconnection.c index 136e317b1..880d87d2c 100644 --- a/gio/gdtlsconnection.c +++ b/gio/gdtlsconnection.c @@ -88,6 +88,8 @@ enum { PROP_CERTIFICATE, PROP_PEER_CERTIFICATE, PROP_PEER_CERTIFICATE_ERRORS, + PROP_PROTOCOL_VERSION, + PROP_CIPHERSUITE_NAME, }; static void @@ -263,6 +265,37 @@ g_dtls_connection_default_init (GDtlsConnectionInterface *iface) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + /** + * GDtlsConnection:protocol-version: + * + * The DTLS protocol version in use. See g_dtls_connection_get_protocol_version(). + * + * Since: 2.70 + */ + g_object_interface_install_property (iface, + g_param_spec_enum ("protocol-version", + P_("Protocol Version"), + P_("DTLS protocol version negotiated for this connection"), + G_TYPE_TLS_PROTOCOL_VERSION, + G_TLS_PROTOCOL_VERSION_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GDtlsConnection:ciphersuite-name: (nullable) + * + * The name of the DTLS ciphersuite in use. See g_dtls_connection_get_ciphersuite_name(). + * + * Since: 2.70 + */ + g_object_interface_install_property (iface, + g_param_spec_string ("ciphersuite-name", + P_("Ciphersuite Name"), + P_("Name of ciphersuite negotiated for this connection"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /** * GDtlsConnection::accept-certificate: * @conn: a #GDtlsConnection @@ -1123,3 +1156,66 @@ g_dtls_connection_get_channel_binding_data (GDtlsConnection *conn, return iface->get_binding_data (conn, type, data, error); } + +/** + * g_dtls_connection_get_protocol_version: + * @conn: a #GDTlsConnection + * + * Returns the current DTLS protocol version, which may be + * %G_TLS_PROTOCOL_VERSION_UNKNOWN if the connection has not handshaked, or + * has been closed, or if the TLS backend has implemented a protocol version + * that is not a recognized #GTlsProtocolVersion. + * + * Returns: The current DTLS protocol version + * + * Since: 2.70 + */ +GTlsProtocolVersion +g_dtls_connection_get_protocol_version (GDtlsConnection *conn) +{ + GTlsProtocolVersion protocol_version; + GEnumClass *enum_class; + GEnumValue *enum_value; + + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), G_TLS_PROTOCOL_VERSION_UNKNOWN); + + g_object_get (G_OBJECT (conn), + "protocol-version", &protocol_version, + NULL); + + /* Convert unknown values to G_TLS_PROTOCOL_VERSION_UNKNOWN. */ + enum_class = g_type_class_peek_static (G_TYPE_TLS_PROTOCOL_VERSION); + enum_value = g_enum_get_value (enum_class, protocol_version); + return enum_value ? protocol_version : G_TLS_PROTOCOL_VERSION_UNKNOWN; +} + +/** + * g_dtls_connection_get_ciphersuite_name: + * @conn: a #GDTlsConnection + * + * Returns the name of the current DTLS ciphersuite, or %NULL if the + * connection has not handshaked or has been closed. Beware that the TLS + * backend may use any of multiple different naming conventions, because + * OpenSSL and GnuTLS have their own ciphersuite naming conventions that + * are different from each other and different from the standard, IANA- + * registered ciphersuite names. The ciphersuite name is intended to be + * displayed to the user for informative purposes only, and parsing it + * is not recommended. + * + * Returns: (nullable): The name of the current DTLS ciphersuite, or %NULL + * + * Since: 2.70 + */ +gchar * +g_dtls_connection_get_ciphersuite_name (GDtlsConnection *conn) +{ + gchar *ciphersuite_name; + + g_return_val_if_fail (G_IS_DTLS_CONNECTION (conn), NULL); + + g_object_get (G_OBJECT (conn), + "ciphersuite-name", &ciphersuite_name, + NULL); + + return g_steal_pointer (&ciphersuite_name); +} diff --git a/gio/gdtlsconnection.h b/gio/gdtlsconnection.h index e73cf1459..45a16f50a 100644 --- a/gio/gdtlsconnection.h +++ b/gio/gdtlsconnection.h @@ -216,6 +216,12 @@ gboolean g_dtls_connection_get_channel_binding_data (GDtlsConnec GError **error); G_GNUC_END_IGNORE_DEPRECATIONS +GLIB_AVAILABLE_IN_2_70 +GTlsProtocolVersion g_dtls_connection_get_protocol_version (GDtlsConnection *conn); + +GLIB_AVAILABLE_IN_2_70 +gchar * g_dtls_connection_get_ciphersuite_name (GDtlsConnection *conn); + G_END_DECLS #endif /* __G_DTLS_CONNECTION_H__ */ diff --git a/gio/gioenums.h b/gio/gioenums.h index c2e3d33ae..d81ada416 100644 --- a/gio/gioenums.h +++ b/gio/gioenums.h @@ -1825,6 +1825,40 @@ typedef enum { G_TLS_CERTIFICATE_REQUEST_NONE = 0 } GTlsCertificateRequestFlags; +/** + * GTlsProtocolVersion: + * @G_TLS_PROTOCOL_VERSION_UNKNOWN: No protocol version or unknown protocol version + * @G_TLS_PROTOCOL_VERSION_SSL_3_0: SSL 3.0, which is insecure and should not be used + * @G_TLS_PROTOCOL_VERSION_TLS_1_0: TLS 1.0, which is insecure and should not be used + * @G_TLS_PROTOCOL_VERSION_TLS_1_1: TLS 1.1, which is insecure and should not be used + * @G_TLS_PROTOCOL_VERSION_TLS_1_2: TLS 1.2, defined by [RFC 5246](https://datatracker.ietf.org/doc/html/rfc5246) + * @G_TLS_PROTOCOL_VERSION_TLS_1_3: TLS 1.3, defined by [RFC 8446](https://datatracker.ietf.org/doc/html/rfc8446) + * @G_TLS_PROTOCOL_VERSION_DTLS_1_0: DTLS 1.0, which is insecure and should not be used + * @G_TLS_PROTOCOL_VERSION_DTLS_1_2: DTLS 1.2, defined by [RFC 6347](https://datatracker.ietf.org/doc/html/rfc6347) + * + * The TLS or DTLS protocol version used by a #GTlsConnection or + * #GDtlsConnection. The integer values of these versions are sequential + * to ensure newer known protocol versions compare greater than older + * known versions. Any known DTLS protocol version will compare greater + * than any SSL or TLS protocol version. The protocol version may be + * %G_TLS_PROTOCOL_VERSION_UNKNOWN if the TLS backend supports a newer + * protocol version that GLib does not yet know about. This means that + * it's possible for an unknown DTLS protocol version to compare less + * than the TLS protocol versions. + * + * Since: 2.70 + */ +typedef enum { + G_TLS_PROTOCOL_VERSION_UNKNOWN = 0, + G_TLS_PROTOCOL_VERSION_SSL_3_0 = 1, + G_TLS_PROTOCOL_VERSION_TLS_1_0 = 2, + G_TLS_PROTOCOL_VERSION_TLS_1_1 = 3, + G_TLS_PROTOCOL_VERSION_TLS_1_2 = 4, + G_TLS_PROTOCOL_VERSION_TLS_1_3 = 5, + G_TLS_PROTOCOL_VERSION_DTLS_1_0 = 201, + G_TLS_PROTOCOL_VERSION_DTLS_1_2 = 202, +} GTlsProtocolVersion; + /** * GIOModuleScopeFlags: * @G_IO_MODULE_SCOPE_NONE: No module scan flags diff --git a/gio/gtlsconnection.c b/gio/gtlsconnection.c index 5654ca9ee..3bd37ae97 100644 --- a/gio/gtlsconnection.c +++ b/gio/gtlsconnection.c @@ -93,6 +93,8 @@ enum { PROP_PEER_CERTIFICATE_ERRORS, PROP_ADVERTISED_PROTOCOLS, PROP_NEGOTIATED_PROTOCOL, + PROP_PROTOCOL_VERSION, + PROP_CIPHERSUITE_NAME, }; static void @@ -295,6 +297,37 @@ g_tls_connection_class_init (GTlsConnectionClass *klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + /** + * GTlsConnection:protocol-version: + * + * The TLS protocol version in use. See g_tls_connection_get_protocol_version(). + * + * Since: 2.70 + */ + g_object_class_install_property (gobject_class, PROP_PROTOCOL_VERSION, + g_param_spec_enum ("protocol-version", + P_("Protocol Version"), + P_("TLS protocol version negotiated for this connection"), + G_TYPE_TLS_PROTOCOL_VERSION, + G_TLS_PROTOCOL_VERSION_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * GTlsConnection:ciphersuite-name: (nullable) + * + * The name of the TLS ciphersuite in use. See g_tls_connection_get_ciphersuite_name(). + * + * Since: 2.70 + */ + g_object_class_install_property (gobject_class, PROP_CIPHERSUITE_NAME, + g_param_spec_string ("ciphersuite-name", + P_("Ciphersuite Name"), + P_("Name of ciphersuite negotiated for this connection"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /** * GTlsConnection::accept-certificate: * @conn: a #GTlsConnection @@ -1028,6 +1061,69 @@ g_tls_connection_handshake_finish (GTlsConnection *conn, return G_TLS_CONNECTION_GET_CLASS (conn)->handshake_finish (conn, result, error); } +/** + * g_tls_connection_get_protocol_version: + * @conn: a #GTlsConnection + * + * Returns the current TLS protocol version, which may be + * %G_TLS_PROTOCOL_VERSION_UNKNOWN if the connection has not handshaked, or + * has been closed, or if the TLS backend has implemented a protocol version + * that is not a recognized #GTlsProtocolVersion. + * + * Returns: The current TLS protocol version + * + * Since: 2.70 + */ +GTlsProtocolVersion +g_tls_connection_get_protocol_version (GTlsConnection *conn) +{ + GTlsProtocolVersion protocol_version; + GEnumClass *enum_class; + GEnumValue *enum_value; + + g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), G_TLS_PROTOCOL_VERSION_UNKNOWN); + + g_object_get (G_OBJECT (conn), + "protocol-version", &protocol_version, + NULL); + + /* Convert unknown values to G_TLS_PROTOCOL_VERSION_UNKNOWN. */ + enum_class = g_type_class_peek_static (G_TYPE_TLS_PROTOCOL_VERSION); + enum_value = g_enum_get_value (enum_class, protocol_version); + return enum_value ? protocol_version : G_TLS_PROTOCOL_VERSION_UNKNOWN; +} + +/** + * g_tls_connection_get_ciphersuite_name: + * @conn: a #GTlsConnection + * + * Returns the name of the current TLS ciphersuite, or %NULL if the + * connection has not handshaked or has been closed. Beware that the TLS + * backend may use any of multiple different naming conventions, because + * OpenSSL and GnuTLS have their own ciphersuite naming conventions that + * are different from each other and different from the standard, IANA- + * registered ciphersuite names. The ciphersuite name is intended to be + * displayed to the user for informative purposes only, and parsing it + * is not recommended. + * + * Returns: (nullable): The name of the current TLS ciphersuite, or %NULL + * + * Since: 2.70 + */ +gchar * +g_tls_connection_get_ciphersuite_name (GTlsConnection *conn) +{ + gchar *ciphersuite_name; + + g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), NULL); + + g_object_get (G_OBJECT (conn), + "ciphersuite-name", &ciphersuite_name, + NULL); + + return g_steal_pointer (&ciphersuite_name); +} + /** * g_tls_error_quark: * diff --git a/gio/gtlsconnection.h b/gio/gtlsconnection.h index 037222733..a40a253a6 100644 --- a/gio/gtlsconnection.h +++ b/gio/gtlsconnection.h @@ -155,6 +155,12 @@ gboolean g_tls_connection_handshake_finish (GTlsConnecti GAsyncResult *result, GError **error); +GLIB_AVAILABLE_IN_2_70 +GTlsProtocolVersion g_tls_connection_get_protocol_version (GTlsConnection *conn); + +GLIB_AVAILABLE_IN_2_70 +gchar * g_tls_connection_get_ciphersuite_name (GTlsConnection *conn); + /** * G_TLS_ERROR: *