mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 18:05:37 +00:00
srtpenc: Add support for adding a MKI
https://bugzilla.gnome.org/show_bug.cgi?id=797305
This commit is contained in:
parent
46b5756d30
commit
75d4ede815
2 changed files with 83 additions and 9 deletions
|
@ -100,6 +100,10 @@
|
||||||
* the clients will start with a rollover counter of 0 which will
|
* the clients will start with a rollover counter of 0 which will
|
||||||
* probably be incorrect if the stream has been transmitted for a
|
* probably be incorrect if the stream has been transmitted for a
|
||||||
* while to other clients.
|
* while to other clients.
|
||||||
|
*
|
||||||
|
* This element supports sending with a single Master Key, it is possible to set the
|
||||||
|
* Master Key Identifier (MKI) using the "mki" property. If this property is set, the MKI
|
||||||
|
* will be added to every buffer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gstsrtpenc.h"
|
#include "gstsrtpenc.h"
|
||||||
|
@ -152,7 +156,8 @@ enum
|
||||||
PROP_RANDOM_KEY,
|
PROP_RANDOM_KEY,
|
||||||
PROP_REPLAY_WINDOW_SIZE,
|
PROP_REPLAY_WINDOW_SIZE,
|
||||||
PROP_ALLOW_REPEAT_TX,
|
PROP_ALLOW_REPEAT_TX,
|
||||||
PROP_STATS
|
PROP_STATS,
|
||||||
|
PROP_MKI
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ProcessBufferItData
|
typedef struct ProcessBufferItData
|
||||||
|
@ -318,6 +323,13 @@ gst_srtp_enc_class_init (GstSrtpEncClass * klass)
|
||||||
g_object_class_install_property (gobject_class, PROP_STATS,
|
g_object_class_install_property (gobject_class, PROP_STATS,
|
||||||
g_param_spec_boxed ("stats", "Statistics", "Various statistics",
|
g_param_spec_boxed ("stats", "Statistics", "Various statistics",
|
||||||
GST_TYPE_STRUCTURE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
GST_TYPE_STRUCTURE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||||
|
#ifdef HAVE_SRTP2
|
||||||
|
g_object_class_install_property (gobject_class, PROP_MKI,
|
||||||
|
g_param_spec_boxed ("mki", "MKI",
|
||||||
|
"Master key Identifier (NULL means no MKI)", GST_TYPE_BUFFER,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||||
|
GST_PARAM_MUTABLE_PLAYING));
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstSrtpEnc::soft-limit:
|
* GstSrtpEnc::soft-limit:
|
||||||
|
@ -372,6 +384,12 @@ gst_srtp_enc_create_session (GstSrtpEnc * filter)
|
||||||
srtp_policy_t policy;
|
srtp_policy_t policy;
|
||||||
GstMapInfo map;
|
GstMapInfo map;
|
||||||
guchar tmp[1];
|
guchar tmp[1];
|
||||||
|
#ifdef HAVE_SRTP2
|
||||||
|
srtp_master_key_t mkey;
|
||||||
|
srtp_master_key_t *mkey_ptr = &mkey;
|
||||||
|
gboolean has_mki = FALSE;
|
||||||
|
GstMapInfo mki_map;
|
||||||
|
#endif
|
||||||
|
|
||||||
memset (&policy, 0, sizeof (srtp_policy_t));
|
memset (&policy, 0, sizeof (srtp_policy_t));
|
||||||
|
|
||||||
|
@ -416,6 +434,29 @@ gst_srtp_enc_create_session (GstSrtpEnc * filter)
|
||||||
policy.key = tmp;
|
policy.key = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_SRTP2
|
||||||
|
if (filter->mki) {
|
||||||
|
if (!gst_buffer_map (filter->mki, &mki_map, GST_MAP_READ)) {
|
||||||
|
GST_OBJECT_UNLOCK (filter);
|
||||||
|
GST_ELEMENT_ERROR (filter, LIBRARY, SETTINGS, ("Could not map MKI"),
|
||||||
|
(NULL));
|
||||||
|
GST_OBJECT_LOCK (filter);
|
||||||
|
|
||||||
|
ret = srtp_err_status_fail;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
has_mki = TRUE;
|
||||||
|
|
||||||
|
policy.num_master_keys = 1;
|
||||||
|
policy.keys = &mkey_ptr;
|
||||||
|
mkey.key = policy.key;
|
||||||
|
policy.key = NULL;
|
||||||
|
|
||||||
|
mkey.mki_id = (guchar *) mki_map.data;
|
||||||
|
mkey.mki_size = mki_map.size;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
policy.ssrc.value = 0;
|
policy.ssrc.value = 0;
|
||||||
policy.ssrc.type = ssrc_any_outbound;
|
policy.ssrc.type = ssrc_any_outbound;
|
||||||
policy.next = NULL;
|
policy.next = NULL;
|
||||||
|
@ -429,9 +470,17 @@ gst_srtp_enc_create_session (GstSrtpEnc * filter)
|
||||||
ret = srtp_create (&filter->session, &policy);
|
ret = srtp_create (&filter->session, &policy);
|
||||||
filter->first_session = FALSE;
|
filter->first_session = FALSE;
|
||||||
|
|
||||||
|
#ifdef HAVE_SRTP2
|
||||||
|
done:
|
||||||
|
|
||||||
|
if (has_mki)
|
||||||
|
gst_buffer_unmap (filter->mki, &mki_map);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (HAS_CRYPTO (filter))
|
if (HAS_CRYPTO (filter))
|
||||||
gst_buffer_unmap (filter->key, &map);
|
gst_buffer_unmap (filter->key, &map);
|
||||||
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,9 +644,8 @@ gst_srtp_enc_dispose (GObject * object)
|
||||||
}
|
}
|
||||||
gst_iterator_free (it);
|
gst_iterator_free (it);
|
||||||
|
|
||||||
if (filter->key)
|
gst_buffer_replace (&filter->key, NULL);
|
||||||
gst_buffer_unref (filter->key);
|
gst_buffer_replace (&filter->mki, NULL);
|
||||||
filter->key = NULL;
|
|
||||||
|
|
||||||
if (filter->ssrcs_set)
|
if (filter->ssrcs_set)
|
||||||
g_hash_table_unref (filter->ssrcs_set);
|
g_hash_table_unref (filter->ssrcs_set);
|
||||||
|
@ -658,8 +706,7 @@ gst_srtp_enc_set_property (GObject * object, guint prop_id,
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_MKEY:
|
case PROP_MKEY:
|
||||||
if (filter->key)
|
gst_clear_buffer (&filter->key);
|
||||||
gst_buffer_unref (filter->key);
|
|
||||||
filter->key = g_value_dup_boxed (value);
|
filter->key = g_value_dup_boxed (value);
|
||||||
filter->key_changed = TRUE;
|
filter->key_changed = TRUE;
|
||||||
GST_INFO_OBJECT (object, "Set property: key=[%p]", filter->key);
|
GST_INFO_OBJECT (object, "Set property: key=[%p]", filter->key);
|
||||||
|
@ -697,7 +744,14 @@ gst_srtp_enc_set_property (GObject * object, guint prop_id,
|
||||||
case PROP_ALLOW_REPEAT_TX:
|
case PROP_ALLOW_REPEAT_TX:
|
||||||
filter->allow_repeat_tx = g_value_get_boolean (value);
|
filter->allow_repeat_tx = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
#ifdef HAVE_SRTP2
|
||||||
|
case PROP_MKI:
|
||||||
|
gst_clear_buffer (&filter->mki);
|
||||||
|
filter->mki = g_value_dup_boxed (value);
|
||||||
|
filter->key_changed = TRUE;
|
||||||
|
GST_INFO_OBJECT (object, "Set property: mki=[%p]", filter->mki);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -742,6 +796,12 @@ gst_srtp_enc_get_property (GObject * object, guint prop_id,
|
||||||
case PROP_STATS:
|
case PROP_STATS:
|
||||||
g_value_take_boxed (value, gst_srtp_enc_create_stats (filter));
|
g_value_take_boxed (value, gst_srtp_enc_create_stats (filter));
|
||||||
break;
|
break;
|
||||||
|
#ifdef HAVE_SRTP2
|
||||||
|
case PROP_MKI:
|
||||||
|
if (filter->mki)
|
||||||
|
g_value_set_boxed (value, filter->mki);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -816,6 +876,11 @@ gst_srtp_enc_sink_setcaps (GstPad * pad, GstSrtpEnc * filter,
|
||||||
if (HAS_CRYPTO (filter))
|
if (HAS_CRYPTO (filter))
|
||||||
gst_structure_set (ps, "srtp-key", GST_TYPE_BUFFER, filter->key, NULL);
|
gst_structure_set (ps, "srtp-key", GST_TYPE_BUFFER, filter->key, NULL);
|
||||||
|
|
||||||
|
#ifdef HAVE_SRTP2
|
||||||
|
if (filter->mki)
|
||||||
|
gst_structure_set (ps, "mki", GST_TYPE_BUFFER, filter->mki, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Add srtp-specific params to source caps */
|
/* Add srtp-specific params to source caps */
|
||||||
gst_structure_set (ps,
|
gst_structure_set (ps,
|
||||||
"srtp-cipher", G_TYPE_STRING,
|
"srtp-cipher", G_TYPE_STRING,
|
||||||
|
@ -894,7 +959,7 @@ gst_srtp_enc_sink_query (GstPad * pad, GstObject * parent, GstQuery * query,
|
||||||
else
|
else
|
||||||
gst_structure_set_name (ps, "application/x-rtp");
|
gst_structure_set_name (ps, "application/x-rtp");
|
||||||
gst_structure_remove_fields (ps, "srtp-key", "srtp-cipher", "srtp-auth",
|
gst_structure_remove_fields (ps, "srtp-key", "srtp-cipher", "srtp-auth",
|
||||||
"srtcp-cipher", "srtcp-auth", NULL);
|
"srtcp-cipher", "srtcp-auth", "mki", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_query_set_caps_result (query, ret);
|
gst_query_set_caps_result (query, ret);
|
||||||
|
@ -1059,11 +1124,19 @@ gst_srtp_enc_process_buffer (GstSrtpEnc * filter, GstPad * pad,
|
||||||
ret = GST_FLOW_FLUSHING;
|
ret = GST_FLOW_FLUSHING;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_SRTP2
|
||||||
|
if (is_rtcp)
|
||||||
|
err = srtp_protect_rtcp_mki (filter->session, mapout.data, &size,
|
||||||
|
(filter->mki != NULL), 0);
|
||||||
|
else
|
||||||
|
err = srtp_protect_mki (filter->session, mapout.data, &size,
|
||||||
|
(filter->mki != NULL), 0);
|
||||||
|
#else
|
||||||
if (is_rtcp)
|
if (is_rtcp)
|
||||||
err = srtp_protect_rtcp (filter->session, mapout.data, &size);
|
err = srtp_protect_rtcp (filter->session, mapout.data, &size);
|
||||||
else
|
else
|
||||||
err = srtp_protect (filter->session, mapout.data, &size);
|
err = srtp_protect (filter->session, mapout.data, &size);
|
||||||
|
#endif
|
||||||
|
|
||||||
GST_OBJECT_UNLOCK (filter);
|
GST_OBJECT_UNLOCK (filter);
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ struct _GstSrtpEnc
|
||||||
guint rtp_auth;
|
guint rtp_auth;
|
||||||
guint rtcp_cipher;
|
guint rtcp_cipher;
|
||||||
guint rtcp_auth;
|
guint rtcp_auth;
|
||||||
|
GstBuffer *mki;
|
||||||
|
|
||||||
srtp_t session;
|
srtp_t session;
|
||||||
gboolean first_session;
|
gboolean first_session;
|
||||||
|
|
Loading…
Reference in a new issue