[asterisk-commits] kmoore: branch kmoore/pimp_sip_srtp r386327 - in /team/kmoore/pimp_sip_srtp: ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Apr 22 16:16:39 CDT 2013


Author: kmoore
Date: Mon Apr 22 16:16:35 2013
New Revision: 386327

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386327
Log:
Fleshing out of work for SDES SRTP in chan_gulp/res_sip

Modified:
    team/kmoore/pimp_sip_srtp/channels/chan_sip.c
    team/kmoore/pimp_sip_srtp/configs/res_sip.conf.sample
    team/kmoore/pimp_sip_srtp/include/asterisk/res_sip.h
    team/kmoore/pimp_sip_srtp/include/asterisk/res_sip_session.h
    team/kmoore/pimp_sip_srtp/include/asterisk/sdp_srtp.h
    team/kmoore/pimp_sip_srtp/main/sdp_srtp.c
    team/kmoore/pimp_sip_srtp/res/res_sip/sip_configuration.c
    team/kmoore/pimp_sip_srtp/res/res_sip_sdp_rtp.c

Modified: team/kmoore/pimp_sip_srtp/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pimp_sip_srtp/channels/chan_sip.c?view=diff&rev=386327&r1=386326&r2=386327
==============================================================================
--- team/kmoore/pimp_sip_srtp/channels/chan_sip.c (original)
+++ team/kmoore/pimp_sip_srtp/channels/chan_sip.c Mon Apr 22 16:16:35 2013
@@ -33284,7 +33284,7 @@
 		return FALSE;
 	}
 
