srtpdec: fix "srtp-key" check
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / ext / srtp / gstsrtpdec.c
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 "gstsrtpelements.h"
119 #include "gstsrtpdec.h"
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_WITH_CODE (GstSrtpDec, gst_srtp_dec, GST_TYPE_ELEMENT,
181     GST_DEBUG_CATEGORY_INIT (gst_srtp_dec_debug, "srtpdec", 0, "SRTP dec");
182     );
183 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (srtpdec, "srtpdec", GST_RANK_NONE,
184     GST_TYPE_SRTP_DEC, srtp_element_init (plugin));
185
186 static void gst_srtp_dec_set_property (GObject * object, guint prop_id,
187     const GValue * value, GParamSpec * pspec);
188 static void gst_srtp_dec_get_property (GObject * object, guint prop_id,
189     GValue * value, GParamSpec * pspec);
190
191 static void gst_srtp_dec_clear_streams (GstSrtpDec * filter);
192 static void gst_srtp_dec_remove_stream (GstSrtpDec * filter, guint ssrc);
193
194 static gboolean gst_srtp_dec_sink_event_rtp (GstPad * pad, GstObject * parent,
195     GstEvent * event);
196 static gboolean gst_srtp_dec_sink_event_rtcp (GstPad * pad, GstObject * parent,
197     GstEvent * event);
198
199 static gboolean gst_srtp_dec_sink_query_rtp (GstPad * pad, GstObject * parent,
200     GstQuery * query);
201 static gboolean gst_srtp_dec_sink_query_rtcp (GstPad * pad,
202     GstObject * parent, GstQuery * query);
203
204
205 static GstIterator *gst_srtp_dec_iterate_internal_links_rtp (GstPad * pad,
206     GstObject * parent);
207 static GstIterator *gst_srtp_dec_iterate_internal_links_rtcp (GstPad * pad,
208     GstObject * parent);
209
210 static GstFlowReturn gst_srtp_dec_chain_rtp (GstPad * pad,
211     GstObject * parent, GstBuffer * buf);
212 static GstFlowReturn gst_srtp_dec_chain_rtcp (GstPad * pad,
213     GstObject * parent, GstBuffer * buf);
214
215 static GstStateChangeReturn gst_srtp_dec_change_state (GstElement * element,
216     GstStateChange transition);
217
218 static GstSrtpDecSsrcStream *request_key_with_signal (GstSrtpDec * filter,
219     guint32 ssrc, gint signal);
220
221 struct _GstSrtpDecSsrcStream
222 {
223   guint32 ssrc;
224
225   guint32 roc;
226   GstBuffer *key;
227   GstSrtpCipherType rtp_cipher;
228   GstSrtpAuthType rtp_auth;
229   GstSrtpCipherType rtcp_cipher;
230   GstSrtpAuthType rtcp_auth;
231   GArray *keys;
232   guint recv_count;
233   guint recv_drop_count;
234 };
235
236 #ifdef HAVE_SRTP2
237 struct GstSrtpDecKey
238 {
239   GstBuffer *mki;
240   GstBuffer *key;
241 };
242 #endif
243
244 #define STREAM_HAS_CRYPTO(stream)                       \
245   (stream->rtp_cipher != GST_SRTP_CIPHER_NULL ||        \
246       stream->rtcp_cipher != GST_SRTP_CIPHER_NULL ||    \
247       stream->rtp_auth != GST_SRTP_AUTH_NULL ||         \
248       stream->rtcp_auth != GST_SRTP_AUTH_NULL)
249
250
251 /* initialize the srtpdec's class */
252 static void
253 gst_srtp_dec_class_init (GstSrtpDecClass * klass)
254 {
255   GObjectClass *gobject_class;
256   GstElementClass *gstelement_class;
257
258   gobject_class = (GObjectClass *) klass;
259   gstelement_class = (GstElementClass *) klass;
260
261   gobject_class->set_property = gst_srtp_dec_set_property;
262   gobject_class->get_property = gst_srtp_dec_get_property;
263
264   gst_element_class_add_static_pad_template (gstelement_class,
265       &rtp_src_template);
266   gst_element_class_add_static_pad_template (gstelement_class,
267       &rtp_sink_template);
268   gst_element_class_add_static_pad_template (gstelement_class,
269       &rtcp_src_template);
270   gst_element_class_add_static_pad_template (gstelement_class,
271       &rtcp_sink_template);
272
273   gst_element_class_set_static_metadata (gstelement_class, "SRTP decoder",
274       "Filter/Network/SRTP",
275       "A SRTP and SRTCP decoder",
276       "Gabriel Millaire <millaire.gabriel@collabora.com>");
277
278   /* Install callbacks */
279   gstelement_class->change_state =
280       GST_DEBUG_FUNCPTR (gst_srtp_dec_change_state);
281
282   klass->clear_streams = GST_DEBUG_FUNCPTR (gst_srtp_dec_clear_streams);
283   klass->remove_stream = GST_DEBUG_FUNCPTR (gst_srtp_dec_remove_stream);
284
285   /* Install properties */
286   g_object_class_install_property (gobject_class, PROP_REPLAY_WINDOW_SIZE,
287       g_param_spec_uint ("replay-window-size", "Replay window size",
288           "Size of the replay protection window",
289           64, 0x8000, DEFAULT_REPLAY_WINDOW_SIZE,
290           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
291   g_object_class_install_property (gobject_class, PROP_STATS,
292       g_param_spec_boxed ("stats", "Statistics", "Various statistics",
293           GST_TYPE_STRUCTURE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
294
295   /* Install signals */
296   /**
297    * GstSrtpDec::request-key:
298    * @gstsrtpdec: the element on which the signal is emitted
299    * @ssrc: The unique SSRC of the stream
300    *
301    * Signal emitted to get the parameters relevant to stream
302    * with @ssrc. User should provide the key and the RTP and
303    * RTCP encryption ciphers and authentication, and return
304    * them wrapped in a GstCaps.
305    */
306   gst_srtp_dec_signals[SIGNAL_REQUEST_KEY] =
307       g_signal_new ("request-key", G_TYPE_FROM_CLASS (klass),
308       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, GST_TYPE_CAPS, 1, G_TYPE_UINT);
309
310   /**
311    * GstSrtpDec::clear-keys:
312    * @gstsrtpdec: the element on which the signal is emitted
313    *
314    * Clear the internal list of streams
315    */
316   gst_srtp_dec_signals[SIGNAL_CLEAR_KEYS] =
317       g_signal_new ("clear-keys", G_TYPE_FROM_CLASS (klass),
318       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
319       G_STRUCT_OFFSET (GstSrtpDecClass, clear_streams), NULL, NULL, NULL,
320       G_TYPE_NONE, 0, G_TYPE_NONE);
321
322   /**
323    * GstSrtpDec::soft-limit:
324    * @gstsrtpdec: the element on which the signal is emitted
325    * @ssrc: The unique SSRC of the stream
326    *
327    * Signal emitted when the stream with @ssrc has reached the
328    * soft limit of utilisation of it's master encryption key.
329    * User should provide a new key and new RTP and RTCP encryption
330    * ciphers and authentication, and return them wrapped in a
331    * GstCaps.
332    */
333   gst_srtp_dec_signals[SIGNAL_SOFT_LIMIT] =
334       g_signal_new ("soft-limit", G_TYPE_FROM_CLASS (klass),
335       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, GST_TYPE_CAPS, 1, G_TYPE_UINT);
336
337   /**
338    * GstSrtpDec::hard-limit:
339    * @gstsrtpdec: the element on which the signal is emitted
340    * @ssrc: The unique SSRC of the stream
341    *
342    * Signal emitted when the stream with @ssrc has reached the
343    * hard limit of utilisation of it's master encryption key.
344    * User should provide a new key and new RTP and RTCP encryption
345    * ciphers and authentication, and return them wrapped in a
346    * GstCaps. If user could not provide those parameters or signal
347    * is not answered, the buffers of this stream will be dropped.
348    */
349   gst_srtp_dec_signals[SIGNAL_HARD_LIMIT] =
350       g_signal_new ("hard-limit", G_TYPE_FROM_CLASS (klass),
351       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, GST_TYPE_CAPS, 1, G_TYPE_UINT);
352
353   /**
354    * GstSrtpDec::remove-key:
355    * @gstsrtpdec: the element on which the signal is emitted
356    * @ssrc: The SSRC for which to remove the key.
357    *
358    * Removes keys for a specific SSRC
359    */
360   gst_srtp_dec_signals[SIGNAL_REMOVE_KEY] =
361       g_signal_new ("remove-key", G_TYPE_FROM_CLASS (klass),
362       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
363       G_STRUCT_OFFSET (GstSrtpDecClass, remove_stream), NULL, NULL, NULL,
364       G_TYPE_NONE, 1, G_TYPE_UINT);
365
366 }
367
368 /* initialize the new element
369  * instantiate pads and add them to element
370  * set pad callback functions
371  * initialize instance structure
372  */
373 static void
374 gst_srtp_dec_init (GstSrtpDec * filter)
375 {
376   filter->replay_window_size = DEFAULT_REPLAY_WINDOW_SIZE;
377
378   filter->rtp_sinkpad =
379       gst_pad_new_from_static_template (&rtp_sink_template, "rtp_sink");
380   gst_pad_set_event_function (filter->rtp_sinkpad,
381       GST_DEBUG_FUNCPTR (gst_srtp_dec_sink_event_rtp));
382   gst_pad_set_query_function (filter->rtp_sinkpad,
383       GST_DEBUG_FUNCPTR (gst_srtp_dec_sink_query_rtp));
384   gst_pad_set_iterate_internal_links_function (filter->rtp_sinkpad,
385       GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtp));
386   gst_pad_set_chain_function (filter->rtp_sinkpad,
387       GST_DEBUG_FUNCPTR (gst_srtp_dec_chain_rtp));
388
389   filter->rtp_srcpad =
390       gst_pad_new_from_static_template (&rtp_src_template, "rtp_src");
391   gst_pad_set_iterate_internal_links_function (filter->rtp_srcpad,
392       GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtp));
393
394   gst_pad_set_element_private (filter->rtp_sinkpad, filter->rtp_srcpad);
395   gst_pad_set_element_private (filter->rtp_srcpad, filter->rtp_sinkpad);
396
397   gst_element_add_pad (GST_ELEMENT (filter), filter->rtp_sinkpad);
398   gst_element_add_pad (GST_ELEMENT (filter), filter->rtp_srcpad);
399
400
401   filter->rtcp_sinkpad =
402       gst_pad_new_from_static_template (&rtcp_sink_template, "rtcp_sink");
403   gst_pad_set_event_function (filter->rtcp_sinkpad,
404       GST_DEBUG_FUNCPTR (gst_srtp_dec_sink_event_rtcp));
405   gst_pad_set_query_function (filter->rtcp_sinkpad,
406       GST_DEBUG_FUNCPTR (gst_srtp_dec_sink_query_rtcp));
407   gst_pad_set_iterate_internal_links_function (filter->rtcp_sinkpad,
408       GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtcp));
409   gst_pad_set_chain_function (filter->rtcp_sinkpad,
410       GST_DEBUG_FUNCPTR (gst_srtp_dec_chain_rtcp));
411
412   filter->rtcp_srcpad =
413       gst_pad_new_from_static_template (&rtcp_src_template, "rtcp_src");
414   gst_pad_set_iterate_internal_links_function (filter->rtcp_srcpad,
415       GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtcp));
416
417   gst_pad_set_element_private (filter->rtcp_sinkpad, filter->rtcp_srcpad);
418   gst_pad_set_element_private (filter->rtcp_srcpad, filter->rtcp_sinkpad);
419
420   gst_element_add_pad (GST_ELEMENT (filter), filter->rtcp_sinkpad);
421   gst_element_add_pad (GST_ELEMENT (filter), filter->rtcp_srcpad);
422
423   filter->first_session = TRUE;
424 }
425
426 static GstStructure *
427 gst_srtp_dec_create_stats (GstSrtpDec * filter)
428 {
429   GstStructure *s;
430   GValue va = G_VALUE_INIT;
431   GValue v = G_VALUE_INIT;
432
433   s = gst_structure_new_empty ("application/x-srtp-decoder-stats");
434
435   g_value_init (&va, GST_TYPE_ARRAY);
436   g_value_init (&v, GST_TYPE_STRUCTURE);
437
438   if (filter->session) {
439     GHashTableIter iter;
440     gpointer key, value;
441
442     g_hash_table_iter_init (&iter, filter->streams);
443     while (g_hash_table_iter_next (&iter, &key, &value)) {
444       GstSrtpDecSsrcStream *stream = value;
445       GstStructure *ss;
446       guint32 ssrc = GPOINTER_TO_UINT (key);
447       srtp_err_status_t status;
448       guint32 roc;
449
450       status = srtp_get_stream_roc (filter->session, ssrc, &roc);
451       if (status != srtp_err_status_ok) {
452         continue;
453       }
454
455       ss = gst_structure_new ("application/x-srtp-stream",
456           "ssrc", G_TYPE_UINT, ssrc, "roc", G_TYPE_UINT, roc, "recv-count",
457           G_TYPE_UINT, stream->recv_count, "recv-drop-count", G_TYPE_UINT,
458           stream->recv_drop_count, NULL);
459
460       g_value_take_boxed (&v, ss);
461       gst_value_array_append_value (&va, &v);
462     }
463   }
464
465   gst_structure_take_value (s, "streams", &va);
466   gst_structure_set (s, "recv-count", G_TYPE_UINT, filter->recv_count, NULL);
467   gst_structure_set (s, "recv-drop-count", G_TYPE_UINT,
468       filter->recv_drop_count, NULL);
469   GST_LOG_OBJECT (filter, "stats: recv-count %u recv-drop-count %u",
470       filter->recv_count, filter->recv_drop_count);
471   g_value_unset (&v);
472
473   return s;
474 }
475
476 static void
477 gst_srtp_dec_set_property (GObject * object, guint prop_id,
478     const GValue * value, GParamSpec * pspec)
479 {
480   GstSrtpDec *filter = GST_SRTP_DEC (object);
481
482   GST_OBJECT_LOCK (filter);
483
484   switch (prop_id) {
485     case PROP_REPLAY_WINDOW_SIZE:
486       filter->replay_window_size = g_value_get_uint (value);
487       break;
488     default:
489       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
490       break;
491   }
492
493   GST_OBJECT_UNLOCK (filter);
494 }
495
496 static void
497 gst_srtp_dec_get_property (GObject * object, guint prop_id,
498     GValue * value, GParamSpec * pspec)
499 {
500   GstSrtpDec *filter = GST_SRTP_DEC (object);
501
502   GST_OBJECT_LOCK (filter);
503
504   switch (prop_id) {
505     case PROP_REPLAY_WINDOW_SIZE:
506       g_value_set_uint (value, filter->replay_window_size);
507       break;
508     case PROP_STATS:
509       g_value_take_boxed (value, gst_srtp_dec_create_stats (filter));
510       break;
511     default:
512       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
513       break;
514   }
515
516   GST_OBJECT_UNLOCK (filter);
517 }
518
519 static void
520 gst_srtp_dec_remove_stream (GstSrtpDec * filter, guint ssrc)
521 {
522   GstSrtpDecSsrcStream *stream = NULL;
523
524   if (filter->streams == NULL)
525     return;
526
527   stream = g_hash_table_lookup (filter->streams, GUINT_TO_POINTER (ssrc));
528
529   if (stream) {
530     srtp_remove_stream (filter->session, ssrc);
531     g_hash_table_remove (filter->streams, GUINT_TO_POINTER (ssrc));
532   }
533 }
534
535 static GstSrtpDecSsrcStream *
536 find_stream_by_ssrc (GstSrtpDec * filter, guint32 ssrc)
537 {
538   return g_hash_table_lookup (filter->streams, GUINT_TO_POINTER (ssrc));
539 }
540
541 #ifdef HAVE_SRTP2
542 static void
543 clear_key (gpointer data)
544 {
545   struct GstSrtpDecKey *key = data;
546
547   gst_clear_buffer (&key->mki);
548   gst_clear_buffer (&key->key);
549 }
550 #endif
551
552
553 /* get info from buffer caps
554  */
555 static GstSrtpDecSsrcStream *
556 get_stream_from_caps (GstSrtpDec * filter, GstCaps * caps, guint32 ssrc)
557 {
558   GstSrtpDecSsrcStream *stream;
559   GstStructure *s;
560   GstBuffer *buf;
561   const gchar *rtp_cipher, *rtp_auth, *rtcp_cipher, *rtcp_auth;
562
563   /* Create new stream structure and set default values */
564   stream = g_slice_new0 (GstSrtpDecSsrcStream);
565   stream->ssrc = ssrc;
566   stream->key = NULL;
567
568   /* Get info from caps */
569   s = gst_caps_get_structure (caps, 0);
570   if (!s)
571     goto error;
572
573   rtp_cipher = gst_structure_get_string (s, "srtp-cipher");
574   rtp_auth = gst_structure_get_string (s, "srtp-auth");
575   rtcp_cipher = gst_structure_get_string (s, "srtcp-cipher");
576   rtcp_auth = gst_structure_get_string (s, "srtcp-auth");
577   if (!rtp_cipher || !rtp_auth || !rtcp_cipher || !rtcp_auth)
578     goto error;
579
580   gst_structure_get_uint (s, "roc", &stream->roc);
581
582   stream->rtp_cipher = enum_value_from_nick (GST_TYPE_SRTP_CIPHER_TYPE,
583       rtp_cipher);
584   stream->rtp_auth = enum_value_from_nick (GST_TYPE_SRTP_AUTH_TYPE, rtp_auth);
585   stream->rtcp_cipher = enum_value_from_nick (GST_TYPE_SRTP_CIPHER_TYPE,
586       rtcp_cipher);
587   stream->rtcp_auth = enum_value_from_nick (GST_TYPE_SRTP_AUTH_TYPE, rtcp_auth);
588
589   if ((gint) stream->rtp_cipher == -1 || (gint) stream->rtp_auth == -1 ||
590       (gint) stream->rtcp_cipher == -1 || (gint) stream->rtcp_auth == -1) {
591     GST_WARNING_OBJECT (filter, "Invalid caps for stream,"
592         " unknown cipher or auth type");
593     goto error;
594   }
595
596   /* RFC 3711 says in "3. SRTP Framework" that SRTCP message authentication
597    * is MANDATORY. In case of GCM let the pipeline handle any errors.
598    */
599   if (stream->rtcp_cipher != GST_SRTP_CIPHER_AES_128_GCM
600       && stream->rtcp_cipher != GST_SRTP_CIPHER_AES_256_GCM
601       && stream->rtcp_cipher != GST_SRTP_CIPHER_NULL
602       && stream->rtcp_auth == GST_SRTP_AUTH_NULL) {
603     GST_WARNING_OBJECT (filter,
604         "Cannot have SRTP NULL authentication with a not-NULL encryption"
605         " cipher.");
606     goto error;
607   }
608
609   if (gst_structure_get (s, "srtp-key", GST_TYPE_BUFFER, &buf, NULL) && buf) {
610 #ifdef HAVE_SRTP2
611     GstBuffer *mki = NULL;
612     guint i;
613     gsize mki_size = 0;
614 #endif
615
616     GST_DEBUG_OBJECT (filter, "Got key [%p] for SSRC %u", buf, ssrc);
617
618 #ifdef HAVE_SRTP2
619     if (gst_structure_get (s, "mki", GST_TYPE_BUFFER, &mki, NULL) && mki) {
620       struct GstSrtpDecKey key = {.mki = mki,.key = buf };
621
622       mki_size = gst_buffer_get_size (mki);
623       if (mki_size > SRTP_MAX_MKI_LEN) {
624         GST_WARNING_OBJECT (filter, "MKI is longer than allowed (%"
625             G_GSIZE_FORMAT " > %d).", mki_size, SRTP_MAX_MKI_LEN);
626         gst_buffer_unref (mki);
627         gst_buffer_unref (buf);
628         goto error;
629       }
630
631       stream->keys =
632           g_array_sized_new (FALSE, TRUE, sizeof (struct GstSrtpDecKey), 2);
633       g_array_set_clear_func (stream->keys, clear_key);
634
635       g_array_append_val (stream->keys, key);
636
637       /* Append more MKIs */
638       for (i = 1; i < SRTP_MAX_NUM_MASTER_KEYS; i++) {
639         char mki_id[16];
640         char key_id[16];
641         g_snprintf (mki_id, 16, "mki%d", i + 1);
642         g_snprintf (key_id, 16, "srtp-key%d", i + 1);
643
644         if (gst_structure_get (s, mki_id, GST_TYPE_BUFFER, &mki,
645                 key_id, GST_TYPE_BUFFER, &buf, NULL)) {
646           if (gst_buffer_get_size (mki) != mki_size) {
647             GST_WARNING_OBJECT (filter,
648                 "MKIs need to all have the same size (first was %"
649                 G_GSIZE_FORMAT ", current is %" G_GSIZE_FORMAT ").",
650                 mki_size, gst_buffer_get_size (mki));
651             gst_buffer_unref (mki);
652             gst_buffer_unref (buf);
653             goto error;
654           }
655           key.mki = mki;
656           key.key = buf;
657           g_array_append_val (stream->keys, key);
658         } else {
659           break;
660         }
661       }
662     } else
663 #endif
664     {
665       stream->key = buf;
666     }
667   } else if (STREAM_HAS_CRYPTO (stream)) {
668     goto error;
669   }
670
671   return stream;
672
673 error:
674   g_slice_free (GstSrtpDecSsrcStream, stream);
675   return NULL;
676 }
677
678 /* Get SRTP params by signal
679  */
680 static GstCaps *
681 signal_get_srtp_params (GstSrtpDec * filter, guint32 ssrc, gint signal)
682 {
683   GstCaps *caps = NULL;
684
685   g_signal_emit (filter, gst_srtp_dec_signals[signal], 0, ssrc, &caps);
686
687   if (caps != NULL)
688     GST_DEBUG_OBJECT (filter, "Caps received");
689
690   return caps;
691 }
692
693 /* Create a stream in the session
694  */
695 static srtp_err_status_t
696 init_session_stream (GstSrtpDec * filter, guint32 ssrc,
697     GstSrtpDecSsrcStream * stream)
698 {
699   srtp_err_status_t ret;
700   srtp_policy_t policy;
701   GstMapInfo map;
702   guchar tmp[1];
703 #ifdef HAVE_SRTP2
704   GstMapInfo *key_maps = NULL;
705   GstMapInfo *mki_maps = NULL;
706 #endif
707
708   memset (&policy, 0, sizeof (srtp_policy_t));
709
710   if (!stream)
711     return srtp_err_status_bad_param;
712
713   GST_INFO_OBJECT (filter, "Setting RTP policy...");
714   set_crypto_policy_cipher_auth (stream->rtp_cipher, stream->rtp_auth,
715       &policy.rtp);
716   GST_INFO_OBJECT (filter, "Setting RTCP policy...");
717   set_crypto_policy_cipher_auth (stream->rtcp_cipher, stream->rtcp_auth,
718       &policy.rtcp);
719
720 #ifdef HAVE_SRTP2
721   if (stream->keys) {
722     guint i;
723     srtp_master_key_t *keys;
724
725     keys = g_alloca (sizeof (srtp_master_key_t) * stream->keys->len);
726     policy.keys = g_alloca (sizeof (gpointer) * stream->keys->len);
727     key_maps = g_alloca (sizeof (GstMapInfo) * stream->keys->len);
728     mki_maps = g_alloca (sizeof (GstMapInfo) * stream->keys->len);
729
730     for (i = 0; i < stream->keys->len; i++) {
731       struct GstSrtpDecKey *key =
732           &g_array_index (stream->keys, struct GstSrtpDecKey, i);
733       policy.keys[i] = &keys[i];
734
735       gst_buffer_map (key->mki, &mki_maps[i], GST_MAP_READ);
736       gst_buffer_map (key->key, &key_maps[i], GST_MAP_READ);
737
738       policy.keys[i]->key = (guchar *) key_maps[i].data;
739       policy.keys[i]->mki_id = (guchar *) mki_maps[i].data;
740       policy.keys[i]->mki_size = mki_maps[i].size;
741     }
742     policy.num_master_keys = stream->keys->len;
743   } else
744 #endif
745   if (stream->key) {
746     gst_buffer_map (stream->key, &map, GST_MAP_READ);
747     policy.key = (guchar *) map.data;
748   } else {
749     policy.key = tmp;
750   }
751
752   policy.ssrc.value = ssrc;
753   policy.ssrc.type = ssrc_specific;
754   policy.window_size = filter->replay_window_size;
755   policy.next = NULL;
756
757   /* If it is the first stream, create the session
758    * If not, add the stream policy to the session
759    */
760   if (filter->first_session)
761     ret = srtp_create (&filter->session, &policy);
762   else
763     ret = srtp_add_stream (filter->session, &policy);
764
765   if (stream->key)
766     gst_buffer_unmap (stream->key, &map);
767
768 #ifdef HAVE_SRTP2
769   if (key_maps) {
770     guint i;
771
772     for (i = 0; i < stream->keys->len; i++) {
773       struct GstSrtpDecKey *key = &g_array_index (stream->keys,
774           struct GstSrtpDecKey, i);
775       gst_buffer_unmap (key->mki, &mki_maps[i]);
776       gst_buffer_unmap (key->key, &key_maps[i]);
777     }
778
779   }
780 #endif
781
782   if (ret == srtp_err_status_ok) {
783     srtp_err_status_t status;
784
785     status = srtp_set_stream_roc (filter->session, ssrc, stream->roc);
786 #ifdef HAVE_SRTP2
787     (void) status;              /* Ignore unused variable */
788 #else
789     if (status == srtp_err_status_ok) {
790       /* Here, we just set the ROC, but we also need to set the initial
791        * RTP sequence number later, otherwise libsrtp will not be able
792        * to get the right packet index. */
793       g_hash_table_add (filter->streams_roc_changed, GUINT_TO_POINTER (ssrc));
794     }
795 #endif
796
797     filter->first_session = FALSE;
798     g_hash_table_insert (filter->streams, GUINT_TO_POINTER (stream->ssrc),
799         stream);
800   }
801
802   return ret;
803 }
804
805 /* Return a stream structure for a given buffer
806  */
807 static GstSrtpDecSsrcStream *
808 validate_buffer (GstSrtpDec * filter, GstBuffer * buf, guint32 * ssrc,
809     gboolean * is_rtcp)
810 {
811   GstSrtpDecSsrcStream *stream = NULL;
812   GstRTPBuffer rtpbuf = GST_RTP_BUFFER_INIT;
813
814   if (gst_rtp_buffer_map (buf,
815           GST_MAP_READ | GST_RTP_BUFFER_MAP_FLAG_SKIP_PADDING, &rtpbuf)) {
816     if (gst_rtp_buffer_get_payload_type (&rtpbuf) < 64
817         || gst_rtp_buffer_get_payload_type (&rtpbuf) > 80) {
818       *ssrc = gst_rtp_buffer_get_ssrc (&rtpbuf);
819
820       gst_rtp_buffer_unmap (&rtpbuf);
821       *is_rtcp = FALSE;
822       goto have_ssrc;
823     }
824     gst_rtp_buffer_unmap (&rtpbuf);
825   }
826
827   if (rtcp_buffer_get_ssrc (buf, ssrc)) {
828     *is_rtcp = TRUE;
829   } else {
830     GST_WARNING_OBJECT (filter, "No SSRC found in buffer");
831     return NULL;
832   }
833
834 have_ssrc:
835
836   stream = find_stream_by_ssrc (filter, *ssrc);
837
838   if (stream)
839     return stream;
840
841   return request_key_with_signal (filter, *ssrc, SIGNAL_REQUEST_KEY);
842 }
843
844 static void
845 free_stream (GstSrtpDecSsrcStream * stream)
846 {
847   if (stream->key)
848     gst_buffer_unref (stream->key);
849   if (stream->keys)
850     g_array_free (stream->keys, TRUE);
851   g_slice_free (GstSrtpDecSsrcStream, stream);
852 }
853
854 static gboolean
855 buffers_are_equal (GstBuffer * a, GstBuffer * b)
856 {
857   GstMapInfo info;
858
859   if (a == b)
860     return TRUE;
861
862   if (a == NULL || b == NULL)
863     return FALSE;
864
865   if (gst_buffer_get_size (a) != gst_buffer_get_size (b))
866     return FALSE;
867
868   if (gst_buffer_map (a, &info, GST_MAP_READ)) {
869     gboolean equal;
870
871     equal = (gst_buffer_memcmp (b, 0, info.data, info.size) == 0);
872     gst_buffer_unmap (a, &info);
873
874     return equal;
875   } else {
876     return FALSE;
877   }
878 }
879
880 static gboolean
881 keys_are_equal (GArray * a, GArray * b)
882 {
883 #ifdef HAVE_SRTP2
884   guint i;
885
886   if (a == b)
887     return TRUE;
888
889   if (a == NULL || b == NULL)
890     return FALSE;
891
892   if (a->len != b->len)
893     return FALSE;
894
895   for (i = 0; i < a->len; i++) {
896     struct GstSrtpDecKey *key_a = &g_array_index (a,
897         struct GstSrtpDecKey, i);
898     struct GstSrtpDecKey *key_b = &g_array_index (b,
899         struct GstSrtpDecKey, i);
900
901     if (!buffers_are_equal (key_a->mki, key_b->mki))
902       return FALSE;
903
904     if (!buffers_are_equal (key_a->key, key_b->key))
905       return FALSE;
906   }
907
908   return TRUE;
909 #else
910   return FALSE;
911 #endif
912 }
913
914 /* Create new stream from params in caps
915  */
916 static GstSrtpDecSsrcStream *
917 update_session_stream_from_caps (GstSrtpDec * filter, guint32 ssrc,
918     GstCaps * caps)
919 {
920   GstSrtpDecSsrcStream *stream = NULL;
921   GstSrtpDecSsrcStream *old_stream = NULL;
922   srtp_err_status_t err;
923
924   g_return_val_if_fail (GST_IS_SRTP_DEC (filter), NULL);
925   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
926
927   stream = get_stream_from_caps (filter, caps, ssrc);
928
929   old_stream = find_stream_by_ssrc (filter, ssrc);
930   if (stream && old_stream &&
931       stream->rtp_cipher == old_stream->rtp_cipher &&
932       stream->rtcp_cipher == old_stream->rtcp_cipher &&
933       stream->rtp_auth == old_stream->rtp_auth &&
934       stream->rtcp_auth == old_stream->rtcp_auth &&
935       ((stream->keys && keys_are_equal (stream->keys, old_stream->keys)) ||
936           buffers_are_equal (stream->key, old_stream->key))) {
937     free_stream (stream);
938     return old_stream;
939   }
940
941   /* Remove existing stream, if any */
942   gst_srtp_dec_remove_stream (filter, ssrc);
943
944   if (stream) {
945     /* Create new session stream */
946     err = init_session_stream (filter, ssrc, stream);
947
948     if (err != srtp_err_status_ok) {
949       GST_WARNING_OBJECT (filter, "Failed to create the stream (err: %d)", err);
950       if (stream->key)
951         gst_buffer_unref (stream->key);
952       g_slice_free (GstSrtpDecSsrcStream, stream);
953       stream = NULL;
954     }
955   }
956
957   return stream;
958 }
959
960 static gboolean
961 remove_yes (gpointer key, gpointer value, gpointer user_data)
962 {
963   return TRUE;
964 }
965
966 /* Clear the policy list
967  */
968 static void
969 gst_srtp_dec_clear_streams (GstSrtpDec * filter)
970 {
971   guint nb = 0;
972
973   GST_OBJECT_LOCK (filter);
974
975   if (!filter->first_session) {
976     srtp_dealloc (filter->session);
977     filter->session = NULL;
978   }
979
980   if (filter->streams)
981     nb = g_hash_table_foreach_remove (filter->streams, remove_yes, NULL);
982
983   filter->first_session = TRUE;
984
985   GST_OBJECT_UNLOCK (filter);
986
987   GST_DEBUG_OBJECT (filter, "Cleared %d streams", nb);
988 }
989
990 /* Send a signal
991  */
992 static GstSrtpDecSsrcStream *
993 request_key_with_signal (GstSrtpDec * filter, guint32 ssrc, gint signal)
994 {
995   GstCaps *caps;
996   GstSrtpDecSsrcStream *stream = NULL;
997
998   caps = signal_get_srtp_params (filter, ssrc, signal);
999
1000   if (caps) {
1001     stream = update_session_stream_from_caps (filter, ssrc, caps);
1002     if (stream)
1003       GST_DEBUG_OBJECT (filter, "New stream set with SSRC %u", ssrc);
1004     else
1005       GST_WARNING_OBJECT (filter, "Could not set stream with SSRC %u", ssrc);
1006     gst_caps_unref (caps);
1007   } else {
1008     GST_WARNING_OBJECT (filter, "Could not get caps for stream with SSRC %u",
1009         ssrc);
1010   }
1011
1012   return stream;
1013 }
1014
1015 static gboolean
1016 gst_srtp_dec_sink_setcaps (GstPad * pad, GstObject * parent,
1017     GstCaps * caps, gboolean is_rtcp)
1018 {
1019   GstSrtpDec *filter = GST_SRTP_DEC (parent);
1020   GstPad *otherpad;
1021   GstStructure *ps;
1022   gboolean ret = FALSE;
1023
1024   g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
1025
1026   ps = gst_caps_get_structure (caps, 0);
1027
1028   if (gst_structure_has_field_typed (ps, "ssrc", G_TYPE_UINT) &&
1029       gst_structure_has_field_typed (ps, "srtp-cipher", G_TYPE_STRING) &&
1030       gst_structure_has_field_typed (ps, "srtp-auth", G_TYPE_STRING) &&
1031       gst_structure_has_field_typed (ps, "srtcp-cipher", G_TYPE_STRING) &&
1032       gst_structure_has_field_typed (ps, "srtcp-auth", G_TYPE_STRING)) {
1033     guint ssrc;
1034
1035     gst_structure_get_uint (ps, "ssrc", &ssrc);
1036
1037     if (!update_session_stream_from_caps (filter, ssrc, caps)) {
1038       GST_WARNING_OBJECT (pad, "Could not create session from pad caps: %"
1039           GST_PTR_FORMAT, caps);
1040       return FALSE;
1041     }
1042   }
1043
1044   caps = gst_caps_copy (caps);
1045   ps = gst_caps_get_structure (caps, 0);
1046   gst_structure_remove_fields (ps, "srtp-key", "srtp-cipher", "srtp-auth",
1047       "srtcp-cipher", "srtcp-auth", "mki", NULL);
1048
1049   if (is_rtcp)
1050     gst_structure_set_name (ps, "application/x-rtcp");
1051   else
1052     gst_structure_set_name (ps, "application/x-rtp");
1053
1054   otherpad = gst_pad_get_element_private (pad);
1055
1056   ret = gst_pad_set_caps (otherpad, caps);
1057
1058   gst_caps_unref (caps);
1059
1060   return ret;
1061 }
1062
1063 static gboolean
1064 gst_srtp_dec_sink_event_rtp (GstPad * pad, GstObject * parent, GstEvent * event)
1065 {
1066   gboolean ret;
1067   GstCaps *caps;
1068   GstSrtpDec *filter = GST_SRTP_DEC (parent);
1069
1070   switch (GST_EVENT_TYPE (event)) {
1071     case GST_EVENT_CAPS:
1072       gst_event_parse_caps (event, &caps);
1073       ret = gst_srtp_dec_sink_setcaps (pad, parent, caps, FALSE);
1074       gst_event_unref (event);
1075       return ret;
1076     case GST_EVENT_SEGMENT:
1077       /* Make sure to send a caps event downstream before the segment event,
1078        * even if upstream didn't */
1079       if (!gst_pad_has_current_caps (filter->rtp_srcpad)) {
1080         GstCaps *caps = gst_caps_new_empty_simple ("application/x-rtp");
1081
1082         gst_pad_set_caps (filter->rtp_srcpad, caps);
1083         gst_caps_unref (caps);
1084       }
1085       filter->rtp_has_segment = TRUE;
1086       break;
1087     case GST_EVENT_FLUSH_STOP:
1088       filter->rtp_has_segment = FALSE;
1089       break;
1090     default:
1091       break;
1092   }
1093
1094   return gst_pad_event_default (pad, parent, event);
1095 }
1096
1097 static gboolean
1098 gst_srtp_dec_sink_event_rtcp (GstPad * pad, GstObject * parent,
1099     GstEvent * event)
1100 {
1101   gboolean ret;
1102   GstCaps *caps;
1103   GstSrtpDec *filter = GST_SRTP_DEC (parent);
1104
1105   switch (GST_EVENT_TYPE (event)) {
1106     case GST_EVENT_CAPS:
1107       gst_event_parse_caps (event, &caps);
1108       ret = gst_srtp_dec_sink_setcaps (pad, parent, caps, TRUE);
1109       gst_event_unref (event);
1110       return ret;
1111     case GST_EVENT_SEGMENT:
1112       /* Make sure to send a caps event downstream before the segment event,
1113        * even if upstream didn't */
1114       if (!gst_pad_has_current_caps (filter->rtcp_srcpad)) {
1115         GstCaps *caps = gst_caps_new_empty_simple ("application/x-rtcp");
1116
1117         gst_pad_set_caps (filter->rtcp_srcpad, caps);
1118         gst_caps_unref (caps);
1119       }
1120       filter->rtcp_has_segment = TRUE;
1121       break;
1122     case GST_EVENT_FLUSH_STOP:
1123       filter->rtcp_has_segment = FALSE;
1124       break;
1125     default:
1126       break;
1127   }
1128
1129   return gst_pad_event_default (pad, parent, event);
1130 }
1131
1132 static gboolean
1133 gst_srtp_dec_sink_query (GstPad * pad, GstObject * parent, GstQuery * query,
1134     gboolean is_rtcp)
1135 {
1136   switch (GST_QUERY_TYPE (query)) {
1137     case GST_QUERY_CAPS:
1138     {
1139       GstCaps *filter = NULL;
1140       GstCaps *other_filter = NULL;
1141       GstCaps *template_caps;
1142       GstPad *otherpad;
1143       GstCaps *other_caps;
1144       GstCaps *ret;
1145       int i;
1146
1147       gst_query_parse_caps (query, &filter);
1148
1149       otherpad = (GstPad *) gst_pad_get_element_private (pad);
1150
1151       if (filter) {
1152         other_filter = gst_caps_copy (filter);
1153
1154         for (i = 0; i < gst_caps_get_size (other_filter); i++) {
1155           GstStructure *ps = gst_caps_get_structure (other_filter, i);
1156           if (is_rtcp)
1157             gst_structure_set_name (ps, "application/x-rtcp");
1158           else
1159             gst_structure_set_name (ps, "application/x-rtp");
1160           gst_structure_remove_fields (ps, "srtp-key", "srtp-cipher",
1161               "srtp-auth", "srtcp-cipher", "srtcp-auth", "mki", NULL);
1162         }
1163       }
1164
1165
1166       other_caps = gst_pad_peer_query_caps (otherpad, other_filter);
1167       if (other_filter)
1168         gst_caps_unref (other_filter);
1169       if (!other_caps) {
1170         goto return_template;
1171       }
1172
1173       template_caps = gst_pad_get_pad_template_caps (otherpad);
1174       ret = gst_caps_intersect_full (other_caps, template_caps,
1175           GST_CAPS_INTERSECT_FIRST);
1176       gst_caps_unref (other_caps);
1177       gst_caps_unref (template_caps);
1178
1179       ret = gst_caps_make_writable (ret);
1180
1181       for (i = 0; i < gst_caps_get_size (ret); i++) {
1182         GstStructure *ps = gst_caps_get_structure (ret, i);
1183         if (is_rtcp)
1184           gst_structure_set_name (ps, "application/x-srtcp");
1185         else
1186           gst_structure_set_name (ps, "application/x-srtp");
1187       }
1188
1189       if (filter) {
1190         GstCaps *tmp;
1191
1192         tmp = gst_caps_intersect (ret, filter);
1193         gst_caps_unref (ret);
1194         ret = tmp;
1195       }
1196
1197       gst_query_set_caps_result (query, ret);
1198       gst_caps_unref (ret);
1199       return TRUE;
1200
1201     return_template:
1202
1203       ret = gst_pad_get_pad_template_caps (pad);
1204       gst_query_set_caps_result (query, ret);
1205       gst_caps_unref (ret);
1206       return TRUE;
1207     }
1208     default:
1209       return gst_pad_query_default (pad, parent, query);
1210   }
1211 }
1212
1213 static gboolean
1214 gst_srtp_dec_sink_query_rtp (GstPad * pad, GstObject * parent, GstQuery * query)
1215 {
1216   return gst_srtp_dec_sink_query (pad, parent, query, FALSE);
1217 }
1218
1219 static gboolean
1220 gst_srtp_dec_sink_query_rtcp (GstPad * pad, GstObject * parent,
1221     GstQuery * query)
1222 {
1223   return gst_srtp_dec_sink_query (pad, parent, query, TRUE);
1224 }
1225
1226 static GstIterator *
1227 gst_srtp_dec_iterate_internal_links (GstPad * pad, GstObject * parent,
1228     gboolean is_rtcp)
1229 {
1230   GstSrtpDec *filter = GST_SRTP_DEC (parent);
1231   GstPad *otherpad = NULL;
1232   GstIterator *it = NULL;
1233
1234   otherpad = (GstPad *) gst_pad_get_element_private (pad);
1235
1236   if (otherpad) {
1237     GValue val = { 0 };
1238
1239     g_value_init (&val, GST_TYPE_PAD);
1240     g_value_set_object (&val, otherpad);
1241     it = gst_iterator_new_single (GST_TYPE_PAD, &val);
1242     g_value_unset (&val);
1243   } else {
1244     GST_ELEMENT_ERROR (GST_ELEMENT_CAST (filter), CORE, PAD, (NULL),
1245         ("Unable to get linked pad"));
1246   }
1247
1248   return it;
1249 }
1250
1251 static GstIterator *
1252 gst_srtp_dec_iterate_internal_links_rtp (GstPad * pad, GstObject * parent)
1253 {
1254   return gst_srtp_dec_iterate_internal_links (pad, parent, FALSE);
1255 }
1256
1257 static GstIterator *
1258 gst_srtp_dec_iterate_internal_links_rtcp (GstPad * pad, GstObject * parent)
1259 {
1260   return gst_srtp_dec_iterate_internal_links (pad, parent, TRUE);
1261 }
1262
1263 static void
1264 gst_srtp_dec_push_early_events (GstSrtpDec * filter, GstPad * pad,
1265     GstPad * otherpad, gboolean is_rtcp)
1266 {
1267   GstEvent *otherev, *ev;
1268
1269   ev = gst_pad_get_sticky_event (pad, GST_EVENT_STREAM_START, 0);
1270   if (ev) {
1271     gst_event_unref (ev);
1272   } else {
1273     gchar *new_stream_id;
1274
1275     otherev = gst_pad_get_sticky_event (otherpad, GST_EVENT_STREAM_START, 0);
1276
1277     if (otherev) {
1278       const gchar *other_stream_id;
1279
1280       gst_event_parse_stream_start (otherev, &other_stream_id);
1281
1282       new_stream_id = g_strdup_printf ("%s/%s", other_stream_id,
1283           is_rtcp ? "rtcp" : "rtp");
1284       gst_event_unref (otherev);
1285     } else {
1286       new_stream_id = gst_pad_create_stream_id (pad, GST_ELEMENT (filter),
1287           is_rtcp ? "rtcp" : "rtp");
1288     }
1289
1290     ev = gst_event_new_stream_start (new_stream_id);
1291     g_free (new_stream_id);
1292
1293     gst_pad_push_event (pad, ev);
1294   }
1295
1296   ev = gst_pad_get_sticky_event (pad, GST_EVENT_CAPS, 0);
1297   if (ev) {
1298     gst_event_unref (ev);
1299   } else {
1300     GstCaps *caps;
1301
1302     if (is_rtcp)
1303       caps = gst_caps_new_empty_simple ("application/x-rtcp");
1304     else
1305       caps = gst_caps_new_empty_simple ("application/x-rtp");
1306
1307     gst_pad_set_caps (pad, caps);
1308     gst_caps_unref (caps);
1309   }
1310
1311   ev = gst_pad_get_sticky_event (pad, GST_EVENT_SEGMENT, 0);
1312   if (ev) {
1313     gst_event_unref (ev);
1314   } else {
1315     ev = gst_pad_get_sticky_event (otherpad, GST_EVENT_SEGMENT, 0);
1316
1317     if (ev)
1318       gst_pad_push_event (pad, ev);
1319   }
1320
1321   if (is_rtcp)
1322     filter->rtcp_has_segment = TRUE;
1323   else
1324     filter->rtp_has_segment = TRUE;
1325
1326 }
1327
1328 /*
1329  * This function should be called while holding the filter lock
1330  */
1331 static gboolean
1332 gst_srtp_dec_decode_buffer (GstSrtpDec * filter, GstPad * pad, GstBuffer * buf,
1333     gboolean is_rtcp, guint32 ssrc)
1334 {
1335   GstMapInfo map;
1336   srtp_err_status_t err;
1337   gint size;
1338   GstSrtpDecSsrcStream *stream;
1339
1340   GST_LOG_OBJECT (pad, "Received %s buffer of size %" G_GSIZE_FORMAT
1341       " with SSRC = %u", is_rtcp ? "RTCP" : "RTP", gst_buffer_get_size (buf),
1342       ssrc);
1343   filter->recv_count++;
1344   /* Change buffer to remove protection */
1345   buf = gst_buffer_make_writable (buf);
1346
1347   gst_buffer_map (buf, &map, GST_MAP_READWRITE);
1348   size = map.size;
1349
1350 unprotect:
1351
1352   gst_srtp_init_event_reporter ();
1353
1354   if (is_rtcp) {
1355 #ifdef HAVE_SRTP2
1356     stream = find_stream_by_ssrc (filter, ssrc);
1357
1358     err = srtp_unprotect_rtcp_mki (filter->session, map.data, &size,
1359         stream && stream->keys);
1360 #else
1361     err = srtp_unprotect_rtcp (filter->session, map.data, &size);
1362 #endif
1363   } else {
1364 #ifndef HAVE_SRTP2
1365     /* If ROC has changed, we know we need to set the initial RTP
1366      * sequence number too. */
1367     if (g_hash_table_contains (filter->streams_roc_changed,
1368             GUINT_TO_POINTER (ssrc))) {
1369       srtp_stream_t stream;
1370
1371       stream = srtp_get_stream (filter->session, htonl (ssrc));
1372
1373       if (stream) {
1374         guint16 seqnum = 0;
1375         GstRTPBuffer rtpbuf = GST_RTP_BUFFER_INIT;
1376
1377         gst_rtp_buffer_map (buf,
1378             GST_MAP_READ | GST_RTP_BUFFER_MAP_FLAG_SKIP_PADDING, &rtpbuf);
1379         seqnum = gst_rtp_buffer_get_seq (&rtpbuf);
1380         gst_rtp_buffer_unmap (&rtpbuf);
1381
1382         /* We finally add the RTP sequence number to the current
1383          * rollover counter. */
1384         stream->rtp_rdbx.index &= ~0xFFFF;
1385         stream->rtp_rdbx.index |= seqnum;
1386       }
1387
1388       g_hash_table_remove (filter->streams_roc_changed,
1389           GUINT_TO_POINTER (ssrc));
1390     }
1391 #endif
1392
1393 #ifdef HAVE_SRTP2
1394     {
1395       stream = find_stream_by_ssrc (filter, ssrc);
1396
1397       err = srtp_unprotect_mki (filter->session, map.data, &size,
1398           stream && stream->keys);
1399     }
1400 #else
1401     err = srtp_unprotect (filter->session, map.data, &size);
1402 #endif
1403   }
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   stream->recv_count++;
1410   /* Signal user depending on type of error */
1411   switch (err) {
1412     case srtp_err_status_ok:
1413       /* success! */
1414       break;
1415     case srtp_err_status_replay_fail:
1416       GST_DEBUG_OBJECT (filter,
1417           "Dropping replayed packet, probably retransmission");
1418       stream->recv_drop_count++;
1419       goto err;
1420     case srtp_err_status_replay_old:
1421       GST_DEBUG_OBJECT (filter,
1422           "Dropping replayed old packet, probably retransmission");
1423       stream->recv_drop_count++;
1424       goto err;
1425     case srtp_err_status_key_expired:{
1426
1427       GST_OBJECT_UNLOCK (filter);
1428       stream = request_key_with_signal (filter, ssrc, SIGNAL_HARD_LIMIT);
1429       GST_OBJECT_LOCK (filter);
1430
1431       /* Check the key request created a new stream */
1432       if (stream == NULL) {
1433         GST_WARNING_OBJECT (filter, "Hard limit reached, no new key, dropping");
1434         goto err;
1435       }
1436
1437       goto unprotect;
1438     }
1439     case srtp_err_status_auth_fail:
1440       GST_WARNING_OBJECT (filter, "Error authentication packet, dropping");
1441       stream->recv_drop_count++;
1442       goto err;
1443     case srtp_err_status_cipher_fail:
1444       GST_WARNING_OBJECT (filter, "Error while decrypting packet, dropping");
1445       stream->recv_drop_count++;
1446       goto err;
1447     default:
1448       GST_WARNING_OBJECT (pad,
1449           "Unable to unprotect buffer (unprotect failed code %d)", err);
1450       stream->recv_drop_count++;
1451       goto err;
1452   }
1453   gst_buffer_unmap (buf, &map);
1454   gst_buffer_set_size (buf, size);
1455   return TRUE;
1456
1457 err:
1458   filter->recv_drop_count++;
1459   gst_buffer_unmap (buf, &map);
1460   return FALSE;
1461 }
1462
1463 static GstFlowReturn
1464 gst_srtp_dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf,
1465     gboolean is_rtcp)
1466 {
1467   GstSrtpDec *filter = GST_SRTP_DEC (parent);
1468   GstPad *otherpad;
1469   GstSrtpDecSsrcStream *stream = NULL;
1470   GstFlowReturn ret = GST_FLOW_OK;
1471   guint32 ssrc = 0;
1472
1473   GST_OBJECT_LOCK (filter);
1474
1475   /* Check if this stream exists, if not create a new stream */
1476
1477   if (!(stream = validate_buffer (filter, buf, &ssrc, &is_rtcp))) {
1478     GST_OBJECT_UNLOCK (filter);
1479     GST_WARNING_OBJECT (filter, "Invalid buffer, dropping");
1480     goto drop_buffer;
1481   }
1482
1483   if (!STREAM_HAS_CRYPTO (stream)) {
1484     GST_OBJECT_UNLOCK (filter);
1485     goto push_out;
1486   }
1487
1488   if (!gst_srtp_dec_decode_buffer (filter, pad, buf, is_rtcp, ssrc)) {
1489     GST_OBJECT_UNLOCK (filter);
1490     goto drop_buffer;
1491   }
1492
1493   GST_OBJECT_UNLOCK (filter);
1494
1495   /* If all is well, we may have reached soft limit */
1496   if (gst_srtp_get_soft_limit_reached ())
1497     request_key_with_signal (filter, ssrc, SIGNAL_SOFT_LIMIT);
1498
1499 push_out:
1500   /* Push buffer to source pad */
1501   if (is_rtcp) {
1502     otherpad = filter->rtcp_srcpad;
1503     if (!filter->rtcp_has_segment)
1504       gst_srtp_dec_push_early_events (filter, filter->rtcp_srcpad,
1505           filter->rtp_srcpad, TRUE);
1506   } else {
1507     otherpad = filter->rtp_srcpad;
1508     if (!filter->rtp_has_segment)
1509       gst_srtp_dec_push_early_events (filter, filter->rtp_srcpad,
1510           filter->rtcp_srcpad, FALSE);
1511   }
1512   ret = gst_pad_push (otherpad, buf);
1513
1514   return ret;
1515
1516 drop_buffer:
1517   /* Drop buffer, except if gst_pad_push returned OK or an error */
1518
1519   gst_buffer_unref (buf);
1520
1521   return ret;
1522 }
1523
1524 static GstFlowReturn
1525 gst_srtp_dec_chain_rtp (GstPad * pad, GstObject * parent, GstBuffer * buf)
1526 {
1527   return gst_srtp_dec_chain (pad, parent, buf, FALSE);
1528 }
1529
1530 static GstFlowReturn
1531 gst_srtp_dec_chain_rtcp (GstPad * pad, GstObject * parent, GstBuffer * buf)
1532 {
1533   return gst_srtp_dec_chain (pad, parent, buf, TRUE);
1534 }
1535
1536 static GstStateChangeReturn
1537 gst_srtp_dec_change_state (GstElement * element, GstStateChange transition)
1538 {
1539   GstStateChangeReturn res;
1540   GstSrtpDec *filter;
1541
1542   filter = GST_SRTP_DEC (element);
1543   GST_OBJECT_LOCK (filter);
1544
1545   switch (transition) {
1546     case GST_STATE_CHANGE_READY_TO_PAUSED:
1547       filter->streams = g_hash_table_new_full (g_direct_hash, g_direct_equal,
1548           NULL, (GDestroyNotify) free_stream);
1549
1550 #ifndef HAVE_SRTP2
1551       filter->streams_roc_changed =
1552           g_hash_table_new (g_direct_hash, g_direct_equal);
1553 #endif
1554
1555       filter->rtp_has_segment = FALSE;
1556       filter->rtcp_has_segment = FALSE;
1557       filter->recv_count = 0;
1558       filter->recv_drop_count = 0;
1559       break;
1560     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1561       break;
1562     default:
1563       break;
1564   }
1565
1566   GST_OBJECT_UNLOCK (filter);
1567
1568   res = GST_ELEMENT_CLASS (gst_srtp_dec_parent_class)->change_state (element,
1569       transition);
1570
1571   switch (transition) {
1572     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1573       break;
1574     case GST_STATE_CHANGE_PAUSED_TO_READY:
1575       gst_srtp_dec_clear_streams (filter);
1576       g_hash_table_unref (filter->streams);
1577       filter->streams = NULL;
1578 #ifndef HAVE_SRTP2
1579       g_hash_table_unref (filter->streams_roc_changed);
1580       filter->streams_roc_changed = NULL;
1581 #endif
1582
1583       break;
1584     case GST_STATE_CHANGE_READY_TO_NULL:
1585       break;
1586     default:
1587       break;
1588   }
1589   return res;
1590 }