[asterisk-commits] branch oej/securertp-trunk r34459 - in /team/oej/securertp-trunk: ./ build_to...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Fri Jun 16 05:23:00 MST 2006


Author: oej
Date: Fri Jun 16 07:22:59 2006
New Revision: 34459

URL: http://svn.digium.com/view/asterisk?rev=34459&view=rev
Log:
Update from Mikael Magnusson
This now compiles ok and is ready for heavy testing!!!

Added:
    team/oej/securertp-trunk/res/res_srtp.c   (with props)
Modified:
    team/oej/securertp-trunk/Makefile
    team/oej/securertp-trunk/build_tools/menuselect-deps.in
    team/oej/securertp-trunk/channels/chan_sip.c
    team/oej/securertp-trunk/configure.ac
    team/oej/securertp-trunk/include/asterisk/aes.h
    team/oej/securertp-trunk/include/asterisk/rtp.h
    team/oej/securertp-trunk/makeopts.in
    team/oej/securertp-trunk/rtp.c
    team/oej/securertp-trunk/utils.c

Modified: team/oej/securertp-trunk/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/securertp-trunk/Makefile?rev=34459&r1=34458&r2=34459&view=diff
==============================================================================
--- team/oej/securertp-trunk/Makefile (original)
+++ team/oej/securertp-trunk/Makefile Fri Jun 16 07:22:59 2006
@@ -415,6 +415,12 @@
 
 db1-ast/libdb1.a:
 	$(MAKE) -C db1-ast libdb1.a
+
+res_srtp.so: res_srtp.o
+	$(CC) $(SOLINK) -o $@ $(CFLAGS) $(SRTP_INCLUDE) $< $(SRTP_LIB)
+
+res_srtp.so: res_srtp.o
+	$(CC) $(SOLINK) -o $@ $(CFLAGS) $(SRTP_INCLUDE) $< $(SRTP_LIB)
 
 ifneq ($(wildcard .depend),)
   include .depend

Modified: team/oej/securertp-trunk/build_tools/menuselect-deps.in
URL: http://svn.digium.com/view/asterisk/team/oej/securertp-trunk/build_tools/menuselect-deps.in?rev=34459&r1=34458&r2=34459&view=diff
==============================================================================
--- team/oej/securertp-trunk/build_tools/menuselect-deps.in (original)
+++ team/oej/securertp-trunk/build_tools/menuselect-deps.in Fri Jun 16 07:22:59 2006
@@ -26,3 +26,4 @@
 LIBGSM=@PBX_LIBgsm@
 IKSEMEL=@PBX_LIBIKSEMEL@
 IXJUSER=@PBX_IXJUSER@
+LIBSRTP=@PBX_LIBSRTP@

Modified: team/oej/securertp-trunk/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/securertp-trunk/channels/chan_sip.c?rev=34459&r1=34458&r2=34459&view=diff
==============================================================================
--- team/oej/securertp-trunk/channels/chan_sip.c (original)
+++ team/oej/securertp-trunk/channels/chan_sip.c Fri Jun 16 07:22:59 2006
@@ -168,8 +168,12 @@
 #define SRTP_MASTERSALT_LEN (SRTP_MASTER_LEN - SRTP_MASTERKEY_LEN)
 #define SRTP_MASTER_LEN64 ((SRTP_MASTER_LEN * 8 + 5) / 6 + 1)
 