-	if (ast_sdp_crypto_process((*srtp)->crypto, a, rtp, *srtp) < 0) {
+	if (ast_sdp_crypto_process(rtp, *srtp, a) < 0) {
 		return FALSE;
 	}
 

Modified: team/kmoore/pimp_sip_srtp/configs/res_sip.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pimp_sip_srtp/configs/res_sip.conf.sample?view=diff&rev=386327&r1=386326&r2=386327
==============================================================================
--- team/kmoore/pimp_sip_srtp/configs/res_sip.conf.sample (original)
+++ team/kmoore/pimp_sip_srtp/configs/res_sip.conf.sample Mon Apr 22 16:16:35 2013
@@ -22,3 +22,4 @@
 ;rtp_ipv6=yes             ; Force IPv6 for RTP transport
 ;rtp_symmetric=yes        ; Enable symmetric RTP support
 ;use_ptime=yes            ; Whether to use the ptime value received from the endpoint or not
+;media_encryption=no      ; Options for media encryption are deny, no, and sdes

Modified: team/kmoore/pimp_sip_srtp/include/asterisk/res_sip.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pimp_sip_srtp/include/asterisk/res_sip.h?view=diff&rev=386327&r1=386326&r2=386327
==============================================================================
--- team/kmoore/pimp_sip_srtp/include/asterisk/res_sip.h (original)
+++ team/kmoore/pimp_sip_srtp/include/asterisk/res_sip.h Mon Apr 22 16:16:35 2013
@@ -250,6 +250,8 @@
 };
 
 enum ast_sip_session_media_encryption {
+	/*! Invalid media encryption configuration */
+	AST_SIP_MEDIA_ENCRYPT_INVALID = 0,
 	/*! Do not allow any encryption of session media */
 	AST_SIP_MEDIA_ENCRYPT_DENY,
 	/*! Do not offer media encryption, but accept it if offered */

Modified: team/kmoore/pimp_sip_srtp/include/asterisk/res_sip_session.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pimp_sip_srtp/include/asterisk/res_sip_session.h?view=diff&rev=386327&r1=386326&r2=386327
==============================================================================
--- team/kmoore/pimp_sip_srtp/include/asterisk/res_sip_session.h (original)
+++ team/kmoore/pimp_sip_srtp/include/asterisk/res_sip_session.h Mon Apr 22 16:16:35 2013
@@ -26,6 +26,8 @@
 #include "asterisk/channel.h"
 /* Needed for ast_sockaddr struct */
 #include "asterisk/netsock.h"
+/* Neeed for ast_sdp_srtp struct */
+#include "asterisk/sdp_srtp.h"
 
 /* Forward declarations */
 struct ast_sip_endpoint;
@@ -54,6 +56,8 @@
 	struct ast_sockaddr direct_media_addr;
 	/*! \brief SDP handler that setup the RTP */
 	struct ast_sip_session_sdp_handler *handler;
+	/*! \brief Holds SRTP information */
+	struct ast_sdp_srtp srtp;
 	/*! \brief Stream is on hold */
 	unsigned int held:1;
 	/*! \brief Stream type this session media handles */

Modified: team/kmoore/pimp_sip_srtp/include/asterisk/sdp_srtp.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pimp_sip_srtp/include/asterisk/sdp_srtp.h?view=diff&rev=386327&r1=386326&r2=386327
==============================================================================
--- team/kmoore/pimp_sip_srtp/include/asterisk/sdp_srtp.h (original)
+++ team/kmoore/pimp_sip_srtp/include/asterisk/sdp_srtp.h Mon Apr 22 16:16:35 2013
@@ -81,8 +81,7 @@
  * \retval 0 success
  * \retval nonzero failure
  */
-int ast_sdp_crypto_process(struct ast_sdp_crypto *p, const char *attr, struct ast_rtp_instance *rtp, struct ast_sdp_srtp *srtp);
-
+int ast_sdp_crypto_process(struct ast_rtp_instance *rtp, struct ast_sdp_srtp *srtp, const char *attr);
 
 /*! \brief Generate an SRTP a=crypto offer
  *

Modified: team/kmoore/pimp_sip_srtp/main/sdp_srtp.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pimp_sip_srtp/main/sdp_srtp.c?view=diff&rev=386327&r1=386326&r2=386327
==============================================================================
--- team/kmoore/pimp_sip_srtp/main/sdp_srtp.c (original)
+++ team/kmoore/pimp_sip_srtp/main/sdp_srtp.c Mon Apr 22 16:16:35 2013
@@ -208,7 +208,7 @@
 	return res;
 }
 
-int ast_sdp_crypto_process(struct ast_sdp_crypto *p, const char *attr, struct ast_rtp_instance *rtp, struct ast_sdp_srtp *srtp)
+int ast_sdp_crypto_process(struct ast_rtp_instance *rtp, struct ast_sdp_srtp *srtp, const char *attr)
 {
 	char *str = NULL;
 	char *tag = NULL;
@@ -223,6 +223,7 @@
 	int suite_val = 0;
 	unsigned char remote_key[SRTP_MASTER_LEN];
 	int taglen = 0;
+	struct ast_sdp_crypto *crypto = srtp->crypto; 
 
 	if (!ast_rtp_engine_srtp_is_registered()) {
 		return -1;
@@ -290,28 +291,28 @@
 		return -1;
 	}
 
-	if (!memcmp(p->remote_key, remote_key, sizeof(p->remote_key))) {
+	if (!memcmp(crypto->remote_key, remote_key, sizeof(crypto->remote_key))) {
 		ast_debug(1, "SRTP remote key unchanged; maintaining current policy\n");
 		ast_set_flag(srtp, AST_SRTP_CRYPTO_OFFER_OK);
 		return 0;
 	}
-	memcpy(p->remote_key, remote_key, sizeof(p->remote_key));
-
-	if (ast_sdp_crypto_activate(p, suite_val, remote_key, rtp) < 0) {
-		return -1;
-	}
-
-	if (!p->tag) {
+	memcpy(crypto->remote_key, remote_key, sizeof(crypto->remote_key));
+
+	if (ast_sdp_crypto_activate(crypto, suite_val, remote_key, rtp) < 0) {
+		return -1;
+	}
+
+	if (!crypto->tag) {
 		ast_log(LOG_DEBUG, "Accepting crypto tag %s\n", tag);
-		p->tag = ast_strdup(tag);
-		if (!p->tag) {
+		crypto->tag = ast_strdup(tag);
+		if (!crypto->tag) {
 			ast_log(LOG_ERROR, "Could not allocate memory for tag\n");
 			return -1;
 		}
 	}
 
 	/* Finally, rebuild the crypto line */
-	if (ast_sdp_crypto_build_offer(p, taglen)) {
+	if (ast_sdp_crypto_build_offer(crypto, taglen)) {
 		return -1;
 	}
 

Modified: team/kmoore/pimp_sip_srtp/res/res_sip/sip_configuration.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pimp_sip_srtp/res/res_sip/sip_configuration.c?view=diff&rev=386327&r1=386326&r2=386327
==============================================================================
--- team/kmoore/pimp_sip_srtp/res/res_sip/sip_configuration.c (original)
+++ team/kmoore/pimp_sip_srtp/res/res_sip/sip_configuration.c Mon Apr 22 16:16:35 2013
@@ -286,8 +286,8 @@
 		endpoint->media_encryption = AST_SIP_MEDIA_ENCRYPT_NONE;
 	} else if (!strcasecmp("sdes", var->value)) {
 		endpoint->media_encryption = AST_SIP_MEDIA_ENCRYPT_SDES;
-	} else if (!strcasecmp("dtls", var->value)) {
-		endpoint->media_encryption = AST_SIP_MEDIA_ENCRYPT_DTLS;
+	/*} else if (!strcasecmp("dtls", var->value)) {
+		endpoint->media_encryption = AST_SIP_MEDIA_ENCRYPT_DTLS;*/
 	} else {
 		return -1;
 	}

Modified: team/kmoore/pimp_sip_srtp/res/res_sip_sdp_rtp.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pimp_sip_srtp/res/res_sip_sdp_rtp.c?view=diff&rev=386327&r1=386326&r2=386327
==============================================================================
--- team/kmoore/pimp_sip_srtp/res/res_sip_sdp_rtp.c (original)
+++ team/kmoore/pimp_sip_srtp/res/res_sip_sdp_rtp.c Mon Apr 22 16:16:35 2013
@@ -47,6 +47,7 @@
 #include "asterisk/causes.h"
 #include "asterisk/sched.h"
 #include "asterisk/acl.h"
+#include "asterisk/sdp_srtp.h"
 
 #include "asterisk/res_sip.h"
 #include "asterisk/res_sip_session.h"
@@ -457,6 +458,96 @@
 					 session_media->rtp, pref);
 }
 
