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