[glib: 1/2] tls: expose SAN details on GTlsCertificate




commit 4d3618cbd14c0f494652567084acfeec8f437773
Author: Ross Wollman <ross wollman gmail com>
Date:   Thu Jun 10 00:54:45 2021 +0000

    tls: expose SAN details on GTlsCertificate
    
    This changeset exposes
    
    * `dns-names`
    * `ip-addresses`
    
    on GTlsCertificate provided by the underlying TLS Backend.
    
    See https://gitlab.gnome.org/GNOME/glib-networking/-/merge_requests/165 for the corresponding 
glib-networking changes.
    
    Relates: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2113
    Relates: https://gitlab.gnome.org/GNOME/glib-networking/-/merge_requests/156/diffs
    Relates: https://github.com/microsoft/playwright/issues/6759

 docs/reference/gio/gio-sections-common.txt |  2 +
 gio/gtlscertificate.c                      | 80 ++++++++++++++++++++++++++++++
 gio/gtlscertificate.h                      |  6 +++
 gio/tests/gtesttlsbackend.c                | 16 ++++++
 gio/tests/tls-certificate.c                | 49 ++++++++++++++++++
 5 files changed, 153 insertions(+)
---
diff --git a/docs/reference/gio/gio-sections-common.txt b/docs/reference/gio/gio-sections-common.txt
index 9cdc4ba66..5151a9d75 100644
--- a/docs/reference/gio/gio-sections-common.txt
+++ b/docs/reference/gio/gio-sections-common.txt
@@ -3718,6 +3718,8 @@ g_tls_certificate_new_from_file
 g_tls_certificate_new_from_files
 g_tls_certificate_new_from_pkcs11_uris
 g_tls_certificate_list_new_from_file
+g_tls_certificate_get_dns_names
+g_tls_certificate_get_ip_addresses
 g_tls_certificate_get_issuer
 g_tls_certificate_get_issuer_name
 g_tls_certificate_get_not_valid_before
diff --git a/gio/gtlscertificate.c b/gio/gtlscertificate.c
index 1e01af659..aadc562a6 100644
--- a/gio/gtlscertificate.c
+++ b/gio/gtlscertificate.c
@@ -67,6 +67,8 @@ enum
   PROP_NOT_VALID_AFTER,
   PROP_SUBJECT_NAME,
   PROP_ISSUER_NAME,
+  PROP_DNS_NAMES,
+  PROP_IP_ADDRESSES,
 };
 
 static void
@@ -315,6 +317,38 @@ g_tls_certificate_class_init (GTlsCertificateClass *class)
                                                         NULL,
                                                         G_PARAM_READABLE |
                                                           G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GTlsCertificate:dns-names: (nullable)
+   *
+   * The DNS names from the certificate's Subject Alternative Names (SANs),
+   * %NULL if unavailable.
+   *
+   * Since: 2.70
+   */
+  g_object_class_install_property (gobject_class, PROP_DNS_NAMES,
+                                   g_param_spec_boxed ("dns-names",
+                                                       P_("DNS Names"),
+                                                       P_("DNS Names listed on the cert."),
+                                                       G_TYPE_PTR_ARRAY,
+                                                       G_PARAM_READABLE |
+                                                         G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GTlsCertificate:ip-addresses: (nullable)
+   *
+   * The IP addresses from the certificate's Subject Alternative Names (SANs),
+   * %NULL if unavailable.
+   *
+   * Since: 2.70
+   */
+  g_object_class_install_property (gobject_class, PROP_IP_ADDRESSES,
+                                   g_param_spec_boxed ("ip-addresses",
+                                                       P_("IP Addresses"),
+                                                       P_("IP Addresses listed on the cert."),
+                                                       G_TYPE_PTR_ARRAY,
+                                                       G_PARAM_READABLE |
+                                                         G_PARAM_STATIC_STRINGS));
 }
 
 static GTlsCertificate *
@@ -1033,3 +1067,49 @@ g_tls_certificate_get_issuer_name (GTlsCertificate *cert)
 
   return g_steal_pointer (&issuer_name);
 }
