[glib/mcatanzaro/tls-info: 26/26] tls: add functions to get protocol version and ciphersuite name




commit ff4894c976c3547c11517828ac6802541666b011
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Wed Apr 28 16:08:00 2021 -0500

    tls: add functions to get protocol version and ciphersuite name
    
    This adds g_tls_connection_get_protocol_version(),
    g_tls_connection_get_ciphersuite_name(), and DTLS variants. This will
    allow populating TLS connection information in the WebKit web inspector.
    
    This is WIP because we found it's not quite possibly to implement
    correctly with GnuTLS. See glib-networking!151.

 docs/reference/gio/gio-sections-common.txt |  7 +++
 gio/gdtlsconnection.c                      | 96 ++++++++++++++++++++++++++++++
 gio/gdtlsconnection.h                      |  6 ++
 gio/gioenums.h                             | 34 +++++++++++
 gio/gtlsconnection.c                       | 96 ++++++++++++++++++++++++++++++
 gio/gtlsconnection.h                       |  6 ++
 6 files changed, 245 insertions(+)
---
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
 <SUBSECTION>
 GTlsAuthenticationMode
 GTlsCertificateFlags
+GTlsProtocolVersion
 <SUBSECTION Standard>
 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
 </SECTION>
 
 <SECTION>
@@ -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
 <SUBSECTION>
 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
 <SUBSECTION>
 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..68cf0bf43 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
+ * 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:
  *


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]