+/* SRTP flags */
+#define SRTP_ENCR_OPTIONAL	1	/* SRTP encryption optional */
+
 /*! \brief structure for secure RTP audio */
 struct sip_srtp {
+	unsigned int flags;
 	char *a_crypto;
 	unsigned char local_key[SRTP_MASTER_LEN];
 	char local_key64[SRTP_MASTER_LEN64];
@@ -2676,7 +2680,6 @@
 		} else if (!strcasecmp(ast_var_name(current),"SIPTRANSFER_REPLACES")) {
 			/* We're replacing a call. */
 			p->options->replaces = ast_var_value(current);
-<<<<<<< .working
 		} else if (!strncasecmp(ast_var_name(current), "SIP_SRTP_SDES", strlen("SIP_SRTP_SDES"))) {
 			if (!ast_srtp_is_registered()) {
 				ast_log(LOG_WARNING, "SIP_SRTP_SDES set but SRTP is not available\n");
@@ -2688,13 +2691,16 @@
 					ast_log(LOG_WARNING, "SIP SRTP sdes setup failed\n");
 					return -1;
 				}
-			}
-=======
+
+				if (!strcasecmp(ast_var_value(current), "optional")) {
+					ast_set_flag(p->srtp, SRTP_ENCR_OPTIONAL);
+				}
+
+			}
 		} else if (!strcasecmp(ast_var_name(current),"T38CALL")) {
 			p->t38.state = T38_LOCAL_DIRECT;
 			if (option_debug)
 				ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
->>>>>>> .merge-right.r34043
 		}
 
 	}
@@ -4552,9 +4558,9 @@
 	while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') {
 		int x;
 		int audio = FALSE;
+		char protocol[5] = "";
+
 		len = -1;
-		char protocol[5] = "";
-
 		numberofmediastreams++;
 
 		if (p->vrtp)
@@ -4753,15 +4759,11 @@
 		ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype);
 		if (p->vrtp)
 			ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype);
-
-		if (secure_audio && !(p->srtp && p->srtp->a_crypto)) {
-			ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n");
-			return -2;
-		}
-		if (secure_video && !(p->srtp && p->srtp->a_crypto)) {
-			ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n");
-			return -2;
-		}
+	}
+
+	if (secure_audio && !(p->srtp && p->srtp->a_crypto)) {
+		ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n");
+		return -2;
 	}
 	
 	if (udptlportno != -1) {
@@ -4879,6 +4881,11 @@
 		p->t38.state = T38_DISABLED;
 		if (option_debug > 1)
 			ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
+	}
+
+	if (secure_video && !(p->srtp && p->srtp->a_crypto)) {
+		ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n");
+		return -2;
 	}
 
 	/* Now gather all of the codecs that we are asked for: */
@@ -5813,6 +5820,7 @@
 	struct sip_srtp *srtp = p->srtp;
 	int needvideo = FALSE;
 	int debug = sip_debug_test_pvt(p);
+	const char a_encr_optional[] = "a=encryption:optional\r\n";
 
 	m_video[0] = '\0';	/* Reset the video media string if it's not needed */
 
@@ -5881,13 +5889,13 @@
 		}
 	}
 
-	if (a_crypto) {
+	if (a_crypto && !ast_test_flag(srtp, SRTP_ENCR_OPTIONAL)) {
 		protocol = "SAVP";
 	} else {
 		protocol = "AVP";
 	}
 
-		
+	
 
 	/* 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. */
@@ -6036,8 +6044,12 @@
 	if (needvideo) /* only if video response is appropriate */
 		len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold);
 
-	if (a_crypto)
+	if (a_crypto) {
 		len += strlen(a_crypto);
+		if (ast_test_flag(srtp, SRTP_ENCR_OPTIONAL)) {
+			len += strlen(a_encr_optional);
+		}
+	}
 
 	add_header(resp, "Content-Type", "application/sdp");
 	add_header_contentLength(resp, len);
@@ -6050,8 +6062,12 @@
 	add_line(resp, stime);
 	add_line(resp, m_audio);
 	add_line(resp, a_audio);
-	if (a_crypto)
-		len += strlen(a_crypto);
+	if (a_crypto) {
+		add_line(resp, a_crypto);
+		if (ast_test_flag(srtp, SRTP_ENCR_OPTIONAL)) {
+			add_line(resp, a_encr_optional);
+		}
+	}
 	add_line(resp, hold);
 	if (needvideo) { /* only if video response is appropriate */
 		add_line(resp, m_video);
@@ -16479,6 +16495,11 @@
 	if (!ast_srtp_is_registered())
 		return -1;
 
+	if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !srtp) {
+		ast_log(LOG_WARNING, "Ignoring unexpected crypto attribute in SDP answer\n");
+		return -1;
+	}
+
 	/* Crypto already accepted */
 	if (srtp && srtp->a_crypto)
 		return -1;