+/*! \brief figure out media transport encryption type from the media transport string */
+static enum ast_sip_session_media_encryption get_media_encryption_type(pj_str_t transport)
+{
+	RAII_VAR(char *, transport_str, ast_strndup(transport.ptr, transport.slen), ast_free);
+	if (strstr(transport_str, "UDP/TLS")) {
+		return AST_SIP_MEDIA_ENCRYPT_DTLS;
+	} else if (strstr(transport_str, "SAVP")) {
+		return AST_SIP_MEDIA_ENCRYPT_SDES;
+	} else {
+		return AST_SIP_MEDIA_ENCRYPT_NONE;
+	}
+}
+
+/*!
+ * \brief Checks whether the encryption offered in SDP is compatible with the endpoint's configuration
+ * \internal
+ *
+ * \param endpoint_encryption Media encryption configured for the endpoint
+ * \param stream pjmedia_sdp_media stream description
+ *
+ * \retval AST_SIP_MEDIA_ENCRYPT_INVALID on encryption mismatch
+ * \retval The encryption requested in the SDP
+ */
+static enum ast_sip_session_media_encryption check_endpoint_media_encryption(
+	enum ast_sip_session_media_encryption endpoint_encryption,
+	const struct pjmedia_sdp_media *stream)
+{
+	enum ast_sip_session_media_encryption incoming_encryption;
+
+	incoming_encryption = get_media_encryption_type(stream->desc.transport);
+	if (incoming_encryption == AST_SIP_MEDIA_ENCRYPT_DTLS) {
+		/* DTLS not yet supported */
+		return AST_SIP_MEDIA_ENCRYPT_INVALID;
+	}
+
+	if (incoming_encryption == endpoint_encryption) {
+		return incoming_encryption;
+	}
+
+	switch (endpoint_encryption) {
+	case AST_SIP_MEDIA_ENCRYPT_DENY:
+		if (incoming_encryption != AST_SIP_MEDIA_ENCRYPT_NONE) {
+			/* Encryption offered, but not allowed */
+			return AST_SIP_MEDIA_ENCRYPT_INVALID;
+		}
+		break;
+	case AST_SIP_MEDIA_ENCRYPT_NONE:
+		if (incoming_encryption != AST_SIP_MEDIA_ENCRYPT_SDES) {
+			/* Can only silently upgrade to SDES from no encryption */
+			return AST_SIP_MEDIA_ENCRYPT_INVALID;
+		}
+		break;
+	case AST_SIP_MEDIA_ENCRYPT_SDES:
+		/* Can't silently upgrade or downgrade from SDES */
+		return AST_SIP_MEDIA_ENCRYPT_INVALID;
+	case AST_SIP_MEDIA_ENCRYPT_DTLS:
+		/* Can't silently upgrade or downgrade from DTLS */
+		return AST_SIP_MEDIA_ENCRYPT_INVALID;
+	case AST_SIP_MEDIA_ENCRYPT_INVALID:
+		/* This shouldn't ever happen */
+		return AST_SIP_MEDIA_ENCRYPT_INVALID;
+	}
+
+	return incoming_encryption;
+}
+
+static int setup_sdes_srtp(struct ast_sip_session_media *session_media,
+	const struct pjmedia_sdp_media *stream)
+{
+	pjmedia_sdp_attr *attr;
+	RAII_VAR(char *, crypto_str, NULL, ast_free);
+
+	/* check the stream for the required crypto attribute */
+	attr = pjmedia_sdp_media_find_attr2(stream, "crypto", NULL);
+	if (!attr) {
+		return -1;
+	}
+
+	crypto_str = ast_strndup(attr->value.ptr, attr->value.slen);
+	if (!crypto_str) {
+		return -1;
+	}
+
+	if (ast_sdp_crypto_process(session_media->rtp, &session_media->srtp, crypto_str)) {
+		return -1;
+	}
+
+	return 0;
+}
+
 /*! \brief Function which negotiates an incoming media stream */
 static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
 					 const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
