diff options
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_sip.c | 25 | ||||
-rw-r--r-- | channels/sip/include/sdp_crypto.h | 6 | ||||
-rw-r--r-- | channels/sip/include/sip.h | 3 | ||||
-rw-r--r-- | channels/sip/include/srtp.h | 2 | ||||
-rw-r--r-- | channels/sip/sdp_crypto.c | 11 |
5 files changed, 34 insertions, 13 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index f226b1c56..3d64c8493 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -11127,14 +11127,25 @@ static void get_our_media_address(struct sip_pvt *p, int needvideo, int needtext } } -static void get_crypto_attrib(struct sip_srtp *srtp, const char **a_crypto) +static void get_crypto_attrib(struct sip_pvt *p, struct sip_srtp *srtp, const char **a_crypto) { + int taglen = 80; + /* Set encryption properties */ if (srtp) { if (!srtp->crypto) { srtp->crypto = sdp_crypto_setup(); } - if (srtp->crypto && (sdp_crypto_offer(srtp->crypto) >= 0)) { + + /* set the key length based on INVITE or settings */ + if (ast_test_flag(srtp, SRTP_CRYPTO_TAG_80)) { + taglen = 80; + } else if (ast_test_flag(&p->flags[2], SIP_PAGE3_SRTP_TAG_32) || + ast_test_flag(srtp, SRTP_CRYPTO_TAG_32)) { + taglen = 32; + } + + if (srtp->crypto && (sdp_crypto_offer(srtp->crypto, taglen) >= 0)) { *a_crypto = sdp_crypto_attrib(srtp->crypto); } @@ -11302,7 +11313,7 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int /* Ok, we need video. Let's add what we need for video and set codecs. Video is handled differently than audio since we can not transcode. */ if (needvideo) { - get_crypto_attrib(p->vsrtp, &v_a_crypto); + get_crypto_attrib(p, p->vsrtp, &v_a_crypto); ast_str_append(&m_video, 0, "m=video %d RTP/%s", ast_sockaddr_port(&vdest), v_a_crypto ? "SAVP" : "AVP"); @@ -11319,7 +11330,7 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int if (needtext) { if (sipdebug_text) ast_verbose("Lets set up the text sdp\n"); - get_crypto_attrib(p->tsrtp, &t_a_crypto); + get_crypto_attrib(p, p->tsrtp, &t_a_crypto); ast_str_append(&m_text, 0, "m=text %d RTP/%s", ast_sockaddr_port(&tdest), t_a_crypto ? "SAVP" : "AVP"); if (debug) { /* XXX should I use tdest below ? */ @@ -11332,7 +11343,7 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int /* We break with the "recommendation" and send our IP, in order that our peer doesn't have to ast_gethostbyname() us */ - get_crypto_attrib(p->srtp, &a_crypto); + get_crypto_attrib(p, p->srtp, &a_crypto); ast_str_append(&m_audio, 0, "m=audio %d RTP/%s", ast_sockaddr_port(&dest), a_crypto ? "SAVP" : "AVP"); @@ -27701,6 +27712,8 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON); } else if (!strcasecmp(v->name, "encryption")) { ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_USE_SRTP); + } else if (!strcasecmp(v->name, "encryption_taglen")) { + ast_set2_flag(&peer->flags[2], !strcasecmp(v->value, "32"), SIP_PAGE3_SRTP_TAG_32); } else if (!strcasecmp(v->name, "snom_aoc_enabled")) { ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC); } @@ -29647,7 +29660,7 @@ static int process_crypto(struct sip_pvt *p, struct ast_rtp_instance *rtp, struc return FALSE; } - if (sdp_crypto_process((*srtp)->crypto, a, rtp) < 0) { + if (sdp_crypto_process((*srtp)->crypto, a, rtp, *srtp) < 0) { return FALSE; } diff --git a/channels/sip/include/sdp_crypto.h b/channels/sip/include/sdp_crypto.h index b1c153438..aa553cb00 100644 --- a/channels/sip/include/sdp_crypto.h +++ b/channels/sip/include/sdp_crypto.h @@ -31,6 +31,7 @@ #include <asterisk/rtp_engine.h> struct sdp_crypto; +struct sip_srtp; /*! \brief Initialize an return an sdp_crypto struct * @@ -51,11 +52,12 @@ void sdp_crypto_destroy(struct sdp_crypto *crypto); * \param p A valid sdp_crypto struct * \param attr the a:crypto line from SDP * \param rtp The rtp instance associated with the SDP being parsed + * \param srtp SRTP structure * * \retval 0 success * \retval nonzero failure */ -int sdp_crypto_process(struct sdp_crypto *p, const char *attr, struct ast_rtp_instance *rtp); +int sdp_crypto_process(struct sdp_crypto *p, const char *attr, struct ast_rtp_instance *rtp, struct sip_srtp *srtp); /*! \brief Generate an SRTP a=crypto offer @@ -68,7 +70,7 @@ int sdp_crypto_process(struct sdp_crypto *p, const char *attr, struct ast_rtp_in * \retval 0 success * \retval nonzero failure */ -int sdp_crypto_offer(struct sdp_crypto *p); +int sdp_crypto_offer(struct sdp_crypto *p, int taglen); /*! \brief Return the a_crypto value of the sdp_crypto struct diff --git a/channels/sip/include/sip.h b/channels/sip/include/sip.h index 5018f0f83..7e0f2d261 100644 --- a/channels/sip/include/sip.h +++ b/channels/sip/include/sip.h @@ -354,9 +354,10 @@ #define SIP_PAGE3_SNOM_AOC (1 << 0) /*!< DPG: Allow snom aoc messages */ +#define SIP_PAGE3_SRTP_TAG_32 (1 << 1) /*!< DP: Use a 32bit auth tag in INVITE not 80bit */ #define SIP_PAGE3_FLAGS_TO_COPY \ - (SIP_PAGE3_SNOM_AOC) + (SIP_PAGE3_SNOM_AOC | SIP_PAGE3_SRTP_TAG_32) /*@}*/ diff --git a/channels/sip/include/srtp.h b/channels/sip/include/srtp.h index b7a3fc30b..95281922f 100644 --- a/channels/sip/include/srtp.h +++ b/channels/sip/include/srtp.h @@ -34,6 +34,8 @@ #define SRTP_ENCR_OPTIONAL (1 << 1) /* SRTP encryption optional */ #define SRTP_CRYPTO_ENABLE (1 << 2) #define SRTP_CRYPTO_OFFER_OK (1 << 3) +#define SRTP_CRYPTO_TAG_32 (1 << 4) +#define SRTP_CRYPTO_TAG_80 (1 << 5) /*! \brief structure for secure RTP audio */ struct sip_srtp { diff --git a/channels/sip/sdp_crypto.c b/channels/sip/sdp_crypto.c index 9abf79ebc..bf3b2cd20 100644 --- a/channels/sip/sdp_crypto.c +++ b/channels/sip/sdp_crypto.c @@ -32,6 +32,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/options.h" #include "asterisk/utils.h" #include "include/sdp_crypto.h" +#include "include/srtp.h" #define SRTP_MASTER_LEN 30 #define SRTP_MASTERKEY_LEN 16 @@ -188,7 +189,7 @@ err: return res; } -int sdp_crypto_process(struct sdp_crypto *p, const char *attr, struct ast_rtp_instance *rtp) +int sdp_crypto_process(struct sdp_crypto *p, const char *attr, struct ast_rtp_instance *rtp, struct sip_srtp *srtp) { char *str = NULL; char *tag = NULL; @@ -228,8 +229,10 @@ int sdp_crypto_process(struct sdp_crypto *p, const char *attr, struct ast_rtp_in 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); } 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); } else { ast_log(LOG_WARNING, "Unsupported crypto suite: %s\n", suite); return -1; @@ -283,16 +286,16 @@ int sdp_crypto_process(struct sdp_crypto *p, const char *attr, struct ast_rtp_in return 0; } -int sdp_crypto_offer(struct sdp_crypto *p) +int sdp_crypto_offer(struct sdp_crypto *p, int taglen) { char crypto_buf[128]; - const char *crypto_suite = "AES_CM_128_HMAC_SHA1_80"; /* Crypto offer */ 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 AES_CM_128_HMAC_SHA1_%i inline:%s\r\n", + taglen, p->local_key64) < 1) { return -1; } |