/* GStreamer
 * Copyright (C) <2014> Wim Taymans <wim.taymans@gmail.com>
 *
 * gstmikey.h: various helper functions to manipulate mikey messages
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:gstmikey
 * @short_description: Helper methods for dealing with MIKEY messages
 *
 * <refsect2>
 * <para>
 * The GstMIKEY helper functions makes it easy to parse and create MIKEY
 * messages.
 * </para>
 * </refsect2>
 *
 * Since: 1.4
 */

#include <string.h>

#include "gstmikey.h"

GST_DEFINE_MINI_OBJECT_TYPE (GstMIKEYPayload, gst_mikey_payload);
GST_DEFINE_MINI_OBJECT_TYPE (GstMIKEYMessage, gst_mikey_message);

static void
payload_destroy (GstMIKEYPayload ** payload)
{
  gst_mikey_payload_unref (*payload);
}

#define INIT_ARRAY(field, type, init_func)              \
G_STMT_START {                                          \
  if (field)                                            \
    g_array_set_size ((field), 0);                      \
  else {                                                \
    (field) = g_array_new (FALSE, TRUE, sizeof (type)); \
    g_array_set_clear_func ((field), (GDestroyNotify)init_func);        \
  }                                                     \
} G_STMT_END

#define FREE_ARRAY(field)         \
G_STMT_START {                    \
  if (field)                      \
    g_array_free ((field), TRUE); \
  (field) = NULL;                 \
} G_STMT_END

#define INIT_MEMDUP(field, data, len)            \
G_STMT_START {                                   \
  g_free ((field));                              \
  (field) = g_memdup (data, len);                \
} G_STMT_END
#define FREE_MEMDUP(field)                       \
G_STMT_START {                                   \
  g_free ((field));                              \
  (field) = NULL;                                \
} G_STMT_END


/* Key data transport payload (KEMAC) */
static guint
get_mac_len (GstMIKEYMacAlg mac_alg)
{
  guint len;

  switch (mac_alg) {
    case GST_MIKEY_MAC_NULL:
      len = 0;                  /* no MAC key */
      break;
    case GST_MIKEY_MAC_HMAC_SHA_1_160:
      len = 20;                 /* 160 bits key */
      break;
    default:
      len = -1;
      break;
  }
  return len;
}

/**
 * gst_mikey_payload_kemac_set:
 * @payload: a #GstMIKEYPayload
 * @enc_alg: the #GstMIKEYEncAlg
 * @mac_alg: a #GstMIKEYMacAlg
 *
 * Set the KEMAC parameters. @payload should point to a %GST_MIKEY_PT_KEMAC
 * payload.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_payload_kemac_set (GstMIKEYPayload * payload,
    GstMIKEYEncAlg enc_alg, GstMIKEYMacAlg mac_alg)
{
  GstMIKEYPayloadKEMAC *p = (GstMIKEYPayloadKEMAC *) payload;

  g_return_val_if_fail (payload != NULL, FALSE);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_KEMAC, FALSE);

  p->enc_alg = enc_alg;
  p->mac_alg = mac_alg;
  INIT_ARRAY (p->subpayloads, GstMIKEYPayload *, payload_destroy);

  return TRUE;
}

static gboolean
gst_mikey_payload_kemac_dispose (GstMIKEYPayloadKEMAC * payload)
{
  FREE_ARRAY (payload->subpayloads);

  return TRUE;
}

static GstMIKEYPayloadKEMAC *
gst_mikey_payload_kemac_copy (const GstMIKEYPayloadKEMAC * payload)
{
  guint i, len;
  GstMIKEYPayloadKEMAC *copy = g_slice_dup (GstMIKEYPayloadKEMAC, payload);
  gst_mikey_payload_kemac_set (&copy->pt, payload->enc_alg, payload->mac_alg);
  len = payload->subpayloads->len;
  for (i = 0; i < len; i++) {
    GstMIKEYPayload *pay =
        g_array_index (payload->subpayloads, GstMIKEYPayload *, i);
    gst_mikey_payload_kemac_add_sub (&copy->pt, gst_mikey_payload_copy (pay));
  }
  return copy;
}

/**
 * gst_mikey_payload_kemac_get_n_sub:
 * @payload: a #GstMIKEYPayload
 *
 * Get the number of sub payloads of @payload. @payload should be of type
 * %GST_MIKEY_PT_KEMAC.
 *
 * Returns: the number of sub payloads in @payload
 *
 * Since: 1.4
 */
guint
gst_mikey_payload_kemac_get_n_sub (const GstMIKEYPayload * payload)
{
  GstMIKEYPayloadKEMAC *p = (GstMIKEYPayloadKEMAC *) payload;

  g_return_val_if_fail (payload != NULL, 0);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_KEMAC, 0);

  return p->subpayloads->len;
}

/**
 * gst_mikey_payload_kemac_get_sub:
 * @payload: a #GstMIKEYPayload
 * @idx: an index
 *
 * Get the sub payload of @payload at @idx. @payload should be of type
 * %GST_MIKEY_PT_KEMAC.
 *
 * Returns: (transfer none): the #GstMIKEYPayload at @idx.
 *
 * Since: 1.4
 */
const GstMIKEYPayload *
gst_mikey_payload_kemac_get_sub (const GstMIKEYPayload * payload, guint idx)
{
  GstMIKEYPayloadKEMAC *p = (GstMIKEYPayloadKEMAC *) payload;

  g_return_val_if_fail (payload != NULL, 0);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_KEMAC, 0);

  if (p->subpayloads->len <= idx)
    return NULL;

  return g_array_index (p->subpayloads, GstMIKEYPayload *, idx);
}

/**
 * gst_mikey_payload_kemac_remove_sub:
 * @payload: a #GstMIKEYPayload
 * @idx: the index to remove
 *
 * Remove the sub payload at @idx in @payload.
 *
 * Returns: %TRUE on success.
 *
 * Since: 1.4
 */
gboolean
gst_mikey_payload_kemac_remove_sub (GstMIKEYPayload * payload, guint idx)
{
  GstMIKEYPayloadKEMAC *p = (GstMIKEYPayloadKEMAC *) payload;

  g_return_val_if_fail (payload != NULL, 0);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_KEMAC, 0);
  g_return_val_if_fail (p->subpayloads->len > idx, FALSE);

  g_array_remove_index (p->subpayloads, idx);

  return TRUE;
}

/**
 * gst_mikey_payload_kemac_add_sub:
 * @payload: a #GstMIKEYPayload
 * @newpay: (transfer full): a #GstMIKEYPayload to add
 *
 * Add a new sub payload to @payload.
 *
 * Returns: %TRUE on success.
 *
 * Since: 1.4
 */
gboolean
gst_mikey_payload_kemac_add_sub (GstMIKEYPayload * payload,
    GstMIKEYPayload * newpay)
{
  GstMIKEYPayloadKEMAC *p = (GstMIKEYPayloadKEMAC *) payload;

  g_return_val_if_fail (payload != NULL, 0);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_KEMAC, 0);

  g_array_append_val (p->subpayloads, newpay);

  return TRUE;
}

/* Envelope data payload (PKE) */
/**
 * gst_mikey_payload_pke_set:
 * @payload: a #GstMIKEYPayload
 * @C: envelope key cache indicator
 * @data_len: the length of @data
 * @data: (array length=data_len): the encrypted envelope key
 *
 * Set the PKE values in @payload. @payload must be of type
 * %GST_MIKEY_PT_PKE.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_payload_pke_set (GstMIKEYPayload * payload, GstMIKEYCacheType C,
    guint16 data_len, const guint8 * data)
{
  GstMIKEYPayloadPKE *p = (GstMIKEYPayloadPKE *) payload;

  g_return_val_if_fail (payload != NULL, FALSE);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_PKE, FALSE);

  p->C = C;
  p->data_len = data_len;
  INIT_MEMDUP (p->data, data, data_len);

  return TRUE;
}

static gboolean
gst_mikey_payload_pke_dispose (GstMIKEYPayloadPKE * payload)
{
  FREE_MEMDUP (payload->data);

  return TRUE;
}

static GstMIKEYPayloadPKE *
gst_mikey_payload_pke_copy (const GstMIKEYPayloadPKE * payload)
{
  GstMIKEYPayloadPKE *copy = g_slice_dup (GstMIKEYPayloadPKE, payload);
  gst_mikey_payload_pke_set (&copy->pt, payload->C, payload->data_len,
      payload->data);
  return copy;
}

/* DH data payload (DH) */
/* Signature payload (SIGN) */

/* Timestamp payload (T) */
static guint
get_ts_len (GstMIKEYTSType type)
{
  guint len;

  switch (type) {
    case GST_MIKEY_TS_TYPE_NTP_UTC:
    case GST_MIKEY_TS_TYPE_NTP:
      len = 8;
      break;
    case GST_MIKEY_TS_TYPE_COUNTER:
      len = 4;
      break;
    default:
      len = -1;
      break;
  }
  return len;
}

