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




commit d0f9dfcb11249d16940e960498082486a65603e3
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.

 gio/gdtlsconnection.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gio/gdtlsconnection.h |  6 ++++
 gio/gioenums.h        | 27 +++++++++++++++
 gio/gtlsconnection.c  | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gio/gtlsconnection.h  |  6 ++++
 5 files changed, 231 insertions(+)
---
diff --git a/gio/gdtlsconnection.c b/gio/gdtlsconnection.c
index 4bbc88d7a..fb839a5b1 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_("TLS 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:
+   *
+   * The name of the TLS ciphersuite in use. See g_tls_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 f2f66c875..c45647cff 100644
--- a/gio/gioenums.h
+++ b/gio/gioenums.h
@@ -1816,6 +1816,33 @@ 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
+ * @G_TLS_PROTOCOL_VERSION_TLS_1_3: TLS 1.3, defined by RFC 8446
+ * @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
+ *
+ * The TLS or DTLS protocol version used by a #GTlsConnection or
+ * #GDtlsConnection.
+ *
+ * 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..c245f52c2 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:
+   *
+   * 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]