1 /*
2  * Copyright (c) 2014, Ericsson AB. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this
11  * list of conditions and the following disclaimer in the documentation and/or other
12  * materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
23  * OF SUCH DAMAGE.
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #include <gst/gst.h>
31 
32 #include "gstdtlsconnection.h"
33 
34 #include "gstdtlsagent.h"
35 #include "gstdtlscertificate.h"
36 
37 #ifdef __APPLE__
38 # define __AVAILABILITYMACROS__
39 # define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
40 #endif
41 
42 #include <openssl/err.h>
43 #include <openssl/ssl.h>
44 
45 #ifdef G_OS_WIN32
46 #include <winsock2.h>
47 #else
48 #include <string.h>
49 #include <errno.h>
50 #endif
51 
52 GST_DEBUG_CATEGORY_STATIC (gst_dtls_connection_debug);
53 #define GST_CAT_DEFAULT gst_dtls_connection_debug
54 
55 #define SRTP_KEY_LEN 16
56 #define SRTP_SALT_LEN 14
57 
58 enum
59 {
60   SIGNAL_ON_ENCODER_KEY,
61   SIGNAL_ON_DECODER_KEY,
62   SIGNAL_ON_PEER_CERTIFICATE,
63   NUM_SIGNALS
64 };
65 
66 static guint signals[NUM_SIGNALS];
67 
68 enum
69 {
70   PROP_0,
71   PROP_AGENT,
72   NUM_PROPERTIES
73 };
74 
75 static GParamSpec *properties[NUM_PROPERTIES];
76 
77 static int connection_ex_index;
78 
79 static void handle_timeout (gpointer data, gpointer user_data);
80 
81 struct _GstDtlsConnectionPrivate
82 {
83   SSL *ssl;
84   BIO *bio;
85 
86   gboolean is_client;
87   gboolean is_alive;
88   gboolean keys_exported;
89 
90   GMutex mutex;
91   GCond condition;
92   gpointer bio_buffer;
93   gint bio_buffer_len;
94   gint bio_buffer_offset;
95 
96   GClosure *send_closure;
97 
98   gboolean timeout_pending;
99   GThreadPool *thread_pool;
100 };
101 
102 G_DEFINE_TYPE_WITH_CODE (GstDtlsConnection, gst_dtls_connection, G_TYPE_OBJECT,
103     G_ADD_PRIVATE (GstDtlsConnection)
104     GST_DEBUG_CATEGORY_INIT (gst_dtls_connection_debug, "dtlsconnection", 0,
105         "DTLS Connection"));
106 
107 static void gst_dtls_connection_finalize (GObject * gobject);
108 static void gst_dtls_connection_set_property (GObject *, guint prop_id,
109     const GValue *, GParamSpec *);
110 
111 static void log_state (GstDtlsConnection *, const gchar * str);
112 static void export_srtp_keys (GstDtlsConnection *);
113 static void openssl_poll (GstDtlsConnection *);
114 static int openssl_verify_callback (int preverify_ok,
115     X509_STORE_CTX * x509_ctx);
116 
117 static BIO_METHOD *BIO_s_gst_dtls_connection (void);
118 static int bio_method_write (BIO *, const char *data, int size);
119 static int bio_method_read (BIO *, char *out_buffer, int size);
120 static long bio_method_ctrl (BIO *, int cmd, long arg1, void *arg2);
121 static int bio_method_new (BIO *);
122 static int bio_method_free (BIO *);
123 
124 static void
gst_dtls_connection_class_init(GstDtlsConnectionClass * klass)125 gst_dtls_connection_class_init (GstDtlsConnectionClass * klass)
126 {
127   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
128 
129   gobject_class->set_property = gst_dtls_connection_set_property;
130 
131   connection_ex_index =
132       SSL_get_ex_new_index (0, (gpointer) "gstdtlsagent connection index", NULL,
133       NULL, NULL);
134 
135   signals[SIGNAL_ON_DECODER_KEY] =
136       g_signal_new ("on-decoder-key", G_TYPE_FROM_CLASS (klass),
137       G_SIGNAL_RUN_LAST, 0, NULL, NULL,
138       g_cclosure_marshal_generic, G_TYPE_NONE, 3,
139       G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT);
140 
141   signals[SIGNAL_ON_ENCODER_KEY] =
142       g_signal_new ("on-encoder-key", G_TYPE_FROM_CLASS (klass),
143       G_SIGNAL_RUN_LAST, 0, NULL, NULL,
144       g_cclosure_marshal_generic, G_TYPE_NONE, 3,
145       G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT);
146 
147   signals[SIGNAL_ON_PEER_CERTIFICATE] =
148       g_signal_new ("on-peer-certificate", G_TYPE_FROM_CLASS (klass),
149       G_SIGNAL_RUN_LAST, 0, NULL, NULL,
150       g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 1, G_TYPE_STRING);
151 
152   properties[PROP_AGENT] =
153       g_param_spec_object ("agent",
154       "DTLS Agent",
155       "Agent to use in creation of the connection",
156       GST_TYPE_DTLS_AGENT,
157       G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
158 
159   g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
160 
161   _gst_dtls_init_openssl ();
162 
163   gobject_class->finalize = gst_dtls_connection_finalize;
164 }
165 
166 static void
gst_dtls_connection_init(GstDtlsConnection * self)167 gst_dtls_connection_init (GstDtlsConnection * self)
168 {
169   GstDtlsConnectionPrivate *priv;
170 
171   self->priv = priv = gst_dtls_connection_get_instance_private (self);
172 
173   priv->ssl = NULL;
174   priv->bio = NULL;
175 
176   priv->send_closure = NULL;
177 
178   priv->is_client = FALSE;
179   priv->is_alive = TRUE;
180   priv->keys_exported = FALSE;
181 
182   priv->bio_buffer = NULL;
183   priv->bio_buffer_len = 0;
184   priv->bio_buffer_offset = 0;
185 
186   g_mutex_init (&priv->mutex);
187   g_cond_init (&priv->condition);
188 
189   /* Thread pool for handling timeouts, we only need one thread for that
190    * really and share threads with all other thread pools around there as
191    * this is not going to happen very often */
192   priv->thread_pool = g_thread_pool_new (handle_timeout, self, 1, FALSE, NULL);
193   g_assert (priv->thread_pool);
194   priv->timeout_pending = FALSE;
195 }
196 
197 static void
gst_dtls_connection_finalize(GObject * gobject)198 gst_dtls_connection_finalize (GObject * gobject)
199 {
200   GstDtlsConnection *self = GST_DTLS_CONNECTION (gobject);
201   GstDtlsConnectionPrivate *priv = self->priv;
202 
203   g_thread_pool_free (priv->thread_pool, TRUE, TRUE);
204   priv->thread_pool = NULL;
205 
206   SSL_free (priv->ssl);
207   priv->ssl = NULL;
208 
209   if (priv->send_closure) {
210     g_closure_unref (priv->send_closure);
211     priv->send_closure = NULL;
212   }
213 
214   g_mutex_clear (&priv->mutex);
215   g_cond_clear (&priv->condition);
216 
217   GST_DEBUG_OBJECT (self, "finalized");
218 
219   G_OBJECT_CLASS (gst_dtls_connection_parent_class)->finalize (gobject);
220 }
221 
222 #if OPENSSL_VERSION_NUMBER < 0x10100001L
223 static void
BIO_set_data(BIO * bio,void * ptr)224 BIO_set_data (BIO * bio, void *ptr)
225 {
226   bio->ptr = ptr;
227 }
228 
229 static void *
BIO_get_data(BIO * bio)230 BIO_get_data (BIO * bio)
231 {
232   return bio->ptr;
233 }
234 
235 static void
BIO_set_shutdown(BIO * bio,int shutdown)236 BIO_set_shutdown (BIO * bio, int shutdown)
237 {
238   bio->shutdown = shutdown;
239 }
240 
241 static void
BIO_set_init(BIO * bio,int init)242 BIO_set_init (BIO * bio, int init)
243 {
244   bio->init = init;
245 }
246 
247 static X509 *
X509_STORE_CTX_get0_cert(X509_STORE_CTX * ctx)248 X509_STORE_CTX_get0_cert (X509_STORE_CTX * ctx)
249 {
250   return ctx->cert;
251 }
252 #endif
253 
254 static void
gst_dtls_connection_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)255 gst_dtls_connection_set_property (GObject * object, guint prop_id,
256     const GValue * value, GParamSpec * pspec)
257 {
258   GstDtlsConnection *self = GST_DTLS_CONNECTION (object);
259   GstDtlsAgent *agent;
260   GstDtlsConnectionPrivate *priv = self->priv;
261   SSL_CTX *ssl_context;
262 
263   switch (prop_id) {
264     case PROP_AGENT:
265       g_return_if_fail (!priv->ssl);
266       agent = GST_DTLS_AGENT (g_value_get_object (value));
267       g_return_if_fail (GST_IS_DTLS_AGENT (agent));
268 
269       ssl_context = _gst_dtls_agent_peek_context (agent);
270 
271       priv->ssl = SSL_new (ssl_context);
272       g_return_if_fail (priv->ssl);
273 
274       priv->bio = BIO_new (BIO_s_gst_dtls_connection ());
275       g_return_if_fail (priv->bio);
276 
277       BIO_set_data (priv->bio, self);
278       SSL_set_bio (priv->ssl, priv->bio, priv->bio);
279 
280       SSL_set_verify (priv->ssl,
281           SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
282           openssl_verify_callback);
283       SSL_set_ex_data (priv->ssl, connection_ex_index, self);
284 
285       log_state (self, "connection created");
286       break;
287     default:
288       G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
289   }
290 }
291 
292 void
gst_dtls_connection_start(GstDtlsConnection * self,gboolean is_client)293 gst_dtls_connection_start (GstDtlsConnection * self, gboolean is_client)
294 {
295   GstDtlsConnectionPrivate *priv;
296 
297   priv = self->priv;
298 
299   g_return_if_fail (priv->send_closure);
300   g_return_if_fail (priv->ssl);
301   g_return_if_fail (priv->bio);
302 
303   GST_TRACE_OBJECT (self, "locking @ start");
304   g_mutex_lock (&priv->mutex);
305   GST_TRACE_OBJECT (self, "locked @ start");
306 
307   priv->is_alive = TRUE;
308   priv->bio_buffer = NULL;
309   priv->bio_buffer_len = 0;
310   priv->bio_buffer_offset = 0;
311   priv->keys_exported = FALSE;
312 
313   priv->is_client = is_client;
314   if (priv->is_client) {
315     SSL_set_connect_state (priv->ssl);
316   } else {
317     SSL_set_accept_state (priv->ssl);
318   }
319   log_state (self, "initial state set");
320 
321   openssl_poll (self);
322 
323   log_state (self, "first poll done");
324 
325   GST_TRACE_OBJECT (self, "unlocking @ start");
326   g_mutex_unlock (&priv->mutex);
327 }
328 
329 static void
handle_timeout(gpointer data,gpointer user_data)330 handle_timeout (gpointer data, gpointer user_data)
331 {
332   GstDtlsConnection *self = user_data;
333   GstDtlsConnectionPrivate *priv;
334   gint ret;
335 
336   priv = self->priv;
337 
338   g_mutex_lock (&priv->mutex);
339   priv->timeout_pending = FALSE;
340   if (priv->is_alive) {
341     ret = DTLSv1_handle_timeout (priv->ssl);
342 
343     GST_DEBUG_OBJECT (self, "handle timeout returned %d, is_alive: %d", ret,
344         priv->is_alive);
345 
346     if (ret < 0) {
347       GST_WARNING_OBJECT (self, "handling timeout failed");
348     } else if (ret > 0) {
349       log_state (self, "handling timeout before poll");
350       openssl_poll (self);
351       log_state (self, "handling timeout after poll");
352     }
353   }
354   g_mutex_unlock (&priv->mutex);
355 }
356 
357 static gboolean
schedule_timeout_handling(GstClock * clock,GstClockTime time,GstClockID id,gpointer user_data)358 schedule_timeout_handling (GstClock * clock, GstClockTime time, GstClockID id,
359     gpointer user_data)
360 {
361   GstDtlsConnection *self = user_data;
362 
363   g_mutex_lock (&self->priv->mutex);
364   if (self->priv->is_alive && !self->priv->timeout_pending) {
365     self->priv->timeout_pending = TRUE;
366 
367     GST_TRACE_OBJECT (self, "Schedule timeout now");
368     g_thread_pool_push (self->priv->thread_pool, GINT_TO_POINTER (0xc0ffee),
369         NULL);
370   }
371   g_mutex_unlock (&self->priv->mutex);
372 
373   return TRUE;
374 }
375 
376 static void
gst_dtls_connection_check_timeout_locked(GstDtlsConnection * self)377 gst_dtls_connection_check_timeout_locked (GstDtlsConnection * self)
378 {
379   GstDtlsConnectionPrivate *priv;
380   struct timeval timeout;
381   gint64 end_time, wait_time;
382 
383   g_return_if_fail (GST_IS_DTLS_CONNECTION (self));
384 
385   priv = self->priv;
386 
387   if (DTLSv1_get_timeout (priv->ssl, &timeout)) {
388     wait_time = timeout.tv_sec * G_USEC_PER_SEC + timeout.tv_usec;
389 
390     GST_DEBUG_OBJECT (self, "waiting for %" G_GINT64_FORMAT " usec", wait_time);
391     if (wait_time) {
392       GstClock *system_clock = gst_system_clock_obtain ();
393       GstClockID clock_id;
394 #ifndef G_DISABLE_ASSERT
395       GstClockReturn clock_return;
396 #endif
397 
398       end_time = gst_clock_get_time (system_clock) + wait_time * GST_USECOND;
399 
400       clock_id = gst_clock_new_single_shot_id (system_clock, end_time);
401 #ifndef G_DISABLE_ASSERT
402       clock_return =
403 #else
404       (void)
405 #endif
406           gst_clock_id_wait_async (clock_id, schedule_timeout_handling,
407           g_object_ref (self), (GDestroyNotify) g_object_unref);
408       g_assert (clock_return == GST_CLOCK_OK);
409       gst_clock_id_unref (clock_id);
410       gst_object_unref (system_clock);
411     } else {
412       if (self->priv->is_alive && !self->priv->timeout_pending) {
413         self->priv->timeout_pending = TRUE;
414         GST_TRACE_OBJECT (self, "Schedule timeout now");
415 
416         g_thread_pool_push (self->priv->thread_pool, GINT_TO_POINTER (0xc0ffee),
417             NULL);
418       }
419     }
420   } else {
421     GST_DEBUG_OBJECT (self, "no timeout set");
422   }
423 }
424 
425 void
gst_dtls_connection_check_timeout(GstDtlsConnection * self)426 gst_dtls_connection_check_timeout (GstDtlsConnection * self)
427 {
428   GstDtlsConnectionPrivate *priv;
429 
430   g_return_if_fail (GST_IS_DTLS_CONNECTION (self));
431 
432   priv = self->priv;
433 
434   GST_TRACE_OBJECT (self, "locking @ start_timeout");
435   g_mutex_lock (&priv->mutex);
436   GST_TRACE_OBJECT (self, "locked @ start_timeout");
437   gst_dtls_connection_check_timeout_locked (self);
438   g_mutex_unlock (&priv->mutex);
439   GST_TRACE_OBJECT (self, "unlocking @ start_timeout");
440 }
441 
442 void
gst_dtls_connection_stop(GstDtlsConnection * self)443 gst_dtls_connection_stop (GstDtlsConnection * self)
444 {
445   g_return_if_fail (GST_IS_DTLS_CONNECTION (self));
446   g_return_if_fail (self->priv->ssl);
447   g_return_if_fail (self->priv->bio);
448 
449   GST_DEBUG_OBJECT (self, "stopping connection");
450 
451   GST_TRACE_OBJECT (self, "locking @ stop");
452   g_mutex_lock (&self->priv->mutex);
453   GST_TRACE_OBJECT (self, "locked @ stop");
454 
455   self->priv->is_alive = FALSE;
456   GST_TRACE_OBJECT (self, "signaling @ stop");
457   g_cond_signal (&self->priv->condition);
458   GST_TRACE_OBJECT (self, "signaled @ stop");
459 
460   GST_TRACE_OBJECT (self, "unlocking @ stop");
461   g_mutex_unlock (&self->priv->mutex);
462 
463   GST_DEBUG_OBJECT (self, "stopped connection");
464 }
465 
466 void
gst_dtls_connection_close(GstDtlsConnection * self)467 gst_dtls_connection_close (GstDtlsConnection * self)
468 {
469   g_return_if_fail (GST_IS_DTLS_CONNECTION (self));
470   g_return_if_fail (self->priv->ssl);
471   g_return_if_fail (self->priv->bio);
472 
473   GST_DEBUG_OBJECT (self, "closing connection");
474 
475   GST_TRACE_OBJECT (self, "locking @ close");
476   g_mutex_lock (&self->priv->mutex);
477   GST_TRACE_OBJECT (self, "locked @ close");
478 
479   if (self->priv->is_alive) {
480     self->priv->is_alive = FALSE;
481     g_cond_signal (&self->priv->condition);
482   }
483 
484   GST_TRACE_OBJECT (self, "unlocking @ close");
485   g_mutex_unlock (&self->priv->mutex);
486 
487   GST_DEBUG_OBJECT (self, "closed connection");
488 }
489 
490 void
gst_dtls_connection_set_send_callback(GstDtlsConnection * self,GClosure * closure)491 gst_dtls_connection_set_send_callback (GstDtlsConnection * self,
492     GClosure * closure)
493 {
494   g_return_if_fail (GST_IS_DTLS_CONNECTION (self));
495 
496   GST_TRACE_OBJECT (self, "locking @ set_send_callback");
497   g_mutex_lock (&self->priv->mutex);
498   GST_TRACE_OBJECT (self, "locked @ set_send_callback");
499 
500   if (self->priv->send_closure) {
501     g_closure_unref (self->priv->send_closure);
502     self->priv->send_closure = NULL;
503   }
504   self->priv->send_closure = closure;
505 
506   if (closure && G_CLOSURE_NEEDS_MARSHAL (closure)) {
507     g_closure_set_marshal (closure, g_cclosure_marshal_generic);
508   }
509 
510   GST_TRACE_OBJECT (self, "unlocking @ set_send_callback");
511   g_mutex_unlock (&self->priv->mutex);
512 }
513 
514 gint
gst_dtls_connection_process(GstDtlsConnection * self,gpointer data,gint len)515 gst_dtls_connection_process (GstDtlsConnection * self, gpointer data, gint len)
516 {
517   GstDtlsConnectionPrivate *priv;
518   gint result;
519 
520   g_return_val_if_fail (GST_IS_DTLS_CONNECTION (self), 0);
521   g_return_val_if_fail (self->priv->ssl, 0);
522   g_return_val_if_fail (self->priv->bio, 0);
523 
524   priv = self->priv;
525 
526   GST_TRACE_OBJECT (self, "locking @ process");
527   g_mutex_lock (&priv->mutex);
528   GST_TRACE_OBJECT (self, "locked @ process");
529 
530   g_warn_if_fail (!priv->bio_buffer);
531 
532   priv->bio_buffer = data;
533   priv->bio_buffer_len = len;
534   priv->bio_buffer_offset = 0;
535 
536   log_state (self, "process start");
537 
538   if (SSL_want_write (priv->ssl)) {
539     openssl_poll (self);
540     log_state (self, "process want write, after poll");
541   }
542 
543   result = SSL_read (priv->ssl, data, len);
544 
545   log_state (self, "process after read");
546 
547   openssl_poll (self);
548 
549   log_state (self, "process after poll");
550 
551   GST_DEBUG_OBJECT (self, "read result: %d", result);
552 
553   GST_TRACE_OBJECT (self, "unlocking @ process");
554   g_mutex_unlock (&priv->mutex);
555 
556   return result;
557 }
558 
559 gint
gst_dtls_connection_send(GstDtlsConnection * self,gpointer data,gint len)560 gst_dtls_connection_send (GstDtlsConnection * self, gpointer data, gint len)
561 {
562   int ret = 0;
563 
564   g_return_val_if_fail (GST_IS_DTLS_CONNECTION (self), 0);
565 
566   g_return_val_if_fail (self->priv->ssl, 0);
567   g_return_val_if_fail (self->priv->bio, 0);
568 
569   GST_TRACE_OBJECT (self, "locking @ send");
570   g_mutex_lock (&self->priv->mutex);
571   GST_TRACE_OBJECT (self, "locked @ send");
572 
573   if (SSL_is_init_finished (self->priv->ssl)) {
574     ret = SSL_write (self->priv->ssl, data, len);
575     GST_DEBUG_OBJECT (self, "data sent: input was %d B, output is %d B", len,
576         ret);
577   } else {
578     GST_WARNING_OBJECT (self,
579         "tried to send data before handshake was complete");
580     ret = 0;
581   }
582 
583   GST_TRACE_OBJECT (self, "unlocking @ send");
584   g_mutex_unlock (&self->priv->mutex);
585 
586   return ret;
587 }
588 
589 /*
590      ######   #######  ##    ##
591     ##    ## ##     ## ###   ##
592     ##       ##     ## ####  ##
593     ##       ##     ## ## ## ##
594     ##       ##     ## ##  ####
595     ##    ## ##     ## ##   ###
596      ######   #######  ##    ##
597 */
598 
599 static void
log_state(GstDtlsConnection * self,const gchar * str)600 log_state (GstDtlsConnection * self, const gchar * str)
601 {
602   GstDtlsConnectionPrivate *priv = self->priv;
603   guint states = 0;
604 
605   states |= (! !SSL_is_init_finished (priv->ssl) << 0);
606   states |= (! !SSL_in_init (priv->ssl) << 4);
607   states |= (! !SSL_in_before (priv->ssl) << 8);
608   states |= (! !SSL_in_connect_init (priv->ssl) << 12);
609   states |= (! !SSL_in_accept_init (priv->ssl) << 16);
610   states |= (! !SSL_want_write (priv->ssl) << 20);
611   states |= (! !SSL_want_read (priv->ssl) << 24);
612 
613 #if OPENSSL_VERSION_NUMBER < 0x10100001L
614   GST_LOG_OBJECT (self, "%s: role=%s buf=(%d,%p:%d/%d) %x|%x %s",
615       str,
616       priv->is_client ? "client" : "server",
617       pqueue_size (priv->ssl->d1->sent_messages),
618       priv->bio_buffer,
619       priv->bio_buffer_offset,
620       priv->bio_buffer_len,
621       states, SSL_get_state (priv->ssl), SSL_state_string_long (priv->ssl));
622 #else
623   GST_LOG_OBJECT (self, "%s: role=%s buf=(%p:%d/%d) %x|%x %s",
624       str,
625       priv->is_client ? "client" : "server",
626       priv->bio_buffer,
627       priv->bio_buffer_offset,
628       priv->bio_buffer_len,
629       states, SSL_get_state (priv->ssl), SSL_state_string_long (priv->ssl));
630 #endif
631 }
632 
633 static void
export_srtp_keys(GstDtlsConnection * self)634 export_srtp_keys (GstDtlsConnection * self)
635 {
636   typedef struct
637   {
638     guint8 v[SRTP_KEY_LEN];
639   } Key;
640 
641   typedef struct
642   {
643     guint8 v[SRTP_SALT_LEN];
644   } Salt;
645 
646   struct
647   {
648     Key client_key;
649     Key server_key;
650     Salt client_salt;
651     Salt server_salt;
652   } exported_keys;
653 
654   struct
655   {
656     Key key;
657     Salt salt;
658   } client_key, server_key;
659 
660   SRTP_PROTECTION_PROFILE *profile;
661   GstDtlsSrtpCipher cipher;
662   GstDtlsSrtpAuth auth;
663   gint success;
664 
665   static gchar export_string[] = "EXTRACTOR-dtls_srtp";
666 
667   success = SSL_export_keying_material (self->priv->ssl,
668       (gpointer) & exported_keys, 60, export_string, strlen (export_string),
669       NULL, 0, 0);
670 
671   if (!success) {
672     GST_WARNING_OBJECT (self, "failed to export srtp keys");
673     return;
674   }
675 
676   profile = SSL_get_selected_srtp_profile (self->priv->ssl);
677 
678   GST_INFO_OBJECT (self, "keys received, profile is %s", profile->name);
679 
680   switch (profile->id) {
681     case SRTP_AES128_CM_SHA1_80:
682       cipher = GST_DTLS_SRTP_CIPHER_AES_128_ICM;
683       auth = GST_DTLS_SRTP_AUTH_HMAC_SHA1_80;
684       break;
685     case SRTP_AES128_CM_SHA1_32:
686       cipher = GST_DTLS_SRTP_CIPHER_AES_128_ICM;
687       auth = GST_DTLS_SRTP_AUTH_HMAC_SHA1_32;
688       break;
689     default:
690       GST_WARNING_OBJECT (self, "invalid crypto suite set by handshake");
691       goto beach;
692   }
693 
694   client_key.key = exported_keys.client_key;
695   server_key.key = exported_keys.server_key;
696   client_key.salt = exported_keys.client_salt;
697   server_key.salt = exported_keys.server_salt;
698 
699   if (self->priv->is_client) {
700     g_signal_emit (self, signals[SIGNAL_ON_ENCODER_KEY], 0, &client_key, cipher,
701         auth);
702     g_signal_emit (self, signals[SIGNAL_ON_DECODER_KEY], 0, &server_key,
703         cipher, auth);
704   } else {
705     g_signal_emit (self, signals[SIGNAL_ON_ENCODER_KEY], 0, &server_key,
706         cipher, auth);
707     g_signal_emit (self, signals[SIGNAL_ON_DECODER_KEY], 0, &client_key, cipher,
708         auth);
709   }
710 
711 beach:
712   self->priv->keys_exported = TRUE;
713 }
714 
715 static int
ssl_warn_cb(const char * str,size_t len,void * u)716 ssl_warn_cb (const char *str, size_t len, void *u)
717 {
718   GstDtlsConnection *self = u;
719   GST_WARNING_OBJECT (self, "ssl error: %s", str);
720   return 0;
721 }
722 
723 static int
ssl_err_cb(const char * str,size_t len,void * u)724 ssl_err_cb (const char *str, size_t len, void *u)
725 {
726   GstDtlsConnection *self = u;
727   GST_ERROR_OBJECT (self, "ssl error: %s", str);
728   return 0;
729 }
730 
731 static void
openssl_poll(GstDtlsConnection * self)732 openssl_poll (GstDtlsConnection * self)
733 {
734   int ret;
735   int error;
736 
737   log_state (self, "poll: before handshake");
738 
739   ERR_clear_error ();
740   ret = SSL_do_handshake (self->priv->ssl);
741 
742   log_state (self, "poll: after handshake");
743 
744   switch (ret) {
745     case 1:
746       if (!self->priv->keys_exported) {
747         GST_INFO_OBJECT (self,
748             "handshake just completed successfully, exporting keys");
749         export_srtp_keys (self);
750       } else {
751         GST_INFO_OBJECT (self, "handshake is completed");
752       }
753       return;
754     case 0:
755       GST_DEBUG_OBJECT (self, "do_handshake encountered EOF");
756       break;
757     case -1:
758       GST_DEBUG_OBJECT (self, "do_handshake encountered BIO error");
759       break;
760     default:
761       GST_DEBUG_OBJECT (self, "do_handshake returned %d", ret);
762   }
763 
764   error = SSL_get_error (self->priv->ssl, ret);
765 
766   switch (error) {
767     case SSL_ERROR_NONE:
768       GST_WARNING_OBJECT (self, "no error, handshake should be done");
769       break;
770     case SSL_ERROR_SSL:
771       GST_ERROR_OBJECT (self, "SSL error");
772       ERR_print_errors_cb (ssl_err_cb, self);
773       return;
774     case SSL_ERROR_WANT_READ:
775       GST_LOG_OBJECT (self, "SSL wants read");
776       break;
777     case SSL_ERROR_WANT_WRITE:
778       GST_LOG_OBJECT (self, "SSL wants write");
779       break;
780     case SSL_ERROR_SYSCALL:{
781       gchar message[1024] = "<unknown>";
782       gint syserror;
783 #ifdef G_OS_WIN32
784       syserror = WSAGetLastError ();
785       FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, syserror, 0, message,
786           sizeof message, NULL);
787 #else
788       syserror = errno;
789       strerror_r (syserror, message, sizeof message);
790 #endif
791       GST_CAT_LEVEL_LOG (GST_CAT_DEFAULT,
792           syserror != 0 ? GST_LEVEL_WARNING : GST_LEVEL_LOG,
793           self, "SSL syscall error: errno %d: %s", syserror, message);
794       break;
795     }
796     default:
797       GST_WARNING_OBJECT (self, "Unknown SSL error: %d, ret: %d", error, ret);
798   }
799 
800   ERR_print_errors_cb (ssl_warn_cb, self);
801 }
802 
803 static int
openssl_verify_callback(int preverify_ok,X509_STORE_CTX * x509_ctx)804 openssl_verify_callback (int preverify_ok, X509_STORE_CTX * x509_ctx)
805 {
806   GstDtlsConnection *self;
807   SSL *ssl;
808   BIO *bio;
809   gchar *pem = NULL;
810   gboolean accepted = FALSE;
811 
812   ssl =
813       X509_STORE_CTX_get_ex_data (x509_ctx,
814       SSL_get_ex_data_X509_STORE_CTX_idx ());
815   self = SSL_get_ex_data (ssl, connection_ex_index);
816   g_return_val_if_fail (GST_IS_DTLS_CONNECTION (self), FALSE);
817 
818   pem = _gst_dtls_x509_to_pem (X509_STORE_CTX_get0_cert (x509_ctx));
819 
820   if (!pem) {
821     GST_WARNING_OBJECT (self,
822         "failed to convert received certificate to pem format");
823   } else {
824     bio = BIO_new (BIO_s_mem ());
825     if (bio) {
826       gchar buffer[2048];
827       gint len;
828 
829       len =
830           X509_NAME_print_ex (bio,
831           X509_get_subject_name (X509_STORE_CTX_get0_cert (x509_ctx)), 1,
832           XN_FLAG_MULTILINE);
833       BIO_read (bio, buffer, len);
834       buffer[len] = '\0';
835       GST_DEBUG_OBJECT (self, "Peer certificate received:\n%s", buffer);
836       BIO_free (bio);
837     } else {
838       GST_DEBUG_OBJECT (self, "failed to create certificate print membio");
839     }
840 
841     g_signal_emit (self, signals[SIGNAL_ON_PEER_CERTIFICATE], 0, pem,
842         &accepted);
843     g_free (pem);
844   }
845 
846   return accepted;
847 }
848 
849 /*
850     ########  ####  #######
851     ##     ##  ##  ##     ##
852     ##     ##  ##  ##     ##
853     ########   ##  ##     ##
854     ##     ##  ##  ##     ##
855     ##     ##  ##  ##     ##
856     ########  ####  #######
857 */
858 
859 #if OPENSSL_VERSION_NUMBER < 0x10100001L
860 static BIO_METHOD custom_bio_methods = {
861   BIO_TYPE_BIO,
862   "stream",
863   bio_method_write,
864   bio_method_read,
865   NULL,
866   NULL,
867   bio_method_ctrl,
868   bio_method_new,
869   bio_method_free,
870   NULL,
871 };
872 
873 static BIO_METHOD *
BIO_s_gst_dtls_connection(void)874 BIO_s_gst_dtls_connection (void)
875 {
876   return &custom_bio_methods;
877 }
878 #else
879 static BIO_METHOD *custom_bio_methods;
880 
881 static BIO_METHOD *
BIO_s_gst_dtls_connection(void)882 BIO_s_gst_dtls_connection (void)
883 {
884   if (custom_bio_methods != NULL)
885     return custom_bio_methods;
886 
887   custom_bio_methods = BIO_meth_new (BIO_TYPE_BIO, "stream");
888   if (custom_bio_methods == NULL
889       || !BIO_meth_set_write (custom_bio_methods, bio_method_write)
890       || !BIO_meth_set_read (custom_bio_methods, bio_method_read)
891       || !BIO_meth_set_ctrl (custom_bio_methods, bio_method_ctrl)
892       || !BIO_meth_set_create (custom_bio_methods, bio_method_new)
893       || !BIO_meth_set_destroy (custom_bio_methods, bio_method_free)) {
894     BIO_meth_free (custom_bio_methods);
895     return NULL;
896   }
897 
898   return custom_bio_methods;
899 }
900 #endif
901 
902 static int
bio_method_write(BIO * bio,const char * data,int size)903 bio_method_write (BIO * bio, const char *data, int size)
904 {
905   GstDtlsConnection *self = GST_DTLS_CONNECTION (BIO_get_data (bio));
906 
907   GST_LOG_OBJECT (self, "BIO: writing %d", size);
908 
909   if (self->priv->send_closure) {
910     GValue values[3] = { G_VALUE_INIT };
911 
912     g_value_init (&values[0], GST_TYPE_DTLS_CONNECTION);
913     g_value_set_object (&values[0], self);
914 
915     g_value_init (&values[1], G_TYPE_POINTER);
916     g_value_set_pointer (&values[1], (gpointer) data);
917 
918     g_value_init (&values[2], G_TYPE_INT);
919     g_value_set_int (&values[2], size);
920 
921     g_closure_invoke (self->priv->send_closure, NULL, 3, values, NULL);
922 
923     g_value_unset (&values[0]);
924   }
925 
926   return size;
927 }
928 
929 static int
bio_method_read(BIO * bio,char * out_buffer,int size)930 bio_method_read (BIO * bio, char *out_buffer, int size)
931 {
932   GstDtlsConnection *self = GST_DTLS_CONNECTION (BIO_get_data (bio));
933   GstDtlsConnectionPrivate *priv = self->priv;
934   guint internal_size;
935   gint copy_size;
936 
937   internal_size = priv->bio_buffer_len - priv->bio_buffer_offset;
938 
939   if (!priv->bio_buffer) {
940     GST_LOG_OBJECT (self, "BIO: EOF");
941     return 0;
942   }
943 
944   if (!out_buffer || size <= 0) {
945     GST_WARNING_OBJECT (self, "BIO: read got invalid arguments");
946     if (internal_size) {
947       BIO_set_retry_read (bio);
948     }
949     return internal_size;
950   }
951 
952   if (size > internal_size) {
953     copy_size = internal_size;
954   } else {
955     copy_size = size;
956   }
957 
958   GST_DEBUG_OBJECT (self,
959       "reading %d/%d bytes %d at offset %d, output buff size is %d", copy_size,
960       priv->bio_buffer_len, internal_size, priv->bio_buffer_offset, size);
961 
962   memcpy (out_buffer, (guint8 *) priv->bio_buffer + priv->bio_buffer_offset,
963       copy_size);
964   priv->bio_buffer_offset += copy_size;
965 
966   if (priv->bio_buffer_len == priv->bio_buffer_offset) {
967     priv->bio_buffer = NULL;
968   }
969 
970   return copy_size;
971 }
972 
973 static long
bio_method_ctrl(BIO * bio,int cmd,long arg1,void * arg2)974 bio_method_ctrl (BIO * bio, int cmd, long arg1, void *arg2)
975 {
976   GstDtlsConnection *self = GST_DTLS_CONNECTION (BIO_get_data (bio));
977   GstDtlsConnectionPrivate *priv = self->priv;
978 
979   switch (cmd) {
980     case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
981     case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
982       GST_LOG_OBJECT (self, "BIO: Timeout set");
983       gst_dtls_connection_check_timeout_locked (self);
984       return 1;
985     case BIO_CTRL_RESET:
986       priv->bio_buffer = NULL;
987       priv->bio_buffer_len = 0;
988       priv->bio_buffer_offset = 0;
989       GST_LOG_OBJECT (self, "BIO: EOF reset");
990       return 1;
991     case BIO_CTRL_EOF:{
992       gint eof = !(priv->bio_buffer_len - priv->bio_buffer_offset);
993       GST_LOG_OBJECT (self, "BIO: EOF query returned %d", eof);
994       return eof;
995     }
996     case BIO_CTRL_WPENDING:
997       GST_LOG_OBJECT (self, "BIO: pending write");
998       return 1;
999     case BIO_CTRL_PENDING:{
1000       gint pending = priv->bio_buffer_len - priv->bio_buffer_offset;
1001       GST_LOG_OBJECT (self, "BIO: %d bytes pending", pending);
1002       return pending;
1003     }
1004     case BIO_CTRL_FLUSH:
1005       GST_LOG_OBJECT (self, "BIO: flushing");
1006       return 1;
1007     case BIO_CTRL_DGRAM_QUERY_MTU:
1008       GST_DEBUG_OBJECT (self, "BIO: MTU query, returning 0...");
1009       return 0;
1010     case BIO_CTRL_DGRAM_MTU_EXCEEDED:
1011       GST_WARNING_OBJECT (self, "BIO: MTU exceeded");
1012       return 0;
1013     default:
1014       GST_LOG_OBJECT (self, "BIO: unhandled ctrl, %d", cmd);
1015       return 0;
1016   }
1017 }
1018 
1019 static int
bio_method_new(BIO * bio)1020 bio_method_new (BIO * bio)
1021 {
1022   GST_LOG_OBJECT (NULL, "BIO: new");
1023 
1024   BIO_set_shutdown (bio, 0);
1025   BIO_set_init (bio, 1);
1026 
1027   return 1;
1028 }
1029 
1030 static int
bio_method_free(BIO * bio)1031 bio_method_free (BIO * bio)
1032 {
1033   if (!bio) {
1034     GST_LOG_OBJECT (NULL, "BIO free called with null bio");
1035     return 0;
1036   }
1037 
1038   GST_LOG_OBJECT (GST_DTLS_CONNECTION (BIO_get_data (bio)), "BIO free");
1039   return 0;
1040 }
1041