--- channels/chan_sip.c (Asterisk 16.8-cert2) +++ channels/chan_sip.c (working copy) @@ -34298,6 +34298,39 @@ return FALSE; } + /* Nokia Symbian/S60 requires little-endian ROC; default of RFC is network + * order = big endian. Nokia Series 40 and Nokia Asha Software Platform are + * not affected and use network order. As User-Agent, these use NokiaModel, + * for example Nokia6300i and Nokia503. Nokia MeeGo/Maemo do not offer sRTP. + * Symbian/S60 uses *Type, Type is RA-x or RM-xxx, for example: + * a) Nokia RA-6 300.34.84 + * b) E66-1 RM-343 510.21.009 + * c) S60 RM-670 113.010.1506 + * + * http://www.nokiaport.de/?pid=models + * http://web.archive.org/web/20080416025322/http://www.forum.nokia.com/main/resources/technologies/voice_over_IP/voip_support_in_nokia_devices.html + * http://web.archive.org/web/20090528115458/http://www.forum.nokia.com/Technology_Topics/Mobile_Technologies/VoIP/Nokia_VoIP_Framework/VoIP_support_in_Nokia_devices.xhtml + * http://web.archive.org/web/20120309140131/http://www.developer.nokia.com/Community/Wiki/VoIP_support_in_Nokia_devices + * Nokia E63, Nokia E66, and Nokia E71 (only those) send no User-Agent on + * REGISTER and no while answering to an INVITE. Therefore, these phones + * cannot be catched/filtered by the code below. Calls initiated by these + * phones do work because the User-Agent is sent. If you have users using + * such phones to receive calls, consider to change the rtp->seqno from + * random to 0 (in res/res_rtp_asterisk.c:ast_rtp_new); then calls last at + * least 21 minutes. + */ + if (strstr(p->useragent, " RA-") + || strstr(p->useragent, " RM-") + /* required for INVITE from Asterisk because INVITE session does not exchange User-Agent: */ + || (p->relatedpeer && strstr(p->relatedpeer->useragent, " RA-")) + || (p->relatedpeer && strstr(p->relatedpeer->useragent, " RM-"))) { + struct ast_sdp_srtp *tmp = *srtp; + do { + ast_set_flag(tmp, AST_SRTP_CRYPTO_ROC_LE); + tmp = AST_LIST_NEXT(tmp, sdp_srtp_list); + } while (tmp); + } + if (ast_sdp_crypto_process(rtp, *srtp, a) < 0) { return FALSE; } --- include/asterisk/res_srtp.h (Asterisk 16.8-cert2) +++ include/asterisk/res_srtp.h (working copy) @@ -55,4 +55,6 @@ /* Crypto suites */ enum ast_srtp_suite { + AST_AES_CM_128_HMAC_SHA1_32_ROC_LE = -2, + AST_AES_CM_128_HMAC_SHA1_80_ROC_LE = -1, /* https://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml */ AST_AES_CM_128_HMAC_SHA1_80 = 1, --- include/asterisk/sdp_srtp.h (Asterisk 16.8-cert2) +++ include/asterisk/sdp_srtp.h (working copy) @@ -42,2 +42,3 @@ +#define AST_SRTP_CRYPTO_ROC_LE (1 << 9) /* SRTP flags */ --- res/res_srtp.c (Asterisk 16.8-cert2) +++ res/res_srtp.c (working copy) @@ -319,6 +319,13 @@ static int ast_srtp_policy_set_suite(struct ast_srtp_policy *policy, enum ast_srtp_suite suite) { + if (suite == AST_AES_CM_128_HMAC_SHA1_32_ROC_LE) { + policy->sp.allow_repeat_tx = (policy->sp.allow_repeat_tx | 0x02); + suite = AST_AES_CM_128_HMAC_SHA1_32; + } else if (suite == AST_AES_CM_128_HMAC_SHA1_80_ROC_LE) { + policy->sp.allow_repeat_tx = (policy->sp.allow_repeat_tx | 0x02); + suite = AST_AES_CM_128_HMAC_SHA1_80; + } return policy_set_suite(&policy->sp.rtp, suite) | policy_set_suite(&policy->sp.rtcp, suite); } @@ -867,2 +874,5 @@ suite_val = AST_AES_CM_128_HMAC_SHA1_80; + if (ast_test_flag(srtp, AST_SRTP_CRYPTO_ROC_LE)) { + suite_val = AST_AES_CM_128_HMAC_SHA1_80_ROC_LE; + } ast_set_flag(srtp, AST_SRTP_CRYPTO_TAG_80); @@ -871,2 +881,5 @@ suite_val = AST_AES_CM_128_HMAC_SHA1_32; + if (ast_test_flag(srtp, AST_SRTP_CRYPTO_ROC_LE)) { + suite_val = AST_AES_CM_128_HMAC_SHA1_32_ROC_LE; + } ast_set_flag(srtp, AST_SRTP_CRYPTO_TAG_32);