Asterisk - The Open Source Telephony Project  GIT-master-a1fa8df
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"

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

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1285 of file res_srtp.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 1285 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 574 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().

575 {
576  struct ast_srtp_policy *match;
577 
578  /* For existing streams, replace if its an SSRC stream, or bail if its a wildcard */
579  if ((match = find_policy(srtp, &policy->sp, OBJ_POINTER))) {
580  if (policy->sp.ssrc.type != ssrc_specific) {
581  ast_log(AST_LOG_WARNING, "Cannot replace an existing wildcard policy\n");
582  ao2_t_ref(match, -1, "Unreffing already existing policy");
583  return -1;
584  } else {
585  if (srtp_remove_stream(srtp->session, match->sp.ssrc.value) != err_status_ok) {
586  ast_log(AST_LOG_WARNING, "Failed to remove SRTP stream for SSRC %u\n", match->sp.ssrc.value);
587  }
588  ao2_t_unlink(srtp->policies, match, "Remove existing match policy");
589  ao2_t_ref(match, -1, "Unreffing already existing policy");
590  }
591  }
592 
593  ast_debug(3, "Adding new policy for %s %u\n",
594  policy->sp.ssrc.type == ssrc_specific ? "SSRC" : "type",
595  policy->sp.ssrc.type == ssrc_specific ? policy->sp.ssrc.value : policy->sp.ssrc.type);
596  if (srtp_add_stream(srtp->session, &policy->sp) != err_status_ok) {
597  ast_log(AST_LOG_WARNING, "Failed to add SRTP stream for %s %u\n",
598  policy->sp.ssrc.type == ssrc_specific ? "SSRC" : "type",
599  policy->sp.ssrc.type == ssrc_specific ? policy->sp.ssrc.value : policy->sp.ssrc.type);
600  return -1;
601  }
602 
603  ao2_t_link(srtp->policies, policy, "Added additional stream");
604 
605  return 0;
606 }
#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:2316
struct ao2_container * policies
Definition: res_srtp.c:67
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#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 608 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.

609 {
610  struct ast_srtp_policy *match;
611  struct srtp_policy_t sp = {
612  .ssrc.type = ssrc_specific,
613  .ssrc.value = from_ssrc,
614  };
616 
617  /* If we find a match, return and unlink it from the container so we
618  * can change the SSRC (which is part of the hash) and then have
619  * ast_srtp_add_stream link it back in if all is well */
620  if ((match = find_policy(srtp, &sp, OBJ_POINTER | OBJ_UNLINK))) {
621  match->sp.ssrc.value = to_ssrc;
622  if (ast_srtp_add_stream(srtp, match)) {
623  ast_log(LOG_WARNING, "Couldn't add stream\n");
624  } else if ((status = srtp_remove_stream(srtp->session, from_ssrc))) {
625  ast_debug(3, "Couldn't remove stream (%u)\n", status);
626  }
627  ao2_t_ref(match, -1, "Unreffing found policy in change_source");
628  }
629 
630  return 0;
631 }
#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:2316
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#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:574
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 515 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().

516 {
517  struct ast_srtp *temp;
518  int status;
519 
520  if (!(temp = res_srtp_new())) {
521  return -1;
522  }
524 
525  /* Any failures after this point can use ast_srtp_destroy to destroy the instance */
526  status = srtp_create(&temp->session, &policy->sp);
527  if (status != err_status_ok) {
528  /* Session either wasn't created or was created and dealloced. */
529  temp->session = NULL;
530  ast_srtp_destroy(temp);
531  ast_log(LOG_ERROR, "Failed to create srtp session on rtp instance (%p) - %s\n",
532  rtp, srtp_errstr(status));
533  return -1;
534  }
535 
536  temp->rtp = rtp;
537  *srtp = temp;
538 
539  ao2_t_link((*srtp)->policies, policy, "Created initial policy");
540 
541  return 0;
542 }
#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:561
#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 561 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().

562 {
563  if (srtp->session) {
564  srtp_dealloc(srtp->session);
565  }
566 
567  ao2_t_callback(srtp->policies, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "Unallocate policy");
568  ao2_t_ref(srtp->policies, -1, "Destroying container");
569 
570  ast_free(srtp);
572 }
#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 348 of file res_srtp.c.

References err_status_ok.

349 {
350 #ifdef HAVE_OPENSSL
351  return RAND_bytes(key, len) > 0 ? 0: -1;
352 #else
353  return crypto_get_random(key, len) != err_status_ok ? -1: 0;
354 #endif
355 }
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 326 of file res_srtp.c.

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

