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




commit a17c28790ac4111878961f6b0973068deebe9fcc
Author: Ross A. Wollman <ross wollman gmail com>
Date:   Wed May 26 07:59:37 2021 +0000

    tls: expose cert details on GTlsCertificate
    
    This changeset exposes
    
    * `not-valid-before`
    * `not-valid-after`
    * `subject-name`
    * `issuer-name`
    
    on GTlsCertificate provided by the underlying TLS Backend.
    
    In order to make use of these changes,
    see the related [glib-networking MR][glib-networking].
    
    This change aims to help populate more of the [`Certificate`][wk-cert]
    info in the WebKit Inspector Protocol on Linux.
    
    This changeset stems from work in Microsoft Playwright to [add more info
    into its HAR capture][pw] generated from the Inspector Protocol events
    and will bring feature parity across WebKit platforms.
    
    [wk-cert]: 
https://github.com/WebKit/WebKit/blob/8afe31a018b11741abdf9b4d5bb973d7c1d9ff05/Source/JavaScriptCore/inspector/protocol/Security.json
    [pw]: https://github.com/microsoft/playwright/pull/6631
    [glib-networking]: https://gitlab.gnome.org/GNOME/glib-networking/-/merge_requests/156

 docs/reference/gio/gio-sections-common.txt |   4 +
 gio/gtlscertificate.c                      | 156 +++++++++++++++++++++++++++++
 gio/gtlscertificate.h                      |  12 +++
 gio/tests/gtesttlsbackend.c                |  20 ++++
 gio/tests/tls-certificate.c                |  94 +++++++++++++++++
 5 files changed, 286 insertions(+)
---
diff --git a/docs/reference/gio/gio-sections-common.txt b/docs/reference/gio/gio-sections-common.txt
index e38971c12..ece7d5db1 100644
--- a/docs/reference/gio/gio-sections-common.txt
+++ b/docs/reference/gio/gio-sections-common.txt
@@ -3716,6 +3716,10 @@ g_tls_certificate_new_from_files
 g_tls_certificate_new_from_pkcs11_uris
 g_tls_certificate_list_new_from_file
 g_tls_certificate_get_issuer
+g_tls_certificate_get_issuer_name
+g_tls_certificate_get_not_valid_before
+g_tls_certificate_get_not_valid_after
+g_tls_certificate_get_subject_name
 g_tls_certificate_verify
 g_tls_certificate_is_same
 <SUBSECTION Standard>
diff --git a/gio/gtlscertificate.c b/gio/gtlscertificate.c
index ae9e88016..c46ad107c 100644
--- a/gio/gtlscertificate.c
+++ b/gio/gtlscertificate.c
@@ -63,6 +63,10 @@ enum
   PROP_ISSUER,
   PROP_PKCS11_URI,
   PROP_PRIVATE_KEY_PKCS11_URI,
+  PROP_NOT_VALID_BEFORE,
+  PROP_NOT_VALID_AFTER,
+  PROP_SUBJECT_NAME,
+  PROP_ISSUER_NAME,
 };
 
 static void
@@ -248,6 +252,69 @@ g_tls_certificate_class_init (GTlsCertificateClass *class)
                                                         G_PARAM_READWRITE |
                                                           G_PARAM_CONSTRUCT_ONLY |
                                                           G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GTlsCertificate:not-valid-before: (nullable)
