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

Pavel Grunt pgrunt at redhat.com
Mon Jan 9 14:38:43 UTC 2017


On Thu, 2016-12-22 at 17:03 +0100, Christophe Fergeau wrote:
> 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;

looking at openssl implementation
https://github.com/openssl/openssl/commit/8b8d963db5bb619fbada014f294f
d09a855a2650

it uses BIO_TYPE_START and increments when called

> +}
> +
> +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(str
> eam),
>                                                     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)) {

style - "||" should be at the end of the line

> +            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);

Thanks,
Pavel



More information about the Spice-devel mailing list