/**
 * gst_mikey_payload_t_set:
 * @payload: a #GstMIKEYPayload
 * @type: the #GstMIKEYTSType
 * @ts_value: (array): the timestamp value
 *
 * Set the timestamp in a %GST_MIKEY_PT_T @payload.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_payload_t_set (GstMIKEYPayload * payload,
    GstMIKEYTSType type, const guint8 * ts_value)
{
  GstMIKEYPayloadT *p = (GstMIKEYPayloadT *) payload;
  guint ts_len;

  g_return_val_if_fail (payload != NULL, FALSE);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_T, FALSE);

  if ((ts_len = get_ts_len (type)) == -1)
    return FALSE;

  p->type = type;
  INIT_MEMDUP (p->ts_value, ts_value, ts_len);

  return TRUE;
}

static gboolean
gst_mikey_payload_t_dispose (GstMIKEYPayloadT * payload)
{
  FREE_MEMDUP (payload->ts_value);

  return TRUE;
}

static GstMIKEYPayloadT *
gst_mikey_payload_t_copy (const GstMIKEYPayloadT * payload)
{
  GstMIKEYPayloadT *copy = g_slice_dup (GstMIKEYPayloadT, payload);
  gst_mikey_payload_t_set (&copy->pt, payload->type, payload->ts_value);
  return copy;
}

/* ID payload (ID) */
/* Certificate Payload (CERT) */
/* Cert hash payload (CHASH)*/
/* Ver msg payload (V) */
/* Security Policy payload (SP)*/
static void
param_clear (GstMIKEYPayloadSPParam * param)
{
  FREE_MEMDUP (param->val);
}

/**
 * gst_mikey_payload_sp_set:
 * @payload: a #GstMIKEYPayload
 * @policy: the policy number
 * @proto: a #GstMIKEYSecProto
 *
 * Set the Security Policy parameters for @payload.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_payload_sp_set (GstMIKEYPayload * payload,
    guint policy, GstMIKEYSecProto proto)
{
  GstMIKEYPayloadSP *p = (GstMIKEYPayloadSP *) payload;

  g_return_val_if_fail (payload != NULL, FALSE);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_SP, FALSE);

  p->policy = policy;
  p->proto = proto;
  INIT_ARRAY (p->params, GstMIKEYPayloadSPParam, param_clear);

  return TRUE;
}

static gboolean
gst_mikey_payload_sp_dispose (GstMIKEYPayloadSP * payload)
{
  FREE_ARRAY (payload->params);

  return TRUE;
}

static GstMIKEYPayloadSP *
gst_mikey_payload_sp_copy (const GstMIKEYPayloadSP * payload)
{
  guint i, len;
  GstMIKEYPayloadSP *copy = g_slice_dup (GstMIKEYPayloadSP, payload);
  gst_mikey_payload_sp_set (&copy->pt, payload->policy, payload->proto);
  len = payload->params->len;
  for (i = 0; i < len; i++) {
    GstMIKEYPayloadSPParam *param = &g_array_index (payload->params,
        GstMIKEYPayloadSPParam, i);
    gst_mikey_payload_sp_add_param (&copy->pt, param->type, param->len,
        param->val);
  }
  return copy;
}

/**
 * gst_mikey_payload_sp_get_n_params:
 * @payload: a #GstMIKEYPayload
 *
 * Get the number of security policy parameters in a %GST_MIKEY_PT_SP
 * @payload.
 *
 * Returns: the number of parameters in @payload
 *
 * Since: 1.4
 */
guint
gst_mikey_payload_sp_get_n_params (const GstMIKEYPayload * payload)
{
  GstMIKEYPayloadSP *p = (GstMIKEYPayloadSP *) payload;

  g_return_val_if_fail (payload != NULL, 0);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_SP, 0);

  return p->params->len;

}

/**
 * gst_mikey_payload_sp_get_param:
 * @payload: a #GstMIKEYPayload
 * @idx: an index
 *
 * Get the Security Policy parameter in a %GST_MIKEY_PT_SP @payload
 * at @idx.
 *
 * Returns: the #GstMIKEYPayloadSPParam at @idx in @payload
 *
 * Since: 1.4
 */
const GstMIKEYPayloadSPParam *
gst_mikey_payload_sp_get_param (const GstMIKEYPayload * payload, guint idx)
{
  GstMIKEYPayloadSP *p = (GstMIKEYPayloadSP *) payload;

  g_return_val_if_fail (payload != NULL, NULL);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_SP, NULL);

  if (p->params->len <= idx)
    return NULL;

  return &g_array_index (p->params, GstMIKEYPayloadSPParam, idx);
}

/**
 * gst_mikey_payload_sp_remove_param:
 * @payload: a #GstMIKEYPayload
 * @idx: an index
 *
 * Remove the Security Policy parameters from a %GST_MIKEY_PT_SP
 * @payload at @idx.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_payload_sp_remove_param (GstMIKEYPayload * payload, guint idx)
{
  GstMIKEYPayloadSP *p = (GstMIKEYPayloadSP *) payload;

  g_return_val_if_fail (payload != NULL, FALSE);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_SP, FALSE);
  g_return_val_if_fail (p->params->len > idx, FALSE);

  g_array_remove_index (p->params, idx);

  return TRUE;
}

/**
 * gst_mikey_payload_sp_add_param:
 * @payload: a #GstMIKEYPayload
 * @type: a type
 * @len: a length
 * @val: (array length=len): @len bytes of data
 *
 * Add a new parameter to the %GST_MIKEY_PT_SP @payload with @type, @len
 * and @val.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_payload_sp_add_param (GstMIKEYPayload * payload,
    guint8 type, guint8 len, const guint8 * val)
{
  GstMIKEYPayloadSPParam param = { 0 };
  GstMIKEYPayloadSP *p = (GstMIKEYPayloadSP *) payload;

  g_return_val_if_fail (payload != NULL, FALSE);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_SP, FALSE);

  param.type = type;
  param.len = len;
  INIT_MEMDUP (param.val, val, len);

  g_array_append_val (p->params, param);

  return TRUE;
}

/* RAND payload (RAND) */
/**
 * gst_mikey_payload_rand_set:
 * @payload: a #GstMIKEYPayload
 * @len: the length of @rand
 * @rand: (array length=len): random values
 *
 * Set the random values in a %GST_MIKEY_PT_RAND @payload.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_payload_rand_set (GstMIKEYPayload * payload, guint8 len,
    const guint8 * rand)
{
  GstMIKEYPayloadRAND *p = (GstMIKEYPayloadRAND *) payload;

  g_return_val_if_fail (payload != NULL, FALSE);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_RAND, FALSE);

  p->len = len;
  INIT_MEMDUP (p->rand, rand, len);

  return TRUE;
}

static gboolean
gst_mikey_payload_rand_dispose (GstMIKEYPayloadRAND * payload)
{
  FREE_MEMDUP (payload->rand);

  return TRUE;
}

static GstMIKEYPayloadRAND *
gst_mikey_payload_rand_copy (const GstMIKEYPayloadRAND * payload)
{
  GstMIKEYPayloadRAND *copy = g_slice_dup (GstMIKEYPayloadRAND, payload);
  gst_mikey_payload_rand_set (&copy->pt, payload->len, payload->rand);
  return copy;
}



/* Error payload (ERR) */
/* Key data sub-payload */

/**
 * gst_mikey_payload_key_data_set_key:
 * @payload: a #GstMIKEYPayload
 * @key_type: a #GstMIKEYKeyDataType
 * @key_len: the length of @key_data
 * @key_data: (array length=key_len): the key of type @key_type
 *
 * Set @key_len bytes of @key_data of type @key_type as the key for the
 * %GST_MIKEY_PT_KEY_DATA @payload.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_payload_key_data_set_key (GstMIKEYPayload * payload,
    GstMIKEYKeyDataType key_type, guint16 key_len, const guint8 * key_data)
{
  GstMIKEYPayloadKeyData *p = (GstMIKEYPayloadKeyData *) payload;

  g_return_val_if_fail (payload != NULL, FALSE);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_KEY_DATA, FALSE);
  g_return_val_if_fail (key_len > 0 && key_data != NULL, FALSE);

  p->key_type = key_type;
  p->key_len = key_len;
  INIT_MEMDUP (p->key_data, key_data, key_len);

  return TRUE;
}

/**
 * gst_mikey_payload_key_data_set_salt:
 * @payload: a #GstMIKEYPayload
 * @salt_len: the length of @salt_data
 * @salt_data: (array length=salt_len) (allow-none): the salt
 *
 * Set the salt key data. If @salt_len is 0 and @salt_data is %NULL, the
 * salt data will be removed.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_payload_key_data_set_salt (GstMIKEYPayload * payload,
    guint16 salt_len, const guint8 * salt_data)
{
  GstMIKEYPayloadKeyData *p = (GstMIKEYPayloadKeyData *) payload;

  g_return_val_if_fail (payload != NULL, FALSE);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_KEY_DATA, FALSE);
  g_return_val_if_fail ((salt_len == 0 && salt_data == NULL) ||
      (salt_len > 0 && salt_data != NULL), FALSE);

  p->salt_len = salt_len;
  INIT_MEMDUP (p->salt_data, salt_data, salt_len);

  return TRUE;
}

/* Key validity data */

