/*
 * Copyright (c) 2014, Ericsson AB. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this
 * list of conditions and the following disclaimer in the documentation and/or other
 * materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gst.h>

#include "gstdtlsconnection.h"

#include "gstdtlsagent.h"
#include "gstdtlscertificate.h"

#ifdef __APPLE__
# define __AVAILABILITYMACROS__
# define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
#endif

#include <openssl/err.h>
#include <openssl/ssl.h>

GST_DEBUG_CATEGORY_STATIC (gst_dtls_connection_debug);
#define GST_CAT_DEFAULT gst_dtls_connection_debug
G_DEFINE_TYPE_WITH_CODE (GstDtlsConnection, gst_dtls_connection, G_TYPE_OBJECT,
    GST_DEBUG_CATEGORY_INIT (gst_dtls_connection_debug, "dtlsconnection", 0,
        "DTLS Connection"));

#define GST_DTLS_CONNECTION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), GST_TYPE_DTLS_CONNECTION, GstDtlsConnectionPrivate))

#define SRTP_KEY_LEN 16
#define SRTP_SALT_LEN 14

enum
{
  SIGNAL_ON_ENCODER_KEY,
  SIGNAL_ON_DECODER_KEY,
  SIGNAL_ON_PEER_CERTIFICATE,
  NUM_SIGNALS
};

static guint signals[NUM_SIGNALS];

enum
{
  PROP_0,
  PROP_AGENT,
  NUM_PROPERTIES
};

static GParamSpec *properties[NUM_PROPERTIES];

static int connection_ex_index;

struct _GstDtlsConnectionPrivate
{
  SSL *ssl;
  BIO *bio;
  GThread *thread;

  gboolean is_client;
  gboolean is_alive;
  gboolean keys_exported;
  gboolean timeout_set;

  GMutex mutex;
  GCond condition;
  gpointer bio_buffer;
  gint bio_buffer_len;
  gint bio_buffer_offset;

  GClosure *send_closure;
};

static void gst_dtls_connection_finalize (GObject * gobject);
static void gst_dtls_connection_set_property (GObject *, guint prop_id,
    const GValue *, GParamSpec *);

static void log_state (GstDtlsConnection *, const gchar * str);
static gpointer connection_timeout_thread_func (GstDtlsConnection *);
static void export_srtp_keys (GstDtlsConnection *);
static void openssl_poll (GstDtlsConnection *);
static int openssl_verify_callback (int preverify_ok,
    X509_STORE_CTX * x509_ctx);

static BIO_METHOD *BIO_s_gst_dtls_connection (void);
static int bio_method_write (BIO *, const char *data, int size);
static int bio_method_read (BIO *, char *out_buffer, int size);
static long bio_method_ctrl (BIO *, int cmd, long arg1, void *arg2);
static int bio_method_new (BIO *);
static int bio_method_free (BIO *);

static void
gst_dtls_connection_class_init (GstDtlsConnectionClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  g_type_class_add_private (klass, sizeof (GstDtlsConnectionPrivate));

  gobject_class->set_property = gst_dtls_connection_set_property;

  connection_ex_index =
      SSL_get_ex_new_index (0, (gpointer) "gstdtlsagent connection index", NULL,
      NULL, NULL);

  signals[SIGNAL_ON_DECODER_KEY] =
      g_signal_new ("on-decoder-key", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL,
      g_cclosure_marshal_generic, G_TYPE_NONE, 3,
      G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT);

  signals[SIGNAL_ON_ENCODER_KEY] =
      g_signal_new ("on-encoder-key", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL,
      g_cclosure_marshal_generic, G_TYPE_NONE, 3,
      G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT);

  signals[SIGNAL_ON_PEER_CERTIFICATE] =
      g_signal_new ("on-peer-certificate", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL,
      g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 1, G_TYPE_STRING);

  properties[PROP_AGENT] =
      g_param_spec_object ("agent",
      "DTLS Agent",
      "Agent to use in creation of the connection",
      GST_TYPE_DTLS_AGENT,
      G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);

  g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);

  _gst_dtls_init_openssl ();

  gobject_class->finalize = gst_dtls_connection_finalize;
}

static void
gst_dtls_connection_init (GstDtlsConnection * self)
{
  GstDtlsConnectionPrivate *priv = GST_DTLS_CONNECTION_GET_PRIVATE (self);
  self->priv = priv;

  priv->ssl = NULL;
  priv->bio = NULL;
  priv->thread = NULL;

  priv->send_closure = NULL;

  priv->is_client = FALSE;
  priv->is_alive = TRUE;
  priv->keys_exported = FALSE;
  priv->timeout_set = FALSE;

  priv->bio_buffer = NULL;
  priv->bio_buffer_len = 0;
  priv->bio_buffer_offset = 0;

  g_mutex_init (&priv->mutex);
  g_cond_init (&priv->condition);
}

static void
gst_dtls_connection_finalize (GObject * gobject)
{
  GstDtlsConnection *self = GST_DTLS_CONNECTION (gobject);
  GstDtlsConnectionPrivate *priv = self->priv;


  SSL_free (priv->ssl);
  priv->ssl = NULL;

  if (priv->send_closure) {
    g_closure_unref (priv->send_closure);
    priv->send_closure = NULL;
  }

  g_mutex_clear (&priv->mutex);
  g_cond_clear (&priv->condition);

  GST_DEBUG_OBJECT (self, "finalized");

  G_OBJECT_CLASS (gst_dtls_connection_parent_class)->finalize (gobject);
}

static void
gst_dtls_connection_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstDtlsConnection *self = GST_DTLS_CONNECTION (object);
  GstDtlsAgent *agent;
  GstDtlsConnectionPrivate *priv = self->priv;
  SSL_CTX *ssl_context;

  switch (prop_id) {
    case PROP_AGENT:
      g_return_if_fail (!priv->ssl);
      agent = GST_DTLS_AGENT (g_value_get_object (value));
      g_return_if_fail (GST_IS_DTLS_AGENT (agent));

      ssl_context = _gst_dtls_agent_peek_context (agent);

      priv->ssl = SSL_new (ssl_context);
      g_return_if_fail (priv->ssl);

      priv->bio = BIO_new (BIO_s_gst_dtls_connection ());
      g_return_if_fail (priv->bio);

      priv->bio->ptr = self;
      SSL_set_bio (priv->ssl, priv->bio, priv->bio);

      SSL_set_verify (priv->ssl,
          SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
          openssl_verify_callback);
      SSL_set_ex_data (priv->ssl, connection_ex_index, self);

      log_state (self, "connection created");
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
  }
}

void
gst_dtls_connection_start (GstDtlsConnection * self, gboolean is_client)
{
  GstDtlsConnectionPrivate *priv;

  g_return_if_fail (GST_IS_DTLS_CONNECTION (self));

  priv = self->priv;

  g_return_if_fail (priv->send_closure);
  g_return_if_fail (priv->ssl);
  g_return_if_fail (priv->bio);

  GST_TRACE_OBJECT (self, "locking @ start");
  g_mutex_lock (&priv->mutex);
  GST_TRACE_OBJECT (self, "locked @ start");

  priv->is_alive = TRUE;
  priv->timeout_set = FALSE;
  priv->bio_buffer = NULL;
  priv->bio_buffer_len = 0;
  priv->bio_buffer_offset = 0;
  priv->keys_exported = FALSE;

  priv->is_client = is_client;
  if (priv->is_client) {
    SSL_set_connect_state (priv->ssl);
  } else {
    SSL_set_accept_state (priv->ssl);
  }
  log_state (self, "initial state set");

  openssl_poll (self);

  log_state (self, "first poll done");
  priv->thread = NULL;

  GST_TRACE_OBJECT (self, "unlocking @ start");
  g_mutex_unlock (&priv->mutex);
}

void
gst_dtls_connection_start_timeout (GstDtlsConnection * self)
{
  GstDtlsConnectionPrivate *priv;
  GError *error = NULL;
  gchar *thread_name;

  g_return_if_fail (GST_IS_DTLS_CONNECTION (self));

  priv = self->priv;

  thread_name = g_strdup_printf ("connection_thread_%p", self);

  GST_TRACE_OBJECT (self, "locking @ start_timeout");
  g_mutex_lock (&priv->mutex);
  GST_TRACE_OBJECT (self, "locked @ start_timeout");

  GST_INFO_OBJECT (self, "starting connection timeout");
  priv->thread = g_thread_try_new (thread_name,
      (GThreadFunc) connection_timeout_thread_func, self, &error);
  if (error) {
    GST_WARNING_OBJECT (self, "error creating connection thread: %s (%d)",
        error->message, error->code);
    g_clear_error (&error);
  }

  g_free (thread_name);

  GST_TRACE_OBJECT (self, "unlocking @ start_timeout");
  g_mutex_unlock (&priv->mutex);
}

void
gst_dtls_connection_stop (GstDtlsConnection * self)
{
  g_return_if_fail (GST_IS_DTLS_CONNECTION (self));
  g_return_if_fail (self->priv->ssl);
  g_return_if_fail (self->priv->bio);

  GST_DEBUG_OBJECT (self, "stopping connection");

  GST_TRACE_OBJECT (self, "locking @ stop");
  g_mutex_lock (&self->priv->mutex);
  GST_TRACE_OBJECT (self, "locked @ stop");

  self->priv->is_alive = FALSE;
  GST_TRACE_OBJECT (self, "signaling @ stop");
  g_cond_signal (&self->priv->condition);
  GST_TRACE_OBJECT (self, "signaled @ stop");

  GST_TRACE_OBJECT (self, "unlocking @ stop");
  g_mutex_unlock (&self->priv->mutex);

  GST_DEBUG_OBJECT (self, "stopped connection");
}

void
gst_dtls_connection_close (GstDtlsConnection * self)
{
  g_return_if_fail (GST_IS_DTLS_CONNECTION (self));
  g_return_if_fail (self->priv->ssl);
  g_return_if_fail (self->priv->bio);

  GST_DEBUG_OBJECT (self, "closing connection");

  GST_TRACE_OBJECT (self, "locking @ close");
  g_mutex_lock (&self->priv->mutex);
  GST_TRACE_OBJECT (self, "locked @ close");

  if (self->priv->is_alive) {
    self->priv->is_alive = FALSE;
    g_cond_signal (&self->priv->condition);
  }

  GST_TRACE_OBJECT (self, "unlocking @ close");
  g_mutex_unlock (&self->priv->mutex);

  if (self->priv->thread) {
    g_thread_join (self->priv->thread);
    self->priv->thread = NULL;
  }

  GST_DEBUG_OBJECT (self, "closed connection");
}

void
gst_dtls_connection_set_send_callback (GstDtlsConnection * self,
    GClosure * closure)
{
  g_return_if_fail (GST_IS_DTLS_CONNECTION (self));

  GST_TRACE_OBJECT (self, "locking @ set_send_callback");
  g_mutex_lock (&self->priv->mutex);
  GST_TRACE_OBJECT (self, "locked @ set_send_callback");

  self->priv->send_closure = closure;

  if (closure && G_CLOSURE_NEEDS_MARSHAL (closure)) {
    g_closure_set_marshal (closure, g_cclosure_marshal_generic);
  }

  GST_TRACE_OBJECT (self, "unlocking @ set_send_callback");
  g_mutex_unlock (&self->priv->mutex);
}

gint
gst_dtls_connection_process (GstDtlsConnection * self, gpointer data, gint len)
{
  GstDtlsConnectionPrivate *priv;
  gint result;

  g_return_val_if_fail (GST_IS_DTLS_CONNECTION (self), 0);
  g_return_val_if_fail (self->priv->ssl, 0);
  g_return_val_if_fail (self->priv->bio, 0);

  priv = self->priv;

  GST_TRACE_OBJECT (self, "locking @ process");
  g_mutex_lock (&priv->mutex);
  GST_TRACE_OBJECT (self, "locked @ process");

  g_warn_if_fail (!priv->bio_buffer);

  priv->bio_buffer = data;
  priv->bio_buffer_len = len;
  priv->bio_buffer_offset = 0;

  log_state (self, "process start");

  if (SSL_want_write (priv->ssl)) {
    openssl_poll (self);
    log_state (self, "process want write, after poll");
  }

  result = SSL_read (priv->ssl, data, len);

  log_state (self, "process after read");

  openssl_poll (self);

  log_state (self, "process after poll");

  GST_DEBUG_OBJECT (self, "read result: %d", result);

  GST_TRACE_OBJECT (self, "unlocking @ process");
  g_mutex_unlock (&priv->mutex);

  return result;
}

gint
gst_dtls_connection_send (GstDtlsConnection * self, gpointer data, gint len)
{
  int ret = 0;

  g_return_val_if_fail (GST_IS_DTLS_CONNECTION (self), 0);

  g_return_val_if_fail (self->priv->ssl, 0);
  g_return_val_if_fail (self->priv->bio, 0);

  GST_TRACE_OBJECT (self, "locking @ send");
  g_mutex_lock (&self->priv->mutex);
  GST_TRACE_OBJECT (self, "locked @ send");

  if (SSL_is_init_finished (self->priv->ssl)) {
    ret = SSL_write (self->priv->ssl, data, len);
    GST_DEBUG_OBJECT (self, "data sent: input was %d B, output is %d B", len,
        ret);
  } else {
    GST_WARNING_OBJECT (self,
        "tried to send data before handshake was complete");
    ret = 0;
  }

  GST_TRACE_OBJECT (self, "unlocking @ send");
  g_mutex_unlock (&self->priv->mutex);

  return ret;
}

/*
     ######   #######  ##    ##
    ##    ## ##     ## ###   ##
    ##       ##     ## ####  ##
    ##       ##     ## ## ## ##
    ##       ##     ## ##  ####
    ##    ## ##     ## ##   ###
     ######   #######  ##    ##
*/

