rtp_secure_media=mandatory
rtp_secure_media=optional
rtp_secure_media=mandatory:AES_CM_256_HMAC_SHA1_80,AES_CM_256_HMAC_SHA1_32
rtp_secure_media=optional:AES_CM_256_HMAC_SHA1_80
rtp_secure_media=forbidden

true implies mandatory
false implies forbidden
not set implies optional

rtp_secure_media_inbound or rtp_secure_media_outbound take precedence and are treated the same way based on leg direction
This commit is contained in:
Anthony Minessale 2014-03-06 07:33:05 +05:00
parent eba0cb5f0f
commit e5b291514c
5 changed files with 438 additions and 376 deletions

View File

@ -169,7 +169,7 @@ SWITCH_DECLARE(void) switch_media_handle_set_media_flag(switch_media_handle_t *s
SWITCH_DECLARE(void) switch_media_handle_clear_media_flag(switch_media_handle_t *smh, switch_core_media_flag_t flag);
SWITCH_DECLARE(int32_t) switch_media_handle_test_media_flag(switch_media_handle_t *smh, switch_core_media_flag_t flag);
SWITCH_DECLARE(void) switch_media_handle_set_media_flags(switch_media_handle_t *smh, switch_core_media_flag_t flags[]);
SWITCH_DECLARE(void) switch_core_session_check_outgoing_crypto(switch_core_session_t *session, const char *sec_var);
SWITCH_DECLARE(void) switch_core_session_check_outgoing_crypto(switch_core_session_t *session);
SWITCH_DECLARE(const char *) switch_core_session_local_crypto_key(switch_core_session_t *session, switch_media_type_t type);
SWITCH_DECLARE(int) switch_core_session_check_incoming_crypto(switch_core_session_t *session,
const char *varname,

View File

@ -1223,13 +1223,6 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
sofia_glue_execute_sql_now(tech_pvt->profile, &sql, SWITCH_TRUE);
}
if (((var = switch_channel_get_variable(channel, SOFIA_SECURE_MEDIA_VARIABLE)) ||
(var = switch_channel_get_variable(channel, "rtp_secure_media"))) &&
(switch_true(var) || switch_core_media_crypto_str2type(var) != CRYPTO_INVALID)) {
switch_channel_set_flag(tech_pvt->channel, CF_SECURE);
}
if (sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_TIMING)) {
switch_core_media_reset_autofix(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
}
@ -1252,18 +1245,18 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ:
{
const char *pl = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<media_control>\n<vc_primitive>\n<to_encoder>\n<picture_fast_update>\n</picture_fast_update>\n</to_encoder>\n</vc_primitive>\n</media_control>";
//time_t now = switch_epoch_time_now(NULL);
time_t now = switch_epoch_time_now(NULL);
//if (!tech_pvt->last_vid_info || (now - tech_pvt->last_vid_info) > 5) {
if (!tech_pvt->last_vid_info || (now - tech_pvt->last_vid_info) > 1) {
// tech_pvt->last_vid_info = now;
tech_pvt->last_vid_info = now;
if (!zstr(msg->string_arg)) {
pl = msg->string_arg;
}
nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("application/media_control+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END());
//}
}
}
break;
@ -4349,18 +4342,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
tech_pvt->dest_to = tech_pvt->dest;
}
if ((hval = switch_event_get_header(var_event, "media_webrtc")) && switch_true(hval)) {
switch_channel_set_variable(nchannel, "rtp_secure_media", SWITCH_RTP_CRYPTO_KEY_80);
}
if ((hval = switch_event_get_header(var_event, SOFIA_SECURE_MEDIA_VARIABLE)) ||
(hval = switch_event_get_header(var_event, "rtp_secure_media"))) {
switch_channel_set_variable(nchannel, "rtp_secure_media", hval);
}
if (!zstr(tech_pvt->dest) && switch_stristr("transport=ws", tech_pvt->dest)) {
switch_channel_set_variable(nchannel, "rtp_secure_media", SWITCH_RTP_CRYPTO_KEY_80);
switch_channel_set_variable(nchannel, "media_webrtc", "true");
switch_core_session_set_ice(nsession);
}

View File

@ -111,9 +111,6 @@ typedef struct private_object private_object_t;
#define SOFIA_DEFAULT_PORT "5060"
#define SOFIA_DEFAULT_TLS_PORT "5061"
#define SOFIA_REFER_TO_VARIABLE "sip_refer_to"
#define SOFIA_SECURE_MEDIA_VARIABLE "rtp_secure_media"
#define SOFIA_SECURE_MEDIA_CONFIRMED_VARIABLE "rtp_secure_media_confirmed"
#define SOFIA_SECURE_VIDEO_CONFIRMED_VARIABLE "sip_secure_video_confirmed"
//#define SOFIA_HAS_CRYPTO_VARIABLE "rtp_has_crypto"
//#define SOFIA_HAS_VIDEO_CRYPTO_VARIABLE "sip_has_video_crypto"
//#define SOFIA_CRYPTO_MANDATORY_VARIABLE "sip_crypto_mandatory"

View File

@ -74,6 +74,11 @@ struct media_helper {
int up;
};
typedef enum {
CRYPTO_MODE_OPTIONAL,
CRYPTO_MODE_MANDATORY,
CRYPTO_MODE_FORBIDDEN
} switch_rtp_crypto_mode_t;
typedef struct switch_rtp_engine_s {
switch_secure_settings_t ssec[CRYPTO_INVALID+1];
@ -181,6 +186,10 @@ struct switch_media_handle_s {
char *msid;
char *cname;
switch_rtp_crypto_mode_t crypto_mode;
switch_rtp_crypto_key_type_t crypto_suite_order[CRYPTO_INVALID+1];
uint8_t crypto_suite_enabled[CRYPTO_INVALID+1];
};
@ -226,6 +235,7 @@ SWITCH_DECLARE(int) switch_core_media_crypto_keylen(switch_rtp_crypto_key_type_t
static int get_channels(const char *name, int dft)
{
if (!switch_true(switch_core_get_variable("NDLB_broken_opus_sdp")) && !strcasecmp(name, "opus")) {
return 2; /* IKR???*/
}
@ -713,6 +723,8 @@ SWITCH_DECLARE(void) switch_core_session_clear_crypto(switch_core_session_t *ses
"srtp_remote_video_crypto_tag",
"srtp_remote_video_crypto_type",
"rtp_secure_media",
"rtp_secure_media_inbound",
"rtp_secure_media_outbound",
NULL};
for(i = 0; vars[i] ;i++) {
@ -1028,6 +1040,7 @@ static void switch_core_session_apply_crypto(switch_core_session_t *session, swi
}
if (!session->media_handle) return;
engine = &session->media_handle->engines[type];
if (switch_channel_test_flag(session->channel, CF_RECOVERING)) {
@ -1050,10 +1063,86 @@ static void switch_core_session_apply_crypto(switch_core_session_t *session, swi
SUITES[engine->ssec[engine->crypto_type].crypto_type].keylen);
switch_channel_set_variable(session->channel, varname, "true");
switch_channel_set_variable(session->channel, "rtp_secure_media_negotiated", SUITES[engine->crypto_type].name);
}
}
static void switch_core_session_parse_crypto_prefs(switch_core_session_t *session)
{
const char *var = NULL;
const char *val = NULL;
char *suites = NULL;
switch_media_handle_t *smh;
char *fields[CRYPTO_INVALID+1];
int argc = 0, i = 0, j = 0, k = 0;
if (!(smh = session->media_handle)) {
return;
}
if (switch_channel_test_flag(session->channel, CF_WEBRTC)) {
return;
}
if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
var = "rtp_secure_media_inbound";
} else {
var = "rtp_secure_media_outbound";
}
if (!(val = switch_channel_get_variable(session->channel, var))) {
var = "rtp_secure_media";
val = switch_channel_get_variable(session->channel, var);
}
if (!zstr(val) && (suites = strchr(val, ':'))) {
*suites++ = '\0';
}
if (zstr(val) || !strcasecmp(val, "optional")) {
smh->crypto_mode = CRYPTO_MODE_OPTIONAL;
} else if (switch_true(val) || !strcasecmp(val, "mandatory")) {
smh->crypto_mode = CRYPTO_MODE_MANDATORY;
} else {
smh->crypto_mode = CRYPTO_MODE_FORBIDDEN;
if (!switch_false(val) && strcasecmp(val, "forbidden")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "INVALID VALUE FOR %s defaulting to 'forbidden'\n", var);
}
}
if (smh->crypto_mode != CRYPTO_MODE_FORBIDDEN && !zstr(suites)) {
argc = switch_split((char *)suites, ':', fields);
for (i = 0; i < argc; i++) {
int ok = 0;
for (j = 0; j < CRYPTO_INVALID; j++) {
if (!strcasecmp(fields[i], SUITES[j].name)) {
smh->crypto_suite_order[k++] = SUITES[j].type;
smh->crypto_suite_enabled[SUITES[i].type] = 1;
ok++;
break;
}
}
if (!ok) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "INVALID SUITE SUPPLIED\n");
}
}
} else {
for (i = 0; i < CRYPTO_INVALID; i++) {
smh->crypto_suite_order[k++] = SUITES[i].type;
smh->crypto_suite_enabled[SUITES[i].type] = 1;
}
}
}
SWITCH_DECLARE(int) switch_core_session_check_incoming_crypto(switch_core_session_t *session,
const char *varname,
@ -1064,29 +1153,28 @@ SWITCH_DECLARE(int) switch_core_session_check_incoming_crypto(switch_core_sessio
int ctype = 0;
const char *vval = NULL;
switch_rtp_engine_t *engine;
const char *suite = switch_channel_get_variable(session->channel, "rtp_secure_media");
switch_media_handle_t *smh;
if (!session->media_handle) return 0;
if (!(smh = session->media_handle)) {
return 0;
}
if (smh->crypto_mode == CRYPTO_MODE_FORBIDDEN) {
return -1;
}
engine = &session->media_handle->engines[type];
if (suite && !strcasecmp(suite, "optional")) {
suite = "true";
}
for (i = 0; smh->crypto_suite_order[i] != CRYPTO_INVALID; i++) {
switch_rtp_crypto_key_type_t j = SUITES[smh->crypto_suite_order[i]].type;
if (zstr(suite) || (!switch_true(suite) && switch_core_media_crypto_str2type(suite) == CRYPTO_INVALID)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Crypto suite: [%s] not valid in this context.\n", crypto);
goto end;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,"looking for crypto suite [%s] in [%s]\n", SUITES[j].name, crypto);
if (switch_true(suite)) {
suite = NULL;
}
for (i = 0; i < CRYPTO_INVALID; i++) {
if ((zstr(suite) || switch_stristr(SUITES[i].name, suite)) && switch_stristr(SUITES[i].name, crypto)) {
ctype = SUITES[i].type;
vval = SUITES[i].name;
if (switch_stristr(SUITES[j].name, crypto)) {
ctype = SUITES[j].type;
vval = SUITES[j].name;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Found suite %s\n", vval);
switch_channel_set_variable(session->channel, "rtp_secure_media_negotiated", vval);
break;
}
}
@ -1163,48 +1251,47 @@ SWITCH_DECLARE(int) switch_core_session_check_incoming_crypto(switch_core_sessio
engine->ssec[engine->crypto_type].crypto_tag = crypto_tag;
got_crypto++;
switch_channel_set_variable(session->channel, varname, vval);
if (zstr(engine->ssec[engine->crypto_type].local_crypto_key)) {
switch_channel_set_variable(session->channel, varname, vval);
switch_core_media_build_crypto(session->media_handle, type, crypto_tag, ctype, SWITCH_RTP_CRYPTO_SEND, 1);
}
}
end:
if (got_crypto && vval && switch_true(switch_channel_get_variable(session->channel, "rtp_secure_media"))) {
switch_channel_set_variable(session->channel, "rtp_secure_media", vval);
}
return got_crypto;
}
SWITCH_DECLARE(void) switch_core_session_check_outgoing_crypto(switch_core_session_t *session, const char *sec_var)
SWITCH_DECLARE(void) switch_core_session_check_outgoing_crypto(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_media_handle_t *smh;
int i;
if (!switch_core_session_media_handle_ready(session) == SWITCH_STATUS_SUCCESS) {
return;
}
if (!zstr(sec_var)) {
int i;
int all = switch_true(sec_var) || !strcasecmp(sec_var, "optional");
if (!(smh = session->media_handle)) {
return;
}
for (i = 0; i < CRYPTO_INVALID; i++) {
if (all || switch_stristr(SUITES[i].name, sec_var)) {
if (!(smh->crypto_mode == CRYPTO_MODE_OPTIONAL || smh->crypto_mode == CRYPTO_MODE_MANDATORY)) {
return;
}
switch_channel_set_flag(channel, CF_SECURE);
for (i = 0; smh->crypto_suite_order[i] != CRYPTO_INVALID; i++) {
switch_core_media_build_crypto(session->media_handle,
SWITCH_MEDIA_TYPE_AUDIO, 0, SUITES[i].type, SWITCH_RTP_CRYPTO_SEND, 0);
SWITCH_MEDIA_TYPE_AUDIO, 0, smh->crypto_suite_order[i], SWITCH_RTP_CRYPTO_SEND, 0);
switch_core_media_build_crypto(session->media_handle,
SWITCH_MEDIA_TYPE_VIDEO, 0, SUITES[i].type, SWITCH_RTP_CRYPTO_SEND, 0);
}
}
SWITCH_MEDIA_TYPE_VIDEO, 0, smh->crypto_suite_order[i], SWITCH_RTP_CRYPTO_SEND, 0);
}
}
#define add_stat(_i, _s) \
@ -1337,21 +1424,24 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t
session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].read_frame.buflen = SWITCH_RTP_MAX_BUF_LEN;
session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].type = SWITCH_MEDIA_TYPE_AUDIO;
session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].crypto_type = CRYPTO_INVALID;
for (i = 0; i < CRYPTO_INVALID; i++) {
session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec[i].crypto_type = i;
}
session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].read_frame.buflen = SWITCH_RTP_MAX_BUF_LEN;
session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].type = SWITCH_MEDIA_TYPE_VIDEO;
session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].crypto_type = CRYPTO_INVALID;
for (i = 0; i < CRYPTO_INVALID; i++) {
session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].ssec[i].crypto_type = i;
}
session->media_handle->mparams = params;
for (i = 0; i <= CRYPTO_INVALID; i++) {
session->media_handle->crypto_suite_order[i] = CRYPTO_INVALID;
}
switch_mutex_init(&session->media_handle->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
switch_mutex_init(&session->media_handle->sdp_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
@ -2815,8 +2905,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
const char *tmp;
int m_idx = 0;
int nm_idx = 0;
int needs_crypto = 0;
const char *var;
switch_assert(session);
@ -2839,27 +2927,13 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
return 0;
}
if (!switch_channel_test_flag(session->channel, CF_DTLS) && (var = switch_channel_get_variable(session->channel, "rtp_secure_media"))) {
if (strcasecmp(var, "optional")) {
if (switch_true(var) || switch_core_media_crypto_str2type(var) != CRYPTO_INVALID) {
needs_crypto = 1;
switch_channel_set_variable(session->channel, "rtp_crypto_mandatory", "true");
}
if (sdp_type == SDP_TYPE_REQUEST) {
if (switch_false(var) || switch_core_media_crypto_str2type(var) == CRYPTO_INVALID) {
got_crypto = -1;
}
}
}
}
if (dtls_ok(session) && (tmp = switch_channel_get_variable(smh->session->channel, "webrtc_enable_dtls")) && switch_false(tmp)) {
switch_channel_clear_flag(smh->session->channel, CF_DTLS_OK);
switch_channel_clear_flag(smh->session->channel, CF_DTLS);
}
switch_core_session_parse_crypto_prefs(session);
clear_pmaps(a_engine);
clear_pmaps(v_engine);
@ -2872,15 +2946,12 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
if (!strcasecmp(val, "generous")) {
greedy = 0;
scrooge = 0;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "rtp_codec_negotiation overriding sofia inbound-codec-negotiation : generous\n" );
} else if (!strcasecmp(val, "greedy")) {
greedy = 1;
scrooge = 0;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "rtp_codec_negotiation overriding sofia inbound-codec-negotiation : greedy\n" );
} else if (!strcasecmp(val, "scrooge")) {
scrooge = 1;
greedy = 1;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "rtp_codec_negotiation overriding sofia inbound-codec-negotiation : scrooge\n" );
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "rtp_codec_negotiation ignored invalid value : '%s' \n", val );
}
@ -3093,7 +3164,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
SWITCH_LOG_WARNING, "%s Error Passing T.38 to unanswered channel %s\n",
switch_channel_get_name(session->channel), switch_channel_get_name(other_channel));
switch_core_session_rwunlock(other_session);
//sofia_set_flag(session, TFLAG_NOREPLY);
pass = 0;
match = 0;
goto done;
@ -3175,8 +3246,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
ptime = atoi(attr->a_value);
} else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) {
maxptime = atoi(attr->a_value);
} else if (got_crypto < 1 && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)) { //&&
//(!switch_channel_test_flag(session->channel, CF_WEBRTC) || switch_stristr(SWITCH_RTP_CRYPTO_KEY_80, attr->a_value))) {
} else if (got_crypto < 1 && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)) {
int crypto_tag;
if (!(smh->mparams->ndlb & SM_NDLB_ALLOW_CRYPTO_IN_AVP) &&
@ -3374,7 +3444,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
}
}
if (needs_crypto && got_crypto < 1) {
if (smh->crypto_mode == CRYPTO_MODE_MANDATORY && got_crypto < 1) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Crypto not negotiated but required.\n");
match = 0;
m_idx = nm_idx = 0;
@ -3685,7 +3755,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
}
}
if (needs_crypto && got_video_crypto < 1) {
if (smh->crypto_mode == CRYPTO_MODE_MANDATORY && got_video_crypto < 1) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Crypto not negotiated but required.\n");
vmatch = 0;
m_idx = 0;
@ -4670,8 +4740,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
switch_rtp_reset_media_timer(a_engine->rtp_session);
}
if (!switch_channel_test_flag(session->channel, CF_SECURE) && (var = switch_channel_get_variable(session->channel, "rtp_secure_media")) &&
(switch_true(var) || switch_core_media_crypto_str2type(var) != CRYPTO_INVALID)) {
if (a_engine->crypto_type) {
switch_channel_set_flag(session->channel, CF_SECURE);
}
@ -5528,7 +5597,6 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen,
int rate;
int already_did[128] = { 0 };
int ptime = 0, noptime = 0;
//const char *local_audio_crypto_key = switch_core_session_local_crypto_key(session, SWITCH_MEDIA_TYPE_AUDIO);
const char *local_sdp_audio_zrtp_hash;
switch_media_handle_t *smh;
switch_rtp_engine_t *a_engine;
@ -5768,9 +5836,11 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen,
if (secure && !switch_channel_test_flag(session->channel, CF_DTLS)) {
int i;
for (i = 0; i < CRYPTO_INVALID; i++) {
if ((a_engine->crypto_type == i || a_engine->crypto_type == CRYPTO_INVALID) && !zstr(a_engine->ssec[i].local_crypto_key)) {
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=crypto:%s\n", a_engine->ssec[i].local_crypto_key);
for (i = 0; smh->crypto_suite_order[i] != CRYPTO_INVALID; i++) {
switch_rtp_crypto_key_type_t j = SUITES[smh->crypto_suite_order[i]].type;
if ((a_engine->crypto_type == j || a_engine->crypto_type == CRYPTO_INVALID) && !zstr(a_engine->ssec[j].local_crypto_key)) {
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=crypto:%s\n", a_engine->ssec[j].local_crypto_key);
}
}
//switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\n");
@ -5941,7 +6011,6 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
int red = 0;
payload_map_t *pmap;
int is_outbound = switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND;
const char *secure_media_var = switch_channel_get_variable(session->channel, "rtp_secure_media");
switch_assert(session);
@ -5987,8 +6056,8 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
generate_local_fingerprint(smh, SWITCH_MEDIA_TYPE_AUDIO);
}
}
switch_core_session_check_outgoing_crypto(session, secure_media_var);
switch_core_session_parse_crypto_prefs(session);
switch_core_session_check_outgoing_crypto(session);
} else {
if (switch_channel_test_flag(smh->session->channel, CF_DTLS)) {
@ -6402,8 +6471,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
generate_m(session, buf, SDPBUFLEN, port, family, ip, 0, append_audio, sr, use_cng, cng_type, map, 1, sdp_type);
bp = (buf + strlen(buf));
/* asterisk can't handle AVP and SAVP in sep streams, way to blow off the spec....*/
if (switch_true(switch_channel_get_variable(session->channel, "sdp_secure_savp_only"))) {
if (smh->crypto_mode == CRYPTO_MODE_MANDATORY) {
both = 0;
}
@ -6439,8 +6507,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
generate_m(session, bp, SDPBUFLEN - strlen(buf), port, family, ip, cur_ptime, append_audio, sr, use_cng, cng_type, map, 1, sdp_type);
bp = (buf + strlen(buf));
/* asterisk can't handle AVP and SAVP in sep streams, way to blow off the spec....*/
if (switch_true(switch_channel_get_variable(session->channel, "sdp_secure_savp_only"))) {
if (smh->crypto_mode == CRYPTO_MODE_MANDATORY) {
both = 0;
}
}
@ -6476,21 +6543,22 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
}
if ((v_port = v_engine->adv_sdp_port)) {
int loops;
for (loops = 0; loops < 2; loops++) {
if (switch_channel_test_flag(smh->session->channel, CF_ICE)) {
gen_ice(session, SWITCH_MEDIA_TYPE_VIDEO, ip, (switch_port_t)v_port);
}
/*
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=video %d RTP/%sAVP%s",
v_port, ((!zstr(local_video_crypto_key) || switch_channel_test_flag(session->channel, CF_DTLS))
&& switch_channel_test_flag(session->channel, CF_SECURE)) ? "S" : "",
switch_channel_test_flag(session->channel, CF_WEBRTC) ? "F" : "");
*/
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=video %d %s",
v_port, get_media_profile_name(session,
(!v_engine->no_crypto || switch_channel_test_flag(session->channel, CF_DTLS))
&& v_engine->crypto_type != CRYPTO_INVALID));
v_port,
get_media_profile_name(session,
(loops == 0 && switch_channel_test_flag(session->channel, CF_SECURE)
&& switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) ||
a_engine->crypto_type != CRYPTO_INVALID));
@ -6800,11 +6868,16 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
if (loops == 0 && switch_channel_test_flag(session->channel, CF_SECURE) && !switch_channel_test_flag(session->channel, CF_DTLS)) {
int i;
if (switch_channel_test_flag(session->channel, CF_SECURE) && !switch_channel_test_flag(session->channel, CF_DTLS) &&
v_engine->crypto_type != CRYPTO_INVALID &&
!zstr(v_engine->ssec[v_engine->crypto_type].local_crypto_key)) {
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=crypto:%s\n", v_engine->ssec[v_engine->crypto_type].local_crypto_key);
for (i = 0; smh->crypto_suite_order[i] != CRYPTO_INVALID; i++) {
switch_rtp_crypto_key_type_t j = SUITES[smh->crypto_suite_order[i]].type;
if ((a_engine->crypto_type == j || a_engine->crypto_type == CRYPTO_INVALID) && !zstr(a_engine->ssec[j].local_crypto_key)) {
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=crypto:%s\n", v_engine->ssec[j].local_crypto_key);
}
}
//switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\n");
}
@ -6813,8 +6886,17 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Adding video a=zrtp-hash:%s\n", local_sdp_video_zrtp_hash);
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=zrtp-hash:%s\n", local_sdp_video_zrtp_hash);
}
if (switch_channel_test_flag(session->channel, CF_DTLS) ||
!switch_channel_test_flag(session->channel, CF_SECURE) ||
smh->crypto_mode == CRYPTO_MODE_MANDATORY || smh->crypto_mode == CRYPTO_MODE_FORBIDDEN) {
break;
}
}
}
}
if (map) {

View File

@ -3092,6 +3092,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
switch_channel_set_variable(channel, "rtp_has_crypto", "AES_CM_256_HMAC_SHA1_80");
}
break;
case AES_CM_128_NULL_AUTH:
crypto_policy_set_aes_cm_128_null_auth(&policy->rtp);
crypto_policy_set_aes_cm_128_null_auth(&policy->rtcp);
@ -3355,9 +3356,9 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session
int initiator = 0;
const char *zrtp_enabled = switch_channel_get_variable(channel, "zrtp_secure_media");
const char *srtp_enabled = switch_channel_get_variable(channel, "rtp_secure_media");
int srtp_enabled = switch_channel_test_flag(channel, CF_SECURE);
if (switch_true(srtp_enabled) && switch_true(zrtp_enabled)) {
if (srtp_enabled && switch_true(zrtp_enabled)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING,
"You can not have ZRTP and SRTP enabled simultaneously, ZRTP will be disabled for this call!\n");
switch_channel_set_variable(channel, "zrtp_secure_media", NULL);