/**
 * gst_mikey_payload_key_data_set_spi:
 * @payload: a #GstMIKEYPayload
 * @spi_len: the length of @spi_data
 * @spi_data: (array length=spi_len): the SPI/MKI data
 *
 * Set the SPI/MKI validity in the %GST_MIKEY_PT_KEY_DATA @payload.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_payload_key_data_set_spi (GstMIKEYPayload * payload,
    guint8 spi_len, const guint8 * spi_data)
{
  GstMIKEYPayloadKeyData *p = (GstMIKEYPayloadKeyData *) payload;

  g_return_val_if_fail (payload != NULL, FALSE);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_KEY_DATA, FALSE);
  g_return_val_if_fail ((spi_len == 0 && spi_data == NULL) ||
      (spi_len > 0 && spi_data != NULL), FALSE);

  p->kv_type = GST_MIKEY_KV_SPI;
  p->kv_len[0] = spi_len;
  INIT_MEMDUP (p->kv_data[0], spi_data, spi_len);
  p->kv_len[1] = 0;
  FREE_MEMDUP (p->kv_data[1]);

  return TRUE;
}

/**
 * gst_mikey_payload_key_data_set_interval:
 * @payload: a #GstMIKEYPayload
 * @vf_len: the length of @vf_data
 * @vf_data: (array length=vf_data): the Valid From data
 * @vt_len: the length of @vt_data
 * @vt_data: (array length=vt_len): the Valid To data
 *
 * Set the key validity period in the %GST_MIKEY_PT_KEY_DATA @payload.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_payload_key_data_set_interval (GstMIKEYPayload * payload,
    guint8 vf_len, const guint8 * vf_data, guint8 vt_len,
    const guint8 * vt_data)
{
  GstMIKEYPayloadKeyData *p = (GstMIKEYPayloadKeyData *) payload;

  g_return_val_if_fail (payload != NULL, FALSE);
  g_return_val_if_fail (payload->type == GST_MIKEY_PT_KEY_DATA, FALSE);
  g_return_val_if_fail ((vf_len == 0 && vf_data == NULL) ||
      (vf_len > 0 && vf_data != NULL), FALSE);
  g_return_val_if_fail ((vt_len == 0 && vt_data == NULL) ||
      (vt_len > 0 && vt_data != NULL), FALSE);

  p->kv_type = GST_MIKEY_KV_INTERVAL;
  p->kv_len[0] = vf_len;
  INIT_MEMDUP (p->kv_data[0], vf_data, vf_len);
  p->kv_len[1] = vt_len;
  INIT_MEMDUP (p->kv_data[1], vt_data, vt_len);

  return TRUE;
}

static gboolean
gst_mikey_payload_key_data_dispose (GstMIKEYPayloadKeyData * payload)
{
  FREE_MEMDUP (payload->key_data);
  FREE_MEMDUP (payload->salt_data);
  FREE_MEMDUP (payload->kv_data[0]);
  FREE_MEMDUP (payload->kv_data[1]);

  return TRUE;
}

static GstMIKEYPayloadKeyData *
gst_mikey_payload_key_data_copy (const GstMIKEYPayloadKeyData * payload)
{
  GstMIKEYPayloadKeyData *copy = g_slice_dup (GstMIKEYPayloadKeyData, payload);
  gst_mikey_payload_key_data_set_key (&copy->pt, payload->key_type,
      payload->key_len, payload->key_data);
  gst_mikey_payload_key_data_set_salt (&copy->pt, payload->salt_len,
      payload->salt_data);
  if (payload->kv_type == GST_MIKEY_KV_SPI)
    gst_mikey_payload_key_data_set_spi (&copy->pt, payload->kv_len[0],
        payload->kv_data[0]);
  else if (payload->kv_type == GST_MIKEY_KV_INTERVAL)
    gst_mikey_payload_key_data_set_interval (&copy->pt, payload->kv_len[0],
        payload->kv_data[0], payload->kv_len[1], payload->kv_data[1]);
  else {
    FREE_MEMDUP (copy->kv_data[0]);
    FREE_MEMDUP (copy->kv_data[1]);
  }
  return copy;
}

/* General Extension Payload */

static void
mikey_payload_free (GstMIKEYPayload * payload)
{
  g_slice_free1 (payload->len, payload);
}


/**
 * gst_mikey_payload_new:
 * @type: a #GstMIKEYPayloadType
 *
 * Make a new #GstMIKEYPayload with @type.
 *
 * Returns: (nullable): a new #GstMIKEYPayload or %NULL on failure.
 *
 * Since: 1.4
 */
GstMIKEYPayload *
gst_mikey_payload_new (GstMIKEYPayloadType type)
{
  guint len = 0;
  GstMIKEYPayload *result;
  GstMiniObjectCopyFunction copy;
  GstMiniObjectDisposeFunction clear;

  switch (type) {
    case GST_MIKEY_PT_KEMAC:
      len = sizeof (GstMIKEYPayloadKEMAC);
      clear = (GstMiniObjectDisposeFunction) gst_mikey_payload_kemac_dispose;
      copy = (GstMiniObjectCopyFunction) gst_mikey_payload_kemac_copy;
      break;
    case GST_MIKEY_PT_T:
      len = sizeof (GstMIKEYPayloadT);
      clear = (GstMiniObjectDisposeFunction) gst_mikey_payload_t_dispose;
      copy = (GstMiniObjectCopyFunction) gst_mikey_payload_t_copy;
      break;
    case GST_MIKEY_PT_PKE:
      len = sizeof (GstMIKEYPayloadPKE);
      clear = (GstMiniObjectDisposeFunction) gst_mikey_payload_pke_dispose;
      copy = (GstMiniObjectCopyFunction) gst_mikey_payload_pke_copy;
      break;
    case GST_MIKEY_PT_DH:
    case GST_MIKEY_PT_SIGN:
    case GST_MIKEY_PT_ID:
    case GST_MIKEY_PT_CERT:
    case GST_MIKEY_PT_CHASH:
    case GST_MIKEY_PT_V:
    case GST_MIKEY_PT_SP:
      len = sizeof (GstMIKEYPayloadSP);
      clear = (GstMiniObjectDisposeFunction) gst_mikey_payload_sp_dispose;
      copy = (GstMiniObjectCopyFunction) gst_mikey_payload_sp_copy;
      break;
    case GST_MIKEY_PT_RAND:
      len = sizeof (GstMIKEYPayloadRAND);
      clear = (GstMiniObjectDisposeFunction) gst_mikey_payload_rand_dispose;
      copy = (GstMiniObjectCopyFunction) gst_mikey_payload_rand_copy;
      break;
    case GST_MIKEY_PT_ERR:
      break;
    case GST_MIKEY_PT_KEY_DATA:
      len = sizeof (GstMIKEYPayloadKeyData);
      clear = (GstMiniObjectDisposeFunction) gst_mikey_payload_key_data_dispose;
      copy = (GstMiniObjectCopyFunction) gst_mikey_payload_key_data_copy;
      break;
    case GST_MIKEY_PT_GEN_EXT:
    case GST_MIKEY_PT_LAST:
      break;
  }
  if (len == 0)
    return NULL;

  result = g_slice_alloc0 (len);
  gst_mini_object_init (GST_MINI_OBJECT_CAST (result),
      0, GST_TYPE_MIKEY_PAYLOAD, copy, clear,
      (GstMiniObjectFreeFunction) mikey_payload_free);
  result->type = type;
  result->len = len;

  return result;
}

static GstMIKEYMessage *
mikey_message_copy (GstMIKEYMessage * msg)
{
  GstMIKEYMessage *copy;
  guint i, len;

  copy = gst_mikey_message_new ();

  gst_mikey_message_set_info (copy, msg->version, msg->type, msg->V,
      msg->prf_func, msg->CSB_id, msg->map_type);

  len = msg->map_info->len;
  for (i = 0; i < len; i++) {
    const GstMIKEYMapSRTP *srtp = gst_mikey_message_get_cs_srtp (msg, i);
    gst_mikey_message_add_cs_srtp (copy, srtp->policy, srtp->ssrc, srtp->roc);
  }

  len = msg->payloads->len;
  for (i = 0; i < len; i++) {
    const GstMIKEYPayload *pay = gst_mikey_message_get_payload (msg, i);
    gst_mikey_message_add_payload (copy, gst_mikey_payload_copy (pay));
  }
  return copy;
}

static void
mikey_message_free (GstMIKEYMessage * msg)
{
  FREE_ARRAY (msg->map_info);
  FREE_ARRAY (msg->payloads);

  g_slice_free (GstMIKEYMessage, msg);
}

/**
 * gst_mikey_message_new:
 *
 * Make a new MIKEY message.
 *
 * Returns: a new #GstMIKEYMessage on success
 *
 * Since: 1.4
 */
GstMIKEYMessage *
gst_mikey_message_new (void)
{
  GstMIKEYMessage *result;

  result = g_slice_new0 (GstMIKEYMessage);
  gst_mini_object_init (GST_MINI_OBJECT_CAST (result),
      0, GST_TYPE_MIKEY_MESSAGE,
      (GstMiniObjectCopyFunction) mikey_message_copy, NULL,
      (GstMiniObjectFreeFunction) mikey_message_free);

  INIT_ARRAY (result->map_info, GstMIKEYMapSRTP, NULL);
  INIT_ARRAY (result->payloads, GstMIKEYPayload *, payload_destroy);

  return result;
}

/**
 * gst_mikey_message_new_from_bytes:
 * @bytes: a #GBytes
 * @info: a #GstMIKEYDecryptInfo
 * @error: a #GError
 *
 * Make a new #GstMIKEYMessage from @bytes.
 *
 * Returns: a new #GstMIKEYMessage
 *
 * Since: 1.4
 */
GstMIKEYMessage *
gst_mikey_message_new_from_bytes (GBytes * bytes, GstMIKEYDecryptInfo * info,
    GError ** error)
{
  gconstpointer data;
  gsize size;

  g_return_val_if_fail (bytes != NULL, NULL);

  data = g_bytes_get_data (bytes, &size);
  return gst_mikey_message_new_from_data (data, size, info, error);
}