static void
log_state (GstDtlsConnection * self, const gchar * str)
{
  GstDtlsConnectionPrivate *priv = self->priv;
  guint states = 0;

  states |= (! !SSL_is_init_finished (priv->ssl) << 0);
  states |= (! !SSL_in_init (priv->ssl) << 4);
  states |= (! !SSL_in_before (priv->ssl) << 8);
  states |= (! !SSL_in_connect_init (priv->ssl) << 12);
  states |= (! !SSL_in_accept_init (priv->ssl) << 16);
  states |= (! !SSL_want_write (priv->ssl) << 20);
  states |= (! !SSL_want_read (priv->ssl) << 24);

  GST_LOG_OBJECT (self, "%s: role=%s buf=(%d,%p:%d/%d) %x|%x %s",
      str,
      priv->is_client ? "client" : "server",
      pqueue_size (priv->ssl->d1->sent_messages),
      priv->bio_buffer,
      priv->bio_buffer_offset,
      priv->bio_buffer_len,
      states, SSL_get_state (priv->ssl), SSL_state_string_long (priv->ssl));
}

static gpointer
connection_timeout_thread_func (GstDtlsConnection * self)
{
  GstDtlsConnectionPrivate *priv = self->priv;
  struct timeval timeout;
  gint64 end_time, wait_time;
  gint ret;

  while (priv->is_alive) {
    GST_TRACE_OBJECT (self, "locking @ timeout");
    g_mutex_lock (&priv->mutex);
    GST_TRACE_OBJECT (self, "locked @ timeout");

    if (DTLSv1_get_timeout (priv->ssl, &timeout)) {
      wait_time = timeout.tv_sec * G_USEC_PER_SEC + timeout.tv_usec;

      if (wait_time) {
        GST_DEBUG_OBJECT (self, "waiting for %" G_GINT64_FORMAT " usec",
            wait_time);

        end_time = g_get_monotonic_time () + wait_time;

        GST_TRACE_OBJECT (self, "wait @ timeout");
        g_cond_wait_until (&priv->condition, &priv->mutex, end_time);
        GST_TRACE_OBJECT (self, "continued @ timeout");
      }

      ret = DTLSv1_handle_timeout (priv->ssl);

      GST_DEBUG_OBJECT (self, "handle timeout returned %d, is_alive: %d", ret,
          priv->is_alive);

      if (ret < 0) {
        GST_TRACE_OBJECT (self, "unlocking @ timeout failed");
        g_mutex_unlock (&priv->mutex);
        break;                  /* self failed after DTLS1_TMO_ALERT_COUNT (12) attempts */
      }

      if (ret > 0) {
        log_state (self, "handling timeout before poll");
        openssl_poll (self);
        log_state (self, "handling timeout after poll");
      }
    } else {
      GST_DEBUG_OBJECT (self, "waiting indefinitely");

      priv->timeout_set = FALSE;

      while (!priv->timeout_set && priv->is_alive) {
        GST_TRACE_OBJECT (self, "wait @ timeout");
        g_cond_wait (&priv->condition, &priv->mutex);
      }
      GST_TRACE_OBJECT (self, "continued @ timeout");
    }

    GST_TRACE_OBJECT (self, "unlocking @ timeout");
    g_mutex_unlock (&priv->mutex);
  }

  log_state (self, "timeout thread exiting");

  return NULL;
}

