Asterisk - The Open Source Telephony Project GIT-master-0deac78
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 1312 of file res_srtp.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1312 of file res_srtp.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1312 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 601 of file res_srtp.c.

602{
603 struct ast_srtp_policy *match;
604
605 /* For existing streams, replace if its an SSRC stream, or bail if its a wildcard */
606 if ((match = find_policy(srtp, &policy->sp, OBJ_POINTER))) {
607 if (policy->sp.ssrc.type != ssrc_specific) {
608 ast_log(AST_LOG_WARNING, "Cannot replace an existing wildcard policy\n");
609 ao2_t_ref(match, -1, "Unreffing already existing policy");
610 return -1;
611 } else {
612 if (srtp_remove_stream(srtp->session, match->sp.ssrc.value) != err_status_ok) {
613 ast_log(AST_LOG_WARNING, "Failed to remove SRTP stream for SSRC %u\n", match->sp.ssrc.value);
614 }
615 ao2_t_unlink(srtp->policies, match, "Remove existing match policy");
616 ao2_t_ref(match, -1, "Unreffing already existing policy");
617 }
618 }
619
620 ast_debug(3, "Adding new policy for %s %u\n",
621 policy->sp.ssrc.type == ssrc_specific ? "SSRC" : "type",
622 policy->sp.ssrc.type == ssrc_specific ? policy->sp.ssrc.value : policy->sp.ssrc.type);
623 if (srtp_add_stream(srtp->session, &policy->sp) != err_status_ok) {
624 ast_log(AST_LOG_WARNING, "Failed to add SRTP stream for %s %u\n",
625 policy->sp.ssrc.type == ssrc_specific ? "SSRC" : "type",
626 policy->sp.ssrc.type == ssrc_specific ? policy->sp.ssrc.value : policy->sp.ssrc.type);
627 return -1;
628 }
629
630 ao2_t_link(srtp->policies, policy, "Added additional stream");
631
632 return 0;
633}
#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:2388
#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:203
#define err_status_ok
Definition: srtp_compat.h:32
srtp_policy_t sp
Definition: res_srtp.c:104
struct ao2_container * policies
Definition: res_srtp.c:94
srtp_t session
Definition: res_srtp.c:95

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 635 of file res_srtp.c.

636{
637 struct ast_srtp_policy *match;
638 struct srtp_policy_t sp = {
639 .ssrc.type = ssrc_specific,
640 .ssrc.value = from_ssrc,
641 };
643
644 /* If we find a match, return and unlink it from the container so we
645 * can change the SSRC (which is part of the hash) and then have
646 * ast_srtp_add_stream link it back in if all is well */
647 if ((match = find_policy(srtp, &sp, OBJ_POINTER | OBJ_UNLINK))) {
648 match->sp.ssrc.value = to_ssrc;
649 if (ast_srtp_add_stream(srtp, match)) {
650 ast_log(LOG_WARNING, "Couldn't add stream\n");
651 } else if ((status = srtp_remove_stream(srtp->session, from_ssrc))) {
652 ast_debug(3, "Couldn't remove stream (%u)\n", status);
653 }
654 ao2_t_ref(match, -1, "Unreffing found policy in change_source");
655 }
656
657 return 0;
658}
jack_status_t status
Definition: app_jack.c:149
@ 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:601
#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 542 of file res_srtp.c.

