Asterisk - The Open Source Telephony Project GIT-master-f36a736
Data Structures | Functions | Variables
res_srtp.c File Reference

Secure RTP (SRTP) More...

#include "asterisk.h"
#include <math.h>
#include <srtp/srtp.h>
#include <srtp/crypto_kernel.h>
#include "asterisk/astobj2.h"
#include "asterisk/frame.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/sdp_srtp.h"
#include "asterisk/res_srtp.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/utils.h"
Include dependency graph for res_srtp.c:

Go to the source code of this file.

Data Structures

struct  ast_sdp_crypto
 
struct  ast_srtp
 
struct  ast_srtp_policy
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int ast_srtp_add_stream (struct ast_srtp *srtp, struct ast_srtp_policy *policy)
 
static int ast_srtp_change_source (struct ast_srtp *srtp, unsigned int from_ssrc, unsigned int to_ssrc)
 
static int ast_srtp_create (struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy)
 
static void ast_srtp_destroy (struct ast_srtp *srtp)
 
static int ast_srtp_get_random (unsigned char *key, size_t len)
 
static struct ast_srtp_policyast_srtp_policy_alloc (void)
 
static void ast_srtp_policy_destroy (struct ast_srtp_policy *policy)
 
static int ast_srtp_policy_set_master_key (struct ast_srtp_policy *policy, const unsigned char *key, size_t key_len, const unsigned char *salt, size_t salt_len)
 
static void ast_srtp_policy_set_ssrc (struct ast_srtp_policy *policy, unsigned long ssrc, int inbound)
 
static int ast_srtp_policy_set_suite (struct ast_srtp_policy *policy, enum ast_srtp_suite suite)
 
static int ast_srtp_protect (struct ast_srtp *srtp, void **buf, int *len, int rtcp)
 
static int ast_srtp_replace (struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy)
 
static void ast_srtp_set_cb (struct ast_srtp *srtp, const struct ast_srtp_cb *cb, void *data)
 
static int ast_srtp_unprotect (struct ast_srtp *srtp, void *buf, int *len, int rtcp)
 
static int crypto_activate (struct ast_sdp_crypto *p, int suite_val, unsigned char *remote_key, int key_len, struct ast_rtp_instance *rtp)
 
static struct ast_sdp_cryptocrypto_init_keys (struct ast_sdp_crypto *p, const int key_len)
 
static struct ast_srtp_policyfind_policy (struct ast_srtp *srtp, const srtp_policy_t *policy, int flags)
 
static int load_module (void)
 
static int policy_cmp_fn (void *obj, void *arg, int flags)
 
static void policy_destructor (void *obj)
 
static int policy_hash_fn (const void *obj, const int flags)
 
static int policy_set_suite (crypto_policy_t *p, enum ast_srtp_suite suite)
 
static struct ast_sdp_cryptores_sdp_crypto_alloc (void)
 
static int res_sdp_crypto_build_offer (struct ast_sdp_crypto *p, int taglen)
 
static void res_sdp_crypto_dtor (struct ast_sdp_crypto *crypto)
 
static int res_sdp_crypto_parse_offer (struct ast_rtp_instance *rtp, struct ast_sdp_srtp *srtp, const char *attr)
 
static const char * res_sdp_srtp_get_attr (struct ast_sdp_srtp *srtp, int dtls_enabled, int default_taglen_32)
 
static int res_srtp_init (void)
 
static struct ast_srtpres_srtp_new (void)
 
static void res_srtp_shutdown (void)
 
static struct ast_sdp_cryptosdp_crypto_alloc (const int key_len)
 
static int set_crypto_policy (struct ast_srtp_policy *policy, int suite_val, const unsigned char *master_key, int key_len, unsigned long ssrc, int inbound)
 
static const char * srtp_errstr (int err)
 