Modified: team/oej/securertp-trunk/configure.ac
URL: http://svn.digium.com/view/asterisk/team/oej/securertp-trunk/configure.ac?rev=34459&r1=34458&r2=34459&view=diff
==============================================================================
--- team/oej/securertp-trunk/configure.ac (original)
+++ team/oej/securertp-trunk/configure.ac Fri Jun 16 07:22:59 2006
@@ -213,6 +213,7 @@
 AST_EXT_LIB([tinfo], [tgetent], [], [TINFO], [Term Info])
 AST_EXT_LIB([vorbis], [vorbis_info_init], [vorbis/codec.h], [VORBIS], [Vorbis], [-lm -lvorbisenc])
 AST_EXT_LIB([z], [compress], [zlib.h], [ZLIB], [zlib])
+AST_EXT_LIB([srtp], [srtp_init], [srtp/srtp.h], [SRTP], [libSRTP])
 
 EDITLINE_LIBS=""
 if test "x$TERMCAP_LIB" != "x" ; then

Modified: team/oej/securertp-trunk/include/asterisk/aes.h
URL: http://svn.digium.com/view/asterisk/team/oej/securertp-trunk/include/asterisk/aes.h?rev=34459&r1=34458&r2=34459&view=diff
==============================================================================
--- team/oej/securertp-trunk/include/asterisk/aes.h (original)
+++ team/oej/securertp-trunk/include/asterisk/aes.h Fri Jun 16 07:22:59 2006
@@ -115,6 +115,8 @@
 
 #ifdef  AES_ENCRYPT
 
+#define aes_encrypt ast_aes_encrypt
+
 typedef struct  
 {   aes_32t ks[KS_LENGTH];
 } aes_encrypt_ctx;
@@ -139,6 +141,8 @@
 #endif
 
 #ifdef AES_DECRYPT
+
+#define aes_decrypt ast_aes_decrypt
 
 typedef struct  
 {   aes_32t ks[KS_LENGTH];

Modified: team/oej/securertp-trunk/include/asterisk/rtp.h
URL: http://svn.digium.com/view/asterisk/team/oej/securertp-trunk/include/asterisk/rtp.h?rev=34459&r1=34458&r2=34459&view=diff
==============================================================================
--- team/oej/securertp-trunk/include/asterisk/rtp.h (original)
+++ team/oej/securertp-trunk/include/asterisk/rtp.h Fri Jun 16 07:22:59 2006
@@ -133,6 +133,7 @@
 };
 
 
+/*!
  * \brief Get the amount of space required to hold an RTP session
  * \return number of bytes required
  */

Modified: team/oej/securertp-trunk/makeopts.in
URL: http://svn.digium.com/view/asterisk/team/oej/securertp-trunk/makeopts.in?rev=34459&r1=34458&r2=34459&view=diff
==============================================================================
--- team/oej/securertp-trunk/makeopts.in (original)
+++ team/oej/securertp-trunk/makeopts.in Fri Jun 16 07:22:59 2006
@@ -123,3 +123,6 @@
 
 RADIUSCLIENT_LIB=@RADIUSCLIENT_LIB@
 RADIUSCLIENT_INCLUDE=@RADIUSCLIENT_INCLUDE@
+
+SRTP_LIB=@SRTP_LIB@
+SRTP_INCLUDE=@SRTP_INCLUDE@

