00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "asterisk.h"
00038
00039 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 292309 $")
00040
00041 #include <srtp/srtp.h>
00042
00043 #include "asterisk/lock.h"
00044 #include "asterisk/sched.h"
00045 #include "asterisk/module.h"
00046 #include "asterisk/options.h"
00047 #include "asterisk/rtp_engine.h"
00048 #include "asterisk/astobj2.h"
00049
00050 struct ast_srtp {
00051 struct ast_rtp_instance *rtp;
00052 struct ao2_container *policies;
00053 srtp_t session;
00054 const struct ast_srtp_cb *cb;
00055 void *data;
00056 unsigned char buf[8192 + AST_FRIENDLY_OFFSET];
00057 };
00058
00059 struct ast_srtp_policy {
00060 srtp_policy_t sp;
00061 };
00062
00063 static int g_initialized = 0;
00064
00065
00066 static int ast_srtp_create(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy);
00067 static void ast_srtp_destroy(struct ast_srtp *srtp);
00068 static int ast_srtp_add_stream(struct ast_srtp *srtp, struct ast_srtp_policy *policy);
00069 static int ast_srtp_change_source(struct ast_srtp *srtp, unsigned int from_ssrc, unsigned int to_ssrc);
00070
00071 static int ast_srtp_unprotect(struct ast_srtp *srtp, void *buf, int *len, int rtcp);
00072 static int ast_srtp_protect(struct ast_srtp *srtp, void **buf, int *len, int rtcp);
00073 static void ast_srtp_set_cb(struct ast_srtp *srtp, const struct ast_srtp_cb *cb, void *data);
00074 static int ast_srtp_get_random(unsigned char *key, size_t len);
00075
00076
00077 static struct ast_srtp_policy *ast_srtp_policy_alloc(void);
00078 static void ast_srtp_policy_destroy(struct ast_srtp_policy *policy);
00079 static int ast_srtp_policy_set_suite(struct ast_srtp_policy *policy, enum ast_srtp_suite suite);
00080 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);
00081 static void ast_srtp_policy_set_ssrc(struct ast_srtp_policy *policy, unsigned long ssrc, int inbound);
00082
00083 static struct ast_srtp_res srtp_res = {
00084 .create = ast_srtp_create,
00085 .destroy = ast_srtp_destroy,
00086 .add_stream = ast_srtp_add_stream,
00087 .change_source = ast_srtp_change_source,
00088 .set_cb = ast_srtp_set_cb,
00089 .unprotect = ast_srtp_unprotect,
00090 .protect = ast_srtp_protect,
00091 .get_random = ast_srtp_get_random
00092 };
00093
00094 static struct ast_srtp_policy_res policy_res = {
00095 .alloc = ast_srtp_policy_alloc,
00096 .destroy = ast_srtp_policy_destroy,
00097 .set_suite = ast_srtp_policy_set_suite,
00098 .set_master_key = ast_srtp_policy_set_master_key,
00099 .set_ssrc = ast_srtp_policy_set_ssrc
00100 };
00101
00102 static const char *srtp_errstr(int err)
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 }
00141
00142 static int policy_hash_fn(const void *obj, const int flags)
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 }
00148
00149 static int policy_cmp_fn(void *obj, void *arg, int flags)
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 }
00155
00156 static struct ast_srtp_policy *find_policy(struct ast_srtp *srtp, const srtp_policy_t *policy, int flags)
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 }
00167
00168 static struct ast_srtp *res_srtp_new(void)
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 }
00184
00185
00186
00187
00188 static void srtp_event_cb(srtp_event_data_t *data)
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 }
00205
00206 static void ast_srtp_policy_set_ssrc(struct ast_srtp_policy *policy,
00207 unsigned long ssrc, int inbound)
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 }
00216
00217 static void policy_destructor(void *obj)
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 }
00226
00227 static struct ast_srtp_policy *ast_srtp_policy_alloc()
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 }
00237
00238 static void ast_srtp_policy_destroy(struct ast_srtp_policy *policy)
00239 {
00240 ao2_t_ref(policy, -1, "Destroying policy");
00241 }
00242
00243 static int policy_set_suite(crypto_policy_t *p, enum ast_srtp_suite 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 }
00269
00270 static int ast_srtp_policy_set_suite(struct ast_srtp_policy *policy, enum ast_srtp_suite suite)
00271 {
00272 return policy_set_suite(&policy->sp.rtp, suite) | policy_set_suite(&policy->sp.rtcp, suite);
00273 }
00274
00275 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)
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 }
00296
00297 static int ast_srtp_get_random(unsigned char *key, size_t len)
00298 {
00299 return crypto_get_random(key, len) != err_status_ok ? -1: 0;
00300 }
00301
00302 static void ast_srtp_set_cb(struct ast_srtp *srtp, const struct ast_srtp_cb *cb, void *data)
00303 {
00304 if (!srtp) {
00305 return;
00306 }
00307
00308 srtp->cb = cb;
00309 srtp->data = data;
00310 }
00311
00312
00313 static int ast_srtp_unprotect(struct ast_srtp *srtp, void *buf, int *len, int rtcp)
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 }
00345
00346 static int ast_srtp_protect(struct ast_srtp *srtp, void **buf, int *len, int rtcp)
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 }
00364
00365 static int ast_srtp_create(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy)
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 }
00385
00386 static void ast_srtp_destroy(struct ast_srtp *srtp)
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 }
00398
00399 static int ast_srtp_add_stream(struct ast_srtp *srtp, struct ast_srtp_policy *policy)
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 }
00417
00418 static int ast_srtp_change_source(struct ast_srtp *srtp, unsigned int from_ssrc, unsigned int to_ssrc)
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
00428
00429
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 }
00442
00443 static int res_srtp_init(void)
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 }
00457
00458
00459
00460
00461
00462 static int load_module(void)
00463 {
00464 return res_srtp_init();
00465 }
00466
00467 static int unload_module(void)
00468 {
00469 ast_rtp_engine_unregister_srtp();
00470 return 0;
00471 }
00472
00473 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Secure RTP (SRTP)",
00474 .load = load_module,
00475 .unload = unload_module,
00476 .load_pri = AST_MODPRI_CHANNEL_DEPEND,
00477 );