+
+/**
+ * g_tls_certificate_get_dns_names:
+ * @cert: a #GTlsCertificate
+ *
+ * Gets the value of #GTlsCertificate:dns-names.
+ *
+ * Returns: (nullable) (element-type GBytes) (transfer container): A #GPtrArray of
+ * #GBytes elements, or %NULL if it's not available.
+ *
+ * Since: 2.70
+ */
+GPtrArray *
+g_tls_certificate_get_dns_names (GTlsCertificate *cert)
+{
+  GPtrArray *dns_names = NULL;
+
+  g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
+
+  g_object_get (G_OBJECT (cert), "dns-names", &dns_names, NULL);
+
+  return g_steal_pointer (&dns_names);
+}
+
+/**
+ * g_tls_certificate_get_ip_addresses:
+ * @cert: a #GTlsCertificate
+ *
+ * Gets the value of #GTlsCertificate:ip-addresses.
+ *
+ * Returns: (nullable) (element-type GInetAddress) (transfer container): A #GPtrArray
+ * of #GInetAddress elements, or %NULL if it's not available.
+ *
+ * Since: 2.70
+ */
+GPtrArray *
+g_tls_certificate_get_ip_addresses (GTlsCertificate *cert)
+{
+  GPtrArray *ip_addresses = NULL;
+
+  g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
+
+  g_object_get (G_OBJECT (cert), "ip-addresses", &ip_addresses, NULL);
+
+  return g_steal_pointer (&ip_addresses);
+}
diff --git a/gio/gtlscertificate.h b/gio/gtlscertificate.h
index 27307d8a2..3b92b97fc 100644
--- a/gio/gtlscertificate.h
+++ b/gio/gtlscertificate.h
@@ -104,6 +104,12 @@ gchar                *g_tls_certificate_get_subject_name     (GTlsCertificate
 GLIB_AVAILABLE_IN_2_70
 gchar                *g_tls_certificate_get_issuer_name      (GTlsCertificate     *cert);
 
+GLIB_AVAILABLE_IN_2_70
+GPtrArray            *g_tls_certificate_get_dns_names        (GTlsCertificate     *cert);
+
+GLIB_AVAILABLE_IN_2_70
+GPtrArray            *g_tls_certificate_get_ip_addresses     (GTlsCertificate     *cert);
+
 G_END_DECLS
 
 #endif /* __G_TLS_CERTIFICATE_H__ */
diff --git a/gio/tests/gtesttlsbackend.c b/gio/tests/gtesttlsbackend.c
index 869c71673..1e07c1e5e 100644
--- a/gio/tests/gtesttlsbackend.c
+++ b/gio/tests/gtesttlsbackend.c
@@ -114,6 +114,8 @@ enum
   PROP_CERT_NOT_VALID_AFTER,
   PROP_CERT_SUBJECT_NAME,
   PROP_CERT_ISSUER_NAME,
+  PROP_CERT_DNS_NAMES,
+  PROP_CERT_IP_ADDRESSES,
 };
 
 static void g_test_tls_certificate_initable_iface_init (GInitableIface *iface);