Added: team/oej/securertp-trunk/res/res_srtp.c
URL: http://svn.digium.com/view/asterisk/team/oej/securertp-trunk/res/res_srtp.c?rev=34459&view=auto
==============================================================================
--- team/oej/securertp-trunk/res/res_srtp.c (added)
+++ team/oej/securertp-trunk/res/res_srtp.c Fri Jun 16 07:22:59 2006
@@ -1,0 +1,554 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2005, Mikael Magnusson
+ *
+ * Mikael Magnusson <mikma at users.sourceforge.net>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ * 
+ * Builds on libSRTP http://srtp.sourceforge.net
+ */
+
+
+/*! \file res_srtp.c 
+ *
+ * \brief Secure RTP (SRTP)
+ * 
+ * Secure RTP (SRTP) 
+ * Specified in RFC 3711.
+ * 
+ * \author Mikael Magnusson <mikma at users.sourceforge.net>
+ */
+
+/* The SIP channel will automatically use sdescriptions if received in a SDP offer, 
+   and res_srtp is loaded. SRTP with sdescriptions key exchange can be activated 
+  in outgoing offers by setting _SIP_SRTP_SDES=1 in extension.conf before executing Dial
+
+  The dial fails if the callee doesn't support SRTP and sdescriptions.
+
+  exten => 2345,1,Set(_SIP_SRTP_SDES=1)
+  exten => 2345,2,Dial(SIP/1001)
+
+  NOTE: Since chan_sip does not support TLS, this is just a first step
+  towards a secure channel. At this moment, all key exchange will be sent
+  in clear text, making it easy to eavesdrop.
+*/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include <srtp/srtp.h>
+
+#include "asterisk/lock.h"
+#include "asterisk/module.h"
+#include "asterisk/options.h"
+#include "asterisk/rtp.h"
+
+struct ast_srtp {
+	struct ast_rtp *rtp;
+	srtp_t session;
+	const struct ast_srtp_cb *cb;
+	void *data;
+	unsigned char buf[8192 + AST_FRIENDLY_OFFSET];
+};
+
+struct ast_srtp_policy {
+	srtp_policy_t sp;
+};
+
+static const char desc[] = "Secure RTP (SRTP)";
+static int srtpdebug = 1;
+static int g_initialized = 0;
+
+/* Exported functions */
+int usecount(void);
+
+/* SRTP functions */
+static int res_srtp_create(struct ast_srtp **srtp,
+			   struct ast_rtp *rtp,
+			   struct ast_srtp_policy *policy);
+static void res_srtp_destroy(struct ast_srtp *srtp);
+static int res_srtp_add_stream(struct ast_srtp *srtp,
+			       struct ast_srtp_policy *policy);
+
+static int res_srtp_unprotect(struct ast_srtp *srtp, void *buf, int *len);
+static int res_srtp_protect(struct ast_srtp *srtp, void **buf, int *len);
+static int res_srtp_get_random(unsigned char *key, size_t len);
+static void res_srtp_set_cb(struct ast_srtp *srtp,
+			    const struct ast_srtp_cb *cb, void *data);
+
+/* Policy functions */
+static struct ast_srtp_policy *res_srtp_policy_alloc(void);
+static void res_srtp_policy_destroy(struct ast_srtp_policy *policy);
+static int res_srtp_policy_set_suite(struct ast_srtp_policy *policy,
+				     enum ast_srtp_suite suite);
+static int res_srtp_policy_set_master_key(struct ast_srtp_policy *policy,
+			      const unsigned char *key, size_t key_len,
+			      const unsigned char *salt, size_t salt_len);
+static int res_srtp_policy_set_encr_alg(struct ast_srtp_policy *policy,
+					enum ast_srtp_ealg ealg);
+static int res_srtp_policy_set_auth_alg(struct ast_srtp_policy *policy,
+					enum ast_srtp_aalg aalg);
+static void res_srtp_policy_set_encr_keylen(struct ast_srtp_policy *policy,
+					    int ekeyl);
+static void res_srtp_policy_set_auth_keylen(struct ast_srtp_policy *policy,
+					    int akeyl);
+static void res_srtp_policy_set_srtp_auth_taglen(struct ast_srtp_policy *policy,
+						 int autht);
+static void res_srtp_policy_set_srtp_encr_enable(struct ast_srtp_policy *policy,
+						 int enable);
+static void res_srtp_policy_set_srtcp_encr_enable(struct ast_srtp_policy *policy,
+						  int enable);
+static void res_srtp_policy_set_srtp_auth_enable(struct ast_srtp_policy *policy,
+						 int enable);
+static void res_srtp_policy_set_ssrc(struct ast_srtp_policy *policy,
+				     unsigned long ssrc, int inbound);
+
+static struct ast_srtp_res srtp_res = {
+	.create = res_srtp_create,
+	.destroy = res_srtp_destroy,
+	.add_stream = res_srtp_add_stream,
+	.set_cb = res_srtp_set_cb,
+	.unprotect = res_srtp_unprotect,
+	.protect = res_srtp_protect,
+	.get_random = res_srtp_get_random
+};
+
+static struct ast_srtp_policy_res policy_res = {
+	.alloc = res_srtp_policy_alloc,
+	.destroy = res_srtp_policy_destroy,
+	.set_suite = res_srtp_policy_set_suite,
+	.set_master_key = res_srtp_policy_set_master_key,
+	.set_encr_alg = res_srtp_policy_set_encr_alg,
+	.set_auth_alg = res_srtp_policy_set_auth_alg,
+	.set_encr_keylen = res_srtp_policy_set_encr_keylen,
+	.set_auth_keylen = res_srtp_policy_set_auth_keylen,
+	.set_srtp_auth_taglen = res_srtp_policy_set_srtp_auth_taglen,
+	.set_srtp_encr_enable = res_srtp_policy_set_srtp_encr_enable,
+	.set_srtcp_encr_enable = res_srtp_policy_set_srtcp_encr_enable,
+	.set_srtp_auth_enable = res_srtp_policy_set_srtp_auth_enable,
+	.set_ssrc = res_srtp_policy_set_ssrc
+};
+
+static const char *srtp_errstr(int err)
+{
+	switch(err) {
+	case err_status_ok:
+		return "nothing to report";
+	case err_status_fail:
+		return "unspecified failure";
+	case err_status_bad_param:
+		return "unsupported parameter";
+	case err_status_alloc_fail:
+		return "couldn't allocate memory";
+	case err_status_dealloc_fail:
+		return "couldn't deallocate properly";
+	case err_status_init_fail:
+		return "couldn't initialize";
+	case err_status_terminus:
+		return "can't process as much data as requested";
+	case err_status_auth_fail:
+		return "authentication failure";
+	case err_status_cipher_fail:
+		return "cipher failure";
+	case err_status_replay_fail:
+		return "replay check failed (bad index)";
+	case err_status_replay_old:
+		return "replay check failed (index too old)";
+	case err_status_algo_fail:
+		return "algorithm failed test routine";
+	case err_status_no_such_op:
+		return "unsupported operation";
+	case err_status_no_ctx:
+		return "no appropriate context found";
+	case err_status_cant_check:
+		return "unable to perform desired validation";
+	case err_status_key_expired:
+		return "can't use key any more";
+	default:
+		return "unknown";
+	}
+}
+
+static struct ast_srtp *res_srtp_new(void)
+{
+	struct ast_srtp *srtp = malloc(sizeof(*srtp));
+	memset(srtp, 0, sizeof(*srtp));
+	return srtp;
+}
+
+/*
+  struct ast_srtp_policy
+*/
+static void srtp_event_cb(srtp_event_data_t *data)
+{
+	switch (data->event) {
+	case event_ssrc_collision: {
+		if (option_debug || srtpdebug) {
+			ast_log(LOG_DEBUG, "SSRC collision ssrc:%u dir:%d\n",
+				ntohl(data->stream->ssrc),
+				data->stream->direction);
+		}
+		break;
+	}
+	case event_key_soft_limit: {
+		if (option_debug || srtpdebug) {
+			ast_log(LOG_DEBUG, "event_key_soft_limit\n");
+		}
+		break;
+	}
+	case event_key_hard_limit: {
+		if (option_debug || srtpdebug) {
+			ast_log(LOG_DEBUG, "event_key_hard_limit\n");
+		}
+		break;
+	}
+	case event_packet_index_limit: {
+		if (option_debug || srtpdebug) {
+			ast_log(LOG_DEBUG, "event_packet_index_limit\n");
+		}
+		break;
+	}
+	}
+}
+
+static void res_srtp_policy_set_ssrc(struct ast_srtp_policy *policy,
+				     unsigned long ssrc, int inbound)
+{
+	if (ssrc) {
+		policy->sp.ssrc.type = ssrc_specific;
+		policy->sp.ssrc.value = ssrc;
+	} else {
+		policy->sp.ssrc.type =
+			inbound ? ssrc_any_inbound : ssrc_any_outbound;
+	}
+}
+
+static struct ast_srtp_policy *res_srtp_policy_alloc()
+{
+	struct ast_srtp_policy *tmp = malloc(sizeof(*tmp));
+
+	memset(tmp, 0, sizeof(*tmp));
+	return tmp;
+}
+
+static void res_srtp_policy_destroy(struct ast_srtp_policy *policy)
+{
+	if (policy->sp.key) {
+		free(policy->sp.key);
+		policy->sp.key = NULL;
+	}
+	free(policy);
+}
+
+static int policy_set_suite(crypto_policy_t *p, enum ast_srtp_suite suite)
+{
+	switch (suite) {
+	case AST_AES_CM_128_HMAC_SHA1_80:
+		p->cipher_type = AES_128_ICM;
+		p->cipher_key_len = 30;
+		p->auth_type = HMAC_SHA1;
+		p->auth_key_len = 20;
+		p->auth_tag_len = 10;
+		p->sec_serv = sec_serv_conf_and_auth;
+		return 0;
+
+	case AST_AES_CM_128_HMAC_SHA1_32:
+		p->cipher_type = AES_128_ICM;
+		p->cipher_key_len = 30;
+		p->auth_type = HMAC_SHA1;
+		p->auth_key_len = 20;
+		p->auth_tag_len = 4;
+		p->sec_serv = sec_serv_conf_and_auth;
+		return 0;
+
+	default:
+		ast_log(LOG_ERROR, "Invalid crypto suite: %d\n", suite);
+		return -1;
+	}
+}
+
+static int res_srtp_policy_set_suite(struct ast_srtp_policy *policy,
+			  enum ast_srtp_suite suite)
+{
+	int res = policy_set_suite(&policy->sp.rtp, suite) |
+		policy_set_suite(&policy->sp.rtcp, suite);
+
+	return res;
+}
+
+static int res_srtp_policy_set_master_key(struct ast_srtp_policy *policy,
+			       const unsigned char *key, size_t key_len,
+			       const unsigned char *salt, size_t salt_len)
+{
+	size_t size = key_len + salt_len;
+	unsigned char *master_key = NULL;
+
+	if (policy->sp.key) {
+		free(policy->sp.key);
+		policy->sp.key = NULL;
+	}
+
+	master_key = malloc(size);
+
+	memcpy(master_key, key, key_len);
+	memcpy(master_key + key_len, salt, salt_len);
+
+	policy->sp.key = master_key;
+	return 0;
+}
+
+static int res_srtp_policy_set_encr_alg(struct ast_srtp_policy *policy,
+			     enum ast_srtp_ealg ealg)
+{
+	int type = -1;
+
+	switch (ealg) {
+	case AST_MIKEY_SRTP_EALG_NULL:
+		type = NULL_CIPHER;
+		break;
+	case AST_MIKEY_SRTP_EALG_AESCM:
+		type = AES_128_ICM;
+		break;
+	default:
+		return -1;
+	}
+
+	policy->sp.rtp.cipher_type = type;
+	policy->sp.rtcp.cipher_type = type;
+	return 0;
+}
+
+static int res_srtp_policy_set_auth_alg(struct ast_srtp_policy *policy,
+			     enum ast_srtp_aalg aalg)
+{
+	int type = -1;
+
+	switch (aalg) {
+	case AST_MIKEY_SRTP_AALG_NULL:
+		type = NULL_AUTH;
+		break;
+	case AST_MIKEY_SRTP_AALG_SHA1HMAC:
+		type = HMAC_SHA1;
+		break;
+	default:
+		return -1;
+	}
+
+	policy->sp.rtp.auth_type = type;
+	policy->sp.rtcp.auth_type = type;
+	return 0;
+}
+
+static void res_srtp_policy_set_encr_keylen(struct ast_srtp_policy *policy, int ekeyl)
+{
+	policy->sp.rtp.cipher_key_len = ekeyl;
+	policy->sp.rtcp.cipher_key_len = ekeyl;
+}
+
+static void res_srtp_policy_set_auth_keylen(struct ast_srtp_policy *policy, int akeyl)
+{
+	policy->sp.rtp.auth_key_len = akeyl;
+	policy->sp.rtcp.auth_key_len = akeyl;
+}
+
+static void res_srtp_policy_set_srtp_auth_taglen(struct ast_srtp_policy *policy, int autht)
+{
+	policy->sp.rtp.auth_tag_len = autht;
+	policy->sp.rtcp.auth_tag_len = autht;
+	
+}
+
+static void res_srtp_policy_set_srtp_encr_enable(struct ast_srtp_policy *policy, int enable)
+{
+	int serv = enable ? sec_serv_conf : sec_serv_none;
+	policy->sp.rtp.sec_serv = 
+		(policy->sp.rtp.sec_serv & ~sec_serv_conf) | serv;
+}
+
+static void res_srtp_policy_set_srtcp_encr_enable(struct ast_srtp_policy *policy, int enable)
+{
+	int serv = enable ? sec_serv_conf : sec_serv_none;
+	policy->sp.rtcp.sec_serv = 
+		(policy->sp.rtcp.sec_serv & ~sec_serv_conf) | serv;
+}
+
+static void res_srtp_policy_set_srtp_auth_enable(struct ast_srtp_policy *policy, int enable)
+{
+	int serv = enable ? sec_serv_auth : sec_serv_none;
+	policy->sp.rtp.sec_serv = 
+		(policy->sp.rtp.sec_serv & ~sec_serv_auth) | serv;
+}
+
+
+static int res_srtp_get_random(unsigned char *key, size_t len)
+{
+	int res = crypto_get_random(key, len);
+
+	return res != err_status_ok ? -1: 0;
+}
+
+static void res_srtp_set_cb(struct ast_srtp *srtp,
+			    const struct ast_srtp_cb *cb, void *data)
+{
+	if (!srtp)
+		return;
+	
+	srtp->cb = cb;
+	srtp->data = data;
+}
+
+
+/* Vtable functions */
+
+static int res_srtp_unprotect(struct ast_srtp *srtp, void *buf, int *len)
+{
+	int res = 0;
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		srtp_hdr_t *header = buf;
+		
+		res = srtp_unprotect(srtp->session, buf, len);
+		if (res != err_status_no_ctx)
+			break;
+		
+		if (srtp->cb && srtp->cb->no_ctx) {
+			if (srtp->cb->no_ctx(srtp->rtp, ntohl(header->ssrc), srtp->data) < 0) {
+				break;
+			}
+			
+		} else {
+			break;
+		}
+	}
+	
+	if (res != err_status_ok) {
+		if (option_debug || srtpdebug) {
+			ast_log(LOG_DEBUG, "SRTP unprotect: %s\n",
+				 srtp_errstr(res));
+		}
+		return -1;
+	}
+
+	return *len;
+}
+
+static int res_srtp_protect(struct ast_srtp *srtp, void **buf, int *len)
+{
+	int res = 0;
+
+	if ((*len + SRTP_MAX_TRAILER_LEN) > sizeof(srtp->buf))
+		return -1;
+
+	memcpy(srtp->buf, *buf, *len);
+
+	res = srtp_protect(srtp->session, srtp->buf, len);
+
+	if (res != err_status_ok) {
+		if (option_debug || srtpdebug) {
+			ast_log(LOG_DEBUG, "SRTP protect: %s\n",
+				 srtp_errstr(res));
+		}
+		return -1;
+	}
+
+	*buf = srtp->buf;
+	return *len;
+}
+
+static int res_srtp_create(struct ast_srtp **srtp, struct ast_rtp *rtp,
+		struct ast_srtp_policy *policy)
+{
+	int res;
+	struct ast_srtp *temp = res_srtp_new();
+
+	res = srtp_create(&temp->session, &policy->sp);
+	if (res != err_status_ok) {
+		return -1;
+	}
+	
+	temp->rtp = rtp;
+	*srtp = temp;
+
+	return 0;
+}
+
+static void res_srtp_destroy(struct ast_srtp *srtp)
+{
+	if (srtp->session) {
+		srtp_dealloc(srtp->session);
+	}
+
+	free(srtp);
+}
+
+static int res_srtp_add_stream(struct ast_srtp *srtp, struct ast_srtp_policy *policy)
+{
+	int res;
+	
+	res = srtp_add_stream(srtp->session, &policy->sp);
+	if (res != err_status_ok)
+		return -1;
+
+	return 0;
+}
+
+static int res_srtp_init(void)
+{
+	int res;
+
+	if (g_initialized)
+		return 0;
+
+	res = srtp_init();
+	if (res != err_status_ok)
+		return -1;
+	
+	srtp_install_event_handler(srtp_event_cb);
+
+	return ast_rtp_register_srtp(&srtp_res, &policy_res);
+}
+
+
+/*
+ * Exported functions
+ */
+
+static int load_module(void *mod)
+{
+	__mod_desc = mod;
+	return  res_srtp_init();
+}
+
+static int unload_module(void *mod)
+{
+	return ast_rtp_unregister_srtp(&srtp_res, &policy_res);
+}
+
+int usecount(void)
+{
+	return 1;
+}
+
+static const char *description(void)
+{
+	return (char *)desc;
+}
+
+static const char *key(void)
+{
+	return ASTERISK_GPL_KEY;
+}
+
+STD_MOD(MOD_0 | NO_UNLOAD, NULL, NULL, NULL);

