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

Secure RTP (SRTP) More...

#include "asterisk.h"
#include <math.h>
#include <srtp2/srtp.h>
#include "srtp/srtp_compat.h"
#include <openssl/rand.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[email protected]@use[email protected]rs.so[email protected]urce[email protected]forge[email protected].net

Definition in file res_srtp.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1281 of file res_srtp.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1281 of file res_srtp.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

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

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().

574 {
575  struct ast_srtp_policy *match;
576 
577  /* For existing streams, replace if its an SSRC stream, or bail if its a wildcard */
578  if ((match = find_policy(srtp, &policy->sp, OBJ_POINTER))) {
579  if (policy->sp.ssrc.type != ssrc_specific) {
580  ast_log(AST_LOG_WARNING, "Cannot replace an existing wildcard policy\n");
581  ao2_t_ref(match, -1, "Unreffing already existing policy");
582  return -1;
583  } else {
584  if (srtp_remove_stream(srtp->session, match->sp.ssrc.value) != err_status_ok) {
585  ast_log(AST_LOG_WARNING, "Failed to remove SRTP stream for SSRC %u\n", match->sp.ssrc.value);
586  }
587  ao2_t_unlink(srtp->policies, match, "Remove existing match policy");
588  ao2_t_ref(match, -1, "Unreffing already existing policy");
589  }
590  }
591 
592  ast_debug(3, "Adding new policy for %s %u\n",
593  policy->sp.ssrc.type == ssrc_specific ? "SSRC" : "type",
594  policy->sp.ssrc.type == ssrc_specific ? policy->sp.ssrc.value : policy->sp.ssrc.type);
595  if (srtp_add_stream(srtp->session, &policy->sp) != err_status_ok) {
596  ast_log(AST_LOG_WARNING, "Failed to add SRTP stream for %s %u\n",
597  policy->sp.ssrc.type == ssrc_specific ? "SSRC" : "type",
598  policy->sp.ssrc.type == ssrc_specific ? policy->sp.ssrc.value : policy->sp.ssrc.type);
599  return -1;
600  }
601 
602  ao2_t_link(srtp->policies, policy, "Added additional stream");
603 
604  return 0;
605 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
#define OBJ_POINTER
Definition: astobj2.h:1154
#define AST_LOG_WARNING
Definition: logger.h:279
#define ao2_t_link(container, obj, tag)
Add an object to a container.
Definition: astobj2.h:1547
#define ao2_t_unlink(container, obj, tag)
Remove an object from a container.
Definition: astobj2.h:1596
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:2315
struct ao2_container * policies
Definition: res_srtp.c:67
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static struct ast_srtp_policy * find_policy(struct ast_srtp *srtp, const srtp_policy_t *policy, int flags)
Definition: res_srtp.c:176
srtp_t session
Definition: res_srtp.c:68
#define err_status_ok
Definition: srtp_compat.h:32
srtp_policy_t sp
Definition: res_srtp.c:77

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

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, ast_srtp_policy::sp, and status.

608 {
609  struct ast_srtp_policy *match;
610  struct srtp_policy_t sp = {
611  .ssrc.type = ssrc_specific,
612  .ssrc.value = from_ssrc,
613  };
615 
616  /* If we find a match, return and unlink it from the container so we
617  * can change the SSRC (which is part of the hash) and then have
618  * ast_srtp_add_stream link it back in if all is well */
619  if ((match = find_policy(srtp, &sp, OBJ_POINTER | OBJ_UNLINK))) {
620  match->sp.ssrc.value = to_ssrc;
621  if (ast_srtp_add_stream(srtp, match)) {
622  ast_log(LOG_WARNING, "Couldn't add stream\n");
623  } else if ((status = srtp_remove_stream(srtp->session, from_ssrc))) {
624  ast_debug(3, "Couldn't remove stream (%u)\n", status);
625  }
626  ao2_t_ref(match, -1, "Unreffing found policy in change_source");
627  }
628 
629  return 0;
630 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
#define OBJ_POINTER
Definition: astobj2.h:1154
#define LOG_WARNING
Definition: logger.h:274
#define err_status_t
Definition: srtp_compat.h:31
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:2315
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static struct ast_srtp_policy * find_policy(struct ast_srtp *srtp, const srtp_policy_t *policy, int flags)
Definition: res_srtp.c:176
static int ast_srtp_add_stream(struct ast_srtp *srtp, struct ast_srtp_policy *policy)
Definition: res_srtp.c:573
srtp_t session
Definition: res_srtp.c:68
jack_status_t status
Definition: app_jack.c:146
srtp_policy_t sp
Definition: res_srtp.c:77

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

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().

515 {
516  struct ast_srtp *temp;
517  int status;
518 
519  if (!(temp = res_srtp_new())) {
520  return -1;
521  }
523 
524  /* Any failures after this point can use ast_srtp_destroy to destroy the instance */
525  status = srtp_create(&temp->session, &policy->sp);
526  if (status != err_status_ok) {
527  /* Session either wasn't created or was created and dealloced. */
528  temp->session = NULL;
529  ast_srtp_destroy(temp);
530  ast_log(LOG_ERROR, "Failed to create srtp session on rtp instance (%p) - %s\n",
531  rtp, srtp_errstr(status));
532  return -1;
533  }
534 
535  temp->rtp = rtp;
536  *srtp = temp;
537 
538  ao2_t_link((*srtp)->policies, policy, "Created initial policy");
539 
540  return 0;
541 }
#define ao2_t_link(container, obj, tag)
Add an object to a container.
Definition: astobj2.h:1547
#define NULL
Definition: resample.c:96
static void ast_srtp_destroy(struct ast_srtp *srtp)
Definition: res_srtp.c:560
#define ast_log
Definition: astobj2.c:42
struct ast_module * self
Definition: module.h:342
#define LOG_ERROR
Definition: logger.h:285
static struct ast_srtp * res_srtp_new(void)
Definition: res_srtp.c:188
static const char * srtp_errstr(int err)
Definition: res_srtp.c:122
srtp_t session
Definition: res_srtp.c:68
#define err_status_ok
Definition: srtp_compat.h:32
struct ast_rtp_instance * rtp
Definition: res_srtp.c:66
jack_status_t status
Definition: app_jack.c:146
srtp_policy_t sp
Definition: res_srtp.c:77
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:443

◆ ast_srtp_destroy()

static void ast_srtp_destroy ( struct ast_srtp srtp)
static

Definition at line 560 of file res_srtp.c.

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().

561 {
562  if (srtp->session) {
563  srtp_dealloc(srtp->session);
564  }
565 
566  ao2_t_callback(srtp->policies, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "Unallocate policy");
567  ao2_t_ref(srtp->policies, -1, "Destroying container");
568 
569  ast_free(srtp);
571 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
struct ao2_container * policies
Definition: res_srtp.c:67
#define NULL
Definition: resample.c:96
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
struct ast_module * self
Definition: module.h:342
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:1714
#define ast_free(a)
Definition: astmm.h:182
srtp_t session
Definition: res_srtp.c:68

◆ ast_srtp_get_random()

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

Definition at line 347 of file res_srtp.c.

References err_status_ok.

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

◆ ast_srtp_policy_alloc()

static struct ast_srtp_policy * ast_srtp_policy_alloc ( void  )
static

Definition at line 251 of file res_srtp.c.

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

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

◆ ast_srtp_policy_destroy()

static void ast_srtp_policy_destroy ( struct ast_srtp_policy policy)
static

Definition at line 262 of file res_srtp.c.

References ao2_t_ref.

263 {
264  ao2_t_ref(policy, -1, "Destroying policy");
265 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463

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

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

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

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

References ast_srtp_policy::sp.

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

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

References policy_set_suite(), and ast_srtp_policy::sp.

321 {
322  return policy_set_suite(&policy->sp.rtp, suite) | policy_set_suite(&policy->sp.rtcp, suite);
323 }
static int policy_set_suite(crypto_policy_t *p, enum ast_srtp_suite suite)
Definition: res_srtp.c:267
srtp_policy_t sp
Definition: res_srtp.c:77

◆ ast_srtp_protect()

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

Definition at line 486 of file res_srtp.c.

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

487 {
488  int res;
489  unsigned char *localbuf;
490 
491  if (!srtp->session) {
492  ast_log(LOG_ERROR, "SRTP protect %s - missing session\n", rtcp ? "rtcp" : "rtp");
493  errno = EINVAL;
494  return -1;
495  }
496 
497  if ((*len + SRTP_MAX_TRAILER_LEN) > sizeof(srtp->buf)) {
498  return -1;
499  }
500 
501  localbuf = rtcp ? srtp->rtcpbuf : srtp->buf;
502 
503  memcpy(localbuf, *buf, *len);
504 
505  if ((res = rtcp ? srtp_protect_rtcp(srtp->session, localbuf, len) : srtp_protect(srtp->session, localbuf, len)) != err_status_ok && res != err_status_replay_fail) {
506  ast_log(LOG_WARNING, "SRTP protect: %s\n", srtp_errstr(res));
507  return -1;
508  }
509 
510  *buf = localbuf;
511  return *len;
512 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
unsigned char rtcpbuf[8192+AST_FRIENDLY_OFFSET]
Definition: res_srtp.c:73
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int errno
static const char * srtp_errstr(int err)
Definition: res_srtp.c:122
srtp_t session
Definition: res_srtp.c:68
#define err_status_replay_fail
Definition: srtp_compat.h:41
#define err_status_ok
Definition: srtp_compat.h:32
unsigned char buf[8192+AST_FRIENDLY_OFFSET]
Definition: res_srtp.c:72

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

References ast_log, ast_srtp_create(), ast_srtp_destroy(), and LOG_ERROR.

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

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

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

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

◆ ast_srtp_unprotect()

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

Definition at line 367 of file res_srtp.c.

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, 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.

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

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

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, and set_crypto_policy().

Referenced by res_sdp_crypto_parse_offer().

751 {
752  struct ast_srtp_policy *local_policy = NULL;
753  struct ast_srtp_policy *remote_policy = NULL;
754  struct ast_rtp_instance_stats stats = {0,};
755  int res = -1;
756 
757  if (!p) {
758  return -1;
759  }
760 
761  if (!(local_policy = policy_res.alloc())) {
762  return -1;
763  }
764 
765  if (!(remote_policy = policy_res.alloc())) {
766  goto err;
767  }
768 
770  goto err;
771  }
772 
773  if (set_crypto_policy(local_policy, suite_val, p->local_key, key_len, stats.local_ssrc, 0) < 0) {
774  goto err;
775  }
776 
777  if (set_crypto_policy(remote_policy, suite_val, remote_key, key_len, 0, 1) < 0) {
778  goto err;
779  }
780 
781  /* Add the SRTP policies */
782  if (ast_rtp_instance_add_srtp_policy(rtp, remote_policy, local_policy, 0)) {
783  ast_log(LOG_WARNING, "Could not set SRTP policies\n");
784  goto err;
785  }
786 
787  ast_debug(1 , "SRTP policy activated\n");
788  res = 0;
789 
790 err:
791  if (local_policy) {
792  policy_res.destroy(local_policy);
793  }
794 
795  if (remote_policy) {
796  policy_res.destroy(remote_policy);
797  }
798 
799  return res;
800 }
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:2446
#define LOG_WARNING
Definition: logger.h:274
struct ast_srtp_policy *(* alloc)(void)
Definition: res_srtp.h:71
#define NULL
Definition: resample.c:96
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:2736
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static struct ast_srtp_policy_res policy_res
Definition: res_srtp.c:114
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:734
unsigned int local_ssrc
Definition: rtp_engine.h:422
unsigned char local_key[SRTP_MAX_KEY_LEN]
Definition: res_srtp.c:634
void(* destroy)(struct ast_srtp_policy *policy)
Definition: res_srtp.h:72

◆ crypto_init_keys()

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

Definition at line 652 of file res_srtp.c.

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, and ast_sdp_crypto::remote_key.

Referenced by res_sdp_crypto_parse_offer(), and sdp_crypto_alloc().

653 {
654  unsigned char remote_key[key_len];
655 
656  if (srtp_res.get_random(p->local_key, key_len) < 0) {
657  return NULL;
658  }
659 
660  ast_base64encode(p->local_key64, p->local_key, key_len, sizeof(p->local_key64));
661 
662  p->key_len = ast_base64decode(remote_key, p->local_key64, sizeof(remote_key));
663 
664  if (p->key_len != key_len) {
665  ast_log(LOG_ERROR, "base64 encode/decode bad len %d != %d\n", p->key_len, key_len);
666  return NULL;
667  }
668 
669  if (memcmp(remote_key, p->local_key, p->key_len)) {
670  ast_log(LOG_ERROR, "base64 encode/decode bad key\n");
671  return NULL;
672  }
673 
674  ast_debug(1 , "local_key64 %s len %zu\n", p->local_key64, strlen(p->local_key64));
675 
676  return p;
677 }
#define NULL
Definition: resample.c:96
static struct ast_srtp_res srtp_res
Definition: res_srtp.c:102
int ast_base64decode(unsigned char *dst, const char *src, int max)
Decode data from base64.
Definition: main/utils.c:294
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
Definition: main/utils.c:404
unsigned char local_key[SRTP_MAX_KEY_LEN]
Definition: res_srtp.c:634
int(* get_random)(unsigned char *key, size_t len)
Definition: res_srtp.h:52
char local_key64[((SRTP_MAX_KEY_LEN) *8+5)/6+1]
Definition: res_srtp.c:636

◆ find_policy()

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

Definition at line 176 of file res_srtp.c.

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

Referenced by ast_srtp_add_stream(), and ast_srtp_change_source().

177 {
178  struct ast_srtp_policy tmp = {
179  .sp = {
180  .ssrc.type = policy->ssrc.type,
181  .ssrc.value = policy->ssrc.value,
182  },
183  };
184 
185  return ao2_t_find(srtp->policies, &tmp, flags, "Looking for policy");
186 }
static int tmp()
Definition: bt_open.c:389
struct ao2_container * policies
Definition: res_srtp.c:67
#define ao2_t_find(container, arg, flags, tag)
Definition: astobj2.h:1754

◆ load_module()

static int load_module ( void  )
static

Definition at line 1265 of file res_srtp.c.

References res_srtp_init().

Referenced by unload_module().

1266 {
1267  return res_srtp_init();
1268 }
static int res_srtp_init(void)
Definition: res_srtp.c:1226

◆ policy_cmp_fn()

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

Definition at line 169 of file res_srtp.c.

References ast_srtp_policy::sp.

Referenced by res_srtp_new().

170 {
171  const struct ast_srtp_policy *one = obj, *two = arg;
172 
173  return one->sp.ssrc.type == two->sp.ssrc.type && one->sp.ssrc.value == two->sp.ssrc.value;
174 }
srtp_policy_t sp
Definition: res_srtp.c:77

◆ policy_destructor()

static void policy_destructor ( void *  obj)
static

Definition at line 241 of file res_srtp.c.

References ast_free, NULL, and ast_srtp_policy::sp.

Referenced by ast_srtp_policy_alloc().

242 {
243  struct ast_srtp_policy *policy = obj;
244 
245  if (policy->sp.key) {
246  ast_free(policy->sp.key);
247  policy->sp.key = NULL;
248  }
249 }
#define NULL
Definition: resample.c:96
#define ast_free(a)
Definition: astmm.h:182
srtp_policy_t sp
Definition: res_srtp.c:77

◆ policy_hash_fn()

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

Definition at line 162 of file res_srtp.c.

References ast_srtp_policy::sp.

Referenced by res_srtp_new().

163 {
164  const struct ast_srtp_policy *policy = obj;
165 
166  return policy->sp.ssrc.type == ssrc_specific ? policy->sp.ssrc.value : policy->sp.ssrc.type;
167 }
srtp_policy_t sp
Definition: res_srtp.c:77

◆ policy_set_suite()

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

Definition at line 267 of file res_srtp.c.

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().

268 {
269  switch (suite) {
272  return 0;
273 
276  return 0;
277 
278 #ifdef HAVE_SRTP_192
281  return 0;
282 
285  return 0;
286 #endif
287 #ifdef HAVE_SRTP_256
290  return 0;
291 
294  return 0;
295 #endif
296 #ifdef HAVE_SRTP_GCM
297  case AST_AES_GCM_128:
299  return 0;
300 
301  case AST_AES_GCM_256:
303  return 0;
304 
305  case AST_AES_GCM_128_8:
307  return 0;
308 
309  case AST_AES_GCM_256_8:
311  return 0;
312 #endif
313 
314  default:
315  ast_log(LOG_ERROR, "Invalid crypto suite: %u\n", suite);
316  return -1;
317  }
318 }
#define crypto_policy_set_aes_cm_192_hmac_sha1_32
Definition: srtp_compat.h:11
#define crypto_policy_set_aes_cm_192_hmac_sha1_80
Definition: srtp_compat.h:10
#define crypto_policy_set_aes_cm_256_hmac_sha1_80
Definition: srtp_compat.h:12
#define crypto_policy_set_aes_cm_128_hmac_sha1_80
Definition: srtp_compat.h:8
#define ast_log
Definition: astobj2.c:42
#define crypto_policy_set_aes_gcm_128_16_auth
Definition: srtp_compat.h:14
#define crypto_policy_set_aes_gcm_256_8_auth
Definition: srtp_compat.h:17
#define LOG_ERROR
Definition: logger.h:285
#define crypto_policy_set_aes_gcm_128_8_auth
Definition: srtp_compat.h:16
#define crypto_policy_set_aes_gcm_256_16_auth
Definition: srtp_compat.h:15
#define crypto_policy_set_aes_cm_128_hmac_sha1_32
Definition: srtp_compat.h:9
#define crypto_policy_set_aes_cm_256_hmac_sha1_32
Definition: srtp_compat.h:13

◆ res_sdp_crypto_alloc()

static struct ast_sdp_crypto* res_sdp_crypto_alloc ( void  )
static

Definition at line 698 of file res_srtp.c.

References sdp_crypto_alloc(), and SRTP_MASTER_KEY_LEN.

Referenced by res_sdp_srtp_get_attr().

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

◆ res_sdp_crypto_build_offer()

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

Definition at line 703 of file res_srtp.c.

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().

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

◆ res_sdp_crypto_dtor()

static void res_sdp_crypto_dtor ( struct ast_sdp_crypto crypto)
static

Definition at line 641 of file res_srtp.c.

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

Referenced by sdp_crypto_alloc().

642 {
643  if (crypto) {
644  ast_free(crypto->a_crypto);
645  crypto->a_crypto = NULL;
646  ast_free(crypto);
647 
649  }
650 }
#define NULL
Definition: resample.c:96
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
struct ast_module * self
Definition: module.h:342
char * a_crypto
Definition: res_srtp.c:633
#define ast_free(a)
Definition: astmm.h:182

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

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_verb, 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().

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

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

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, ast_sdp_crypto::tag, and tmp().

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

◆ res_srtp_init()

static int res_srtp_init ( void  )
static

Definition at line 1226 of file res_srtp.c.

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

Referenced by load_module().

1227 {
1228  if (g_initialized) {
1229  return 0;
1230  }
1231 
1232  if (srtp_init() != err_status_ok) {
1233  ast_log(AST_LOG_WARNING, "Failed to initialize libsrtp\n");
1234  return -1;
1235  }
1236 
1237  srtp_install_event_handler(srtp_event_cb);
1238 
1240  ast_log(AST_LOG_WARNING, "Failed to register SRTP with rtp engine\n");
1242  return -1;
1243  }
1244 
1246  ast_log(AST_LOG_WARNING, "Failed to register SDP SRTP crypto API\n");
1248  return -1;
1249  }
1250 
1251 #ifdef HAVE_SRTP_GET_VERSION
1252  ast_verb(2, "%s initialized\n", srtp_get_version_string());
1253 #else
1254  ast_verb(2, "libsrtp initialized\n");
1255 #endif
1256 
1257  g_initialized = 1;
1258  return 0;
1259 }
static void res_srtp_shutdown(void)
Definition: res_srtp.c:1215
#define AST_LOG_WARNING
Definition: logger.h:279
static struct ast_srtp_res srtp_res
Definition: res_srtp.c:102
#define ast_verb(level,...)
Definition: logger.h:463
static struct ast_sdp_crypto_api res_sdp_crypto_api
Definition: res_srtp.c:1207
#define ast_log
Definition: astobj2.c:42
static struct ast_srtp_policy_res policy_res
Definition: res_srtp.c:114
int ast_rtp_engine_register_srtp(struct ast_srtp_res *srtp_res, struct ast_srtp_policy_res *policy_res)
Definition: rtp_engine.c:2710
static void srtp_event_cb(srtp_event_data_t *data)
Definition: res_srtp.c:212
int ast_sdp_crypto_register(struct ast_sdp_crypto_api *api)
Register SDP SRTP crypto processing routines.
Definition: sdp_srtp.c:123
#define err_status_ok
Definition: srtp_compat.h:32
static int g_initialized
Definition: res_srtp.c:81

◆ res_srtp_new()

static struct ast_srtp* res_srtp_new ( void  )
static

Definition at line 188 of file res_srtp.c.

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().

189 {
190  struct ast_srtp *srtp;
191 
192  if (!(srtp = ast_calloc(1, sizeof(*srtp)))) {
193  ast_log(LOG_ERROR, "Unable to allocate memory for srtp\n");
194  return NULL;
195  }
196 
198  policy_hash_fn, NULL, policy_cmp_fn, "SRTP policy container");
199  if (!srtp->policies) {
200  ast_free(srtp);
201  return NULL;
202  }
203 
204  srtp->warned = 1;
205 
206  return srtp;
207 }
static int policy_hash_fn(const void *obj, const int flags)
Definition: res_srtp.c:162
struct ao2_container * policies
Definition: res_srtp.c:67
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
int warned
Definition: res_srtp.c:71
#define LOG_ERROR
Definition: logger.h:285
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
#define ao2_t_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn, tag)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1308
static int policy_cmp_fn(void *obj, void *arg, int flags)
Definition: res_srtp.c:169

◆ res_srtp_shutdown()

static void res_srtp_shutdown ( void  )
static

Definition at line 1215 of file res_srtp.c.

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

Referenced by res_srtp_init(), and unload_module().

1216 {
1219  srtp_install_event_handler(NULL);
1220 #ifdef HAVE_SRTP_SHUTDOWN
1221  srtp_shutdown();
1222 #endif
1223  g_initialized = 0;
1224 }
#define NULL
Definition: resample.c:96
void ast_rtp_engine_unregister_srtp(void)
Definition: rtp_engine.c:2725
static struct ast_sdp_crypto_api res_sdp_crypto_api
Definition: res_srtp.c:1207
void ast_sdp_crypto_unregister(struct ast_sdp_crypto_api *api)
Unregister SDP SRTP crypto processing routines.
Definition: sdp_srtp.c:132
static int g_initialized
Definition: res_srtp.c:81

◆ sdp_crypto_alloc()

static struct ast_sdp_crypto* sdp_crypto_alloc ( const int  key_len)
static

Definition at line 679 of file res_srtp.c.

References ast_calloc, ast_module_ref, crypto_init_keys(), 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().

680 {
681  struct ast_sdp_crypto *p, *result;
682 
683  if (!(p = ast_calloc(1, sizeof(*p)))) {
684  return NULL;
685  }
686  p->tag = 1;
688 
689  /* default is a key which uses AST_AES_CM_128_HMAC_SHA1_xx */
690  result = crypto_init_keys(p, key_len);
691  if (!result) {
693  }
694 
695  return result;
696 }
static void res_sdp_crypto_dtor(struct ast_sdp_crypto *crypto)
Definition: res_srtp.c:641
#define NULL
Definition: resample.c:96
static struct ast_sdp_crypto * crypto_init_keys(struct ast_sdp_crypto *p, const int key_len)
Definition: res_srtp.c:652
struct ast_module * self
Definition: module.h:342
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static PGresult * result
Definition: cel_pgsql.c:88
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:443

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

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

Referenced by crypto_activate().

735 {
736  if (policy_res.set_master_key(policy, master_key, key_len, NULL, 0) < 0) {
737  return -1;
738  }
739 
740  if (policy_res.set_suite(policy, suite_val)) {
741  ast_log(LOG_WARNING, "Could not set remote SRTP suite\n");
742  return -1;
743  }
744 
745  policy_res.set_ssrc(policy, ssrc, inbound);
746 
747  return 0;
748 }
#define LOG_WARNING
Definition: logger.h:274
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
#define NULL
Definition: resample.c:96
int(* set_suite)(struct ast_srtp_policy *policy, enum ast_srtp_suite suite)
Definition: res_srtp.h:73
#define ast_log
Definition: astobj2.c:42
void(* set_ssrc)(struct ast_srtp_policy *policy, unsigned long ssrc, int inbound)
Definition: res_srtp.h:75
static struct ast_srtp_policy_res policy_res
Definition: res_srtp.c:114

◆ srtp_errstr()

static const char* srtp_errstr ( int  err)
static

Definition at line 122 of file res_srtp.c.

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().

123 {
124  switch(err) {
125  case err_status_ok:
126  return "nothing to report";
127  case err_status_fail:
128  return "unspecified failure";
130  return "unsupported parameter";
132  return "couldn't allocate memory";
134  return "couldn't deallocate properly";
136  return "couldn't initialize";
137  case err_status_terminus:
138  return "can't process as much data as requested";
140  return "authentication failure";
142  return "cipher failure";
144  return "replay check failed (bad index)";
146  return "replay check failed (index too old)";
148  return "algorithm failed test routine";
150  return "unsupported operation";
151  case err_status_no_ctx:
152  return "no appropriate context found";
154  return "unable to perform desired validation";
156  return "can't use key any more";
157  default:
158  return "unknown";
159  }
160 }
#define err_status_algo_fail
Definition: srtp_compat.h:43
#define err_status_cant_check
Definition: srtp_compat.h:46
#define err_status_bad_param
Definition: srtp_compat.h:34
#define err_status_dealloc_fail
Definition: srtp_compat.h:36
#define err_status_alloc_fail
Definition: srtp_compat.h:35
#define err_status_cipher_fail
Definition: srtp_compat.h:40
#define err_status_replay_old
Definition: srtp_compat.h:42
#define err_status_no_such_op
Definition: srtp_compat.h:44
#define err_status_init_fail
Definition: srtp_compat.h:37
#define err_status_auth_fail
Definition: srtp_compat.h:39
#define err_status_no_ctx
Definition: srtp_compat.h:45
#define err_status_replay_fail
Definition: srtp_compat.h:41
#define err_status_key_expired
Definition: srtp_compat.h:47
#define err_status_ok
Definition: srtp_compat.h:32
#define err_status_fail
Definition: srtp_compat.h:33
#define err_status_terminus
Definition: srtp_compat.h:38

◆ srtp_event_cb()

static void srtp_event_cb ( srtp_event_data_t *  data)
static

Definition at line 212 of file res_srtp.c.

References ast_debug.

Referenced by res_srtp_init().

213 {
214  switch (data->event) {
215  case event_ssrc_collision:
216  ast_debug(1, "SSRC collision\n");
217  break;
218  case event_key_soft_limit:
219  ast_debug(1, "event_key_soft_limit\n");
220  break;
221  case event_key_hard_limit:
222  ast_debug(1, "event_key_hard_limit\n");
223  break;
224  case event_packet_index_limit:
225  ast_debug(1, "event_packet_index_limit\n");
226  break;
227  }
228 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1270 of file res_srtp.c.

References AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CHANNEL_DEPEND, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ASTERISK_GPL_KEY, load_module(), and res_srtp_shutdown().

1271 {
1273  return 0;
1274 }
static void res_srtp_shutdown(void)
Definition: res_srtp.c:1215

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

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

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

Referenced by res_srtp_init(), and res_srtp_shutdown().

◆ policy_res

struct ast_srtp_policy_res policy_res
static

Definition at line 114 of file res_srtp.c.

Referenced by ast_rtp_engine_register_srtp().

◆ res_sdp_crypto_api

struct ast_sdp_crypto_api res_sdp_crypto_api
static

Definition at line 1207 of file res_srtp.c.

◆ srtp_res

struct ast_srtp_res srtp_res
static

Definition at line 102 of file res_srtp.c.

Referenced by ast_rtp_engine_register_srtp().