提交 366bf3f8 authored 作者: Mike Jerris's avatar Mike Jerris

Merge pull request #2 in FSA/freeswitch-advantage from…

Merge pull request #2 in FSA/freeswitch-advantage from ~PIOTRGREGOR/freeswitch:feature/FS-10778-srtp-mki-support to v1.8-fsa

* commit '903ea6e6':
  FS-10778: Fix compilation and refactor code
...@@ -1388,155 +1388,161 @@ switch_status_t switch_core_media_add_crypto(switch_core_session_t *session, swi ...@@ -1388,155 +1388,161 @@ switch_status_t switch_core_media_add_crypto(switch_core_session_t *session, swi
p = strchr(key_param, ' '); p = strchr(key_param, ' ');
if (p && *p && *(p + 1)) { if (!(p && *p && *(p + 1))) {
p++; goto no_crypto_found;
}
type = switch_core_media_crypto_str2type(p); p++;
if (type == CRYPTO_INVALID) { type = switch_core_media_crypto_str2type(p);
goto bad_crypto;
}
p = strchr(p, ' '); /* skip the crypto suite description */ if (type == CRYPTO_INVALID) {
if (p == NULL) { goto bad_crypto;
goto bad_crypto; }
}
do { p = strchr(p, ' '); /* skip the crypto suite description */
if (*key_material_n == SWITCH_CRYPTO_MKI_MAX) { if (p == NULL) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Skipping excess of MKIs due to max number of suppoerted MKIs %d exceeded\n", SWITCH_CRYPTO_MKI_MAX); goto bad_crypto;
break; }
}
p = switch_strip_spaces((char*) p, 0); do {
if (p) { if (*key_material_n == SWITCH_CRYPTO_MKI_MAX) {
key_material_begin = p; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Skipping excess of MKIs due to max number of suppoerted MKIs %d exceeded\n", SWITCH_CRYPTO_MKI_MAX);
key_material_end = switch_core_media_crypto_find_key_material_candidate_end(p); break;
}
/* Parsing the key material candidate within [begin, end). */ p = switch_strip_spaces((char*) p, 0);
if (!p) {
break;
}
if ((delimit = strchr(p, ':')) == NULL) { key_material_begin = p;
goto bad_error_parsing_near; key_material_end = switch_core_media_crypto_find_key_material_candidate_end(p);
}
method_len = delimit - p; /* Parsing the key material candidate within [begin, end). */
if (strncasecmp(p, CRYPTO_KEY_PARAM_METHOD[CRYPTO_KEY_PARAM_METHOD_INLINE], method_len)) { if ((delimit = strchr(p, ':')) == NULL) {
goto bad_key_param_method; goto bad_error_parsing_near;
} }
method = CRYPTO_KEY_PARAM_METHOD_INLINE;
/* Valid key-material found. Save as default key in secure_settings_s. */ method_len = delimit - p;
p = delimit + 1; /* skip ':' */ if (strncasecmp(p, CRYPTO_KEY_PARAM_METHOD[CRYPTO_KEY_PARAM_METHOD_INLINE], method_len)) {
if (!(p && *p && *(p + 1))) { goto bad_key_param_method;
goto bad_keysalt; }
}
/* Check if '|' is present in currently considered key-material. */ method = CRYPTO_KEY_PARAM_METHOD_INLINE;
if ((opts = strchr(p, '|')) && (opts < key_material_end)) {
keysalt_len = opts - p;
} else {
keysalt_len = key_material_end - p;
}
if (keysalt_len > sizeof(key)) { /* Valid key-material found. Save as default key in secure_settings_s. */
goto bad_keysalt_len;
}
switch_b64_decode(p, (char *) key, keysalt_len); p = delimit + 1; /* skip ':' */
if (!(p && *p && *(p + 1))) {
goto bad_keysalt;
}
if (!multiple_keys) { /* First key becomes default (used in case no MKI is found). */ /* Check if '|' is present in currently considered key-material. */
if (direction == SWITCH_RTP_CRYPTO_SEND) { if ((opts = strchr(p, '|')) && (opts < key_material_end)) {
memcpy(ssec->local_raw_key, key, SUITES[type].keysalt_len); keysalt_len = opts - p;
} else { } else {
memcpy(ssec->remote_raw_key, key, SUITES[type].keysalt_len); keysalt_len = key_material_end - p;
} }
multiple_keys = true;
}
p += keysalt_len; if (keysalt_len > sizeof(key)) {
goto bad_keysalt_len;
}
if (p < key_material_end) { /* Parse LIFETIME or MKI. */ switch_b64_decode(p, (char *) key, keysalt_len);
if (opts) { /* if opts != NULL then opts points to first '|' in current key-material cadidate */ if (!multiple_keys) { /* First key becomes default (used in case no MKI is found). */
if (direction == SWITCH_RTP_CRYPTO_SEND) {
memcpy(ssec->local_raw_key, key, SUITES[type].keysalt_len);
} else {
memcpy(ssec->remote_raw_key, key, SUITES[type].keysalt_len);
}
multiple_keys = true;
}
lifetime = 0; p += keysalt_len;
mki_id = 0;
mki_size = 0;
for (int i = 0; i < 2 && (*opts == '|'); ++i) { if (!(p < key_material_end)) {
continue;
}
opt_field = parse_lifetime_mki(&opts, key_material_end); if (opts) { /* if opts != NULL then opts points to first '|' in current key-material cadidate, parse it as LIFETIME or MKI */
switch ((opt_field >> 24) & 0x3) { lifetime = 0;
mki_id = 0;
mki_size = 0;
case CRYPTO_KEY_MATERIAL_LIFETIME: for (int i = 0; i < 2 && (*opts == '|'); ++i) {
lifetime_base = ((opt_field & 0x00ffff00) >> 8) & 0xffff; opt_field = parse_lifetime_mki(&opts, key_material_end);
lifetime_exp = (opt_field & 0x000000ff) & 0xffff;
lifetime = pow(lifetime_base, lifetime_exp);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "LIFETIME found in %s, base %u exp %u\n", p, lifetime_base, lifetime_exp);
break;
case CRYPTO_KEY_MATERIAL_MKI: switch ((opt_field >> 24) & 0x3) {
mki_id = ((opt_field & 0x00ffff00) >> 8) & 0xffff; case CRYPTO_KEY_MATERIAL_LIFETIME:
mki_size = (opt_field & 0x000000ff) & 0xffff;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MKI found in %s, id %u size %u\n", p, mki_id, mki_size);
break;
default: lifetime_base = ((opt_field & 0x00ffff00) >> 8) & 0xffff;
goto bad_key_lifetime_or_mki; lifetime_exp = (opt_field & 0x000000ff) & 0xffff;
} lifetime = pow(lifetime_base, lifetime_exp);
} switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "LIFETIME found in %s, base %u exp %u\n", p, lifetime_base, lifetime_exp);
break;
if (mki_id == 0 && lifetime == 0) { case CRYPTO_KEY_MATERIAL_MKI:
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Bad MKI found in %s, (parsed as: id %u size %u lifetime base %u exp %u\n", p, mki_id, mki_size, lifetime_base, lifetime_exp);
return SWITCH_STATUS_FALSE;
} else if (mki_id == 0 || lifetime == 0) {
if (mki_id == 0) {
if (key_material)
goto bad_key_no_mki_index;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Skipping MKI due to empty index\n"); mki_id = ((opt_field & 0x00ffff00) >> 8) & 0xffff;
} else { mki_size = (opt_field & 0x000000ff) & 0xffff;
if (mki_size == 0) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MKI found in %s, id %u size %u\n", p, mki_id, mki_size);
goto bad_key_no_mki_size; break;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Skipping MKI due to empty lifetime\n"); default:
} goto bad_key_lifetime_or_mki;
continue; }
} }
}
if (key_material) { if (mki_id == 0 && lifetime == 0) {
if (mki_id == 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Bad MKI found in %s, (parsed as: id %u size %u lifetime base %u exp %u\n", p, mki_id, mki_size, lifetime_base, lifetime_exp);
goto bad_key_no_mki_index; return SWITCH_STATUS_FALSE;
} } else if (mki_id == 0 || lifetime == 0) {
if (mki_id == 0) {
if (key_material)
goto bad_key_no_mki_index;
if (mki_size != key_material->mki_size) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Skipping MKI due to empty index\n");
goto bad_key_mki_size; } else {
} if (mki_size == 0)
} goto bad_key_no_mki_size;
key_material = switch_core_media_crypto_append_key_material(session, key_material, method, (unsigned char*) key, switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Skipping MKI due to empty lifetime\n");
SUITES[type].keysalt_len, (char*) key_material_begin, key_material_end - key_material_begin, lifetime, mki_id, mki_size);
*key_material_n = *key_material_n + 1;
} }
continue;
} }
} while ((p = switch_strip_spaces((char*) key_material_end, 0)) && (*p != '\0')); }
if (direction == SWITCH_RTP_CRYPTO_SEND || direction == SWITCH_RTP_CRYPTO_SEND_RTCP) { if (key_material) {
ssec->local_key_material_next = key_material; if (mki_id == 0) {
} else { goto bad_key_no_mki_index;
ssec->remote_key_material_next = key_material; }
if (mki_size != key_material->mki_size) {
goto bad_key_mki_size;
}
} }
return SWITCH_STATUS_SUCCESS; key_material = switch_core_media_crypto_append_key_material(session, key_material, method, (unsigned char*) key,
SUITES[type].keysalt_len, (char*) key_material_begin, key_material_end - key_material_begin, lifetime, mki_id, mki_size);
*key_material_n = *key_material_n + 1;
} while ((p = switch_strip_spaces((char*) key_material_end, 0)) && (*p != '\0'));
if (direction == SWITCH_RTP_CRYPTO_SEND || direction == SWITCH_RTP_CRYPTO_SEND_RTCP) {
ssec->local_key_material_next = key_material;
} else {
ssec->remote_key_material_next = key_material;
} }
return SWITCH_STATUS_SUCCESS;
no_crypto_found: no_crypto_found:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error! No crypto to parse\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error! No crypto to parse\n");
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论