Fix reINVITE issues when SRTP mode is mandatory
This commit is contained in:
parent
493815f88e
commit
9f4760fe25
|
@ -1107,6 +1107,7 @@ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t*
|
|||
tsk_bool_t is_ice_enabled[TMEDIA_SESSION_MAX_LINES] = { tsk_false };
|
||||
tsk_bool_t is_ice_restart[TMEDIA_SESSION_MAX_LINES] = { tsk_false };
|
||||
tsk_bool_t is_dtls_fingerprint_changed[TMEDIA_SESSION_MAX_LINES] = { tsk_false };
|
||||
tsk_bool_t is_sdes_crypto_changed[TMEDIA_SESSION_MAX_LINES] = { tsk_false };
|
||||
tmedia_type_t media_types[TMEDIA_SESSION_MAX_LINES] = { tmedia_none };
|
||||
tsk_bool_t is_media_type_changed = tsk_false;
|
||||
tsk_bool_t is_ro_media_lines_changed = tsk_false;
|
||||
|
@ -1189,12 +1190,13 @@ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t*
|
|||
while ((M0 = (const tsdp_header_M_t*)tsdp_message_get_headerAt(self->sdp.ro, tsdp_htype_M, index))){
|
||||
++m_lines_count;
|
||||
if (m_lines_count >= TMEDIA_SESSION_MAX_LINES) {
|
||||
TSK_DEBUG_ERROR("Too many m-lines %d>%d", m_lines_count, TMEDIA_SESSION_MAX_LINES);
|
||||
TSK_DEBUG_ERROR("Too many m-lines %u>%u", (unsigned)m_lines_count, (unsigned)TMEDIA_SESSION_MAX_LINES);
|
||||
ret = -2;
|
||||
goto bail;
|
||||
}
|
||||
M1 = (const tsdp_header_M_t*)tsdp_message_get_headerAt(sdp, tsdp_htype_M, index);
|
||||
// media-level diffs
|
||||
|
||||
if ((ret = tsdp_header_M_diff(M0, M1, &med_level_diff)) != 0) {
|
||||
goto bail;
|
||||
}
|
||||
|
@ -1205,8 +1207,8 @@ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t*
|
|||
if (tmedia_defaults_get_ice_enabled() && (med_level_diff & tsdp_header_M_diff_ice_enabled)) is_ice_enabled[index] = tsk_true;
|
||||
if (tmedia_defaults_get_ice_enabled() && (med_level_diff & tsdp_header_M_diff_ice_restart)) is_ice_restart[index] = tsk_true;
|
||||
if (med_level_diff & tsdp_header_M_diff_dtls_fingerprint) is_dtls_fingerprint_changed[index] = tsk_true;
|
||||
if (med_level_diff & tsdp_header_M_diff_sdes_crypto);
|
||||
if (med_level_diff & tsdp_header_M_diff_media_type);
|
||||
if (med_level_diff & tsdp_header_M_diff_sdes_crypto) is_sdes_crypto_changed[index] = tsk_true;
|
||||
if (med_level_diff & tsdp_header_M_diff_media_type); // cannot happen as media must keep same index
|
||||
|
||||
// dtls fingerprint (session-level)
|
||||
if (!is_dtls_fingerprint_changed[index]) {
|
||||
|
@ -1225,6 +1227,7 @@ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t*
|
|||
}
|
||||
}
|
||||
}
|
||||
// TODO: sdes crypo lines (session-level)
|
||||
|
||||
// media type
|
||||
media_types[index] = tmedia_type_from_sdp_headerM(M1);
|
||||
|
@ -1313,6 +1316,7 @@ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t*
|
|||
TSK_DEBUG_INFO(
|
||||
"m_lines_count=%u,\n"
|
||||
"is_dtls_fingerprint_changed=%u,\n"
|
||||
"is_sdes_crypto_changed=%u,\n"
|
||||
"is_ice_enabled=%u,\n"
|
||||
"is_ice_restart=%u,\n"
|
||||
"is_ro_hold_resume_changed=%u,\n"
|
||||
|
@ -1325,6 +1329,7 @@ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t*
|
|||
"is_local_encoder_still_ok=%u\n",
|
||||
(unsigned)m_lines_count,
|
||||
(unsigned)__flags_sum((const tsk_bool_t*)&is_dtls_fingerprint_changed, m_lines_count),
|
||||
(unsigned)__flags_sum((const tsk_bool_t*)&is_sdes_crypto_changed, m_lines_count),
|
||||
(unsigned)__flags_sum((const tsk_bool_t*)&is_ice_enabled, m_lines_count),
|
||||
(unsigned)__flags_sum((const tsk_bool_t*)&is_ice_restart, m_lines_count),
|
||||
(unsigned)__flags_sum((const tsk_bool_t*)&is_ro_hold_resume_changed, m_lines_count),
|
||||
|
@ -1348,7 +1353,7 @@ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t*
|
|||
*/
|
||||
if (self->started) {
|
||||
for (index = 0; index < m_lines_count; ++index) {
|
||||
if (/* && (!is_ro_loopback_address[index]) && */ ((is_ro_codecs_changed[index] && !is_local_encoder_still_ok[index]) || is_ro_network_info_changed[index] || is_dtls_fingerprint_changed[index])) {
|
||||
if (/* && (!is_ro_loopback_address[index]) && */ ((is_ro_codecs_changed[index] && !is_local_encoder_still_ok[index]) || is_ro_network_info_changed[index] || is_dtls_fingerprint_changed[index] || is_sdes_crypto_changed[index])) {
|
||||
TSK_DEBUG_INFO("Stop media index %d to reconf", (int)index);
|
||||
stopped_to_reconf[index] = tsk_true;
|
||||
tmedia_session_mgr_set(self,
|
||||
|
@ -1518,7 +1523,7 @@ end_of_sessions_update:
|
|||
for (index = 0; index < m_lines_count; ++index) {
|
||||
if (stopped_to_reconf[index] && !is_ice_enabled[index]) {
|
||||
if ((ret = _tmedia_session_mgr_start(self, (int)index))) {
|
||||
TSK_DEBUG_ERROR("Failed to re-start session at index = %d", index);
|
||||
TSK_DEBUG_ERROR("Failed to re-start session at index = %d", (int)index);
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
|
@ -2365,7 +2370,7 @@ static int _tmedia_session_mgr_start(tmedia_session_mgr_t* self, int session_ind
|
|||
}
|
||||
}
|
||||
}
|
||||
if (session_index) {
|
||||
if (session_index == kSessionIndexAll) {
|
||||
self->started = tsk_true;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@ typedef struct trtp_srtp_ctx_internal_xs
|
|||
trtp_srtp_crypto_type_t crypto_type;
|
||||
char key_str[SRTP_MAX_KEY_LEN];
|
||||
char key_bin[SRTP_MASTER_KEY_LEN];
|
||||
tsk_bool_t have_valid_key;
|
||||
|
||||
srtp_t session;
|
||||
srtp_policy_t policy;
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
/*
|
||||
* Copyright (C) 2012 Mamadou Diop
|
||||
* Copyright (C) 2012-2013 Doubango Telecom <http://www.doubango.org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
* Copyright (C) 2012 Mamadou Diop
|
||||
* Copyright (C) 2012-2013 Doubango Telecom <http://www.doubango.org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
/**@file trtp_srtp.c
|
||||
*/
|
||||
#include "tinyrtp/trtp_srtp.h"
|
||||
|
@ -30,297 +30,303 @@ crypto_get_random(unsigned char *buffer, unsigned int length);
|
|||
|
||||
int trtp_srtp_ctx_internal_init(struct trtp_srtp_ctx_internal_xs* ctx, int32_t tag, trtp_srtp_crypto_type_t type, uint32_t ssrc)
|
||||
{
|
||||
char* key_str = ctx->key_str;
|
||||
err_status_t srtp_err;
|
||||
tsk_size_t size;
|
||||
|
||||
if(!ctx){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ctx->initialized){
|
||||
trtp_srtp_ctx_internal_deinit(ctx);
|
||||
}
|
||||
|
||||
ctx->tag = tag;
|
||||
ctx->crypto_type = type;
|
||||
if((srtp_err = crypto_get_random((unsigned char*)ctx->key_bin, sizeof(ctx->key_bin))) != err_status_ok){
|
||||
TSK_DEBUG_ERROR("crypto_get_random() failed");
|
||||
return -2;
|
||||
}
|
||||
size = tsk_base64_encode((const uint8_t*)ctx->key_bin, sizeof(ctx->key_bin), &key_str);
|
||||
key_str[size] = '\0';
|
||||
|
||||
switch(ctx->crypto_type){
|
||||
case HMAC_SHA1_80:
|
||||
{
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&ctx->policy.rtp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&ctx->policy.rtcp);
|
||||
break;
|
||||
}
|
||||
case HMAC_SHA1_32:
|
||||
default:
|
||||
{
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_32(&ctx->policy.rtp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&ctx->policy.rtcp); // RTCP always 80
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->policy.key = (unsigned char*)ctx->key_bin;
|
||||
ctx->policy.ssrc.type = ssrc_any_outbound;
|
||||
ctx->policy.ssrc.value = ssrc;
|
||||
ctx->policy.window_size = 2048;
|
||||
ctx->policy.allow_repeat_tx = 1;
|
||||
if((srtp_err = srtp_create(&ctx->session, &ctx->policy)) != err_status_ok){
|
||||
TSK_DEBUG_ERROR("srtp_create() failed");
|
||||
return -3;
|
||||
}
|
||||
ctx->initialized = tsk_true;
|
||||
return 0;
|
||||
char* key_str = ctx->key_str;
|
||||
err_status_t srtp_err;
|
||||
tsk_size_t size;
|
||||
|
||||
if (!ctx) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ctx->initialized) {
|
||||
trtp_srtp_ctx_internal_deinit(ctx);
|
||||
}
|
||||
|
||||
ctx->tag = tag;
|
||||
ctx->crypto_type = type;
|
||||
if (!ctx->have_valid_key) { // use same key to avoid unseless SRTP re-negs (also fix interop-issues against buggy clients -reINVITEs-)
|
||||
if ((srtp_err = crypto_get_random((unsigned char*)ctx->key_bin, sizeof(ctx->key_bin))) != err_status_ok) {
|
||||
TSK_DEBUG_ERROR("crypto_get_random() failed");
|
||||
return -2;
|
||||
}
|
||||
size = tsk_base64_encode((const uint8_t*)ctx->key_bin, sizeof(ctx->key_bin), &key_str);
|
||||
key_str[size] = '\0';
|
||||
ctx->have_valid_key = tsk_true;
|
||||
}
|
||||
|
||||
switch(ctx->crypto_type){
|
||||
case HMAC_SHA1_80:
|
||||
{
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&ctx->policy.rtp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&ctx->policy.rtcp);
|
||||
break;
|
||||
}
|
||||
case HMAC_SHA1_32:
|
||||
default:
|
||||
{
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_32(&ctx->policy.rtp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&ctx->policy.rtcp); // RTCP always 80
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->policy.key = (unsigned char*)ctx->key_bin;
|
||||
ctx->policy.ssrc.type = ssrc_any_outbound;
|
||||
ctx->policy.ssrc.value = ssrc;
|
||||
ctx->policy.window_size = 2048;
|
||||
ctx->policy.allow_repeat_tx = 1;
|
||||
if ((srtp_err = srtp_create(&ctx->session, &ctx->policy)) != err_status_ok) {
|
||||
TSK_DEBUG_ERROR("srtp_create() failed");
|
||||
return -3;
|
||||
}
|
||||
ctx->initialized = tsk_true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int trtp_srtp_ctx_internal_deinit(struct trtp_srtp_ctx_internal_xs* ctx)
|
||||
{
|
||||
if(!ctx){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if(ctx->initialized){
|
||||
/*err_status_t srtp_err =*/ srtp_dealloc(ctx->session);
|
||||
memset(&ctx->policy, 0, sizeof(ctx->policy));
|
||||
ctx->initialized = tsk_false;
|
||||
}
|
||||
return 0;
|
||||
if(!ctx){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if(ctx->initialized){
|
||||
/*err_status_t srtp_err =*/ srtp_dealloc(ctx->session);
|
||||
memset(&ctx->policy, 0, sizeof(ctx->policy));
|
||||
ctx->initialized = tsk_false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int trtp_srtp_ctx_init(trtp_srtp_ctx_xt* ctx, int32_t tag, trtp_srtp_crypto_type_t type, uint32_t ssrc)
|
||||
{
|
||||
int ret;
|
||||
if(!ctx){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if((ret = trtp_srtp_ctx_internal_init(&ctx->rtp, tag, type, ssrc))){
|
||||
return ret;
|
||||
}
|
||||
return trtp_srtp_ctx_internal_init(&ctx->rtcp, tag, type, ssrc);
|
||||
int ret;
|
||||
if(!ctx){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if((ret = trtp_srtp_ctx_internal_init(&ctx->rtp, tag, type, ssrc))){
|
||||
return ret;
|
||||
}
|
||||
return trtp_srtp_ctx_internal_init(&ctx->rtcp, tag, type, ssrc);
|
||||
}
|
||||
|
||||
int trtp_srtp_ctx_deinit(trtp_srtp_ctx_xt* ctx)
|
||||
{
|
||||
int ret;
|
||||
if(!ctx){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if((ret = trtp_srtp_ctx_internal_deinit(&ctx->rtp))){
|
||||
return ret;
|
||||
}
|
||||
return trtp_srtp_ctx_internal_deinit(&ctx->rtcp);
|
||||
{
|
||||
int ret;
|
||||
if(!ctx){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if((ret = trtp_srtp_ctx_internal_deinit(&ctx->rtp))){
|
||||
return ret;
|
||||
}
|
||||
return trtp_srtp_ctx_internal_deinit(&ctx->rtcp);
|
||||
}
|
||||
|
||||
int trtp_srtp_match_line(const char* crypto_line, int32_t* tag, int32_t* crypto_type, char* key, tsk_size_t key_size)
|
||||
{
|
||||
char* saveptr;
|
||||
char* v = tsk_strtok_r((char*)crypto_line, " :|;", &saveptr);
|
||||
int32_t k = 0;
|
||||
while(v){
|
||||
switch(k){
|
||||
case 0:
|
||||
{
|
||||
if(tag){
|
||||
*tag = atoi(v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if(tsk_striequals(v, TRTP_SRTP_AES_CM_128_HMAC_SHA1_80)){
|
||||
if(crypto_type){
|
||||
*crypto_type = HMAC_SHA1_80;
|
||||
}
|
||||
}
|
||||
else if(tsk_striequals(v, TRTP_SRTP_AES_CM_128_HMAC_SHA1_32)){
|
||||
if(crypto_type){
|
||||
*crypto_type = HMAC_SHA1_32;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return -0xFF;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
if(!tsk_striequals(v, "inline")){
|
||||
return -0xFF;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
if(key && key_size){
|
||||
memset(key, 0, key_size);
|
||||
memcpy(key, v, TSK_MIN(key_size, tsk_strlen(v)));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
++k;
|
||||
v = tsk_strtok_r(tsk_null, " :|;", &saveptr);
|
||||
}
|
||||
|
||||
return -0xF0;
|
||||
char* copyptr = tsk_strdup(crypto_line); // "strtok_r" will insert "\0" and modify the string
|
||||
char* saveptr = tsk_null;
|
||||
char* v = tsk_strtok_r(copyptr, " :|;", &saveptr);
|
||||
int32_t k = 0;
|
||||
int ret = -0xF0;
|
||||
while(v){
|
||||
switch(k){
|
||||
case 0:
|
||||
{
|
||||
if(tag){
|
||||
*tag = atoi(v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if(tsk_striequals(v, TRTP_SRTP_AES_CM_128_HMAC_SHA1_80)){
|
||||
if(crypto_type){
|
||||
*crypto_type = HMAC_SHA1_80;
|
||||
}
|
||||
}
|
||||
else if(tsk_striequals(v, TRTP_SRTP_AES_CM_128_HMAC_SHA1_32)){
|
||||
if(crypto_type){
|
||||
*crypto_type = HMAC_SHA1_32;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = -0xFF; goto bail;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
if(!tsk_striequals(v, "inline")){
|
||||
ret = -0xFF; goto bail;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
if(key && key_size){
|
||||
memset(key, 0, key_size);
|
||||
memcpy(key, v, TSK_MIN(key_size, tsk_strlen(v)));
|
||||
}
|
||||
ret = 0; goto bail;
|
||||
}
|
||||
}
|
||||
++k;
|
||||
v = tsk_strtok_r(tsk_null, " :|;", &saveptr);
|
||||
}
|
||||
bail:
|
||||
TSK_FREE(copyptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
tsk_size_t trtp_srtp_get_local_contexts(trtp_manager_t* rtp_mgr, const struct trtp_srtp_ctx_xs ** contexts, tsk_size_t contexts_count)
|
||||
{
|
||||
tsk_size_t ret = 0;
|
||||
if(!rtp_mgr || !contexts){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(contexts_count > ret && rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_80].rtp.initialized){
|
||||
contexts[ret++] = &rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_80];
|
||||
}
|
||||
if(contexts_count > ret && rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_32].rtp.initialized){
|
||||
contexts[ret++] = &rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_32];
|
||||
}
|
||||
return ret;
|
||||
tsk_size_t ret = 0;
|
||||
if(!rtp_mgr || !contexts){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (contexts_count > ret && rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_80].rtp.initialized) {
|
||||
contexts[ret++] = &rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_80];
|
||||
}
|
||||
if (contexts_count > ret && rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_32].rtp.initialized) {
|
||||
contexts[ret++] = &rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_32];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int trtp_srtp_set_crypto(struct trtp_manager_s* rtp_mgr, const char* crypto_line, int32_t idx)
|
||||
{
|
||||
//e.g. 2 F8_128_HMAC_SHA1_80 inline:MTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5QUJjZGVm|2^20|1:4;inline:QUJjZGVmMTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5|2^20|2:4"
|
||||
trtp_srtp_ctx_xt* srtp_ctx;
|
||||
int ret;
|
||||
uint8_t *key_bin;
|
||||
err_status_t srtp_err;
|
||||
int32_t tag, crypto_type;
|
||||
char key_str[SRTP_MAX_KEY_LEN + 1];
|
||||
|
||||
memset(key_str, 0, sizeof(key_str));
|
||||
|
||||
if((ret = trtp_srtp_match_line(crypto_line, &tag, &crypto_type, key_str, sizeof(key_str) - 1))){
|
||||
return ret;
|
||||
}
|
||||
|
||||
srtp_ctx = &rtp_mgr->srtp_contexts[idx][crypto_type];
|
||||
ret = trtp_srtp_ctx_deinit(srtp_ctx);
|
||||
|
||||
srtp_ctx->rtp.tag = tag;
|
||||
srtp_ctx->rtp.crypto_type = (trtp_srtp_crypto_type_t)crypto_type;
|
||||
memcpy(srtp_ctx->rtp.key_str, key_str, sizeof(srtp_ctx->rtp.key_str));
|
||||
|
||||
switch(srtp_ctx->rtp.crypto_type){
|
||||
case HMAC_SHA1_80:
|
||||
{
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->rtp.policy.rtp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->rtp.policy.rtcp);
|
||||
if(idx == TRTP_SRTP_LINE_IDX_REMOTE){
|
||||
trtp_srtp_ctx_deinit(&rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_32]);
|
||||
rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_80].rtp.tag =
|
||||
rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_80].rtcp.tag = srtp_ctx->rtp.tag;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HMAC_SHA1_32:
|
||||
{
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_32(&srtp_ctx->rtp.policy.rtp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->rtp.policy.rtcp); // RTCP always 80
|
||||
if(idx == TRTP_SRTP_LINE_IDX_REMOTE){
|
||||
trtp_srtp_ctx_deinit(&rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_80]);
|
||||
rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_32].rtp.tag =
|
||||
rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_32].rtcp.tag = srtp_ctx->rtp.tag;
|
||||
}
|
||||
break;
|
||||
}
|
||||
//e.g. 2 F8_128_HMAC_SHA1_80 inline:MTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5QUJjZGVm|2^20|1:4;inline:QUJjZGVmMTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5|2^20|2:4"
|
||||
trtp_srtp_ctx_xt* srtp_ctx;
|
||||
int ret;
|
||||
uint8_t *key_bin;
|
||||
err_status_t srtp_err;
|
||||
int32_t tag, crypto_type;
|
||||
char key_str[SRTP_MAX_KEY_LEN + 1];
|
||||
|
||||
memset(key_str, 0, sizeof(key_str));
|
||||
|
||||
if ((ret = trtp_srtp_match_line(crypto_line, &tag, &crypto_type, key_str, sizeof(key_str) - 1))) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
srtp_ctx = &rtp_mgr->srtp_contexts[idx][crypto_type];
|
||||
ret = trtp_srtp_ctx_deinit(srtp_ctx);
|
||||
|
||||
srtp_ctx->rtp.tag = tag;
|
||||
srtp_ctx->rtp.crypto_type = (trtp_srtp_crypto_type_t)crypto_type;
|
||||
memcpy(srtp_ctx->rtp.key_str, key_str, sizeof(srtp_ctx->rtp.key_str));
|
||||
|
||||
switch(srtp_ctx->rtp.crypto_type){
|
||||
case HMAC_SHA1_80:
|
||||
{
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->rtp.policy.rtp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->rtp.policy.rtcp);
|
||||
if (idx == TRTP_SRTP_LINE_IDX_REMOTE) {
|
||||
trtp_srtp_ctx_deinit(&rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_32]);
|
||||
rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_80].rtp.tag =
|
||||
rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_80].rtcp.tag = srtp_ctx->rtp.tag;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HMAC_SHA1_32:
|
||||
{
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_32(&srtp_ctx->rtp.policy.rtp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->rtp.policy.rtcp); // RTCP always 80
|
||||
if (idx == TRTP_SRTP_LINE_IDX_REMOTE) {
|
||||
trtp_srtp_ctx_deinit(&rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_80]);
|
||||
rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_32].rtp.tag =
|
||||
rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_32].rtcp.tag = srtp_ctx->rtp.tag;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
key_bin = (unsigned char*)srtp_ctx->rtp.key_bin;
|
||||
tsk_base64_decode((const uint8_t*)srtp_ctx->rtp.key_str, tsk_strlen(srtp_ctx->rtp.key_str), (char**)&key_bin);
|
||||
srtp_ctx->rtp.policy.key = key_bin;
|
||||
srtp_ctx->rtp.policy.ssrc.type = idx == TRTP_SRTP_LINE_IDX_REMOTE ? ssrc_any_inbound : ssrc_any_outbound;
|
||||
srtp_ctx->rtp.policy.window_size = 2048;
|
||||
srtp_ctx->rtp.policy.allow_repeat_tx = 1;
|
||||
if((srtp_err = srtp_create(&srtp_ctx->rtp.session, &srtp_ctx->rtp.policy)) != err_status_ok){
|
||||
TSK_DEBUG_ERROR("srtp_create() failed: %d", srtp_err);
|
||||
return -3;
|
||||
}
|
||||
srtp_ctx->rtp.initialized = tsk_true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
key_bin = (unsigned char*)srtp_ctx->rtp.key_bin;
|
||||
tsk_base64_decode((const uint8_t*)srtp_ctx->rtp.key_str, (tsk_size_t)tsk_strlen(srtp_ctx->rtp.key_str), (char**)&key_bin);
|
||||
srtp_ctx->rtp.policy.key = key_bin;
|
||||
srtp_ctx->rtp.policy.ssrc.type = idx == TRTP_SRTP_LINE_IDX_REMOTE ? ssrc_any_inbound : ssrc_any_outbound;
|
||||
srtp_ctx->rtp.policy.window_size = 2048;
|
||||
srtp_ctx->rtp.policy.allow_repeat_tx = 1;
|
||||
if ((srtp_err = srtp_create(&srtp_ctx->rtp.session, &srtp_ctx->rtp.policy)) != err_status_ok) {
|
||||
TSK_DEBUG_ERROR("srtp_create() failed: %d", srtp_err);
|
||||
return -3;
|
||||
}
|
||||
srtp_ctx->rtp.initialized = tsk_true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int trtp_srtp_set_key_and_salt(trtp_manager_t* rtp_mgr, trtp_srtp_crypto_type_t crypto_type, const void* key, tsk_size_t key_size, const void* salt, tsk_size_t salt_size, int32_t idx, tsk_bool_t is_rtp)
|
||||
{
|
||||
int ret;
|
||||
trtp_srtp_ctx_internal_xt* srtp_ctx;
|
||||
err_status_t srtp_err;
|
||||
if(!rtp_mgr || !key || !key_size || !salt || !salt_size){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
srtp_ctx = is_rtp ? &rtp_mgr->srtp_contexts[idx][crypto_type].rtp : &rtp_mgr->srtp_contexts[idx][crypto_type].rtcp;
|
||||
if((ret = trtp_srtp_ctx_internal_deinit(srtp_ctx))){
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch((srtp_ctx->crypto_type = crypto_type)){
|
||||
case HMAC_SHA1_80:
|
||||
default:
|
||||
{
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->policy.rtp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->policy.rtcp);
|
||||
break;
|
||||
}
|
||||
case HMAC_SHA1_32:
|
||||
{
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_32(&srtp_ctx->policy.rtp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->policy.rtcp); // always 80
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(srtp_ctx->key_bin, key, key_size);
|
||||
int ret;
|
||||
trtp_srtp_ctx_internal_xt* srtp_ctx;
|
||||
err_status_t srtp_err;
|
||||
if (!rtp_mgr || !key || !key_size || !salt || !salt_size) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
srtp_ctx = is_rtp ? &rtp_mgr->srtp_contexts[idx][crypto_type].rtp : &rtp_mgr->srtp_contexts[idx][crypto_type].rtcp;
|
||||
if ((ret = trtp_srtp_ctx_internal_deinit(srtp_ctx))) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch ((srtp_ctx->crypto_type = crypto_type)) {
|
||||
case HMAC_SHA1_80:
|
||||
default:
|
||||
{
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->policy.rtp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->policy.rtcp);
|
||||
break;
|
||||
}
|
||||
case HMAC_SHA1_32:
|
||||
{
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_32(&srtp_ctx->policy.rtp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->policy.rtcp); // always 80
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(srtp_ctx->key_bin, key, key_size);
|
||||
#if HAVE_APPEND_SALT_TO_KEY
|
||||
append_salt_to_key(srtp_ctx->key_bin, key_size, (void*)salt, salt_size);
|
||||
append_salt_to_key(srtp_ctx->key_bin, key_size, (void*)salt, salt_size);
|
||||
#else
|
||||
memcpy(&srtp_ctx->key_bin[key_size], salt, salt_size);
|
||||
memcpy(&srtp_ctx->key_bin[key_size], salt, salt_size);
|
||||
#endif
|
||||
|
||||
srtp_ctx->policy.key = (unsigned char *)srtp_ctx->key_bin;
|
||||
srtp_ctx->policy.ssrc.type = idx == TRTP_SRTP_LINE_IDX_REMOTE ? ssrc_any_inbound : ssrc_any_outbound;
|
||||
srtp_ctx->policy.window_size = 2048;
|
||||
srtp_ctx->policy.allow_repeat_tx = 1;
|
||||
if((srtp_err = srtp_create(&srtp_ctx->session, &srtp_ctx->policy)) != err_status_ok){
|
||||
TSK_DEBUG_ERROR("srtp_create() failed: %d", srtp_err);
|
||||
return -3;
|
||||
}
|
||||
srtp_ctx->initialized = tsk_true;
|
||||
return 0;
|
||||
|
||||
srtp_ctx->policy.key = (unsigned char *)srtp_ctx->key_bin;
|
||||
srtp_ctx->policy.ssrc.type = idx == TRTP_SRTP_LINE_IDX_REMOTE ? ssrc_any_inbound : ssrc_any_outbound;
|
||||
srtp_ctx->policy.window_size = 2048;
|
||||
srtp_ctx->policy.allow_repeat_tx = 1;
|
||||
if((srtp_err = srtp_create(&srtp_ctx->session, &srtp_ctx->policy)) != err_status_ok){
|
||||
TSK_DEBUG_ERROR("srtp_create() failed: %d", srtp_err);
|
||||
return -3;
|
||||
}
|
||||
srtp_ctx->initialized = tsk_true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tsk_bool_t trtp_srtp_is_initialized(trtp_manager_t* rtp_mgr)
|
||||
{
|
||||
if(!rtp_mgr){
|
||||
return tsk_false;
|
||||
}
|
||||
return ((rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][0].rtp.initialized || rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][1].rtp.initialized)
|
||||
&& rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_REMOTE][0].rtp.initialized);
|
||||
if (!rtp_mgr) {
|
||||
return tsk_false;
|
||||
}
|
||||
return ((rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][0].rtp.initialized || rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][1].rtp.initialized)
|
||||
&& rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_REMOTE][0].rtp.initialized);
|
||||
}
|
||||
|
||||
tsk_bool_t trtp_srtp_is_started(trtp_manager_t* rtp_mgr)
|
||||
{
|
||||
if(!rtp_mgr){
|
||||
TSK_DEBUG_ERROR("Invalid argument");
|
||||
return tsk_false;
|
||||
}
|
||||
return (rtp_mgr ->srtp_ctx_neg_remote && rtp_mgr ->srtp_ctx_neg_local);
|
||||
if (!rtp_mgr) {
|
||||
TSK_DEBUG_ERROR("Invalid argument");
|
||||
return tsk_false;
|
||||
}
|
||||
return (rtp_mgr ->srtp_ctx_neg_remote && rtp_mgr ->srtp_ctx_neg_local);
|
||||
}
|
||||
|
||||
#endif /* HAVE_SRTP */
|
|
@ -818,13 +818,13 @@ tsk_bool_t tsdp_header_M_is_ice_enabled(const tsdp_header_M_t* self)
|
|||
const tsdp_header_A_t *A;
|
||||
tsk_bool_t have_ufrag = tsk_false, have_pwd = tsk_false, have_candidates = tsk_false;
|
||||
|
||||
if ((A = tsdp_header_M_findA(self, "ice-ufrag"))) {
|
||||
have_ufrag = tsk_true;
|
||||
}
|
||||
if ((A = tsdp_header_M_findA(self, "ice-pwd"))) {
|
||||
have_pwd = tsk_true;
|
||||
}
|
||||
have_candidates = (tsdp_header_M_findA_at(self, "candidate", 0) != tsk_null);
|
||||
if ((A = tsdp_header_M_findA(self, "ice-ufrag"))) {
|
||||
have_ufrag = tsk_true;
|
||||
}
|
||||
if ((A = tsdp_header_M_findA(self, "ice-pwd"))) {
|
||||
have_pwd = tsk_true;
|
||||
}
|
||||
have_candidates = (tsdp_header_M_findA_at(self, "candidate", 0) != tsk_null);
|
||||
return have_ufrag && have_pwd && have_candidates;
|
||||
}
|
||||
return tsk_false;
|
||||
|
@ -873,14 +873,16 @@ int tsdp_header_M_diff(const tsdp_header_M_t* M_old, const tsdp_header_M_t* M_ne
|
|||
do {
|
||||
A0 = tsdp_header_M_findA_at(M_old, "crypto", index);
|
||||
A1 = M_new ? tsdp_header_M_findA_at(M_new, "crypto", index) : tsk_null;
|
||||
if (A0 && A1 && !tsk_striequals(A0->value, A1->value)) {
|
||||
diff |= tsdp_header_M_diff_dtls_fingerprint;
|
||||
}
|
||||
else if ((A0 && !A1) || (!A0 && A1)) {
|
||||
diff |= tsdp_header_M_diff_dtls_fingerprint;
|
||||
}
|
||||
if (A0 && A1) {
|
||||
if (!tsk_striequals(A0->value, A1->value)) {
|
||||
diff |= tsdp_header_M_diff_sdes_crypto;
|
||||
}
|
||||
}
|
||||
else if (index == 0) { // (A1 && !AO) means "more" crypto lines, otherwise "less". In all cases if the first matched we're ok
|
||||
diff |= tsdp_header_M_diff_sdes_crypto;
|
||||
}
|
||||
++index;
|
||||
} while (A0 && A1);
|
||||
} while ((A0 && A1) && ((diff & tsdp_header_M_diff_sdes_crypto) != tsdp_header_M_diff_sdes_crypto));
|
||||
|
||||
// media lines
|
||||
if ((diff & tsdp_header_M_diff_index) != tsdp_header_M_diff_index) {
|
||||
|
|
Loading…
Reference in New Issue