/* 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
 * @title: GstMIKEYMessage
 * @short_description: Helper methods for dealing with MIKEY messages
 *
 * The GstMIKEY helper functions makes it easy to parse and create MIKEY
 * messages.
 *
 * 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;
}
