This commit is contained in:
Anthony Minessale 2014-02-26 04:02:47 +05:00
parent 514bbd3818
commit 5646957c5b
9 changed files with 214 additions and 197 deletions

View File

@ -39,17 +39,6 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_MAX_CAND_ACL 25 #define SWITCH_MAX_CAND_ACL 25
typedef enum {
SDP_TYPE_REQUEST,
SDP_TYPE_RESPONSE
} switch_sdp_type_t;
typedef enum {
ICE_GOOGLE_JINGLE = (1 << 0),
ICE_VANILLA = (1 << 1),
ICE_CONTROLLED = (1 << 2)
} switch_core_media_ice_type_t;
typedef enum { typedef enum {
DTMF_2833, DTMF_2833,
DTMF_INFO, DTMF_INFO,
@ -157,41 +146,6 @@ typedef struct switch_core_media_params_s {
} switch_core_media_params_t; } switch_core_media_params_t;
typedef struct payload_map_s {
switch_media_type_t type;
switch_sdp_type_t sdp_type;
uint32_t ptime;
uint32_t rate;
uint8_t allocated;
uint8_t negotiated;
uint8_t current;
unsigned long hash;
char *rm_encoding;
char *iananame;
switch_payload_t pt;
unsigned long rm_rate;
unsigned long adv_rm_rate;
uint32_t codec_ms;
uint32_t bitrate;
char *rm_fmtp;
switch_payload_t agreed_pt;
switch_payload_t recv_pt;
char *fmtp_out;
char *remote_sdp_ip;
switch_port_t remote_sdp_port;
int channels;
int adv_channels;
struct payload_map_s *next;
} payload_map_t;
static inline const char *switch_media_type2str(switch_media_type_t type) static inline const char *switch_media_type2str(switch_media_type_t type)
{ {
switch(type) { switch(type) {
@ -311,6 +265,12 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se
uint32_t ptime, uint32_t ptime,
uint8_t negotiated); uint8_t negotiated);
SWITCH_DECLARE(switch_rtp_crypto_key_type_t) switch_core_media_crypto_str2type(const char *str);
SWITCH_DECLARE(const char *) switch_core_media_crypto_type2str(switch_rtp_crypto_key_type_t type);
SWITCH_DECLARE(int) switch_core_media_crypto_keylen(switch_rtp_crypto_key_type_t type);
SWITCH_END_EXTERN_C SWITCH_END_EXTERN_C
#endif #endif
/* For Emacs: /* For Emacs:

View File

@ -37,7 +37,6 @@
#define SWITCH_FRAME_H #define SWITCH_FRAME_H
#include <switch.h> #include <switch.h>
#include <switch_core_media.h>
SWITCH_BEGIN_EXTERN_C SWITCH_BEGIN_EXTERN_C
/*! \brief An abstraction of a data frame */ /*! \brief An abstraction of a data frame */

View File

@ -41,18 +41,16 @@
SWITCH_BEGIN_EXTERN_C SWITCH_BEGIN_EXTERN_C
#include <switch_core_media.h>
#define SWITCH_RTP_MAX_BUF_LEN 16384 #define SWITCH_RTP_MAX_BUF_LEN 16384
#define SWITCH_RTCP_MAX_BUF_LEN 16384 #define SWITCH_RTCP_MAX_BUF_LEN 16384
#define SWITCH_RTP_MAX_BUF_LEN_WORDS 4094 /* (max / 4) - 2 */ #define SWITCH_RTP_MAX_BUF_LEN_WORDS 4094 /* (max / 4) - 2 */
#define SWITCH_RTP_MAX_CRYPTO_LEN 64 #define SWITCH_RTP_MAX_CRYPTO_LEN 64
#define SWITCH_RTP_KEY_LEN 30 //#define SWITCH_RTP_KEY_LEN 30
#define SWITCH_RTP_CRYPTO_KEY_32 "AES_CM_128_HMAC_SHA1_32" //#define SWITCH_RTP_CRYPTO_KEY_32 "AES_CM_128_HMAC_SHA1_32"
#define SWITCH_RTP_CRYPTO_KEY_80 "AES_CM_128_HMAC_SHA1_80" #define SWITCH_RTP_CRYPTO_KEY_80 "AES_CM_128_HMAC_SHA1_80"
#define SWITCH_RTP_CRYPTO_KEY_128_8 "AEAD_AES_128_GCM_8"
#define SWITCH_RTP_CRYPTO_KEY_256_8 "AEAD_AES_256_GCM_8"
typedef enum { typedef enum {
SWITCH_RTP_CRYPTO_SEND, SWITCH_RTP_CRYPTO_SEND,
SWITCH_RTP_CRYPTO_RECV, SWITCH_RTP_CRYPTO_RECV,
SWITCH_RTP_CRYPTO_SEND_RTCP, SWITCH_RTP_CRYPTO_SEND_RTCP,
@ -60,16 +58,12 @@ SWITCH_BEGIN_EXTERN_C
SWITCH_RTP_CRYPTO_MAX SWITCH_RTP_CRYPTO_MAX
} switch_rtp_crypto_direction_t; } switch_rtp_crypto_direction_t;
typedef enum { typedef struct switch_srtp_crypto_suite_s {
NO_CRYPTO, char *name;
AES_CM_128_HMAC_SHA1_80, switch_rtp_crypto_key_type_t type;
AES_CM_128_HMAC_SHA1_32, int keylen;
AES_CM_256_HMAC_SHA1_80, } switch_srtp_crypto_suite_t;
AES_CM_192_HMAC_SHA1_80,
AEAD_AES_256_GCM_8,
AEAD_AES_128_GCM_8,
AES_CM_128_NULL_AUTH
} switch_rtp_crypto_key_type_t;
struct switch_rtp_crypto_key { struct switch_rtp_crypto_key {
uint32_t index; uint32_t index;

View File

@ -2312,6 +2312,67 @@ typedef void (*switch_event_channel_func_t)(const char *event_channel, cJSON *js
struct switch_live_array_s; struct switch_live_array_s;
typedef struct switch_live_array_s switch_live_array_t; typedef struct switch_live_array_s switch_live_array_t;
typedef enum {
SDP_TYPE_REQUEST,
SDP_TYPE_RESPONSE
} switch_sdp_type_t;
typedef enum {
AEAD_AES_256_GCM_8,
AEAD_AES_128_GCM_8,
AES_CM_256_HMAC_SHA1_80,
AES_CM_192_HMAC_SHA1_80,
AES_CM_128_HMAC_SHA1_80,
AES_CM_256_HMAC_SHA1_32,
AES_CM_192_HMAC_SHA1_32,
AES_CM_128_HMAC_SHA1_32,
AES_CM_128_NULL_AUTH,
NO_CRYPTO,
CRYPTO_INVALID
} switch_rtp_crypto_key_type_t;
typedef struct payload_map_s {
switch_media_type_t type;
switch_sdp_type_t sdp_type;
uint32_t ptime;
uint32_t rate;
uint8_t allocated;
uint8_t negotiated;
uint8_t current;
unsigned long hash;
char *rm_encoding;
char *iananame;
switch_payload_t pt;
unsigned long rm_rate;
unsigned long adv_rm_rate;
uint32_t codec_ms;
uint32_t bitrate;
char *rm_fmtp;
switch_payload_t agreed_pt;
switch_payload_t recv_pt;
char *fmtp_out;
char *remote_sdp_ip;
switch_port_t remote_sdp_port;
int channels;
int adv_channels;
struct payload_map_s *next;
} payload_map_t;
typedef enum {
ICE_GOOGLE_JINGLE = (1 << 0),
ICE_VANILLA = (1 << 1),
ICE_CONTROLLED = (1 << 2)
} switch_core_media_ice_type_t;
SWITCH_END_EXTERN_C SWITCH_END_EXTERN_C

View File

@ -33,6 +33,10 @@
#include <switch_stun.h> #include <switch_stun.h>
#include <libdingaling.h> #include <libdingaling.h>
#define SWITCH_RTP_KEY_LEN 30
#define SWITCH_RTP_CRYPTO_KEY_32 "AES_CM_128_HMAC_SHA1_32"
#define SWITCH_RTP_CRYPTO_KEY_80 "AES_CM_128_HMAC_SHA1_80"
#define MDL_RTCP_DUR 5000 #define MDL_RTCP_DUR 5000
#define DL_CAND_WAIT 10000000 #define DL_CAND_WAIT 10000000
#define DL_CAND_INITIAL_WAIT 2000000 #define DL_CAND_INITIAL_WAIT 2000000

View File

@ -1220,7 +1220,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
if (((var = switch_channel_get_variable(channel, SOFIA_SECURE_MEDIA_VARIABLE)) || if (((var = switch_channel_get_variable(channel, SOFIA_SECURE_MEDIA_VARIABLE)) ||
(var = switch_channel_get_variable(channel, "rtp_secure_media"))) && (var = switch_channel_get_variable(channel, "rtp_secure_media"))) &&
(switch_true(var) || !strcasecmp(var, SWITCH_RTP_CRYPTO_KEY_32) || !strcasecmp(var, SWITCH_RTP_CRYPTO_KEY_80))) { (switch_true(var) || switch_core_media_crypto_str2type(var) != CRYPTO_INVALID)) {
switch_channel_set_flag(tech_pvt->channel, CF_SECURE); switch_channel_set_flag(tech_pvt->channel, CF_SECURE);
} }

View File

@ -3331,21 +3331,6 @@ SWITCH_DECLARE(void) switch_channel_check_zrtp(switch_channel_t *channel)
} }
} }
static void check_secure(switch_channel_t *channel)
{
const char *var, *sec;
if (!switch_channel_media_ready(channel) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
if ((sec = switch_channel_get_variable(channel, "rtp_secure_media")) && switch_true(sec)) {
if (!(var = switch_channel_get_variable(channel, "rtp_has_crypto"))) {
switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_WARNING, "rtp_secure_media invalid in this context.\n");
switch_channel_set_variable(channel, "rtp_secure_media", NULL);
}
}
}
}
SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_channel_t *channel, const char *file, const char *func, int line) SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_channel_t *channel, const char *file, const char *func, int line)
{ {
switch_event_t *event; switch_event_t *event;
@ -3433,8 +3418,6 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_pre_answer(switch_channel
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
check_secure(channel);
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
msg.message_id = SWITCH_MESSAGE_INDICATE_PROGRESS; msg.message_id = SWITCH_MESSAGE_INDICATE_PROGRESS;
msg.from = channel->name; msg.from = channel->name;
@ -3720,8 +3703,6 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
check_secure(channel);
msg.message_id = SWITCH_MESSAGE_INDICATE_ANSWER; msg.message_id = SWITCH_MESSAGE_INDICATE_ANSWER;
msg.from = channel->name; msg.from = channel->name;
status = switch_core_session_perform_receive_message(channel->session, &msg, file, func, line); status = switch_core_session_perform_receive_message(channel->session, &msg, file, func, line);

View File

@ -183,6 +183,48 @@ struct switch_media_handle_s {
}; };
static switch_srtp_crypto_suite_t SUITES[CRYPTO_INVALID] = {
{ "AEAD_AES_256_GCM_8", AEAD_AES_256_GCM_8, 46},
{ "AEAD_AES_128_GCM_8", AEAD_AES_128_GCM_8, 30},
{ "AES_CM_256_HMAC_SHA1_80", AES_CM_256_HMAC_SHA1_80, 46},
{ "AES_CM_192_HMAC_SHA1_80", AES_CM_192_HMAC_SHA1_80, 38},
{ "AES_CM_128_HMAC_SHA1_80", AES_CM_128_HMAC_SHA1_80, 30},
{ "AES_CM_256_HMAC_SHA1_32", AES_CM_256_HMAC_SHA1_32, 46},
{ "AES_CM_192_HMAC_SHA1_32", AES_CM_192_HMAC_SHA1_32, 38},
{ "AES_CM_128_HMAC_SHA1_32", AES_CM_128_HMAC_SHA1_32, 30},
{ "AES_CM_128_NULL_AUTH", AES_CM_128_NULL_AUTH, 30},
{ "NULL", NO_CRYPTO, 0 }
};
SWITCH_DECLARE(switch_rtp_crypto_key_type_t) switch_core_media_crypto_str2type(const char *str)
{
int i;
for (i = 0; i < CRYPTO_INVALID; i++) {
if (!strncasecmp(str, SUITES[i].name, strlen(SUITES[i].name))) {
return SUITES[i].type;
}
}
return CRYPTO_INVALID;
}
SWITCH_DECLARE(const char *) switch_core_media_crypto_type2str(switch_rtp_crypto_key_type_t type)
{
switch_assert(type < CRYPTO_INVALID);
return SUITES[type].name;
}
SWITCH_DECLARE(int) switch_core_media_crypto_keylen(switch_rtp_crypto_key_type_t type)
{
switch_assert(type < CRYPTO_INVALID);
return SUITES[type].keylen;
}
static int get_channels(const char *name, int dft) static int get_channels(const char *name, int dft)
{ {
if (!strcasecmp(name, "opus")) { if (!strcasecmp(name, "opus")) {
@ -806,7 +848,6 @@ static switch_status_t switch_core_media_build_crypto(switch_media_handle_t *smh
int index, switch_rtp_crypto_key_type_t ctype, switch_rtp_crypto_direction_t direction, int force) int index, switch_rtp_crypto_key_type_t ctype, switch_rtp_crypto_direction_t direction, int force)
{ {
unsigned char b64_key[512] = ""; unsigned char b64_key[512] = "";
const char *type_str;
unsigned char *key; unsigned char *key;
const char *val; const char *val;
switch_channel_t *channel; switch_channel_t *channel;
@ -822,28 +863,16 @@ static switch_status_t switch_core_media_build_crypto(switch_media_handle_t *smh
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
if (ctype == AES_CM_128_HMAC_SHA1_80) {
type_str = SWITCH_RTP_CRYPTO_KEY_80;
} else if (ctype == AEAD_AES_256_GCM_8) {
type_str = SWITCH_RTP_CRYPTO_KEY_256_8;
} else if (ctype == AEAD_AES_128_GCM_8) {
type_str = SWITCH_RTP_CRYPTO_KEY_128_8;
} else if (ctype == AES_CM_256_HMAC_SHA1_80) {
type_str = SWITCH_RTP_CRYPTO_KEY_80;
} else if (ctype == AES_CM_192_HMAC_SHA1_80) {
type_str = SWITCH_RTP_CRYPTO_KEY_80;
} else {
type_str = SWITCH_RTP_CRYPTO_KEY_32;
}
//#define SAME_KEY //#define SAME_KEY
#ifdef SAME_KEY #ifdef SAME_KEY
if (switch_channel_test_flag(channel, CF_WEBRTC) && type == SWITCH_MEDIA_TYPE_VIDEO) { if (switch_channel_test_flag(channel, CF_WEBRTC) && type == SWITCH_MEDIA_TYPE_VIDEO) {
if (direction == SWITCH_RTP_CRYPTO_SEND) { if (direction == SWITCH_RTP_CRYPTO_SEND) {
memcpy(engine->ssec.local_raw_key, smh->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec.local_raw_key, SWITCH_RTP_KEY_LEN); memcpy(engine->ssec.local_raw_key, smh->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec.local_raw_key, SUITES[ctype].keylen);
key = engine->ssec.local_raw_key; key = engine->ssec.local_raw_key;
} else { } else {
memcpy(engine->ssec.remote_raw_key, smh->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec.remote_raw_key, SWITCH_RTP_KEY_LEN); memcpy(engine->ssec.remote_raw_key, smh->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec.remote_raw_key, SUITES[ctype].keylen);
key = engine->ssec.remote_raw_key; key = engine->ssec.remote_raw_key;
} }
} else { } else {
@ -854,19 +883,19 @@ static switch_status_t switch_core_media_build_crypto(switch_media_handle_t *smh
key = engine->ssec.remote_raw_key; key = engine->ssec.remote_raw_key;
} }
switch_rtp_get_random(key, SWITCH_RTP_KEY_LEN); switch_rtp_get_random(key, SUITES[ctype].keylen);
#ifdef SAME_KEY #ifdef SAME_KEY
} }
#endif #endif
switch_b64_encode(key, SWITCH_RTP_KEY_LEN, b64_key, sizeof(b64_key)); switch_b64_encode(key, SUITES[ctype].keylen, b64_key, sizeof(b64_key));
p = strrchr((char *) b64_key, '='); p = strrchr((char *) b64_key, '=');
while (p && *p && *p == '=') { while (p && *p && *p == '=') {
*p-- = '\0'; *p-- = '\0';
} }
engine->ssec.local_crypto_key = switch_core_session_sprintf(smh->session, "%d %s inline:%s", index, type_str, b64_key); engine->ssec.local_crypto_key = switch_core_session_sprintf(smh->session, "%d %s inline:%s", index, SUITES[ctype].name, b64_key);
switch_channel_set_variable_name_printf(smh->session->channel, engine->ssec.local_crypto_key, "rtp_last_%s_local_crypto_key", type2str(type)); switch_channel_set_variable_name_printf(smh->session->channel, engine->ssec.local_crypto_key, "rtp_last_%s_local_crypto_key", type2str(type));
@ -897,15 +926,10 @@ switch_status_t switch_core_media_add_crypto(switch_secure_settings_t *ssec, con
if (p && *p && *(p + 1)) { if (p && *p && *(p + 1)) {
p++; p++;
if (!strncasecmp(p, SWITCH_RTP_CRYPTO_KEY_32, strlen(SWITCH_RTP_CRYPTO_KEY_32))) {
type = AES_CM_128_HMAC_SHA1_32; type = switch_core_media_crypto_str2type(p);
} else if (!strncasecmp(p, SWITCH_RTP_CRYPTO_KEY_80, strlen(SWITCH_RTP_CRYPTO_KEY_80))) {
type = AES_CM_128_HMAC_SHA1_80; if (type == CRYPTO_INVALID) {
} else if (!strncasecmp(p, SWITCH_RTP_CRYPTO_KEY_256_8, strlen(SWITCH_RTP_CRYPTO_KEY_256_8))) {
type = AEAD_AES_128_GCM_8;
} else if (!strncasecmp(p, SWITCH_RTP_CRYPTO_KEY_128_8, strlen(SWITCH_RTP_CRYPTO_KEY_128_8))) {
type = AEAD_AES_256_GCM_8;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error near [%s]\n", p); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error near [%s]\n", p);
goto bad; goto bad;
} }
@ -923,10 +947,10 @@ switch_status_t switch_core_media_add_crypto(switch_secure_settings_t *ssec, con
if (direction == SWITCH_RTP_CRYPTO_SEND) { if (direction == SWITCH_RTP_CRYPTO_SEND) {
ssec->crypto_send_type = type; ssec->crypto_send_type = type;
memcpy(ssec->local_raw_key, key, SWITCH_RTP_KEY_LEN); memcpy(ssec->local_raw_key, key, SUITES[type].keylen);
} else { } else {
ssec->crypto_recv_type = type; ssec->crypto_recv_type = type;
memcpy(ssec->remote_raw_key, key, SWITCH_RTP_KEY_LEN); memcpy(ssec->remote_raw_key, key, SUITES[type].keylen);
} }
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
@ -1006,10 +1030,10 @@ static void switch_core_session_apply_crypto(switch_core_session_t *session, swi
switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_SEND, 1, switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_SEND, 1,
engine->ssec.crypto_type, engine->ssec.local_raw_key, SWITCH_RTP_KEY_LEN); engine->ssec.crypto_type, engine->ssec.local_raw_key, SUITES[engine->ssec.crypto_type].keylen);
switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_RECV, engine->ssec.crypto_tag, switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_RECV, engine->ssec.crypto_tag,
engine->ssec.crypto_type, engine->ssec.remote_raw_key, SWITCH_RTP_KEY_LEN); engine->ssec.crypto_type, engine->ssec.remote_raw_key, SUITES[engine->ssec.crypto_type].keylen);
switch_channel_set_variable(session->channel, varname, "true"); switch_channel_set_variable(session->channel, varname, "true");
} }
@ -1022,46 +1046,52 @@ SWITCH_DECLARE(int) switch_core_session_check_incoming_crypto(switch_core_sessio
switch_media_type_t type, const char *crypto, int crypto_tag, switch_sdp_type_t sdp_type) switch_media_type_t type, const char *crypto, int crypto_tag, switch_sdp_type_t sdp_type)
{ {
int got_crypto = 0; int got_crypto = 0;
int i = 0;
int ctype = 0;
const char *vval = NULL;
switch_rtp_engine_t *engine; switch_rtp_engine_t *engine;
const char *suite = switch_channel_get_variable(session->channel, "rtp_secure_media");
if (!session->media_handle) return 0; if (!session->media_handle) return 0;
engine = &session->media_handle->engines[type]; engine = &session->media_handle->engines[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;
}
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;
break;
}
}
if (engine->ssec.remote_crypto_key && switch_rtp_ready(engine->rtp_session)) { if (engine->ssec.remote_crypto_key && switch_rtp_ready(engine->rtp_session)) {
/* Compare all the key. The tag may remain the same even if key changed */ /* Compare all the key. The tag may remain the same even if key changed */
if (crypto && !strcmp(crypto, engine->ssec.remote_crypto_key)) { if (crypto && !strcmp(crypto, engine->ssec.remote_crypto_key)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Existing key is still valid.\n"); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Existing key is still valid.\n");
got_crypto = 1;
} else { } else {
const char *a = switch_stristr("AES", engine->ssec.remote_crypto_key); const char *a = switch_stristr("AE", engine->ssec.remote_crypto_key);
const char *b = switch_stristr("AES", crypto); const char *b = switch_stristr("AE", crypto);
/* Change our key every time we can */
if (sdp_type == SDP_TYPE_REQUEST) { if (sdp_type == SDP_TYPE_REQUEST) {
if (switch_stristr(SWITCH_RTP_CRYPTO_KEY_32, crypto)) { if (!vval) {
switch_channel_set_variable(session->channel, varname, SWITCH_RTP_CRYPTO_KEY_32); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unsupported Crypto [%s]\n", crypto);
goto end;
switch_core_media_build_crypto(session->media_handle, type, crypto_tag, AES_CM_128_HMAC_SHA1_32, SWITCH_RTP_CRYPTO_SEND, 1);
switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_SEND, atoi(crypto), engine->ssec.crypto_type,
engine->ssec.local_raw_key, SWITCH_RTP_KEY_LEN);
} else if (switch_stristr(SWITCH_RTP_CRYPTO_KEY_80, crypto)) {
switch_channel_set_variable(session->channel, varname, SWITCH_RTP_CRYPTO_KEY_80);
switch_core_media_build_crypto(session->media_handle, type, crypto_tag, AES_CM_128_HMAC_SHA1_80, SWITCH_RTP_CRYPTO_SEND, 1);
switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_SEND, atoi(crypto), engine->ssec.crypto_type,
engine->ssec.local_raw_key, SWITCH_RTP_KEY_LEN);
} else if (switch_stristr(SWITCH_RTP_CRYPTO_KEY_256_8, crypto)) {
switch_channel_set_variable(session->channel, varname, SWITCH_RTP_CRYPTO_KEY_256_8);
switch_core_media_build_crypto(session->media_handle, type, crypto_tag, AEAD_AES_256_GCM_8, SWITCH_RTP_CRYPTO_SEND, 1);
switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_SEND, atoi(crypto), engine->ssec.crypto_type,
engine->ssec.local_raw_key, SWITCH_RTP_KEY_LEN);
} else if (switch_stristr(SWITCH_RTP_CRYPTO_KEY_128_8, crypto)) {
switch_channel_set_variable(session->channel, varname, SWITCH_RTP_CRYPTO_KEY_128_8);
switch_core_media_build_crypto(session->media_handle, type, crypto_tag, AEAD_AES_128_GCM_8, SWITCH_RTP_CRYPTO_SEND, 1);
switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_SEND, atoi(crypto), engine->ssec.crypto_type,
engine->ssec.local_raw_key, SWITCH_RTP_KEY_LEN);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Crypto Setup Failed!.\n");
} }
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);
switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_SEND, atoi(crypto), engine->ssec.crypto_type,
engine->ssec.local_raw_key, SUITES[ctype].keylen);
} }
if (a && b && !strncasecmp(a, b, 23)) { if (a && b && !strncasecmp(a, b, 23)) {
@ -1074,7 +1104,7 @@ SWITCH_DECLARE(int) switch_core_session_check_incoming_crypto(switch_core_sessio
if (switch_rtp_ready(engine->rtp_session) && switch_channel_test_flag(session->channel, CF_SECURE)) { if (switch_rtp_ready(engine->rtp_session) && switch_channel_test_flag(session->channel, CF_SECURE)) {
switch_core_media_add_crypto(&engine->ssec, engine->ssec.remote_crypto_key, SWITCH_RTP_CRYPTO_RECV); switch_core_media_add_crypto(&engine->ssec, engine->ssec.remote_crypto_key, SWITCH_RTP_CRYPTO_RECV);
switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_RECV, engine->ssec.crypto_tag, switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_RECV, engine->ssec.crypto_tag,
engine->ssec.crypto_type, engine->ssec.remote_raw_key, SWITCH_RTP_KEY_LEN); engine->ssec.crypto_type, engine->ssec.remote_raw_key, SUITES[engine->ssec.crypto_type].keylen);
} }
got_crypto++; got_crypto++;
} else { } else {
@ -1082,30 +1112,29 @@ SWITCH_DECLARE(int) switch_core_session_check_incoming_crypto(switch_core_sessio
} }
} }
} else if (!switch_rtp_ready(engine->rtp_session)) { } else if (!switch_rtp_ready(engine->rtp_session)) {
if (!vval) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unsupported Crypto [%s]\n", crypto);
goto end;
}
engine->ssec.remote_crypto_key = switch_core_session_strdup(session, crypto); engine->ssec.remote_crypto_key = switch_core_session_strdup(session, crypto);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set Remote Key [%s]\n", engine->ssec.remote_crypto_key); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set Remote Key [%s]\n", engine->ssec.remote_crypto_key);
switch_channel_set_variable(session->channel, "srtp_remote_audio_crypto_key", crypto); switch_channel_set_variable(session->channel, "srtp_remote_audio_crypto_key", crypto);
engine->ssec.crypto_tag = crypto_tag; engine->ssec.crypto_tag = crypto_tag;
got_crypto++; got_crypto++;
if (zstr(engine->ssec.local_crypto_key)) { if (zstr(engine->ssec.local_crypto_key)) {
if (switch_stristr(SWITCH_RTP_CRYPTO_KEY_32, crypto)) { switch_channel_set_variable(session->channel, varname, vval);
switch_channel_set_variable(session->channel, varname, SWITCH_RTP_CRYPTO_KEY_32); switch_core_media_build_crypto(session->media_handle, type, crypto_tag, ctype, SWITCH_RTP_CRYPTO_SEND, 1);
switch_core_media_build_crypto(session->media_handle, type, crypto_tag, AES_CM_128_HMAC_SHA1_32, SWITCH_RTP_CRYPTO_SEND, 1);
} else if (switch_stristr(SWITCH_RTP_CRYPTO_KEY_80, crypto)) {
switch_channel_set_variable(session->channel, varname, SWITCH_RTP_CRYPTO_KEY_80);
switch_core_media_build_crypto(session->media_handle, type, crypto_tag, AES_CM_128_HMAC_SHA1_80, SWITCH_RTP_CRYPTO_SEND, 1);
} else if (switch_stristr(SWITCH_RTP_CRYPTO_KEY_256_8, crypto)) {
switch_channel_set_variable(session->channel, varname, SWITCH_RTP_CRYPTO_KEY_256_8);
switch_core_media_build_crypto(session->media_handle, type, crypto_tag, AEAD_AES_256_GCM_8, SWITCH_RTP_CRYPTO_SEND, 1);
} else if (switch_stristr(SWITCH_RTP_CRYPTO_KEY_128_8, crypto)) {
switch_channel_set_variable(session->channel, varname, SWITCH_RTP_CRYPTO_KEY_128_8);
switch_core_media_build_crypto(session->media_handle, type, crypto_tag, AEAD_AES_128_GCM_8, SWITCH_RTP_CRYPTO_SEND, 1);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Crypto Setup Failed!.\n");
}
} }
} }
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; return got_crypto;
} }
@ -1121,31 +1150,26 @@ SWITCH_DECLARE(void) switch_core_session_check_outgoing_crypto(switch_core_sessi
} }
if ((var = switch_channel_get_variable(channel, sec_var)) && !zstr(var)) { if ((var = switch_channel_get_variable(channel, sec_var)) && !zstr(var)) {
if (switch_true(var) || !strcasecmp(var, SWITCH_RTP_CRYPTO_KEY_32)) { int i;
switch_rtp_crypto_key_type_t ctype = CRYPTO_INVALID;
if (switch_true(var)) {
ctype = AES_CM_128_HMAC_SHA1_32;
} else {
for (i = 0; i < CRYPTO_INVALID; i++) {
if (!strcasecmp(var, SUITES[i].name)) {
ctype = SUITES[i].type;
break;
}
}
}
if (ctype != CRYPTO_INVALID) {
switch_channel_set_flag(channel, CF_SECURE); switch_channel_set_flag(channel, CF_SECURE);
switch_core_media_build_crypto(session->media_handle, switch_core_media_build_crypto(session->media_handle,
SWITCH_MEDIA_TYPE_AUDIO, 1, AES_CM_128_HMAC_SHA1_32, SWITCH_RTP_CRYPTO_SEND, 0); SWITCH_MEDIA_TYPE_AUDIO, 1, ctype, SWITCH_RTP_CRYPTO_SEND, 0);
switch_core_media_build_crypto(session->media_handle, switch_core_media_build_crypto(session->media_handle,
SWITCH_MEDIA_TYPE_VIDEO, 1, AES_CM_128_HMAC_SHA1_32, SWITCH_RTP_CRYPTO_SEND, 0); SWITCH_MEDIA_TYPE_VIDEO, 1, ctype, SWITCH_RTP_CRYPTO_SEND, 0);
} else if (!strcasecmp(var, SWITCH_RTP_CRYPTO_KEY_80)) {
switch_channel_set_flag(channel, CF_SECURE);
switch_core_media_build_crypto(session->media_handle,
SWITCH_MEDIA_TYPE_AUDIO, 1, AES_CM_128_HMAC_SHA1_80, SWITCH_RTP_CRYPTO_SEND, 0);
switch_core_media_build_crypto(session->media_handle,
SWITCH_MEDIA_TYPE_VIDEO, 1, AES_CM_128_HMAC_SHA1_80, SWITCH_RTP_CRYPTO_SEND, 0);
} else if (!strcasecmp(var, SWITCH_RTP_CRYPTO_KEY_256_8)) {
switch_channel_set_flag(channel, CF_SECURE);
switch_core_media_build_crypto(session->media_handle,
SWITCH_MEDIA_TYPE_AUDIO, 1, AEAD_AES_256_GCM_8, SWITCH_RTP_CRYPTO_SEND, 0);
switch_core_media_build_crypto(session->media_handle,
SWITCH_MEDIA_TYPE_VIDEO, 1, AEAD_AES_256_GCM_8, SWITCH_RTP_CRYPTO_SEND, 0);
} else if (!strcasecmp(var, SWITCH_RTP_CRYPTO_KEY_128_8)) {
switch_channel_set_flag(channel, CF_SECURE);
switch_core_media_build_crypto(session->media_handle,
SWITCH_MEDIA_TYPE_AUDIO, 1, AEAD_AES_128_GCM_8, SWITCH_RTP_CRYPTO_SEND, 0);
switch_core_media_build_crypto(session->media_handle,
SWITCH_MEDIA_TYPE_VIDEO, 1, AEAD_AES_128_GCM_8, SWITCH_RTP_CRYPTO_SEND, 0);
} }
} }
@ -2770,11 +2794,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
} }
if (sdp_type == SDP_TYPE_REQUEST && (var = switch_channel_get_variable(session->channel, "rtp_secure_media"))) { if (sdp_type == SDP_TYPE_REQUEST && (var = switch_channel_get_variable(session->channel, "rtp_secure_media"))) {
if (!switch_true(var) if (!switch_true(var) && switch_core_media_crypto_str2type(var) == CRYPTO_INVALID) {
&& strcasecmp(var, SWITCH_RTP_CRYPTO_KEY_32)
&& strcasecmp(var, SWITCH_RTP_CRYPTO_KEY_80)
&& strcasecmp(var, SWITCH_RTP_CRYPTO_KEY_128_8)
&& strcasecmp(var, SWITCH_RTP_CRYPTO_KEY_256_8)) {
got_crypto = -1; got_crypto = -1;
} }
} }
@ -3098,8 +3118,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
ptime = atoi(attr->a_value); ptime = atoi(attr->a_value);
} else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) { } else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) {
maxptime = atoi(attr->a_value); maxptime = atoi(attr->a_value);
} else if (!got_crypto && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value) && } else if (!got_crypto && !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))) { //(!switch_channel_test_flag(session->channel, CF_WEBRTC) || switch_stristr(SWITCH_RTP_CRYPTO_KEY_80, attr->a_value))) {
int crypto_tag; int crypto_tag;
if (!(smh->mparams->ndlb & SM_NDLB_ALLOW_CRYPTO_IN_AVP) && if (!(smh->mparams->ndlb & SM_NDLB_ALLOW_CRYPTO_IN_AVP) &&
@ -3113,7 +3133,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
crypto = attr->a_value; crypto = attr->a_value;
crypto_tag = atoi(crypto); crypto_tag = atoi(crypto);
got_crypto = switch_core_session_check_incoming_crypto(session, got_crypto = switch_core_session_check_incoming_crypto(session,
"rtp_has_crypto", SWITCH_MEDIA_TYPE_AUDIO, crypto, crypto_tag, sdp_type); "rtp_has_crypto", SWITCH_MEDIA_TYPE_AUDIO, crypto, crypto_tag, sdp_type);
@ -3122,7 +3141,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
if (got_crypto > 0 && !got_avp) { if (got_crypto > 0 && !got_avp) {
switch_channel_set_variable(session->channel, "rtp_crypto_mandatory", "true"); switch_channel_set_variable(session->channel, "rtp_crypto_mandatory", "true");
switch_channel_set_variable(session->channel, "rtp_secure_media", "true"); //switch_channel_set_variable(session->channel, "rtp_secure_media", "true");
} }
if (got_crypto == -1 && got_savp && !got_avp) { if (got_crypto == -1 && got_savp && !got_avp) {
@ -3568,7 +3587,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
if (got_video_crypto && !got_video_avp) { if (got_video_crypto && !got_video_avp) {
switch_channel_set_variable(session->channel, "rtp_crypto_mandatory", "true"); switch_channel_set_variable(session->channel, "rtp_crypto_mandatory", "true");
switch_channel_set_variable(session->channel, "rtp_secure_media", "true"); //switch_channel_set_variable(session->channel, "rtp_secure_media", "true");
} }
if (!(rm_encoding = map->rm_encoding)) { if (!(rm_encoding = map->rm_encoding)) {
@ -4588,7 +4607,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
switch_rtp_reset_media_timer(a_engine->rtp_session); switch_rtp_reset_media_timer(a_engine->rtp_session);
} }
if ((var = switch_channel_get_variable(session->channel, "rtp_secure_media")) && switch_true(var)) { if ((var = switch_channel_get_variable(session->channel, "rtp_secure_media")) && (switch_true(var) || switch_core_media_crypto_str2type(var) != CRYPTO_INVALID)) {
switch_channel_set_flag(session->channel, CF_SECURE); switch_channel_set_flag(session->channel, CF_SECURE);
} }
@ -8480,10 +8499,10 @@ SWITCH_DECLARE (void) switch_core_media_recover_session(switch_core_session_t *s
switch_channel_set_flag(smh->session->channel, CF_SECURE); switch_channel_set_flag(smh->session->channel, CF_SECURE);
switch_rtp_add_crypto_key(a_engine->rtp_session, SWITCH_RTP_CRYPTO_SEND, idx, switch_rtp_add_crypto_key(a_engine->rtp_session, SWITCH_RTP_CRYPTO_SEND, idx,
a_engine->ssec.crypto_send_type, a_engine->ssec.local_raw_key, SWITCH_RTP_KEY_LEN); a_engine->ssec.crypto_send_type, a_engine->ssec.local_raw_key, SUITES[a_engine->ssec.crypto_send_type].keylen);
switch_rtp_add_crypto_key(a_engine->rtp_session, SWITCH_RTP_CRYPTO_RECV, a_engine->ssec.crypto_tag, switch_rtp_add_crypto_key(a_engine->rtp_session, SWITCH_RTP_CRYPTO_RECV, a_engine->ssec.crypto_tag,
a_engine->ssec.crypto_recv_type, a_engine->ssec.remote_raw_key, SWITCH_RTP_KEY_LEN); a_engine->ssec.crypto_recv_type, a_engine->ssec.remote_raw_key, SUITES[a_engine->ssec.crypto_recv_type].keylen);
} }

View File

@ -2731,7 +2731,6 @@ static int do_dtls(switch_rtp_t *rtp_session, switch_dtls_t *dtls)
if (!dtls->bytes && !ready) { if (!dtls->bytes && !ready) {
printf("SKIP\n");
return 0; return 0;
} }