1 /*
2  * GStreamer - GStreamer SRTP decoder
3  *
4  * Copyright 2009-2011 Collabora Ltd.
5  *  @author: Gabriel Millaire <gabriel.millaire@collabora.co.uk>
6  *  @author: Olivier Crete <olivier.crete@collabora.com>
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24  * DEALINGS IN THE SOFTWARE.
25  *
26  * Alternatively, the contents of this file may be used under the
27  * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
28  * which case the following provisions apply instead of the ones
29  * mentioned above:
30  *
31  * This library is free software; you can redistribute it and/or
32  * modify it under the terms of the GNU Library General Public
33  * License as published by the Free Software Foundation; either
34  * version 2 of the License, or (at your option) any later version.
35  *
36  * This library is distributed in the hope that it will be useful,
37  * but WITHOUT ANY WARRANTY; without even the implied warranty of
38  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
39  * Library General Public License for more details.
40  *
41  * You should have received a copy of the GNU Library General Public
42  * License along with this library; if not, write to the
43  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
44  * Boston, MA 02111-1307, USA.
45  */
46 
47 /**
48  * SECTION:element-srtpdec
49  * @title: srtpdec
50  * @see_also: srtpenc
51  *
52  * gstrtpdec acts as a decoder that removes security from SRTP and SRTCP
53  * packets (encryption and authentication) and out RTP and RTCP. It
54  * receives packet of type 'application/x-srtp' or 'application/x-srtcp'
55  * on its sink pad, and outs packets of type 'application/x-rtp' or
56  * 'application/x-rtcp' on its source pad.
57  *
58  * For each packet received, it checks if the internal SSRC is in the list
59  * of streams already in use. If this is not the case, it sends a signal to
60  * the user to get the needed parameters to create a new stream : master
61  * key, encryption and authentication mechanisms for both RTP and RTCP. If
62  * the user can't provide those parameters, the buffer is dropped and a
63  * warning is emitted.
64  *
65  * This element uses libsrtp library. The encryption and authentication
66  * mechanisms available are :
67  *
68  * Encryption
69  * - AES_ICM 256 bits (maximum security)
70  * - AES_ICM 128 bits (default)
71  * - NULL
72  *
73  * Authentication
74  * - HMAC_SHA1 80 bits (default, maximum protection)
75  * - HMAC_SHA1 32 bits
76  * - NULL
77  *
78  * Note that for SRTP protection, authentication is mandatory (non-null)
79  * if encryption is used (non-null).
80  *
81  * Each packet received is first analysed (checked for valid SSRC) then
82  * its buffer is unprotected with libsrtp, then pushed on the source pad.
83  * If protection failed or the stream could not be created, the buffer
84  * is dropped and a warning is emitted.
85  *
86  * When the maximum usage of the master key is reached, a soft-limit
87  * signal is sent to the user, and new parameters (master key) are needed
88  * in return. If the hard limit is reached, a flag is set and every
89  * subsequent packet is dropped, until a new key is set and the stream
90  * has been updated.
91  *
92  * If a stream is to be shared between multiple clients the SRTP
93  * rollover counter for a given SSRC must be set in the caps "roc" field
94  * when the request-key signal is emitted by the decoder. The rollover
95  * counters should have been transmitted by a signaling protocol by some
96  * other means. If no rollover counter is provided by the user, 0 is
97  * used by default.
98  *
99  * It is possible to receive a stream protected by multiple master keys, each buffer
100  * then contains a Master Key Identifier (MKI) to identify which key was used for this
101  * buffer. If multiple keys are needed, the first key can be specified in the caps as
102  * "srtp-key=(buffer)key1data, mki=(buffer)mki1data", then the second one can be given in
103  * the same caps as "srtp-key2=(buffer)key2data, mki2=(buffer)mki2data", and more can
104  * be added up to 15.
105  *
106  * ## Example pipelines
107  * |[
108  * gst-launch-1.0 udpsrc port=5004 caps='application/x-srtp, payload=(int)8, ssrc=(uint)1356955624, srtp-key=(buffer)012345678901234567890123456789012345678901234567890123456789, srtp-cipher=(string)aes-128-icm, srtp-auth=(string)hmac-sha1-80, srtcp-cipher=(string)aes-128-icm, srtcp-auth=(string)hmac-sha1-80' !  srtpdec ! rtppcmadepay ! alawdec ! pulsesink
109  * ]| Receive PCMA SRTP packets through UDP using caps to specify
110  * master key and protection.
111  * |[
112  * gst-launch-1.0 audiotestsrc ! alawenc ! rtppcmapay ! 'application/x-rtp, payload=(int)8, ssrc=(uint)1356955624' ! srtpenc key="012345678901234567890123456789012345678901234567890123456789" ! udpsink port=5004
113  * ]| Send PCMA SRTP packets through UDP, nothing how the SSRC is forced so
114  * that the receiver will recognize it.
115  *
116  */
117 
118 #include "gstsrtpdec.h"
119 
120 #include <gst/rtp/gstrtpbuffer.h>
121 #include <string.h>
122 
123 GST_DEBUG_CATEGORY_STATIC (gst_srtp_dec_debug);
124 #define GST_CAT_DEFAULT gst_srtp_dec_debug
125 
126 #define DEFAULT_REPLAY_WINDOW_SIZE 128
127 
128 /* Filter signals and args */
129 enum
130 {
131   SIGNAL_REQUEST_KEY = 1,
132   SIGNAL_CLEAR_KEYS,
133   SIGNAL_SOFT_LIMIT,
134   SIGNAL_HARD_LIMIT,
135   SIGNAL_REMOVE_KEY,
136   LAST_SIGNAL
137 };
138 
139 enum
140 {
141   PROP_0,
142   PROP_REPLAY_WINDOW_SIZE,
143   PROP_STATS
144 };
145 
146 /* the capabilities of the inputs and outputs.
147  *
148  * describe the real formats here.
149  */
150 static GstStaticPadTemplate rtp_sink_template =
151 GST_STATIC_PAD_TEMPLATE ("rtp_sink",
152     GST_PAD_SINK,
153     GST_PAD_ALWAYS,
154     GST_STATIC_CAPS ("application/x-srtp")
155     );
156 
157 static GstStaticPadTemplate rtp_src_template =
158 GST_STATIC_PAD_TEMPLATE ("rtp_src",
159     GST_PAD_SRC,
160     GST_PAD_ALWAYS,
161     GST_STATIC_CAPS ("application/x-rtp")
162     );
163 
164 static GstStaticPadTemplate rtcp_sink_template =
165 GST_STATIC_PAD_TEMPLATE ("rtcp_sink",
166     GST_PAD_SINK,
167     GST_PAD_ALWAYS,
168     GST_STATIC_CAPS ("application/x-srtcp")
169     );
170 
171 static GstStaticPadTemplate rtcp_src_template =
172 GST_STATIC_PAD_TEMPLATE ("rtcp_src",
173     GST_PAD_SRC,
174     GST_PAD_ALWAYS,
175     GST_STATIC_CAPS ("application/x-rtcp")
176     );
177 
178 static guint gst_srtp_dec_signals[LAST_SIGNAL] = { 0 };
179 
180 G_DEFINE_TYPE (GstSrtpDec, gst_srtp_dec, GST_TYPE_ELEMENT);
181 
182 static void gst_srtp_dec_set_property (GObject * object, guint prop_id,
183     const GValue * value, GParamSpec * pspec);
184 static void gst_srtp_dec_get_property (GObject * object, guint prop_id,
185     GValue * value, GParamSpec * pspec);
186 
187 static void gst_srtp_dec_clear_streams (GstSrtpDec * filter);
188 static void gst_srtp_dec_remove_stream (GstSrtpDec * filter, guint ssrc);
189 
190 static gboolean gst_srtp_dec_sink_event_rtp (GstPad * pad, GstObject * parent,
191     GstEvent * event);
192 static gboolean gst_srtp_dec_sink_event_rtcp (GstPad * pad, GstObject * parent,
193     GstEvent * event);
194 
195 static gboolean gst_srtp_dec_sink_query_rtp (GstPad * pad, GstObject * parent,
196     GstQuery * query);
197 static gboolean gst_srtp_dec_sink_query_rtcp (GstPad * pad,
198     GstObject * parent, GstQuery * query);
199 
200 
201 static GstIterator *gst_srtp_dec_iterate_internal_links_rtp (GstPad * pad,
202     GstObject * parent);
203 static GstIterator *gst_srtp_dec_iterate_internal_links_rtcp (GstPad * pad,
204     GstObject * parent);
205 
206 static GstFlowReturn gst_srtp_dec_chain_rtp (GstPad * pad,
207     GstObject * parent, GstBuffer * buf);
208 static GstFlowReturn gst_srtp_dec_chain_rtcp (GstPad * pad,
209     GstObject * parent, GstBuffer * buf);
210 
211 static GstStateChangeReturn gst_srtp_dec_change_state (GstElement * element,
212     GstStateChange transition);
213 
214 static GstSrtpDecSsrcStream *request_key_with_signal (GstSrtpDec * filter,
215     guint32 ssrc, gint signal);
216 
217 struct _GstSrtpDecSsrcStream
218 {
219   guint32 ssrc;
220 
221   guint32 roc;
222   GstBuffer *key;
223   GstSrtpCipherType rtp_cipher;
224   GstSrtpAuthType rtp_auth;
225   GstSrtpCipherType rtcp_cipher;
226   GstSrtpAuthType rtcp_auth;
227   GArray *keys;
228 };
229 
230 #ifdef HAVE_SRTP2
231 struct GstSrtpDecKey
232 {
233   GstBuffer *mki;
234   GstBuffer *key;
235 };
236 #endif
237 
238 #define STREAM_HAS_CRYPTO(stream)                       \
239   (stream->rtp_cipher != GST_SRTP_CIPHER_NULL ||        \
240       stream->rtcp_cipher != GST_SRTP_CIPHER_NULL ||    \
241       stream->rtp_auth != GST_SRTP_AUTH_NULL ||         \
242       stream->rtcp_auth != GST_SRTP_AUTH_NULL)
243 
244 
245 /* initialize the srtpdec's class */
246 static void
gst_srtp_dec_class_init(GstSrtpDecClass * klass)247 gst_srtp_dec_class_init (GstSrtpDecClass * klass)
248 {
249   GObjectClass *gobject_class;
250   GstElementClass *gstelement_class;
251 
252   gobject_class = (GObjectClass *) klass;
253   gstelement_class = (GstElementClass *) klass;
254 
255   gobject_class->set_property = gst_srtp_dec_set_property;
256   gobject_class->get_property = gst_srtp_dec_get_property;
257 
258   gst_element_class_add_static_pad_template (gstelement_class,
259       &rtp_src_template);
260   gst_element_class_add_static_pad_template (gstelement_class,
261       &rtp_sink_template);
262   gst_element_class_add_static_pad_template (gstelement_class,
263       &rtcp_src_template);
264   gst_element_class_add_static_pad_template (gstelement_class,
265       &rtcp_sink_template);
266 
267   gst_element_class_set_static_metadata (gstelement_class, "SRTP decoder",
268       "Filter/Network/SRTP",
269       "A SRTP and SRTCP decoder",
270       "Gabriel Millaire <millaire.gabriel@collabora.com>");
271 
272   /* Install callbacks */
273   gstelement_class->change_state =
274       GST_DEBUG_FUNCPTR (gst_srtp_dec_change_state);
275 
276   klass->clear_streams = GST_DEBUG_FUNCPTR (gst_srtp_dec_clear_streams);
277   klass->remove_stream = GST_DEBUG_FUNCPTR (gst_srtp_dec_remove_stream);
278 
279   /* Install properties */
280   g_object_class_install_property (gobject_class, PROP_REPLAY_WINDOW_SIZE,
281       g_param_spec_uint ("replay-window-size", "Replay window size",
282           "Size of the replay protection window",
283           64, 0x8000, DEFAULT_REPLAY_WINDOW_SIZE,
284           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
285   g_object_class_install_property (gobject_class, PROP_STATS,
286       g_param_spec_boxed ("stats", "Statistics", "Various statistics",
287           GST_TYPE_STRUCTURE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
288 
289   /* Install signals */
290   /**
291    * GstSrtpDec::request-key:
292    * @gstsrtpdec: the element on which the signal is emitted
293    * @ssrc: The unique SSRC of the stream
294    *
295    * Signal emited to get the parameters relevant to stream
296    * with @ssrc. User should provide the key and the RTP and
297    * RTCP encryption ciphers and authentication, and return
298    * them wrapped in a GstCaps.
299    */
300   gst_srtp_dec_signals[SIGNAL_REQUEST_KEY] =
301       g_signal_new ("request-key", G_TYPE_FROM_CLASS (klass),
302       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, GST_TYPE_CAPS, 1, G_TYPE_UINT);
303 
304   /**
305    * GstSrtpDec::clear-keys:
306    * @gstsrtpdec: the element on which the signal is emitted
307    *
308    * Clear the internal list of streams
309    */
310   gst_srtp_dec_signals[SIGNAL_CLEAR_KEYS] =
311       g_signal_new ("clear-keys", G_TYPE_FROM_CLASS (klass),
312       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
313       G_STRUCT_OFFSET (GstSrtpDecClass, clear_streams), NULL, NULL, NULL,
314       G_TYPE_NONE, 0, G_TYPE_NONE);
315 
316   /**
317    * GstSrtpDec::soft-limit:
318    * @gstsrtpdec: the element on which the signal is emitted
319    * @ssrc: The unique SSRC of the stream
320    *
321    * Signal emited when the stream with @ssrc has reached the
322    * soft limit of utilisation of it's master encryption key.
323    * User should provide a new key and new RTP and RTCP encryption
324    * ciphers and authentication, and return them wrapped in a
325    * GstCaps.
326    */
327   gst_srtp_dec_signals[SIGNAL_SOFT_LIMIT] =
328       g_signal_new ("soft-limit", G_TYPE_FROM_CLASS (klass),
329       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, GST_TYPE_CAPS, 1, G_TYPE_UINT);
330 
331   /**
332    * GstSrtpDec::hard-limit:
333    * @gstsrtpdec: the element on which the signal is emitted
334    * @ssrc: The unique SSRC of the stream
335    *
336    * Signal emited when the stream with @ssrc has reached the
337    * hard limit of utilisation of it's master encryption key.
338    * User should provide a new key and new RTP and RTCP encryption
339    * ciphers and authentication, and return them wrapped in a
340    * GstCaps. If user could not provide those parameters or signal
341    * is not answered, the buffers of this stream will be dropped.
342    */
343   gst_srtp_dec_signals[SIGNAL_HARD_LIMIT] =
344       g_signal_new ("hard-limit", G_TYPE_FROM_CLASS (klass),
345       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, GST_TYPE_CAPS, 1, G_TYPE_UINT);
346 
347   /**
348    * GstSrtpDec::remove-key:
349    * @gstsrtpdec: the element on which the signal is emitted
350    * @ssrc: The SSRC for which to remove the key.
351    *
352    * Removes keys for a specific SSRC
353    */
354   gst_srtp_dec_signals[SIGNAL_REMOVE_KEY] =
355       g_signal_new ("remove-key", G_TYPE_FROM_CLASS (klass),
356       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
357       G_STRUCT_OFFSET (GstSrtpDecClass, remove_stream), NULL, NULL, NULL,
358       G_TYPE_NONE, 1, G_TYPE_UINT);
359 
360 }
361 
362 /* initialize the new element
363  * instantiate pads and add them to element
364  * set pad calback functions
365  * initialize instance structure
366  */
367 static void
gst_srtp_dec_init(GstSrtpDec * filter)368 gst_srtp_dec_init (GstSrtpDec * filter)
369 {
370   filter->replay_window_size = DEFAULT_REPLAY_WINDOW_SIZE;
371 
372   filter->rtp_sinkpad =
373       gst_pad_new_from_static_template (&rtp_sink_template, "rtp_sink");
374   gst_pad_set_event_function (filter->rtp_sinkpad,
375       GST_DEBUG_FUNCPTR (gst_srtp_dec_sink_event_rtp));
376   gst_pad_set_query_function (filter->rtp_sinkpad,
377       GST_DEBUG_FUNCPTR (gst_srtp_dec_sink_query_rtp));
378   gst_pad_set_iterate_internal_links_function (filter->rtp_sinkpad,
379       GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtp));
380   gst_pad_set_chain_function (filter->rtp_sinkpad,
381       GST_DEBUG_FUNCPTR (gst_srtp_dec_chain_rtp));
382 
383   filter->rtp_srcpad =
384       gst_pad_new_from_static_template (&rtp_src_template, "rtp_src");
385   gst_pad_set_iterate_internal_links_function (filter->rtp_srcpad,
386       GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtp));
387 
388   gst_pad_set_element_private (filter->rtp_sinkpad, filter->rtp_srcpad);
389   gst_pad_set_element_private (filter->rtp_srcpad, filter->rtp_sinkpad);
390 
391   gst_element_add_pad (GST_ELEMENT (filter), filter->rtp_sinkpad);
392   gst_element_add_pad (GST_ELEMENT (filter), filter->rtp_srcpad);
393 
394 
395   filter->rtcp_sinkpad =
396       gst_pad_new_from_static_template (&rtcp_sink_template, "rtcp_sink");
397   gst_pad_set_event_function (filter->rtcp_sinkpad,
398       GST_DEBUG_FUNCPTR (gst_srtp_dec_sink_event_rtcp));
399   gst_pad_set_query_function (filter->rtcp_sinkpad,
400       GST_DEBUG_FUNCPTR (gst_srtp_dec_sink_query_rtcp));
401   gst_pad_set_iterate_internal_links_function (filter->rtcp_sinkpad,
402       GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtcp));
403   gst_pad_set_chain_function (filter->rtcp_sinkpad,
404       GST_DEBUG_FUNCPTR (gst_srtp_dec_chain_rtcp));
405 
406   filter->rtcp_srcpad =
407       gst_pad_new_from_static_template (&rtcp_src_template, "rtcp_src");
408   gst_pad_set_iterate_internal_links_function (filter->rtcp_srcpad,
409       GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtcp));
410 
411   gst_pad_set_element_private (filter->rtcp_sinkpad, filter->rtcp_srcpad);
412   gst_pad_set_element_private (filter->rtcp_srcpad, filter->rtcp_sinkpad);
413 
414   gst_element_add_pad (GST_ELEMENT (filter), filter->rtcp_sinkpad);
415   gst_element_add_pad (GST_ELEMENT (filter), filter->rtcp_srcpad);
416 
417   filter->first_session = TRUE;
418 
419 #ifndef HAVE_SRTP2
420   filter->roc_changed = FALSE;
421 #endif
422 }
423 
424 static GstStructure *
gst_srtp_dec_create_stats(GstSrtpDec * filter)425 gst_srtp_dec_create_stats (GstSrtpDec * filter)
426 {
427   GstStructure *s;
428   GValue va = G_VALUE_INIT;
429   GValue v = G_VALUE_INIT;
430 
431   s = gst_structure_new_empty ("application/x-srtp-decoder-stats");
432 
433   g_value_init (&va, GST_TYPE_ARRAY);
434   g_value_init (&v, GST_TYPE_STRUCTURE);
435 
436   if (filter->session) {
437     GHashTableIter iter;
438     gpointer key;
439 
440     g_hash_table_iter_init (&iter, filter->streams);
441     while (g_hash_table_iter_next (&iter, &key, NULL)) {
442       GstStructure *ss;
443       guint32 ssrc = GPOINTER_TO_UINT (key);
444       srtp_err_status_t status;
445       guint32 roc;
446 
447       status = srtp_get_stream_roc (filter->session, ssrc, &roc);
448       if (status != srtp_err_status_ok) {
449         continue;
450       }
451 
452       ss = gst_structure_new ("application/x-srtp-stream",
453           "ssrc", G_TYPE_UINT, ssrc, "roc", G_TYPE_UINT, roc, NULL);
454 
455       g_value_take_boxed (&v, ss);
456       gst_value_array_append_value (&va, &v);
457     }
458   }
459 
460   gst_structure_take_value (s, "streams", &va);
461   g_value_unset (&v);
462 
463   return s;
464 }
465 
466 static void
gst_srtp_dec_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)467 gst_srtp_dec_set_property (GObject * object, guint prop_id,
468     const GValue * value, GParamSpec * pspec)
469 {
470   GstSrtpDec *filter = GST_SRTP_DEC (object);
471 
472   GST_OBJECT_LOCK (filter);
473 
474   switch (prop_id) {
475     case PROP_REPLAY_WINDOW_SIZE:
476       filter->replay_window_size = g_value_get_uint (value);
477       break;
478     default:
479       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
480       break;
481   }
482 
483   GST_OBJECT_UNLOCK (filter);
484 }
485 
486 static void
gst_srtp_dec_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)487 gst_srtp_dec_get_property (GObject * object, guint prop_id,
488     GValue * value, GParamSpec * pspec)
489 {
490   GstSrtpDec *filter = GST_SRTP_DEC (object);
491 
492   GST_OBJECT_LOCK (filter);
493 
494   switch (prop_id) {
495     case PROP_REPLAY_WINDOW_SIZE:
496       g_value_set_uint (value, filter->replay_window_size);
497       break;
498     case PROP_STATS:
499       g_value_take_boxed (value, gst_srtp_dec_create_stats (filter));
500       break;
501     default:
502       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
503       break;
504   }
505 
506   GST_OBJECT_UNLOCK (filter);
507 }
508 
509 static void
gst_srtp_dec_remove_stream(GstSrtpDec * filter,guint ssrc)510 gst_srtp_dec_remove_stream (GstSrtpDec * filter, guint ssrc)
511 {
512   GstSrtpDecSsrcStream *stream = NULL;
513 
514   if (filter->streams == NULL)
515     return;
516 
517   stream = g_hash_table_lookup (filter->streams, GUINT_TO_POINTER (ssrc));
518 
519   if (stream) {
520     srtp_remove_stream (filter->session, ssrc);
521     g_hash_table_remove (filter->streams, GUINT_TO_POINTER (ssrc));
522   }
523 }
524 
525 static GstSrtpDecSsrcStream *
find_stream_by_ssrc(GstSrtpDec * filter,guint32 ssrc)526 find_stream_by_ssrc (GstSrtpDec * filter, guint32 ssrc)
527 {
528   return g_hash_table_lookup (filter->streams, GUINT_TO_POINTER (ssrc));
529 }
530 
531 #ifdef HAVE_SRTP2
532 static void
clear_key(gpointer data)533 clear_key (gpointer data)
534 {
535   struct GstSrtpDecKey *key = data;
536 
537   gst_clear_buffer (&key->mki);
538   gst_clear_buffer (&key->key);
539 }
540 #endif
541 
542 
543 /* get info from buffer caps
544  */
545 static GstSrtpDecSsrcStream *
get_stream_from_caps(GstSrtpDec * filter,GstCaps * caps,guint32 ssrc)546 get_stream_from_caps (GstSrtpDec * filter, GstCaps * caps, guint32 ssrc)
547 {
548   GstSrtpDecSsrcStream *stream;
549   GstStructure *s;
550   GstBuffer *buf;
551   const gchar *rtp_cipher, *rtp_auth, *rtcp_cipher, *rtcp_auth;
552 
553   /* Create new stream structure and set default values */
554   stream = g_slice_new0 (GstSrtpDecSsrcStream);
555   stream->ssrc = ssrc;
556   stream->key = NULL;
557 
558   /* Get info from caps */
559   s = gst_caps_get_structure (caps, 0);
560   if (!s)
561     goto error;
562 
563   rtp_cipher = gst_structure_get_string (s, "srtp-cipher");
564   rtp_auth = gst_structure_get_string (s, "srtp-auth");
565   rtcp_cipher = gst_structure_get_string (s, "srtcp-cipher");
566   rtcp_auth = gst_structure_get_string (s, "srtcp-auth");
567   if (!rtp_cipher || !rtp_auth || !rtcp_cipher || !rtcp_auth)
568     goto error;
569 
570   gst_structure_get_uint (s, "roc", &stream->roc);
571 
572   stream->rtp_cipher = enum_value_from_nick (GST_TYPE_SRTP_CIPHER_TYPE,
573       rtp_cipher);
574   stream->rtp_auth = enum_value_from_nick (GST_TYPE_SRTP_AUTH_TYPE, rtp_auth);
575   stream->rtcp_cipher = enum_value_from_nick (GST_TYPE_SRTP_CIPHER_TYPE,
576       rtcp_cipher);
577   stream->rtcp_auth = enum_value_from_nick (GST_TYPE_SRTP_AUTH_TYPE, rtcp_auth);
578 
579   if ((gint) stream->rtp_cipher == -1 || (gint) stream->rtp_auth == -1 ||
580       (gint) stream->rtcp_cipher == -1 || (gint) stream->rtcp_auth == -1) {
581     GST_WARNING_OBJECT (filter, "Invalid caps for stream,"
582         " unknown cipher or auth type");
583     goto error;
584   }
585 
586   /* RFC 3711 says in "3. SRTP Framework" that SRTCP message authentication
587    * is MANDATORY. In case of GCM let the pipeline handle any errors.
588    */
589   if (stream->rtcp_cipher != GST_SRTP_CIPHER_AES_128_GCM
590       && stream->rtcp_cipher != GST_SRTP_CIPHER_AES_256_GCM
591       && stream->rtcp_cipher != GST_SRTP_CIPHER_NULL
592       && stream->rtcp_auth == GST_SRTP_AUTH_NULL) {
593     GST_WARNING_OBJECT (filter,
594         "Cannot have SRTP NULL authentication with a not-NULL encryption"
595         " cipher.");
596     goto error;
597   }
598 
599   if (gst_structure_get (s, "srtp-key", GST_TYPE_BUFFER, &buf, NULL) || !buf) {
600 #ifdef HAVE_SRTP2
601     GstBuffer *mki = NULL;
602     guint i;
603     gsize mki_size = 0;
604 #endif
605 
606     GST_DEBUG_OBJECT (filter, "Got key [%p] for SSRC %u", buf, ssrc);
607 
608 #ifdef HAVE_SRTP2
609     if (gst_structure_get (s, "mki", GST_TYPE_BUFFER, &mki, NULL) && mki) {
610       struct GstSrtpDecKey key = {.mki = mki,.key = buf };
611 
612       mki_size = gst_buffer_get_size (mki);
613       if (mki_size > SRTP_MAX_MKI_LEN) {
614         GST_WARNING_OBJECT (filter, "MKI is longer than allowed (%zu > %d).",
615             mki_size, SRTP_MAX_MKI_LEN);
616         gst_buffer_unref (mki);
617         gst_buffer_unref (buf);
618         goto error;
619       }
620 
621       stream->keys =
622           g_array_sized_new (FALSE, TRUE, sizeof (struct GstSrtpDecKey), 2);
623       g_array_set_clear_func (stream->keys, clear_key);
624 
625       g_array_append_val (stream->keys, key);
626 
627       /* Append more MKIs */
628       for (i = 1; i < SRTP_MAX_NUM_MASTER_KEYS; i++) {
629         char mki_id[16];
630         char key_id[16];
631         g_snprintf (mki_id, 16, "mki%d", i + 1);
632         g_snprintf (key_id, 16, "srtp-key%d", i + 1);
633 
634         if (gst_structure_get (s, mki_id, GST_TYPE_BUFFER, &mki,
635                 key_id, GST_TYPE_BUFFER, &buf, NULL)) {
636           if (gst_buffer_get_size (mki) != mki_size) {
637             GST_WARNING_OBJECT (filter,
638                 "MKIs need to all have the same size (first was %zu,"
639                 " current is %zu).", mki_size, gst_buffer_get_size (mki));
640             gst_buffer_unref (mki);
641             gst_buffer_unref (buf);
642             goto error;
643           }
644           key.mki = mki;
645           key.key = buf;
646           g_array_append_val (stream->keys, key);
647         } else {
648           break;
649         }
650       }
651     } else
652 #endif
653     {
654       stream->key = buf;
655     }
656   } else if (STREAM_HAS_CRYPTO (stream)) {
657     goto error;
658   }
659 
660   return stream;
661 
662 error:
663   g_slice_free (GstSrtpDecSsrcStream, stream);
664   return NULL;
665 }
666 
667 /* Get SRTP params by signal
668  */
669 static GstCaps *
signal_get_srtp_params(GstSrtpDec * filter,guint32 ssrc,gint signal)670 signal_get_srtp_params (GstSrtpDec * filter, guint32 ssrc, gint signal)
671 {
672   GstCaps *caps = NULL;
673 
674   g_signal_emit (filter, gst_srtp_dec_signals[signal], 0, ssrc, &caps);
675 
676   if (caps != NULL)
677     GST_DEBUG_OBJECT (filter, "Caps received");
678 
679   return caps;
680 }
681 
682 /* Create a stream in the session
683  */
684 static srtp_err_status_t
init_session_stream(GstSrtpDec * filter,guint32 ssrc,GstSrtpDecSsrcStream * stream)685 init_session_stream (GstSrtpDec * filter, guint32 ssrc,
686     GstSrtpDecSsrcStream * stream)
687 {
688   srtp_err_status_t ret;
689   srtp_policy_t policy;
690   GstMapInfo map;
691   guchar tmp[1];
692 #ifdef HAVE_SRTP2
693   GstMapInfo *key_maps = NULL;
694   GstMapInfo *mki_maps = NULL;
695 #endif
696 
697   memset (&policy, 0, sizeof (srtp_policy_t));
698 
699   if (!stream)
700     return srtp_err_status_bad_param;
701 
702   GST_INFO_OBJECT (filter, "Setting RTP policy...");
703   set_crypto_policy_cipher_auth (stream->rtp_cipher, stream->rtp_auth,
704       &policy.rtp);
705   GST_INFO_OBJECT (filter, "Setting RTCP policy...");
706   set_crypto_policy_cipher_auth (stream->rtcp_cipher, stream->rtcp_auth,
707       &policy.rtcp);
708 
709 #ifdef HAVE_SRTP2
710   if (stream->keys) {
711     guint i;
712     srtp_master_key_t *keys;
713 
714     keys = g_alloca (sizeof (srtp_master_key_t) * stream->keys->len);
715     policy.keys = g_alloca (sizeof (gpointer) * stream->keys->len);
716     key_maps = g_alloca (sizeof (GstMapInfo) * stream->keys->len);
717     mki_maps = g_alloca (sizeof (GstMapInfo) * stream->keys->len);
718 
719     for (i = 0; i < stream->keys->len; i++) {
720       struct GstSrtpDecKey *key =
721           &g_array_index (stream->keys, struct GstSrtpDecKey, i);
722       policy.keys[i] = &keys[i];
723 
724       gst_buffer_map (key->mki, &mki_maps[i], GST_MAP_READ);
725       gst_buffer_map (key->key, &key_maps[i], GST_MAP_READ);
726 
727       policy.keys[i]->key = (guchar *) key_maps[i].data;
728       policy.keys[i]->mki_id = (guchar *) mki_maps[i].data;
729       policy.keys[i]->mki_size = mki_maps[i].size;
730     }
731     policy.num_master_keys = stream->keys->len;
732   } else
733 #endif
734   if (stream->key) {
735     gst_buffer_map (stream->key, &map, GST_MAP_READ);
736     policy.key = (guchar *) map.data;
737   } else {
738     policy.key = tmp;
739   }
740 
741   policy.ssrc.value = ssrc;
742   policy.ssrc.type = ssrc_specific;
743   policy.window_size = filter->replay_window_size;
744   policy.next = NULL;
745 
746   /* If it is the first stream, create the session
747    * If not, add the stream policy to the session
748    */
749   if (filter->first_session)
750     ret = srtp_create (&filter->session, &policy);
751   else
752     ret = srtp_add_stream (filter->session, &policy);
753 
754   if (stream->key)
755     gst_buffer_unmap (stream->key, &map);
756 
757 #ifdef HAVE_SRTP2
758   if (key_maps) {
759     guint i;
760 
761     for (i = 0; i < stream->keys->len; i++) {
762       struct GstSrtpDecKey *key = &g_array_index (stream->keys,
763           struct GstSrtpDecKey, i);
764       gst_buffer_unmap (key->mki, &mki_maps[i]);
765       gst_buffer_unmap (key->key, &key_maps[i]);
766     }
767 
768   }
769 #endif
770 
771   if (ret == srtp_err_status_ok) {
772     srtp_err_status_t status;
773 
774     status = srtp_set_stream_roc (filter->session, ssrc, stream->roc);
775 #ifdef HAVE_SRTP2
776     (void) status;              /* Ignore unused variable */
777 #else
778     if (status == srtp_err_status_ok) {
779       /* Here, we just set the ROC, but we also need to set the initial
780        * RTP sequence number later, otherwise libsrtp will not be able
781        * to get the right packet index. */
782       filter->roc_changed = TRUE;
783     }
784 #endif
785 
786     filter->first_session = FALSE;
787     g_hash_table_insert (filter->streams, GUINT_TO_POINTER (stream->ssrc),
788         stream);
789   }
790 
791   return ret;
792 }
793 
794 /* Return a stream structure for a given buffer
795  */
796 static GstSrtpDecSsrcStream *
validate_buffer(GstSrtpDec * filter,GstBuffer * buf,guint32 * ssrc,gboolean * is_rtcp)797 validate_buffer (GstSrtpDec * filter, GstBuffer * buf, guint32 * ssrc,
798     gboolean * is_rtcp)
799 {
800   GstSrtpDecSsrcStream *stream = NULL;
801   GstRTPBuffer rtpbuf = GST_RTP_BUFFER_INIT;
802 
803   if (gst_rtp_buffer_map (buf,
804           GST_MAP_READ | GST_RTP_BUFFER_MAP_FLAG_SKIP_PADDING, &rtpbuf)) {
805     if (gst_rtp_buffer_get_payload_type (&rtpbuf) < 64
806         || gst_rtp_buffer_get_payload_type (&rtpbuf) > 80) {
807       *ssrc = gst_rtp_buffer_get_ssrc (&rtpbuf);
808 
809       gst_rtp_buffer_unmap (&rtpbuf);
810       *is_rtcp = FALSE;
811       goto have_ssrc;
812     }
813     gst_rtp_buffer_unmap (&rtpbuf);
814   }
815 
816   if (rtcp_buffer_get_ssrc (buf, ssrc)) {
817     *is_rtcp = TRUE;
818   } else {
819     GST_WARNING_OBJECT (filter, "No SSRC found in buffer");
820     return NULL;
821   }
822 
823 have_ssrc:
824 
825   stream = find_stream_by_ssrc (filter, *ssrc);
826 
827   if (stream)
828     return stream;
829 
830   return request_key_with_signal (filter, *ssrc, SIGNAL_REQUEST_KEY);
831 }
832 
833 static void
free_stream(GstSrtpDecSsrcStream * stream)834 free_stream (GstSrtpDecSsrcStream * stream)
835 {
836   if (stream->key)
837     gst_buffer_unref (stream->key);
838   if (stream->keys)
839     g_array_free (stream->keys, TRUE);
840   g_slice_free (GstSrtpDecSsrcStream, stream);
841 }
842 
843 static gboolean
buffers_are_equal(GstBuffer * a,GstBuffer * b)844 buffers_are_equal (GstBuffer * a, GstBuffer * b)
845 {
846   GstMapInfo info;
847 
848   if (a == b)
849     return TRUE;
850 
851   if (a == NULL || b == NULL)
852     return FALSE;
853 
854   if (gst_buffer_get_size (a) != gst_buffer_get_size (b))
855     return FALSE;
856 
857   if (gst_buffer_map (a, &info, GST_MAP_READ)) {
858     gboolean equal;
859 
860     equal = (gst_buffer_memcmp (b, 0, info.data, info.size) == 0);
861     gst_buffer_unmap (a, &info);
862 
863     return equal;
864   } else {
865     return FALSE;
866   }
867 }
868 
869 static gboolean
keys_are_equal(GArray * a,GArray * b)870 keys_are_equal (GArray * a, GArray * b)
871 {
872 #ifdef HAVE_SRTP2
873   guint i;
874 
875   if (a == b)
876     return TRUE;
877 
878   if (a == NULL || b == NULL)
879     return FALSE;
880 
881   if (a->len != b->len)
882     return FALSE;
883 
884   for (i = 0; i < a->len; i++) {
885     struct GstSrtpDecKey *key_a = &g_array_index (a,
886         struct GstSrtpDecKey, i);
887     struct GstSrtpDecKey *key_b = &g_array_index (b,
888         struct GstSrtpDecKey, i);
889 
890     if (!buffers_are_equal (key_a->mki, key_b->mki))
891       return FALSE;
892 
893     if (!buffers_are_equal (key_a->key, key_b->key))
894       return FALSE;
895   }
896 
897   return TRUE;
898 #else
899   return FALSE;
900 #endif
901 }
902 
903 /* Create new stream from params in caps
904  */
905 static GstSrtpDecSsrcStream *
update_session_stream_from_caps(GstSrtpDec * filter,guint32 ssrc,GstCaps * caps)906 update_session_stream_from_caps (GstSrtpDec * filter, guint32 ssrc,
907     GstCaps * caps)
908 {
909   GstSrtpDecSsrcStream *stream = NULL;
910   GstSrtpDecSsrcStream *old_stream = NULL;
911   srtp_err_status_t err;
912 
913   g_return_val_if_fail (GST_IS_SRTP_DEC (filter), NULL);
914   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
915 
916   stream = get_stream_from_caps (filter, caps, ssrc);
917 
918   old_stream = find_stream_by_ssrc (filter, ssrc);
919   if (stream && old_stream &&
920       stream->rtp_cipher == old_stream->rtp_cipher &&
921       stream->rtcp_cipher == old_stream->rtcp_cipher &&
922       stream->rtp_auth == old_stream->rtp_auth &&
923       stream->rtcp_auth == old_stream->rtcp_auth &&
924       ((stream->keys && keys_are_equal (stream->keys, old_stream->keys)) ||
925           buffers_are_equal (stream->key, old_stream->key))) {
926     free_stream (stream);
927     return old_stream;
928   }
929 
930   /* Remove existing stream, if any */
931   gst_srtp_dec_remove_stream (filter, ssrc);
932 
933   if (stream) {
934     /* Create new session stream */
935     err = init_session_stream (filter, ssrc, stream);
936 
937     if (err != srtp_err_status_ok) {
938       GST_WARNING_OBJECT (filter, "Failed to create the stream (err: %d)", err);
939       if (stream->key)
940         gst_buffer_unref (stream->key);
941       g_slice_free (GstSrtpDecSsrcStream, stream);
942       stream = NULL;
943     }
944   }
945 
946   return stream;
947 }
948 
949 static gboolean
remove_yes(gpointer key,gpointer value,gpointer user_data)950 remove_yes (gpointer key, gpointer value, gpointer user_data)
951 {
952   return TRUE;
953 }
954 
955 /* Clear the policy list
956  */
957 static void
gst_srtp_dec_clear_streams(GstSrtpDec * filter)958 gst_srtp_dec_clear_streams (GstSrtpDec * filter)
959 {
960   guint nb = 0;
961 
962   GST_OBJECT_LOCK (filter);
963 
964   if (!filter->first_session) {
965     srtp_dealloc (filter->session);
966     filter->session = NULL;
967   }
968 
969   if (filter->streams)
970     nb = g_hash_table_foreach_remove (filter->streams, remove_yes, NULL);
971 
972   filter->first_session = TRUE;
973 
974   GST_OBJECT_UNLOCK (filter);
975 
976   GST_DEBUG_OBJECT (filter, "Cleared %d streams", nb);
977 }
978 
979 /* Send a signal
980  */
981 static GstSrtpDecSsrcStream *
request_key_with_signal(GstSrtpDec * filter,guint32 ssrc,gint signal)982 request_key_with_signal (GstSrtpDec * filter, guint32 ssrc, gint signal)
983 {
984   GstCaps *caps;
985   GstSrtpDecSsrcStream *stream = NULL;
986 
987   caps = signal_get_srtp_params (filter, ssrc, signal);
988 
989   if (caps) {
990     stream = update_session_stream_from_caps (filter, ssrc, caps);
991     if (stream)
992       GST_DEBUG_OBJECT (filter, "New stream set with SSRC %u", ssrc);
993     else
994       GST_WARNING_OBJECT (filter, "Could not set stream with SSRC %u", ssrc);
995     gst_caps_unref (caps);
996   } else {
997     GST_WARNING_OBJECT (filter, "Could not get caps for stream with SSRC %u",
998         ssrc);
999   }
1000 
1001   return stream;
1002 }
1003 
1004 static gboolean
gst_srtp_dec_sink_setcaps(GstPad * pad,GstObject * parent,GstCaps * caps,gboolean is_rtcp)1005 gst_srtp_dec_sink_setcaps (GstPad * pad, GstObject * parent,
1006     GstCaps * caps, gboolean is_rtcp)
1007 {
1008   GstSrtpDec *filter = GST_SRTP_DEC (parent);
1009   GstPad *otherpad;
1010   GstStructure *ps;
1011   gboolean ret = FALSE;
1012 
1013   g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
1014 
1015   ps = gst_caps_get_structure (caps, 0);
1016 
1017   if (gst_structure_has_field_typed (ps, "ssrc", G_TYPE_UINT) &&
1018       gst_structure_has_field_typed (ps, "srtp-cipher", G_TYPE_STRING) &&
1019       gst_structure_has_field_typed (ps, "srtp-auth", G_TYPE_STRING) &&
1020       gst_structure_has_field_typed (ps, "srtcp-cipher", G_TYPE_STRING) &&
1021       gst_structure_has_field_typed (ps, "srtcp-auth", G_TYPE_STRING)) {
1022     guint ssrc;
1023 
1024     gst_structure_get_uint (ps, "ssrc", &ssrc);
1025 
1026     if (!update_session_stream_from_caps (filter, ssrc, caps)) {
1027       GST_WARNING_OBJECT (pad, "Could not create session from pad caps: %"
1028           GST_PTR_FORMAT, caps);
1029       return FALSE;
1030     }
1031   }
1032 
1033   caps = gst_caps_copy (caps);
1034   ps = gst_caps_get_structure (caps, 0);
1035   gst_structure_remove_fields (ps, "srtp-key", "srtp-cipher", "srtp-auth",
1036       "srtcp-cipher", "srtcp-auth", "mki", NULL);
1037 
1038   if (is_rtcp)
1039     gst_structure_set_name (ps, "application/x-rtcp");
1040   else
1041     gst_structure_set_name (ps, "application/x-rtp");
1042 
1043   otherpad = gst_pad_get_element_private (pad);
1044 
1045   ret = gst_pad_set_caps (otherpad, caps);
1046 
1047   gst_caps_unref (caps);
1048 
1049   return ret;
1050 }
1051 
1052 static gboolean
gst_srtp_dec_sink_event_rtp(GstPad * pad,GstObject * parent,GstEvent * event)1053 gst_srtp_dec_sink_event_rtp (GstPad * pad, GstObject * parent, GstEvent * event)
1054 {
1055   gboolean ret;
1056   GstCaps *caps;
1057   GstSrtpDec *filter = GST_SRTP_DEC (parent);
1058 
1059   switch (GST_EVENT_TYPE (event)) {
1060     case GST_EVENT_CAPS:
1061       gst_event_parse_caps (event, &caps);
1062       ret = gst_srtp_dec_sink_setcaps (pad, parent, caps, FALSE);
1063       gst_event_unref (event);
1064       return ret;
1065     case GST_EVENT_SEGMENT:
1066       /* Make sure to send a caps event downstream before the segment event,
1067        * even if upstream didn't */
1068       if (!gst_pad_has_current_caps (filter->rtp_srcpad)) {
1069         GstCaps *caps = gst_caps_new_empty_simple ("application/x-rtp");
1070 
1071         gst_pad_set_caps (filter->rtp_srcpad, caps);
1072         gst_caps_unref (caps);
1073       }
1074       filter->rtp_has_segment = TRUE;
1075       break;
1076     case GST_EVENT_FLUSH_STOP:
1077       filter->rtp_has_segment = FALSE;
1078       break;
1079     default:
1080       break;
1081   }
1082 
1083   return gst_pad_event_default (pad, parent, event);
1084 }
1085 
1086 static gboolean
gst_srtp_dec_sink_event_rtcp(GstPad * pad,GstObject * parent,GstEvent * event)1087 gst_srtp_dec_sink_event_rtcp (GstPad * pad, GstObject * parent,
1088     GstEvent * event)
1089 {
1090   gboolean ret;
1091   GstCaps *caps;
1092   GstSrtpDec *filter = GST_SRTP_DEC (parent);
1093 
1094   switch (GST_EVENT_TYPE (event)) {
1095     case GST_EVENT_CAPS:
1096       gst_event_parse_caps (event, &caps);
1097       ret = gst_srtp_dec_sink_setcaps (pad, parent, caps, TRUE);
1098       gst_event_unref (event);
1099       return ret;
1100     case GST_EVENT_SEGMENT:
1101       /* Make sure to send a caps event downstream before the segment event,
1102        * even if upstream didn't */
1103       if (!gst_pad_has_current_caps (filter->rtcp_srcpad)) {
1104         GstCaps *caps = gst_caps_new_empty_simple ("application/x-rtcp");
1105 
1106         gst_pad_set_caps (filter->rtcp_srcpad, caps);
1107         gst_caps_unref (caps);
1108       }
1109       filter->rtcp_has_segment = TRUE;
1110       break;
1111     case GST_EVENT_FLUSH_STOP:
1112       filter->rtcp_has_segment = FALSE;
1113       break;
1114     default:
1115       break;
1116   }
1117 
1118   return gst_pad_event_default (pad, parent, event);
1119 }
1120 
1121 static gboolean
gst_srtp_dec_sink_query(GstPad * pad,GstObject * parent,GstQuery * query,gboolean is_rtcp)1122 gst_srtp_dec_sink_query (GstPad * pad, GstObject * parent, GstQuery * query,
1123     gboolean is_rtcp)
1124 {
1125   switch (GST_QUERY_TYPE (query)) {
1126     case GST_QUERY_CAPS:
1127     {
1128       GstCaps *filter = NULL;
1129       GstCaps *other_filter = NULL;
1130       GstCaps *template_caps;
1131       GstPad *otherpad;
1132       GstCaps *other_caps;
1133       GstCaps *ret;
1134       int i;
1135 
1136       gst_query_parse_caps (query, &filter);
1137 
1138       otherpad = (GstPad *) gst_pad_get_element_private (pad);
1139 
1140       if (filter) {
1141         other_filter = gst_caps_copy (filter);
1142 
1143         for (i = 0; i < gst_caps_get_size (other_filter); i++) {
1144           GstStructure *ps = gst_caps_get_structure (other_filter, i);
1145           if (is_rtcp)
1146             gst_structure_set_name (ps, "application/x-rtcp");
1147           else
1148             gst_structure_set_name (ps, "application/x-rtp");
1149           gst_structure_remove_fields (ps, "srtp-key", "srtp-cipher",
1150               "srtp-auth", "srtcp-cipher", "srtcp-auth", "mki", NULL);
1151         }
1152       }
1153 
1154 
1155       other_caps = gst_pad_peer_query_caps (otherpad, other_filter);
1156       if (other_filter)
1157         gst_caps_unref (other_filter);
1158       if (!other_caps) {
1159         goto return_template;
1160       }
1161 
1162       template_caps = gst_pad_get_pad_template_caps (otherpad);
1163       ret = gst_caps_intersect_full (other_caps, template_caps,
1164           GST_CAPS_INTERSECT_FIRST);
1165       gst_caps_unref (other_caps);
1166       gst_caps_unref (template_caps);
1167 
1168       ret = gst_caps_make_writable (ret);
1169 
1170       for (i = 0; i < gst_caps_get_size (ret); i++) {
1171         GstStructure *ps = gst_caps_get_structure (ret, i);
1172         if (is_rtcp)
1173           gst_structure_set_name (ps, "application/x-srtcp");
1174         else
1175           gst_structure_set_name (ps, "application/x-srtp");
1176       }
1177 
1178       if (filter) {
1179         GstCaps *tmp;
1180 
1181         tmp = gst_caps_intersect (ret, filter);
1182         gst_caps_unref (ret);
1183         ret = tmp;
1184       }
1185 
1186       gst_query_set_caps_result (query, ret);
1187       gst_caps_unref (ret);
1188       return TRUE;
1189 
1190     return_template:
1191 
1192       ret = gst_pad_get_pad_template_caps (pad);
1193       gst_query_set_caps_result (query, ret);
1194       gst_caps_unref (ret);
1195       return TRUE;
1196     }
1197     default:
1198       return gst_pad_query_default (pad, parent, query);
1199   }
1200 }
1201 
1202 static gboolean
gst_srtp_dec_sink_query_rtp(GstPad * pad,GstObject * parent,GstQuery * query)1203 gst_srtp_dec_sink_query_rtp (GstPad * pad, GstObject * parent, GstQuery * query)
1204 {
1205   return gst_srtp_dec_sink_query (pad, parent, query, FALSE);
1206 }
1207 
1208 static gboolean
gst_srtp_dec_sink_query_rtcp(GstPad * pad,GstObject * parent,GstQuery * query)1209 gst_srtp_dec_sink_query_rtcp (GstPad * pad, GstObject * parent,
1210     GstQuery * query)
1211 {
1212   return gst_srtp_dec_sink_query (pad, parent, query, TRUE);
1213 }
1214 
1215 static GstIterator *
gst_srtp_dec_iterate_internal_links(GstPad * pad,GstObject * parent,gboolean is_rtcp)1216 gst_srtp_dec_iterate_internal_links (GstPad * pad, GstObject * parent,
1217     gboolean is_rtcp)
1218 {
1219   GstSrtpDec *filter = GST_SRTP_DEC (parent);
1220   GstPad *otherpad = NULL;
1221   GstIterator *it = NULL;
1222 
1223   otherpad = (GstPad *) gst_pad_get_element_private (pad);
1224 
1225   if (otherpad) {
1226     GValue val = { 0 };
1227 
1228     g_value_init (&val, GST_TYPE_PAD);
1229     g_value_set_object (&val, otherpad);
1230     it = gst_iterator_new_single (GST_TYPE_PAD, &val);
1231     g_value_unset (&val);
1232   } else {
1233     GST_ELEMENT_ERROR (GST_ELEMENT_CAST (filter), CORE, PAD, (NULL),
1234         ("Unable to get linked pad"));
1235   }
1236 
1237   return it;
1238 }
1239 
1240 static GstIterator *
gst_srtp_dec_iterate_internal_links_rtp(GstPad * pad,GstObject * parent)1241 gst_srtp_dec_iterate_internal_links_rtp (GstPad * pad, GstObject * parent)
1242 {
1243   return gst_srtp_dec_iterate_internal_links (pad, parent, FALSE);
1244 }
1245 
1246 static GstIterator *
gst_srtp_dec_iterate_internal_links_rtcp(GstPad * pad,GstObject * parent)1247 gst_srtp_dec_iterate_internal_links_rtcp (GstPad * pad, GstObject * parent)
1248 {
1249   return gst_srtp_dec_iterate_internal_links (pad, parent, TRUE);
1250 }
1251 
1252 static void
gst_srtp_dec_push_early_events(GstSrtpDec * filter,GstPad * pad,GstPad * otherpad,gboolean is_rtcp)1253 gst_srtp_dec_push_early_events (GstSrtpDec * filter, GstPad * pad,
1254     GstPad * otherpad, gboolean is_rtcp)
1255 {
1256   GstEvent *otherev, *ev;
1257 
1258   ev = gst_pad_get_sticky_event (pad, GST_EVENT_STREAM_START, 0);
1259   if (ev) {
1260     gst_event_unref (ev);
1261   } else {
1262     gchar *new_stream_id;
1263 
1264     otherev = gst_pad_get_sticky_event (otherpad, GST_EVENT_STREAM_START, 0);
1265 
1266     if (otherev) {
1267       const gchar *other_stream_id;
1268 
1269       gst_event_parse_stream_start (otherev, &other_stream_id);
1270 
1271       new_stream_id = g_strdup_printf ("%s/%s", other_stream_id,
1272           is_rtcp ? "rtcp" : "rtp");
1273       gst_event_unref (otherev);
1274     } else {
1275       new_stream_id = gst_pad_create_stream_id (pad, GST_ELEMENT (filter),
1276           is_rtcp ? "rtcp" : "rtp");
1277     }
1278 
1279     ev = gst_event_new_stream_start (new_stream_id);
1280     g_free (new_stream_id);
1281 
1282     gst_pad_push_event (pad, ev);
1283   }
1284 
1285   ev = gst_pad_get_sticky_event (pad, GST_EVENT_CAPS, 0);
1286   if (ev) {
1287     gst_event_unref (ev);
1288   } else {
1289     GstCaps *caps;
1290 
1291     if (is_rtcp)
1292       caps = gst_caps_new_empty_simple ("application/x-rtcp");
1293     else
1294       caps = gst_caps_new_empty_simple ("application/x-rtp");
1295 
1296     gst_pad_set_caps (pad, caps);
1297     gst_caps_unref (caps);
1298   }
1299 
1300   ev = gst_pad_get_sticky_event (pad, GST_EVENT_SEGMENT, 0);
1301   if (ev) {
1302     gst_event_unref (ev);
1303   } else {
1304     ev = gst_pad_get_sticky_event (otherpad, GST_EVENT_SEGMENT, 0);
1305 
1306     if (ev)
1307       gst_pad_push_event (pad, ev);
1308   }
1309 
1310   if (is_rtcp)
1311     filter->rtcp_has_segment = TRUE;
1312   else
1313     filter->rtp_has_segment = TRUE;
1314 
1315 }
1316 
1317 /*
1318  * This function should be called while holding the filter lock
1319  */
1320 static gboolean
gst_srtp_dec_decode_buffer(GstSrtpDec * filter,GstPad * pad,GstBuffer * buf,gboolean is_rtcp,guint32 ssrc)1321 gst_srtp_dec_decode_buffer (GstSrtpDec * filter, GstPad * pad, GstBuffer * buf,
1322     gboolean is_rtcp, guint32 ssrc)
1323 {
1324   GstMapInfo map;
1325   srtp_err_status_t err;
1326   gint size;
1327 
1328   GST_LOG_OBJECT (pad, "Received %s buffer of size %" G_GSIZE_FORMAT
1329       " with SSRC = %u", is_rtcp ? "RTCP" : "RTP", gst_buffer_get_size (buf),
1330       ssrc);
1331 
1332   /* Change buffer to remove protection */
1333   buf = gst_buffer_make_writable (buf);
1334 
1335   gst_buffer_map (buf, &map, GST_MAP_READWRITE);
1336   size = map.size;
1337 
1338 unprotect:
1339 
1340   gst_srtp_init_event_reporter ();
1341 
1342   if (is_rtcp) {
1343 #ifdef HAVE_SRTP2
1344     GstSrtpDecSsrcStream *stream = find_stream_by_ssrc (filter, ssrc);
1345 
1346     err = srtp_unprotect_rtcp_mki (filter->session, map.data, &size,
1347         stream && stream->keys);
1348 #else
1349     err = srtp_unprotect_rtcp (filter->session, map.data, &size);
1350 #endif
1351   } else {
1352 #ifndef HAVE_SRTP2
1353     /* If ROC has changed, we know we need to set the initial RTP
1354      * sequence number too. */
1355     if (filter->roc_changed) {
1356       srtp_stream_t stream;
1357 
1358       stream = srtp_get_stream (filter->session, htonl (ssrc));
1359 
1360       if (stream) {
1361         guint16 seqnum = 0;
1362         GstRTPBuffer rtpbuf = GST_RTP_BUFFER_INIT;
1363 
1364         gst_rtp_buffer_map (buf,
1365             GST_MAP_READ | GST_RTP_BUFFER_MAP_FLAG_SKIP_PADDING, &rtpbuf);
1366         seqnum = gst_rtp_buffer_get_seq (&rtpbuf);
1367         gst_rtp_buffer_unmap (&rtpbuf);
1368 
1369         /* We finally add the RTP sequence number to the current
1370          * rollover counter. */
1371         stream->rtp_rdbx.index &= ~0xFFFF;
1372         stream->rtp_rdbx.index |= seqnum;
1373       }
1374 
1375       filter->roc_changed = FALSE;
1376     }
1377 #endif
1378 
1379 #ifdef HAVE_SRTP2
1380     {
1381       GstSrtpDecSsrcStream *stream = find_stream_by_ssrc (filter, ssrc);
1382 
1383       err = srtp_unprotect_mki (filter->session, map.data, &size,
1384           stream && stream->keys);
1385     }
1386 #else
1387     err = srtp_unprotect (filter->session, map.data, &size);
1388 #endif
1389   }
1390 
1391   /* Signal user depending on type of error */
1392   switch (err) {
1393     case srtp_err_status_ok:
1394       /* success! */
1395       break;
1396     case srtp_err_status_replay_fail:
1397       GST_INFO_OBJECT (filter,
1398           "Dropping replayed packet, probably retransmission");
1399       goto err;
1400     case srtp_err_status_key_expired:{
1401       GstSrtpDecSsrcStream *stream;
1402 
1403       /* Check we have an existing stream to rekey */
1404       stream = find_stream_by_ssrc (filter, ssrc);
1405       if (stream == NULL) {
1406         GST_WARNING_OBJECT (filter, "Could not find matching stream, dropping");
1407         goto err;
1408       }
1409 
1410       GST_OBJECT_UNLOCK (filter);
1411       stream = request_key_with_signal (filter, ssrc, SIGNAL_HARD_LIMIT);
1412       GST_OBJECT_LOCK (filter);
1413 
1414       /* Check the key request created a new stream */
1415       if (stream == NULL) {
1416         GST_WARNING_OBJECT (filter, "Hard limit reached, no new key, dropping");
1417         goto err;
1418       }
1419 
1420       goto unprotect;
1421     }
1422     case srtp_err_status_auth_fail:
1423       GST_WARNING_OBJECT (filter, "Error authentication packet, dropping");
1424       goto err;
1425     case srtp_err_status_cipher_fail:
1426       GST_WARNING_OBJECT (filter, "Error while decrypting packet, dropping");
1427       goto err;
1428     default:
1429       GST_WARNING_OBJECT (pad,
1430           "Unable to unprotect buffer (unprotect failed code %d)", err);
1431       goto err;
1432   }
1433 
1434   gst_buffer_unmap (buf, &map);
1435   gst_buffer_set_size (buf, size);
1436   return TRUE;
1437 
1438 err:
1439   gst_buffer_unmap (buf, &map);
1440   return FALSE;
1441 }
1442 
1443 static GstFlowReturn
gst_srtp_dec_chain(GstPad * pad,GstObject * parent,GstBuffer * buf,gboolean is_rtcp)1444 gst_srtp_dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf,
1445     gboolean is_rtcp)
1446 {
1447   GstSrtpDec *filter = GST_SRTP_DEC (parent);
1448   GstPad *otherpad;
1449   GstSrtpDecSsrcStream *stream = NULL;
1450   GstFlowReturn ret = GST_FLOW_OK;
1451   guint32 ssrc = 0;
1452 
1453   GST_OBJECT_LOCK (filter);
1454 
1455   /* Check if this stream exists, if not create a new stream */
1456 
1457   if (!(stream = validate_buffer (filter, buf, &ssrc, &is_rtcp))) {
1458     GST_OBJECT_UNLOCK (filter);
1459     GST_WARNING_OBJECT (filter, "Invalid buffer, dropping");
1460     goto drop_buffer;
1461   }
1462 
1463   if (!STREAM_HAS_CRYPTO (stream)) {
1464     GST_OBJECT_UNLOCK (filter);
1465     goto push_out;
1466   }
1467 
1468   if (!gst_srtp_dec_decode_buffer (filter, pad, buf, is_rtcp, ssrc)) {
1469     GST_OBJECT_UNLOCK (filter);
1470     goto drop_buffer;
1471   }
1472 
1473   GST_OBJECT_UNLOCK (filter);
1474 
1475   /* If all is well, we may have reached soft limit */
1476   if (gst_srtp_get_soft_limit_reached ())
1477     request_key_with_signal (filter, ssrc, SIGNAL_SOFT_LIMIT);
1478 
1479 push_out:
1480   /* Push buffer to source pad */
1481   if (is_rtcp) {
1482     otherpad = filter->rtcp_srcpad;
1483     if (!filter->rtcp_has_segment)
1484       gst_srtp_dec_push_early_events (filter, filter->rtcp_srcpad,
1485           filter->rtp_srcpad, TRUE);
1486   } else {
1487     otherpad = filter->rtp_srcpad;
1488     if (!filter->rtp_has_segment)
1489       gst_srtp_dec_push_early_events (filter, filter->rtp_srcpad,
1490           filter->rtcp_srcpad, FALSE);
1491   }
1492   ret = gst_pad_push (otherpad, buf);
1493 
1494   return ret;
1495 
1496 drop_buffer:
1497   /* Drop buffer, except if gst_pad_push returned OK or an error */
1498 
1499   gst_buffer_unref (buf);
1500 
1501   return ret;
1502 }
1503 
1504 static GstFlowReturn
gst_srtp_dec_chain_rtp(GstPad * pad,GstObject * parent,GstBuffer * buf)1505 gst_srtp_dec_chain_rtp (GstPad * pad, GstObject * parent, GstBuffer * buf)
1506 {
1507   return gst_srtp_dec_chain (pad, parent, buf, FALSE);
1508 }
1509 
1510 static GstFlowReturn
gst_srtp_dec_chain_rtcp(GstPad * pad,GstObject * parent,GstBuffer * buf)1511 gst_srtp_dec_chain_rtcp (GstPad * pad, GstObject * parent, GstBuffer * buf)
1512 {
1513   return gst_srtp_dec_chain (pad, parent, buf, TRUE);
1514 }
1515 
1516 static GstStateChangeReturn
gst_srtp_dec_change_state(GstElement * element,GstStateChange transition)1517 gst_srtp_dec_change_state (GstElement * element, GstStateChange transition)
1518 {
1519   GstStateChangeReturn res;
1520   GstSrtpDec *filter;
1521 
1522   filter = GST_SRTP_DEC (element);
1523   GST_OBJECT_LOCK (filter);
1524 
1525   switch (transition) {
1526     case GST_STATE_CHANGE_READY_TO_PAUSED:
1527       filter->streams = g_hash_table_new_full (g_direct_hash, g_direct_equal,
1528           NULL, (GDestroyNotify) free_stream);
1529       filter->rtp_has_segment = FALSE;
1530       filter->rtcp_has_segment = FALSE;
1531       break;
1532     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1533       break;
1534     default:
1535       break;
1536   }
1537 
1538   GST_OBJECT_UNLOCK (filter);
1539 
1540   res = GST_ELEMENT_CLASS (gst_srtp_dec_parent_class)->change_state (element,
1541       transition);
1542 
1543   switch (transition) {
1544     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1545       break;
1546     case GST_STATE_CHANGE_PAUSED_TO_READY:
1547       gst_srtp_dec_clear_streams (filter);
1548       g_hash_table_unref (filter->streams);
1549       filter->streams = NULL;
1550       break;
1551     case GST_STATE_CHANGE_READY_TO_NULL:
1552       break;
1553     default:
1554       break;
1555   }
1556   return res;
1557 }
1558 
1559 
1560 /* entry point to initialize the plug-in
1561  * initialize the plug-in itself
1562  * register the element factories and other features
1563  */
1564 gboolean
gst_srtp_dec_plugin_init(GstPlugin * srtpdec)1565 gst_srtp_dec_plugin_init (GstPlugin * srtpdec)
1566 {
1567   GST_DEBUG_CATEGORY_INIT (gst_srtp_dec_debug, "srtpdec", 0, "SRTP dec");
1568 
1569   return gst_element_register (srtpdec, "srtpdec", GST_RANK_NONE,
1570       GST_TYPE_SRTP_DEC);
1571 }
1572