@@ -139,6 +141,8 @@ g_test_tls_certificate_get_property (GObject    *object,
                                      GParamSpec *pspec)
 {
   GTestTlsCertificate *cert = (GTestTlsCertificate *) object;
+  GPtrArray *data = NULL;
+  const gchar *dns_name = "a.example.com";
 
   switch (prop_id)
     {
@@ -172,6 +176,16 @@ g_test_tls_certificate_get_property (GObject    *object,
     case PROP_CERT_ISSUER_NAME:
       g_value_set_string (value, "DC=COM,DC=EXAMPLE,OU=Certificate 
Authority,CN=ca.example.com,emailAddress=ca example com");
       break;
+    case PROP_CERT_DNS_NAMES:
+      data = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref);
+      g_ptr_array_add (data, g_bytes_new_static (dns_name, strlen (dns_name)));
+      g_value_take_boxed (value, data);
+      break;
+    case PROP_CERT_IP_ADDRESSES:
+      data = g_ptr_array_new_with_free_func (g_object_unref);
+      g_ptr_array_add (data, g_inet_address_new_from_string ("192.0.2.1"));
+      g_value_take_boxed (value, data);
+      break;
     default:
       g_assert_not_reached ();
       break;
@@ -250,6 +264,8 @@ g_test_tls_certificate_class_init (GTestTlsCertificateClass *test_class)
   g_object_class_override_property (gobject_class, PROP_CERT_NOT_VALID_AFTER, "not-valid-after");
   g_object_class_override_property (gobject_class, PROP_CERT_SUBJECT_NAME, "subject-name");
   g_object_class_override_property (gobject_class, PROP_CERT_ISSUER_NAME, "issuer-name");
+  g_object_class_override_property (gobject_class, PROP_CERT_DNS_NAMES, "dns-names");
+  g_object_class_override_property (gobject_class, PROP_CERT_IP_ADDRESSES, "ip-addresses");
 }
 
 static void
diff --git a/gio/tests/tls-certificate.c b/gio/tests/tls-certificate.c
index 6f68a5ddb..d0a908530 100644
--- a/gio/tests/tls-certificate.c
+++ b/gio/tests/tls-certificate.c
@@ -548,6 +548,51 @@ issuer_name (void)
   g_object_unref (cert);
 }
 
+static void
+dns_names (void)
+{
+  GTlsCertificate *cert;
+  GError *error = NULL;
+  GPtrArray *actual;
+  const gchar *dns_name = "a.example.com";
+  GBytes *expected = g_bytes_new_static (dns_name, strlen (dns_name));
+
+  cert = g_tls_certificate_new_from_pkcs11_uris 
("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", NULL, &error);
+  g_assert_no_error (error);
+  g_assert_nonnull (cert);
+
+  actual = g_tls_certificate_get_dns_names (cert);
+  g_assert_nonnull (actual);
+  g_assert_cmpuint (actual->len, ==, 1);
+  g_assert_true (g_ptr_array_find_with_equal_func (actual, expected, (GEqualFunc)g_bytes_equal, NULL));
+
+  g_ptr_array_free (actual, FALSE);
+  g_bytes_unref (expected);
+  g_object_unref (cert);
+}
+
+static void
+ip_addresses (void)
+{
+  GTlsCertificate *cert;
+  GError *error = NULL;
+  GPtrArray *actual;
+  GInetAddress *expected = g_inet_address_new_from_string ("192.0.2.1");
+
+  cert = g_tls_certificate_new_from_pkcs11_uris 
("pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=ca-bundle.crt", NULL, &error);
+  g_assert_no_error (error);
+  g_assert_nonnull (cert);
+
+  actual = g_tls_certificate_get_ip_addresses (cert);
+  g_assert_nonnull (actual);
+  g_assert_cmpuint (actual->len, ==, 1);
+  g_assert_true (g_ptr_array_find_with_equal_func (actual, expected, (GEqualFunc)g_inet_address_equal, 
NULL));
+
+  g_ptr_array_free (actual, TRUE);
+  g_object_unref (expected);
+  g_object_unref (cert);
+}
+
 int
 main (int   argc,
       char *argv[])
@@ -626,6 +671,10 @@ main (int   argc,
                    subject_name);
   g_test_add_func ("/tls-certificate/issuer-name",
                    issuer_name);
+  g_test_add_func ("/tls-certificate/dns-names",
+                   dns_names);
+  g_test_add_func ("/tls-certificate/ip-addresses",
+                   ip_addresses);
   g_test_add_func ("/tls-certificate/pem-parser-no-sentinel",
                    pem_parser_no_sentinel);
 


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