diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 37e8df8484..d9183405ea 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -39,17 +39,6 @@ SWITCH_BEGIN_EXTERN_C #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 { DTMF_2833, DTMF_INFO, @@ -157,41 +146,6 @@ typedef struct switch_core_media_params_s { } 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) { switch(type) { @@ -311,6 +265,12 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se uint32_t ptime, 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 #endif /* For Emacs: diff --git a/src/include/switch_frame.h b/src/include/switch_frame.h index a15ef34c8a..bbbca0917b 100644 --- a/src/include/switch_frame.h +++ b/src/include/switch_frame.h @@ -37,7 +37,6 @@ #define SWITCH_FRAME_H #include -#include SWITCH_BEGIN_EXTERN_C /*! \brief An abstraction of a data frame */ diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index e807476490..c6082fa9c5 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -41,18 +41,16 @@ SWITCH_BEGIN_EXTERN_C -#include - #define SWITCH_RTP_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_CRYPTO_LEN 64 -#define SWITCH_RTP_KEY_LEN 30 -#define SWITCH_RTP_CRYPTO_KEY_32 "AES_CM_128_HMAC_SHA1_32" +//#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 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_RECV, SWITCH_RTP_CRYPTO_SEND_RTCP, @@ -60,16 +58,12 @@ SWITCH_BEGIN_EXTERN_C SWITCH_RTP_CRYPTO_MAX } switch_rtp_crypto_direction_t; -typedef enum { - NO_CRYPTO, - AES_CM_128_HMAC_SHA1_80, - AES_CM_128_HMAC_SHA1_32, - AES_CM_256_HMAC_SHA1_80, - 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; +typedef struct switch_srtp_crypto_suite_s { + char *name; + switch_rtp_crypto_key_type_t type; + int keylen; +} switch_srtp_crypto_suite_t; + struct switch_rtp_crypto_key { uint32_t index; diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 8bd1dff30c..f9f5a492d7 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -2312,6 +2312,67 @@ typedef void (*switch_event_channel_func_t)(const char *event_channel, cJSON *js struct switch_live_array_s; 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 diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index d2f6f20641..ab4e647032 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -33,6 +33,10 @@ #include #include +#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 DL_CAND_WAIT 10000000 #define DL_CAND_INITIAL_WAIT 2000000 diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 90aaaee1fc..9f6f0643ef 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -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)) || (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); } diff --git a/src/switch_channel.c b/src/switch_channel.c index a1b9efeba6..7351fc691b 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -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_event_t *event; @@ -3433,8 +3418,6 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_pre_answer(switch_channel return SWITCH_STATUS_SUCCESS; } - check_secure(channel); - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { msg.message_id = SWITCH_MESSAGE_INDICATE_PROGRESS; msg.from = channel->name; @@ -3720,8 +3703,6 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t * return SWITCH_STATUS_SUCCESS; } - check_secure(channel); - msg.message_id = SWITCH_MESSAGE_INDICATE_ANSWER; msg.from = channel->name; status = switch_core_session_perform_receive_message(channel->session, &msg, file, func, line); diff --git a/src/switch_core_media.c b/src/switch_core_media.c index e2b92b6177..ffb0b306bd 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -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) { 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) { unsigned char b64_key[512] = ""; - const char *type_str; unsigned char *key; const char *val; 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; } - 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 #ifdef SAME_KEY if (switch_channel_test_flag(channel, CF_WEBRTC) && type == SWITCH_MEDIA_TYPE_VIDEO) { 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; } 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; } } 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; } - switch_rtp_get_random(key, SWITCH_RTP_KEY_LEN); + switch_rtp_get_random(key, SUITES[ctype].keylen); #ifdef SAME_KEY } #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, '='); while (p && *p && *p == '=') { *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)); @@ -897,15 +926,10 @@ switch_status_t switch_core_media_add_crypto(switch_secure_settings_t *ssec, con if (p && *p && *(p + 1)) { p++; - if (!strncasecmp(p, SWITCH_RTP_CRYPTO_KEY_32, strlen(SWITCH_RTP_CRYPTO_KEY_32))) { - type = AES_CM_128_HMAC_SHA1_32; - } else if (!strncasecmp(p, SWITCH_RTP_CRYPTO_KEY_80, strlen(SWITCH_RTP_CRYPTO_KEY_80))) { - type = AES_CM_128_HMAC_SHA1_80; - } 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 { + + type = switch_core_media_crypto_str2type(p); + + if (type == CRYPTO_INVALID) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error near [%s]\n", p); 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) { 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 { 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; } @@ -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, - 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, - 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"); } @@ -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) { int got_crypto = 0; - + int i = 0; + int ctype = 0; + const char *vval = NULL; switch_rtp_engine_t *engine; + const char *suite = switch_channel_get_variable(session->channel, "rtp_secure_media"); + if (!session->media_handle) return 0; + 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)) { /* Compare all the key. The tag may remain the same even if key changed */ 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"); + got_crypto = 1; } else { - const char *a = switch_stristr("AES", engine->ssec.remote_crypto_key); - const char *b = switch_stristr("AES", crypto); + const char *a = switch_stristr("AE", engine->ssec.remote_crypto_key); + const char *b = switch_stristr("AE", crypto); - /* Change our key every time we can */ - if (sdp_type == SDP_TYPE_REQUEST) { - if (switch_stristr(SWITCH_RTP_CRYPTO_KEY_32, crypto)) { - switch_channel_set_variable(session->channel, varname, SWITCH_RTP_CRYPTO_KEY_32); - - 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"); + if (!vval) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unsupported Crypto [%s]\n", crypto); + goto end; } + 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)) { @@ -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)) { 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, - 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++; } 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)) { + + 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); 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); engine->ssec.crypto_tag = crypto_tag; got_crypto++; - + if (zstr(engine->ssec.local_crypto_key)) { - if (switch_stristr(SWITCH_RTP_CRYPTO_KEY_32, crypto)) { - switch_channel_set_variable(session->channel, varname, SWITCH_RTP_CRYPTO_KEY_32); - 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"); - } + 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; } @@ -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 (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_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_MEDIA_TYPE_VIDEO, 1, AES_CM_128_HMAC_SHA1_32, 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); + SWITCH_MEDIA_TYPE_VIDEO, 1, ctype, 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 (!switch_true(var) - && 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)) { + if (!switch_true(var) && switch_core_media_crypto_str2type(var) == CRYPTO_INVALID) { 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); } else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) { maxptime = atoi(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))) { + } 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))) { int crypto_tag; 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_tag = atoi(crypto); - got_crypto = switch_core_session_check_incoming_crypto(session, "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) { 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) { @@ -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) { 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)) { @@ -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); } - 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); } @@ -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_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, - 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); } diff --git a/src/switch_rtp.c b/src/switch_rtp.c index a5d0226a31..48ee1be44d 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2731,7 +2731,6 @@ static int do_dtls(switch_rtp_t *rtp_session, switch_dtls_t *dtls) if (!dtls->bytes && !ready) { - printf("SKIP\n"); return 0; }