[glib/wip/tingping/gtls-certificate-serialize] WIP: Add serialization functions to GTlsCertificate



commit d5903624cbf5eb9e631183d63230c2403b56d2eb
Author: Patrick Griffis <pgriffis igalia com>
Date:   Fri Jun 7 12:38:32 2019 -0700

    WIP: Add serialization functions to GTlsCertificate
    
    This is useful to transfer certificates over IPC

 gio/gtlscertificate.c       | 62 +++++++++++++++++++++++++++++++++++++++++++++
 gio/gtlscertificate.h       | 15 ++++++++++-
 gio/tests/gtesttlsbackend.c | 23 +++++++++++++++++
 gio/tests/tls-certificate.c | 35 +++++++++++++++++++++++++
 4 files changed, 134 insertions(+), 1 deletion(-)
---
diff --git a/gio/gtlscertificate.c b/gio/gtlscertificate.c
index 72de5eb1f..457db00ef 100644
--- a/gio/gtlscertificate.c
+++ b/gio/gtlscertificate.c
@@ -750,3 +750,65 @@ g_tls_certificate_is_same (GTlsCertificate     *cert_one,
 
   return equal;
 }
+
+/**
+ * g_tls_certificate_serialize:
+ * @cert: a certificate to serialize
+ * @error: a pointer to a %NULL #GError, or %NULL
+ *
+ * Serializes the contents of a #GTlsCertificate. The contents
+ * of the returned data is implementation defined and may not
+ * be transferable to a different #GTlsBackend.
+ *
+ * Returns: A #GVariant if successful, %NULL if @error is set
+ *
+ * Since: 2.62
+ */
+GVariant *
+g_tls_certificate_serialize (GTlsCertificate  *cert,
+                             GError          **error)
+{
+  g_return_val_if_fail (cert != NULL, NULL);
+
+  if (G_TLS_CERTIFICATE_GET_CLASS (cert)->serialize == NULL)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "TLS backend does not support 
serialization");
+      return NULL;
+    }
+
+  return G_TLS_CERTIFICATE_GET_CLASS (cert)->serialize (cert, error);
+}
+
+/**
+ * g_tls_certificate_deserialize:
+ * @cert: a certificate to deserialize
+ * @error: a pointer to a %NULL #GError, or %NULL
+ *
+ * Deserializes the return value of g_tls_certificate_serialize() into a
+ * #GTlsCertificate. This will use the default #GTlsBackend to create the
+ * certificate.
+ *
+ * Returns: A #GTlsCertificate if successful, %NULL if @error is set
+ *
+ * Since: 2.62
+ */
+GTlsCertificate *
+g_tls_certificate_deserialize (GVariant  *serialized_cert,
+                               GError   **error)
+{
+  GTlsBackend *backend = g_tls_backend_get_default ();
+  GType cert_type = g_tls_backend_get_certificate_type (backend);
+  GTlsCertificateClass *klass = g_type_class_ref (cert_type);
+  GTlsCertificate *cert;
+
+  if (klass->deserialize == NULL)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "TLS backend does not support 
serialization");
+      g_type_class_unref (klass);
+      return NULL;
+    }
+
+  cert = klass->deserialize (serialized_cert, error);
+  g_type_class_unref (klass);
+  return cert;
+}
diff --git a/gio/gtlscertificate.h b/gio/gtlscertificate.h
index a064543c4..85d800e25 100644
--- a/gio/gtlscertificate.h
+++ b/gio/gtlscertificate.h
@@ -51,9 +51,14 @@ struct _GTlsCertificateClass
                                    GSocketConnectable  *identity,
                                    GTlsCertificate     *trusted_ca);
 
+  GVariant *            (* serialize)   (GTlsCertificate  *cert,
+                                         GError          **error);
+
+  GTlsCertificate *     (* deserialize) (GVariant         *serialized_certificate,
+                                         GError         **error);
   /*< private >*/
   /* Padding for future expansion */
-  gpointer padding[8];
+  gpointer padding[6];
 };
 
 GLIB_AVAILABLE_IN_ALL
@@ -87,6 +92,14 @@ GLIB_AVAILABLE_IN_2_34
 gboolean              g_tls_certificate_is_same            (GTlsCertificate     *cert_one,
                                                             GTlsCertificate     *cert_two);
 