+   *
+   * The time at which this cert is considered to be valid,
+   * %NULL if unavailable.
+   *
+   * Since: 2.70
+   */
+  g_object_class_install_property (gobject_class, PROP_NOT_VALID_BEFORE,
+                                   g_param_spec_boxed ("not-valid-before",
+                                                       P_("Not Valid Before"),
+                                                       P_("Cert should not be considered valid before this 
time."),
+                                                       G_TYPE_DATE_TIME,
+                                                       G_PARAM_READABLE |
+                                                         G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GTlsCertificate:not-valid-after: (nullable)
+   *
+   * The time at which this cert is no longer valid,
+   * %NULL if unavailable.
+   *
+   * Since: 2.70
+   */
+  g_object_class_install_property (gobject_class, PROP_NOT_VALID_AFTER,
+                                   g_param_spec_boxed ("not-valid-after",
+                                                       P_("Not Valid after"),
+                                                       P_("Cert should not be considered valid after this 
time."),
+                                                       G_TYPE_DATE_TIME,
+                                                       G_PARAM_READABLE |
+                                                         G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GTlsCertificate:subject-name: (nullable)
+   *
+   * The subject from the cert,
+   * %NULL if unavailable.
+   *
+   * Since: 2.70
+   */
+  g_object_class_install_property (gobject_class, PROP_SUBJECT_NAME,
+                                   g_param_spec_string ("subject-name",
+                                                        P_("Subject Name"),
+                                                        P_("The subject name from the certificate."),
+                                                        NULL,
+                                                        G_PARAM_READABLE |
+                                                          G_PARAM_STATIC_STRINGS));
+  /**
+   * GTlsCertificate:issuer-name: (nullable)
+   *
+   * The issuer from the certificate,
+   * %NULL if unavailable.
+   *
+   * Since: 2.70
+   */
+  g_object_class_install_property (gobject_class, PROP_ISSUER_NAME,
+                                   g_param_spec_string ("issuer-name",
+                                                        P_("Issuer Name"),
+                                                        P_("The issuer from the certificate."),
+                                                        NULL,
+                                                        G_PARAM_READABLE |
+                                                          G_PARAM_STATIC_STRINGS));
 }
 
 static GTlsCertificate *
@@ -876,3 +943,92 @@ g_tls_certificate_is_same (GTlsCertificate     *cert_one,
 
   return equal;
 }
+
+
+/**
+ * g_tls_certificate_get_not_valid_before:
+ * @cert: a #GTlsCertificate
+ *
+ * Returns the time at which the certificate became or will become valid.
+ *
+ * Returns: (nullable) (transfer full): The not-valid-before date, or %NULL if it's not available.
+ *
+ * Since: 2.70
+ */
+GDateTime *
+g_tls_certificate_get_not_valid_before (GTlsCertificate *cert)
+{
+  GDateTime *not_valid_before = NULL;
+
+  g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
+
+  g_object_get (G_OBJECT (cert), "not-valid-before", &not_valid_before, NULL);
+
+  return g_steal_pointer (&not_valid_before);
+}
+
+/**
+ * g_tls_certificate_get_not_valid_after:
+ * @cert: a #GTlsCertificate
+ *
+ * Returns the time at which the certificate became or will become invalid.
+ *
+ * Returns: (nullable) (transfer full): The not-valid-after date, or %NULL if it's not available.
+ *
+ * Since: 2.70
+ */
+GDateTime *
+g_tls_certificate_get_not_valid_after (GTlsCertificate *cert)
+{
+  GDateTime *not_valid_after = NULL;
+
+  g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
+
+  g_object_get (G_OBJECT (cert), "not-valid-after", &not_valid_after, NULL);
+
+  return g_steal_pointer (&not_valid_after);
+}
+
+/**
+ * g_tls_certificate_get_subject_name:
+ * @cert: a #GTlsCertificate
+ *
+ * Returns the subject name from the certificate.
+ *
+ * Returns: (nullable) (transfer full): The subject name, or %NULL if it's not available.
+ *
+ * Since: 2.70
+ */
+gchar *
+g_tls_certificate_get_subject_name (GTlsCertificate *cert)
+{
+  gchar *subject_name = NULL;
+
+  g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
+
+  g_object_get (G_OBJECT (cert), "subject-name", &subject_name, NULL);
+
+  return g_steal_pointer (&subject_name);
+}
+
+/**
+ * g_tls_certificate_get_issuer_name:
+ * @cert: a #GTlsCertificate
+ *
+ * Returns the issuer name from the certificate.
+ *
+ * Returns: (nullable) (transfer full): The issuer name, or %NULL if it's not available.
+ *
+ * Since: 2.70
+ */
+gchar *
+g_tls_certificate_get_issuer_name (GTlsCertificate *cert)
+{
+  gchar *issuer_name = NULL;
+
+  g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
+
+  g_object_get (G_OBJECT (cert), "issuer-name", &issuer_name, NULL);
+
+  return g_steal_pointer (&issuer_name);
+}
diff --git a/gio/gtlscertificate.h b/gio/gtlscertificate.h
index ead4f015e..27307d8a2 100644
--- a/gio/gtlscertificate.h
+++ b/gio/gtlscertificate.h
@@ -92,6 +92,18 @@ GLIB_AVAILABLE_IN_2_34
 gboolean              g_tls_certificate_is_same            (GTlsCertificate     *cert_one,
                                                             GTlsCertificate     *cert_two);
 
+GLIB_AVAILABLE_IN_2_70
+GDateTime            *g_tls_certificate_get_not_valid_before (GTlsCertificate     *cert);
+
+GLIB_AVAILABLE_IN_2_70
+GDateTime            *g_tls_certificate_get_not_valid_after  (GTlsCertificate     *cert);
+
+GLIB_AVAILABLE_IN_2_70
+gchar                *g_tls_certificate_get_subject_name     (GTlsCertificate     *cert);
+
+GLIB_AVAILABLE_IN_2_70
+gchar                *g_tls_certificate_get_issuer_name      (GTlsCertificate     *cert);
+
 G_END_DECLS
 
 #endif /* __G_TLS_CERTIFICATE_H__ */
diff --git a/gio/tests/gtesttlsbackend.c b/gio/tests/gtesttlsbackend.c
index 56d155031..869c71673 100644
--- a/gio/tests/gtesttlsbackend.c
+++ b/gio/tests/gtesttlsbackend.c
@@ -110,6 +110,10 @@ enum
   PROP_CERT_ISSUER,
   PROP_CERT_PKCS11_URI,
   PROP_CERT_PRIVATE_KEY_PKCS11_URI,
+  PROP_CERT_NOT_VALID_BEFORE,
+  PROP_CERT_NOT_VALID_AFTER,
+  PROP_CERT_SUBJECT_NAME,
+  PROP_CERT_ISSUER_NAME,
 };
 
 static void g_test_tls_certificate_initable_iface_init (GInitableIface *iface);
@@ -156,6 +160,18 @@ g_test_tls_certificate_get_property (GObject    *object,
     case PROP_CERT_PRIVATE_KEY_PKCS11_URI:
       g_value_set_string (value, cert->private_key_pkcs11_uri);
       break;
+    case PROP_CERT_NOT_VALID_BEFORE:
+      g_value_take_boxed (value, g_date_time_new_from_iso8601 ("2020-10-12T17:49:44Z", NULL));
+      break;
+    case PROP_CERT_NOT_VALID_AFTER:
+      g_value_take_boxed (value, g_date_time_new_from_iso8601 ("2045-10-06T17:49:44Z", NULL));
+      break;
+    case PROP_CERT_SUBJECT_NAME:
+      g_value_set_string (value, "DC=COM,DC=EXAMPLE,CN=server.example.com");
+      break;
+    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;
     default:
       g_assert_not_reached ();
       break;
@@ -230,6 +246,10 @@ g_test_tls_certificate_class_init (GTestTlsCertificateClass *test_class)
   g_object_class_override_property (gobject_class, PROP_CERT_ISSUER, "issuer");
   g_object_class_override_property (gobject_class, PROP_CERT_PKCS11_URI, "pkcs11-uri");
   g_object_class_override_property (gobject_class, PROP_CERT_PRIVATE_KEY_PKCS11_URI, 
"private-key-pkcs11-uri");
+  g_object_class_override_property (gobject_class, PROP_CERT_NOT_VALID_BEFORE, "not-valid-before");
+  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");
 }
 
 static void
diff --git a/gio/tests/tls-certificate.c b/gio/tests/tls-certificate.c
index c0fc80c4b..cfc349ea1 100644
--- a/gio/tests/tls-certificate.c
+++ b/gio/tests/tls-certificate.c
@@ -430,6 +430,92 @@ from_unsupported_pkcs11_uri (void)
   g_clear_error (&error);
 }
 
+static void
+not_valid_before (void)
+{
+  const gchar *EXPECTED_NOT_VALID_BEFORE = "2020-10-12T17:49:44Z";
+
+  GTlsCertificate *cert;
+  GError *error = NULL;
+  GDateTime *actual;
+  gchar *actual_str;
+
+  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_not_valid_before (cert);
+  g_assert_nonnull (actual);
+  actual_str = g_date_time_format_iso8601 (actual);
+  g_assert_cmpstr (actual_str, ==, EXPECTED_NOT_VALID_BEFORE);
+  g_free (actual_str);
+  g_date_time_unref (actual);
+  g_object_unref (cert);
+}
+
+static void
+not_valid_after (void)
+{
+  const gchar *EXPECTED_NOT_VALID_AFTER = "2045-10-06T17:49:44Z";
+
+  GTlsCertificate *cert;
+  GError *error = NULL;
+  GDateTime *actual;
+  gchar *actual_str;
+
+  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_not_valid_after (cert);
+  g_assert_nonnull (actual);
+  actual_str = g_date_time_format_iso8601 (actual);
+  g_assert_cmpstr (actual_str, ==, EXPECTED_NOT_VALID_AFTER);
+  g_free (actual_str);
+  g_date_time_unref (actual);
+  g_object_unref (cert);
+}
+
+static void
+subject_name (void)
+{
+  const gchar *EXPECTED_SUBJECT_NAME = "DC=COM,DC=EXAMPLE,CN=server.example.com";
+
+  GTlsCertificate *cert;
+  GError *error = NULL;
+  gchar *actual;
+
+  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_subject_name (cert);
+  g_assert_nonnull (actual);
+  g_assert_cmpstr (actual, ==, EXPECTED_SUBJECT_NAME);
+  g_free (actual);
+  g_object_unref (cert);
+}
+
+static void
+issuer_name (void)
+{
+  const gchar *EXPECTED_ISSUER_NAME = "DC=COM,DC=EXAMPLE,OU=Certificate 
Authority,CN=ca.example.com,emailAddress=ca example com";
+
+  GTlsCertificate *cert;
+  GError *error = NULL;
+  gchar *actual;
+
+  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_issuer_name (cert);
+  g_assert_nonnull (actual);
+  g_assert_cmpstr (actual, ==, EXPECTED_ISSUER_NAME);
+  g_free (actual);
+  g_object_unref (cert);
+}
+
 int
 main (int   argc,
       char *argv[])
@@ -500,6 +586,14 @@ main (int   argc,
                    from_pkcs11_uri);
   g_test_add_func ("/tls-certificate/pkcs11-uri-unsupported",
                    from_unsupported_pkcs11_uri);
+  g_test_add_func ("/tls-certificate/not-valid-before",
+                   not_valid_before);
+  g_test_add_func ("/tls-certificate/not-valid-after",
+                   not_valid_after);
+  g_test_add_func ("/tls-certificate/subject-name",
+                   subject_name);
+  g_test_add_func ("/tls-certificate/issuer-name",
+                   issuer_name);
 
   rtv = g_test_run();
 


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