[asterisk-commits] oej: branch oej/teapot-1.8 r399444 - in /team/oej/teapot-1.8: ./ channels/ ch...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Sep 19 04:10:00 CDT 2013
Author: oej
Date: Thu Sep 19 04:09:56 2013
New Revision: 399444
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=399444
Log:
Adding the SRTP lifetime handling for testing
Added:
team/oej/teapot-1.8/README.lingon.txt (with props)
team/oej/teapot-1.8/patches/lingon-srtp-key-lifetime-1.8.diff (with props)
Modified:
team/oej/teapot-1.8/channels/chan_sip.c
team/oej/teapot-1.8/channels/sip/sdp_crypto.c
Added: team/oej/teapot-1.8/README.lingon.txt
URL: http://svnview.digium.com/svn/asterisk/team/oej/teapot-1.8/README.lingon.txt?view=auto&rev=399444
==============================================================================
--- team/oej/teapot-1.8/README.lingon.txt (added)
+++ team/oej/teapot-1.8/README.lingon.txt Thu Sep 19 04:09:56 2013
@@ -1,0 +1,57 @@
+Edvina AB
+Olle E. Johansson
+
+
+Project started: 2013-09-12
+
+
+Goal: To accept INVITEs with crypto lifetime and MKI values
+Out of scope: To actually follow and honor the crypto lifetime
+ This may be part 2 of this project though
+
+
+Problem:
+========
+
+Chan_sip currently doesn't parse any key attributes in SDES negotiations,
+nor does it support multiple keys in the SDP. When receiving any attribute,
+chan_sip hangs up the call. This is obviously not a behaviour anyone wants.
+Generally, hanging up a call is considered bad behaviour.
+
+Current status:
+===============
+- We do accept lifetimes over 10 hours (hard coded, could be setting)
+- We only accept MKI number 1. Nothing else.
+- We handle no lifetime, only MKI or only lifetime too
+- We check that the lifetime is not too big
+- We check that the crypto tag is up to 9 characters only (should be checked for digits only at some point)
+- We reject everything with an option like FEC_ORDER
+
+tested with a few different a=crypto syntaxes below.
+
+SDES crypto attribute examples:
+==============================
+
+Syntax: from RFC 4568
+ a=crypto:<tag> <crypto-suite> <key-params> [<session-params>]
+
+For SDES the key-params starts with "inline:". There can be multiple key-params, separated
+with semi-colon.
+
+Example of a=crypto headers:
+a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32
+
+a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32
+
+THe lifetime can be ignored as this example (also from RFC 4568)
+ inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2|1066:4
+
+There can be multiple keys with different MKI values:
+
+a=crypto:2 F8_128_HMAC_SHA1_80
+ inline:MTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5QUJjZGVm|2^20|1:4;
+ inline:QUJjZGVmMTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5|2^20|2:4
+ FEC_ORDER=FEC_SRTP
+
+
+The MKI always have a colon. The lifetime parameter can be decimal.
Propchange: team/oej/teapot-1.8/README.lingon.txt
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/oej/teapot-1.8/README.lingon.txt
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/oej/teapot-1.8/README.lingon.txt
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: team/oej/teapot-1.8/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/teapot-1.8/channels/chan_sip.c?view=diff&rev=399444&r1=399443&r2=399444
==============================================================================
--- team/oej/teapot-1.8/channels/chan_sip.c (original)
+++ team/oej/teapot-1.8/channels/chan_sip.c Thu Sep 19 04:09:56 2013
@@ -6627,11 +6627,12 @@
} else { /* Incoming call, not up */
const char *res;
AST_SCHED_DEL_UNREF(sched, p->provisional_keepalive_sched_id, dialog_unref(p, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr"));
- ast_debug(2, "==> Hangupcause %d \n", p->hangupcause)
- if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause)))
+ ast_debug(2, "==> Hangupcause %d \n", p->hangupcause);
+ if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause))) {
transmit_response_reliable(p, res, &p->initreq);
- else
+ } else {
transmit_response_reliable(p, "603 Declined", &p->initreq);
+ }
p->invitestate = INV_TERMINATED;
}
} else { /* Call is in UP state, send BYE */
Modified: team/oej/teapot-1.8/channels/sip/sdp_crypto.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/teapot-1.8/channels/sip/sdp_crypto.c?view=diff&rev=399444&r1=399443&r2=399444
==============================================================================
--- team/oej/teapot-1.8/channels/sip/sdp_crypto.c (original)
+++ team/oej/teapot-1.8/channels/sip/sdp_crypto.c Thu Sep 19 04:09:56 2013
@@ -36,6 +36,7 @@
#include "asterisk/options.h"
#include "asterisk/utils.h"
#include "include/sdp_crypto.h"
+#include "math.h"
#define SRTP_MASTER_LEN 30
#define SRTP_MASTERKEY_LEN 16
@@ -197,12 +198,39 @@
char *key_params = NULL;
char *key_param = NULL;
char *session_params = NULL;
- char *key_salt = NULL;
- char *lifetime = NULL;
+ char *key_salt = NULL; /* The actual master key and key salt */
+ char *lifetime = NULL; /* Key lifetime (# of RTP packets) */
+ char *mki = NULL; /* Master Key Index */
int found = 0;
int key_len = 0;
int suite_val = 0;
unsigned char remote_key[SRTP_MASTER_LEN];
+ unsigned long sdeslifetime = 0;
+
+ /* Syntax: from RFC 4568
+ a=crypto:<tag> <crypto-suite> <key-params> [<session-params>]
+
+ for SDES the key-params starts with "inline:"
+
+Example of a=crypto headers:
+a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32
+
+a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32
+
+THe lifetime can be ignored as this example (also from RFC 4568)
+ inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2|1066:4
+
+There can be multiple keys with different MKI values:
+
+a=crypto:2 F8_128_HMAC_SHA1_80
+ inline:MTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5QUJjZGVm|2^20|1:4;
+ inline:QUJjZGVmMTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5|2^20|2:4
+ FEC_ORDER=FEC_SRTP
+
+SNOM sends without lifetime or MKI:
+a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:H5Yen2gCtRLey/IBGPjHeLLpbnivJDg6IjzvV3vZ
+
+ */
if (!ast_rtp_engine_srtp_is_registered()) {
return -1;
@@ -217,12 +245,18 @@
session_params = strsep(&str, " ");
if (!tag || !suite) {
- ast_log(LOG_WARNING, "Unrecognized a=%s", attr);
+ ast_log(LOG_WARNING, "Unrecognized a=%s\n", attr);
+ return -1;
+ }
+
+ /* Tags can be maxmimum 9 digits and not start with 0 */
+ if( strlen(tag) > 9 || tag[0] == '0') {
+ ast_log(LOG_WARNING, "Unacceptable a=crypto tag: %s\n ", tag);
return -1;
}
if (session_params) {
- ast_log(LOG_WARNING, "Unsupported crypto parameters: %s", session_params);
+ ast_log(LOG_WARNING, "Unsupported crypto parameters: %s\n", session_params);
return -1;
}
@@ -235,22 +269,64 @@
return -1;
}
+ /* Separate multiple key parameters and find one that works. */
while ((key_param = strsep(&key_params, ";"))) {
char *method = NULL;
char *info = NULL;
method = strsep(&key_param, ":");
info = strsep(&key_param, ";");
+ sdeslifetime = 0;
+
if (!strcmp(method, "inline")) {
+ /* This is a SDES key parameter. */
key_salt = strsep(&info, "|");
+
+ /* The next one can be either lifetime or MKI */
lifetime = strsep(&info, "|");
-
if (lifetime) {
- ast_log(LOG_NOTICE, "Crypto life time unsupported: %s\n", attr);
- continue;
+ /* Is this MKI? */
+ mki = strchr(lifetime, ':');
+ if (mki != NULL) {
+ mki = lifetime;
+ lifetime = NULL;
+ } else {
+ mki = strsep(&info, "|");
+ }
+ /* At this point we do not support multiple keys, sorry */
+ if (*mki != '1') {
+ ast_log(LOG_ERROR, "Crypto mki handling not implemented. MKI = %s \n", mki);
+ continue;
+ }
+
+
}
-
+
+ ast_debug(3, "==> SRTP SDES lifetime %s MKI %s \n", lifetime ? lifetime : "-", mki?mki : "-");
+
+ if (lifetime) {
+ if (strlen(lifetime) > 2) {
+ if (lifetime[0] == '2' && lifetime[1] == '^') {
+ sdeslifetime = (unsigned long) pow(2, atoi(&lifetime[2]));
+ } else {
+ sdeslifetime = (unsigned long) atoi(lifetime);
+ }
+ } else {
+ /* Decimal lifetime */
+ sdeslifetime = (unsigned int) atoi(lifetime);
+ }
+ if (sdeslifetime > pow(2, 48)) { /* Maximum lifetime for the crypto algorithms we do support */
+ ast_log(LOG_ERROR, "Crypto life time to big: %s Lifetime %lu \n", attr, sdeslifetime);
+ continue;
+ }
+ /* 1,800,000 in lifetime is 10 hours. Anything above that is acceptable. */
+ if (sdeslifetime < 1800000) {
+ ast_log(LOG_ERROR, "Crypto life time to short: %s Lifetime %lu \n", attr, sdeslifetime);
+ continue;
+ }
+ ast_debug(2, "Crypto life time accepted: %s Lifetime %lu \n", attr, sdeslifetime);
+ }
found = 1;
break;
}
@@ -280,7 +356,7 @@
}
if (!p->tag) {
- ast_log(LOG_DEBUG, "Accepting crypto tag %s\n", tag);
+ ast_debug(2, "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");
@@ -310,7 +386,7 @@
return -1;
}
- ast_log(LOG_DEBUG, "Crypto line: %s", p->a_crypto);
+ ast_debug(2, "Crypto line: %s", p->a_crypto);
return 0;
}
Added: team/oej/teapot-1.8/patches/lingon-srtp-key-lifetime-1.8.diff
URL: http://svnview.digium.com/svn/asterisk/team/oej/teapot-1.8/patches/lingon-srtp-key-lifetime-1.8.diff?view=auto&rev=399444
==============================================================================
--- team/oej/teapot-1.8/patches/lingon-srtp-key-lifetime-1.8.diff (added)
+++ team/oej/teapot-1.8/patches/lingon-srtp-key-lifetime-1.8.diff Thu Sep 19 04:09:56 2013
@@ -1,0 +1,235 @@
+Index: channels/sip/sdp_crypto.c
+===================================================================
+--- channels/sip/sdp_crypto.c (.../branches/1.8) (revision 399443)
++++ channels/sip/sdp_crypto.c (.../team/oej/lingon-srtp-key-lifetime-1.8) (revision 399443)
+@@ -36,6 +36,7 @@
+ #include "asterisk/options.h"
+ #include "asterisk/utils.h"
+ #include "include/sdp_crypto.h"
++#include "math.h"
+
+ #define SRTP_MASTER_LEN 30
+ #define SRTP_MASTERKEY_LEN 16
+@@ -197,13 +198,40 @@
+ char *key_params = NULL;
+ char *key_param = NULL;
+ char *session_params = NULL;
+- char *key_salt = NULL;
+- char *lifetime = NULL;
++ char *key_salt = NULL; /* The actual master key and key salt */
++ char *lifetime = NULL; /* Key lifetime (# of RTP packets) */
++ char *mki = NULL; /* Master Key Index */
+ int found = 0;
+ int key_len = 0;
+ int suite_val = 0;
+ unsigned char remote_key[SRTP_MASTER_LEN];
++ unsigned long sdeslifetime = 0;
+
++ /* Syntax: from RFC 4568
++ a=crypto:<tag> <crypto-suite> <key-params> [<session-params>]
++
++ for SDES the key-params starts with "inline:"
++
++Example of a=crypto headers:
++a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32
++
++a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32
++
++THe lifetime can be ignored as this example (also from RFC 4568)
++ inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2|1066:4
++
++There can be multiple keys with different MKI values:
++
++a=crypto:2 F8_128_HMAC_SHA1_80
++ inline:MTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5QUJjZGVm|2^20|1:4;
++ inline:QUJjZGVmMTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5|2^20|2:4
++ FEC_ORDER=FEC_SRTP
++
++SNOM sends without lifetime or MKI:
++a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:H5Yen2gCtRLey/IBGPjHeLLpbnivJDg6IjzvV3vZ
++
++ */
++
+ if (!ast_rtp_engine_srtp_is_registered()) {
+ return -1;
+ }
+@@ -217,12 +245,18 @@
+ session_params = strsep(&str, " ");
+
+ if (!tag || !suite) {
+- ast_log(LOG_WARNING, "Unrecognized a=%s", attr);
++ ast_log(LOG_WARNING, "Unrecognized a=%s\n", attr);
+ return -1;
+ }
+
++ /* Tags can be maxmimum 9 digits and not start with 0 */
++ if( strlen(tag) > 9 || tag[0] == '0') {
++ ast_log(LOG_WARNING, "Unacceptable a=crypto tag: %s\n ", tag);
++ return -1;
++ }
++
+ if (session_params) {
+- ast_log(LOG_WARNING, "Unsupported crypto parameters: %s", session_params);
++ ast_log(LOG_WARNING, "Unsupported crypto parameters: %s\n", session_params);
+ return -1;
+ }
+
+@@ -235,22 +269,64 @@
+ return -1;
+ }
+
++ /* Separate multiple key parameters and find one that works. */
+ while ((key_param = strsep(&key_params, ";"))) {
+ char *method = NULL;
+ char *info = NULL;
+
+ method = strsep(&key_param, ":");
+ info = strsep(&key_param, ";");
++ sdeslifetime = 0;
+
++
+ if (!strcmp(method, "inline")) {
++ /* This is a SDES key parameter. */
+ key_salt = strsep(&info, "|");
++
++ /* The next one can be either lifetime or MKI */
+ lifetime = strsep(&info, "|");
++ if (lifetime) {
++ /* Is this MKI? */
++ mki = strchr(lifetime, ':');
++ if (mki != NULL) {
++ mki = lifetime;
++ lifetime = NULL;
++ } else {
++ mki = strsep(&info, "|");
++ }
++ /* At this point we do not support multiple keys, sorry */
++ if (*mki != '1') {
++ ast_log(LOG_ERROR, "Crypto mki handling not implemented. MKI = %s \n", mki);
++ continue;
++ }
++
+
++ }
++
++ ast_debug(3, "==> SRTP SDES lifetime %s MKI %s \n", lifetime ? lifetime : "-", mki?mki : "-");
++
+ if (lifetime) {
+- ast_log(LOG_NOTICE, "Crypto life time unsupported: %s\n", attr);
+- continue;
++ if (strlen(lifetime) > 2) {
++ if (lifetime[0] == '2' && lifetime[1] == '^') {
++ sdeslifetime = (unsigned long) pow(2, atoi(&lifetime[2]));
++ } else {
++ sdeslifetime = (unsigned long) atoi(lifetime);
++ }
++ } else {
++ /* Decimal lifetime */
++ sdeslifetime = (unsigned int) atoi(lifetime);
++ }
++ if (sdeslifetime > pow(2, 48)) { /* Maximum lifetime for the crypto algorithms we do support */
++ ast_log(LOG_ERROR, "Crypto life time to big: %s Lifetime %lu \n", attr, sdeslifetime);
++ continue;
++ }
++ /* 1,800,000 in lifetime is 10 hours. Anything above that is acceptable. */
++ if (sdeslifetime < 1800000) {
++ ast_log(LOG_ERROR, "Crypto life time to short: %s Lifetime %lu \n", attr, sdeslifetime);
++ continue;
++ }
++ ast_debug(2, "Crypto life time accepted: %s Lifetime %lu \n", attr, sdeslifetime);
+ }
+-
+ found = 1;
+ break;
+ }
+@@ -280,7 +356,7 @@
+ }
+
+ if (!p->tag) {
+- ast_log(LOG_DEBUG, "Accepting crypto tag %s\n", tag);
++ ast_debug(2, "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");
+@@ -310,7 +386,7 @@
+ return -1;
+ }
+
+- ast_log(LOG_DEBUG, "Crypto line: %s", p->a_crypto);
++ ast_debug(2, "Crypto line: %s", p->a_crypto);
+
+ return 0;
+ }
+Index: README.lingon.txt
+===================================================================
+--- README.lingon.txt (.../branches/1.8) (revision 0)
++++ README.lingon.txt (.../team/oej/lingon-srtp-key-lifetime-1.8) (revision 399443)
+@@ -0,0 +1,57 @@
++Edvina AB
++Olle E. Johansson
++
++
++Project started: 2013-09-12
++
++
++Goal: To accept INVITEs with crypto lifetime and MKI values
++Out of scope: To actually follow and honor the crypto lifetime
++ This may be part 2 of this project though
++
++
++Problem:
++========
++
++Chan_sip currently doesn't parse any key attributes in SDES negotiations,
++nor does it support multiple keys in the SDP. When receiving any attribute,
++chan_sip hangs up the call. This is obviously not a behaviour anyone wants.
++Generally, hanging up a call is considered bad behaviour.
++
++Current status:
++===============
++- We do accept lifetimes over 10 hours (hard coded, could be setting)
++- We only accept MKI number 1. Nothing else.
++- We handle no lifetime, only MKI or only lifetime too
++- We check that the lifetime is not too big
++- We check that the crypto tag is up to 9 characters only (should be checked for digits only at some point)
++- We reject everything with an option like FEC_ORDER
++
++tested with a few different a=crypto syntaxes below.
++
++SDES crypto attribute examples:
++==============================
++
++Syntax: from RFC 4568
++ a=crypto:<tag> <crypto-suite> <key-params> [<session-params>]
++
++For SDES the key-params starts with "inline:". There can be multiple key-params, separated
++with semi-colon.
++
++Example of a=crypto headers:
++a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32
++
++a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32
++
++THe lifetime can be ignored as this example (also from RFC 4568)
++ inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2|1066:4
++
++There can be multiple keys with different MKI values:
++
++a=crypto:2 F8_128_HMAC_SHA1_80
++ inline:MTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5QUJjZGVm|2^20|1:4;
++ inline:QUJjZGVmMTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5|2^20|2:4
++ FEC_ORDER=FEC_SRTP
++
++
++The MKI always have a colon. The lifetime parameter can be decimal.
+
+Property changes on: README.lingon.txt
+___________________________________________________________________
+Added: svn:eol-style
+ + native
+Added: svn:mime-type
+ + text/plain
+Added: svn:keywords
+ + Author Date Id Revision
+
+
Propchange: team/oej/teapot-1.8/patches/lingon-srtp-key-lifetime-1.8.diff
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/oej/teapot-1.8/patches/lingon-srtp-key-lifetime-1.8.diff
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/oej/teapot-1.8/patches/lingon-srtp-key-lifetime-1.8.diff
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the asterisk-commits
mailing list