/**
 * gst_mikey_message_set_info:
 * @msg: a #GstMIKEYMessage
 * @version: a version
 * @type: a #GstMIKEYType
 * @V: verify flag
 * @prf_func: the #GstMIKEYPRFFunc function to use
 * @CSB_id: the Crypto Session Bundle id
 * @map_type: the #GstMIKEYCSIDMapType
 *
 * Set the information in @msg.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_message_set_info (GstMIKEYMessage * msg, guint8 version,
    GstMIKEYType type, gboolean V, GstMIKEYPRFFunc prf_func, guint32 CSB_id,
    GstMIKEYMapType map_type)
{
  g_return_val_if_fail (msg != NULL, FALSE);

  msg->version = version;
  msg->type = type;
  msg->V = V;
  msg->prf_func = prf_func;
  msg->CSB_id = CSB_id;
  msg->map_type = map_type;

  return TRUE;
}

/**
 * gst_mikey_message_get_n_cs:
 * @msg: a #GstMIKEYMessage
 *
 * Get the number of crypto sessions in @msg.
 *
 * Returns: the number of crypto sessions
 *
 * Since: 1.4
 */
guint
gst_mikey_message_get_n_cs (const GstMIKEYMessage * msg)
{
  g_return_val_if_fail (msg != NULL, 0);

  return msg->map_info->len;
}

/**
 * gst_mikey_message_get_cs_srtp:
 * @msg: a #GstMIKEYMessage
 * @idx: an index
 *
 * Get the policy information of @msg at @idx.
 *
 * Returns: a #GstMIKEYMapSRTP
 *
 * Since: 1.4
 */
const GstMIKEYMapSRTP *
gst_mikey_message_get_cs_srtp (const GstMIKEYMessage * msg, guint idx)
{
  g_return_val_if_fail (msg != NULL, NULL);
  g_return_val_if_fail (msg->map_type == GST_MIKEY_MAP_TYPE_SRTP, NULL);

  if (msg->map_info->len <= idx)
    return NULL;

  return &g_array_index (msg->map_info, GstMIKEYMapSRTP, idx);
}

/**
 * gst_mikey_message_insert_cs_srtp:
 * @msg: a #GstMIKEYMessage
 * @idx: the index to insert at
 * @map: the map info
 *
 * Insert a Crypto Session map for SRTP in @msg at @idx
 *
 * When @idx is -1, the policy will be appended.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_message_insert_cs_srtp (GstMIKEYMessage * msg, gint idx,
    const GstMIKEYMapSRTP * map)
{
  g_return_val_if_fail (msg != NULL, FALSE);
  g_return_val_if_fail (msg->map_type == GST_MIKEY_MAP_TYPE_SRTP, FALSE);
  g_return_val_if_fail (map != NULL, FALSE);
  g_return_val_if_fail (idx == -1 || msg->map_info->len > idx, FALSE);

  if (idx == -1)
    g_array_append_val (msg->map_info, *map);
  else
    g_array_insert_val (msg->map_info, idx, *map);

  return TRUE;
}

/**
 * gst_mikey_message_replace_cs_srtp:
 * @msg: a #GstMIKEYMessage
 * @idx: the index to insert at
 * @map: the map info
 *
 * Replace a Crypto Session map for SRTP in @msg at @idx with @map.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_message_replace_cs_srtp (GstMIKEYMessage * msg, gint idx,
    const GstMIKEYMapSRTP * map)
{
  g_return_val_if_fail (msg != NULL, FALSE);
  g_return_val_if_fail (msg->map_type == GST_MIKEY_MAP_TYPE_SRTP, FALSE);
  g_return_val_if_fail (map != NULL, FALSE);
  g_return_val_if_fail (msg->map_info->len > idx, FALSE);

  g_array_index (msg->map_info, GstMIKEYMapSRTP, idx) = *map;

  return TRUE;
}

/**
 * gst_mikey_message_remove_cs_srtp:
 * @msg: a #GstMIKEYMessage
 * @idx: the index to remove
 *
 * Remove the SRTP policy at @idx.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_message_remove_cs_srtp (GstMIKEYMessage * msg, gint idx)
{
  g_return_val_if_fail (msg != NULL, FALSE);
  g_return_val_if_fail (msg->map_type == GST_MIKEY_MAP_TYPE_SRTP, FALSE);
  g_return_val_if_fail (msg->map_info->len > idx, FALSE);

  g_array_remove_index (msg->map_info, idx);

  return TRUE;
}

/**
 * gst_mikey_message_add_cs_srtp:
 * @msg: a #GstMIKEYMessage
 * @policy: The security policy applied for the stream with @ssrc
 * @ssrc: the SSRC that must be used for the stream
 * @roc: current rollover counter
 *
 * Add a Crypto policy for SRTP to @msg.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_message_add_cs_srtp (GstMIKEYMessage * msg, guint8 policy,
    guint32 ssrc, guint32 roc)
{
  GstMIKEYMapSRTP val;

  g_return_val_if_fail (msg != NULL, FALSE);
  g_return_val_if_fail (msg->map_type == GST_MIKEY_MAP_TYPE_SRTP, FALSE);

  val.policy = policy;
  val.ssrc = ssrc;
  val.roc = roc;

  return gst_mikey_message_insert_cs_srtp (msg, -1, &val);
}

/* adding/retrieving payloads */
/**
 * gst_mikey_message_get_n_payloads:
 * @msg: a #GstMIKEYMessage
 *
 * Get the number of payloads in @msg.
 *
 * Returns: the number of payloads in @msg
 *
 * Since: 1.4
 */
guint
gst_mikey_message_get_n_payloads (const GstMIKEYMessage * msg)
{
  g_return_val_if_fail (msg != NULL, 0);

  return msg->payloads->len;
}

/**
 * gst_mikey_message_get_payload:
 * @msg: a #GstMIKEYMessage
 * @idx: an index
 *
 * Get the #GstMIKEYPayload at @idx in @msg
 *
 * Returns: (transfer none): the #GstMIKEYPayload at @idx. The payload
 * remains valid for as long as it is part of @msg.
 *
 * Since: 1.4
 */
const GstMIKEYPayload *
gst_mikey_message_get_payload (const GstMIKEYMessage * msg, guint idx)
{
  g_return_val_if_fail (msg != NULL, NULL);

  if (idx >= msg->payloads->len)
    return NULL;

  return g_array_index (msg->payloads, GstMIKEYPayload *, idx);
}

/**
 * gst_mikey_message_find_payload:
 * @msg: a #GstMIKEYMessage
 * @type: a #GstMIKEYPayloadType
 * @nth: payload to find
 *
 * Find the @nth occurence of the payload with @type in @msg.
 *
 * Returns: the @nth #GstMIKEYPayload of @type.
 *
 * Since: 1.4
 */
const GstMIKEYPayload *
gst_mikey_message_find_payload (const GstMIKEYMessage * msg,
    GstMIKEYPayloadType type, guint idx)
{
  guint i, len, count;

  count = 0;
  len = msg->payloads->len;
  for (i = 0; i < len; i++) {
    GstMIKEYPayload *payload =
        g_array_index (msg->payloads, GstMIKEYPayload *, i);

    if (payload->type == type) {
      if (count == idx)
        return payload;

      count++;
    }
  }
  return NULL;
}