static void srtp_event_cb (srtp_event_data_t *data)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Secure RTP (SRTP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static int g_initialized = 0
 
static struct ast_srtp_policy_res policy_res
 
static struct ast_sdp_crypto_api res_sdp_crypto_api
 
static struct ast_srtp_res srtp_res
 

Detailed Description

Secure RTP (SRTP)

Secure RTP (SRTP) Specified in RFC 3711.

Author
Mikael Magnusson mikma.nosp@m.@use.nosp@m.rs.so.nosp@m.urce.nosp@m.forge.nosp@m..net

Definition in file res_srtp.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1286 of file res_srtp.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1286 of file res_srtp.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1286 of file res_srtp.c.

◆ ast_srtp_add_stream()

static int ast_srtp_add_stream ( struct ast_srtp srtp,
struct ast_srtp_policy policy 
)
static

Definition at line 575 of file res_srtp.c.

576{
577 struct ast_srtp_policy *match;
578
579 /* For existing streams, replace if its an SSRC stream, or bail if its a wildcard */
580 if ((match = find_policy(srtp, &policy->sp, OBJ_POINTER))) {
581 if (policy->sp.ssrc.type != ssrc_specific) {
582 ast_log(AST_LOG_WARNING, "Cannot replace an existing wildcard policy\n");
583 ao2_t_ref(match, -1, "Unreffing already existing policy");
584 return -1;
585 } else {
586 if (srtp_remove_stream(srtp->session, match->sp.ssrc.value) != err_status_ok) {
587 ast_log(AST_LOG_WARNING, "Failed to remove SRTP stream for SSRC %u\n", match->sp.ssrc.value);
588 }
589 ao2_t_unlink(srtp->policies, match, "Remove existing match policy");
590 ao2_t_ref(match, -1, "Unreffing already existing policy");
591 }
592 }
593
594 ast_debug(3, "Adding new policy for %s %u\n",
595 policy->sp.ssrc.type == ssrc_specific ? "SSRC" : "type",
596 policy->sp.ssrc.type == ssrc_specific ? policy->sp.ssrc.value : policy->sp.ssrc.type);
597 if (srtp_add_stream(srtp->session, &policy->sp) != err_status_ok) {
598 ast_log(AST_LOG_WARNING, "Failed to add SRTP stream for %s %u\n",
599 policy->sp.ssrc.type == ssrc_specific ? "SSRC" : "type",
600 policy->sp.ssrc.type == ssrc_specific ? policy->sp.ssrc.value : policy->sp.ssrc.type);
601 return -1;
602 }
603
604 ao2_t_link(srtp->policies, policy, "Added additional stream");
605
606 return 0;
607}
#define ast_log
Definition: astobj2.c:42
#define ao2_t_ref(o, delta, tag)
Definition: astobj2.h:460
#define OBJ_POINTER
Definition: astobj2.h:1150
#define ao2_t_link(container, obj, tag)
Definition: astobj2.h:1534
#define ao2_t_unlink(container, obj, tag)
Definition: astobj2.h:1580
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2362
#define AST_LOG_WARNING
#define ast_debug(level,...)
Log a DEBUG message.
static struct ast_srtp_policy * find_policy(struct ast_srtp *srtp, const srtp_policy_t *policy, int flags)
Definition: res_srtp.c:177
#define err_status_ok
Definition: srtp_compat.h:32
srtp_policy_t sp
Definition: res_srtp.c:78
struct ao2_container * policies
Definition: res_srtp.c:68
srtp_t session
Definition: res_srtp.c:69

References ao2_t_link, ao2_t_ref, ao2_t_unlink, ast_debug, ast_log, AST_LOG_WARNING, err_status_ok, find_policy(), match(), OBJ_POINTER, ast_srtp::policies, ast_srtp::session, and ast_srtp_policy::sp.

Referenced by ast_srtp_change_source().

◆ ast_srtp_change_source()

static int ast_srtp_change_source ( struct ast_srtp srtp,
unsigned int  from_ssrc,
unsigned int  to_ssrc 
)
static

Definition at line 609 of file res_srtp.c.

610{
611 struct ast_srtp_policy *match;
612 struct srtp_policy_t sp = {
613 .ssrc.type = ssrc_specific,
614 .ssrc.value = from_ssrc,
615 };
617
618 /* If we find a match, return and unlink it from the container so we
619 * can change the SSRC (which is part of the hash) and then have
620 * ast_srtp_add_stream link it back in if all is well */
621 if ((match = find_policy(srtp, &sp, OBJ_POINTER | OBJ_UNLINK))) {
622 match->sp.ssrc.value = to_ssrc;
623 if (ast_srtp_add_stream(srtp, match)) {
624 ast_log(LOG_WARNING, "Couldn't add stream\n");
625 } else if ((status = srtp_remove_stream(srtp->session, from_ssrc))) {
626 ast_debug(3, "Couldn't remove stream (%u)\n", status);
627 }
628 ao2_t_ref(match, -1, "Unreffing found policy in change_source");
629 }
630
631 return 0;
632}
jack_status_t status
Definition: app_jack.c:146
@ OBJ_UNLINK
Definition: astobj2.h:1039
#define LOG_WARNING
static int ast_srtp_add_stream(struct ast_srtp *srtp, struct ast_srtp_policy *policy)
Definition: res_srtp.c:575
#define err_status_t
Definition: srtp_compat.h:31

References ao2_t_ref, ast_debug, ast_log, ast_srtp_add_stream(), err_status_t, find_policy(), LOG_WARNING, match(), OBJ_POINTER, OBJ_UNLINK, ast_srtp::session, and status.

◆ ast_srtp_create()

static int ast_srtp_create ( struct ast_srtp **  srtp,
struct ast_rtp_instance rtp,
struct ast_srtp_policy policy 
)
static

Definition at line 516 of file res_srtp.c.

517{
518 struct ast_srtp *temp;
519 int status;
520
521 if (!(temp = res_srtp_new())) {
522 return -1;
523 }
525
526 /* Any failures after this point can use ast_srtp_destroy to destroy the instance */
527 status = srtp_create(&temp->session, &policy->sp);
528 if (status != err_status_ok) {
529 /* Session either wasn't created or was created and dealloced. */
530 temp->session = NULL;
531 ast_srtp_destroy(temp);
532 ast_log(LOG_ERROR, "Failed to create srtp session on rtp instance (%p) - %s\n",
534 return -1;
535 }
536
537 temp->rtp = rtp;
538 *srtp = temp;
539
540 ao2_t_link((*srtp)->policies, policy, "Created initial policy");
541
542 return 0;
543}
#define LOG_ERROR
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:457
static const char * srtp_errstr(int err)
Definition: res_srtp.c:123
static struct ast_srtp * res_srtp_new(void)
Definition: res_srtp.c:189
static void ast_srtp_destroy(struct ast_srtp *srtp)
Definition: res_srtp.c:562
#define NULL
Definition: resample.c:96
struct ast_module * self
Definition: module.h:356
struct ast_rtp_instance * rtp
Definition: res_srtp.c:67

References ao2_t_link, ast_log, ast_module_ref, ast_srtp_destroy(), err_status_ok, LOG_ERROR, NULL, res_srtp_new(), ast_srtp::rtp, ast_module_info::self, ast_srtp::session, ast_srtp_policy::sp, srtp_errstr(), and status.

Referenced by ast_srtp_replace().

◆ ast_srtp_destroy()

static void ast_srtp_destroy ( struct ast_srtp srtp)
static

Definition at line 562 of file res_srtp.c.

563{
564 if (srtp->session) {
565 srtp_dealloc(srtp->session);
566 }
567
568 ao2_t_callback(srtp->policies, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "Unallocate policy");
569 ao2_t_ref(srtp->policies, -1, "Destroying container");
570
571 ast_free(srtp);
573}
#define ast_free(a)
Definition: astmm.h:180
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
Definition: astobj2.h:1696
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:483

References ao2_t_callback, ao2_t_ref, ast_free, ast_module_unref, NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, ast_srtp::policies, ast_module_info::self, and ast_srtp::session.

Referenced by ast_srtp_create(), and ast_srtp_replace().

◆ ast_srtp_get_random()

static int ast_srtp_get_random ( unsigned char *  key,
size_t  len 
)
static

Definition at line 349 of file res_srtp.c.

350{
351#ifdef HAVE_OPENSSL
352 return RAND_bytes(key, len) > 0 ? 0: -1;
353#else
354 return crypto_get_random(key, len) != err_status_ok ? -1: 0;
355#endif
356}
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

References err_status_ok, and len().

◆ ast_srtp_policy_alloc()

static struct ast_srtp_policy * ast_srtp_policy_alloc ( void  )
static

Definition at line 252 of file res_srtp.c.

253{
254 struct ast_srtp_policy *tmp;
255
256 if (!(tmp = ao2_t_alloc(sizeof(*tmp), policy_destructor, "Allocating policy"))) {
257 ast_log(LOG_ERROR, "Unable to allocate memory for srtp_policy\n");
258 }
259
260 return tmp;
261}
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
Definition: astobj2.h:407
static int tmp()
Definition: bt_open.c:389
static void policy_destructor(void *obj)
Definition: res_srtp.c:242

References ao2_t_alloc, ast_log, LOG_ERROR, policy_destructor(), and tmp().

◆ ast_srtp_policy_destroy()

static void ast_srtp_policy_destroy ( struct ast_srtp_policy policy)
static

Definition at line 263 of file res_srtp.c.

264{
265 ao2_t_ref(policy, -1, "Destroying policy");
266}

References ao2_t_ref.

◆ ast_srtp_policy_set_master_key()

static int ast_srtp_policy_set_master_key ( struct ast_srtp_policy policy,
const unsigned char *  key,
size_t  key_len,
const unsigned char *  salt,
size_t  salt_len 
)
static

Definition at line 327 of file res_srtp.c.

328{
329 size_t size = key_len + salt_len;
330 unsigned char *master_key;
331
332 if (policy->sp.key) {
333 ast_free(policy->sp.key);
334 policy->sp.key = NULL;
335 }
336
337 if (!(master_key = ast_calloc(1, size))) {
338 return -1;
339 }
340
341 memcpy(master_key, key, key_len);
342 memcpy(master_key + key_len, salt, salt_len);
343
344 policy->sp.key = master_key;
345
346 return 0;
347}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202

References ast_calloc, ast_free, NULL, and ast_srtp_policy::sp.

◆ ast_srtp_policy_set_ssrc()

static void ast_srtp_policy_set_ssrc ( struct ast_srtp_policy policy,
unsigned long  ssrc,
int  inbound 
)
static

Definition at line 231 of file res_srtp.c.

233{
234 if (ssrc) {
235 policy->sp.ssrc.type = ssrc_specific;
236 policy->sp.ssrc.value = ssrc;
237 } else {
238 policy->sp.ssrc.type = inbound ? ssrc_any_inbound : ssrc_any_outbound;
239 }
240}

References ast_srtp_policy::sp.

◆ ast_srtp_policy_set_suite()

static int ast_srtp_policy_set_suite ( struct ast_srtp_policy policy,
enum ast_srtp_suite  suite 
)
static

Definition at line 322 of file res_srtp.c.

323{
324 return policy_set_suite(&policy->sp.rtp, suite) | policy_set_suite(&policy->sp.rtcp, suite);
325}
static int policy_set_suite(crypto_policy_t *p, enum ast_srtp_suite suite)
Definition: res_srtp.c:268

References policy_set_suite(), and ast_srtp_policy::sp.

◆ ast_srtp_protect()

static int ast_srtp_protect ( struct ast_srtp srtp,
void **  buf,
int *  len,
int  rtcp 
)
static

Definition at line 488 of file res_srtp.c.

489{
490 int res;
491 unsigned char *localbuf;
492
493 if (!srtp->session) {
494 ast_log(LOG_ERROR, "SRTP protect %s - missing session\n", rtcp ? "rtcp" : "rtp");
495 errno = EINVAL;
496 return -1;
497 }
498
499 if ((*len + SRTP_MAX_TRAILER_LEN) > sizeof(srtp->buf)) {
500 return -1;
501 }
502
503 localbuf = rtcp ? srtp->rtcpbuf : srtp->buf;
504
505 memcpy(localbuf, *buf, *len);
506
507 if ((res = rtcp ? srtp_protect_rtcp(srtp->session, localbuf, len) : srtp_protect(srtp->session, localbuf, len)) != err_status_ok && res != err_status_replay_fail) {
508 ast_log(LOG_WARNING, "SRTP protect: %s\n", srtp_errstr(res));
509 return -1;
510 }
511
512 *buf = localbuf;
513 return *len;
514}
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int errno
#define err_status_replay_fail
Definition: srtp_compat.h:41
unsigned char buf[8192+AST_FRIENDLY_OFFSET]
Definition: res_srtp.c:73
unsigned char rtcpbuf[8192+AST_FRIENDLY_OFFSET]
Definition: res_srtp.c:74

References ast_log, ast_srtp::buf, buf, err_status_ok, err_status_replay_fail, errno, len(), LOG_ERROR, LOG_WARNING, ast_srtp::rtcpbuf, ast_srtp::session, and srtp_errstr().

◆ ast_srtp_replace()

static int ast_srtp_replace ( struct ast_srtp **  srtp,
struct ast_rtp_instance rtp,
struct ast_srtp_policy policy 
)
static

Definition at line 545 of file res_srtp.c.

546{
547 struct ast_srtp *old = *srtp;
548 int res = ast_srtp_create(srtp, rtp, policy);
549
550 if (!res && old) {
551 ast_srtp_destroy(old);
552 }
553
554 if (res) {
555 ast_log(LOG_ERROR, "Failed to replace srtp (%p) on rtp instance (%p) "
556 "- keeping old\n", *srtp, rtp);
557 }
558
559 return res;
560}
static int ast_srtp_create(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy)
Definition: res_srtp.c:516

References ast_log, ast_srtp_create(), ast_srtp_destroy(), LOG_ERROR, and ast_srtp::rtp.

◆ ast_srtp_set_cb()

static void ast_srtp_set_cb ( struct ast_srtp srtp,
const struct ast_srtp_cb cb,
void *  data 
)
static

Definition at line 358 of file res_srtp.c.

359{
360 if (!srtp) {
361 return;
362 }
363
364 srtp->cb = cb;
365 srtp->data = data;
366}
void * data
Definition: res_srtp.c:71
const struct ast_srtp_cb * cb
Definition: res_srtp.c:70

References ast_srtp::cb, and ast_srtp::data.

◆ ast_srtp_unprotect()

static int ast_srtp_unprotect ( struct ast_srtp srtp,
void *  buf,
int *  len,
int  rtcp 
)
static

Definition at line 369 of file res_srtp.c.

370{
371 int res = 0;
372 int i;
373 int rtcp = (flags & 0x01) >> 0;
374 int retry = (flags & 0x02) >> 1;
375 struct ast_rtp_instance_stats stats = {0,};
376
377tryagain:
378
379 if (!srtp->session) {
380 ast_log(LOG_ERROR, "SRTP unprotect %s - missing session\n", rtcp ? "rtcp" : "rtp");
381 errno = EINVAL;
382 return -1;
383 }
384
385 for (i = 0; i < 2; i++) {
386 res = rtcp ? srtp_unprotect_rtcp(srtp->session, buf, len) : srtp_unprotect(srtp->session, buf, len);
387 if (res != err_status_no_ctx) {
388 break;
389 }
390
391 if (srtp->cb && srtp->cb->no_ctx) {
393 break;
394 }
395 if (srtp->cb->no_ctx(srtp->rtp, stats.remote_ssrc, srtp->data) < 0) {
396 break;
397 }
398 } else {
399 break;
400 }
401 }
402
403 if (retry == 0 && res == err_status_replay_old) {
404 ast_log(AST_LOG_NOTICE, "SRTP unprotect failed with %s, retrying\n", srtp_errstr(res));
405
406 if (srtp->session) {
407 struct ast_srtp_policy *policy;
408 struct ao2_iterator it;
409 int policies_count;
410
411 /* dealloc first */
412 ast_debug(5, "SRTP destroy before re-create\n");
413 srtp_dealloc(srtp->session);
414
415 /* get the count */
416 policies_count = ao2_container_count(srtp->policies);
417
418 /* get the first to build up */
419 it = ao2_iterator_init(srtp->policies, 0);
420 policy = ao2_iterator_next(&it);
421
422 ast_debug(5, "SRTP try to re-create\n");
423 if (policy) {
424 int res_srtp_create = srtp_create(&srtp->session, &policy->sp);
425 if (res_srtp_create == err_status_ok) {
426 ast_debug(5, "SRTP re-created with first policy\n");
427 ao2_t_ref(policy, -1, "Unreffing first policy for re-creating srtp session");
428
429 /* if we have more than one policy, add them */
430 if (policies_count > 1) {
431 ast_debug(5, "Add all the other %d policies\n",
432 policies_count - 1);
433 while ((policy = ao2_iterator_next(&it))) {
434 srtp_add_stream(srtp->session, &policy->sp);
435 ao2_t_ref(policy, -1, "Unreffing n-th policy for re-creating srtp session");
436 }
437 }
438
439 retry++;
441 goto tryagain;
442 }
443 ast_log(LOG_ERROR, "SRTP session could not be re-created after unprotect failure: %s\n", srtp_errstr(res_srtp_create));
444
445 /* If srtp_create() fails with a previously alloced session, it will have been dealloced before returning. */
446 srtp->session = NULL;
447
448 ao2_t_ref(policy, -1, "Unreffing first policy after srtp_create failed");
449 }
451 }
452 }
453
454 if (!srtp->session) {
455 errno = EINVAL;
456 return -1;
457 }
458
459 if (res != err_status_ok && res != err_status_replay_fail ) {
460 /*
461 * Authentication failures happen when an active attacker tries to
462 * insert malicious RTP packets. Furthermore, authentication failures
463 * happen, when the other party encrypts the sRTP data in an unexpected
464 * way. This happens quite often with RTCP. Therefore, when you see
465 * authentication failures, try to identify the implementation
466 * (author and product name) used by your other party. Try to investigate
467 * whether they use a custom library or an outdated version of libSRTP.
468 */
469 if (rtcp) {
470 ast_verb(2, "SRTCP unprotect failed on SSRC %u because of %s\n",
472 } else {
473 if ((srtp->warned >= 10) && !((srtp->warned - 10) % 150)) {
474 ast_verb(2, "SRTP unprotect failed on SSRC %u because of %s %d\n",
475 ast_rtp_instance_get_ssrc(srtp->rtp), srtp_errstr(res), srtp->warned);
476 srtp->warned = 11;
477 } else {
478 srtp->warned++;
479 }
480 }
481 errno = EAGAIN;
482 return -1;
483 }
484
485 return *len;
486}
static struct ast_mansession session
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define AST_LOG_NOTICE
#define ast_verb(level,...)
@ AST_RTP_INSTANCE_STAT_REMOTE_SSRC
Definition: rtp_engine.h:251
int ast_rtp_instance_get_stats(struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
Retrieve statistics about an RTP instance.
Definition: rtp_engine.c:2622
unsigned int ast_rtp_instance_get_ssrc(struct ast_rtp_instance *rtp)
Retrieve the local SSRC value that we will be using.
Definition: rtp_engine.c:4011
#define err_status_replay_old
Definition: srtp_compat.h:42
#define err_status_no_ctx
Definition: srtp_compat.h:45
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
unsigned int remote_ssrc
Definition: rtp_engine.h:454
int(* no_ctx)(struct ast_rtp_instance *rtp, unsigned long ssrc, void *data)
Definition: res_srtp.h:31
int warned
Definition: res_srtp.c:72

References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_t_ref, ast_debug, ast_log, AST_LOG_NOTICE, ast_rtp_instance_get_ssrc(), ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_REMOTE_SSRC, ast_verb, buf, ast_srtp::cb, ast_srtp::data, err_status_no_ctx, err_status_ok, err_status_replay_fail, err_status_replay_old, errno, len(), LOG_ERROR, ast_srtp_cb::no_ctx, NULL, ast_srtp::policies, ast_rtp_instance_stats::remote_ssrc, ast_srtp::rtp, ast_srtp::session, ast_srtp_policy::sp, srtp_errstr(), and ast_srtp::warned.

◆ crypto_activate()

static int crypto_activate ( struct ast_sdp_crypto p,
int  suite_val,
unsigned char *  remote_key,
int  key_len,
struct ast_rtp_instance rtp 
)
static

Definition at line 752 of file res_srtp.c.

753{
754 struct ast_srtp_policy *local_policy = NULL;
755 struct ast_srtp_policy *remote_policy = NULL;
756 struct ast_rtp_instance_stats stats = {0,};
757 int res = -1;
758
759 if (!p) {
760 return -1;
761 }
762
763 if (!(local_policy = policy_res.alloc())) {
764 return -1;
765 }
766
767 if (!(remote_policy = policy_res.alloc())) {
768 goto err;
769 }
770
772 goto err;
773 }
774
775 if (set_crypto_policy(local_policy, suite_val, p->local_key, key_len, stats.local_ssrc, 0) < 0) {
776 goto err;
777 }
778
779 if (set_crypto_policy(remote_policy, suite_val, remote_key, key_len, 0, 1) < 0) {
780 goto err;
781 }
782
783 /* Add the SRTP policies */
784 if (ast_rtp_instance_add_srtp_policy(rtp, remote_policy, local_policy, 0)) {
785 ast_log(LOG_WARNING, "Could not set SRTP policies\n");
786 goto err;
787 }
788
789 ast_debug(1 , "SRTP policy activated\n");
790 res = 0;
791
792err:
793 if (local_policy) {
794 policy_res.destroy(local_policy);
795 }
796
797 if (remote_policy) {
798 policy_res.destroy(remote_policy);
799 }
800
801 return res;
802}
static int set_crypto_policy(struct ast_srtp_policy *policy, int suite_val, const unsigned char *master_key, int key_len, unsigned long ssrc, int inbound)
Definition: res_srtp.c:736
static struct ast_srtp_policy_res policy_res
Definition: res_srtp.c:115
@ AST_RTP_INSTANCE_STAT_LOCAL_SSRC
Definition: rtp_engine.h:249
int ast_rtp_instance_add_srtp_policy(struct ast_rtp_instance *instance, struct ast_srtp_policy *remote_policy, struct ast_srtp_policy *local_policy, int rtcp)
Add or replace the SRTP policies for the given RTP instance.
Definition: rtp_engine.c:2936
unsigned int local_ssrc
Definition: rtp_engine.h:452
unsigned char local_key[SRTP_MAX_KEY_LEN]
Definition: res_srtp.c:636
void(* destroy)(struct ast_srtp_policy *policy)
Definition: res_srtp.h:72
struct ast_srtp_policy *(* alloc)(void)
Definition: res_srtp.h:71

References ast_srtp_policy_res::alloc, ast_debug, ast_log, ast_rtp_instance_add_srtp_policy(), ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_LOCAL_SSRC, ast_srtp_policy_res::destroy, ast_sdp_crypto::local_key, ast_rtp_instance_stats::local_ssrc, LOG_WARNING, NULL, policy_res, and set_crypto_policy().

Referenced by res_sdp_crypto_parse_offer().

◆ crypto_init_keys()

static struct ast_sdp_crypto * crypto_init_keys ( struct ast_sdp_crypto p,
const int  key_len 
)
static

Definition at line 654 of file res_srtp.c.

655{
656 unsigned char remote_key[key_len];
657
658 if (srtp_res.get_random(p->local_key, key_len) < 0) {
659 return NULL;
660 }
661
662 ast_base64encode(p->local_key64, p->local_key, key_len, sizeof(p->local_key64));
663
664 p->key_len = ast_base64decode(remote_key, p->local_key64, sizeof(remote_key));
665
666 if (p->key_len != key_len) {
667 ast_log(LOG_ERROR, "base64 encode/decode bad len %d != %d\n", p->key_len, key_len);
668 return NULL;
669 }
670
671 if (memcmp(remote_key, p->local_key, p->key_len)) {
672 ast_log(LOG_ERROR, "base64 encode/decode bad key\n");
673 return NULL;
674 }
675
676 ast_debug(1 , "local_key64 %s len %zu\n", p->local_key64, strlen(p->local_key64));
677
678 return p;
679}
static struct ast_srtp_res srtp_res
Definition: res_srtp.c:103
char local_key64[((SRTP_MAX_KEY_LEN) *8+5)/6+1]
Definition: res_srtp.c:638
int(* get_random)(unsigned char *key, size_t len)
Definition: res_srtp.h:52
int ast_base64decode(unsigned char *dst, const char *src, int max)
Decode data from base64.
Definition: utils.c:296
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
Definition: utils.c:406

References ast_base64decode(), ast_base64encode(), ast_debug, ast_log, ast_srtp_res::get_random, ast_sdp_crypto::key_len, ast_sdp_crypto::local_key, ast_sdp_crypto::local_key64, LOG_ERROR, NULL, ast_sdp_crypto::remote_key, and srtp_res.

Referenced by res_sdp_crypto_parse_offer(), and sdp_crypto_alloc().

◆ find_policy()

static struct ast_srtp_policy * find_policy ( struct ast_srtp srtp,
const srtp_policy_t *  policy,
int  flags 
)
static

Definition at line 177 of file res_srtp.c.

178{
179 struct ast_srtp_policy tmp = {
180 .sp = {
181 .ssrc.type = policy->ssrc.type,
182 .ssrc.value = policy->ssrc.value,
183 },
184 };
185
186 return ao2_t_find(srtp->policies, &tmp, flags, "Looking for policy");
187}
#define ao2_t_find(container, arg, flags, tag)
Definition: astobj2.h:1734

References ao2_t_find, ast_srtp::policies, and tmp().

Referenced by ast_srtp_add_stream(), and ast_srtp_change_source().

◆ load_module()

static int load_module ( void  )
static

Definition at line 1270 of file res_srtp.c.

1271{
1272 return res_srtp_init();
1273}
static int res_srtp_init(void)
Definition: res_srtp.c:1231

References res_srtp_init().

◆ policy_cmp_fn()

static int policy_cmp_fn ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 170 of file res_srtp.c.

171{
172 const struct ast_srtp_policy *one = obj, *two = arg;
173
174 return one->sp.ssrc.type == two->sp.ssrc.type && one->sp.ssrc.value == two->sp.ssrc.value;
175}

References ast_srtp_policy::sp.

Referenced by res_srtp_new().

◆ policy_destructor()

static void policy_destructor ( void *  obj)
static

Definition at line 242 of file res_srtp.c.

243{
244 struct ast_srtp_policy *policy = obj;
245
246 if (policy->sp.key) {
247 ast_free(policy->sp.key);
248 policy->sp.key = NULL;
249 }
250}

References ast_free, NULL, and ast_srtp_policy::sp.

Referenced by ast_srtp_policy_alloc().

◆ policy_hash_fn()

static int policy_hash_fn ( const void *  obj,
const int  flags 
)
static

Definition at line 163 of file res_srtp.c.

164{
165 const struct ast_srtp_policy *policy = obj;
166
167 return policy->sp.ssrc.type == ssrc_specific ? policy->sp.ssrc.value : policy->sp.ssrc.type;
168}

References ast_srtp_policy::sp.

Referenced by res_srtp_new().

◆ policy_set_suite()

static int policy_set_suite ( crypto_policy_t p,
enum ast_srtp_suite  suite 
)
static

Definition at line 268 of file res_srtp.c.

269{
270 switch (suite) {
273 return 0;
274
277 return 0;
278
279#if defined(HAVE_SRTP_192) && defined(ENABLE_SRTP_AES_192)
282 return 0;
283
286 return 0;
287#endif
288#if defined(HAVE_SRTP_256) && defined(ENABLE_SRTP_AES_256)
291 return 0;
292
295 return 0;
296#endif
297#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM)
298 case AST_AES_GCM_128:
300 return 0;
301
304 return 0;
305#endif
306#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM) && defined(ENABLE_SRTP_AES_256)
307 case AST_AES_GCM_256:
309 return 0;
310
313 return 0;
314#endif
315
316 default:
317 ast_log(LOG_ERROR, "Invalid crypto suite: %u\n", suite);
318 return -1;
319 }
320}
@ AST_AES_CM_128_HMAC_SHA1_80
Definition: res_srtp.h:58
@ AST_AES_GCM_256
Definition: res_srtp.h:63
@ AST_AES_GCM_128
Definition: res_srtp.h:62
@ AST_AES_CM_128_HMAC_SHA1_32
Definition: res_srtp.h:59
@ AST_AES_CM_256_HMAC_SHA1_32
Definition: res_srtp.h:61
@ AST_AES_CM_192_HMAC_SHA1_80
Definition: res_srtp.h:66
@ AST_AES_CM_256_HMAC_SHA1_80
Definition: res_srtp.h:60
@ AST_AES_GCM_128_8
Definition: res_srtp.h:64
@ AST_AES_CM_192_HMAC_SHA1_32
Definition: res_srtp.h:67
@ AST_AES_GCM_256_8
Definition: res_srtp.h:65
#define crypto_policy_set_aes_gcm_256_8_auth
Definition: srtp_compat.h:17
#define crypto_policy_set_aes_cm_192_hmac_sha1_80
Definition: srtp_compat.h:10
#define crypto_policy_set_aes_gcm_128_16_auth
Definition: srtp_compat.h:14
#define crypto_policy_set_aes_cm_128_hmac_sha1_32
Definition: srtp_compat.h:9
#define crypto_policy_set_aes_cm_128_hmac_sha1_80
Definition: srtp_compat.h:8
#define crypto_policy_set_aes_gcm_256_16_auth
Definition: srtp_compat.h:15
#define crypto_policy_set_aes_cm_192_hmac_sha1_32
Definition: srtp_compat.h:11
#define crypto_policy_set_aes_cm_256_hmac_sha1_32
Definition: srtp_compat.h:13
#define crypto_policy_set_aes_cm_256_hmac_sha1_80
Definition: srtp_compat.h:12
#define crypto_policy_set_aes_gcm_128_8_auth
Definition: srtp_compat.h:16

References AST_AES_CM_128_HMAC_SHA1_32, AST_AES_CM_128_HMAC_SHA1_80, AST_AES_CM_192_HMAC_SHA1_32, AST_AES_CM_192_HMAC_SHA1_80, AST_AES_CM_256_HMAC_SHA1_32, AST_AES_CM_256_HMAC_SHA1_80, AST_AES_GCM_128, AST_AES_GCM_128_8, AST_AES_GCM_256, AST_AES_GCM_256_8, ast_log, crypto_policy_set_aes_cm_128_hmac_sha1_32, crypto_policy_set_aes_cm_128_hmac_sha1_80, crypto_policy_set_aes_cm_192_hmac_sha1_32, crypto_policy_set_aes_cm_192_hmac_sha1_80, crypto_policy_set_aes_cm_256_hmac_sha1_32, crypto_policy_set_aes_cm_256_hmac_sha1_80, crypto_policy_set_aes_gcm_128_16_auth, crypto_policy_set_aes_gcm_128_8_auth, crypto_policy_set_aes_gcm_256_16_auth, crypto_policy_set_aes_gcm_256_8_auth, and LOG_ERROR.

Referenced by ast_srtp_policy_set_suite().

◆ res_sdp_crypto_alloc()

static struct ast_sdp_crypto * res_sdp_crypto_alloc ( void  )
static

Definition at line 700 of file res_srtp.c.

701{
703}
#define SRTP_MASTER_KEY_LEN
static struct ast_sdp_crypto * sdp_crypto_alloc(const int key_len)
Definition: res_srtp.c:681

References sdp_crypto_alloc(), and SRTP_MASTER_KEY_LEN.

Referenced by res_sdp_srtp_get_attr().

◆ res_sdp_crypto_build_offer()

static int res_sdp_crypto_build_offer ( struct ast_sdp_crypto p,
int  taglen 
)
static

Definition at line 705 of file res_srtp.c.

706{
707 int res;
708
709 /* Rebuild the crypto line */
710 ast_free(p->a_crypto);
711 p->a_crypto = NULL;
712
713 if ((taglen & 0x007f) == 8) {
714 res = ast_asprintf(&p->a_crypto, "%d AEAD_AES_%d_GCM_%d inline:%s",
715 p->tag, 128 + ((taglen & 0x0300) >> 2), taglen & 0x007f, p->local_key64);
716 } else if ((taglen & 0x007f) == 16) {
717 res = ast_asprintf(&p->a_crypto, "%d AEAD_AES_%d_GCM inline:%s",
718 p->tag, 128 + ((taglen & 0x0300) >> 2), p->local_key64);
719 } else if ((taglen & 0x0300) && !(taglen & 0x0080)) {
720 res = ast_asprintf(&p->a_crypto, "%d AES_%d_CM_HMAC_SHA1_%d inline:%s",
721 p->tag, 128 + ((taglen & 0x0300) >> 2), taglen & 0x007f, p->local_key64);
722 } else {
723 res = ast_asprintf(&p->a_crypto, "%d AES_CM_%d_HMAC_SHA1_%d inline:%s",
724 p->tag, 128 + ((taglen & 0x0300) >> 2), taglen & 0x007f, p->local_key64);
725 }
726 if (res == -1 || !p->a_crypto) {
727 ast_log(LOG_ERROR, "Could not allocate memory for crypto line\n");
728 return -1;
729 }
730
731 ast_debug(1, "Crypto line: a=crypto:%s\n", p->a_crypto);
732
733 return 0;
734}
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
char * a_crypto
Definition: res_srtp.c:635

References ast_sdp_crypto::a_crypto, ast_asprintf, ast_debug, ast_free, ast_log, ast_sdp_crypto::local_key64, LOG_ERROR, NULL, and ast_sdp_crypto::tag.

Referenced by res_sdp_crypto_parse_offer(), and res_sdp_srtp_get_attr().

◆ res_sdp_crypto_dtor()

static void res_sdp_crypto_dtor ( struct ast_sdp_crypto crypto)
static

Definition at line 643 of file res_srtp.c.

644{
645 if (crypto) {
646 ast_free(crypto->a_crypto);
647 crypto->a_crypto = NULL;
648 ast_free(crypto);
649
651 }
652}

References ast_sdp_crypto::a_crypto, ast_free, ast_module_unref, NULL, and ast_module_info::self.

Referenced by sdp_crypto_alloc().

◆ res_sdp_crypto_parse_offer()

static int res_sdp_crypto_parse_offer ( struct ast_rtp_instance rtp,
struct ast_sdp_srtp srtp,
const char *  attr 
)
static

Definition at line 804 of file res_srtp.c.

805{
806 char *str = NULL;
807 char *tag = NULL;
808 char *suite = NULL;
809 char *key_params = NULL;
810 char *key_param = NULL;
811 char *session_params = NULL;
812 char *key_salt = NULL; /* The actual master key and key salt */
813 char *lifetime = NULL; /* Key lifetime (# of RTP packets) */
814 char *mki = NULL; /* Master Key Index */
815 int found = 0;
816 int key_len_from_sdp;
817 int key_len_expected;
818 int tag_from_sdp;
819 int suite_val = 0;
820 unsigned char remote_key[SRTP_MAX_KEY_LEN];
821 int taglen;
822 double sdes_lifetime;
823 struct ast_sdp_crypto *crypto;
824 struct ast_sdp_srtp *tmp;
825
826 str = ast_strdupa(attr);
827
828 tag = strsep(&str, " ");
829 suite = strsep(&str, " ");
830 key_params = strsep(&str, " ");
831 session_params = strsep(&str, " ");
832
833 if (!tag || !suite) {
834 ast_log(LOG_WARNING, "Unrecognized crypto attribute a=%s\n", attr);
835 return -1;
836 }
837
838 /* RFC4568 9.1 - tag is 1-9 digits */
839 if (sscanf(tag, "%30d", &tag_from_sdp) != 1 || tag_from_sdp < 0 || tag_from_sdp > 999999999) {
840 ast_log(LOG_WARNING, "Unacceptable a=crypto tag: %s\n", tag);
841 return -1;
842 }
843
844 if (!ast_strlen_zero(session_params)) {
845 ast_log(LOG_WARNING, "Unsupported crypto parameters: %s\n", session_params);
846 return -1;
847 }
848
849 /* On egress, Asterisk sent several crypto lines in the SIP/SDP offer
850 The remote party might have choosen another line than the first */
851 for (tmp = srtp; tmp && tmp->crypto && tmp->crypto->tag != tag_from_sdp;) {
853 }
854 if (tmp) { /* tag matched an already created crypto line */
855 unsigned int flags = tmp->flags;
856
857 /* Make that crypto line the head of the list, not by changing the
858 list structure but by exchanging the content of the list members */
859 crypto = tmp->crypto;
860 tmp->crypto = srtp->crypto;
861 tmp->flags = srtp->flags;
862 srtp->crypto = crypto;
863 srtp->flags = flags;
864 } else {
865 crypto = srtp->crypto;
866 crypto->tag = tag_from_sdp;
867 }
868
876
877 if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80")) {
878 suite_val = AST_AES_CM_128_HMAC_SHA1_80;
880 key_len_expected = 30;
881 } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
882 suite_val = AST_AES_CM_128_HMAC_SHA1_32;
884 key_len_expected = 30;
885#if defined(HAVE_SRTP_192) && defined(ENABLE_SRTP_AES_192)
886 } else if (!strcmp(suite, "AES_192_CM_HMAC_SHA1_80")) {
887 suite_val = AST_AES_CM_192_HMAC_SHA1_80;
890 key_len_expected = 38;
891 } else if (!strcmp(suite, "AES_192_CM_HMAC_SHA1_32")) {
892 suite_val = AST_AES_CM_192_HMAC_SHA1_32;
895 key_len_expected = 38;
896 /* RFC used a different name while in draft, some still use that */
897 } else if (!strcmp(suite, "AES_CM_192_HMAC_SHA1_80")) {
898 suite_val = AST_AES_CM_192_HMAC_SHA1_80;
902 key_len_expected = 38;
903 } else if (!strcmp(suite, "AES_CM_192_HMAC_SHA1_32")) {
904 suite_val = AST_AES_CM_192_HMAC_SHA1_32;
908 key_len_expected = 38;
909#endif
910#if defined(HAVE_SRTP_256) && defined(ENABLE_SRTP_AES_256)
911 } else if (!strcmp(suite, "AES_256_CM_HMAC_SHA1_80")) {
912 suite_val = AST_AES_CM_256_HMAC_SHA1_80;
915 key_len_expected = 46;
916 } else if (!strcmp(suite, "AES_256_CM_HMAC_SHA1_32")) {
917 suite_val = AST_AES_CM_256_HMAC_SHA1_32;
920 key_len_expected = 46;
921 /* RFC used a different name while in draft, some still use that */
922 } else if (!strcmp(suite, "AES_CM_256_HMAC_SHA1_80")) {
923 suite_val = AST_AES_CM_256_HMAC_SHA1_80;
927 key_len_expected = 46;
928 } else if (!strcmp(suite, "AES_CM_256_HMAC_SHA1_32")) {
929 suite_val = AST_AES_CM_256_HMAC_SHA1_32;
933 key_len_expected = 46;
934#endif
935#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM)
936 } else if (!strcmp(suite, "AEAD_AES_128_GCM")) {
937 suite_val = AST_AES_GCM_128;
939 key_len_expected = AES_128_GCM_KEYSIZE_WSALT;
940 /* RFC contained a (too) short auth tag for RTP media, some still use that */
941 } else if (!strcmp(suite, "AEAD_AES_128_GCM_8")) {
942 suite_val = AST_AES_GCM_128_8;
944 key_len_expected = AES_128_GCM_KEYSIZE_WSALT;
945#endif
946#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM) && defined(ENABLE_SRTP_AES_256)
947 } else if (!strcmp(suite, "AEAD_AES_256_GCM")) {
948 suite_val = AST_AES_GCM_256;
951 key_len_expected = AES_256_GCM_KEYSIZE_WSALT;
952 /* RFC contained a (too) short auth tag for RTP media, some still use that */
953 } else if (!strcmp(suite, "AEAD_AES_256_GCM_8")) {
954 suite_val = AST_AES_GCM_256_8;
957 key_len_expected = AES_256_GCM_KEYSIZE_WSALT;
958#endif
959 } else {
960 ast_debug(3, "Unsupported crypto suite: %s\n", suite);
961 return -1;
962 }
963
964 while ((key_param = strsep(&key_params, ";"))) {
965 unsigned int n_lifetime;
966 char *method = NULL;
967 char *info = NULL;
968
969 method = strsep(&key_param, ":");
970 info = strsep(&key_param, ";");
971 sdes_lifetime = 0;
972
973 if (strcmp(method, "inline")) {
974 continue;
975 }
976
977 key_salt = strsep(&info, "|");
978
979 /* The next parameter can be either lifetime or MKI */
980 lifetime = strsep(&info, "|");
981 if (!lifetime) {
982 found = 1;
983 break;
984 }
985
986 mki = strchr(lifetime, ':');
987 if (mki) {
988 mki = lifetime;
989 lifetime = NULL;
990 } else {
991 mki = strsep(&info, "|");
992 }
993
994 if (mki && *mki != '1') {
995 ast_log(LOG_NOTICE, "Crypto MKI handling is not supported: ignoring attribute %s\n", attr);
996 continue;
997 }
998
999 if (lifetime) {
1000 if (!strncmp(lifetime, "2^", 2)) {
1001 char *lifetime_val = lifetime + 2;
1002
1003 /* Exponential lifetime */
1004 if (sscanf(lifetime_val, "%30u", &n_lifetime) != 1) {
1005 ast_log(LOG_NOTICE, "Failed to parse lifetime value in crypto attribute: %s\n", attr);
1006 continue;
1007 }
1008
1009 if (n_lifetime > 48) {
1010 /* Yeah... that's a bit big. */
1011 ast_log(LOG_NOTICE, "Crypto lifetime exponent of '%u' is a bit large; using 48\n", n_lifetime);
1012 n_lifetime = 48;
1013 }
1014 sdes_lifetime = pow(2, n_lifetime);
1015 } else {
1016 /* Decimal lifetime */
1017 if (sscanf(lifetime, "%30u", &n_lifetime) != 1) {
1018 ast_log(LOG_NOTICE, "Failed to parse lifetime value in crypto attribute: %s\n", attr);
1019 continue;
1020 }
1021 sdes_lifetime = n_lifetime;
1022 }
1023
1024 /* Accept anything above ~5.8 hours. Less than ~5.8; reject. */
1025 if (sdes_lifetime < 1048576) {
1026 ast_log(LOG_NOTICE, "Rejecting crypto attribute '%s': lifetime '%f' too short\n", attr, sdes_lifetime);
1027 continue;
1028 }
1029 }
1030
1031 ast_debug(2, "Crypto attribute '%s' accepted with lifetime '%f', MKI '%s'\n",
1032 attr, sdes_lifetime, mki ? mki : "-");
1033
1034 found = 1;
1035 break;
1036 }
1037
1038 if (!found) {
1039 ast_log(LOG_NOTICE, "SRTP crypto offer not acceptable: '%s'\n", attr);
1040 return -1;
1041 }
1042
1043 key_len_from_sdp = ast_base64decode(remote_key, key_salt, sizeof(remote_key));
1044 if (key_len_from_sdp != key_len_expected) {
1045 ast_log(LOG_WARNING, "SRTP descriptions key length is '%d', not '%d'\n",
1046 key_len_from_sdp, key_len_expected);
1047 return -1;
1048 }
1049
1050 /* on default, the key is 30 (AES-128); throw that away (only) when the suite changed actually */
1051 /* ingress: optional, but saves one expensive call to get_random(.) */
1052 /* egress: required, because the local key was communicated before the remote key is processed */
1053 if (crypto->key_len != key_len_from_sdp) {
1054 if (!crypto_init_keys(crypto, key_len_from_sdp)) {
1055 return -1;
1056 }
1057 } else if (!memcmp(crypto->remote_key, remote_key, key_len_from_sdp)) {
1058 ast_debug(1, "SRTP remote key unchanged; maintaining current policy\n");
1059 return 0;
1060 }
1061
1062 if (key_len_from_sdp > sizeof(crypto->remote_key)) {
1064 "SRTP key buffer is %zu although it must be at least %d bytes\n",
1065 sizeof(crypto->remote_key), key_len_from_sdp);
1066 return -1;
1067 }
1068 memcpy(crypto->remote_key, remote_key, key_len_from_sdp);
1069
1070 if (crypto_activate(crypto, suite_val, remote_key, key_len_from_sdp, rtp) < 0) {
1071 return -1;
1072 }
1073
1075 taglen = 32;
1076 } else if (ast_test_flag(srtp, AST_SRTP_CRYPTO_TAG_16)) {
1077 taglen = 16;
1078 } else if (ast_test_flag(srtp, AST_SRTP_CRYPTO_TAG_8)) {
1079 taglen = 8;
1080 } else {
1081 taglen = 80;
1082 }
1084 taglen |= 0x0200;
1085 } else if (ast_test_flag(srtp, AST_SRTP_CRYPTO_AES_192)) {
1086 taglen |= 0x0100;
1087 }
1089 taglen |= 0x0080;
1090 }
1091
1092 /* Finally, rebuild the crypto line */
1093 if (res_sdp_crypto_build_offer(crypto, taglen)) {
1094 return -1;
1095 }
1096
1098 return 0;
1099}
const char * str
Definition: app_jack.c:147
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
char * strsep(char **str, const char *delims)
#define LOG_NOTICE
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
def info(msg)
const char * method
Definition: res_pjsip.c:1279
static int crypto_activate(struct ast_sdp_crypto *p, int suite_val, unsigned char *remote_key, int key_len, struct ast_rtp_instance *rtp)
Definition: res_srtp.c:752
static struct ast_sdp_crypto * crypto_init_keys(struct ast_sdp_crypto *p, const int key_len)
Definition: res_srtp.c:654
static int res_sdp_crypto_build_offer(struct ast_sdp_crypto *p, int taglen)
Definition: res_srtp.c:705
#define AST_SRTP_CRYPTO_TAG_16
Definition: sdp_srtp.h:48
#define AST_SRTP_CRYPTO_TAG_80
Definition: sdp_srtp.h:47
#define AST_SRTP_CRYPTO_AES_256
Definition: sdp_srtp.h:51
#define AST_SRTP_CRYPTO_TAG_32
Definition: sdp_srtp.h:46
#define AST_SRTP_CRYPTO_TAG_8
Definition: sdp_srtp.h:49
#define AST_SRTP_CRYPTO_AES_192
Definition: sdp_srtp.h:50
#define AST_SRTP_CRYPTO_OLD_NAME
Definition: sdp_srtp.h:52
#define AST_SRTP_CRYPTO_OFFER_OK
Definition: sdp_srtp.h:45
#define AES_128_GCM_KEYSIZE_WSALT
Definition: srtp_compat.h:22
#define AES_256_GCM_KEYSIZE_WSALT
Definition: srtp_compat.h:28
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
unsigned char remote_key[SRTP_MAX_KEY_LEN]
Definition: res_srtp.c:639
structure for secure RTP audio
Definition: sdp_srtp.h:38
struct ast_sdp_srtp::@278 sdp_srtp_list
struct ast_sdp_crypto * crypto
Definition: sdp_srtp.h:40
unsigned int flags
Definition: sdp_srtp.h:39
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define ast_set_flag(p, flag)
Definition: utils.h:70