543{
544 struct ast_srtp *temp;
545 int status;
546
547 if (!(temp = res_srtp_new())) {
548 return -1;
549 }
551
552 /* Any failures after this point can use ast_srtp_destroy to destroy the instance */
553 status = srtp_create(&temp->session, &policy->sp);
554 if (status != err_status_ok) {
555 /* Session either wasn't created or was created and dealloced. */
556 temp->session = NULL;
557 ast_srtp_destroy(temp);
558 ast_log(LOG_ERROR, "Failed to create srtp session on rtp instance (%p) - %s\n",
560 return -1;
561 }
562
563 temp->rtp = rtp;
564 *srtp = temp;
565
566 ao2_t_link((*srtp)->policies, policy, "Created initial policy");
567
568 return 0;
569}
#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:149
static struct ast_srtp * res_srtp_new(void)
Definition: res_srtp.c:215
static void ast_srtp_destroy(struct ast_srtp *srtp)
Definition: res_srtp.c:588
#define NULL
Definition: resample.c:96
struct ast_module * self
Definition: module.h:356
struct ast_rtp_instance * rtp
Definition: res_srtp.c:93

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 588 of file res_srtp.c.

589{
590 if (srtp->session) {
591 srtp_dealloc(srtp->session);
592 }
593
594 ao2_t_callback(srtp->policies, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "Unallocate policy");
595 ao2_t_ref(srtp->policies, -1, "Destroying container");
596
597 ast_free(srtp);
599}
#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 375 of file res_srtp.c.

376{
377#ifdef HAVE_OPENSSL
378 return RAND_bytes(key, len) > 0 ? 0: -1;
379#else
380 return crypto_get_random(key, len) != err_status_ok ? -1: 0;
381#endif
382}
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 278 of file res_srtp.c.

279{
280 struct ast_srtp_policy *tmp;
281
282 if (!(tmp = ao2_t_alloc(sizeof(*tmp), policy_destructor, "Allocating policy"))) {
283 ast_log(LOG_ERROR, "Unable to allocate memory for srtp_policy\n");
284 }
285
286 return tmp;
287}
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
Definition: astobj2.h:407
static void policy_destructor(void *obj)
Definition: res_srtp.c:268

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

◆ ast_srtp_policy_destroy()

static void ast_srtp_policy_destroy ( struct ast_srtp_policy policy)
static

Definition at line 289 of file res_srtp.c.

290{
291 ao2_t_ref(policy, -1, "Destroying policy");
292}

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 353 of file res_srtp.c.

354{
355 size_t size = key_len + salt_len;
356 unsigned char *master_key;
357
358 if (policy->sp.key) {
359 ast_free(policy->sp.key);
360 policy->sp.key = NULL;
361 }
362
363 if (!(master_key = ast_calloc(1, size))) {
364 return -1;
365 }
366
367 memcpy(master_key, key, key_len);
368 memcpy(master_key + key_len, salt, salt_len);
369
370 policy->sp.key = master_key;
371
372 return 0;
373}
#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 257 of file res_srtp.c.

259{
260 if (ssrc) {
261 policy->sp.ssrc.type = ssrc_specific;
262 policy->sp.ssrc.value = ssrc;
263 } else {
264 policy->sp.ssrc.type = inbound ? ssrc_any_inbound : ssrc_any_outbound;
265 }
266}

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 348 of file res_srtp.c.

349{
350 return policy_set_suite(&policy->sp.rtp, suite) | policy_set_suite(&policy->sp.rtcp, suite);
351}
static int policy_set_suite(crypto_policy_t *p, enum ast_srtp_suite suite)
Definition: res_srtp.c:294

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 514 of file res_srtp.c.

515{
516 int res;
517 unsigned char *localbuf;
518
519 if (!srtp->session) {
520 ast_log(LOG_ERROR, "SRTP protect %s - missing session\n", rtcp ? "rtcp" : "rtp");
521 errno = EINVAL;
522 return -1;
523 }
524
525 if ((*len + SRTP_MAX_TRAILER_LEN) > sizeof(srtp->buf)) {
526 return -1;
527 }
528
529 localbuf = rtcp ? srtp->rtcpbuf : srtp->buf;
530
531 memcpy(localbuf, *buf, *len);
532
533 if ((res = rtcp ? srtp_protect_rtcp(srtp->session, localbuf, len) : srtp_protect(srtp->session, localbuf, len)) != err_status_ok && res != err_status_replay_fail) {
534 ast_log(LOG_WARNING, "SRTP protect: %s\n", srtp_errstr(res));
535 return -1;
536 }
537
538 *buf = localbuf;
539 return *len;
540}
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:99
unsigned char rtcpbuf[8192+AST_FRIENDLY_OFFSET]
Definition: res_srtp.c:100

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 571 of file res_srtp.c.

572{
573 struct ast_srtp *old = *srtp;
574 int res = ast_srtp_create(srtp, rtp, policy);
575
576 if (!res && old) {
577 ast_srtp_destroy(old);
578 }
579
580 if (res) {
581 ast_log(LOG_ERROR, "Failed to replace srtp (%p) on rtp instance (%p) "
582 "- keeping old\n", *srtp, rtp);
583 }
584
585 return res;
586}
static int ast_srtp_create(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy)
Definition: res_srtp.c:542

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 384 of file res_srtp.c.

385{
386 if (!srtp) {
387 return;
388 }
389
390 srtp->cb = cb;
391 srtp->data = data;
392}
void * data
Definition: res_srtp.c:97
const struct ast_srtp_cb * cb
Definition: res_srtp.c:96

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 395 of file res_srtp.c.

396{
397 int res = 0;
398 int i;
399 int rtcp = (flags & 0x01) >> 0;
400 int retry = (flags & 0x02) >> 1;
401 struct ast_rtp_instance_stats stats = {0,};
402
403tryagain:
404
405 if (!srtp->session) {
406 ast_log(LOG_ERROR, "SRTP unprotect %s - missing session\n", rtcp ? "rtcp" : "rtp");
407 errno = EINVAL;
408 return -1;
409 }
410
411 for (i = 0; i < 2; i++) {
412 res = rtcp ? srtp_unprotect_rtcp(srtp->session, buf, len) : srtp_unprotect(srtp->session, buf, len);
413 if (res != err_status_no_ctx) {
414 break;
415 }
416
417 if (srtp->cb && srtp->cb->no_ctx) {
419 break;
420 }
421 if (srtp->cb->no_ctx(srtp->rtp, stats.remote_ssrc, srtp->data) < 0) {
422 break;
423 }
424 } else {
425 break;
426 }
427 }
428
429 if (retry == 0 && res == err_status_replay_old) {
430 ast_log(AST_LOG_NOTICE, "SRTP unprotect failed with %s, retrying\n", srtp_errstr(res));
431
432 if (srtp->session) {
433 struct ast_srtp_policy *policy;
434 struct ao2_iterator it;
435 int policies_count;
436
437 /* dealloc first */
438 ast_debug(5, "SRTP destroy before re-create\n");
439 srtp_dealloc(srtp->session);
440
441 /* get the count */
442 policies_count = ao2_container_count(srtp->policies);
443
444 /* get the first to build up */
445 it = ao2_iterator_init(srtp->policies, 0);
446 policy = ao2_iterator_next(&it);
447
448 ast_debug(5, "SRTP try to re-create\n");
449 if (policy) {
450 int res_srtp_create = srtp_create(&srtp->session, &policy->sp);
451 if (res_srtp_create == err_status_ok) {
452 ast_debug(5, "SRTP re-created with first policy\n");
453 ao2_t_ref(policy, -1, "Unreffing first policy for re-creating srtp session");
454
455 /* if we have more than one policy, add them */
456 if (policies_count > 1) {
457 ast_debug(5, "Add all the other %d policies\n",
458 policies_count - 1);
459 while ((policy = ao2_iterator_next(&it))) {
460 srtp_add_stream(srtp->session, &policy->sp);
461 ao2_t_ref(policy, -1, "Unreffing n-th policy for re-creating srtp session");
462 }
463 }
464
465 retry++;
467 goto tryagain;
468 }
469 ast_log(LOG_ERROR, "SRTP session could not be re-created after unprotect failure: %s\n", srtp_errstr(res_srtp_create));
470
471 /* If srtp_create() fails with a previously alloced session, it will have been dealloced before returning. */
472 srtp->session = NULL;
473
474 ao2_t_ref(policy, -1, "Unreffing first policy after srtp_create failed");
475 }
477 }
478 }
479
480 if (!srtp->session) {
481 errno = EINVAL;
482 return -1;
483 }
484
485 if (res != err_status_ok && res != err_status_replay_fail ) {
486 /*
487 * Authentication failures happen when an active attacker tries to
488 * insert malicious RTP packets. Furthermore, authentication failures
489 * happen, when the other party encrypts the sRTP data in an unexpected
490 * way. This happens quite often with RTCP. Therefore, when you see
491 * authentication failures, try to identify the implementation
492 * (author and product name) used by your other party. Try to investigate
493 * whether they use a custom library or an outdated version of libSRTP.
494 */
495 if (rtcp) {
496 ast_verb(2, "SRTCP unprotect failed on SSRC %u because of %s\n",
498 } else {
499 if ((srtp->warned >= 10) && !((srtp->warned - 10) % 150)) {
500 ast_verb(2, "SRTP unprotect failed on SSRC %u because of %s %d\n",
501 ast_rtp_instance_get_ssrc(srtp->rtp), srtp_errstr(res), srtp->warned);
502 srtp->warned = 11;
503 } else {
504 srtp->warned++;
505 }
506 }
507 errno = EAGAIN;
508 return -1;
509 }
510
511 return *len;
512}
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:2628
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:4017
#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:98

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 778 of file res_srtp.c.

779{
780 struct ast_srtp_policy *local_policy = NULL;
781 struct ast_srtp_policy *remote_policy = NULL;
782 struct ast_rtp_instance_stats stats = {0,};
783 int res = -1;
784
785 if (!p) {
786 return -1;
787 }
788
789 if (!(local_policy = policy_res.alloc())) {
790 return -1;
791 }
792
793 if (!(remote_policy = policy_res.alloc())) {
794 goto err;
795 }
796
798 goto err;
799 }
800
801 if (set_crypto_policy(local_policy, suite_val, p->local_key, key_len, stats.local_ssrc, 0) < 0) {
802 goto err;
803 }
804
805 if (set_crypto_policy(remote_policy, suite_val, remote_key, key_len, 0, 1) < 0) {
806 goto err;
807 }
808
809 /* Add the SRTP policies */
810 if (ast_rtp_instance_add_srtp_policy(rtp, remote_policy, local_policy, 0)) {
811 ast_log(LOG_WARNING, "Could not set SRTP policies\n");
812 goto err;
813 }
814
815 ast_debug(1 , "SRTP policy activated\n");
816 res = 0;
817
818err:
819 if (local_policy) {
820 policy_res.destroy(local_policy);
821 }
822
823 if (remote_policy) {
824 policy_res.destroy(remote_policy);
825 }
826
827 return res;
828}
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:762
static struct ast_srtp_policy_res policy_res
Definition: res_srtp.c:141
@ 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:2942
unsigned int local_ssrc
Definition: rtp_engine.h:452
unsigned char local_key[SRTP_MAX_KEY_LEN]
Definition: res_srtp.c:662
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 680 of file res_srtp.c.