+GLIB_AVAILABLE_IN_2_62
+GVariant *            g_tls_certificate_serialize          (GTlsCertificate     *cert,
+                                                            GError             **error);
+
+GLIB_AVAILABLE_IN_2_62
+GTlsCertificate *     g_tls_certificate_deserialize        (GVariant            *serialized_certificate,
+                                                            GError             **error);
+
 G_END_DECLS
 
 #endif /* __G_TLS_CERTIFICATE_H__ */
diff --git a/gio/tests/gtesttlsbackend.c b/gio/tests/gtesttlsbackend.c
index 157a4a3f3..6a74b15ce 100644
--- a/gio/tests/gtesttlsbackend.c
+++ b/gio/tests/gtesttlsbackend.c
@@ -122,6 +122,27 @@ g_test_tls_certificate_verify (GTlsCertificate     *cert,
   return 0;
 }
 
+static GVariant *
+g_test_tls_certificate_serialize (GTlsCertificate  *cert,
+                                  GError          **error)
+{
+  char *certificate;
+
+  g_object_get (cert, "certificate-pem", &certificate, NULL);
+  return g_variant_new_take_string (g_steal_pointer (&certificate));
+}
+
+static GTlsCertificate *
+g_test_tls_certificate_deserialize (GVariant  *serialized_cert,
+                                    GError   **error)
+{
+  const char *certificate;
+
+  certificate = g_variant_get_string (serialized_cert, NULL);
+  return g_object_new (g_test_tls_certificate_get_type (),
+                       "certificate-pem", certificate, NULL);
+}
+
 static void
 g_test_tls_certificate_get_property (GObject    *object,
                                      guint       prop_id,
@@ -199,6 +220,8 @@ g_test_tls_certificate_class_init (GTestTlsCertificateClass *test_class)
   gobject_class->finalize = g_test_tls_certificate_finalize;
 
   certificate_class->verify = g_test_tls_certificate_verify;
+  certificate_class->serialize = g_test_tls_certificate_serialize;
+  certificate_class->deserialize = g_test_tls_certificate_deserialize;
 
   g_object_class_override_property (gobject_class, PROP_CERT_CERTIFICATE, "certificate");
   g_object_class_override_property (gobject_class, PROP_CERT_CERTIFICATE_PEM, "certificate-pem");
diff --git a/gio/tests/tls-certificate.c b/gio/tests/tls-certificate.c
index e1ba23737..abf9b1c4f 100644
--- a/gio/tests/tls-certificate.c
+++ b/gio/tests/tls-certificate.c
@@ -398,6 +398,39 @@ list_from_file (const Reference *ref)
   g_assert_cmpint (g_list_length (list), ==, 0);
 }
 
+static void
+serialization (const Reference *ref)
+{
+  GTlsCertificate *cert, *deserialized;
+  GVariant *serialized;
+  char *original_key, *deserialized_key;
+  GError *error = NULL;
+
+  cert = g_tls_certificate_new_from_files (g_test_get_filename (G_TEST_DIST, "cert-tests", "cert1.pem", 
NULL),
+                                           g_test_get_filename (G_TEST_DIST, "cert-tests", "key.pem", NULL),
+                                           &error);
+  g_assert_no_error (error);
+  g_assert_nonnull (cert);
+
+  serialized = g_tls_certificate_serialize (cert, &error);
+  g_assert_no_error (error);
+  g_assert_nonnull (serialized);
+
+  deserialized = g_tls_certificate_deserialize (serialized, &error);
+  g_assert_no_error (error);
+  g_assert_nonnull (deserialized);
+
+  g_object_get (cert, "certificate-pem", &original_key, NULL);
+  g_object_get (deserialized, "certificate-pem", &deserialized_key, NULL);
+  g_assert_cmpstr (deserialized_key, ==, original_key);
+
+  g_object_unref (cert);
+  g_object_unref (deserialized);
+  g_variant_unref (serialized);
+  g_free (original_key);
+  g_free (deserialized_key);
+}
+
 int
 main (int   argc,
       char *argv[])
@@ -464,6 +497,8 @@ main (int   argc,
                         &ref, (GTestDataFunc)from_files_pkcs8enc);
   g_test_add_data_func ("/tls-certificate/list_from_file",
                         &ref, (GTestDataFunc)list_from_file);
+  g_test_add_data_func ("/tls-certificate/serialization",
+                        &ref, (GTestDataFunc)serialization);
 
   rtv = g_test_run();
 


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