static void
export_srtp_keys (GstDtlsConnection * self)
{
  typedef struct
  {
    guint8 v[SRTP_KEY_LEN];
  } Key;

  typedef struct
  {
    guint8 v[SRTP_SALT_LEN];
  } Salt;

  struct
  {
    Key client_key;
    Key servgst_key;
    Salt client_salt;
    Salt servgst_salt;
  } exported_keys;

  struct
  {
    Key key;
    Salt salt;
  } client_key, servgst_key;

  SRTP_PROTECTION_PROFILE *profile;
  GstDtlsSrtpCipher cipher;
  GstDtlsSrtpAuth auth;
  gint success;

  static gchar export_string[] = "EXTRACTOR-dtls_srtp";

  success = SSL_export_keying_material (self->priv->ssl,
      (gpointer) & exported_keys, 60, export_string, strlen (export_string),
      NULL, 0, 0);

  if (!success) {
    GST_WARNING_OBJECT (self, "failed to export srtp keys");
    return;
  }

  profile = SSL_get_selected_srtp_profile (self->priv->ssl);

  GST_INFO_OBJECT (self, "keys received, profile is %s", profile->name);

  switch (profile->id) {
    case SRTP_AES128_CM_SHA1_80:
      cipher = GST_DTLS_SRTP_CIPHER_AES_128_ICM;
      auth = GST_DTLS_SRTP_AUTH_HMAC_SHA1_80;
      break;
    case SRTP_AES128_CM_SHA1_32:
      cipher = GST_DTLS_SRTP_CIPHER_AES_128_ICM;
      auth = GST_DTLS_SRTP_AUTH_HMAC_SHA1_32;
      break;
    default:
      GST_WARNING_OBJECT (self, "invalid crypto suite set by handshake");
      goto beach;
  }

  client_key.key = exported_keys.client_key;
  servgst_key.key = exported_keys.servgst_key;
  client_key.salt = exported_keys.client_salt;
  servgst_key.salt = exported_keys.servgst_salt;

  if (self->priv->is_client) {
    g_signal_emit (self, signals[SIGNAL_ON_ENCODER_KEY], 0, &client_key, cipher,
        auth);
    g_signal_emit (self, signals[SIGNAL_ON_DECODER_KEY], 0, &servgst_key,
        cipher, auth);
  } else {
    g_signal_emit (self, signals[SIGNAL_ON_ENCODER_KEY], 0, &servgst_key,
        cipher, auth);
    g_signal_emit (self, signals[SIGNAL_ON_DECODER_KEY], 0, &client_key, cipher,
        auth);
  }

beach:
  self->priv->keys_exported = TRUE;
}

