srt: add passphrase and key length properties

For stream encryption, both `passphrase` and `key-length`
properties are required.

https://bugzilla.gnome.org/show_bug.cgi?id=790315
This commit is contained in:
Justin Kim 2017-11-13 23:01:58 +09:00 committed by Nicolas Dufresne
parent f3b539e0ff
commit ec32124cf0
10 changed files with 113 additions and 6 deletions

View file

@ -33,10 +33,11 @@
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
SRTSOCKET
gst_srt_client_connect (GstElement * elem, int sender,
gst_srt_client_connect_full (GstElement * elem, int sender,
const gchar * host, guint16 port, int rendez_vous,
const gchar * bind_address, guint16 bind_port, int latency,
GSocketAddress ** socket_address, gint * poll_id)
GSocketAddress ** socket_address, gint * poll_id, gchar * passphrase,
int key_length)
{
SRTSOCKET sock;
GError *error = NULL;
@ -78,6 +79,11 @@ gst_srt_client_connect (GstElement * elem, int sender,
srt_setsockopt (sock, 0, SRTO_RENDEZVOUS, &rendez_vous, sizeof (int));
if (passphrase != NULL && passphrase[0] != '\0') {
srt_setsockopt (sock, 0, SRTO_PASSPHRASE, passphrase, strlen (passphrase));
srt_setsockopt (sock, 0, SRTO_PBKEYLEN, &key_length, sizeof (int));
}
if (bind_address || bind_port || rendez_vous) {
gpointer bsa;
size_t bsa_len;
@ -153,6 +159,17 @@ failed:
return SRT_INVALID_SOCK;
}
SRTSOCKET
gst_srt_client_connect (GstElement * elem, int sender,
const gchar * host, guint16 port, int rendez_vous,
const gchar * bind_address, guint16 bind_port, int latency,
GSocketAddress ** socket_address, gint * poll_id)
{
return gst_srt_client_connect_full (elem, sender, host, port,
rendez_vous, bind_address, bind_port, latency, socket_address, poll_id,
NULL, 0);
}
static gboolean
plugin_init (GstPlugin * plugin)
{

View file

@ -31,6 +31,7 @@
#define SRT_DEFAULT_HOST "127.0.0.1"
#define SRT_DEFAULT_URI SRT_URI_SCHEME"://"SRT_DEFAULT_HOST":"G_STRINGIFY(SRT_DEFAULT_PORT)
#define SRT_DEFAULT_LATENCY 125
#define SRT_DEFAULT_KEY_LENGTH 16
G_BEGIN_DECLS
@ -40,6 +41,13 @@ gst_srt_client_connect (GstElement * elem, int sender,
const gchar * bind_address, guint16 bind_port, int latency,
GSocketAddress ** socket_address, gint * poll_id);
SRTSOCKET
gst_srt_client_connect_full (GstElement * elem, int sender,
const gchar * host, guint16 port, int rendez_vous,
const gchar * bind_address, guint16 bind_port, int latency,
GSocketAddress ** socket_address, gint * poll_id,
gchar * passphrase, int key_length);
G_END_DECLS

View file

@ -37,6 +37,9 @@ enum
{
PROP_URI = 1,
PROP_LATENCY,
PROP_PASSPHRASE,
PROP_KEY_LENGTH,
/*< private > */
PROP_LAST
};
@ -73,6 +76,12 @@ gst_srt_base_sink_get_property (GObject * object,
case PROP_LATENCY:
g_value_set_int (value, self->latency);
break;
case PROP_PASSPHRASE:
g_value_set_string (value, self->passphrase);
break;
case PROP_KEY_LENGTH:
g_value_set_int (value, self->key_length);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -93,6 +102,18 @@ gst_srt_base_sink_set_property (GObject * object,
case PROP_LATENCY:
self->latency = g_value_get_int (value);
break;
case PROP_PASSPHRASE:
g_free (self->passphrase);
self->passphrase = g_value_dup_string (value);
break;
case PROP_KEY_LENGTH:
{
gint key_length = g_value_get_int (value);
g_return_if_fail (key_length == 16 || key_length == 24
|| key_length == 32);
self->key_length = key_length;
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -105,6 +126,7 @@ gst_srt_base_sink_finalize (GObject * object)
GstSRTBaseSink *self = GST_SRT_BASE_SINK (object);
g_clear_pointer (&self->uri, gst_uri_unref);
g_clear_pointer (&self->passphrase, g_free);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -166,6 +188,15 @@ gst_srt_base_sink_class_init (GstSRTBaseSinkClass * klass)
G_MAXINT32, SRT_DEFAULT_LATENCY,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
properties[PROP_PASSPHRASE] = g_param_spec_string ("passphrase", "Passphrase",
"The password for the encrypted transmission", NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
properties[PROP_KEY_LENGTH] =
g_param_spec_int ("key-length", "key length",
"Crypto key length in bytes{16,24,32}", 16,
32, SRT_DEFAULT_KEY_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, PROP_LAST, properties);
gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_srt_base_sink_render);
@ -177,6 +208,8 @@ gst_srt_base_sink_init (GstSRTBaseSink * self)
self->uri = gst_uri_from_string (SRT_DEFAULT_URI);
self->queued_buffers = NULL;
self->latency = SRT_DEFAULT_LATENCY;
self->passphrase = NULL;
self->key_length = SRT_DEFAULT_KEY_LENGTH;
}
static GstURIType

View file

@ -47,6 +47,8 @@ struct _GstSRTBaseSink {
GstUri *uri;
GList *queued_buffers;
gint latency;
gchar *passphrase;
gint key_length;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];

View file

@ -37,6 +37,8 @@ enum
PROP_URI = 1,
PROP_CAPS,
PROP_LATENCY,
PROP_PASSPHRASE,
PROP_KEY_LENGTH,
/*< private > */
PROP_LAST
@ -78,6 +80,12 @@ gst_srt_base_src_get_property (GObject * object,
case PROP_LATENCY:
g_value_set_int (value, self->latency);
break;
case PROP_PASSPHRASE:
g_value_set_string (value, self->passphrase);
break;
case PROP_KEY_LENGTH:
g_value_set_int (value, self->key_length);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -104,6 +112,18 @@ gst_srt_base_src_set_property (GObject * object,
case PROP_LATENCY:
self->latency = g_value_get_int (value);
break;
case PROP_PASSPHRASE:
g_free (self->passphrase);
self->passphrase = g_value_dup_string (value);
break;
case PROP_KEY_LENGTH:
{
gint key_length = g_value_get_int (value);
g_return_if_fail (key_length == 16 || key_length == 24
|| key_length == 32);
self->key_length = key_length;
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -117,6 +137,7 @@ gst_srt_base_src_finalize (GObject * object)
g_clear_pointer (&self->uri, gst_uri_unref);
g_clear_pointer (&self->caps, gst_caps_unref);
g_clear_pointer (&self->passphrase, g_free);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -182,6 +203,15 @@ gst_srt_base_src_class_init (GstSRTBaseSrcClass * klass)
G_MAXINT32, SRT_DEFAULT_LATENCY,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
properties[PROP_PASSPHRASE] = g_param_spec_string ("passphrase", "Passphrase",
"The password for the encrypted transmission", NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
properties[PROP_KEY_LENGTH] =
g_param_spec_int ("key-length", "key length",
"Crypto key length in bytes{16,24,32}", 16,
32, SRT_DEFAULT_KEY_LENGTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, PROP_LAST, properties);
gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_srt_base_src_get_caps);
@ -194,6 +224,7 @@ gst_srt_base_src_init (GstSRTBaseSrc * self)
gst_base_src_set_format (GST_BASE_SRC (self), GST_FORMAT_TIME);
gst_base_src_set_live (GST_BASE_SRC (self), TRUE);
self->latency = SRT_DEFAULT_LATENCY;
self->key_length = SRT_DEFAULT_KEY_LENGTH;
}
static GstURIType

View file

@ -44,6 +44,8 @@ struct _GstSRTBaseSrc {
GstUri *uri;
GstCaps *caps;
gint latency;
gchar *passphrase;
gint key_length;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];

View file

@ -157,10 +157,10 @@ gst_srt_client_sink_start (GstBaseSink * sink)
GstSRTBaseSink *base = GST_SRT_BASE_SINK (sink);
GstUri *uri = gst_uri_ref (GST_SRT_BASE_SINK (self)->uri);
priv->sock = gst_srt_client_connect (GST_ELEMENT (sink), FALSE,
priv->sock = gst_srt_client_connect_full (GST_ELEMENT (sink), FALSE,
gst_uri_get_host (uri), gst_uri_get_port (uri), priv->rendez_vous,
priv->bind_address, priv->bind_port, base->latency,
&priv->sockaddr, &priv->poll_id);
&priv->sockaddr, &priv->poll_id, base->passphrase, base->key_length);
g_clear_pointer (&uri, gst_uri_unref);

View file

@ -240,10 +240,10 @@ gst_srt_client_src_start (GstBaseSrc * src)
GstUri *uri = gst_uri_ref (base->uri);
GSocketAddress *socket_address = NULL;
priv->sock = gst_srt_client_connect (GST_ELEMENT (src), FALSE,
priv->sock = gst_srt_client_connect_full (GST_ELEMENT (src), FALSE,
gst_uri_get_host (uri), gst_uri_get_port (uri), priv->rendez_vous,
priv->bind_address, priv->bind_port, base->latency,
&socket_address, &priv->poll_id);
&socket_address, &priv->poll_id, base->passphrase, base->key_length);
g_clear_object (&socket_address);
g_clear_pointer (&uri, gst_uri_unref);

View file

@ -321,6 +321,13 @@ gst_srt_server_sink_start (GstBaseSink * sink)
srt_setsockopt (priv->sock, 0, SRTO_TSBPDDELAY, &lat, sizeof (int));
if (base->passphrase != NULL && base->passphrase[0] != '\0') {
srt_setsockopt (priv->sock, 0, SRTO_PASSPHRASE,
base->passphrase, strlen (base->passphrase));
srt_setsockopt (priv->sock, 0, SRTO_PBKEYLEN,
&base->key_length, sizeof (int));
}
priv->poll_id = srt_epoll_create ();
if (priv->poll_id == -1) {
GST_WARNING_OBJECT (self,

View file

@ -320,6 +320,13 @@ gst_srt_server_src_start (GstBaseSrc * src)
srt_setsockopt (priv->sock, 0, SRTO_TSBPDDELAY, &lat, sizeof (int));
if (base->passphrase != NULL && base->passphrase[0] != '\0') {
srt_setsockopt (priv->sock, 0, SRTO_PASSPHRASE,
base->passphrase, strlen (base->passphrase));
srt_setsockopt (priv->sock, 0, SRTO_PBKEYLEN,
&base->key_length, sizeof (int));
}
priv->poll_id = srt_epoll_create ();
if (priv->poll_id == -1) {
GST_ELEMENT_ERROR (self, LIBRARY, INIT, (NULL),