#include "asterisk.h"
#include <srtp/srtp.h>
#include "asterisk/lock.h"
#include "asterisk/sched.h"
#include "asterisk/module.h"
#include "asterisk/options.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/astobj2.h"
Go to the source code of this file.
Data Structures | |
struct | ast_srtp |
struct | ast_srtp_policy |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (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_policy * | ast_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 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 struct ast_srtp_policy * | find_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 int | res_srtp_init (void) |
static struct ast_srtp * | res_srtp_new (void) |
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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, } |
static struct ast_module_info * | ast_module_info = &__mod_info |
static int | g_initialized = 0 |
static struct ast_srtp_policy_res | policy_res |
static struct ast_srtp_res | srtp_res |
Secure RTP (SRTP) Specified in RFC 3711.
Definition in file res_srtp.c.
static void __reg_module | ( | void | ) | [static] |
Definition at line 477 of file res_srtp.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 477 of file res_srtp.c.
static int ast_srtp_add_stream | ( | struct ast_srtp * | srtp, | |
struct ast_srtp_policy * | policy | |||
) | [static] |
Definition at line 399 of file res_srtp.c.
References ao2_t_link, ao2_t_ref, ast_debug, find_policy(), match(), OBJ_POINTER, ast_srtp::policies, ast_srtp::session, and ast_srtp_policy::sp.
Referenced by ast_srtp_change_source().
00400 { 00401 struct ast_srtp_policy *match; 00402 00403 if ((match = find_policy(srtp, &policy->sp, OBJ_POINTER))) { 00404 ast_debug(3, "Policy already exists, not re-adding\n"); 00405 ao2_t_ref(match, -1, "Unreffing already existing policy"); 00406 return -1; 00407 } 00408 00409 if (srtp_add_stream(srtp->session, &policy->sp) != err_status_ok) { 00410 return -1; 00411 } 00412 00413 ao2_t_link(srtp->policies, policy, "Added additional stream"); 00414 00415 return 0; 00416 }
static int ast_srtp_change_source | ( | struct ast_srtp * | srtp, | |
unsigned int | from_ssrc, | |||
unsigned int | to_ssrc | |||
) | [static] |
Definition at line 418 of file res_srtp.c.
References ao2_t_ref, ast_debug, ast_log(), ast_srtp_add_stream(), find_policy(), LOG_WARNING, match(), OBJ_POINTER, OBJ_UNLINK, ast_srtp::session, and status.
00419 { 00420 struct ast_srtp_policy *match; 00421 struct srtp_policy_t sp = { 00422 .ssrc.type = ssrc_specific, 00423 .ssrc.value = from_ssrc, 00424 }; 00425 err_status_t status; 00426 00427 /* If we find a mach, return and unlink it from the container so we 00428 * can change the SSRC (which is part of the hash) and then have 00429 * ast_srtp_add_stream link it back in if all is well */ 00430 if ((match = find_policy(srtp, &sp, OBJ_POINTER | OBJ_UNLINK))) { 00431 match->sp.ssrc.value = to_ssrc; 00432 if (ast_srtp_add_stream(srtp, match)) { 00433 ast_log(LOG_WARNING, "Couldn't add stream\n"); 00434 } else if ((status = srtp_remove_stream(srtp->session, from_ssrc))) { 00435 ast_debug(3, "Couldn't remove stream (%d)\n", status); 00436 } 00437 ao2_t_ref(match, -1, "Unreffing found policy in change_source"); 00438 } 00439 00440 return 0; 00441 }
static int ast_srtp_create | ( | struct ast_srtp ** | srtp, | |
struct ast_rtp_instance * | rtp, | |||
struct ast_srtp_policy * | policy | |||
) | [static] |
Definition at line 365 of file res_srtp.c.
References ao2_t_link, ast_module_ref(), res_srtp_new(), ast_srtp::rtp, ast_srtp::session, and ast_srtp_policy::sp.
00366 { 00367 struct ast_srtp *temp; 00368 00369 if (!(temp = res_srtp_new())) { 00370 return -1; 00371 } 00372 00373 if (srtp_create(&temp->session, &policy->sp) != err_status_ok) { 00374 return -1; 00375 } 00376 00377 ast_module_ref(ast_module_info->self); 00378 temp->rtp = rtp; 00379 *srtp = temp; 00380 00381 ao2_t_link((*srtp)->policies, policy, "Created initial policy"); 00382 00383 return 0; 00384 }
static void ast_srtp_destroy | ( | struct ast_srtp * | srtp | ) | [static] |
Definition at line 386 of file res_srtp.c.
References ao2_t_callback, ao2_t_ref, ast_free, ast_module_unref(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, ast_srtp::policies, and ast_srtp::session.
00387 { 00388 if (srtp->session) { 00389 srtp_dealloc(srtp->session); 00390 } 00391 00392 ao2_t_callback(srtp->policies, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "Unallocate policy"); 00393 ao2_t_ref(srtp->policies, -1, "Destroying container"); 00394 00395 ast_free(srtp); 00396 ast_module_unref(ast_module_info->self); 00397 }
static int ast_srtp_get_random | ( | unsigned char * | key, | |
size_t | len | |||
) | [static] |
Definition at line 297 of file res_srtp.c.
00298 { 00299 return crypto_get_random(key, len) != err_status_ok ? -1: 0; 00300 }
static struct ast_srtp_policy * ast_srtp_policy_alloc | ( | void | ) | [static] |
Definition at line 227 of file res_srtp.c.
References ao2_t_alloc, ast_log(), LOG_ERROR, and policy_destructor().
00228 { 00229 struct ast_srtp_policy *tmp; 00230 00231 if (!(tmp = ao2_t_alloc(sizeof(*tmp), policy_destructor, "Allocating policy"))) { 00232 ast_log(LOG_ERROR, "Unable to allocate memory for srtp_policy\n"); 00233 } 00234 00235 return tmp; 00236 }
static void ast_srtp_policy_destroy | ( | struct ast_srtp_policy * | policy | ) | [static] |
Definition at line 238 of file res_srtp.c.
References ao2_t_ref.
00239 { 00240 ao2_t_ref(policy, -1, "Destroying policy"); 00241 }
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 275 of file res_srtp.c.
References ast_calloc, ast_free, and ast_srtp_policy::sp.
00276 { 00277 size_t size = key_len + salt_len; 00278 unsigned char *master_key; 00279 00280 if (policy->sp.key) { 00281 ast_free(policy->sp.key); 00282 policy->sp.key = NULL; 00283 } 00284 00285 if (!(master_key = ast_calloc(1, size))) { 00286 return -1; 00287 } 00288 00289 memcpy(master_key, key, key_len); 00290 memcpy(master_key + key_len, salt, salt_len); 00291 00292 policy->sp.key = master_key; 00293 00294 return 0; 00295 }
static void ast_srtp_policy_set_ssrc | ( | struct ast_srtp_policy * | policy, | |
unsigned long | ssrc, | |||
int | inbound | |||
) | [static] |
Definition at line 206 of file res_srtp.c.
References ast_srtp_policy::sp.
00208 { 00209 if (ssrc) { 00210 policy->sp.ssrc.type = ssrc_specific; 00211 policy->sp.ssrc.value = ssrc; 00212 } else { 00213 policy->sp.ssrc.type = inbound ? ssrc_any_inbound : ssrc_any_outbound; 00214 } 00215 }
static int ast_srtp_policy_set_suite | ( | struct ast_srtp_policy * | policy, | |
enum ast_srtp_suite | suite | |||
) | [static] |
Definition at line 270 of file res_srtp.c.
References policy_set_suite(), and ast_srtp_policy::sp.
00271 { 00272 return policy_set_suite(&policy->sp.rtp, suite) | policy_set_suite(&policy->sp.rtcp, suite); 00273 }
static int ast_srtp_protect | ( | struct ast_srtp * | srtp, | |
void ** | buf, | |||
int * | len, | |||
int | rtcp | |||
) | [static] |
Definition at line 346 of file res_srtp.c.
References ast_log(), ast_srtp::buf, LOG_WARNING, ast_srtp::session, and srtp_errstr().
00347 { 00348 int res; 00349 00350 if ((*len + SRTP_MAX_TRAILER_LEN) > sizeof(srtp->buf)) { 00351 return -1; 00352 } 00353 00354 memcpy(srtp->buf, *buf, *len); 00355 00356 if ((res = rtcp ? srtp_protect_rtcp(srtp->session, srtp->buf, len) : srtp_protect(srtp->session, srtp->buf, len)) != err_status_ok && res != err_status_replay_fail) { 00357 ast_log(LOG_WARNING, "SRTP protect: %s\n", srtp_errstr(res)); 00358 return -1; 00359 } 00360 00361 *buf = srtp->buf; 00362 return *len; 00363 }
static void ast_srtp_set_cb | ( | struct ast_srtp * | srtp, | |
const struct ast_srtp_cb * | cb, | |||
void * | data | |||
) | [static] |
Definition at line 302 of file res_srtp.c.
References ast_srtp::cb, and ast_srtp::data.
00303 { 00304 if (!srtp) { 00305 return; 00306 } 00307 00308 srtp->cb = cb; 00309 srtp->data = data; 00310 }
static int ast_srtp_unprotect | ( | struct ast_srtp * | srtp, | |
void * | buf, | |||
int * | len, | |||
int | rtcp | |||
) | [static] |
Definition at line 313 of file res_srtp.c.
References ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_REMOTE_SSRC, ast_srtp::cb, ast_srtp::data, ast_srtp_cb::no_ctx, ast_rtp_instance_stats::remote_ssrc, ast_srtp::rtp, and ast_srtp::session.
00314 { 00315 int res = 0; 00316 int i; 00317 struct ast_rtp_instance_stats stats = {0,}; 00318 00319 for (i = 0; i < 2; i++) { 00320 res = rtcp ? srtp_unprotect_rtcp(srtp->session, buf, len) : srtp_unprotect(srtp->session, buf, len); 00321 if (res != err_status_no_ctx) { 00322 break; 00323 } 00324 00325 if (srtp->cb && srtp->cb->no_ctx) { 00326 if (ast_rtp_instance_get_stats(srtp->rtp, &stats, AST_RTP_INSTANCE_STAT_REMOTE_SSRC)) { 00327 break; 00328 } 00329 if (srtp->cb->no_ctx(srtp->rtp, stats.remote_ssrc, srtp->data) < 0) { 00330 break; 00331 } 00332 } else { 00333 break; 00334 } 00335 } 00336 00337 if (res != err_status_ok && res != err_status_replay_fail ) { 00338 ast_log(LOG_WARNING, "SRTP unprotect: %s\n", srtp_errstr(res)); 00339 errno = EAGAIN; 00340 return -1; 00341 } 00342 00343 return *len; 00344 }
static struct ast_srtp_policy* find_policy | ( | struct ast_srtp * | srtp, | |
const srtp_policy_t * | policy, | |||
int | flags | |||
) | [static] |
Definition at line 156 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().
00157 { 00158 struct ast_srtp_policy tmp = { 00159 .sp = { 00160 .ssrc.type = policy->ssrc.type, 00161 .ssrc.value = policy->ssrc.value, 00162 }, 00163 }; 00164 00165 return ao2_t_find(srtp->policies, &tmp, flags, "Looking for policy"); 00166 }
static int load_module | ( | void | ) | [static] |
Definition at line 462 of file res_srtp.c.
References res_srtp_init().
00463 { 00464 return res_srtp_init(); 00465 }
static int policy_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 149 of file res_srtp.c.
References ast_srtp_policy::sp.
Referenced by res_srtp_new().
00150 { 00151 const struct ast_srtp_policy *one = obj, *two = arg; 00152 00153 return one->sp.ssrc.type == two->sp.ssrc.type && one->sp.ssrc.value == two->sp.ssrc.value; 00154 }
static void policy_destructor | ( | void * | obj | ) | [static] |
Definition at line 217 of file res_srtp.c.
References ast_free, and ast_srtp_policy::sp.
Referenced by ast_srtp_policy_alloc().
00218 { 00219 struct ast_srtp_policy *policy = obj; 00220 00221 if (policy->sp.key) { 00222 ast_free(policy->sp.key); 00223 policy->sp.key = NULL; 00224 } 00225 }
static int policy_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 142 of file res_srtp.c.
References ast_srtp_policy::sp.
Referenced by res_srtp_new().
00143 { 00144 const struct ast_srtp_policy *policy = obj; 00145 00146 return policy->sp.ssrc.type == ssrc_specific ? policy->sp.ssrc.value : policy->sp.ssrc.type; 00147 }
static int policy_set_suite | ( | crypto_policy_t * | p, | |
enum ast_srtp_suite | suite | |||
) | [static] |
Definition at line 243 of file res_srtp.c.
References AST_AES_CM_128_HMAC_SHA1_32, AST_AES_CM_128_HMAC_SHA1_80, ast_log(), and LOG_ERROR.
Referenced by ast_srtp_policy_set_suite().
00244 { 00245 switch (suite) { 00246 case AST_AES_CM_128_HMAC_SHA1_80: 00247 p->cipher_type = AES_128_ICM; 00248 p->cipher_key_len = 30; 00249 p->auth_type = HMAC_SHA1; 00250 p->auth_key_len = 20; 00251 p->auth_tag_len = 10; 00252 p->sec_serv = sec_serv_conf_and_auth; 00253 return 0; 00254 00255 case AST_AES_CM_128_HMAC_SHA1_32: 00256 p->cipher_type = AES_128_ICM; 00257 p->cipher_key_len = 30; 00258 p->auth_type = HMAC_SHA1; 00259 p->auth_key_len = 20; 00260 p->auth_tag_len = 4; 00261 p->sec_serv = sec_serv_conf_and_auth; 00262 return 0; 00263 00264 default: 00265 ast_log(LOG_ERROR, "Invalid crypto suite: %d\n", suite); 00266 return -1; 00267 } 00268 }
static int res_srtp_init | ( | void | ) | [static] |
Definition at line 443 of file res_srtp.c.
References ast_rtp_engine_register_srtp(), g_initialized, policy_res, srtp_event_cb(), and srtp_res.
Referenced by load_module().
00444 { 00445 if (g_initialized) { 00446 return 0; 00447 } 00448 00449 if (srtp_init() != err_status_ok) { 00450 return -1; 00451 } 00452 00453 srtp_install_event_handler(srtp_event_cb); 00454 00455 return ast_rtp_engine_register_srtp(&srtp_res, &policy_res); 00456 }
static struct ast_srtp* res_srtp_new | ( | void | ) | [static] |
Definition at line 168 of file res_srtp.c.
References ao2_t_container_alloc, ast_calloc, ast_free, ast_log(), LOG_ERROR, policy_cmp_fn(), and policy_hash_fn().
Referenced by ast_srtp_create().
00169 { 00170 struct ast_srtp *srtp; 00171 00172 if (!(srtp = ast_calloc(1, sizeof(*srtp)))) { 00173 ast_log(LOG_ERROR, "Unable to allocate memory for srtp\n"); 00174 return NULL; 00175 } 00176 00177 if (!(srtp->policies = ao2_t_container_alloc(5, policy_hash_fn, policy_cmp_fn, "SRTP policy container"))) { 00178 ast_free(srtp); 00179 return NULL; 00180 } 00181 00182 return srtp; 00183 }
static const char* srtp_errstr | ( | int | err | ) | [static] |
Definition at line 102 of file res_srtp.c.
Referenced by ast_srtp_protect().
00103 { 00104 switch(err) { 00105 case err_status_ok: 00106 return "nothing to report"; 00107 case err_status_fail: 00108 return "unspecified failure"; 00109 case err_status_bad_param: 00110 return "unsupported parameter"; 00111 case err_status_alloc_fail: 00112 return "couldn't allocate memory"; 00113 case err_status_dealloc_fail: 00114 return "couldn't deallocate properly"; 00115 case err_status_init_fail: 00116 return "couldn't initialize"; 00117 case err_status_terminus: 00118 return "can't process as much data as requested"; 00119 case err_status_auth_fail: 00120 return "authentication failure"; 00121 case err_status_cipher_fail: 00122 return "cipher failure"; 00123 case err_status_replay_fail: 00124 return "replay check failed (bad index)"; 00125 case err_status_replay_old: 00126 return "replay check failed (index too old)"; 00127 case err_status_algo_fail: 00128 return "algorithm failed test routine"; 00129 case err_status_no_such_op: 00130 return "unsupported operation"; 00131 case err_status_no_ctx: 00132 return "no appropriate context found"; 00133 case err_status_cant_check: 00134 return "unable to perform desired validation"; 00135 case err_status_key_expired: 00136 return "can't use key any more"; 00137 default: 00138 return "unknown"; 00139 } 00140 }
static void srtp_event_cb | ( | srtp_event_data_t * | data | ) | [static] |
Definition at line 188 of file res_srtp.c.
References ast_debug.
Referenced by res_srtp_init().
00189 { 00190 switch (data->event) { 00191 case event_ssrc_collision: 00192 ast_debug(1, "SSRC collision\n"); 00193 break; 00194 case event_key_soft_limit: 00195 ast_debug(1, "event_key_soft_limit\n"); 00196 break; 00197 case event_key_hard_limit: 00198 ast_debug(1, "event_key_hard_limit\n"); 00199 break; 00200 case event_packet_index_limit: 00201 ast_debug(1, "event_packet_index_limit\n"); 00202 break; 00203 } 00204 }
static int unload_module | ( | void | ) | [static] |
Definition at line 467 of file res_srtp.c.
References ast_rtp_engine_unregister_srtp().
00468 { 00469 ast_rtp_engine_unregister_srtp(); 00470 return 0; 00471 }
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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, } [static] |
Definition at line 477 of file res_srtp.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 477 of file res_srtp.c.
int g_initialized = 0 [static] |
struct ast_srtp_policy_res policy_res [static] |
Definition at line 94 of file res_srtp.c.
Referenced by ast_rtp_engine_register_srtp(), and res_srtp_init().
struct ast_srtp_res srtp_res [static] |
Definition at line 83 of file res_srtp.c.
Referenced by ast_rtp_engine_register_srtp(), and res_srtp_init().