/**
 * gst_mikey_message_remove_payload:
 * @msg: a #GstMIKEYMessage
 * @idx: an index
 *
 * Remove the payload in @msg at @idx
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_message_remove_payload (GstMIKEYMessage * msg, guint idx)
{
  g_return_val_if_fail (msg != NULL, FALSE);
  g_return_val_if_fail (msg->payloads->len > idx, FALSE);

  g_array_remove_index (msg->payloads, idx);

  return TRUE;
}

/**
 * gst_mikey_message_insert_payload:
 * @msg: a #GstMIKEYMessage
 * @idx: an index
 * @payload: (transfer full): a #GstMIKEYPayload
 *
 * Insert the @payload at index @idx in @msg. If @idx is -1, the payload
 * will be appended to @msg.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_message_insert_payload (GstMIKEYMessage * msg, guint idx,
    GstMIKEYPayload * payload)
{
  g_return_val_if_fail (msg != NULL, FALSE);
  g_return_val_if_fail (payload != NULL, FALSE);
  g_return_val_if_fail (idx == -1 || msg->payloads->len > idx, FALSE);

  if (idx == -1)
    g_array_append_val (msg->payloads, payload);
  else
    g_array_insert_val (msg->payloads, idx, payload);

  return TRUE;
}

/**
 * gst_mikey_message_add_payload:
 * @msg: a #GstMIKEYMessage
 * @payload: (transfer full): a #GstMIKEYPayload
 *
 * Add a new payload to @msg.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_message_add_payload (GstMIKEYMessage * msg, GstMIKEYPayload * payload)
{
  return gst_mikey_message_insert_payload (msg, -1, payload);
}

/**
 * gst_mikey_message_replace_payload:
 * @msg: a #GstMIKEYMessage
 * @idx: an index
 * @payload: (transfer full): a #GstMIKEYPayload
 *
 * Replace the payload at @idx in @msg with @payload.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_message_replace_payload (GstMIKEYMessage * msg, guint idx,
    GstMIKEYPayload * payload)
{
  GstMIKEYPayload *p;

  g_return_val_if_fail (msg != NULL, FALSE);
  g_return_val_if_fail (payload != NULL, FALSE);
  g_return_val_if_fail (msg->payloads->len > idx, FALSE);

  p = g_array_index (msg->payloads, GstMIKEYPayload *, idx);
  gst_mikey_payload_unref (p);
  g_array_index (msg->payloads, GstMIKEYPayload *, idx) = payload;

  return TRUE;
}

/**
 * gst_mikey_message_add_pke:
 * @msg: a #GstMIKEYMessage
 * @C: envelope key cache indicator
 * @data_len: the length of @data
 * @data: (array length=data_len): the encrypted envelope key
 *
 * Add a new PKE payload to @msg with the given parameters.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_message_add_pke (GstMIKEYMessage * msg, GstMIKEYCacheType C,
    guint16 data_len, const guint8 * data)
{
  GstMIKEYPayload *p;

  g_return_val_if_fail (msg != NULL, FALSE);

  p = gst_mikey_payload_new (GST_MIKEY_PT_PKE);
  if (!gst_mikey_payload_pke_set (p, C, data_len, data)) {
    gst_mikey_payload_unref (p);
    return FALSE;
  }

  return gst_mikey_message_insert_payload (msg, -1, p);
}

/**
 * gst_mikey_message_add_t:
 * @msg: a #GstMIKEYMessage
 * @type: specifies the timestamp type used
 * @ts_value: (array): The timestamp value of the specified @type
 *
 * Add a new T payload to @msg with the given parameters.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_message_add_t (GstMIKEYMessage * msg, GstMIKEYTSType type,
    const guint8 * ts_value)
{
  GstMIKEYPayload *p;

  g_return_val_if_fail (msg != NULL, FALSE);

  p = gst_mikey_payload_new (GST_MIKEY_PT_T);
  if (!gst_mikey_payload_t_set (p, type, ts_value)) {
    gst_mikey_payload_unref (p);
    return FALSE;
  }

  return gst_mikey_message_insert_payload (msg, -1, p);
}

/**
 * gst_mikey_message_add_t_now_ntp_utc:
 * @msg: a #GstMIKEYMessage
 *
 * Add a new T payload to @msg that contains the current time
 * in NTP-UTC format.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_message_add_t_now_ntp_utc (GstMIKEYMessage * msg)
{
  gint64 now;
  guint64 ntptime;
  guint8 bytes[8];

  now = g_get_real_time ();

  /* convert clock time to NTP time. upper 32 bits should contain the seconds
   * and the lower 32 bits, the fractions of a second. */
  ntptime = gst_util_uint64_scale (now, (G_GINT64_CONSTANT (1) << 32), 1000000);
  /* conversion from UNIX timestamp (seconds since 1970) to NTP (seconds
   * since 1900). */
  ntptime += (G_GUINT64_CONSTANT (2208988800) << 32);
  GST_WRITE_UINT64_BE (bytes, ntptime);

  return gst_mikey_message_add_t (msg, GST_MIKEY_TS_TYPE_NTP_UTC, bytes);
}

/**
 * gst_mikey_message_add_rand:
 * @msg: a #GstMIKEYMessage
 * @len: the length of @rand
 * @rand: (array length=len): random data
 *
 * Add a new RAND payload to @msg with the given parameters.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_message_add_rand (GstMIKEYMessage * msg, guint8 len,
    const guint8 * rand)
{
  GstMIKEYPayload *p;

  g_return_val_if_fail (msg != NULL, FALSE);
  g_return_val_if_fail (len != 0 && rand != NULL, FALSE);

  p = gst_mikey_payload_new (GST_MIKEY_PT_RAND);
  if (!gst_mikey_payload_rand_set (p, len, rand)) {
    gst_mikey_payload_unref (p);
    return FALSE;
  }

  return gst_mikey_message_insert_payload (msg, -1, p);
}

/**
 * gst_mikey_message_add_rand_len:
 * @msg: a #GstMIKEYMessage
 * @len: length
 *
 * Add a new RAND payload to @msg with @len random bytes.
 *
 * Returns: %TRUE on success
 *
 * Since: 1.4
 */
gboolean
gst_mikey_message_add_rand_len (GstMIKEYMessage * msg, guint8 len)
{
  GstMIKEYPayloadRAND *p;
  guint i;

  p = (GstMIKEYPayloadRAND *) gst_mikey_payload_new (GST_MIKEY_PT_RAND);
  p->len = len;
  p->rand = g_malloc (len);
  for (i = 0; i < len; i++)
    p->rand[i] = g_random_int_range (0, 256);

  return gst_mikey_message_add_payload (msg, &p->pt);
}

#define ENSURE_SIZE(n)                          \
G_STMT_START {                                  \
  guint offset = data - arr->data;              \
  g_byte_array_set_size (arr, offset + n);      \
  data = arr->data + offset;                    \
} G_STMT_END
static guint
payloads_to_bytes (GArray * payloads, GByteArray * arr, guint8 ** ptr,
    guint offset, GstMIKEYEncryptInfo * info, GError ** error)
{
  guint i, n_payloads, len, start, size;
  guint8 *data;
  GstMIKEYPayload *next_payload;

  len = arr->len;
  start = *ptr - arr->data;
  data = *ptr + offset;

  n_payloads = payloads->len;

  for (i = 0; i < n_payloads; i++) {
    GstMIKEYPayload *payload = g_array_index (payloads, GstMIKEYPayload *, i);

    if (i + 1 < n_payloads)
      next_payload = g_array_index (payloads, GstMIKEYPayload *, i + 1);
    else
      next_payload = NULL;

    switch (payload->type) {
      case GST_MIKEY_PT_KEMAC:
      {
        GstMIKEYPayloadKEMAC *p = (GstMIKEYPayloadKEMAC *) payload;
        guint enc_len;
        guint mac_len;

        if ((mac_len = get_mac_len (p->mac_alg)) == -1)
          break;

        /*                  1                   2                   3
         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * ! Next payload  ! Encr alg      ! Encr data len                 !
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * !                        Encr data                              ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * ! Mac alg       !        MAC                                    ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         */
        ENSURE_SIZE (4);
        data[0] = next_payload ? next_payload->type : GST_MIKEY_PT_LAST;
        data[1] = p->enc_alg;
        enc_len =
            payloads_to_bytes (p->subpayloads, arr, &data, 4, info, error);
        /* FIXME, encrypt data here */
        GST_WRITE_UINT16_BE (&data[2], enc_len);
        data += enc_len;
        ENSURE_SIZE (5 + mac_len);
        data[4] = p->mac_alg;
        /* FIXME, do mac here */
        data += 5 + mac_len;
        break;
      }
      case GST_MIKEY_PT_T:
      {
        GstMIKEYPayloadT *p = (GstMIKEYPayloadT *) payload;
        guint ts_len;

        if ((ts_len = get_ts_len (p->type)) == -1)
          break;

        /*                      1                   2                   3
         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * ! Next Payload  !   TS type     ! TS value                      ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         */
        ENSURE_SIZE (2 + ts_len);
        data[0] = next_payload ? next_payload->type : GST_MIKEY_PT_LAST;
        data[1] = p->type;
        memcpy (&data[2], p->ts_value, ts_len);
        data += 2 + ts_len;
        break;
      }
      case GST_MIKEY_PT_PKE:
      {
        guint16 clen;
        GstMIKEYPayloadPKE *p = (GstMIKEYPayloadPKE *) payload;
        /*                      1                   2                   3
         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * ! Next Payload  ! C ! Data len                  ! Data          ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         */
        ENSURE_SIZE (3 + p->data_len);
        data[0] = next_payload ? next_payload->type : GST_MIKEY_PT_LAST;
        clen = (p->C << 14) || (p->data_len & 0x3fff);
        GST_WRITE_UINT16_BE (&data[1], clen);
        memcpy (&data[3], p->data, p->data_len);
        data += 3 + p->data_len;
        break;
      }
      case GST_MIKEY_PT_DH:
      case GST_MIKEY_PT_SIGN:
      case GST_MIKEY_PT_ID:
      case GST_MIKEY_PT_CERT:
      case GST_MIKEY_PT_CHASH:
      case GST_MIKEY_PT_V:
        break;
      case GST_MIKEY_PT_SP:
      {
        GstMIKEYPayloadSP *p = (GstMIKEYPayloadSP *) payload;
        guint len, plen, i;

        plen = 0;
        len = p->params->len;
        for (i = 0; i < len; i++) {
          GstMIKEYPayloadSPParam *param = &g_array_index (p->params,
              GstMIKEYPayloadSPParam, i);
          plen += 2 + param->len;
        }
        /*                      1                   2                   3
         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * ! Next payload  ! Policy no     ! Prot type     ! Policy param  ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * ~ length (cont) ! Policy param                                  ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         */
        ENSURE_SIZE (5 + plen);
        data[0] = next_payload ? next_payload->type : GST_MIKEY_PT_LAST;
        data[1] = p->policy;
        data[2] = p->proto;
        GST_WRITE_UINT16_BE (&data[3], plen);
        data += 5;
        for (i = 0; i < len; i++) {
          GstMIKEYPayloadSPParam *param = &g_array_index (p->params,
              GstMIKEYPayloadSPParam, i);
          /*                     1                   2                   3
           * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
           * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           * ! Type          ! Length        ! Value                         ~
           * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           */
          data[0] = param->type;
          data[1] = param->len;
          memcpy (&data[2], param->val, param->len);
          data += 2 + param->len;
        }
        break;
      }
      case GST_MIKEY_PT_RAND:
      {
        GstMIKEYPayloadRAND *p = (GstMIKEYPayloadRAND *) payload;
        /*                      1                   2                   3
         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * ! Next payload  ! RAND len      ! RAND                          ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         */
        ENSURE_SIZE (2 + p->len);
        data[0] = next_payload ? next_payload->type : GST_MIKEY_PT_LAST;
        data[1] = p->len;
        memcpy (&data[2], p->rand, p->len);
        data += 2 + p->len;
        break;
      }
      case GST_MIKEY_PT_ERR:
        break;
      case GST_MIKEY_PT_KEY_DATA:
      {
        GstMIKEYPayloadKeyData *p = (GstMIKEYPayloadKeyData *) payload;
        /*                        1                   2                   3
         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * !  Next Payload ! Type  ! KV    ! Key data len                  !
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * !                         Key data                              ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * ! Salt len (optional)           ! Salt data (optional)          ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * !                        KV data (optional)                     ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         */
        ENSURE_SIZE (4 + p->key_len);
        data[0] = next_payload ? next_payload->type : GST_MIKEY_PT_LAST;
        data[1] =
            ((p->key_type | (p->salt_len ? 1 : 0)) << 4) | (p->kv_type & 0xf);
        GST_WRITE_UINT16_BE (&data[2], p->key_len);
        memcpy (&data[4], p->key_data, p->key_len);
        data += 4 + p->key_len;

        if (p->salt_len > 0) {
          ENSURE_SIZE (2 + p->salt_len);
          GST_WRITE_UINT16_BE (&data[0], p->salt_len);
          memcpy (&data[2], p->salt_data, p->salt_len);
          data += 2 + p->salt_len;
        }
        if (p->kv_type == GST_MIKEY_KV_SPI) {
          /*
           *                      1                   2                   3
           *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
           * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           * ! SPI Length    ! SPI                                           ~
           * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           */
          ENSURE_SIZE (1 + p->kv_len[0]);
          data[0] = p->kv_len[0];
          memcpy (&data[1], p->kv_data[0], p->kv_len[0]);
          data += 1 + p->kv_len[0];
        } else if (p->kv_type == GST_MIKEY_KV_INTERVAL) {
          /*
           *                      1                   2                   3
           *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
           * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           * ! VF Length     ! Valid From                                    ~
           * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           * ! VT Length     ! Valid To (expires)                            ~
           * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           */
          ENSURE_SIZE (1 + p->kv_len[0]);
          data[0] = p->kv_len[0];
          memcpy (&data[1], p->kv_data[0], p->kv_len[0]);
          data += 1 + p->kv_len[0];
          ENSURE_SIZE (1 + p->kv_len[1]);
          data[0] = p->kv_len[1];
          memcpy (&data[1], p->kv_data[1], p->kv_len[1]);
          data += 1 + p->kv_len[1];
        }
        break;
      }
      case GST_MIKEY_PT_GEN_EXT:
      case GST_MIKEY_PT_LAST:
        break;
    }
  }
  *ptr = arr->data + start;
  size = arr->len - len;

  return size;
}

