p = strchr(key_param, ' ');
- if (p && *p && *(p + 1)) {
- p++;
+ if (!(p && *p && *(p + 1))) {
+ goto no_crypto_found;
+ }
- type = switch_core_media_crypto_str2type(p);
+ p++;
- if (type == CRYPTO_INVALID) {
- goto bad_crypto;
- }
+ type = switch_core_media_crypto_str2type(p);
- p = strchr(p, ' '); /* skip the crypto suite description */
- if (p == NULL) {
- goto bad_crypto;
- }
+ if (type == CRYPTO_INVALID) {
+ goto bad_crypto;
+ }
- do {
- if (*key_material_n == SWITCH_CRYPTO_MKI_MAX) {
- 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);
- break;
- }
+ p = strchr(p, ' '); /* skip the crypto suite description */
+ if (p == NULL) {
+ goto bad_crypto;
+ }
- p = switch_strip_spaces((char*) p, 0);
- if (p) {
- key_material_begin = p;
- key_material_end = switch_core_media_crypto_find_key_material_candidate_end(p);
+ do {
+ if (*key_material_n == SWITCH_CRYPTO_MKI_MAX) {
+ 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);
+ break;
+ }
- /* Parsing the key material candidate within [begin, end). */
+ p = switch_strip_spaces((char*) p, 0);
+ if (!p) {
+ break;
+ }
- if ((delimit = strchr(p, ':')) == NULL) {
- goto bad_error_parsing_near;
- }
+ key_material_begin = p;
+ 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)) {
- goto bad_key_param_method;
- }
-
- method = CRYPTO_KEY_PARAM_METHOD_INLINE;
+ if ((delimit = strchr(p, ':')) == NULL) {
+ goto bad_error_parsing_near;
+ }
- /* Valid key-material found. Save as default key in secure_settings_s. */
+ method_len = delimit - p;
- p = delimit + 1; /* skip ':' */
- if (!(p && *p && *(p + 1))) {
- goto bad_keysalt;
- }
+ if (strncasecmp(p, CRYPTO_KEY_PARAM_METHOD[CRYPTO_KEY_PARAM_METHOD_INLINE], method_len)) {
+ goto bad_key_param_method;
+ }
- /* Check if '|' is present in currently considered key-material. */
- if ((opts = strchr(p, '|')) && (opts < key_material_end)) {
- keysalt_len = opts - p;
- } else {
- keysalt_len = key_material_end - p;
- }
+ method = CRYPTO_KEY_PARAM_METHOD_INLINE;
- if (keysalt_len > sizeof(key)) {
- goto bad_keysalt_len;
- }
+ /* Valid key-material found. Save as default key in secure_settings_s. */
- 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). */
- 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;
- }
+ /* Check if '|' is present in currently considered key-material. */
+ if ((opts = strchr(p, '|')) && (opts < key_material_end)) {
+ keysalt_len = opts - p;
+ } else {
+ keysalt_len = key_material_end - p;
+ }
- 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;
- mki_id = 0;
- mki_size = 0;
+ p += keysalt_len;
- 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;
- 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;
+ opt_field = parse_lifetime_mki(&opts, key_material_end);
- case CRYPTO_KEY_MATERIAL_MKI:
+ switch ((opt_field >> 24) & 0x3) {
- mki_id = ((opt_field & 0x00ffff00) >> 8) & 0xffff;
- 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;
+ case CRYPTO_KEY_MATERIAL_LIFETIME:
- default:
- goto bad_key_lifetime_or_mki;
- }
- }
+ lifetime_base = ((opt_field & 0x00ffff00) >> 8) & 0xffff;
+ 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) {
- 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;
+ case CRYPTO_KEY_MATERIAL_MKI:
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Skipping MKI due to empty index\n");
- } else {
- if (mki_size == 0)
- goto bad_key_no_mki_size;
+ mki_id = ((opt_field & 0x00ffff00) >> 8) & 0xffff;
+ 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;
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Skipping MKI due to empty lifetime\n");
- }
- continue;
- }
- }
+ default:
+ goto bad_key_lifetime_or_mki;
+ }
+ }
- if (key_material) {
- if (mki_id == 0) {
- goto bad_key_no_mki_index;
- }
+ if (mki_id == 0 && lifetime == 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);
+ 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) {
- goto bad_key_mki_size;
- }
- }
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Skipping MKI due to empty index\n");
+ } 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,
- 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;
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Skipping MKI due to empty lifetime\n");
}
+ 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) {
- ssec->local_key_material_next = key_material;
- } else {
- ssec->remote_key_material_next = key_material;
+ if (key_material) {
+ if (mki_id == 0) {
+ goto bad_key_no_mki_index;
+ }
+
+ 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:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error! No crypto to parse\n");
return SWITCH_STATUS_FALSE;