@@ -464,12 +555,19 @@
 	char host[NI_MAXHOST];
 	RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free_ptr);
 	enum ast_format_type media_type = stream_to_media_type(session_media->stream_type);
+	enum ast_sip_session_media_encryption incoming_encryption;
 
 	/* If no type formats have been configured reject this stream */
 	if (!ast_format_cap_has_type(session->endpoint->codecs, media_type)) {
 		return 0;
 	}
 
+	/* Ensure incoming encryption is compatible with the endpoint's configuration */
+	incoming_encryption = check_endpoint_media_encryption(session->endpoint->media_encryption, stream);
+	if (incoming_encryption == AST_SIP_MEDIA_ENCRYPT_INVALID) {
+		return -1;
+	}
+
 	ast_copy_pj_str(host, stream->conn ? &stream->conn->addr : &sdp->conn->addr, sizeof(host));
 
 	/* Ensure that the address provided is valid */
@@ -483,7 +581,32 @@
 		return -1;
 	}
 
+	if (incoming_encryption == AST_SIP_MEDIA_ENCRYPT_SDES
+			&& setup_sdes_srtp(session_media, stream)) {
+		return -1;
+	}
+
 	return set_caps(session, session_media, stream);
+}
+
+static int add_crypto_to_stream(struct ast_sip_session_media *session_media,
+	pj_pool_t *pool, pjmedia_sdp_media *media)
+{
+	pj_str_t stmp;
+	pjmedia_sdp_attr *attr;
+	const char *crypto_attribute = ast_sdp_srtp_get_attrib(&session_media->srtp,
+		0 /* DTLS can not be enabled for res_sip */,
+		0 /* don't prefer 32byte tag length */);
+	
+	if (!crypto_attribute) {
+		/* No crypto attribute to add */
+		return -1;
+	}
+
+	attr = pjmedia_sdp_attr_create(pool, "crypto", pj_cstr(&stmp, crypto_attribute));
+	media->attr[media->attr_count++] = attr;
+
+	return 0;
 }
 
 /*! \brief Function which creates an outgoing stream */
@@ -494,7 +617,6 @@
 	static const pj_str_t STR_IN = { "IN", 2 };
 	static const pj_str_t STR_IP4 = { "IP4", 3};
 	static const pj_str_t STR_IP6 = { "IP6", 3};
-	static const pj_str_t STR_RTP_AVP = { "RTP/AVP", 7 };
 	static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
 	pjmedia_sdp_media *media;
 	char hostip[PJ_INET6_ADDRSTRLEN+2];
@@ -508,6 +630,7 @@
 	struct ast_format compat_format;
 	RAII_VAR(struct ast_format_cap *, caps, NULL, ast_format_cap_destroy);
 	enum ast_format_type media_type = stream_to_media_type(session_media->stream_type);
+	int crypto_res;
 
 	int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) &&
 		!ast_format_cap_is_empty(session->direct_media_cap);
@@ -524,9 +647,11 @@
 		return -1;
 	}
 
-	/* TODO: This should eventually support SRTP */
+	crypto_res = add_crypto_to_stream(session_media, pool, media);
+
 	media->desc.media = pj_str(session_media->stream_type);
-	media->desc.transport = STR_RTP_AVP;
+	media->desc.transport = pj_str(ast_sdp_get_rtp_profile(
+		!crypto_res, session_media->rtp, 0 /* not using AVPF */));
 
 	/* Add connection level details */
 	if (direct_media_enabled) {




More information about the asterisk-commits mailing list