* the clients will start with a rollover counter of 0 which will
* probably be incorrect if the stream has been transmitted for a
* 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"
PROP_RANDOM_KEY,
PROP_REPLAY_WINDOW_SIZE,
PROP_ALLOW_REPEAT_TX,
- PROP_STATS
+ PROP_STATS,
+ PROP_MKI
};
typedef struct ProcessBufferItData
g_object_class_install_property (gobject_class, PROP_STATS,
g_param_spec_boxed ("stats", "Statistics", "Various statistics",
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:
srtp_policy_t policy;
GstMapInfo map;
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));
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.type = ssrc_any_outbound;
policy.next = NULL;
ret = srtp_create (&filter->session, &policy);
filter->first_session = FALSE;
+#ifdef HAVE_SRTP2
+done:
+
+ if (has_mki)
+ gst_buffer_unmap (filter->mki, &mki_map);
+#endif
+
if (HAS_CRYPTO (filter))
gst_buffer_unmap (filter->key, &map);
+
return ret;
}
}
gst_iterator_free (it);
- if (filter->key)
- gst_buffer_unref (filter->key);
- filter->key = NULL;
+ gst_buffer_replace (&filter->key, NULL);
+ gst_buffer_replace (&filter->mki, NULL);
if (filter->ssrcs_set)
g_hash_table_unref (filter->ssrcs_set);
switch (prop_id) {
case PROP_MKEY:
- if (filter->key)
- gst_buffer_unref (filter->key);
+ gst_clear_buffer (&filter->key);
filter->key = g_value_dup_boxed (value);
filter->key_changed = TRUE;
GST_INFO_OBJECT (object, "Set property: key=[%p]", filter->key);
case PROP_ALLOW_REPEAT_TX:
filter->allow_repeat_tx = g_value_get_boolean (value);
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:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
case PROP_STATS:
g_value_take_boxed (value, gst_srtp_enc_create_stats (filter));
break;
+#ifdef HAVE_SRTP2
+ case PROP_MKI:
+ if (filter->mki)
+ g_value_set_boxed (value, filter->mki);
+ break;
+#endif
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
if (HAS_CRYPTO (filter))
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 */
gst_structure_set (ps,
"srtp-cipher", G_TYPE_STRING,
else
gst_structure_set_name (ps, "application/x-rtp");
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);
ret = GST_FLOW_FLUSHING;
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)
err = srtp_protect_rtcp (filter->session, mapout.data, &size);
else
err = srtp_protect (filter->session, mapout.data, &size);
+#endif
GST_OBJECT_UNLOCK (filter);