681{
682 unsigned char remote_key[key_len];
683
684 if (srtp_res.get_random(p->local_key, key_len) < 0) {
685 return NULL;
686 }
687
688 ast_base64encode(p->local_key64, p->local_key, key_len, sizeof(p->local_key64));
689
690 p->key_len = ast_base64decode(remote_key, p->local_key64, sizeof(remote_key));
691
692 if (p->key_len != key_len) {
693 ast_log(LOG_ERROR, "base64 encode/decode bad len %d != %d\n", p->key_len, key_len);
694 return NULL;
695 }
696
697 if (memcmp(remote_key, p->local_key, p->key_len)) {
698 ast_log(LOG_ERROR, "base64 encode/decode bad key\n");
699 return NULL;
700 }
701
702 ast_debug(1 , "local_key64 %s len %zu\n", p->local_key64, strlen(p->local_key64));
703
704 return p;
705}
static struct ast_srtp_res srtp_res
Definition: res_srtp.c:129
char local_key64[((SRTP_MAX_KEY_LEN) *8+5)/6+1]
Definition: res_srtp.c:664
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 203 of file res_srtp.c.

204{
205 struct ast_srtp_policy tmp = {
206 .sp = {
207 .ssrc.type = policy->ssrc.type,
208 .ssrc.value = policy->ssrc.value,
209 },
210 };
211
212 return ao2_t_find(srtp->policies, &tmp, flags, "Looking for policy");
213}
#define ao2_t_find(container, arg, flags, tag)
Definition: astobj2.h:1734