References AES_128_GCM_KEYSIZE_WSALT, AES_256_GCM_KEYSIZE_WSALT, AST_AES_CM_128_HMAC_SHA1_32, AST_AES_CM_128_HMAC_SHA1_80, AST_AES_CM_192_HMAC_SHA1_32, AST_AES_CM_192_HMAC_SHA1_80, AST_AES_CM_256_HMAC_SHA1_32, AST_AES_CM_256_HMAC_SHA1_80, AST_AES_GCM_128, AST_AES_GCM_128_8, AST_AES_GCM_256, AST_AES_GCM_256_8, ast_base64decode(), ast_clear_flag, ast_debug, AST_LIST_NEXT, ast_log, ast_set_flag, AST_SRTP_CRYPTO_AES_192, AST_SRTP_CRYPTO_AES_256, AST_SRTP_CRYPTO_OFFER_OK, AST_SRTP_CRYPTO_OLD_NAME, AST_SRTP_CRYPTO_TAG_16, AST_SRTP_CRYPTO_TAG_32, AST_SRTP_CRYPTO_TAG_8, AST_SRTP_CRYPTO_TAG_80, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_sdp_srtp::crypto, crypto_activate(), crypto_init_keys(), ast_sdp_srtp::flags, sip_to_pjsip::info(), ast_sdp_crypto::key_len, LOG_ERROR, LOG_NOTICE, LOG_WARNING, method, NULL, ast_sdp_crypto::remote_key, res_sdp_crypto_build_offer(), ast_sdp_srtp::sdp_srtp_list, str, strsep(), ast_sdp_crypto::tag, and tmp().

