diff --git a/channels/sip/sdp_crypto.c b/channels/sip/sdp_crypto.c index 3a95ce9a6c..ea8ea64162 100644 --- a/channels/sip/sdp_crypto.c +++ b/channels/sip/sdp_crypto.c @@ -49,6 +49,8 @@ struct sdp_crypto { char *a_crypto; unsigned char local_key[SRTP_MASTER_LEN]; char local_key64[SRTP_MASTER_LEN64]; + unsigned char remote_key[SRTP_MASTER_LEN]; + char suite[64]; }; static int set_crypto_policy(struct ast_srtp_policy *policy, int suite_val, const unsigned char *master_key, unsigned long ssrc, int inbound); @@ -257,12 +259,20 @@ int sdp_crypto_process(struct sdp_crypto *p, const char *attr, struct ast_rtp_in return -1; } - if ((key_len = ast_base64decode(remote_key, key_salt, sizeof(remote_key))) != SRTP_MASTER_LEN) { - ast_log(LOG_WARNING, "SRTP sdescriptions key %d != %d\n", key_len, 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; + } + + /* Set the accepted policy and remote key */ + ast_copy_string(p->suite, suite, sizeof(p->suite)); + memcpy(p->remote_key, remote_key, sizeof(p->remote_key)); + if (sdp_crypto_activate(p, suite_val, remote_key, rtp) < 0) { return -1; } @@ -280,13 +290,17 @@ int sdp_crypto_process(struct sdp_crypto *p, const char *attr, struct ast_rtp_in int sdp_crypto_offer(struct sdp_crypto *p) { char crypto_buf[128]; - const char *crypto_suite = "AES_CM_128_HMAC_SHA1_80"; /* Crypto offer */ + + if (ast_strlen_zero(p->suite)) { + /* Default crypto offer */ + strcpy(p->suite, "AES_CM_128_HMAC_SHA1_80"); + } if (p->a_crypto) { ast_free(p->a_crypto); } - if (snprintf(crypto_buf, sizeof(crypto_buf), "a=crypto:1 %s inline:%s\r\n", crypto_suite, p->local_key64) < 1) { + if (snprintf(crypto_buf, sizeof(crypto_buf), "a=crypto:1 %s inline:%s\r\n", p->suite, p->local_key64) < 1) { return -1; }