References ao2_t_find, ast_srtp::policies, and ast_srtp_policy::sp.

Referenced by ast_srtp_add_stream(), and ast_srtp_change_source().

◆ load_module()

static int load_module ( void  )
static

Definition at line 1296 of file res_srtp.c.

1297{
1298 return res_srtp_init();
1299}
static int res_srtp_init(void)
Definition: res_srtp.c:1257

References res_srtp_init().

◆ policy_cmp_fn()

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

Definition at line 196 of file res_srtp.c.

197{
198 const struct ast_srtp_policy *one = obj, *two = arg;
199
200 return one->sp.ssrc.type == two->sp.ssrc.type && one->sp.ssrc.value == two->sp.ssrc.value;
201}

References ast_srtp_policy::sp.

Referenced by res_srtp_new().

◆ policy_destructor()

static void policy_destructor ( void *  obj)
static

Definition at line 268 of file res_srtp.c.

269{
270 struct ast_srtp_policy *policy = obj;
271
272 if (policy->sp.key) {
273 ast_free(policy->sp.key);
274 policy->sp.key = NULL;
275 }
276}

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 189 of file res_srtp.c.

190{
191 const struct ast_srtp_policy *policy = obj;
192
193 return policy->sp.ssrc.type == ssrc_specific ? policy->sp.ssrc.value : policy->sp.ssrc.type;
194}

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 294 of file res_srtp.c.

295{
296 switch (suite) {
299 return 0;
300
303 return 0;
304
305#if defined(HAVE_SRTP_192) && defined(ENABLE_SRTP_AES_192)
308 return 0;
309
312 return 0;
313#endif
314#if defined(HAVE_SRTP_256) && defined(ENABLE_SRTP_AES_256)
317 return 0;
318
321 return 0;
322#endif
323#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM)
324 case AST_AES_GCM_128:
326 return 0;
327
330 return 0;
331#endif
332#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM) && defined(ENABLE_SRTP_AES_256)
333 case AST_AES_GCM_256:
335 return 0;
336
339 return 0;
340#endif
341
342 default:
343 ast_log(LOG_ERROR, "Invalid crypto suite: %u\n", suite);
344 return -1;
345 }
346}
@ 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 726 of file res_srtp.c.

727{
729}
#define SRTP_MASTER_KEY_LEN
static struct ast_sdp_crypto * sdp_crypto_alloc(const int key_len)
Definition: res_srtp.c:707

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 731 of file res_srtp.c.

732{
733 int res;
734
735 /* Rebuild the crypto line */
736 ast_free(p->a_crypto);
737 p->a_crypto = NULL;
738
739 if ((taglen & 0x007f) == 8) {
740 res = ast_asprintf(&p->a_crypto, "%d AEAD_AES_%d_GCM_%d inline:%s",
741 p->tag, 128 + ((taglen & 0x0300) >> 2), taglen & 0x007f, p->local_key64);
742 } else if ((taglen & 0x007f) == 16) {
743 res = ast_asprintf(&p->a_crypto, "%d AEAD_AES_%d_GCM inline:%s",
744 p->tag, 128 + ((taglen & 0x0300) >> 2), p->local_key64);
745 } else if ((taglen & 0x0300) && !(taglen & 0x0080)) {
746 res = ast_asprintf(&p->a_crypto, "%d AES_%d_CM_HMAC_SHA1_%d inline:%s",
747 p->tag, 128 + ((taglen & 0x0300) >> 2), taglen & 0x007f, p->local_key64);
748 } else {
749 res = ast_asprintf(&p->a_crypto, "%d AES_CM_%d_HMAC_SHA1_%d inline:%s",
750 p->tag, 128 + ((taglen & 0x0300) >> 2), taglen & 0x007f, p->local_key64);
751 }
752 if (res == -1 || !p->a_crypto) {
753 ast_log(LOG_ERROR, "Could not allocate memory for crypto line\n");
754 return -1;
755 }
756
757 ast_debug(1, "Crypto line: a=crypto:%s\n", p->a_crypto);
758
759 return 0;
760}
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
char * a_crypto
Definition: res_srtp.c:661

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 669 of file res_srtp.c.

670{
671 if (crypto) {
672 ast_free(crypto->a_crypto);
673 crypto->a_crypto = NULL;
674 ast_free(crypto);
675
677 }
678}

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 830 of file res_srtp.c.