◆ res_sdp_srtp_get_attr()

static const char * res_sdp_srtp_get_attr ( struct ast_sdp_srtp srtp,
int  dtls_enabled,
int  default_taglen_32 
)
static

Definition at line 1101 of file res_srtp.c.

1102{
1103 int taglen;
1104
1105 if (!srtp) {
1106 return NULL;
1107 }
1108
1109 /* Set encryption properties */
1110 if (!srtp->crypto) {
1111 if (AST_LIST_NEXT(srtp, sdp_srtp_list)) {
1112 srtp->crypto = res_sdp_crypto_alloc();
1113 ast_log(LOG_ERROR, "SRTP SDP list was not empty\n");
1114 } else {
1115 const int len = default_taglen_32 ? AST_SRTP_CRYPTO_TAG_32 : AST_SRTP_CRYPTO_TAG_80;
1116 const int attr[][3] = {
1117 /* This array creates the following list:
1118 * a=crypto:1 AES_CM_128_HMAC_SHA1_ ...
1119 * a=crypto:2 AEAD_AES_128_GCM ...
1120 * a=crypto:3 AES_256_CM_HMAC_SHA1_ ...
1121 * a=crypto:4 AEAD_AES_256_GCM ...
1122 * a=crypto:5 AES_192_CM_HMAC_SHA1_ ...
1123 * something like 'AEAD_AES_192_GCM' is not specified by the RFCs
1124 *
1125 * If you want to prefer another crypto suite or you want to
1126 * exclude a suite, change this array and recompile Asterisk.
1127 * This list cannot be changed from rtp.conf because you should
1128 * know what you are doing. Especially AES-192 and AES-GCM are
1129 * broken in many VoIP clients, see
1130 * https://github.com/cisco/libsrtp/pull/170
1131 * https://github.com/cisco/libsrtp/pull/184
1132 * Furthermore, AES-GCM uses a shorter crypto-suite string which
1133 * causes Nokia phones based on Symbian/S60 to reject the whole
1134 * INVITE with status 500, even if a matching suite was offered.
1135 * AES-256 might just waste your processor cycles, especially if
1136 * your TLS transport is not secured with equivalent grade, see
1137 * https://security.stackexchange.com/q/61361
1138 * Therefore, AES-128 was preferred here.
1139 *
1140 * If you want to enable one of those defines, please, go for
1141 * CFLAGS='-DENABLE_SRTP_AES_GCM' ./configure && sudo make install
1142 */
1143 { len, 0, 30 },
1144#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM)
1146#endif
1147#if defined(HAVE_SRTP_256) && defined(ENABLE_SRTP_AES_256)
1149#endif
1150#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM) && defined(ENABLE_SRTP_AES_256)
1152#endif
1153#if defined(HAVE_SRTP_192) && defined(ENABLE_SRTP_AES_192)
1155#endif
1156 };
1157 struct ast_sdp_srtp *tmp = srtp;
1158 int i;
1159
1160 for (i = 0; i < ARRAY_LEN(attr); i++) {
1161 if (attr[i][0]) {
1162 ast_set_flag(tmp, attr[i][0]);
1163 }
1164 if (attr[i][1]) {
1165 ast_set_flag(tmp, attr[i][1]);
1166 }
1167 tmp->crypto = sdp_crypto_alloc(attr[i][2]); /* key_len */
1168 tmp->crypto->tag = (i + 1); /* tag starts at 1 */
1169
1170 if (i < ARRAY_LEN(attr) - 1) {
1173 }
1174 }
1175 }
1176 }
1177
1178 if (dtls_enabled) {
1179 /* If DTLS-SRTP is enabled the key details will be pulled from TLS */
1180 return NULL;
1181 }
1182
1183 /* set the key length based on INVITE or settings */
1185 taglen = 80;
1186 } else if (ast_test_flag(srtp, AST_SRTP_CRYPTO_TAG_32)) {
1187 taglen = 32;
1188 } else if (ast_test_flag(srtp, AST_SRTP_CRYPTO_TAG_16)) {
1189 taglen = 16;
1190 } else if (ast_test_flag(srtp, AST_SRTP_CRYPTO_TAG_8)) {
1191 taglen = 8;
1192 } else {
1193 taglen = default_taglen_32 ? 32 : 80;
1194 }
1196 taglen |= 0x0200;
1197 } else if (ast_test_flag(srtp, AST_SRTP_CRYPTO_AES_192)) {
1198 taglen |= 0x0100;
1199 }
1201 taglen |= 0x0080;
1202 }
1203
1204 if (srtp->crypto && (res_sdp_crypto_build_offer(srtp->crypto, taglen) >= 0)) {
1205 return srtp->crypto->a_crypto;
1206 }
1207
1208 ast_log(LOG_WARNING, "No SRTP key management enabled\n");
1209 return NULL;
1210}
static struct ast_sdp_crypto * res_sdp_crypto_alloc(void)
Definition: res_srtp.c:700
struct ast_sdp_srtp * ast_sdp_srtp_alloc(void)
allocate a ast_sdp_srtp structure
Definition: sdp_srtp.c:41
#define ARRAY_LEN(a)
Definition: utils.h:666