327 {
328  size_t size = key_len + salt_len;
329  unsigned char *master_key;
330 
331  if (policy->sp.key) {
332  ast_free(policy->sp.key);
333  policy->sp.key = NULL;
334  }
335 
336  if (!(master_key = ast_calloc(1, size))) {
337  return -1;
338  }
339 
340  memcpy(master_key, key, key_len);
341  memcpy(master_key + key_len, salt, salt_len);
342 
343  policy->sp.key = master_key;
344 
345  return 0;
346 }
#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 321 of file res_srtp.c.

References policy_set_suite(), and ast_srtp_policy::sp.

322 {
323  return policy_set_suite(&policy->sp.rtp, suite) | policy_set_suite(&policy->sp.rtcp, suite);
324 }
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 487 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().

488 {
489  int res;
490  unsigned char *localbuf;
491 
492  if (!srtp->session) {
493  ast_log(LOG_ERROR, "SRTP protect %s - missing session\n", rtcp ? "rtcp" : "rtp");
494  errno = EINVAL;
495  return -1;
496  }
497 
498  if ((*len + SRTP_MAX_TRAILER_LEN) > sizeof(srtp->buf)) {
499  return -1;
500  }
501 
502  localbuf = rtcp ? srtp->rtcpbuf : srtp->buf;
503 
504  memcpy(localbuf, *buf, *len);
505 
506  if ((res = rtcp ? srtp_protect_rtcp(srtp->session, localbuf, len) : srtp_protect(srtp->session, localbuf, len)) != err_status_ok && res != err_status_replay_fail) {
507  ast_log(LOG_WARNING, "SRTP protect: %s\n", srtp_errstr(res));
508  return -1;
509  }
510 
511  *buf = localbuf;
512  return *len;
513 }
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 544 of file res_srtp.c.

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

545 {
546  struct ast_srtp *old = *srtp;
547  int res = ast_srtp_create(srtp, rtp, policy);
548 
549  if (!res && old) {
550  ast_srtp_destroy(old);
551  }
552 
553  if (res) {
554  ast_log(LOG_ERROR, "Failed to replace srtp (%p) on rtp instance (%p) "
555  "- keeping old\n", *srtp, rtp);
556  }
557 
558  return res;
559 }
static int ast_srtp_create(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy)
Definition: res_srtp.c:515
static void ast_srtp_destroy(struct ast_srtp *srtp)
Definition: res_srtp.c:561
#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 357 of file res_srtp.c.

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

358 {
359  if (!srtp) {
360  return;
361  }
362 
363  srtp->cb = cb;
364  srtp->data = data;
365 }
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 368 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.

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

752 {
753  struct ast_srtp_policy *local_policy = NULL;
754  struct ast_srtp_policy *remote_policy = NULL;
755  struct ast_rtp_instance_stats stats = {0,};
756  int res = -1;
757 
758  if (!p) {
759  return -1;
760  }
761 
762  if (!(local_policy = policy_res.alloc())) {
763  return -1;
764  }
765 
766  if (!(remote_policy = policy_res.alloc())) {
767  goto err;
768  }
769 
771  goto err;
772  }
773 
774  if (set_crypto_policy(local_policy, suite_val, p->local_key, key_len, stats.local_ssrc, 0) < 0) {
775  goto err;
776  }
777 
778  if (set_crypto_policy(remote_policy, suite_val, remote_key, key_len, 0, 1) < 0) {
779  goto err;
780  }
781 
782  /* Add the SRTP policies */
783  if (ast_rtp_instance_add_srtp_policy(rtp, remote_policy, local_policy, 0)) {
784  ast_log(LOG_WARNING, "Could not set SRTP policies\n");
785  goto err;
786  }
787 
788  ast_debug(1 , "SRTP policy activated\n");
789  res = 0;
790 
791 err:
792  if (local_policy) {
793  policy_res.destroy(local_policy);
794  }
795 
796  if (remote_policy) {
797  policy_res.destroy(remote_policy);
798  }
799 
800  return res;
801 }
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:444
#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:735
unsigned int local_ssrc
Definition: rtp_engine.h:422
unsigned char local_key[SRTP_MAX_KEY_LEN]
Definition: res_srtp.c:635
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 653 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().

654 {
655  unsigned char remote_key[key_len];
656 
657  if (srtp_res.get_random(p->local_key, key_len) < 0) {
658  return NULL;
659  }
660 
661  ast_base64encode(p->local_key64, p->local_key, key_len, sizeof(p->local_key64));
662 
663  p->key_len = ast_base64decode(remote_key, p->local_key64, sizeof(remote_key));
664 
665  if (p->key_len != key_len) {
666  ast_log(LOG_ERROR, "base64 encode/decode bad len %d != %d\n", p->key_len, key_len);
667  return NULL;
668  }
669 
670  if (memcmp(remote_key, p->local_key, p->key_len)) {
671  ast_log(LOG_ERROR, "base64 encode/decode bad key\n");
672  return NULL;
673  }
674 
675  ast_debug(1 , "local_key64 %s len %zu\n", p->local_key64, strlen(p->local_key64));
676 
677  return p;
678 }
#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:444
#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:635
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:637

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