831{
832 char *str = NULL;
833 char *tag = NULL;
834 char *suite = NULL;
835 char *key_params = NULL;
836 char *key_param = NULL;
837 char *session_params = NULL;
838 char *key_salt = NULL; /* The actual master key and key salt */
839 char *lifetime = NULL; /* Key lifetime (# of RTP packets) */
840 char *mki = NULL; /* Master Key Index */
841 int found = 0;
842 int key_len_from_sdp;
843 int key_len_expected;
844 int tag_from_sdp;
845 int suite_val = 0;
846 unsigned char remote_key[SRTP_MAX_KEY_LEN];
847 int taglen;
848 double sdes_lifetime;
849 struct ast_sdp_crypto *crypto;
850 struct ast_sdp_srtp *tmp;
851
852 str = ast_strdupa(attr);
853
854 tag = strsep(&str, " ");
855 suite = strsep(&str, " ");
856 key_params = strsep(&str, " ");
857 session_params = strsep(&str, " ");
858
859 if (!tag || !suite) {
860 ast_log(LOG_WARNING, "Unrecognized crypto attribute a=%s\n", attr);
861 return -1;
862 }
863
864 /* RFC4568 9.1 - tag is 1-9 digits */
865 if (sscanf(tag, "%30d", &tag_from_sdp) != 1 || tag_from_sdp < 0 || tag_from_sdp > 999999999) {
866 ast_log(LOG_WARNING, "Unacceptable a=crypto tag: %s\n", tag);
867 return -1;
868 }
869
870 if (!ast_strlen_zero(session_params)) {
871 ast_log(LOG_WARNING, "Unsupported crypto parameters: %s\n", session_params);
872 return -1;
873 }
874
875 /* On egress, Asterisk sent several crypto lines in the SIP/SDP offer
876 The remote party might have choosen another line than the first */
877 for (tmp = srtp; tmp && tmp->crypto && tmp->crypto->tag != tag_from_sdp;) {
878 tmp = AST_LIST_NEXT(tmp, sdp_srtp_list);
879 }
880 if (tmp) { /* tag matched an already created crypto line */
881 unsigned int flags = tmp->flags;
882
883 /* Make that crypto line the head of the list, not by changing the
884 list structure but by exchanging the content of the list members */
885 crypto = tmp->crypto;
886 tmp->crypto = srtp->crypto;
887 tmp->flags = srtp->flags;
888 srtp->crypto = crypto;
889 srtp->flags = flags;
890 } else {
891 crypto = srtp->crypto;
892 crypto->tag = tag_from_sdp;
893 }
894
902
903 if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80")) {
904 suite_val = AST_AES_CM_128_HMAC_SHA1_80;
906 key_len_expected = 30;
907 } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
908 suite_val = AST_AES_CM_128_HMAC_SHA1_32;
910 key_len_expected = 30;
911#if defined(HAVE_SRTP_192) && defined(ENABLE_SRTP_AES_192)
912 } else if (!strcmp(suite, "AES_192_CM_HMAC_SHA1_80")) {
913 suite_val = AST_AES_CM_192_HMAC_SHA1_80;
916 key_len_expected = 38;
917 } else if (!strcmp(suite, "AES_192_CM_HMAC_SHA1_32")) {
918 suite_val = AST_AES_CM_192_HMAC_SHA1_32;
921 key_len_expected = 38;
922 /* RFC used a different name while in draft, some still use that */
923 } else if (!strcmp(suite, "AES_CM_192_HMAC_SHA1_80")) {
924 suite_val = AST_AES_CM_192_HMAC_SHA1_80;
928 key_len_expected = 38;
929 } else if (!strcmp(suite, "AES_CM_192_HMAC_SHA1_32")) {
930 suite_val = AST_AES_CM_192_HMAC_SHA1_32;
934 key_len_expected = 38;
935#endif
936#if defined(HAVE_SRTP_256) && defined(ENABLE_SRTP_AES_256)
937 } else if (!strcmp(suite, "AES_256_CM_HMAC_SHA1_80")) {
938 suite_val = AST_AES_CM_256_HMAC_SHA1_80;
941 key_len_expected = 46;
942 } else if (!strcmp(suite, "AES_256_CM_HMAC_SHA1_32")) {
943 suite_val = AST_AES_CM_256_HMAC_SHA1_32;
946 key_len_expected = 46;
947 /* RFC used a different name while in draft, some still use that */
948 } else if (!strcmp(suite, "AES_CM_256_HMAC_SHA1_80")) {
949 suite_val = AST_AES_CM_256_HMAC_SHA1_80;
953 key_len_expected = 46;
954 } else if (!strcmp(suite, "AES_CM_256_HMAC_SHA1_32")) {
955 suite_val = AST_AES_CM_256_HMAC_SHA1_32;
959 key_len_expected = 46;
960#endif
961#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM)
962 } else if (!strcmp(suite, "AEAD_AES_128_GCM")) {
963 suite_val = AST_AES_GCM_128;
965 key_len_expected = AES_128_GCM_KEYSIZE_WSALT;
966 /* RFC contained a (too) short auth tag for RTP media, some still use that */
967 } else if (!strcmp(suite, "AEAD_AES_128_GCM_8")) {
968 suite_val = AST_AES_GCM_128_8;
970 key_len_expected = AES_128_GCM_KEYSIZE_WSALT;
971#endif
972#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM) && defined(ENABLE_SRTP_AES_256)
973 } else if (!strcmp(suite, "AEAD_AES_256_GCM")) {
974 suite_val = AST_AES_GCM_256;
977 key_len_expected = AES_256_GCM_KEYSIZE_WSALT;
978 /* RFC contained a (too) short auth tag for RTP media, some still use that */
979 } else if (!strcmp(suite, "AEAD_AES_256_GCM_8")) {
980 suite_val = AST_AES_GCM_256_8;
983 key_len_expected = AES_256_GCM_KEYSIZE_WSALT;
984#endif
985 } else {
986 ast_debug(3, "Unsupported crypto suite: %s\n", suite);
987 return -1;
988 }
989
990 while ((key_param = strsep(&key_params, ";"))) {
991 unsigned int n_lifetime;
992 char *method = NULL;
993 char *info = NULL;
994
995 method = strsep(&key_param, ":");
996 info = strsep(&key_param, ";");
997 sdes_lifetime = 0;
998
999 if (strcmp(method, "inline")) {
1000 continue;
1001 }
1002
1003 key_salt = strsep(&info, "|");
1004
1005 /* The next parameter can be either lifetime or MKI */
1006 lifetime = strsep(&info, "|");
1007 if (!lifetime) {
1008 found = 1;
1009 break;
1010 }
1011
1012 mki = strchr(lifetime, ':');
1013 if (mki) {
1014 mki = lifetime;
1015 lifetime = NULL;
1016 } else {
1017 mki = strsep(&info, "|");
1018 }
1019
1020 if (mki && *mki != '1') {
1021 ast_log(LOG_NOTICE, "Crypto MKI handling is not supported: ignoring attribute %s\n", attr);
1022 continue;
1023 }
1024
1025 if (lifetime) {
1026 if (!strncmp(lifetime, "2^", 2)) {
1027 char *lifetime_val = lifetime + 2;
1028
1029 /* Exponential lifetime */
1030 if (sscanf(lifetime_val, "%30u", &n_lifetime) != 1) {
1031 ast_log(LOG_NOTICE, "Failed to parse lifetime value in crypto attribute: %s\n", attr);
1032 continue;
1033 }
1034
1035 if (n_lifetime > 48) {
1036 /* Yeah... that's a bit big. */
1037 ast_log(LOG_NOTICE, "Crypto lifetime exponent of '%u' is a bit large; using 48\n", n_lifetime);
1038 n_lifetime = 48;
1039 }
1040 sdes_lifetime = pow(2, n_lifetime);
1041 } else {
1042 /* Decimal lifetime */
1043 if (sscanf(lifetime, "%30u", &n_lifetime) != 1) {
1044 ast_log(LOG_NOTICE, "Failed to parse lifetime value in crypto attribute: %s\n", attr);
1045 continue;
1046 }
1047 sdes_lifetime = n_lifetime;
1048 }
1049
1050 /* Accept anything above ~5.8 hours. Less than ~5.8; reject. */
1051 if (sdes_lifetime < 1048576) {
1052 ast_log(LOG_NOTICE, "Rejecting crypto attribute '%s': lifetime '%f' too short\n", attr, sdes_lifetime);
1053 continue;
1054 }
1055 }
1056
1057 ast_debug(2, "Crypto attribute '%s' accepted with lifetime '%f', MKI '%s'\n",
1058 attr, sdes_lifetime, mki ? mki : "-");
1059
1060 found = 1;
1061 break;
1062 }
1063
1064 if (!found) {
1065 ast_log(LOG_NOTICE, "SRTP crypto offer not acceptable: '%s'\n", attr);
1066 return -1;
1067 }
1068
1069 key_len_from_sdp = ast_base64decode(remote_key, key_salt, sizeof(remote_key));
1070 if (key_len_from_sdp != key_len_expected) {
1071 ast_log(LOG_WARNING, "SRTP descriptions key length is '%d', not '%d'\n",
1072 key_len_from_sdp, key_len_expected);
1073 return -1;
1074 }
1075
1076 /* on default, the key is 30 (AES-128); throw that away (only) when the suite changed actually */
1077 /* ingress: optional, but saves one expensive call to get_random(.) */
1078 /* egress: required, because the local key was communicated before the remote key is processed */
1079 if (crypto->key_len != key_len_from_sdp) {
1080 if (!crypto_init_keys(crypto, key_len_from_sdp)) {
1081 return -1;
1082 }
1083 } else if (!memcmp(crypto->remote_key, remote_key, key_len_from_sdp)) {
1084 ast_debug(1, "SRTP remote key unchanged; maintaining current policy\n");
1085 return 0;
1086 }
1087
1088 if (key_len_from_sdp > sizeof(crypto->remote_key)) {
1090 "SRTP key buffer is %zu although it must be at least %d bytes\n",
1091 sizeof(crypto->remote_key), key_len_from_sdp);
1092 return -1;
1093 }
1094 memcpy(crypto->remote_key, remote_key, key_len_from_sdp);
1095
1096 if (crypto_activate(crypto, suite_val, remote_key, key_len_from_sdp, rtp) < 0) {
1097 return -1;
1098 }
1099
1101 taglen = 32;
1102 } else if (ast_test_flag(srtp, AST_SRTP_CRYPTO_TAG_16)) {
1103 taglen = 16;
1104 } else if (ast_test_flag(srtp, AST_SRTP_CRYPTO_TAG_8)) {
1105 taglen = 8;
1106 } else {
1107 taglen = 80;
1108 }
1110 taglen |= 0x0200;
1111 } else if (ast_test_flag(srtp, AST_SRTP_CRYPTO_AES_192)) {
1112 taglen |= 0x0100;
1113 }
1115 taglen |= 0x0080;
1116 }
1117
1118 /* Finally, rebuild the crypto line */
1119 if (res_sdp_crypto_build_offer(crypto, taglen)) {
1120 return -1;
1121 }
1122
1124 return 0;
1125}
const char * str
Definition: app_jack.c:150
char * strsep(char **str, const char *delims)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#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:778
static struct ast_sdp_crypto * crypto_init_keys(struct ast_sdp_crypto *p, const int key_len)
Definition: res_srtp.c:680
static int res_sdp_crypto_build_offer(struct ast_sdp_crypto *p, int taglen)
Definition: res_srtp.c:731
#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:665
structure for secure RTP audio
Definition: sdp_srtp.h:38
struct ast_sdp_srtp::@283 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(), and ast_sdp_crypto::tag.

