[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