References ast_sdp_crypto::a_crypto, AES_128_GCM_KEYSIZE_WSALT, AES_256_GCM_KEYSIZE_WSALT, ARRAY_LEN, AST_LIST_NEXT, ast_log, ast_sdp_srtp_alloc(), ast_set_flag, AST_SRTP_CRYPTO_AES_192, AST_SRTP_CRYPTO_AES_256, AST_SRTP_CRYPTO_OLD_NAME, AST_SRTP_CRYPTO_TAG_16, AST_SRTP_CRYPTO_TAG_32, AST_SRTP_CRYPTO_TAG_8, AST_SRTP_CRYPTO_TAG_80, ast_test_flag, ast_sdp_srtp::crypto, len(), LOG_ERROR, LOG_WARNING, NULL, res_sdp_crypto_alloc(), res_sdp_crypto_build_offer(), sdp_crypto_alloc(), ast_sdp_srtp::sdp_srtp_list, and tmp().

◆ res_srtp_init()

static int res_srtp_init ( void  )
static

Definition at line 1231 of file res_srtp.c.

1232{
1233 if (g_initialized) {
1234 return 0;
1235 }
1236
1237 if (srtp_init() != err_status_ok) {
1238 ast_log(AST_LOG_WARNING, "Failed to initialize libsrtp\n");
1239 return -1;
1240 }
1241
1242 srtp_install_event_handler(srtp_event_cb);
1243
1245 ast_log(AST_LOG_WARNING, "Failed to register SRTP with rtp engine\n");
1247 return -1;
1248 }
1249
1251 ast_log(AST_LOG_WARNING, "Failed to register SDP SRTP crypto API\n");
1253 return -1;
1254 }
1255
1256#ifdef HAVE_SRTP_GET_VERSION
1257 ast_verb(2, "%s initialized\n", srtp_get_version_string());
1258#else
1259 ast_verb(2, "libsrtp initialized\n");
1260#endif
1261
1262 g_initialized = 1;
1263 return 0;
1264}
static void res_srtp_shutdown(void)
Definition: res_srtp.c:1220
static void srtp_event_cb(srtp_event_data_t *data)
Definition: res_srtp.c:213
static struct ast_sdp_crypto_api res_sdp_crypto_api
Definition: res_srtp.c:1212
static int g_initialized
Definition: res_srtp.c:82
int ast_rtp_engine_register_srtp(struct ast_srtp_res *srtp_res, struct ast_srtp_policy_res *policy_res)
Definition: rtp_engine.c:2910
int ast_sdp_crypto_register(struct ast_sdp_crypto_api *api)
Register SDP SRTP crypto processing routines.
Definition: sdp_srtp.c:123