/**
 * gst_mikey_message_to_bytes:
 * @msg: a #GstMIKEYMessage
 * @info: a #GstMIKEYEncryptInfo
 * @error: a #GError
 *
 * Convert @msg to a #GBytes.
 *
 * Returns: a new #GBytes for @msg.
 *
 * Since: 1.4
 */
GBytes *
gst_mikey_message_to_bytes (GstMIKEYMessage * msg, GstMIKEYEncryptInfo * info,
    GError ** error)
{
  GByteArray *arr = NULL;
  guint8 *data;
  GstMIKEYPayload *next_payload;
  guint i, n_cs;
  arr = g_byte_array_new ();
  data = arr->data;

  if (msg->payloads->len == 0)
    next_payload = NULL;
  else
    next_payload = g_array_index (msg->payloads, GstMIKEYPayload *, 0);

  n_cs = msg->map_info->len;
  /*                      1                   2                   3
   *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * !  version      !  data type    ! next payload  !V! PRF func    !
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * !                         CSB ID                                !
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * ! #CS           ! CS ID map type! CS ID map info                ~
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   */
  ENSURE_SIZE (10 + 9 * n_cs);
  data[0] = msg->version;
  data[1] = msg->type;
  data[2] = next_payload ? next_payload->type : GST_MIKEY_PT_LAST;
  data[3] = (msg->V ? 0x80 : 0x00) | (msg->prf_func & 0x7f);
  GST_WRITE_UINT32_BE (&data[4], msg->CSB_id);
  data[8] = n_cs;
  data[9] = msg->map_type;
  data += 10;

  for (i = 0; i < n_cs; i++) {
    GstMIKEYMapSRTP *info = &g_array_index (msg->map_info, GstMIKEYMapSRTP, i);
    /*                      1                   2                   3
     *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     * ! Policy_no_1   ! SSRC_1                                        !
     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     * ! SSRC_1 (cont) ! ROC_1                                         !
     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     * ! ROC_1 (cont)  ! Policy_no_2   ! SSRC_2                        !
     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     * ! SSRC_2 (cont)                 ! ROC_2                         !
     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     * ! ROC_2 (cont)                  !                               :
     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ...
     */
    data[0] = info->policy;
    GST_WRITE_UINT32_BE (&data[1], info->ssrc);
    GST_WRITE_UINT32_BE (&data[5], info->roc);
    data += 9;
  }

  payloads_to_bytes (msg->payloads, arr, &data, 0, info, error);

  return g_byte_array_free_to_bytes (arr);
}

#undef ENSURE_SIZE

typedef enum
{
  STATE_PSK,
  STATE_PK,
  STATE_KEMAC,
  STATE_OTHER
} ParseState;