Propchange: team/oej/securertp-trunk/res/res_srtp.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/oej/securertp-trunk/res/res_srtp.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/oej/securertp-trunk/res/res_srtp.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/oej/securertp-trunk/rtp.c
URL: http://svn.digium.com/view/asterisk/team/oej/securertp-trunk/rtp.c?rev=34459&r1=34458&r2=34459&view=diff
==============================================================================
--- team/oej/securertp-trunk/rtp.c (original)
+++ team/oej/securertp-trunk/rtp.c Fri Jun 16 07:22:59 2006
@@ -1174,7 +1174,7 @@
 	len = sizeof(sin);
 	
 	/* Cache where the header will go */
-	res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET,
+	res = rtp_recvfrom(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET,
 					0, (struct sockaddr *)&sin, &len);
 
 	rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
@@ -2771,8 +2771,8 @@
 
 	if (p0->srtp || p1->srtp) {
 		ast_log(LOG_NOTICE, "Cannot native bridge in SRTP.\n");
-		ast_mutex_unlock(&c0->lock);
-		ast_mutex_unlock(&c1->lock);
+		ast_channel_unlock(c0);
+		ast_channel_unlock(c1);
 		return AST_BRIDGE_FAILED_NOWARN;
 	}
 

Modified: team/oej/securertp-trunk/utils.c
URL: http://svn.digium.com/view/asterisk/team/oej/securertp-trunk/utils.c?rev=34459&r1=34458&r2=34459&view=diff
==============================================================================
--- team/oej/securertp-trunk/utils.c (original)
+++ team/oej/securertp-trunk/utils.c Fri Jun 16 07:22:59 2006
@@ -358,7 +358,7 @@
 		byte |= *(src++);
 		bits += 8;
 		cntin++;
-		if ((bits == 24) && (cnt + 4 < max)) {
+		if ((bits == 24) && (cnt + 4 <= max)) {
 			*dst++ = base64[(byte >> 18) & 0x3f];
 			*dst++ = base64[(byte >> 12) & 0x3f];
 			*dst++ = base64[(byte >> 6) & 0x3f];
@@ -374,7 +374,7 @@
 			col = 0;
 		}
 	}
-	if (bits && (cnt + 4 < max)) {
+	if (bits && (cnt + 4 <= max)) {
 		/* Add one last character for the remaining bits, 
 		   padding the rest with 0 */
 		byte <<= 24 - bits;



More information about the asterisk-commits mailing list