1
/* $Id: transport_srtp.c 4366 2013-02-21 20:41:31Z ming $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
#include <pjmedia/transport_srtp.h>
22
#include <pjmedia/endpoint.h>
23
#include <pjlib-util/base64.h>
24
#include <pj/assert.h>
31
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
35
#define THIS_FILE "transport_srtp.c"
37
/* Maximum size of outgoing packet */
38
#define MAX_RTP_BUFFER_LEN PJMEDIA_MAX_MTU
39
#define MAX_RTCP_BUFFER_LEN PJMEDIA_MAX_MTU
41
/* Maximum SRTP crypto key length */
42
#define MAX_KEY_LEN 128
44
/* Initial value of probation counter. When probation counter > 0,
45
* it means SRTP is in probation state, and it may restart when
46
* srtp_unprotect() returns err_status_replay_*
48
#define PROBATION_CNT_INIT 100
50
#define DEACTIVATE_MEDIA(pool, m) pjmedia_sdp_media_deactivate(pool, m)
52
static const pj_str_t ID_RTP_AVP = { "RTP/AVP", 7 };
53
static const pj_str_t ID_RTP_SAVP = { "RTP/SAVP", 8 };
54
static const pj_str_t ID_INACTIVE = { "inactive", 8 };
55
static const pj_str_t ID_CRYPTO = { "crypto", 6 };
57
typedef struct crypto_suite
60
cipher_type_id_t cipher_type;
61
unsigned cipher_key_len;
62
auth_type_id_t auth_type;
63
unsigned auth_key_len;
64
unsigned srtp_auth_tag_len;
65
unsigned srtcp_auth_tag_len;
69
/* Crypto suites as defined on RFC 4568 */
70
static crypto_suite crypto_suites[] = {
71
/* plain RTP/RTCP (no cipher & no auth) */
72
{"NULL", NULL_CIPHER, 0, NULL_AUTH, 0, 0, 0, sec_serv_none},
74
/* cipher AES_CM, auth HMAC_SHA1, auth tag len = 10 octets */
75
{"AES_CM_128_HMAC_SHA1_80", AES_128_ICM, 30, HMAC_SHA1, 20, 10, 10,
76
sec_serv_conf_and_auth},
78
/* cipher AES_CM, auth HMAC_SHA1, auth tag len = 4 octets */
79
{"AES_CM_128_HMAC_SHA1_32", AES_128_ICM, 30, HMAC_SHA1, 20, 4, 10,
80
sec_serv_conf_and_auth},
83
* F8_128_HMAC_SHA1_8 not supported by libsrtp?
84
* {"F8_128_HMAC_SHA1_8", NULL_CIPHER, 0, NULL_AUTH, 0, 0, 0, sec_serv_none}
88
typedef struct transport_srtp
90
pjmedia_transport base; /**< Base transport interface. */
91
pj_pool_t *pool; /**< Pool for transport SRTP. */
92
pj_lock_t *mutex; /**< Mutex for libsrtp contexts.*/
93
char rtp_tx_buffer[MAX_RTP_BUFFER_LEN];
94
char rtcp_tx_buffer[MAX_RTCP_BUFFER_LEN];
95
pjmedia_srtp_setting setting;
96
unsigned media_option;
99
pj_bool_t session_inited;
100
pj_bool_t offerer_side;
101
pj_bool_t bypass_srtp;
102
char tx_key[MAX_KEY_LEN];
103
char rx_key[MAX_KEY_LEN];
104
pjmedia_srtp_crypto tx_policy;
105
pjmedia_srtp_crypto rx_policy;
107
/* Temporary policy for negotiation */
108
pjmedia_srtp_crypto tx_policy_neg;
109
pjmedia_srtp_crypto rx_policy_neg;
111
/* libSRTP contexts */
115
/* Stream information */
117
void (*rtp_cb)( void *user_data,
120
void (*rtcp_cb)(void *user_data,
124
/* Transport information */
125
pjmedia_transport *member_tp; /**< Underlying transport. */
127
/* SRTP usage policy of peer. This field is updated when media is starting.
128
* This is useful when SRTP is in optional mode and peer is using mandatory
129
* mode, so when local is about to reinvite/update, it should offer
130
* RTP/SAVP instead of offering RTP/AVP.
132
pjmedia_srtp_use peer_use;
134
/* When probation counter > 0, it means SRTP is in probation state,
135
* and it may restart when srtp_unprotect() returns err_status_replay_*
137
unsigned probation_cnt;
142
* This callback is called by transport when incoming rtp is received
144
static void srtp_rtp_cb( void *user_data, void *pkt, pj_ssize_t size);
147
* This callback is called by transport when incoming rtcp is received
149
static void srtp_rtcp_cb( void *user_data, void *pkt, pj_ssize_t size);
153
* These are media transport operations.
155
static pj_status_t transport_get_info (pjmedia_transport *tp,
156
pjmedia_transport_info *info);
157
static pj_status_t transport_attach (pjmedia_transport *tp,
159
const pj_sockaddr_t *rem_addr,
160
const pj_sockaddr_t *rem_rtcp,
162
void (*rtp_cb)(void*,
165
void (*rtcp_cb)(void*,
168
static void transport_detach (pjmedia_transport *tp,
170
static pj_status_t transport_send_rtp( pjmedia_transport *tp,
173
static pj_status_t transport_send_rtcp(pjmedia_transport *tp,
176
static pj_status_t transport_send_rtcp2(pjmedia_transport *tp,
177
const pj_sockaddr_t *addr,
181
static pj_status_t transport_media_create(pjmedia_transport *tp,
184
const pjmedia_sdp_session *sdp_remote,
185
unsigned media_index);
186
static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
188
pjmedia_sdp_session *sdp_local,
189
const pjmedia_sdp_session *sdp_remote,
190
unsigned media_index);
191
static pj_status_t transport_media_start (pjmedia_transport *tp,
193
const pjmedia_sdp_session *sdp_local,
194
const pjmedia_sdp_session *sdp_remote,
195
unsigned media_index);
196
static pj_status_t transport_media_stop(pjmedia_transport *tp);
197
static pj_status_t transport_simulate_lost(pjmedia_transport *tp,
200
static pj_status_t transport_destroy (pjmedia_transport *tp);
204
static pjmedia_transport_op transport_srtp_op =
210
&transport_send_rtcp,
211
&transport_send_rtcp2,
212
&transport_media_create,
213
&transport_encode_sdp,
214
&transport_media_start,
215
&transport_media_stop,
216
&transport_simulate_lost,
220
/* This function may also be used by other module, e.g: pjmedia/errno.c,
221
* it should have C compatible declaration.
224
const char* get_libsrtp_errstr(int err);
227
const char* get_libsrtp_errstr(int err)
229
#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)
230
static char *liberr[] = {
231
"ok", /* err_status_ok = 0 */
232
"unspecified failure", /* err_status_fail = 1 */
233
"unsupported parameter", /* err_status_bad_param = 2 */
234
"couldn't allocate memory", /* err_status_alloc_fail = 3 */
235
"couldn't deallocate properly", /* err_status_dealloc_fail = 4 */
236
"couldn't initialize", /* err_status_init_fail = 5 */
237
"can't process as much data as requested",
238
/* err_status_terminus = 6 */
239
"authentication failure", /* err_status_auth_fail = 7 */
240
"cipher failure", /* err_status_cipher_fail = 8 */
241
"replay check failed (bad index)", /* err_status_replay_fail = 9 */
242
"replay check failed (index too old)",
243
/* err_status_replay_old = 10 */
244
"algorithm failed test routine", /* err_status_algo_fail = 11 */
245
"unsupported operation", /* err_status_no_such_op = 12 */
246
"no appropriate context found", /* err_status_no_ctx = 13 */
247
"unable to perform desired validation",
248
/* err_status_cant_check = 14 */
249
"can't use key any more", /* err_status_key_expired = 15 */
250
"error in use of socket", /* err_status_socket_err = 16 */
251
"error in use POSIX signals", /* err_status_signal_err = 17 */
252
"nonce check failed", /* err_status_nonce_bad = 18 */
253
"couldn't read data", /* err_status_read_fail = 19 */
254
"couldn't write data", /* err_status_write_fail = 20 */
255
"error pasring data", /* err_status_parse_err = 21 */
256
"error encoding data", /* err_status_encode_err = 22 */
257
"error while using semaphores", /* err_status_semaphore_err = 23 */
258
"error while using pfkey" /* err_status_pfkey_err = 24 */
260
if (err >= 0 && err < (int)PJ_ARRAY_SIZE(liberr)) {
264
pj_ansi_snprintf(msg, sizeof(msg), "Unknown libsrtp error %d", err);
269
pj_ansi_snprintf(msg, sizeof(msg), "libsrtp error %d", err);
274
static pj_bool_t libsrtp_initialized;
275
static void pjmedia_srtp_deinit_lib(pjmedia_endpt *endpt);
277
PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(pjmedia_endpt *endpt)
279
if (libsrtp_initialized == PJ_FALSE) {
283
if (err != err_status_ok) {
284
PJ_LOG(4, (THIS_FILE, "Failed to initialize libsrtp: %s",
285
get_libsrtp_errstr(err)));
286
return PJMEDIA_ERRNO_FROM_LIBSRTP(err);
289
if (pjmedia_endpt_atexit(endpt, pjmedia_srtp_deinit_lib) != PJ_SUCCESS)
291
/* There will be memory leak when it fails to schedule libsrtp
292
* deinitialization, however the memory leak could be harmless,
293
* since in modern OS's memory used by an application is released
294
* when the application terminates.
296
PJ_LOG(4, (THIS_FILE, "Failed to register libsrtp deinit."));
299
libsrtp_initialized = PJ_TRUE;
305
static void pjmedia_srtp_deinit_lib(pjmedia_endpt *endpt)
309
/* Note that currently this SRTP init/deinit is not equipped with
310
* reference counter, it should be safe as normally there is only
311
* one single instance of media endpoint and even if it isn't, the
312
* pjmedia_transport_srtp_create() will invoke SRTP init (the only
313
* drawback should be the delay described by #788).
316
PJ_UNUSED_ARG(endpt);
319
if (err != err_status_ok) {
320
PJ_LOG(4, (THIS_FILE, "Failed to deinitialize libsrtp: %s",
321
get_libsrtp_errstr(err)));
324
libsrtp_initialized = PJ_FALSE;
328
static int get_crypto_idx(const pj_str_t* crypto_name)
331
int cs_cnt = sizeof(crypto_suites)/sizeof(crypto_suites[0]);
333
/* treat unspecified crypto_name as crypto 'NULL' */
334
if (crypto_name->slen == 0)
337
for (i=0; i<cs_cnt; ++i) {
338
if (!pj_stricmp2(crypto_name, crypto_suites[i].name))
346
static int srtp_crypto_cmp(const pjmedia_srtp_crypto* c1,
347
const pjmedia_srtp_crypto* c2)
351
r = pj_strcmp(&c1->key, &c2->key);
355
r = pj_stricmp(&c1->name, &c2->name);
359
return (c1->flags != c2->flags);
363
static pj_bool_t srtp_crypto_empty(const pjmedia_srtp_crypto* c)
365
return (c->name.slen==0 || c->key.slen==0);
369
PJ_DEF(void) pjmedia_srtp_setting_default(pjmedia_srtp_setting *opt)
375
pj_bzero(opt, sizeof(pjmedia_srtp_setting));
376
opt->close_member_tp = PJ_TRUE;
377
opt->use = PJMEDIA_SRTP_OPTIONAL;
379
/* Copy default crypto-suites, but skip crypto 'NULL' */
380
opt->crypto_count = sizeof(crypto_suites)/sizeof(crypto_suites[0]) - 1;
381
for (i=0; i<opt->crypto_count; ++i)
382
opt->crypto[i].name = pj_str(crypto_suites[i+1].name);
387
* Create an SRTP media transport.
389
PJ_DEF(pj_status_t) pjmedia_transport_srtp_create(
390
pjmedia_endpt *endpt,
391
pjmedia_transport *tp,
392
const pjmedia_srtp_setting *opt,
393
pjmedia_transport **p_tp)
396
transport_srtp *srtp;
400
PJ_ASSERT_RETURN(endpt && tp && p_tp, PJ_EINVAL);
402
/* Check crypto availability */
403
if (opt && opt->crypto_count == 0 &&
404
opt->use == PJMEDIA_SRTP_MANDATORY)
405
return PJMEDIA_SRTP_ESDPREQCRYPTO;
408
if (opt && opt->use != PJMEDIA_SRTP_DISABLED) {
409
for (i=0; i < opt->crypto_count; ++i) {
410
int cs_idx = get_crypto_idx(&opt->crypto[i].name);
412
/* check crypto name */
414
return PJMEDIA_SRTP_ENOTSUPCRYPTO;
416
/* check key length */
417
if (opt->crypto[i].key.slen &&
418
opt->crypto[i].key.slen <
419
(pj_ssize_t)crypto_suites[cs_idx].cipher_key_len)
420
return PJMEDIA_SRTP_EINKEYLEN;
425
status = pjmedia_srtp_init_lib(endpt);
426
if (status != PJ_SUCCESS)
429
pool = pjmedia_endpt_create_pool(endpt, "srtp%p", 1000, 1000);
430
srtp = PJ_POOL_ZALLOC_T(pool, transport_srtp);
433
srtp->session_inited = PJ_FALSE;
434
srtp->bypass_srtp = PJ_FALSE;
435
srtp->probation_cnt = PROBATION_CNT_INIT;
438
srtp->setting = *opt;
439
if (opt->use == PJMEDIA_SRTP_DISABLED)
440
srtp->setting.crypto_count = 0;
442
for (i=0; i < srtp->setting.crypto_count; ++i) {
443
int cs_idx = get_crypto_idx(&opt->crypto[i].name);
444
pj_str_t tmp_key = opt->crypto[i].key;
447
srtp->setting.crypto[i].name = pj_str(crypto_suites[cs_idx].name);
450
tmp_key.slen = crypto_suites[cs_idx].cipher_key_len;
451
pj_strdup(pool, &srtp->setting.crypto[i].key, &tmp_key);
454
pjmedia_srtp_setting_default(&srtp->setting);
457
status = pj_lock_create_recursive_mutex(pool, pool->obj_name, &srtp->mutex);
458
if (status != PJ_SUCCESS) {
459
pj_pool_release(pool);
463
/* Initialize base pjmedia_transport */
464
pj_memcpy(srtp->base.name, pool->obj_name, PJ_MAX_OBJ_NAME);
466
srtp->base.type = tp->type;
468
srtp->base.type = PJMEDIA_TRANSPORT_TYPE_UDP;
469
srtp->base.op = &transport_srtp_op;
471
/* Set underlying transport */
472
srtp->member_tp = tp;
474
/* Initialize peer's SRTP usage mode. */
475
srtp->peer_use = srtp->setting.use;
485
* Initialize and start SRTP session with the given parameters.
487
PJ_DEF(pj_status_t) pjmedia_transport_srtp_start(
488
pjmedia_transport *tp,
489
const pjmedia_srtp_crypto *tx,
490
const pjmedia_srtp_crypto *rx)
492
transport_srtp *srtp = (transport_srtp*) tp;
500
int crypto_suites_cnt;
501
pj_status_t status = PJ_SUCCESS;
503
PJ_ASSERT_RETURN(tp && tx && rx, PJ_EINVAL);
505
pj_lock_acquire(srtp->mutex);
507
if (srtp->session_inited) {
508
pjmedia_transport_srtp_stop(tp);
511
crypto_suites_cnt = sizeof(crypto_suites)/sizeof(crypto_suites[0]);
513
/* Get encryption and authentication method */
514
cr_tx_idx = au_tx_idx = get_crypto_idx(&tx->name);
515
if (tx->flags & PJMEDIA_SRTP_NO_ENCRYPTION)
517
if (tx->flags & PJMEDIA_SRTP_NO_AUTHENTICATION)
520
cr_rx_idx = au_rx_idx = get_crypto_idx(&rx->name);
521
if (rx->flags & PJMEDIA_SRTP_NO_ENCRYPTION)
523
if (rx->flags & PJMEDIA_SRTP_NO_AUTHENTICATION)
526
/* Check whether the crypto-suite requested is supported */
527
if (cr_tx_idx == -1 || cr_rx_idx == -1 || au_tx_idx == -1 ||
530
status = PJMEDIA_SRTP_ENOTSUPCRYPTO;
534
/* If all options points to 'NULL' method, just bypass SRTP */
535
if (cr_tx_idx == 0 && cr_rx_idx == 0 && au_tx_idx == 0 && au_rx_idx == 0) {
536
srtp->bypass_srtp = PJ_TRUE;
540
/* Check key length */
541
if (tx->key.slen != (pj_ssize_t)crypto_suites[cr_tx_idx].cipher_key_len ||
542
rx->key.slen != (pj_ssize_t)crypto_suites[cr_rx_idx].cipher_key_len)
544
status = PJMEDIA_SRTP_EINKEYLEN;
548
/* Init transmit direction */
549
pj_bzero(&tx_, sizeof(srtp_policy_t));
550
pj_memmove(srtp->tx_key, tx->key.ptr, tx->key.slen);
551
if (cr_tx_idx && au_tx_idx)
552
tx_.rtp.sec_serv = sec_serv_conf_and_auth;
554
tx_.rtp.sec_serv = sec_serv_conf;
556
tx_.rtp.sec_serv = sec_serv_auth;
558
tx_.rtp.sec_serv = sec_serv_none;
559
tx_.key = (uint8_t*)srtp->tx_key;
560
tx_.ssrc.type = ssrc_any_outbound;
562
tx_.rtp.cipher_type = crypto_suites[cr_tx_idx].cipher_type;
563
tx_.rtp.cipher_key_len = crypto_suites[cr_tx_idx].cipher_key_len;
564
tx_.rtp.auth_type = crypto_suites[au_tx_idx].auth_type;
565
tx_.rtp.auth_key_len = crypto_suites[au_tx_idx].auth_key_len;
566
tx_.rtp.auth_tag_len = crypto_suites[au_tx_idx].srtp_auth_tag_len;
568
tx_.rtcp.auth_tag_len = crypto_suites[au_tx_idx].srtcp_auth_tag_len;
570
err = srtp_create(&srtp->srtp_tx_ctx, &tx_);
571
if (err != err_status_ok) {
572
status = PJMEDIA_ERRNO_FROM_LIBSRTP(err);
575
srtp->tx_policy = *tx;
576
pj_strset(&srtp->tx_policy.key, srtp->tx_key, tx->key.slen);
577
srtp->tx_policy.name=pj_str(crypto_suites[get_crypto_idx(&tx->name)].name);
580
/* Init receive direction */
581
pj_bzero(&rx_, sizeof(srtp_policy_t));
582
pj_memmove(srtp->rx_key, rx->key.ptr, rx->key.slen);
583
if (cr_rx_idx && au_rx_idx)
584
rx_.rtp.sec_serv = sec_serv_conf_and_auth;
586
rx_.rtp.sec_serv = sec_serv_conf;
588
rx_.rtp.sec_serv = sec_serv_auth;
590
rx_.rtp.sec_serv = sec_serv_none;
591
rx_.key = (uint8_t*)srtp->rx_key;
592
rx_.ssrc.type = ssrc_any_inbound;
594
rx_.rtp.sec_serv = crypto_suites[cr_rx_idx].service;
595
rx_.rtp.cipher_type = crypto_suites[cr_rx_idx].cipher_type;
596
rx_.rtp.cipher_key_len = crypto_suites[cr_rx_idx].cipher_key_len;
597
rx_.rtp.auth_type = crypto_suites[au_rx_idx].auth_type;
598
rx_.rtp.auth_key_len = crypto_suites[au_rx_idx].auth_key_len;
599
rx_.rtp.auth_tag_len = crypto_suites[au_rx_idx].srtp_auth_tag_len;
601
rx_.rtcp.auth_tag_len = crypto_suites[au_rx_idx].srtcp_auth_tag_len;
603
err = srtp_create(&srtp->srtp_rx_ctx, &rx_);
604
if (err != err_status_ok) {
605
srtp_dealloc(srtp->srtp_tx_ctx);
606
status = PJMEDIA_ERRNO_FROM_LIBSRTP(err);
609
srtp->rx_policy = *rx;
610
pj_strset(&srtp->rx_policy.key, srtp->rx_key, rx->key.slen);
611
srtp->rx_policy.name=pj_str(crypto_suites[get_crypto_idx(&rx->name)].name);
613
/* Declare SRTP session initialized */
614
srtp->session_inited = PJ_TRUE;
617
#if PJ_LOG_MAX_LEVEL >= 5
619
char b64[PJ_BASE256_TO_BASE64_LEN(MAX_KEY_LEN)];
622
/* TX crypto and key */
623
b64_len = sizeof(b64);
624
status = pj_base64_encode((pj_uint8_t*)tx->key.ptr, tx->key.slen,
626
if (status != PJ_SUCCESS)
627
b64_len = pj_ansi_sprintf(b64, "--key too long--");
631
PJ_LOG(5, (srtp->pool->obj_name, "TX: %s key=%s",
632
srtp->tx_policy.name.ptr, b64));
633
if (srtp->tx_policy.flags) {
634
PJ_LOG(5,(srtp->pool->obj_name, "TX: disable%s%s",
635
(cr_tx_idx?"":" enc"),
636
(au_tx_idx?"":" auth")));
639
/* RX crypto and key */
640
b64_len = sizeof(b64);
641
status = pj_base64_encode((pj_uint8_t*)rx->key.ptr, rx->key.slen,
643
if (status != PJ_SUCCESS)
644
b64_len = pj_ansi_sprintf(b64, "--key too long--");
648
PJ_LOG(5, (srtp->pool->obj_name, "RX: %s key=%s",
649
srtp->rx_policy.name.ptr, b64));
650
if (srtp->rx_policy.flags) {
651
PJ_LOG(5,(srtp->pool->obj_name,"RX: disable%s%s",
652
(cr_rx_idx?"":" enc"),
653
(au_rx_idx?"":" auth")));
659
pj_lock_release(srtp->mutex);
666
PJ_DEF(pj_status_t) pjmedia_transport_srtp_stop(pjmedia_transport *srtp)
668
transport_srtp *p_srtp = (transport_srtp*) srtp;
671
PJ_ASSERT_RETURN(srtp, PJ_EINVAL);
673
pj_lock_acquire(p_srtp->mutex);
675
if (!p_srtp->session_inited) {
676
pj_lock_release(p_srtp->mutex);
680
err = srtp_dealloc(p_srtp->srtp_rx_ctx);
681
if (err != err_status_ok) {
682
PJ_LOG(4, (p_srtp->pool->obj_name,
683
"Failed to dealloc RX SRTP context: %s",
684
get_libsrtp_errstr(err)));
686
err = srtp_dealloc(p_srtp->srtp_tx_ctx);
687
if (err != err_status_ok) {
688
PJ_LOG(4, (p_srtp->pool->obj_name,
689
"Failed to dealloc TX SRTP context: %s",
690
get_libsrtp_errstr(err)));
693
p_srtp->session_inited = PJ_FALSE;
694
pj_bzero(&p_srtp->rx_policy, sizeof(p_srtp->rx_policy));
695
pj_bzero(&p_srtp->tx_policy, sizeof(p_srtp->tx_policy));
697
pj_lock_release(p_srtp->mutex);
702
PJ_DEF(pjmedia_transport *) pjmedia_transport_srtp_get_member(
703
pjmedia_transport *tp)
705
transport_srtp *srtp = (transport_srtp*) tp;
707
PJ_ASSERT_RETURN(tp, NULL);
709
return srtp->member_tp;
713
static pj_status_t transport_get_info(pjmedia_transport *tp,
714
pjmedia_transport_info *info)
716
transport_srtp *srtp = (transport_srtp*) tp;
717
pjmedia_srtp_info srtp_info;
720
PJ_ASSERT_RETURN(tp && info, PJ_EINVAL);
721
PJ_ASSERT_RETURN(info->specific_info_cnt <
722
PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT, PJ_ETOOMANY);
723
PJ_ASSERT_RETURN(sizeof(pjmedia_srtp_info) <=
724
PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE, PJ_ENOMEM);
726
srtp_info.active = srtp->session_inited;
727
srtp_info.rx_policy = srtp->rx_policy;
728
srtp_info.tx_policy = srtp->tx_policy;
729
srtp_info.use = srtp->setting.use;
730
srtp_info.peer_use = srtp->peer_use;
732
spc_info_idx = info->specific_info_cnt++;
733
info->spc_info[spc_info_idx].type = PJMEDIA_TRANSPORT_TYPE_SRTP;
734
info->spc_info[spc_info_idx].cbsize = sizeof(srtp_info);
735
pj_memcpy(&info->spc_info[spc_info_idx].buffer, &srtp_info,
738
return pjmedia_transport_get_info(srtp->member_tp, info);
741
static pj_status_t transport_attach(pjmedia_transport *tp,
743
const pj_sockaddr_t *rem_addr,
744
const pj_sockaddr_t *rem_rtcp,
746
void (*rtp_cb) (void*, void*,
748
void (*rtcp_cb)(void*, void*,
751
transport_srtp *srtp = (transport_srtp*) tp;
754
PJ_ASSERT_RETURN(tp && rem_addr && addr_len, PJ_EINVAL);
756
/* Save the callbacks */
757
pj_lock_acquire(srtp->mutex);
758
srtp->rtp_cb = rtp_cb;
759
srtp->rtcp_cb = rtcp_cb;
760
srtp->user_data = user_data;
761
pj_lock_release(srtp->mutex);
763
/* Attach itself to transport */
764
status = pjmedia_transport_attach(srtp->member_tp, srtp, rem_addr,
765
rem_rtcp, addr_len, &srtp_rtp_cb,
767
if (status != PJ_SUCCESS) {
768
pj_lock_acquire(srtp->mutex);
770
srtp->rtcp_cb = NULL;
771
srtp->user_data = NULL;
772
pj_lock_release(srtp->mutex);
779
static void transport_detach(pjmedia_transport *tp, void *strm)
781
transport_srtp *srtp = (transport_srtp*) tp;
784
PJ_ASSERT_ON_FAIL(tp, return);
786
if (srtp->member_tp) {
787
pjmedia_transport_detach(srtp->member_tp, srtp);
790
/* Clear up application infos from transport */
791
pj_lock_acquire(srtp->mutex);
793
srtp->rtcp_cb = NULL;
794
srtp->user_data = NULL;
795
pj_lock_release(srtp->mutex);
798
static pj_status_t transport_send_rtp( pjmedia_transport *tp,
803
transport_srtp *srtp = (transport_srtp*) tp;
807
if (srtp->bypass_srtp)
808
return pjmedia_transport_send_rtp(srtp->member_tp, pkt, size);
810
if (size > sizeof(srtp->rtp_tx_buffer) - 10)
813
pj_memcpy(srtp->rtp_tx_buffer, pkt, size);
815
pj_lock_acquire(srtp->mutex);
816
if (!srtp->session_inited) {
817
pj_lock_release(srtp->mutex);
818
return PJ_EINVALIDOP;
820
err = srtp_protect(srtp->srtp_tx_ctx, srtp->rtp_tx_buffer, &len);
821
pj_lock_release(srtp->mutex);
823
if (err == err_status_ok) {
824
status = pjmedia_transport_send_rtp(srtp->member_tp,
825
srtp->rtp_tx_buffer, len);
827
status = PJMEDIA_ERRNO_FROM_LIBSRTP(err);
833
static pj_status_t transport_send_rtcp(pjmedia_transport *tp,
837
return transport_send_rtcp2(tp, NULL, 0, pkt, size);
840
static pj_status_t transport_send_rtcp2(pjmedia_transport *tp,
841
const pj_sockaddr_t *addr,
847
transport_srtp *srtp = (transport_srtp*) tp;
851
if (srtp->bypass_srtp) {
852
return pjmedia_transport_send_rtcp2(srtp->member_tp, addr, addr_len,
856
if (size > sizeof(srtp->rtcp_tx_buffer) - 10)
859
pj_memcpy(srtp->rtcp_tx_buffer, pkt, size);
861
pj_lock_acquire(srtp->mutex);
862
if (!srtp->session_inited) {
863
pj_lock_release(srtp->mutex);
864
return PJ_EINVALIDOP;
866
err = srtp_protect_rtcp(srtp->srtp_tx_ctx, srtp->rtcp_tx_buffer, &len);
867
pj_lock_release(srtp->mutex);
869
if (err == err_status_ok) {
870
status = pjmedia_transport_send_rtcp2(srtp->member_tp, addr, addr_len,
871
srtp->rtcp_tx_buffer, len);
873
status = PJMEDIA_ERRNO_FROM_LIBSRTP(err);
880
static pj_status_t transport_simulate_lost(pjmedia_transport *tp,
884
transport_srtp *srtp = (transport_srtp *) tp;
886
PJ_ASSERT_RETURN(tp, PJ_EINVAL);
888
return pjmedia_transport_simulate_lost(srtp->member_tp, dir, pct_lost);
891
static pj_status_t transport_destroy (pjmedia_transport *tp)
893
transport_srtp *srtp = (transport_srtp *) tp;
896
PJ_ASSERT_RETURN(tp, PJ_EINVAL);
898
if (srtp->setting.close_member_tp && srtp->member_tp) {
899
pjmedia_transport_close(srtp->member_tp);
902
status = pjmedia_transport_srtp_stop(tp);
904
/* In case mutex is being acquired by other thread */
905
pj_lock_acquire(srtp->mutex);
906
pj_lock_release(srtp->mutex);
908
pj_lock_destroy(srtp->mutex);
909
pj_pool_release(srtp->pool);
915
* This callback is called by transport when incoming rtp is received
917
static void srtp_rtp_cb( void *user_data, void *pkt, pj_ssize_t size)
919
transport_srtp *srtp = (transport_srtp *) user_data;
922
void (*cb)(void*, void*, pj_ssize_t) = NULL;
923
void *cb_data = NULL;
925
if (srtp->bypass_srtp) {
926
srtp->rtp_cb(srtp->user_data, pkt, size);
934
/* Make sure buffer is 32bit aligned */
935
PJ_ASSERT_ON_FAIL( (((long)pkt) & 0x03)==0, return );
937
if (srtp->probation_cnt > 0)
938
--srtp->probation_cnt;
940
pj_lock_acquire(srtp->mutex);
942
if (!srtp->session_inited) {
943
pj_lock_release(srtp->mutex);
946
err = srtp_unprotect(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len);
947
if (srtp->probation_cnt > 0 &&
948
(err == err_status_replay_old || err == err_status_replay_fail))
950
/* Handle such condition that stream is updated (RTP seq is reinited
951
* & SRTP is restarted), but some old packets are still coming
952
* so SRTP is learning wrong RTP seq. While the newly inited RTP seq
953
* comes, SRTP thinks the RTP seq is replayed, so srtp_unprotect()
954
* will return err_status_replay_*. Restarting SRTP can resolve this.
956
pjmedia_srtp_crypto tx, rx;
959
tx = srtp->tx_policy;
960
rx = srtp->rx_policy;
961
status = pjmedia_transport_srtp_start((pjmedia_transport*)srtp,
963
if (status != PJ_SUCCESS) {
964
PJ_LOG(5,(srtp->pool->obj_name, "Failed to restart SRTP, err=%s",
965
get_libsrtp_errstr(err)));
966
} else if (!srtp->bypass_srtp) {
967
err = srtp_unprotect(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len);
971
if (err != err_status_ok) {
972
PJ_LOG(5,(srtp->pool->obj_name,
973
"Failed to unprotect SRTP, pkt size=%d, err=%s",
974
size, get_libsrtp_errstr(err)));
977
cb_data = srtp->user_data;
980
pj_lock_release(srtp->mutex);
983
(*cb)(cb_data, pkt, len);
988
* This callback is called by transport when incoming rtcp is received
990
static void srtp_rtcp_cb( void *user_data, void *pkt, pj_ssize_t size)
992
transport_srtp *srtp = (transport_srtp *) user_data;
995
void (*cb)(void*, void*, pj_ssize_t) = NULL;
996
void *cb_data = NULL;
998
if (srtp->bypass_srtp) {
999
srtp->rtcp_cb(srtp->user_data, pkt, size);
1007
/* Make sure buffer is 32bit aligned */
1008
PJ_ASSERT_ON_FAIL( (((long)pkt) & 0x03)==0, return );
1010
pj_lock_acquire(srtp->mutex);
1012
if (!srtp->session_inited) {
1013
pj_lock_release(srtp->mutex);
1016
err = srtp_unprotect_rtcp(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len);
1017
if (err != err_status_ok) {
1018
PJ_LOG(5,(srtp->pool->obj_name,
1019
"Failed to unprotect SRTCP, pkt size=%d, err=%s",
1020
size, get_libsrtp_errstr(err)));
1023
cb_data = srtp->user_data;
1026
pj_lock_release(srtp->mutex);
1029
(*cb)(cb_data, pkt, len);
1033
/* Generate crypto attribute, including crypto key.
1034
* If crypto-suite chosen is crypto NULL, just return PJ_SUCCESS,
1035
* and set buffer_len = 0.
1037
static pj_status_t generate_crypto_attr_value(pj_pool_t *pool,
1038
char *buffer, int *buffer_len,
1039
pjmedia_srtp_crypto *crypto,
1043
int cs_idx = get_crypto_idx(&crypto->name);
1044
char b64_key[PJ_BASE256_TO_BASE64_LEN(MAX_KEY_LEN)+1];
1045
int b64_key_len = sizeof(b64_key);
1048
return PJMEDIA_SRTP_ENOTSUPCRYPTO;
1050
/* Crypto-suite NULL. */
1056
/* Generate key if not specified. */
1057
if (crypto->key.slen == 0) {
1059
char key[MAX_KEY_LEN];
1063
PJ_ASSERT_RETURN(MAX_KEY_LEN >= crypto_suites[cs_idx].cipher_key_len,
1069
err = crypto_get_random((unsigned char*)key,
1070
crypto_suites[cs_idx].cipher_key_len);
1071
if (err != err_status_ok) {
1072
PJ_LOG(5,(THIS_FILE, "Failed generating random key: %s",
1073
get_libsrtp_errstr(err)));
1074
return PJMEDIA_ERRNO_FROM_LIBSRTP(err);
1076
for (i=0; i<crypto_suites[cs_idx].cipher_key_len && key_ok; ++i)
1077
if (key[i] == 0) key_ok = PJ_FALSE;
1080
crypto->key.ptr = (char*)
1081
pj_pool_zalloc(pool,
1082
crypto_suites[cs_idx].cipher_key_len);
1083
pj_memcpy(crypto->key.ptr, key, crypto_suites[cs_idx].cipher_key_len);
1084
crypto->key.slen = crypto_suites[cs_idx].cipher_key_len;
1087
if (crypto->key.slen != (pj_ssize_t)crypto_suites[cs_idx].cipher_key_len)
1088
return PJMEDIA_SRTP_EINKEYLEN;
1090
/* Key transmitted via SDP should be base64 encoded. */
1091
status = pj_base64_encode((pj_uint8_t*)crypto->key.ptr, crypto->key.slen,
1092
b64_key, &b64_key_len);
1093
if (status != PJ_SUCCESS) {
1094
PJ_LOG(5,(THIS_FILE, "Failed encoding plain key to base64"));
1098
b64_key[b64_key_len] = '\0';
1100
PJ_ASSERT_RETURN(*buffer_len >= (crypto->name.slen + \
1101
b64_key_len + 16), PJ_ETOOSMALL);
1103
/* Print the crypto attribute value. */
1104
*buffer_len = pj_ansi_snprintf(buffer, *buffer_len, "%d %s inline:%s",
1106
crypto_suites[cs_idx].name,
1112
/* Parse crypto attribute line */
1113
static pj_status_t parse_attr_crypto(pj_pool_t *pool,
1114
const pjmedia_sdp_attr *attr,
1115
pjmedia_srtp_crypto *crypto,
1125
pj_bzero(crypto, sizeof(*crypto));
1126
pj_strdup_with_null(pool, &input, &attr->value);
1129
token = strtok(input.ptr, " ");
1131
PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting tag"));
1132
return PJMEDIA_SDP_EINATTR;
1134
token_len = pj_ansi_strlen(token);
1136
/* Tag must not use leading zeroes. */
1137
if (token_len > 1 && *token == '0')
1138
return PJMEDIA_SDP_EINATTR;
1140
/* Tag must be decimal, i.e: contains only digit '0'-'9'. */
1141
for (itmp = 0; itmp < token_len; ++itmp)
1142
if (!pj_isdigit(token[itmp]))
1143
return PJMEDIA_SDP_EINATTR;
1145
/* Get tag value. */
1149
token = strtok(NULL, " ");
1151
PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting crypto suite"));
1152
return PJMEDIA_SDP_EINATTR;
1154
crypto->name = pj_str(token);
1157
token = strtok(NULL, ":");
1159
PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting key method"));
1160
return PJMEDIA_SDP_EINATTR;
1162
if (pj_ansi_stricmp(token, "inline")) {
1163
PJ_LOG(4,(THIS_FILE, "Attribute crypto key method '%s' not supported!",
1165
return PJMEDIA_SDP_EINATTR;
1169
token = strtok(NULL, "| ");
1171
PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting key"));
1172
return PJMEDIA_SDP_EINATTR;
1174
tmp = pj_str(token);
1175
if (PJ_BASE64_TO_BASE256_LEN(tmp.slen) > MAX_KEY_LEN) {
1176
PJ_LOG(4,(THIS_FILE, "Key too long"));
1177
return PJMEDIA_SRTP_EINKEYLEN;
1181
crypto->key.ptr = (char*) pj_pool_zalloc(pool, MAX_KEY_LEN);
1183
status = pj_base64_decode(&tmp, (pj_uint8_t*)crypto->key.ptr,
1185
if (status != PJ_SUCCESS) {
1186
PJ_LOG(4,(THIS_FILE, "Failed decoding crypto key from base64"));
1189
crypto->key.slen = itmp;
1194
static pj_status_t transport_media_create(pjmedia_transport *tp,
1195
pj_pool_t *sdp_pool,
1197
const pjmedia_sdp_session *sdp_remote,
1198
unsigned media_index)
1200
struct transport_srtp *srtp = (struct transport_srtp*) tp;
1201
unsigned member_tp_option;
1203
PJ_ASSERT_RETURN(tp, PJ_EINVAL);
1205
pj_bzero(&srtp->rx_policy_neg, sizeof(srtp->rx_policy_neg));
1206
pj_bzero(&srtp->tx_policy_neg, sizeof(srtp->tx_policy_neg));
1208
srtp->media_option = options;
1209
member_tp_option = options | PJMEDIA_TPMED_NO_TRANSPORT_CHECKING;
1211
srtp->offerer_side = sdp_remote == NULL;
1214
if (srtp->offerer_side) {
1216
if (srtp->setting.use == PJMEDIA_SRTP_DISABLED)
1221
pjmedia_sdp_media *m_rem;
1223
m_rem = sdp_remote->media[media_index];
1225
/* Nothing to do on inactive media stream */
1226
if (pjmedia_sdp_media_find_attr(m_rem, &ID_INACTIVE, NULL))
1229
/* Validate remote media transport based on SRTP usage option.
1231
switch (srtp->setting.use) {
1232
case PJMEDIA_SRTP_DISABLED:
1233
if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0)
1234
return PJMEDIA_SRTP_ESDPINTRANSPORT;
1236
case PJMEDIA_SRTP_OPTIONAL:
1238
case PJMEDIA_SRTP_MANDATORY:
1239
if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) != 0)
1240
return PJMEDIA_SRTP_ESDPINTRANSPORT;
1245
goto PROPAGATE_MEDIA_CREATE;
1248
srtp->bypass_srtp = PJ_TRUE;
1249
member_tp_option &= ~PJMEDIA_TPMED_NO_TRANSPORT_CHECKING;
1251
PROPAGATE_MEDIA_CREATE:
1252
return pjmedia_transport_media_create(srtp->member_tp, sdp_pool,
1253
member_tp_option, sdp_remote,
1257
static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
1258
pj_pool_t *sdp_pool,
1259
pjmedia_sdp_session *sdp_local,
1260
const pjmedia_sdp_session *sdp_remote,
1261
unsigned media_index)
1263
struct transport_srtp *srtp = (struct transport_srtp*) tp;
1264
pjmedia_sdp_media *m_rem, *m_loc;
1265
enum { MAXLEN = 512 };
1266
char buffer[MAXLEN];
1269
pjmedia_sdp_attr *attr;
1270
pj_str_t attr_value;
1273
PJ_ASSERT_RETURN(tp && sdp_pool && sdp_local, PJ_EINVAL);
1275
pj_bzero(&srtp->rx_policy_neg, sizeof(srtp->rx_policy_neg));
1276
pj_bzero(&srtp->tx_policy_neg, sizeof(srtp->tx_policy_neg));
1278
srtp->offerer_side = sdp_remote == NULL;
1280
m_rem = sdp_remote ? sdp_remote->media[media_index] : NULL;
1281
m_loc = sdp_local->media[media_index];
1283
/* Bypass if media transport is not RTP/AVP or RTP/SAVP */
1284
if (pj_stricmp(&m_loc->desc.transport, &ID_RTP_AVP) != 0 &&
1285
pj_stricmp(&m_loc->desc.transport, &ID_RTP_SAVP) != 0)
1288
/* If the media is inactive, do nothing. */
1289
/* No, we still need to process SRTP offer/answer even if the media is
1290
* marked as inactive, because the transport is still alive in this
1291
* case (e.g. for keep-alive). See:
1292
* http://trac.pjsip.org/repos/ticket/1079
1295
if (pjmedia_sdp_media_find_attr(m_loc, &ID_INACTIVE, NULL) ||
1296
(m_rem && pjmedia_sdp_media_find_attr(m_rem, &ID_INACTIVE, NULL)))
1300
/* Check remote media transport & set local media transport
1301
* based on SRTP usage option.
1303
if (srtp->offerer_side) {
1305
/* Generate transport */
1306
switch (srtp->setting.use) {
1307
case PJMEDIA_SRTP_DISABLED:
1309
case PJMEDIA_SRTP_OPTIONAL:
1310
m_loc->desc.transport =
1311
(srtp->peer_use == PJMEDIA_SRTP_MANDATORY)?
1312
ID_RTP_SAVP : ID_RTP_AVP;
1314
case PJMEDIA_SRTP_MANDATORY:
1315
m_loc->desc.transport = ID_RTP_SAVP;
1319
/* Generate crypto attribute if not yet */
1320
if (pjmedia_sdp_media_find_attr(m_loc, &ID_CRYPTO, NULL) == NULL) {
1321
for (i=0; i<srtp->setting.crypto_count; ++i) {
1322
/* Offer crypto-suites based on setting. */
1323
buffer_len = MAXLEN;
1324
status = generate_crypto_attr_value(srtp->pool, buffer, &buffer_len,
1325
&srtp->setting.crypto[i],
1327
if (status != PJ_SUCCESS)
1330
/* If buffer_len==0, just skip the crypto attribute. */
1332
pj_strset(&attr_value, buffer, buffer_len);
1333
attr = pjmedia_sdp_attr_create(srtp->pool, ID_CRYPTO.ptr,
1335
m_loc->attr[m_loc->attr_count++] = attr;
1343
pj_assert(sdp_remote && m_rem);
1345
/* Generate transport */
1346
switch (srtp->setting.use) {
1347
case PJMEDIA_SRTP_DISABLED:
1348
if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0)
1349
return PJMEDIA_SRTP_ESDPINTRANSPORT;
1351
case PJMEDIA_SRTP_OPTIONAL:
1352
m_loc->desc.transport = m_rem->desc.transport;
1354
case PJMEDIA_SRTP_MANDATORY:
1355
if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) != 0)
1356
return PJMEDIA_SRTP_ESDPINTRANSPORT;
1357
m_loc->desc.transport = ID_RTP_SAVP;
1361
/* Generate crypto attribute if not yet */
1362
if (pjmedia_sdp_media_find_attr(m_loc, &ID_CRYPTO, NULL) == NULL) {
1364
pjmedia_srtp_crypto tmp_rx_crypto;
1365
pj_bool_t has_crypto_attr = PJ_FALSE;
1366
int matched_idx = -1;
1368
int tags[64]; /* assume no more than 64 crypto attrs in a media */
1369
unsigned cr_attr_count = 0;
1371
/* Find supported crypto-suite, get the tag, and assign policy_local */
1372
for (i=0; i<m_rem->attr_count; ++i) {
1373
if (pj_stricmp(&m_rem->attr[i]->name, &ID_CRYPTO) != 0)
1376
has_crypto_attr = PJ_TRUE;
1378
status = parse_attr_crypto(srtp->pool, m_rem->attr[i],
1379
&tmp_rx_crypto, &tags[cr_attr_count]);
1380
if (status != PJ_SUCCESS)
1383
/* Check duplicated tag */
1384
for (j=0; j<cr_attr_count; ++j) {
1385
if (tags[j] == tags[cr_attr_count]) {
1386
DEACTIVATE_MEDIA(sdp_pool, m_loc);
1387
return PJMEDIA_SRTP_ESDPDUPCRYPTOTAG;
1391
if (matched_idx == -1) {
1392
/* lets see if the crypto-suite offered is supported */
1393
for (j=0; j<srtp->setting.crypto_count; ++j)
1394
if (pj_stricmp(&tmp_rx_crypto.name,
1395
&srtp->setting.crypto[j].name) == 0)
1397
int cs_idx = get_crypto_idx(&tmp_rx_crypto.name);
1399
/* Force to use test key */
1400
/* bad keys for snom: */
1401
//char *hex_test_key = "58b29c5c8f42308120ce857e439f2d"
1402
// "7810a8b10ad0b1446be5470faea496";
1403
//char *hex_test_key = "20a26aac7ba062d356ff52b61e3993"
1404
// "ccb78078f12c64db94b9c294927fd0";
1405
//pj_str_t *test_key = &srtp->setting.crypto[j].key;
1406
//char *raw_test_key = pj_pool_zalloc(srtp->pool, 64);
1407
//hex_string_to_octet_string(
1410
// strlen(hex_test_key));
1411
//pj_strset(test_key, raw_test_key,
1412
// crypto_suites[cs_idx].cipher_key_len);
1413
/* EO Force to use test key */
1415
if (tmp_rx_crypto.key.slen !=
1416
(int)crypto_suites[cs_idx].cipher_key_len)
1417
return PJMEDIA_SRTP_EINKEYLEN;
1419
srtp->rx_policy_neg = tmp_rx_crypto;
1420
chosen_tag = tags[cr_attr_count];
1428
/* Check crypto negotiation result */
1429
switch (srtp->setting.use) {
1430
case PJMEDIA_SRTP_DISABLED:
1431
pj_assert(!"Should never reach here");
1434
case PJMEDIA_SRTP_OPTIONAL:
1435
/* bypass SRTP when no crypto-attr and remote uses RTP/AVP */
1436
if (!has_crypto_attr &&
1437
pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0)
1439
/* bypass SRTP when nothing match and remote uses RTP/AVP */
1440
else if (matched_idx == -1 &&
1441
pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0)
1445
case PJMEDIA_SRTP_MANDATORY:
1446
/* Do nothing, intentional */
1450
/* No crypto attr */
1451
if (!has_crypto_attr) {
1452
DEACTIVATE_MEDIA(sdp_pool, m_loc);
1453
return PJMEDIA_SRTP_ESDPREQCRYPTO;
1456
/* No crypto match */
1457
if (matched_idx == -1) {
1458
DEACTIVATE_MEDIA(sdp_pool, m_loc);
1459
return PJMEDIA_SRTP_ENOTSUPCRYPTO;
1462
/* we have to generate crypto answer,
1463
* with srtp->tx_policy_neg matched the offer
1464
* and rem_tag contains matched offer tag.
1466
buffer_len = MAXLEN;
1467
status = generate_crypto_attr_value(srtp->pool, buffer, &buffer_len,
1468
&srtp->setting.crypto[matched_idx],
1470
if (status != PJ_SUCCESS)
1473
srtp->tx_policy_neg = srtp->setting.crypto[matched_idx];
1475
/* If buffer_len==0, just skip the crypto attribute. */
1477
pj_strset(&attr_value, buffer, buffer_len);
1478
attr = pjmedia_sdp_attr_create(sdp_pool, ID_CRYPTO.ptr,
1480
m_loc->attr[m_loc->attr_count++] = attr;
1483
/* At this point, we get valid rx_policy_neg & tx_policy_neg. */
1487
goto PROPAGATE_MEDIA_CREATE;
1490
/* Do not update this flag here as actually the media session hasn't been
1493
//srtp->bypass_srtp = PJ_TRUE;
1495
PROPAGATE_MEDIA_CREATE:
1496
return pjmedia_transport_encode_sdp(srtp->member_tp, sdp_pool,
1497
sdp_local, sdp_remote, media_index);
1502
static pj_status_t transport_media_start(pjmedia_transport *tp,
1504
const pjmedia_sdp_session *sdp_local,
1505
const pjmedia_sdp_session *sdp_remote,
1506
unsigned media_index)
1508
struct transport_srtp *srtp = (struct transport_srtp*) tp;
1509
pjmedia_sdp_media *m_rem, *m_loc;
1513
PJ_ASSERT_RETURN(tp && pool && sdp_local && sdp_remote, PJ_EINVAL);
1515
m_rem = sdp_remote->media[media_index];
1516
m_loc = sdp_local->media[media_index];
1518
if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0)
1519
srtp->peer_use = PJMEDIA_SRTP_MANDATORY;
1521
srtp->peer_use = PJMEDIA_SRTP_OPTIONAL;
1523
/* For answerer side, this function will just have to start SRTP */
1525
/* Check remote media transport & set local media transport
1526
* based on SRTP usage option.
1528
if (srtp->offerer_side) {
1529
if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) {
1530
if (pjmedia_sdp_media_find_attr(m_rem, &ID_CRYPTO, NULL)) {
1531
DEACTIVATE_MEDIA(pool, m_loc);
1532
return PJMEDIA_SRTP_ESDPINCRYPTO;
1535
} else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) {
1536
// Regardless the answer's transport type (RTP/AVP or RTP/SAVP),
1537
// the answer must be processed through in optional mode.
1538
// Please note that at this point transport type is ensured to be
1539
// RTP/AVP or RTP/SAVP, see transport_media_create()
1540
//if (pj_stricmp(&m_rem->desc.transport, &m_loc->desc.transport)) {
1541
//DEACTIVATE_MEDIA(pool, m_loc);
1542
//return PJMEDIA_SDP_EINPROTO;
1544
} else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) {
1545
if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP)) {
1546
DEACTIVATE_MEDIA(pool, m_loc);
1547
return PJMEDIA_SDP_EINPROTO;
1552
if (srtp->offerer_side) {
1553
/* find supported crypto-suite, get the tag, and assign policy_local */
1554
pjmedia_srtp_crypto tmp_tx_crypto;
1555
pj_bool_t has_crypto_attr = PJ_FALSE;
1558
for (i=0; i<m_rem->attr_count; ++i) {
1559
if (pj_stricmp(&m_rem->attr[i]->name, &ID_CRYPTO) != 0)
1562
/* more than one crypto attribute in media answer */
1563
if (has_crypto_attr) {
1564
DEACTIVATE_MEDIA(pool, m_loc);
1565
return PJMEDIA_SRTP_ESDPAMBIGUEANS;
1568
has_crypto_attr = PJ_TRUE;
1570
status = parse_attr_crypto(srtp->pool, m_rem->attr[i],
1571
&tmp_tx_crypto, &rem_tag);
1572
if (status != PJ_SUCCESS)
1576
/* our offer tag is always ordered by setting */
1577
if (rem_tag < 1 || rem_tag > (int)srtp->setting.crypto_count) {
1578
DEACTIVATE_MEDIA(pool, m_loc);
1579
return PJMEDIA_SRTP_ESDPINCRYPTOTAG;
1582
/* match the crypto name */
1583
if (pj_stricmp(&tmp_tx_crypto.name,
1584
&srtp->setting.crypto[rem_tag-1].name) != 0)
1586
DEACTIVATE_MEDIA(pool, m_loc);
1587
return PJMEDIA_SRTP_ECRYPTONOTMATCH;
1590
srtp->tx_policy_neg = srtp->setting.crypto[rem_tag-1];
1591
srtp->rx_policy_neg = tmp_tx_crypto;
1594
if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) {
1595
/* should never reach here */
1597
} else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) {
1598
if (!has_crypto_attr)
1600
} else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) {
1601
if (!has_crypto_attr) {
1602
DEACTIVATE_MEDIA(pool, m_loc);
1603
return PJMEDIA_SRTP_ESDPREQCRYPTO;
1607
/* At this point, we get valid rx_policy_neg & tx_policy_neg. */
1610
/* Make sure we have the SRTP policies */
1611
if (srtp_crypto_empty(&srtp->tx_policy_neg) ||
1612
srtp_crypto_empty(&srtp->rx_policy_neg))
1617
/* Reset probation counts */
1618
srtp->probation_cnt = PROBATION_CNT_INIT;
1620
/* Got policy_local & policy_remote, let's initalize the SRTP */
1622
/* Ticket #1075: media_start() is called whenever media description
1623
* gets updated, e.g: call hold, however we should restart SRTP only
1624
* when the SRTP policy settings are updated.
1626
if (srtp_crypto_cmp(&srtp->tx_policy_neg, &srtp->tx_policy) ||
1627
srtp_crypto_cmp(&srtp->rx_policy_neg, &srtp->rx_policy))
1629
status = pjmedia_transport_srtp_start(tp,
1630
&srtp->tx_policy_neg,
1631
&srtp->rx_policy_neg);
1632
if (status != PJ_SUCCESS)
1636
srtp->bypass_srtp = PJ_FALSE;
1638
goto PROPAGATE_MEDIA_START;
1641
srtp->bypass_srtp = PJ_TRUE;
1642
srtp->peer_use = PJMEDIA_SRTP_DISABLED;
1643
if (srtp->session_inited) {
1644
pjmedia_transport_srtp_stop(tp);
1647
PROPAGATE_MEDIA_START:
1648
return pjmedia_transport_media_start(srtp->member_tp, pool,
1649
sdp_local, sdp_remote,
1653
static pj_status_t transport_media_stop(pjmedia_transport *tp)
1655
struct transport_srtp *srtp = (struct transport_srtp*) tp;
1658
PJ_ASSERT_RETURN(tp, PJ_EINVAL);
1660
status = pjmedia_transport_media_stop(srtp->member_tp);
1661
if (status != PJ_SUCCESS)
1662
PJ_LOG(4, (srtp->pool->obj_name,
1663
"SRTP failed stop underlying media transport."));
1665
return pjmedia_transport_srtp_stop(tp);
1669
PJ_DEF(pj_status_t) pjmedia_transport_srtp_decrypt_pkt(pjmedia_transport *tp,
1674
transport_srtp *srtp = (transport_srtp *)tp;
1677
if (srtp->bypass_srtp)
1680
PJ_ASSERT_RETURN(tp && pkt && (*pkt_len>0), PJ_EINVAL);
1681
PJ_ASSERT_RETURN(srtp->session_inited, PJ_EINVALIDOP);
1683
/* Make sure buffer is 32bit aligned */
1684
PJ_ASSERT_ON_FAIL( (((long)pkt) & 0x03)==0, return PJ_EINVAL);
1686
pj_lock_acquire(srtp->mutex);
1688
if (!srtp->session_inited) {
1689
pj_lock_release(srtp->mutex);
1690
return PJ_EINVALIDOP;
1694
err = srtp_unprotect(srtp->srtp_rx_ctx, pkt, pkt_len);
1696
err = srtp_unprotect_rtcp(srtp->srtp_rx_ctx, pkt, pkt_len);
1698
if (err != err_status_ok) {
1699
PJ_LOG(5,(srtp->pool->obj_name,
1700
"Failed to unprotect SRTP, pkt size=%d, err=%s",
1701
*pkt_len, get_libsrtp_errstr(err)));
1704
pj_lock_release(srtp->mutex);
1706
return (err==err_status_ok) ? PJ_SUCCESS : PJMEDIA_ERRNO_FROM_LIBSRTP(err);