◆ 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 1127 of file res_srtp.c.

1128{
1129 int taglen;
1130
1131 if (!srtp) {
1132 return NULL;
1133 }
1134
1135 /* Set encryption properties */
1136 if (!srtp->crypto) {
1137 if (AST_LIST_NEXT(srtp, sdp_srtp_list)) {
1138 srtp->crypto = res_sdp_crypto_alloc();
1139 ast_log(LOG_ERROR, "SRTP SDP list was not empty\n");
1140 } else {
1141 const int len = default_taglen_32 ? AST_SRTP_CRYPTO_TAG_32 : AST_SRTP_CRYPTO_TAG_80;
1142 const int attr[][3] = {
1143 /* This array creates the following list:
1144 * a=crypto:1 AES_CM_128_HMAC_SHA1_ ...
1145 * a=crypto:2 AEAD_AES_128_GCM ...
1146 * a=crypto:3 AES_256_CM_HMAC_SHA1_ ...
1147 * a=crypto:4 AEAD_AES_256_GCM ...
1148 * a=crypto:5 AES_192_CM_HMAC_SHA1_ ...
1149 * something like 'AEAD_AES_192_GCM' is not specified by the RFCs
1150 *
1151 * If you want to prefer another crypto suite or you want to
1152 * exclude a suite, change this array and recompile Asterisk.
1153 * This list cannot be changed from rtp.conf because you should
1154 * know what you are doing. Especially AES-192 and AES-GCM are
1155 * broken in many VoIP clients, see
1156 * https://github.com/cisco/libsrtp/pull/170
1157 * https://github.com/cisco/libsrtp/pull/184
1158 * Furthermore, AES-GCM uses a shorter crypto-suite string which
1159 * causes Nokia phones based on Symbian/S60 to reject the whole
1160 * INVITE with status 500, even if a matching suite was offered.
1161 * AES-256 might just waste your processor cycles, especially if
1162 * your TLS transport is not secured with equivalent grade, see
1163 * https://security.stackexchange.com/q/61361
1164 * Therefore, AES-128 was preferred here.
1165 *
1166 * If you want to enable one of those defines, please, go for
1167 * CFLAGS='-DENABLE_SRTP_AES_GCM' ./configure && sudo make install
1168 */
1169 { len, 0, 30 },
1170#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM)
1172#endif
1173#if defined(HAVE_SRTP_256) && defined(ENABLE_SRTP_AES_256)
1175#endif
1176#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM) && defined(ENABLE_SRTP_AES_256)
1178#endif
1179#if defined(HAVE_SRTP_192) && defined(ENABLE_SRTP_AES_192)
1181#endif
1182 };
1183 struct ast_sdp_srtp *tmp = srtp;
1184 int i;
1185
1186 for (i = 0; i < ARRAY_LEN(attr); i++) {
1187 if (attr[i][0]) {
1188 ast_set_flag(tmp, attr[i][0]);
1189 }
1190 if (attr[i][1]) {
1191 ast_set_flag(tmp, attr[i][1]);
1192 }
1193 tmp->crypto = sdp_crypto_alloc(attr[i][2]); /* key_len */
1194 tmp->crypto->tag = (i + 1); /* tag starts at 1 */
1195
1196 if (i < ARRAY_LEN(attr) - 1) {
1198 tmp = AST_LIST_NEXT(tmp, sdp_srtp_list);
1199 }
1200 }
1201 }
1202 }
1203
1204 if (dtls_enabled) {
1205 /* If DTLS-SRTP is enabled the key details will be pulled from TLS */
1206 return NULL;
1207 }
1208
1209 /* set the key length based on INVITE or settings */
1211 taglen = 80;
1212 } else if (ast_test_flag(srtp, AST_SRTP_CRYPTO_TAG_32)) {
1213 taglen = 32;
1214 } else if (ast_test_flag(srtp, AST_SRTP_CRYPTO_TAG_16)) {
1215 taglen = 16;
1216 } else if (ast_test_flag(srtp, AST_SRTP_CRYPTO_TAG_8)) {
1217 taglen = 8;
1218 } else {
1219 taglen = default_taglen_32 ? 32 : 80;
1220 }
1222 taglen |= 0x0200;
1223 } else if (ast_test_flag(srtp, AST_SRTP_CRYPTO_AES_192)) {
1224 taglen |= 0x0100;
1225 }
1227 taglen |= 0x0080;
1228 }
1229
1230 if (srtp->crypto && (res_sdp_crypto_build_offer(srtp->crypto, taglen) >= 0)) {
1231 return srtp->crypto->a_crypto;
1232 }
1233
1234 ast_log(LOG_WARNING, "No SRTP key management enabled\n");
1235 return NULL;
1236}
static struct ast_sdp_crypto * res_sdp_crypto_alloc(void)
Definition: res_srtp.c:726
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:703

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 ast_sdp_crypto::tag.

