[Spice-devel] [spice-gtk 3/3] ssl: Use accessors rather than direct struct access

Christophe Fergeau cfergeau at redhat.com
Thu Dec 22 16:03:08 UTC 2016


From: Sebastian Andrzej Siewior <sebastian at breakpoint.cc>

In OpenSSL 1.1.0, the struct fields are private so we can no longer
directly access them.

The accessors are not available in previous OpenSSL releases, so we need
to add compat helpers.
---
 src/bio-gio.c       | 103 ++++++++++++++++++++++++++++++++++++++++++++--------
 src/spice-channel.c |  11 +++++-
 2 files changed, 98 insertions(+), 16 deletions(-)

diff --git a/src/bio-gio.c b/src/bio-gio.c
index 20ee57a..701df93 100644
--- a/src/bio-gio.c
+++ b/src/bio-gio.c
@@ -23,6 +23,72 @@
 #include "spice-util.h"
 #include "bio-gio.h"
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000
+static BIO_METHOD one_static_bio;
+
+static int BIO_meth_set_read(BIO_METHOD *biom,
+                             int (*bread) (BIO *, char *, int))
+{
+    biom->bread = bread;
+    return 1;
+}
+
+static int BIO_meth_set_write(BIO_METHOD *biom,
+                              int (*bwrite) (BIO *, const char *, int))
+{
+    biom->bwrite = bwrite;
+    return 1;
+}
+
+static int BIO_meth_set_puts(BIO_METHOD *biom,
+                             int (*bputs) (BIO *, const char *))
+{
+    biom->bputs = bputs;
+    return 1;
+}
+
+static int BIO_meth_set_ctrl(BIO_METHOD *biom,
+                             long (*ctrl) (BIO *, int, long, void *))
+{
+    biom->ctrl = ctrl;
+    return 1;
+}
+
+static int BIO_get_new_index(void)
+{
+    return 128;
+}
+
+static void BIO_set_init(BIO *a, int init)
+{
+	a->init = init;
+}
+
+static void BIO_set_data(BIO *a, void *ptr)
+{
+    a->ptr = ptr;
+}
+
+static void *BIO_get_data(BIO *a)
+{
+    return a->ptr;
+}
+
+static BIO_METHOD *BIO_meth_new(int type, const char *name)
+{
+    BIO_METHOD *biom = &one_static_bio;
+
+    biom->type = type;
+    biom->name = name;
+    return biom;
+}
+
+static void BIO_meth_free(BIO_METHOD *biom)
+{
+}
+
+#endif
+
 static long bio_gio_ctrl(BIO *b, int cmd, long num, void *ptr)
 {
     long ret;
@@ -44,7 +110,7 @@ static int bio_gio_write(BIO *bio, const char *in, int inl)
     gssize ret;
     GError *error = NULL;
 
-    stream = g_io_stream_get_output_stream(bio->ptr);
+    stream = g_io_stream_get_output_stream(BIO_get_data(bio));
     ret = g_pollable_output_stream_write_nonblocking(G_POLLABLE_OUTPUT_STREAM(stream),
                                                      in, inl, NULL, &error);
     BIO_clear_retry_flags(bio);
@@ -65,7 +131,7 @@ static int bio_gio_read(BIO *bio, char *out, int outl)
     gssize ret;
     GError *error = NULL;
 
-    stream = g_io_stream_get_input_stream(bio->ptr);
+    stream = g_io_stream_get_input_stream(BIO_get_data(bio));
     ret = g_pollable_input_stream_read_nonblocking(G_POLLABLE_INPUT_STREAM(stream),
                                                    out, outl, NULL, &error);
     BIO_clear_retry_flags(bio);
@@ -90,28 +156,35 @@ static int bio_gio_puts(BIO *bio, const char *str)
     return ret;
 }
 
+static BIO_METHOD *bio_gio_method;
+
 G_GNUC_INTERNAL
 BIO* bio_new_giostream(GIOStream *stream)
 {
     BIO *bio;
-    static BIO_METHOD bio_gio_method;
 
-    if (bio_gio_method.name == NULL) {
-        bio_gio_method.type = 128 | BIO_TYPE_SOURCE_SINK;
-        bio_gio_method.name = "gio stream";
+    if (!bio_gio_method) {
+        bio_gio_method = BIO_meth_new(BIO_get_new_index() |
+                                      BIO_TYPE_SOURCE_SINK,
+                                      "gio stream");
+        if (!bio_gio_method)
+            return NULL;
+
+        if (!BIO_meth_set_write(bio_gio_method, bio_gio_write)
+            || !BIO_meth_set_read(bio_gio_method, bio_gio_read)
+            || !BIO_meth_set_puts(bio_gio_method, bio_gio_puts)
+            || !BIO_meth_set_ctrl(bio_gio_method, bio_gio_ctrl)) {
+            BIO_meth_free(bio_gio_method);
+            bio_gio_method = NULL;
+            return NULL;
+        }
     }
 
-    bio = BIO_new(&bio_gio_method);
+    bio = BIO_new(bio_gio_method);
     if (!bio)
         return NULL;
 
-    bio->method->bwrite = bio_gio_write;
-    bio->method->bread = bio_gio_read;
-    bio->method->bputs = bio_gio_puts;
-    bio->method->ctrl = bio_gio_ctrl;
-
-    bio->init = 1;
-    bio->ptr = stream;
-
+    BIO_set_init(bio, 1);
+    BIO_set_data(bio, stream);
     return bio;
 }
diff --git a/src/spice-channel.c b/src/spice-channel.c
index 6a911a6..6556db3 100644
--- a/src/spice-channel.c
+++ b/src/spice-channel.c
@@ -55,6 +55,15 @@ static void spice_channel_reset_capabilities(SpiceChannel *channel);
 static void spice_channel_send_migration_handshake(SpiceChannel *channel);
 static gboolean channel_connect(SpiceChannel *channel, gboolean tls);
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000
+static RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
+{
+    if (pkey->type != EVP_PKEY_RSA) {
+        return NULL;
+    }
+    return pkey->pkey.rsa;
+}
+#endif
 /**
  * SECTION:spice-channel
  * @short_description: the base channel class
@@ -1161,7 +1170,7 @@ static SpiceChannelEvent spice_channel_send_spice_ticket(SpiceChannel *channel)
     pubkey = d2i_PUBKEY_bio(bioKey, NULL);
     g_return_val_if_fail(pubkey != NULL, ret);
 
-    rsa = pubkey->pkey.rsa;
+    rsa = EVP_PKEY_get0_RSA(pubkey);
     nRSASize = RSA_size(rsa);
 
     encrypted = g_alloca(nRSASize);
-- 
2.9.3



More information about the Spice-devel mailing list