static void
openssl_poll (GstDtlsConnection * self)
{
  int ret;
  char buf[512];
  int error;

  log_state (self, "poll: before handshake");

  ret = SSL_do_handshake (self->priv->ssl);

  log_state (self, "poll: after handshake");

  if (ret == 1) {
    if (!self->priv->keys_exported) {
      GST_INFO_OBJECT (self,
          "handshake just completed successfully, exporting keys");
      export_srtp_keys (self);
    } else {
      GST_INFO_OBJECT (self, "handshake is completed");
    }
    return;
  } else {
    if (ret == 0) {
      GST_DEBUG_OBJECT (self, "do_handshake encountered EOF");
    } else if (ret == -1) {
      GST_WARNING_OBJECT (self, "do_handshake encountered BIO error");
    } else {
      GST_DEBUG_OBJECT (self, "do_handshake returned %d", ret);
    }
  }

  error = SSL_get_error (self->priv->ssl, ret);

  switch (error) {
    case SSL_ERROR_NONE:
      GST_WARNING_OBJECT (self, "no error, handshake should be done");
      break;
    case SSL_ERROR_SSL:
      GST_LOG_OBJECT (self, "SSL error %d: %s", error,
          ERR_error_string (ERR_get_error (), buf));
      break;
    case SSL_ERROR_WANT_READ:
      GST_LOG_OBJECT (self, "SSL wants read");
      break;
    case SSL_ERROR_WANT_WRITE:
      GST_LOG_OBJECT (self, "SSL wants write");
      break;
    case SSL_ERROR_SYSCALL:{
      GST_LOG_OBJECT (self, "SSL syscall (error) : %lu", ERR_get_error ());
      break;
    }
    default:
      GST_WARNING_OBJECT (self, "Unknown SSL error: %d, ret: %d", error, ret);
  }
}

