1 /**
2  * @file dtls_srtp.c DTLS-SRTP media encryption
3  *
4  * Copyright (C) 2010 Creytiv.com
5  */
6 
7 #include <re.h>
8 #include <baresip.h>
9 #include <string.h>
10 #include "dtls_srtp.h"
11 
12 
13 /**
14  * @defgroup dtls_srtp dtls_srtp
15  *
16  * DTLS-SRTP media encryption module
17  *
18  * This module implements end-to-end media encryption using DTLS-SRTP
19  * which is now mandatory for WebRTC endpoints.
20  *
21  * DTLS-SRTP can be enabled in ~/.baresip/accounts:
22  *
23  \verbatim
24   <sip:user@domain.com>;mediaenc=dtls_srtp
25   <sip:user@domain.com>;mediaenc=dtls_srtpf
26   <sip:user@domain.com>;mediaenc=srtp-mandf
27  \endverbatim
28  *
29  *
30  * Internally the protocol stack diagram looks something like this:
31  *
32  \verbatim
33  *                    application
34  *                        |
35  *                        |
36  *            [DTLS]   [SRTP]
37  *                \      /
38  *                 \    /
39  *                  \  /
40  *                   \/
41  *              ( TURN/ICE )
42  *                   |
43  *                   |
44  *                [socket]
45  \endverbatim
46  *
47  */
48 
49 struct menc_sess {
50 	struct sdp_session *sdp;
51 	bool offerer;
52 	menc_error_h *errorh;
53 	void *arg;
54 };
55 
56 /* media */
57 struct dtls_srtp {
58 	struct comp compv[2];
59 	const struct menc_sess *sess;
60 	struct sdp_media *sdpm;
61 	struct tmr tmr;
62 	bool started;
63 	bool active;
64 	bool mux;
65 };
66 
67 static struct tls *tls;
68 static const char* srtp_profiles =
69 	"SRTP_AES128_CM_SHA1_80:"
70 	"SRTP_AES128_CM_SHA1_32";
71 
72 
sess_destructor(void * arg)73 static void sess_destructor(void *arg)
74 {
75 	struct menc_sess *sess = arg;
76 
77 	mem_deref(sess->sdp);
78 }
79 
80 
destructor(void * arg)81 static void destructor(void *arg)
82 {
83 	struct dtls_srtp *st = arg;
84 	size_t i;
85 
86 	tmr_cancel(&st->tmr);
87 
88 	for (i=0; i<2; i++) {
89 		struct comp *c = &st->compv[i];
90 
91 		mem_deref(c->uh_srtp);
92 		mem_deref(c->tls_conn);
93 		mem_deref(c->dtls_sock);
94 		mem_deref(c->app_sock);  /* must be freed last */
95 		mem_deref(c->tx);
96 		mem_deref(c->rx);
97 	}
98 
99 	mem_deref(st->sdpm);
100 }
101 
102 
verify_fingerprint(const struct sdp_session * sess,const struct sdp_media * media,struct tls_conn * tc)103 static bool verify_fingerprint(const struct sdp_session *sess,
104 			       const struct sdp_media *media,
105 			       struct tls_conn *tc)
106 {
107 	struct pl hash;
108 	uint8_t md_sdp[32], md_dtls[32];
109 	size_t sz_sdp = sizeof(md_sdp);
110 	size_t sz_dtls;
111 	enum tls_fingerprint type;
112 	int err;
113 
114 	if (sdp_fingerprint_decode(sdp_media_session_rattr(media, sess,
115 							   "fingerprint"),
116 				   &hash, md_sdp, &sz_sdp))
117 		return false;
118 
119 	if (0 == pl_strcasecmp(&hash, "sha-1")) {
120 		type = TLS_FINGERPRINT_SHA1;
121 		sz_dtls = 20;
122 	}
123 	else if (0 == pl_strcasecmp(&hash, "sha-256")) {
124 		type = TLS_FINGERPRINT_SHA256;
125 		sz_dtls = 32;
126 	}
127 	else {
128 		warning("dtls_srtp: unknown fingerprint '%r'\n", &hash);
129 		return false;
130 	}
131 
132 	err = tls_peer_fingerprint(tc, type, md_dtls, sizeof(md_dtls));
133 	if (err) {
134 		warning("dtls_srtp: could not get DTLS fingerprint (%m)\n",
135 			err);
136 		return false;
137 	}
138 
139 	if (sz_sdp != sz_dtls || 0 != memcmp(md_sdp, md_dtls, sz_sdp)) {
140 		warning("dtls_srtp: %r fingerprint mismatch\n", &hash);
141 		info("SDP:  %w\n", md_sdp, sz_sdp);
142 		info("DTLS: %w\n", md_dtls, sz_dtls);
143 		return false;
144 	}
145 
146 	info("dtls_srtp: verified %r fingerprint OK\n", &hash);
147 
148 	return true;
149 }
150 
151 
session_alloc(struct menc_sess ** sessp,struct sdp_session * sdp,bool offerer,menc_error_h * errorh,void * arg)152 static int session_alloc(struct menc_sess **sessp,
153 			 struct sdp_session *sdp, bool offerer,
154 			 menc_error_h *errorh, void *arg)
155 {
156 	struct menc_sess *sess;
157 	int err;
158 
159 	if (!sessp || !sdp)
160 		return EINVAL;
161 
162 	sess = mem_zalloc(sizeof(*sess), sess_destructor);
163 	if (!sess)
164 		return ENOMEM;
165 
166 	sess->sdp     = mem_ref(sdp);
167 	sess->offerer = offerer;
168 	sess->errorh  = errorh;
169 	sess->arg     = arg;
170 
171 	/* RFC 4145 */
172 	err = sdp_session_set_lattr(sdp, true, "setup",
173 				    offerer ? "actpass" : "active");
174 	if (err)
175 		goto out;
176 
177 	/* RFC 4572 */
178 	err = sdp_session_set_lattr(sdp, true, "fingerprint", "SHA-256 %H",
179 				    dtls_print_sha256_fingerprint, tls);
180 	if (err)
181 		goto out;
182 
183  out:
184 	if (err)
185 		mem_deref(sess);
186 	else
187 		*sessp = sess;
188 
189 	return err;
190 }
191 
192 
dtls_estab_handler(void * arg)193 static void dtls_estab_handler(void *arg)
194 {
195 	struct comp *comp = arg;
196 	const struct dtls_srtp *ds = comp->ds;
197 	enum srtp_suite suite;
198 	uint8_t cli_key[30], srv_key[30];
199 	int err;
200 
201 	if (!verify_fingerprint(ds->sess->sdp, ds->sdpm, comp->tls_conn)) {
202 		warning("dtls_srtp: could not verify remote fingerprint\n");
203 		if (ds->sess->errorh)
204 			ds->sess->errorh(EPIPE, ds->sess->arg);
205 		return;
206 	}
207 
208 	err = tls_srtp_keyinfo(comp->tls_conn, &suite,
209 			       cli_key, sizeof(cli_key),
210 			       srv_key, sizeof(srv_key));
211 	if (err) {
212 		warning("dtls_srtp: could not get SRTP keyinfo (%m)\n", err);
213 		return;
214 	}
215 
216 	comp->negotiated = true;
217 
218 	info("dtls_srtp: ---> DTLS-SRTP complete (%s/%s) Profile=%s\n",
219 	     sdp_media_name(ds->sdpm),
220 	     comp->is_rtp ? "RTP" : "RTCP", srtp_suite_name(suite));
221 
222 	err |= srtp_stream_add(&comp->tx, suite,
223 			       ds->active ? cli_key : srv_key, 30, true);
224 	err |= srtp_stream_add(&comp->rx, suite,
225 			       ds->active ? srv_key : cli_key, 30, false);
226 
227 	err |= srtp_install(comp);
228 	if (err) {
229 		warning("dtls_srtp: srtp_install: %m\n", err);
230 	}
231 
232 	/* todo: notify application that crypto is up and running */
233 }
234 
235 
dtls_close_handler(int err,void * arg)236 static void dtls_close_handler(int err, void *arg)
237 {
238 	struct comp *comp = arg;
239 
240 	info("dtls_srtp: dtls-connection closed (%m)\n", err);
241 
242 	comp->tls_conn = mem_deref(comp->tls_conn);
243 
244 	if (!comp->negotiated) {
245 
246 		if (comp->ds->sess->errorh)
247 			comp->ds->sess->errorh(err, comp->ds->sess->arg);
248 	}
249 }
250 
251 
dtls_conn_handler(const struct sa * peer,void * arg)252 static void dtls_conn_handler(const struct sa *peer, void *arg)
253 {
254 	struct comp *comp = arg;
255 	int err;
256 	(void)peer;
257 
258 	info("dtls_srtp: incoming DTLS connect from %J\n", peer);
259 
260 	err = dtls_accept(&comp->tls_conn, tls, comp->dtls_sock,
261 			  dtls_estab_handler, NULL, dtls_close_handler, comp);
262 	if (err) {
263 		warning("dtls_srtp: dtls_accept failed (%m)\n", err);
264 		return;
265 	}
266 }
267 
268 
component_start(struct comp * comp,struct sdp_media * sdpm)269 static int component_start(struct comp *comp, struct sdp_media *sdpm)
270 {
271 	struct sa raddr;
272 	int err = 0;
273 
274 	if (!comp->app_sock || comp->negotiated || comp->dtls_sock)
275 		return 0;
276 
277 	if (comp->is_rtp)
278 		raddr = *sdp_media_raddr(sdpm);
279 	else
280 		sdp_media_raddr_rtcp(sdpm, &raddr);
281 
282 	err = dtls_listen(&comp->dtls_sock, NULL,
283 			  comp->app_sock, 2, LAYER_DTLS,
284 			  dtls_conn_handler, comp);
285 	if (err) {
286 		warning("dtls_srtp: dtls_listen failed (%m)\n", err);
287 		return err;
288 	}
289 
290 	if (sa_isset(&raddr, SA_ALL)) {
291 
292 		if (comp->ds->active && !comp->tls_conn) {
293 
294 			err = dtls_connect(&comp->tls_conn, tls,
295 					   comp->dtls_sock, &raddr,
296 					   dtls_estab_handler, NULL,
297 					   dtls_close_handler, comp);
298 			if (err) {
299 				warning("dtls_srtp: dtls_connect()"
300 					" failed (%m)\n", err);
301 				return err;
302 			}
303 		}
304 	}
305 
306 	return err;
307 }
308 
309 
media_start(struct dtls_srtp * st,struct sdp_media * sdpm)310 static int media_start(struct dtls_srtp *st, struct sdp_media *sdpm)
311 {
312 	int err = 0;
313 
314 	if (st->started)
315 		return 0;
316 
317 	info("dtls_srtp: media=%s -- start DTLS %s\n",
318 	     sdp_media_name(sdpm), st->active ? "client" : "server");
319 
320 	if (!sdp_media_has_media(sdpm))
321 		return 0;
322 
323 	err = component_start(&st->compv[0], sdpm);
324 
325 	if (!st->mux)
326 		err |= component_start(&st->compv[1], sdpm);
327 
328 	if (err)
329 		return err;
330 
331 	st->started = true;
332 
333 	return 0;
334 }
335 
336 
timeout(void * arg)337 static void timeout(void *arg)
338 {
339 	struct dtls_srtp *st = arg;
340 
341 	media_start(st, st->sdpm);
342 }
343 
344 
media_alloc(struct menc_media ** mp,struct menc_sess * sess,struct rtp_sock * rtp,int proto,void * rtpsock,void * rtcpsock,struct sdp_media * sdpm)345 static int media_alloc(struct menc_media **mp, struct menc_sess *sess,
346 		       struct rtp_sock *rtp, int proto,
347 		       void *rtpsock, void *rtcpsock,
348 		       struct sdp_media *sdpm)
349 {
350 	struct dtls_srtp *st;
351 	const char *setup, *fingerprint;
352 	int err = 0;
353 	unsigned i;
354 	(void)rtp;
355 
356 	if (!mp || !sess || proto != IPPROTO_UDP)
357 		return EINVAL;
358 
359 	st = (struct dtls_srtp *)*mp;
360 	if (st)
361 		goto setup;
362 
363 	st = mem_zalloc(sizeof(*st), destructor);
364 	if (!st)
365 		return ENOMEM;
366 
367 	st->sess = sess;
368 	st->sdpm = mem_ref(sdpm);
369 	st->compv[0].app_sock = mem_ref(rtpsock);
370 	st->compv[1].app_sock = mem_ref(rtcpsock);
371 
372 	for (i=0; i<2; i++)
373 		st->compv[i].ds = st;
374 
375 	st->compv[0].is_rtp = true;
376 	st->compv[1].is_rtp = false;
377 
378 	err = sdp_media_set_alt_protos(st->sdpm, 4,
379 				       "RTP/SAVP",
380 				       "RTP/SAVPF",
381 				       "UDP/TLS/RTP/SAVP",
382 				       "UDP/TLS/RTP/SAVPF");
383 	if (err)
384 		goto out;
385 
386  out:
387 	if (err) {
388 		mem_deref(st);
389 		return err;
390 	}
391 	else
392 		*mp = (struct menc_media *)st;
393 
394  setup:
395 	st->mux = (rtpsock == rtcpsock) || (rtcpsock == NULL);
396 
397 	setup = sdp_media_session_rattr(st->sdpm, st->sess->sdp, "setup");
398 	if (setup) {
399 		st->active = !(0 == str_casecmp(setup, "active"));
400 
401 		/* note: we need to wait for ICE to settle ... */
402 		tmr_start(&st->tmr, 100, timeout, st);
403 	}
404 
405 	/* SDP offer/answer on fingerprint attribute */
406 	fingerprint = sdp_media_session_rattr(st->sdpm, st->sess->sdp,
407 					      "fingerprint");
408 	if (fingerprint) {
409 
410 		struct pl hash;
411 
412 		err = sdp_fingerprint_decode(fingerprint, &hash, NULL, NULL);
413 		if (err)
414 			return err;
415 
416 		if (0 == pl_strcasecmp(&hash, "SHA-1")) {
417 			err = sdp_media_set_lattr(st->sdpm, true,
418 						  "fingerprint", "SHA-1 %H",
419 						  dtls_print_sha1_fingerprint,
420 						  tls);
421 		}
422 		else if (0 == pl_strcasecmp(&hash, "SHA-256")) {
423 			err = sdp_media_set_lattr(st->sdpm, true,
424 						  "fingerprint", "SHA-256 %H",
425 						 dtls_print_sha256_fingerprint,
426 						  tls);
427 		}
428 		else {
429 			info("dtls_srtp: unsupported fingerprint hash `%r'\n",
430 			     &hash);
431 			return EPROTO;
432 		}
433 	}
434 
435 	return err;
436 }
437 
438 
439 static struct menc dtls_srtp = {
440 	LE_INIT, "dtls_srtp",  "UDP/TLS/RTP/SAVP", session_alloc, media_alloc
441 };
442 
443 static struct menc dtls_srtpf = {
444 	LE_INIT, "dtls_srtpf", "UDP/TLS/RTP/SAVPF", session_alloc, media_alloc
445 };
446 
447 static struct menc dtls_srtp2 = {
448 	/* note: temp for Webrtc interop */
449 	LE_INIT, "srtp-mandf", "RTP/SAVPF", session_alloc, media_alloc
450 };
451 
452 
module_init(void)453 static int module_init(void)
454 {
455 	struct list *mencl = baresip_mencl();
456 	int err;
457 
458 	err = tls_alloc(&tls, TLS_METHOD_DTLSV1, NULL, NULL);
459 	if (err) {
460 		warning("dtls_srtp: failed to create DTLS context (%m)\n",
461 			err);
462 		return err;
463 	}
464 
465 	err = tls_set_selfsigned(tls, "dtls@baresip");
466 	if (err) {
467 		warning("dtls_srtp: failed to self-sign certificate (%m)\n",
468 			err);
469 		return err;
470 	}
471 
472 	tls_set_verify_client(tls);
473 
474 	err = tls_set_srtp(tls, srtp_profiles);
475 	if (err) {
476 		warning("dtls_srtp: failed to enable SRTP profile (%m)\n",
477 			err);
478 		return err;
479 	}
480 
481 	menc_register(mencl, &dtls_srtpf);
482 	menc_register(mencl, &dtls_srtp);
483 	menc_register(mencl, &dtls_srtp2);
484 
485 	debug("DTLS-SRTP ready with profiles %s\n", srtp_profiles);
486 
487 	return 0;
488 }
489 
490 
module_close(void)491 static int module_close(void)
492 {
493 	menc_unregister(&dtls_srtp);
494 	menc_unregister(&dtls_srtpf);
495 	menc_unregister(&dtls_srtp2);
496 	tls = mem_deref(tls);
497 
498 	return 0;
499 }
500 
501 
502 EXPORT_SYM const struct mod_export DECL_EXPORTS(dtls_srtp) = {
503 	"dtls_srtp",
504 	"menc",
505 	module_init,
506 	module_close
507 };
508