◆ res_srtp_init()

static int res_srtp_init ( void  )
static

Definition at line 1257 of file res_srtp.c.

1258{
1259 if (g_initialized) {
1260 return 0;
1261 }
1262
1263 if (srtp_init() != err_status_ok) {
1264 ast_log(AST_LOG_WARNING, "Failed to initialize libsrtp\n");
1265 return -1;
1266 }
1267
1268 srtp_install_event_handler(srtp_event_cb);
1269
1271 ast_log(AST_LOG_WARNING, "Failed to register SRTP with rtp engine\n");
1273 return -1;
1274 }
1275
1277 ast_log(AST_LOG_WARNING, "Failed to register SDP SRTP crypto API\n");
1279 return -1;
1280 }
1281
1282#ifdef HAVE_SRTP_GET_VERSION
1283 ast_verb(2, "%s initialized\n", srtp_get_version_string());
1284#else
1285 ast_verb(2, "libsrtp initialized\n");
1286#endif
1287
1288 g_initialized = 1;
1289 return 0;
1290}
static void res_srtp_shutdown(void)
Definition: res_srtp.c:1246
static void srtp_event_cb(srtp_event_data_t *data)
Definition: res_srtp.c:239
static struct ast_sdp_crypto_api res_sdp_crypto_api
Definition: res_srtp.c:1238
static int g_initialized
Definition: res_srtp.c:108
int ast_rtp_engine_register_srtp(struct ast_srtp_res *srtp_res, struct ast_srtp_policy_res *policy_res)
Definition: rtp_engine.c:2916
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 215 of file res_srtp.c.