static int
openssl_verify_callback (int preverify_ok, X509_STORE_CTX * x509_ctx)
{
  GstDtlsConnection *self;
  SSL *ssl;
  BIO *bio;
  gchar *pem = NULL;
  gboolean accepted = FALSE;

  ssl =
      X509_STORE_CTX_get_ex_data (x509_ctx,
      SSL_get_ex_data_X509_STORE_CTX_idx ());
  self = SSL_get_ex_data (ssl, connection_ex_index);
  g_return_val_if_fail (GST_IS_DTLS_CONNECTION (self), FALSE);

  pem = _gst_dtls_x509_to_pem (x509_ctx->cert);

  if (!pem) {
    GST_WARNING_OBJECT (self,
        "failed to convert received certificate to pem format");
  } else {
    bio = BIO_new (BIO_s_mem ());
    if (bio) {
      gchar buffer[2048];
      gint len;

      len =
          X509_NAME_print_ex (bio, X509_get_subject_name (x509_ctx->cert), 1,
          XN_FLAG_MULTILINE);
      BIO_read (bio, buffer, len);
      buffer[len] = '\0';
      GST_DEBUG_OBJECT (self, "Peer certificate received:\n%s", buffer);
      BIO_free (bio);
    } else {
      GST_DEBUG_OBJECT (self, "failed to create certificate print membio");
    }

    g_signal_emit (self, signals[SIGNAL_ON_PEER_CERTIFICATE], 0, pem,
        &accepted);
    g_free (pem);
  }

  return accepted;
}

