On 2016-06-26 12:24:11 [+0200], Kurt Roeckx wrote:
> https://breakpoint.cc/openssl-1.1-rebuild-2016-05-29/Attempted/spice-gtk_0.30-1_amd64-20160529-1539

The patch attached has been sent upstream. It is untested and I kindly
asked them to test it. I don't tag it patched until someone confirms
that this works.

> Kurt

Sebastian
>From 0bd3b308f964f52db02b20b5db3a6f9a45c35072 Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
Date: Wed, 21 Sep 2016 19:54:04 +0000
Subject: [PATCH] spice-gtk: get it compiled against openssl 1.1.0

and also 1.0.2h

Signed-off-by: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
---
 src/bio-gio.c       | 114 ++++++++++++++++++++++++++++++++++++++++------------
 src/spice-channel.c |  24 ++++++-----
 2 files changed, 103 insertions(+), 35 deletions(-)

diff --git a/src/bio-gio.c b/src/bio-gio.c
index b310c97..aa8ddac 100644
--- a/src/bio-gio.c
+++ b/src/bio-gio.c
@@ -23,21 +23,74 @@
 #include "spice-util.h"
 #include "bio-gio.h"
 
-typedef struct bio_gsocket_method {
-    BIO_METHOD method;
-    GIOStream *stream;
-} bio_gsocket_method;
+#if OPENSSL_VERSION_NUMBER < 0x10100000
+static BIO_METHOD one_static_bio;
 
-#define BIO_GET_GSOCKET(bio)  (((bio_gsocket_method*)bio->method)->gsocket)
-#define BIO_GET_ISTREAM(bio)  (g_io_stream_get_input_stream(((bio_gsocket_method*)bio->method)->stream))
-#define BIO_GET_OSTREAM(bio)  (g_io_stream_get_output_stream(((bio_gsocket_method*)bio->method)->stream))
+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_destroy(BIO_METHOD *biom, int (*destroy) (BIO *))
+{
+    biom->destroy = destroy;
+    return 1;
+}
+
+static int BIO_get_new_index()
+{
+    return 128;
+}
+
+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;
+}
+
+void BIO_meth_free(BIO_METHOD *biom)
+{
+}
+
+#endif
 
 static int bio_gio_write(BIO *bio, const char *in, int inl)
 {
+    GIOStream *stream;
     gssize ret;
     GError *error = NULL;
 
-    ret = g_pollable_output_stream_write_nonblocking(G_POLLABLE_OUTPUT_STREAM(BIO_GET_OSTREAM(bio)),
+    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);
 
@@ -53,10 +106,12 @@ static int bio_gio_write(BIO *bio, const char *in, int inl)
 
 static int bio_gio_read(BIO *bio, char *out, int outl)
 {
+    GIOStream *stream;
     gssize ret;
     GError *error = NULL;
 
-    ret = g_pollable_input_stream_read_nonblocking(G_POLLABLE_INPUT_STREAM(BIO_GET_ISTREAM(bio)),
+    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);
 
@@ -72,12 +127,14 @@ static int bio_gio_read(BIO *bio, char *out, int outl)
 
 static int bio_gio_destroy(BIO *bio)
 {
-    if (bio == NULL || bio->method == NULL)
+    if (bio == NULL )
         return 0;
 
     SPICE_DEBUG("bio gsocket destroy");
-    g_clear_pointer(&bio->method, g_free);
 
+    /* XXX DO WE NEED to free GIOStream *stream ? */
+
+    BIO_set_data(bio, NULL);
     return 1;
 }
 
@@ -91,23 +148,30 @@ 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)
 {
-    // TODO: make an actual new BIO type, or just switch to GTls already...
-    BIO *bio = BIO_new_socket(-1, BIO_NOCLOSE);
-
-    bio_gsocket_method *bio_method = g_new(bio_gsocket_method, 1);
-    bio_method->method = *bio->method;
-    bio_method->stream = stream;
-
-    bio->method->destroy(bio);
-    bio->method = (BIO_METHOD*)bio_method;
-
-    bio->method->bwrite = bio_gio_write;
-    bio->method->bread = bio_gio_read;
-    bio->method->bputs = bio_gio_puts;
-    bio->method->destroy = bio_gio_destroy;
+    BIO *bio;
+
+    if (!bio_gio_method) {
+        bio_gio_method = BIO_meth_new(BIO_get_new_index(), "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_destroy(bio_gio_method, bio_gio_destroy)) {
+            BIO_meth_free(bio_gio_method);
+            bio_gio_method = NULL;
+            return NULL;
+        }
+    }
 
+    bio = BIO_new(bio_gio_method);
+    if (!bio)
+        return NULL;
+    BIO_set_data(bio, stream);
     return bio;
 }
diff --git a/src/spice-channel.c b/src/spice-channel.c
index 0eb0e61..748cb67 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
@@ -1138,7 +1147,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);
@@ -2329,17 +2338,12 @@ static gboolean spice_channel_delayed_unref(gpointer data)
     return FALSE;
 }
 
-static X509_LOOKUP_METHOD spice_x509_mem_lookup = {
-    "spice_x509_mem_lookup",
-    0
-};
-
 static int spice_channel_load_ca(SpiceChannel *channel)
 {
     SpiceChannelPrivate *c = channel->priv;
     STACK_OF(X509_INFO) *inf;
     X509_INFO *itmp;
-    X509_LOOKUP *lookup;
+    X509_STORE *store;
     BIO *in;
     int i, count = 0;
     guint8 *ca;
@@ -2349,13 +2353,13 @@ static int spice_channel_load_ca(SpiceChannel *channel)
 
     g_return_val_if_fail(c->ctx != NULL, 0);
 
-    lookup = X509_STORE_add_lookup(c->ctx->cert_store, &spice_x509_mem_lookup);
     ca_file = spice_session_get_ca_file(c->session);
     spice_session_get_ca(c->session, &ca, &size);
 
     CHANNEL_DEBUG(channel, "Load CA, file: %s, data: %p", ca_file, ca);
 
     if (ca != NULL) {
+        store = SSL_CTX_get_cert_store(c->ctx);
         in = BIO_new_mem_buf(ca, size);
         inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
         BIO_free(in);
@@ -2363,11 +2367,11 @@ static int spice_channel_load_ca(SpiceChannel *channel)
         for (i = 0; i < sk_X509_INFO_num(inf); i++) {
             itmp = sk_X509_INFO_value(inf, i);
             if (itmp->x509) {
-                X509_STORE_add_cert(lookup->store_ctx, itmp->x509);
+                X509_STORE_add_cert(store, itmp->x509);
                 count++;
             }
             if (itmp->crl) {
-                X509_STORE_add_crl(lookup->store_ctx, itmp->crl);
+                X509_STORE_add_crl(store, itmp->crl);
                 count++;
             }
         }
-- 
2.9.3

Reply via email to