#define CHECK_SIZE(n) if (size < (n)) goto short_data;
#define ADVANCE(n) (d += (n), size -= (n));
static gboolean
payloads_from_bytes (ParseState state, GArray * payloads, const guint8 * d,
    gsize size, guint8 next_payload, GstMIKEYDecryptInfo * info,
    GError ** error)
{
  GstMIKEYPayload *p;

  while (next_payload != GST_MIKEY_PT_LAST) {
    p = NULL;
    switch (next_payload) {
      case GST_MIKEY_PT_KEMAC:
      {
        guint mac_len;
        GstMIKEYEncAlg enc_alg;
        guint16 enc_len;
        const guint8 *enc_data;
        GstMIKEYMacAlg mac_alg;
        guint8 np;
        /*                  1                   2                   3
         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * ! Next payload  ! Encr alg      ! Encr data len                 !
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * !                        Encr data                              ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * ! Mac alg       !        MAC                                    ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         */
        CHECK_SIZE (5);
        next_payload = d[0];
        enc_alg = d[1];
        enc_len = GST_READ_UINT16_BE (&d[2]);
        CHECK_SIZE (5 + enc_len);
        enc_data = &d[4];
        /* FIXME, decrypt data */
        ADVANCE (enc_len);
        mac_alg = d[4];
        if ((mac_len = get_mac_len (mac_alg)) == -1)
          goto invalid_data;
        CHECK_SIZE (5 + mac_len);
        /* FIXME, check MAC */
        ADVANCE (5 + mac_len);

        p = gst_mikey_payload_new (GST_MIKEY_PT_KEMAC);
        gst_mikey_payload_kemac_set (p, enc_alg, mac_alg);

        if (state == STATE_PSK)
          /* we expect Key data for Preshared key */
          np = GST_MIKEY_PT_KEY_DATA;
        else if (state == STATE_PK)
          /* we expect ID for Public key */
          np = GST_MIKEY_PT_ID;
        else
          goto invalid_data;

        payloads_from_bytes (STATE_KEMAC,
            ((GstMIKEYPayloadKEMAC *) p)->subpayloads, enc_data, enc_len, np,
            info, error);
        g_array_append_val (payloads, p);
        break;
      }
      case GST_MIKEY_PT_T:
      {
        GstMIKEYTSType type;
        guint ts_len;
        const guint8 *ts_value;
        /*                      1                   2                   3
         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * ! Next Payload  !   TS type     ! TS value                      ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         */
        CHECK_SIZE (2);
        next_payload = d[0];
        type = d[1];
        if ((ts_len = get_ts_len (type)) == -1)
          goto invalid_data;
        CHECK_SIZE (2 + ts_len);
        ts_value = &d[2];
        ADVANCE (2 + ts_len);

        p = gst_mikey_payload_new (GST_MIKEY_PT_T);
        gst_mikey_payload_t_set (p, type, ts_value);
        g_array_append_val (payloads, p);
        break;
      }
      case GST_MIKEY_PT_PKE:
      {
        guint8 C;
        guint16 clen, data_len;
        const guint8 *data;
        /*                      1                   2                   3
         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * ! Next Payload  ! C ! Data len                  ! Data          ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         */
        CHECK_SIZE (3);
        next_payload = d[0];
        clen = GST_READ_UINT16_BE (&d[1]);
        C = clen >> 14;
        data_len = clen & 0x3fff;
        CHECK_SIZE (3 + data_len);
        data = &d[3];
        ADVANCE (3 + data_len);

        p = gst_mikey_payload_new (GST_MIKEY_PT_PKE);
        gst_mikey_payload_pke_set (p, C, data_len, data);
        g_array_append_val (payloads, p);
        break;
      }
      case GST_MIKEY_PT_DH:
      case GST_MIKEY_PT_SIGN:
      case GST_MIKEY_PT_ID:
      case GST_MIKEY_PT_CERT:
      case GST_MIKEY_PT_CHASH:
      case GST_MIKEY_PT_V:
        break;
      case GST_MIKEY_PT_SP:
      {
        guint8 policy;
        GstMIKEYSecProto proto;
        guint16 plen;
        /*                      1                   2                   3
         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * ! Next payload  ! Policy no     ! Prot type     ! Policy param  ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * ~ length (cont) ! Policy param                                  ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         */
        CHECK_SIZE (5);
        next_payload = d[0];
        policy = d[1];
        proto = d[2];
        plen = GST_READ_UINT16_BE (&d[3]);
        ADVANCE (5);

        p = gst_mikey_payload_new (GST_MIKEY_PT_SP);
        gst_mikey_payload_sp_set (p, policy, proto);

        CHECK_SIZE (plen);
        while (plen) {
          guint8 type, len;

          CHECK_SIZE (2);
          /*                     1                   2                   3
           * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
           * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           * ! Type          ! Length        ! Value                         ~
           * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           */
          type = d[0];
          len = d[1];
          CHECK_SIZE (2 + len);
          gst_mikey_payload_sp_add_param (p, type, len, &d[2]);
          ADVANCE (2 + len);
          plen -= 2 + len;
        }
        g_array_append_val (payloads, p);
        break;
      }
      case GST_MIKEY_PT_RAND:
      {
        guint8 len;
        const guint8 *rand;
        /*                      1                   2                   3
         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * ! Next payload  ! RAND len      ! RAND                          ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         */
        CHECK_SIZE (2);
        next_payload = d[0];
        len = d[1];
        CHECK_SIZE (2 + len);
        rand = &d[2];
        ADVANCE (2 + len);

        p = gst_mikey_payload_new (GST_MIKEY_PT_RAND);
        gst_mikey_payload_rand_set (p, len, rand);
        g_array_append_val (payloads, p);
        break;
      }
      case GST_MIKEY_PT_ERR:
        break;
      case GST_MIKEY_PT_KEY_DATA:
      {
        GstMIKEYKeyDataType key_type;
        GstMIKEYKVType kv_type;
        guint16 key_len, salt_len = 0;
        const guint8 *key_data, *salt_data;
        /*                        1                   2                   3
         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * !  Next Payload ! Type  ! KV    ! Key data len                  !
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * !                         Key data                              ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * ! Salt len (optional)           ! Salt data (optional)          ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         * !                        KV data (optional)                     ~
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         */
        CHECK_SIZE (4);
        next_payload = d[0];
        key_type = d[1] >> 4;
        kv_type = d[1] & 0xf;
        key_len = GST_READ_UINT16_BE (&d[2]);
        CHECK_SIZE (4 + key_len);
        key_data = &d[4];
        ADVANCE (4 + key_len);
        if (key_type & 1) {
          CHECK_SIZE (2);
          salt_len = GST_READ_UINT16_BE (&d[0]);
          CHECK_SIZE (2 + salt_len);
          salt_data = &d[2];
          ADVANCE (2 + salt_len);
        }
        p = gst_mikey_payload_new (GST_MIKEY_PT_KEY_DATA);
        gst_mikey_payload_key_data_set_key (p, key_type & 2, key_len, key_data);
        if (salt_len > 0)
          gst_mikey_payload_key_data_set_salt (p, salt_len, salt_data);

        if (kv_type == GST_MIKEY_KV_SPI) {
          guint8 spi_len;
          const guint8 *spi_data;
          /*
           *                      1                   2                   3
           *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
           * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           * ! SPI Length    ! SPI                                           ~
           * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           */
          CHECK_SIZE (1);
          spi_len = d[0];
          CHECK_SIZE (1 + spi_len);
          spi_data = &d[1];
          ADVANCE (1 + spi_len);

          gst_mikey_payload_key_data_set_spi (p, spi_len, spi_data);
        } else if (kv_type == GST_MIKEY_KV_INTERVAL) {
          guint8 vf_len, vt_len;
          const guint8 *vf_data, *vt_data;
          /*
           *                      1                   2                   3
           *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
           * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           * ! VF Length     ! Valid From                                    ~
           * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           * ! VT Length     ! Valid To (expires)                            ~
           * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           */
          CHECK_SIZE (1);
          vf_len = d[0];
          CHECK_SIZE (1 + vf_len);
          vf_data = &d[1];
          ADVANCE (1 + vf_len);
          CHECK_SIZE (1);
          vt_len = d[0];
          CHECK_SIZE (1 + vt_len);
          vt_data = &d[1];
          ADVANCE (1 + vt_len);

          gst_mikey_payload_key_data_set_interval (p, vf_len, vf_data, vt_len,
              vt_data);
        } else if (kv_type != GST_MIKEY_KV_NULL)
          goto invalid_data;

        g_array_append_val (payloads, p);
        break;
      }
      case GST_MIKEY_PT_GEN_EXT:
      case GST_MIKEY_PT_LAST:
        break;
    }
  }
  return TRUE;

  /* ERRORS */
short_data:
  {
    GST_DEBUG ("not enough data");
    if (p)
      gst_mikey_payload_unref (p);
    return FALSE;
  }
invalid_data:
  {
    GST_DEBUG ("invalid data");
    if (p)
      gst_mikey_payload_unref (p);
    return FALSE;
  }
}

/**
 * gst_mikey_message_new_from_data:
 * @data: (array length=size) (element-type guint8): bytes to read
 * @size: length of @data
 * @info: #GstMIKEYDecryptInfo
 * @error: a #GError
 *
 * Parse @size bytes from @data into a #GstMIKEYMessage. @info contains the
 * parameters to decrypt and verify the data.
 *
 * Returns: a #GstMIKEYMessage on success or %NULL when parsing failed and
 * @error will be set.
 *
 * Since: 1.4
 */
GstMIKEYMessage *
gst_mikey_message_new_from_data (gconstpointer data, gsize size,
    GstMIKEYDecryptInfo * info, GError ** error)
{
  GstMIKEYMessage *msg;
  guint n_cs, i;
  const guint8 *d = data;
  guint8 next_payload;
  ParseState state;

  g_return_val_if_fail (data != NULL, NULL);

  msg = gst_mikey_message_new ();
  /*                      1                   2                   3
   *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * !  version      !  data type    ! next payload  !V! PRF func    !
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * !                         CSB ID                                !
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * ! #CS           ! CS ID map type! CS ID map info                ~
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   */
  CHECK_SIZE (10);
  msg->version = d[0];
  if (msg->version != GST_MIKEY_VERSION)
    goto unknown_version;

  msg->type = d[1];
  next_payload = d[2];
  msg->V = d[3] & 0x80 ? TRUE : FALSE;
  msg->prf_func = d[3] & 0x7f;
  msg->CSB_id = GST_READ_UINT32_BE (&d[4]);
  n_cs = d[8];
  msg->map_type = d[9];
  ADVANCE (10);

  CHECK_SIZE (n_cs * 9);
  for (i = 0; i < n_cs; i++) {
    GstMIKEYMapSRTP map;

    /*                      1                   2                   3
     *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     * ! Policy_no_1   ! SSRC_1                                        !
     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     * ! SSRC_1 (cont) ! ROC_1                                         !
     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     * ! ROC_1 (cont)  ! Policy_no_2   ! SSRC_2                        ~
     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     */
    map.policy = d[0];
    map.ssrc = GST_READ_UINT32_BE (&d[1]);
    map.roc = GST_READ_UINT32_BE (&d[5]);
    gst_mikey_message_insert_cs_srtp (msg, -1, &map);
    ADVANCE (9);
  }
  if (msg->type == GST_MIKEY_TYPE_PSK_INIT)
    state = STATE_PSK;
  else if (msg->type == GST_MIKEY_TYPE_PK_INIT)
    state = STATE_PK;
  else
    state = STATE_OTHER;

  if (!payloads_from_bytes (state, msg->payloads, d, size, next_payload, info,
          error))
    goto parse_error;

  return msg;

  /* ERRORS */
short_data:
  {
    GST_DEBUG ("not enough data");
    gst_mikey_message_unref (msg);
    return NULL;
  }
unknown_version:
  {
    GST_DEBUG ("unknown version");
    gst_mikey_message_unref (msg);
    return NULL;
  }
parse_error:
  {
    GST_DEBUG ("failed to parse");
    gst_mikey_message_unref (msg);
    return NULL;
  }
}

#define AES_128_KEY_LEN 16
#define AES_256_KEY_LEN 32
#define HMAC_32_KEY_LEN 4
#define HMAC_80_KEY_LEN 10

static guint8
enc_key_length_from_cipher_name (const gchar * cipher)
{
  if (g_strcmp0 (cipher, "aes-128-icm") == 0)
    return AES_128_KEY_LEN;
  else if (g_strcmp0 (cipher, "aes-256-icm") == 0)
    return AES_256_KEY_LEN;
  else {
    GST_ERROR ("encryption algorithm '%s' not supported", cipher);
    return 0;
  }
}

static guint8
auth_key_length_from_auth_name (const gchar * auth)
{
  if (g_strcmp0 (auth, "hmac-sha1-32") == 0)
    return HMAC_32_KEY_LEN;
  else if (g_strcmp0 (auth, "hmac-sha1-80") == 0)
    return HMAC_80_KEY_LEN;
  else {
    GST_ERROR ("authentication algorithm '%s' not supported", auth);
    return 0;
  }
}

/**
 * gst_mikey_message_new_from_caps:
 * @caps: a #GstCaps, including SRTP parameters (srtp/srtcp cipher, authorization, key data)
 *
 * Makes mikey message including:
 *  - Security Policy Payload
 *  - Key Data Transport Payload
 *  - Key Data Sub-Payload
 *
 * Returns: (transfer full): a #GstMIKEYMessage,
 * or %NULL if there is no srtp information in the caps.
 *
 * Since: 1.8
 */