/*
    ########  ####  #######
    ##     ##  ##  ##     ##
    ##     ##  ##  ##     ##
    ########   ##  ##     ##
    ##     ##  ##  ##     ##
    ##     ##  ##  ##     ##
    ########  ####  #######
*/

static BIO_METHOD custom_bio_methods = {
  BIO_TYPE_BIO,
  "stream",
  bio_method_write,
  bio_method_read,
  NULL,
  NULL,
  bio_method_ctrl,
  bio_method_new,
  bio_method_free,
  NULL,
};

static BIO_METHOD *
BIO_s_gst_dtls_connection (void)
{
  return &custom_bio_methods;
}

static int
bio_method_write (BIO * bio, const char *data, int size)
{
  GstDtlsConnection *self = GST_DTLS_CONNECTION (bio->ptr);

  GST_LOG_OBJECT (self, "BIO: writing %d", size);

  if (self->priv->send_closure) {
    GValue values[3] = { G_VALUE_INIT };

    g_value_init (&values[0], GST_TYPE_DTLS_CONNECTION);
    g_value_set_object (&values[0], self);

    g_value_init (&values[1], G_TYPE_POINTER);
    g_value_set_pointer (&values[1], (gpointer) data);

    g_value_init (&values[2], G_TYPE_INT);
    g_value_set_int (&values[2], size);

    g_closure_invoke (self->priv->send_closure, NULL, 3, values, NULL);
  }

  return size;
}