References ast_log, AST_LOG_WARNING, ast_rtp_engine_register_srtp(), ast_sdp_crypto_register(), ast_verb, err_status_ok, g_initialized, policy_res, res_sdp_crypto_api, res_srtp_shutdown(), srtp_event_cb(), and srtp_res.

Referenced by load_module().

◆ res_srtp_new()

static struct ast_srtp * res_srtp_new ( void  )
static

Definition at line 189 of file res_srtp.c.

190{
191 struct ast_srtp *srtp;
192
193 if (!(srtp = ast_calloc(1, sizeof(*srtp)))) {
194 ast_log(LOG_ERROR, "Unable to allocate memory for srtp\n");
195 return NULL;
196 }
197
199 policy_hash_fn, NULL, policy_cmp_fn, "SRTP policy container");
200 if (!srtp->policies) {
201 ast_free(srtp);
202 return NULL;
203 }
204
205 srtp->warned = 1;
206
207 return srtp;
208}
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_t_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn, tag)
Definition: astobj2.h:1306
static int policy_cmp_fn(void *obj, void *arg, int flags)
Definition: res_srtp.c:170
static int policy_hash_fn(const void *obj, const int flags)
Definition: res_srtp.c:163

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_t_container_alloc_hash, ast_calloc, ast_free, ast_log, LOG_ERROR, NULL, ast_srtp::policies, policy_cmp_fn(), policy_hash_fn(), and ast_srtp::warned.