References res_srtp_init().

Referenced by unload_module().

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

◆ 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 #if defined(HAVE_SRTP_192) && defined(ENABLE_SRTP_AES_192)
281  return 0;
282 
285  return 0;
286 #endif
287 #if defined(HAVE_SRTP_256) && defined(ENABLE_SRTP_AES_256)
290  return 0;
291 
294  return 0;
295 #endif
296 #if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM)
297  case AST_AES_GCM_128:
299  return 0;
300 
301  case AST_AES_GCM_128_8:
303  return 0;
304 #endif
305 #if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM) && defined(ENABLE_SRTP_AES_256)
306  case AST_AES_GCM_256:
308  return 0;
309 
310  case AST_AES_GCM_256_8:
312  return 0;
313 #endif
314 
315  default:
316  ast_log(LOG_ERROR, "Invalid crypto suite: %u\n", suite);
317  return -1;
318  }
319 }
#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 699 of file res_srtp.c.

References sdp_crypto_alloc(), and SRTP_MASTER_KEY_LEN.

Referenced by res_sdp_srtp_get_attr().

700 {
702 }
static struct ast_sdp_crypto * sdp_crypto_alloc(const int key_len)
Definition: res_srtp.c:680
#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 704 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().

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

◆ res_sdp_crypto_dtor()

static void res_sdp_crypto_dtor ( struct ast_sdp_crypto crypto)
static

Definition at line 642 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().

643 {
644  if (crypto) {
645  ast_free(crypto->a_crypto);
646  crypto->a_crypto = NULL;
647  ast_free(crypto);
648 
650  }
651 }
#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:634
#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 803 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().

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

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

1231 {
1232  if (g_initialized) {
1233  return 0;
1234  }
1235 
1236  if (srtp_init() != err_status_ok) {
1237  ast_log(AST_LOG_WARNING, "Failed to initialize libsrtp\n");
1238  return -1;
1239  }
1240 
1241  srtp_install_event_handler(srtp_event_cb);
1242 
1244  ast_log(AST_LOG_WARNING, "Failed to register SRTP with rtp engine\n");
1246  return -1;
1247  }
1248 
1250  ast_log(AST_LOG_WARNING, "Failed to register SDP SRTP crypto API\n");
1252  return -1;
1253  }
1254 
1255 #ifdef HAVE_SRTP_GET_VERSION
1256  ast_verb(2, "%s initialized\n", srtp_get_version_string());
1257 #else
1258  ast_verb(2, "libsrtp initialized\n");
1259 #endif
1260 
1261  g_initialized = 1;
1262  return 0;
1263 }
static void res_srtp_shutdown(void)
Definition: res_srtp.c:1219
#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:455
static struct ast_sdp_crypto_api res_sdp_crypto_api
Definition: res_srtp.c:1211
#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 1219 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().

1220 {
1223  srtp_install_event_handler(NULL);
1224 #ifdef HAVE_SRTP_SHUTDOWN
1225  srtp_shutdown();
1226 #endif
1227  g_initialized = 0;
1228 }
#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:1211
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 680 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().

681 {
682  struct ast_sdp_crypto *p, *result;
683 
684  if (!(p = ast_calloc(1, sizeof(*p)))) {
685  return NULL;
686  }
687  p->tag = 1;
689 
690  /* default is a key which uses AST_AES_CM_128_HMAC_SHA1_xx */
691  result = crypto_init_keys(p, key_len);
692  if (!result) {
694  }
695 
696  return result;
697 }
static void res_sdp_crypto_dtor(struct ast_sdp_crypto *crypto)
Definition: res_srtp.c:642
#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:653
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 735 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().

736 {
737  if (policy_res.set_master_key(policy, master_key, key_len, NULL, 0) < 0) {
738  return -1;
739  }
740 
741  if (policy_res.set_suite(policy, suite_val)) {
742  ast_log(LOG_WARNING, "Could not set remote SRTP suite\n");
743  return -1;
744  }
745 
746  policy_res.set_ssrc(policy, ssrc, inbound);
747 
748  return 0;
749 }
#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:444

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1274 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().

1275 {
1277  return 0;
1278 }
static void res_srtp_shutdown(void)
Definition: res_srtp.c:1219

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

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1285 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 1211 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().