GstMIKEYMessage *
gst_mikey_message_new_from_caps (GstCaps * caps)
{
  GstMIKEYMessage *msg;
  GstMIKEYPayload *payload, *pkd;
  guint8 byte;
  GstStructure *s;
  GstMapInfo info;
  GstBuffer *srtpkey;
  const GValue *val;
  const gchar *cipher, *auth;
  const gchar *srtpcipher, *srtpauth, *srtcpcipher, *srtcpauth;

  g_return_val_if_fail (caps != NULL && GST_IS_CAPS (caps), NULL);

  s = gst_caps_get_structure (caps, 0);
  g_return_val_if_fail (s != NULL, NULL);

  val = gst_structure_get_value (s, "srtp-key");
  if (!val)
    goto no_key;

  srtpkey = gst_value_get_buffer (val);
  if (!srtpkey || !GST_IS_BUFFER (srtpkey))
    goto no_key;

  srtpcipher = gst_structure_get_string (s, "srtp-cipher");
  srtpauth = gst_structure_get_string (s, "srtp-auth");
  srtcpcipher = gst_structure_get_string (s, "srtcp-cipher");
  srtcpauth = gst_structure_get_string (s, "srtcp-auth");

  /* we need srtp cipher/auth or srtcp cipher/auth */
  if ((srtpcipher == NULL || srtpauth == NULL)
      && (srtcpcipher == NULL || srtcpauth == NULL)) {
    GST_WARNING ("could not find the right SRTP parameters in caps");
    return NULL;
  }

  /* prefer srtp cipher over srtcp */
  cipher = srtpcipher;
  if (cipher == NULL)
    cipher = srtcpcipher;

  /* prefer srtp auth over srtcp */
  auth = srtpauth;
  if (auth == NULL)
    auth = srtcpauth;

  msg = gst_mikey_message_new ();
  /* unencrypted MIKEY message, we send this over TLS so this is allowed */
  gst_mikey_message_set_info (msg, GST_MIKEY_VERSION, GST_MIKEY_TYPE_PSK_INIT,
      FALSE, GST_MIKEY_PRF_MIKEY_1, g_random_int (), GST_MIKEY_MAP_TYPE_SRTP);

  /* timestamp is now */
  gst_mikey_message_add_t_now_ntp_utc (msg);
  /* add some random data */
  gst_mikey_message_add_rand_len (msg, 16);

  /* the policy '0' is SRTP */
  payload = gst_mikey_payload_new (GST_MIKEY_PT_SP);
  gst_mikey_payload_sp_set (payload, 0, GST_MIKEY_SEC_PROTO_SRTP);

  /* only AES-CM is supported */
  byte = 1;
  gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_ENC_ALG, 1, &byte);
  /* encryption key length */
  byte = enc_key_length_from_cipher_name (cipher);
  gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_ENC_KEY_LEN, 1,
      &byte);
  /* only HMAC-SHA1 */
  byte = 1;
  gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_AUTH_ALG, 1,
      &byte);
  /* authentication key length */
  byte = auth_key_length_from_auth_name (auth);
  gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_AUTH_KEY_LEN, 1,
      &byte);
  /* we enable encryption on RTP and RTCP */
  byte = 1;
  gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_SRTP_ENC, 1,
      &byte);
  gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_SRTCP_ENC, 1,
      &byte);
  /* we enable authentication on RTP and RTCP */
  gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_SRTP_AUTH, 1,
      &byte);
  gst_mikey_message_add_payload (msg, payload);

  /* make unencrypted KEMAC */
  payload = gst_mikey_payload_new (GST_MIKEY_PT_KEMAC);
  gst_mikey_payload_kemac_set (payload, GST_MIKEY_ENC_NULL, GST_MIKEY_MAC_NULL);
  /* add the key in KEMAC */
  pkd = gst_mikey_payload_new (GST_MIKEY_PT_KEY_DATA);
  gst_buffer_map (srtpkey, &info, GST_MAP_READ);
  gst_mikey_payload_key_data_set_key (pkd, GST_MIKEY_KD_TEK, info.size,
      info.data);
  gst_buffer_unmap (srtpkey, &info);
  gst_mikey_payload_kemac_add_sub (payload, pkd);
  gst_mikey_message_add_payload (msg, payload);

  return msg;

no_key:
  GST_INFO ("No srtp key");
  return NULL;
}

#define AES_128_KEY_LEN 16
#define AES_256_KEY_LEN 32
#define HMAC_32_KEY_LEN 4
#define HMAC_80_KEY_LEN 10

/**
 * gst_mikey_message_to_caps:
 * @msg: a #GstMIKEYMessage
 * @caps: a #GstCaps to be filled with SRTP parameters (srtp/srtcp cipher, authorization, key data)
 *
 * Returns: %TRUE on success
 *
 * Since: 1.8.1
 */
gboolean
gst_mikey_message_to_caps (const GstMIKEYMessage * msg, GstCaps * caps)
{
  gboolean res = FALSE;
  const GstMIKEYPayload *payload;
  const gchar *srtp_cipher;
  const gchar *srtp_auth;

  srtp_cipher = "aes-128-icm";
  srtp_auth = "hmac-sha1-80";

  /* check the Security policy if any */
  if ((payload = gst_mikey_message_find_payload (msg, GST_MIKEY_PT_SP, 0))) {
    GstMIKEYPayloadSP *p = (GstMIKEYPayloadSP *) payload;
    guint len, i;

    if (p->proto != GST_MIKEY_SEC_PROTO_SRTP)
      goto done;

    len = gst_mikey_payload_sp_get_n_params (payload);
    for (i = 0; i < len; i++) {
      const GstMIKEYPayloadSPParam *param =
          gst_mikey_payload_sp_get_param (payload, i);

      switch (param->type) {
        case GST_MIKEY_SP_SRTP_ENC_ALG:
          switch (param->val[0]) {
            case 0:
              srtp_cipher = "null";
              break;
            case 2:
            case 1:
              srtp_cipher = "aes-128-icm";
              break;
            default:
              break;
          }
          break;
        case GST_MIKEY_SP_SRTP_ENC_KEY_LEN:
          switch (param->val[0]) {
            case AES_128_KEY_LEN:
              srtp_cipher = "aes-128-icm";
              break;
            case AES_256_KEY_LEN:
              srtp_cipher = "aes-256-icm";
              break;
            default:
              break;
          }
          break;
        case GST_MIKEY_SP_SRTP_AUTH_ALG:
          switch (param->val[0]) {
            case 0:
              srtp_auth = "null";
              break;
            case 2:
            case 1:
              srtp_auth = "hmac-sha1-80";
              break;
            default:
              break;
          }
          break;
        case GST_MIKEY_SP_SRTP_AUTH_KEY_LEN:
          switch (param->val[0]) {
            case HMAC_32_KEY_LEN:
              srtp_auth = "hmac-sha1-32";
              break;
            case HMAC_80_KEY_LEN:
              srtp_auth = "hmac-sha1-80";
              break;
            default:
              break;
          }
          break;
        case GST_MIKEY_SP_SRTP_SRTP_ENC:
          break;
        case GST_MIKEY_SP_SRTP_SRTCP_ENC:
          break;
        default:
          break;
      }
    }
  }

  if (!(payload = gst_mikey_message_find_payload (msg, GST_MIKEY_PT_KEMAC, 0)))
    goto done;
  else {
    GstMIKEYPayloadKEMAC *p = (GstMIKEYPayloadKEMAC *) payload;
    const GstMIKEYPayload *sub;
    GstMIKEYPayloadKeyData *pkd;
    GstBuffer *buf;

    if (p->enc_alg != GST_MIKEY_ENC_NULL || p->mac_alg != GST_MIKEY_MAC_NULL)
      goto done;

    if (!(sub = gst_mikey_payload_kemac_get_sub (payload, 0)))
      goto done;

    if (sub->type != GST_MIKEY_PT_KEY_DATA)
      goto done;

    pkd = (GstMIKEYPayloadKeyData *) sub;
    buf =
        gst_buffer_new_wrapped (g_memdup (pkd->key_data, pkd->key_len),
        pkd->key_len);
    gst_caps_set_simple (caps, "srtp-key", GST_TYPE_BUFFER, buf, NULL);
    gst_buffer_unref (buf);
  }

  gst_caps_set_simple (caps,
      "srtp-cipher", G_TYPE_STRING, srtp_cipher,
      "srtp-auth", G_TYPE_STRING, srtp_auth,
      "srtcp-cipher", G_TYPE_STRING, srtp_cipher,
      "srtcp-auth", G_TYPE_STRING, srtp_auth, NULL);

  res = TRUE;

done:
  return res;
}

/**
 * gst_mikey_message_base64_encode:
 * @msg: a #GstMIKEYMessage
 *
 * Returns: (transfer full): a #gchar, base64-encoded data
 *
 * Since: 1.8
 */
gchar *
gst_mikey_message_base64_encode (GstMIKEYMessage * msg)
{
  GBytes *bytes;
  gchar *base64;
  const guint8 *data;
  gsize size;

  g_return_val_if_fail (msg != NULL, NULL);

  /* serialize mikey message to bytes */
  bytes = gst_mikey_message_to_bytes (msg, NULL, NULL);

  /* and make it into base64 */
  data = g_bytes_get_data (bytes, &size);
  base64 = g_base64_encode (data, size);
  g_bytes_unref (bytes);

  return base64;
}