Referenced by ast_srtp_create().

◆ res_srtp_shutdown()

static void res_srtp_shutdown ( void  )
static

Definition at line 1220 of file res_srtp.c.

1221{
1224 srtp_install_event_handler(NULL);
1225#ifdef HAVE_SRTP_SHUTDOWN
1226 srtp_shutdown();
1227#endif
1228 g_initialized = 0;
1229}
void ast_rtp_engine_unregister_srtp(void)
Definition: rtp_engine.c:2925
void ast_sdp_crypto_unregister(struct ast_sdp_crypto_api *api)
Unregister SDP SRTP crypto processing routines.
Definition: sdp_srtp.c:132

References ast_rtp_engine_unregister_srtp(), ast_sdp_crypto_unregister(), g_initialized, NULL, and res_sdp_crypto_api.

Referenced by res_srtp_init(), and unload_module().

◆ sdp_crypto_alloc()

static struct ast_sdp_crypto * sdp_crypto_alloc ( const int  key_len)
static

Definition at line 681 of file res_srtp.c.

682{
683 struct ast_sdp_crypto *p, *result;
684
685 if (!(p = ast_calloc(1, sizeof(*p)))) {
686 return NULL;
687 }
688 p->tag = 1;
690
691 /* default is a key which uses AST_AES_CM_128_HMAC_SHA1_xx */
693 if (!result) {
695 }
696
697 return result;
698}
static PGresult * result
Definition: cel_pgsql.c:84
static void res_sdp_crypto_dtor(struct ast_sdp_crypto *crypto)
Definition: res_srtp.c:643

