mikey: Fix the KEMAC payload

The KEMAC payload actually needs to have subpayloads and the key should
go into the KEY_DATA subpayload. Add support for subpayloads and
implement the KEY_DATA payload.
Add some pointers to the conversion functions that allow us to add
encryption and decryption later.
This commit is contained in:
Wim Taymans 2014-04-04 17:36:04 +02:00
parent 98482c3a0e
commit 675d0400e1
4 changed files with 776 additions and 207 deletions

File diff suppressed because it is too large Load diff

View file

@ -27,6 +27,8 @@
G_BEGIN_DECLS
typedef struct _GstMIKEYMessage GstMIKEYMessage;
typedef struct _GstMIKEYEncryptInfo GstMIKEYEncryptInfo;
typedef struct _GstMIKEYDecryptInfo GstMIKEYDecryptInfo;
/**
* GST_MIKEY_VERSION:
@ -206,10 +208,8 @@ typedef enum
* GstMIKEYPayloadKEMAC:
* @pt: the common #GstMIKEYPayload
* @enc_alg: the #GstMIKEYEncAlg
* @enc_len: the length of @enc_data
* @enc_data: encryption data
* @mac_alg: the #GstMIKEYMacAlg
* @mac: the mac
* @subpayload: the subpayloads
*
* A structure holding the KEMAC payload
*/
@ -217,16 +217,18 @@ typedef struct {
GstMIKEYPayload pt;
GstMIKEYEncAlg enc_alg;
guint16 enc_len;
guint8 *enc_data;
GstMIKEYMacAlg mac_alg;
guint8 *mac;
GArray *subpayloads;
} GstMIKEYPayloadKEMAC;
gboolean gst_mikey_payload_kemac_set (GstMIKEYPayload *payload,
GstMIKEYEncAlg enc_alg,
guint16 enc_len, const guint8 *enc_data,
GstMIKEYMacAlg mac_alg, const guint8 *mac);
gboolean gst_mikey_payload_kemac_set (GstMIKEYPayload *payload,
GstMIKEYEncAlg enc_alg,
GstMIKEYMacAlg mac_alg);
guint gst_mikey_payload_kemac_get_n_sub (const GstMIKEYPayload *payload);
const GstMIKEYPayload * gst_mikey_payload_kemac_get_sub (const GstMIKEYPayload *payload, guint idx);
gboolean gst_mikey_payload_kemac_remove_sub (GstMIKEYPayload *payload, guint idx);
gboolean gst_mikey_payload_kemac_add_sub (GstMIKEYPayload *payload,
GstMIKEYPayload *newpay);
/**
* GstMIKEYCacheType:
@ -404,8 +406,75 @@ typedef struct {
guint8 *rand;
} GstMIKEYPayloadRAND;
gboolean gst_mikey_payload_rand_set (GstMIKEYPayload *payload,
guint8 len, const guint8 *rand);
gboolean gst_mikey_payload_rand_set (GstMIKEYPayload *payload,
guint8 len, const guint8 *rand);
/**
* GstMIKEYKeyDataType:
* @GST_MIKEY_KD_TGK: a TEK Generation Key
* @GST_MIKEY_KD_TEK: Traffic-Encrypting Key
*
* The type of key.
*/
typedef enum
{
GST_MIKEY_KD_TGK = 0,
GST_MIKEY_KD_TEK = 2,
} GstMIKEYKeyDataType;
/**
* GstMIKEYKVType:
* @GST_MIKEY_KV_NULL: No specific usage rule
* @GST_MIKEY_KV_SPI: The key is associated with the SPI/MKI
* @GST_MIKEY_KV_INTERVAL: The key has a start and expiration time
*
* The key validity type
*/
typedef enum
{
GST_MIKEY_KV_NULL = 0,
GST_MIKEY_KV_SPI = 1,
GST_MIKEY_KV_INTERVAL = 2,
} GstMIKEYKVType;
/**
* GstMIKEYPayloadKeyData:
* @pt: the payload header
* @type: the #GstMIKEYKeyDataType of @key_data
* @key_len: length of @key_data
* @key_dat: the key data
* @salt_len: the length of @salt_data, can be 0
* @salt_data: salt data
* @kv_type: the Key Validity type
* @kv_len: length of @kv_data
* @kv_data: key validity data
*
* The Key data payload contains key material. It should be added as sub
* payload to the KEMAC.
*/
typedef struct {
GstMIKEYPayload pt;
GstMIKEYKeyDataType key_type;
guint16 key_len;
guint8 *key_data;
guint16 salt_len;
guint8 *salt_data;
GstMIKEYKVType kv_type;
guint8 kv_len[2];
guint8 *kv_data[2];
} GstMIKEYPayloadKeyData;
gboolean gst_mikey_payload_key_data_set_key (GstMIKEYPayload *payload,
GstMIKEYKeyDataType key_type,
guint16 key_len, const guint8 *key_data);
gboolean gst_mikey_payload_key_data_set_salt (GstMIKEYPayload *payload,
guint16 salt_len, const guint8 *salt_data);
gboolean gst_mikey_payload_key_data_set_spi (GstMIKEYPayload *payload,
guint8 spi_len, const guint8 *spi_data);
gboolean gst_mikey_payload_key_data_set_interval (GstMIKEYPayload *payload,
guint8 vf_len, const guint8 *vf_data,
guint8 vt_len, const guint8 *vt_data);
/**
* GstMIKEYMessage:
@ -432,12 +501,15 @@ struct _GstMIKEYMessage
GArray *payloads;
};
GstMIKEYMessage * gst_mikey_message_new (void);
GstMIKEYMessage * gst_mikey_message_new_from_data (gconstpointer data, gsize size);
GstMIKEYMessage * gst_mikey_message_new_from_bytes (GBytes *bytes);
void gst_mikey_message_free (GstMIKEYMessage *msg);
GBytes * gst_mikey_message_to_bytes (GstMIKEYMessage *msg);
GstMIKEYMessage * gst_mikey_message_new (void);
GstMIKEYMessage * gst_mikey_message_new_from_data (gconstpointer data, gsize size,
GstMIKEYDecryptInfo *info, GError **error);
GstMIKEYMessage * gst_mikey_message_new_from_bytes (GBytes *bytes, GstMIKEYDecryptInfo *info,
GError **error);
GBytes * gst_mikey_message_to_bytes (GstMIKEYMessage *msg, GstMIKEYEncryptInfo *info,
GError **error);
void gst_mikey_message_free (GstMIKEYMessage *msg);
gboolean gst_mikey_message_set_info (GstMIKEYMessage *msg,
guint8 version, GstMIKEYType type, gboolean V,
@ -470,10 +542,6 @@ gboolean gst_mikey_message_replace_payload (GstMIKEYMessage
/* Key data transport payload (KEMAC) */
gboolean gst_mikey_message_add_kemac (GstMIKEYMessage *msg,
GstMIKEYEncAlg enc_alg,
guint16 enc_len, const guint8 *enc_data,
GstMIKEYMacAlg mac_alg, const guint8 *mac);
/* Envelope data payload (PKE) */
gboolean gst_mikey_message_add_pke (GstMIKEYMessage *msg,
GstMIKEYCacheType C,
@ -497,7 +565,6 @@ gboolean gst_mikey_message_add_rand_len (GstMIKEYMessage
/* Error payload (ERR) */
/* Key data sub-payload */
/* Key validity data */
/* General Extension Payload */

View file

@ -55,7 +55,7 @@ GST_START_TEST (create_common)
fail_unless (msg->CSB_id == 0x12345678);
fail_unless (msg->map_type == GST_MIKEY_MAP_TYPE_SRTP);
bytes = gst_mikey_message_to_bytes (msg);
bytes = gst_mikey_message_to_bytes (msg, NULL, NULL);
data = g_bytes_get_data (bytes, &size);
fail_unless (data != NULL);
fail_unless (size == 10);
@ -67,7 +67,7 @@ GST_START_TEST (create_common)
fail_unless (gst_mikey_message_add_cs_srtp (msg, 2, 0x23456789, 1));
fail_unless (gst_mikey_message_get_n_cs (msg) == 2);
bytes = gst_mikey_message_to_bytes (msg);
bytes = gst_mikey_message_to_bytes (msg, NULL, NULL);
data = g_bytes_get_data (bytes, &size);
fail_unless (size == 28);
fail_unless (memcmp (data + 10, test_data2, 18) == 0);
@ -113,10 +113,11 @@ GST_END_TEST
GST_START_TEST (create_payloads)
{
GstMIKEYMessage *msg;
GstMIKEYPayload *payload;
const GstMIKEYPayload *cp;
GstMIKEYPayload *payload, *kp;
const GstMIKEYPayload *cp, *cp2;
const GstMIKEYPayloadKEMAC *p;
const GstMIKEYPayloadT *pt;
const GstMIKEYPayloadKeyData *pkd;
const guint8 ntp_data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
const guint8 edata[] = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0x10
@ -147,32 +148,37 @@ GST_START_TEST (create_payloads)
fail_unless (payload->type == GST_MIKEY_PT_T);
fail_unless (gst_mikey_message_get_n_payloads (msg) == 1);
bytes = gst_mikey_message_to_bytes (msg);
bytes = gst_mikey_message_to_bytes (msg, NULL, NULL);
data = g_bytes_get_data (bytes, &size);
fail_unless (data != NULL);
fail_unless (size == 20);
g_bytes_unref (bytes);
fail_unless (gst_mikey_message_add_kemac (msg, GST_MIKEY_ENC_NULL, 16,
edata, GST_MIKEY_MAC_NULL, NULL));
payload = gst_mikey_payload_new (GST_MIKEY_PT_KEMAC);
fail_unless (gst_mikey_payload_kemac_set (payload, GST_MIKEY_ENC_NULL,
GST_MIKEY_MAC_NULL));
/* add the edata as a key payload */
kp = gst_mikey_payload_new (GST_MIKEY_PT_KEY_DATA);
gst_mikey_payload_key_data_set_key (kp, GST_MIKEY_KD_TEK,
sizeof (edata), edata);
fail_unless (gst_mikey_payload_kemac_add_sub (payload, kp));
fail_unless (gst_mikey_message_add_payload (msg, payload));
fail_unless (gst_mikey_message_get_n_payloads (msg) == 2);
p = (GstMIKEYPayloadKEMAC *) gst_mikey_message_get_payload (msg, 1);
p = (GstMIKEYPayloadKEMAC *) gst_mikey_message_get_payload (msg, 1);
fail_unless (p->enc_alg == GST_MIKEY_ENC_NULL);
fail_unless (p->enc_len == 16);
fail_unless (memcmp (p->enc_data, edata, 16) == 0);
fail_unless (p->mac_alg == GST_MIKEY_MAC_NULL);
fail_unless (p->mac == NULL);
fail_unless (gst_mikey_payload_kemac_get_n_sub (&p->pt) == 1);
fail_unless ((cp = gst_mikey_message_get_payload (msg, 0)) != NULL);
fail_unless (cp->type == GST_MIKEY_PT_T);
fail_unless ((cp = gst_mikey_message_get_payload (msg, 1)) != NULL);
fail_unless (cp->type == GST_MIKEY_PT_KEMAC);
bytes = gst_mikey_message_to_bytes (msg);
bytes = gst_mikey_message_to_bytes (msg, NULL, NULL);
gst_mikey_message_free (msg);
msg = gst_mikey_message_new_from_bytes (bytes);
msg = gst_mikey_message_new_from_bytes (bytes, NULL, NULL);
fail_unless (msg != NULL);
g_bytes_unref (bytes);
fail_unless (gst_mikey_message_get_n_payloads (msg) == 2);
@ -180,6 +186,19 @@ GST_START_TEST (create_payloads)
fail_unless (cp->type == GST_MIKEY_PT_T);
fail_unless ((cp = gst_mikey_message_get_payload (msg, 1)) != NULL);
fail_unless (cp->type == GST_MIKEY_PT_KEMAC);
fail_unless ((cp2 = gst_mikey_payload_kemac_get_sub (cp, 0)) != NULL);
fail_unless (cp2->type == GST_MIKEY_PT_KEY_DATA);
pkd = (GstMIKEYPayloadKeyData *) cp2;
fail_unless (pkd->key_type == GST_MIKEY_KD_TEK);
fail_unless (pkd->key_len == sizeof (edata));
fail_unless (memcmp (pkd->key_data, edata, sizeof (edata)) == 0);
fail_unless (pkd->salt_len == 0);
fail_unless (pkd->salt_data == 0);
fail_unless (pkd->kv_type == GST_MIKEY_KV_NULL);
gst_mikey_message_free (msg);
}

View file

@ -1,6 +1,5 @@
EXPORTS
gst_mikey_message_add_cs_srtp
gst_mikey_message_add_kemac
gst_mikey_message_add_payload
gst_mikey_message_add_pke
gst_mikey_message_add_rand
@ -26,7 +25,15 @@ EXPORTS
gst_mikey_message_to_bytes
gst_mikey_payload_copy
gst_mikey_payload_free
gst_mikey_payload_kemac_add_sub
gst_mikey_payload_kemac_get_n_sub
gst_mikey_payload_kemac_get_sub
gst_mikey_payload_kemac_remove_sub
gst_mikey_payload_kemac_set
gst_mikey_payload_key_data_set_interval
gst_mikey_payload_key_data_set_key
gst_mikey_payload_key_data_set_salt
gst_mikey_payload_key_data_set_spi
gst_mikey_payload_new
gst_mikey_payload_pke_set
gst_mikey_payload_rand_set