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]: 8afe31a018/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
This commit is contained in:
Ross A. Wollman 2021-05-26 07:59:37 +00:00
parent d64d46dc42
commit a17c28790a
5 changed files with 286 additions and 0 deletions

View File

@ -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>

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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

View File

@ -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();