static int
bio_method_read (BIO * bio, char *out_buffer, int size)
{
  GstDtlsConnection *self = GST_DTLS_CONNECTION (bio->ptr);
  GstDtlsConnectionPrivate *priv = self->priv;
  guint internal_size;
  gint copy_size;

  internal_size = priv->bio_buffer_len - priv->bio_buffer_offset;

  if (!priv->bio_buffer) {
    GST_LOG_OBJECT (self, "BIO: EOF");
    return 0;
  }

  if (!out_buffer || size <= 0) {
    GST_WARNING_OBJECT (self, "BIO: read got invalid arguments");
    if (internal_size) {
      BIO_set_retry_read (bio);
    }
    return internal_size;
  }

  if (size > internal_size) {
    copy_size = internal_size;
  } else {
    copy_size = size;
  }

  GST_DEBUG_OBJECT (self,
      "reading %d/%d bytes %d at offset %d, output buff size is %d", copy_size,
      priv->bio_buffer_len, internal_size, priv->bio_buffer_offset, size);

  memcpy (out_buffer, (guint8 *) priv->bio_buffer + priv->bio_buffer_offset,
      copy_size);
  priv->bio_buffer_offset += copy_size;

  if (priv->bio_buffer_len == priv->bio_buffer_offset) {
    priv->bio_buffer = NULL;
  }

  return copy_size;
}

static long
bio_method_ctrl (BIO * bio, int cmd, long arg1, void *arg2)
{
  GstDtlsConnection *self = GST_DTLS_CONNECTION (bio->ptr);
  GstDtlsConnectionPrivate *priv = self->priv;

  switch (cmd) {
    case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
    case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
      GST_LOG_OBJECT (self, "BIO: Timeout set");
      priv->timeout_set = TRUE;
      g_cond_signal (&priv->condition);
      return 1;
    case BIO_CTRL_RESET:
      priv->bio_buffer = NULL;
      priv->bio_buffer_len = 0;
      priv->bio_buffer_offset = 0;
      GST_LOG_OBJECT (self, "BIO: EOF reset");
      return 1;
    case BIO_CTRL_EOF:{
      gint eof = !(priv->bio_buffer_len - priv->bio_buffer_offset);
      GST_LOG_OBJECT (self, "BIO: EOF query returned %d", eof);
      return eof;
    }
    case BIO_CTRL_WPENDING:
      GST_LOG_OBJECT (self, "BIO: pending write");
      return 1;
    case BIO_CTRL_PENDING:{
      gint pending = priv->bio_buffer_len - priv->bio_buffer_offset;
      GST_LOG_OBJECT (self, "BIO: %d bytes pending", pending);
      return pending;
    }
    case BIO_CTRL_FLUSH:
      GST_LOG_OBJECT (self, "BIO: flushing");
      return 1;
    case BIO_CTRL_DGRAM_QUERY_MTU:
      GST_DEBUG_OBJECT (self, "BIO: MTU query, returning 0...");
      return 0;
    case BIO_CTRL_DGRAM_MTU_EXCEEDED:
      GST_WARNING_OBJECT (self, "BIO: MTU exceeded");
      return 0;
    default:
      GST_LOG_OBJECT (self, "BIO: unhandled ctrl, %d", cmd);
      return 0;
  }
}

static int
bio_method_new (BIO * bio)
{
  GST_LOG_OBJECT (NULL, "BIO: new");

  bio->shutdown = 0;
  bio->init = 1;

  return 1;
}

static int
bio_method_free (BIO * bio)
{
  if (!bio) {
    GST_LOG_OBJECT (NULL, "BIO free called with null bio");
    return 0;
  }

  GST_LOG_OBJECT (GST_DTLS_CONNECTION (bio->ptr), "BIO free");
  return 0;
}
