SDP Security descriptions. More...
#include "asterisk.h"#include "asterisk/options.h"#include "asterisk/utils.h"#include "include/sdp_crypto.h"#include "include/srtp.h"
Go to the source code of this file.
Data Structures | |
| struct | sdp_crypto |
Defines | |
| #define | SRTP_MASTER_LEN 30 |
| #define | SRTP_MASTER_LEN64 (((SRTP_MASTER_LEN) * 8 + 5) / 6 + 1) |
| #define | SRTP_MASTERKEY_LEN 16 |
| #define | SRTP_MASTERSALT_LEN ((SRTP_MASTER_LEN) - (SRTP_MASTERKEY_LEN)) |
Functions | |
| static int | sdp_crypto_activate (struct sdp_crypto *p, int suite_val, unsigned char *remote_key, struct ast_rtp_instance *rtp) |
| static struct sdp_crypto * | sdp_crypto_alloc (void) |
| const char * | sdp_crypto_attrib (struct sdp_crypto *p) |
| void | sdp_crypto_destroy (struct sdp_crypto *crypto) |
| int | sdp_crypto_offer (struct sdp_crypto *p, int taglen) |
| int | sdp_crypto_process (struct sdp_crypto *p, const char *attr, struct ast_rtp_instance *rtp, struct sip_srtp *srtp) |
| struct sdp_crypto * | sdp_crypto_setup (void) |
| static int | set_crypto_policy (struct ast_srtp_policy *policy, int suite_val, const unsigned char *master_key, unsigned long ssrc, int inbound) |
Variables | |
| struct ast_srtp_res * | res_srtp |
| struct ast_srtp_policy_res * | res_srtp_policy |
| #define SRTP_MASTER_LEN 30 |
Definition at line 41 of file sdp_crypto.c.
Referenced by sdp_crypto_process(), and sdp_crypto_setup().
| #define SRTP_MASTER_LEN64 (((SRTP_MASTER_LEN) * 8 + 5) / 6 + 1) |
Definition at line 44 of file sdp_crypto.c.
| #define SRTP_MASTERKEY_LEN 16 |
Definition at line 42 of file sdp_crypto.c.
Referenced by set_crypto_policy().
| #define SRTP_MASTERSALT_LEN ((SRTP_MASTER_LEN) - (SRTP_MASTERKEY_LEN)) |
Definition at line 43 of file sdp_crypto.c.
Referenced by set_crypto_policy().
| static int sdp_crypto_activate | ( | struct sdp_crypto * | p, |
| int | suite_val, | ||
| unsigned char * | remote_key, | ||
| struct ast_rtp_instance * | rtp | ||
| ) | [static] |
Definition at line 136 of file sdp_crypto.c.
References ast_srtp_policy_res::alloc, ast_debug, ast_log(), ast_rtp_engine_srtp_is_registered(), ast_rtp_instance_add_srtp_policy(), ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_LOCAL_SSRC, ast_srtp_policy_res::destroy, sdp_crypto::local_key, ast_rtp_instance_stats::local_ssrc, LOG_WARNING, and set_crypto_policy().
Referenced by sdp_crypto_process().
{
struct ast_srtp_policy *local_policy = NULL;
struct ast_srtp_policy *remote_policy = NULL;
struct ast_rtp_instance_stats stats = {0,};
int res = -1;
if (!ast_rtp_engine_srtp_is_registered()) {
return -1;
}
if (!p) {
return -1;
}
if (!(local_policy = res_srtp_policy->alloc())) {
return -1;
}
if (!(remote_policy = res_srtp_policy->alloc())) {
goto err;
}
if (ast_rtp_instance_get_stats(rtp, &stats, AST_RTP_INSTANCE_STAT_LOCAL_SSRC)) {
goto err;
}
if (set_crypto_policy(local_policy, suite_val, p->local_key, stats.local_ssrc, 0) < 0) {
goto err;
}
if (set_crypto_policy(remote_policy, suite_val, remote_key, 0, 1) < 0) {
goto err;
}
/* Add the SRTP policies */
if (ast_rtp_instance_add_srtp_policy(rtp, remote_policy, local_policy)) {
ast_log(LOG_WARNING, "Could not set SRTP policies\n");
goto err;
}
ast_debug(1 , "SRTP policy activated\n");
res = 0;
err:
if (local_policy) {
res_srtp_policy->destroy(local_policy);
}
if (remote_policy) {
res_srtp_policy->destroy(remote_policy);
}
return res;
}
| static struct sdp_crypto* sdp_crypto_alloc | ( | void | ) | [static, read] |
Definition at line 59 of file sdp_crypto.c.
References ast_calloc.
Referenced by sdp_crypto_setup().
{
return ast_calloc(1, sizeof(struct sdp_crypto));
}
| const char* sdp_crypto_attrib | ( | struct sdp_crypto * | p | ) |
Definition at line 315 of file sdp_crypto.c.
References sdp_crypto::a_crypto.
Referenced by get_crypto_attrib().
{
return p->a_crypto;
}
| void sdp_crypto_destroy | ( | struct sdp_crypto * | crypto | ) |
Definition at line 64 of file sdp_crypto.c.
References sdp_crypto::a_crypto, ast_free, and sdp_crypto::tag.
Referenced by sdp_crypto_setup(), and sip_srtp_destroy().
| int sdp_crypto_offer | ( | struct sdp_crypto * | p, |
| int | taglen | ||
| ) |
Definition at line 297 of file sdp_crypto.c.
References sdp_crypto::a_crypto, ast_asprintf, ast_free, ast_log(), sdp_crypto::local_key64, LOG_DEBUG, LOG_ERROR, and sdp_crypto::tag.
Referenced by get_crypto_attrib(), and sdp_crypto_process().
{
/* Rebuild the crypto line */
if (p->a_crypto) {
ast_free(p->a_crypto);
}
if (ast_asprintf(&p->a_crypto, "a=crypto:%s AES_CM_128_HMAC_SHA1_%i inline:%s\r\n",
p->tag ? p->tag : "1", taglen, p->local_key64) == -1) {
ast_log(LOG_ERROR, "Could not allocate memory for crypto line\n");
return -1;
}
ast_log(LOG_DEBUG, "Crypto line: %s", p->a_crypto);
return 0;
}
| int sdp_crypto_process | ( | struct sdp_crypto * | p, |
| const char * | attr, | ||
| struct ast_rtp_instance * | rtp, | ||
| struct sip_srtp * | srtp | ||
| ) |
Definition at line 192 of file sdp_crypto.c.
References AST_AES_CM_128_HMAC_SHA1_32, AST_AES_CM_128_HMAC_SHA1_80, ast_base64decode(), ast_debug, ast_log(), ast_rtp_engine_srtp_is_registered(), ast_set_flag, ast_strdup, ast_strlen_zero(), LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sdp_crypto::remote_key, sdp_crypto_activate(), sdp_crypto_offer(), SRTP_MASTER_LEN, str, and sdp_crypto::tag.
Referenced by process_crypto().
{
char *str = NULL;
char *tag = NULL;
char *suite = NULL;
char *key_params = NULL;
char *key_param = NULL;
char *session_params = NULL;
char *key_salt = NULL;
char *lifetime = NULL;
int found = 0;
int key_len = 0;
int suite_val = 0;
unsigned char remote_key[SRTP_MASTER_LEN];
int taglen = 0;
if (!ast_rtp_engine_srtp_is_registered()) {
return -1;
}
str = ast_strdupa(attr);
strsep(&str, ":");
tag = strsep(&str, " ");
suite = strsep(&str, " ");
key_params = strsep(&str, " ");
session_params = strsep(&str, " ");
if (!tag || !suite) {
ast_log(LOG_WARNING, "Unrecognized a=%s", attr);
return -1;
}
if (!ast_strlen_zero(session_params)) {
ast_log(LOG_WARNING, "Unsupported crypto parameters: %s", session_params);
return -1;
}
if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80")) {
suite_val = AST_AES_CM_128_HMAC_SHA1_80;
ast_set_flag(srtp, SRTP_CRYPTO_TAG_80);
taglen = 80;
} else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
suite_val = AST_AES_CM_128_HMAC_SHA1_32;
ast_set_flag(srtp, SRTP_CRYPTO_TAG_32);
taglen = 32;
} else {
ast_log(LOG_WARNING, "Unsupported crypto suite: %s\n", suite);
return -1;
}
while ((key_param = strsep(&key_params, ";"))) {
char *method = NULL;
char *info = NULL;
method = strsep(&key_param, ":");
info = strsep(&key_param, ";");
if (!strcmp(method, "inline")) {
key_salt = strsep(&info, "|");
lifetime = strsep(&info, "|");
if (lifetime) {
ast_log(LOG_NOTICE, "Crypto life time unsupported: %s\n", attr);
continue;
}
found = 1;
break;
}
}
if (!found) {
ast_log(LOG_NOTICE, "SRTP crypto offer not acceptable\n");
return -1;
}
if ((key_len = ast_base64decode(remote_key, key_salt, sizeof(remote_key))) != SRTP_MASTER_LEN) {
ast_log(LOG_WARNING, "SRTP descriptions key %d != %d\n", key_len, SRTP_MASTER_LEN);
return -1;
}
if (!memcmp(p->remote_key, remote_key, sizeof(p->remote_key))) {
ast_debug(1, "SRTP remote key unchanged; maintaining current policy\n");
return 0;
}
memcpy(p->remote_key, remote_key, sizeof(p->remote_key));
if (sdp_crypto_activate(p, suite_val, remote_key, rtp) < 0) {
return -1;
}
if (!p->tag) {
ast_log(LOG_DEBUG, "Accepting crypto tag %s\n", tag);
p->tag = ast_strdup(tag);
if (!p->tag) {
ast_log(LOG_ERROR, "Could not allocate memory for tag\n");
return -1;
}
}
/* Finally, rebuild the crypto line */
return sdp_crypto_offer(p, taglen);
}
| struct sdp_crypto* sdp_crypto_setup | ( | void | ) | [read] |
Definition at line 73 of file sdp_crypto.c.
References ast_base64decode(), ast_base64encode(), ast_debug, ast_free, ast_log(), ast_rtp_engine_srtp_is_registered(), ast_srtp_res::get_random, sdp_crypto::local_key, sdp_crypto::local_key64, LOG_ERROR, sdp_crypto::remote_key, sdp_crypto_alloc(), sdp_crypto_destroy(), and SRTP_MASTER_LEN.
Referenced by get_crypto_attrib(), and process_crypto().
{
struct sdp_crypto *p;
int key_len;
unsigned char remote_key[SRTP_MASTER_LEN];
if (!ast_rtp_engine_srtp_is_registered()) {
return NULL;
}
if (!(p = sdp_crypto_alloc())) {
return NULL;
}
if (res_srtp->get_random(p->local_key, sizeof(p->local_key)) < 0) {
sdp_crypto_destroy(p);
return NULL;
}
ast_base64encode(p->local_key64, p->local_key, SRTP_MASTER_LEN, sizeof(p->local_key64));
key_len = ast_base64decode(remote_key, p->local_key64, sizeof(remote_key));
if (key_len != SRTP_MASTER_LEN) {
ast_log(LOG_ERROR, "base64 encode/decode bad len %d != %d\n", key_len, SRTP_MASTER_LEN);
ast_free(p);
return NULL;
}
if (memcmp(remote_key, p->local_key, SRTP_MASTER_LEN)) {
ast_log(LOG_ERROR, "base64 encode/decode bad key\n");
ast_free(p);
return NULL;
}
ast_debug(1 , "local_key64 %s len %zu\n", p->local_key64, strlen(p->local_key64));
return p;
}
| static int set_crypto_policy | ( | struct ast_srtp_policy * | policy, |
| int | suite_val, | ||
| const unsigned char * | master_key, | ||
| unsigned long | ssrc, | ||
| int | inbound | ||
| ) | [static] |
Definition at line 113 of file sdp_crypto.c.
References ast_log(), ast_rtp_engine_srtp_is_registered(), LOG_WARNING, ast_srtp_policy_res::set_master_key, ast_srtp_policy_res::set_ssrc, ast_srtp_policy_res::set_suite, SRTP_MASTERKEY_LEN, and SRTP_MASTERSALT_LEN.
Referenced by sdp_crypto_activate().
{
const unsigned char *master_salt = NULL;
if (!ast_rtp_engine_srtp_is_registered()) {
return -1;
}
master_salt = master_key + SRTP_MASTERKEY_LEN;
if (res_srtp_policy->set_master_key(policy, master_key, SRTP_MASTERKEY_LEN, master_salt, SRTP_MASTERSALT_LEN) < 0) {
return -1;
}
if (res_srtp_policy->set_suite(policy, suite_val)) {
ast_log(LOG_WARNING, "Could not set remote SRTP suite\n");
return -1;
}
res_srtp_policy->set_ssrc(policy, ssrc, inbound);
return 0;
}
| struct ast_srtp_res* res_srtp |
Definition at line 49 of file rtp_engine.c.
| struct ast_srtp_policy_res* res_srtp_policy |
Definition at line 50 of file rtp_engine.c.
Referenced by ast_rtp_engine_srtp_is_registered().