References ast_calloc, ast_module_ref, crypto_init_keys(), ast_sdp_crypto::key_len, NULL, res_sdp_crypto_dtor(), result, ast_module_info::self, and ast_sdp_crypto::tag.

Referenced by res_sdp_crypto_alloc(), and res_sdp_srtp_get_attr().

◆ set_crypto_policy()

static int set_crypto_policy ( struct ast_srtp_policy policy,
int  suite_val,
const unsigned char *  master_key,
int  key_len,
unsigned long  ssrc,
int  inbound 
)
static

Definition at line 736 of file res_srtp.c.

737{
738 if (policy_res.set_master_key(policy, master_key, key_len, NULL, 0) < 0) {
739 return -1;
740 }
741
742 if (policy_res.set_suite(policy, suite_val)) {
743 ast_log(LOG_WARNING, "Could not set remote SRTP suite\n");
744 return -1;
745 }
746
747 policy_res.set_ssrc(policy, ssrc, inbound);
748
749 return 0;
750}
int(* set_master_key)(struct ast_srtp_policy *policy, const unsigned char *key, size_t key_len, const unsigned char *salt, size_t salt_len)
Definition: res_srtp.h:74
void(* set_ssrc)(struct ast_srtp_policy *policy, unsigned long ssrc, int inbound)
Definition: res_srtp.h:75
int(* set_suite)(struct ast_srtp_policy *policy, enum ast_srtp_suite suite)
Definition: res_srtp.h:73

References ast_log, ast_sdp_crypto::key_len, LOG_WARNING, NULL, policy_res, ast_srtp_policy_res::set_master_key, ast_srtp_policy_res::set_ssrc, and ast_srtp_policy_res::set_suite.

Referenced by crypto_activate().

◆ srtp_errstr()

static const char * srtp_errstr ( int  err)
static

Definition at line 123 of file res_srtp.c.

124{
125 switch(err) {
126 case err_status_ok:
127 return "nothing to report";
128 case err_status_fail:
129 return "unspecified failure";
131 return "unsupported parameter";
133 return "couldn't allocate memory";
135 return "couldn't deallocate properly";
137 return "couldn't initialize";
139 return "can't process as much data as requested";
141 return "authentication failure";
143 return "cipher failure";
145 return "replay check failed (bad index)";
147 return "replay check failed (index too old)";
149 return "algorithm failed test routine";
151 return "unsupported operation";
153 return "no appropriate context found";
155 return "unable to perform desired validation";
157 return "can't use key any more";
158 default:
159 return "unknown";
160 }
161}
#define err_status_cipher_fail
Definition: srtp_compat.h:40
#define err_status_init_fail
Definition: srtp_compat.h:37
#define err_status_algo_fail
Definition: srtp_compat.h:43
#define err_status_dealloc_fail
Definition: srtp_compat.h:36
#define err_status_alloc_fail
Definition: srtp_compat.h:35
#define err_status_no_such_op
Definition: srtp_compat.h:44
#define err_status_key_expired
Definition: srtp_compat.h:47
#define err_status_cant_check
Definition: srtp_compat.h:46
#define err_status_bad_param
Definition: srtp_compat.h:34
#define err_status_auth_fail
Definition: srtp_compat.h:39
#define err_status_terminus
Definition: srtp_compat.h:38
#define err_status_fail
Definition: srtp_compat.h:33

References err_status_algo_fail, err_status_alloc_fail, err_status_auth_fail, err_status_bad_param, err_status_cant_check, err_status_cipher_fail, err_status_dealloc_fail, err_status_fail, err_status_init_fail, err_status_key_expired, err_status_no_ctx, err_status_no_such_op, err_status_ok, err_status_replay_fail, err_status_replay_old, and err_status_terminus.

Referenced by ast_srtp_create(), ast_srtp_protect(), and ast_srtp_unprotect().

◆ srtp_event_cb()

static void srtp_event_cb ( srtp_event_data_t *  data)
static

Definition at line 213 of file res_srtp.c.

214{
215 switch (data->event) {
216 case event_ssrc_collision:
217 ast_debug(1, "SSRC collision\n");
218 break;
219 case event_key_soft_limit:
220 ast_debug(1, "event_key_soft_limit\n");
221 break;
222 case event_key_hard_limit:
223 ast_debug(1, "event_key_hard_limit\n");
224 break;
225 case event_packet_index_limit:
226 ast_debug(1, "event_packet_index_limit\n");
227 break;
228 }
229}

References ast_debug, and ast_srtp::data.

Referenced by res_srtp_init().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1275 of file res_srtp.c.

1276{
1278 return 0;
1279}

References res_srtp_shutdown().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Secure RTP (SRTP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, }
static

Definition at line 1286 of file res_srtp.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1286 of file res_srtp.c.

◆ g_initialized

int g_initialized = 0
static

Tracks whether or not we've initialized the libsrtp library

Definition at line 82 of file res_srtp.c.

Referenced by res_srtp_init(), and res_srtp_shutdown().

◆ policy_res

struct ast_srtp_policy_res policy_res
static

◆ res_sdp_crypto_api

struct ast_sdp_crypto_api res_sdp_crypto_api
static

Definition at line 1212 of file res_srtp.c.

Referenced by res_srtp_init(), and res_srtp_shutdown().

◆ srtp_res

struct ast_srtp_res srtp_res
static

Definition at line 103 of file res_srtp.c.

Referenced by ast_rtp_engine_register_srtp(), crypto_init_keys(), and res_srtp_init().