Wed Apr 6 11:30:09 2011

Asterisk developer's documentation


res_srtp.c File Reference

Secure RTP (SRTP). More...

#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_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 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_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 int res_srtp_init (void)
static struct ast_srtpres_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_infoast_module_info = &__mod_info
static int g_initialized = 0
static struct ast_srtp_policy_res policy_res
static struct ast_srtp_res srtp_res


Detailed Description

Secure RTP (SRTP).

Secure RTP (SRTP) Specified in RFC 3711.

Author:
Mikael Magnusson <mikma@users.sourceforge.net>

Definition in file res_srtp.c.


Function Documentation

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 }


Variable Documentation

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]

Definition at line 63 of file res_srtp.c.

Referenced by res_srtp_init().

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


Generated on Wed Apr 6 11:30:09 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7