216{
217 struct ast_srtp *srtp;
218
219 if (!(srtp = ast_calloc(1, sizeof(*srtp)))) {
220 ast_log(LOG_ERROR, "Unable to allocate memory for srtp\n");
221 return NULL;
222 }
223
225 policy_hash_fn, NULL, policy_cmp_fn, "SRTP policy container");
226 if (!srtp->policies) {
227 ast_free(srtp);
228 return NULL;
229 }
230
231 srtp->warned = 1;
232
233 return srtp;
234}
@ 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:196
static int policy_hash_fn(const void *obj, const int flags)
Definition: res_srtp.c:189

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 1246 of file res_srtp.c.

1247{
1250 srtp_install_event_handler(NULL);
1251#ifdef HAVE_SRTP_SHUTDOWN
1252 srtp_shutdown();
1253#endif
1254 g_initialized = 0;
1255}
void ast_rtp_engine_unregister_srtp(void)
Definition: rtp_engine.c:2931
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 707 of file res_srtp.c.

708{
709 struct ast_sdp_crypto *p, *result;
710
711 if (!(p = ast_calloc(1, sizeof(*p)))) {
712 return NULL;
713 }
714 p->tag = 1;
716
717 /* default is a key which uses AST_AES_CM_128_HMAC_SHA1_xx */
719 if (!result) {
721 }
722
723 return result;
724}
static PGresult * result
Definition: cel_pgsql.c:84
static void res_sdp_crypto_dtor(struct ast_sdp_crypto *crypto)
Definition: res_srtp.c:669

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 762 of file res_srtp.c.

763{
764 if (policy_res.set_master_key(policy, master_key, key_len, NULL, 0) < 0) {
765 return -1;
766 }
767
768 if (policy_res.set_suite(policy, suite_val)) {
769 ast_log(LOG_WARNING, "Could not set remote SRTP suite\n");
770 return -1;
771 }
772
773 policy_res.set_ssrc(policy, ssrc, inbound);
774
775 return 0;
776}
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 149 of file res_srtp.c.

150{
151 switch(err) {
152 case err_status_ok:
153 return "nothing to report";
154 case err_status_fail:
155 return "unspecified failure";
157 return "unsupported parameter";
159 return "couldn't allocate memory";
161 return "couldn't deallocate properly";
163 return "couldn't initialize";
165 return "can't process as much data as requested";
167 return "authentication failure";
169 return "cipher failure";
171 return "replay check failed (bad index)";
173 return "replay check failed (index too old)";
175 return "algorithm failed test routine";
177 return "unsupported operation";
179 return "no appropriate context found";
181 return "unable to perform desired validation";
183 return "can't use key any more";
184 default:
185 return "unknown";
186 }
187}
#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 239 of file res_srtp.c.

240{
241 switch (data->event) {
242 case event_ssrc_collision:
243 ast_debug(1, "SSRC collision\n");
244 break;
245 case event_key_soft_limit:
246 ast_debug(1, "event_key_soft_limit\n");
247 break;
248 case event_key_hard_limit:
249 ast_debug(1, "event_key_hard_limit\n");
250 break;
251 case event_packet_index_limit:
252 ast_debug(1, "event_packet_index_limit\n");
253 break;
254 }
255}

References ast_debug, and ast_srtp::data.

Referenced by res_srtp_init().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1301 of file res_srtp.c.

1302{
1304 return 0;
1305}

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 1312 of file res_srtp.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1312 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 108 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 1238 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 129 of file res_srtp.c.

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