[asterisk-commits] kmoore: branch kmoore/pjsip_dtls r394495 - in /team/kmoore/pjsip_dtls: includ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jul 16 15:17:52 CDT 2013


Author: kmoore
Date: Tue Jul 16 15:17:50 2013
New Revision: 394495

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=394495
Log:
Base changes, SRTP still works and most of the DTLS code is fleshed out

Modified:
    team/kmoore/pjsip_dtls/include/asterisk/res_sip.h
    team/kmoore/pjsip_dtls/include/asterisk/res_sip_session.h
    team/kmoore/pjsip_dtls/res/res_sip.c
    team/kmoore/pjsip_dtls/res/res_sip/sip_configuration.c
    team/kmoore/pjsip_dtls/res/res_sip_sdp_rtp.c
    team/kmoore/pjsip_dtls/res/res_sip_session.c

Modified: team/kmoore/pjsip_dtls/include/asterisk/res_sip.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_dtls/include/asterisk/res_sip.h?view=diff&rev=394495&r1=394494&r2=394495
==============================================================================
--- team/kmoore/pjsip_dtls/include/asterisk/res_sip.h (original)
+++ team/kmoore/pjsip_dtls/include/asterisk/res_sip.h Tue Jul 16 15:17:50 2013
@@ -34,6 +34,8 @@
 #include "asterisk/endpoints.h"
 /* Needed for pj_sockaddr */
 #include <pjlib.h>
+/* Needed for ast_rtp_dtls_cfg struct */
+#include "asterisk/rtp_engine.h"
 
 /* Forward declarations of PJSIP stuff */
 struct pjsip_rx_data;
@@ -408,6 +410,8 @@
 	struct ast_endpoint *persistent;
 	/*! The number of channels at which busy device state is returned */
 	unsigned int devicestate_busy_at;
+	/*! \brief DTLS-SRTP configuration information */
+	struct ast_rtp_dtls_cfg dtls_cfg;
 };
 
 /*!

Modified: team/kmoore/pjsip_dtls/include/asterisk/res_sip_session.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_dtls/include/asterisk/res_sip_session.h?view=diff&rev=394495&r1=394494&r2=394495
==============================================================================
--- team/kmoore/pjsip_dtls/include/asterisk/res_sip_session.h (original)
+++ team/kmoore/pjsip_dtls/include/asterisk/res_sip_session.h Tue Jul 16 15:17:50 2013
@@ -26,8 +26,10 @@
 #include "asterisk/channel.h"
 /* Needed for ast_sockaddr struct */
 #include "asterisk/netsock.h"
-/* Neeed for ast_sdp_srtp struct */
+/* Needed for ast_sdp_srtp struct */
 #include "asterisk/sdp_srtp.h"
+/* Needed for ast_rtp_dtls_cfg struct */
+#include "asterisk/rtp_engine.h"
 
 /* Forward declarations */
 struct ast_sip_endpoint;
@@ -42,7 +44,6 @@
 struct ast_party_id;
 struct pjmedia_sdp_media;
 struct pjmedia_sdp_session;
-struct ast_rtp_instance;
 struct ast_dsp;
 
 struct ast_sip_session_sdp_handler;
@@ -112,6 +113,8 @@
 	struct ast_codec_pref override_prefs;
 	/* Optional DSP, used only for inband DTMF detection if configured */
 	struct ast_dsp *dsp;
+	/*! \brief DTLS-SRTP configuration information */
+	struct ast_rtp_dtls_cfg dtls_cfg;
 	/* Whether the termination of the session should be deferred */
 	unsigned int defer_terminate:1;
 };

Modified: team/kmoore/pjsip_dtls/res/res_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_dtls/res/res_sip.c?view=diff&rev=394495&r1=394494&r2=394495
==============================================================================
--- team/kmoore/pjsip_dtls/res/res_sip.c (original)
+++ team/kmoore/pjsip_dtls/res/res_sip.c Tue Jul 16 15:17:50 2013
@@ -336,6 +336,9 @@
 								transport should be used in conjunction with this option to prevent
 								exposure of media encryption keys.
 							</para></enum>
+							<enum name="dtls"><para>
+								res_sip will offer DTLS-SRTP setup.
+							</para></enum>
 						</enumlist>
 					</description>
 				</configOption>
@@ -385,6 +388,80 @@
 						When the number of in-use channels for the endpoint matches the devicestate_busy_at setting the
 						Gulp channel driver will return busy as the device state instead of in use.
 					</para></description>
+				</configOption>
+				<configOption name="dtlsverify">
+					<synopsis>Verify that the provided peer certificate is valid</synopsis>
+					<description><para>
+						This option only applies if <replaceable>media_encryption</replaceable> is
+						set to <literal>dtls</literal>.
+					</para></description>
+				</configOption>
+				<configOption name="dtlsrekey">
+					<synopsis>Interval at which to renegotiate the TLS session and rekey the SRTP session</synopsis>
+					<description><para>
+						This option only applies if <replaceable>media_encryption</replaceable> is
+						set to <literal>dtls</literal>.
+					</para><para>
+						If this is not set or the value provided is 0 rekeying will be disabled.
+					</para></description>
+				</configOption>
+				<configOption name="dtlscertfile">
+					<synopsis>Path to certificate file to present to peer</synopsis>
+					<description><para>
+						This option only applies if <replaceable>media_encryption</replaceable> is
+						set to <literal>dtls</literal>.
+					</para></description>
+				</configOption>
+				<configOption name="dtlsprivatekey">
+					<synopsis>Path to private key for certificate file</synopsis>
+					<description><para>
+						This option only applies if <replaceable>media_encryption</replaceable> is
+						set to <literal>dtls</literal>.
+					</para></description>
+				</configOption>
+				<configOption name="dtlscipher">
+					<synopsis>Cipher to use for DTLS negotiation</synopsis>
+					<description><para>
+						This option only applies if <replaceable>media_encryption</replaceable> is
+						set to <literal>dtls</literal>.
+					</para><para>
+						Many options for acceptable ciphers see link for more:
+						http://www.openssl.org/docs/apps/ciphers.html#CIPHER_STRINGS
+					</para></description>
+				</configOption>
+				<configOption name="dtlscafile">
+					<synopsis>Path to certificate authority certificate</synopsis>
+					<description><para>
+						This option only applies if <replaceable>media_encryption</replaceable> is
+						set to <literal>dtls</literal>.
+					</para></description>
+				</configOption>
+				<configOption name="dtlscapath">
+					<synopsis>Path to a directory containing certificate authority certificates</synopsis>
+					<description><para>
+						This option only applies if <replaceable>media_encryption</replaceable> is
+						set to <literal>dtls</literal>.
+					</para></description>
+				</configOption>
+				<configOption name="dtlssetup">
+					<synopsis>Whether we are willing to accept connections, connect to the other party, or both.</synopsis>
+					<description>
+						<para>
+							This option only applies if <replaceable>media_encryption</replaceable> is
+							set to <literal>dtls</literal>.
+						</para>
+						<enumlist>
+							<enum name="active"><para>
+								res_sip will make a connection to the peer.
+							</para></enum>
+							<enum name="passive"><para>
+								res_sip will accept connections from the peer.
+							</para></enum>
+							<enum name="actpass"><para>
+								res_sip will offer and accept connections from the peer.
+							</para></enum>
+						</enumlist>
+					</description>
 				</configOption>
 			</configObject>
 			<configObject name="auth">

Modified: team/kmoore/pjsip_dtls/res/res_sip/sip_configuration.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_dtls/res/res_sip/sip_configuration.c?view=diff&rev=394495&r1=394494&r2=394495
==============================================================================
--- team/kmoore/pjsip_dtls/res/res_sip/sip_configuration.c (original)
+++ team/kmoore/pjsip_dtls/res/res_sip/sip_configuration.c Tue Jul 16 15:17:50 2013
@@ -467,8 +467,9 @@
 		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;
+		ast_rtp_dtls_cfg_parse(&endpoint->dtls_cfg, "dtlsenable", "yes");
 	} else {
 		return -1;
 	}
@@ -516,6 +517,14 @@
 	}
 
 	return 0;
+}
+
+static int dtls_handler(const struct aco_option *opt,
+			 struct ast_variable *var, void *obj)
+{
+	struct ast_sip_endpoint *endpoint = obj;
+
+	return ast_rtp_dtls_cfg_parse(&endpoint->dtls_cfg, var->name, var->value);
 }
 
 static void *sip_nat_hook_alloc(const char *name)
@@ -658,6 +667,14 @@
 	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "namedcallgroup", "", named_groups_handler, NULL, 0, 0);
 	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "namedpickupgroup", "", named_groups_handler, NULL, 0, 0);
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "devicestate_busy_at", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, devicestate_busy_at));
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtlsverify", "", dtls_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtlsrekey", "", dtls_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtlscertfile", "", dtls_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtlsprivatekey", "", dtls_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtlscipher", "", dtls_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtlscafile", "", dtls_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtlscapath", "", dtls_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtlssetup", "", dtls_handler, NULL, 0, 0);
 
 	if (ast_sip_initialize_sorcery_transport(sip_sorcery)) {
 		ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n");

Modified: team/kmoore/pjsip_dtls/res/res_sip_sdp_rtp.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_dtls/res/res_sip_sdp_rtp.c?view=diff&rev=394495&r1=394494&r2=394495
==============================================================================
--- team/kmoore/pjsip_dtls/res/res_sip_sdp_rtp.c (original)
+++ team/kmoore/pjsip_dtls/res/res_sip_sdp_rtp.c Tue Jul 16 15:17:50 2013
@@ -514,16 +514,120 @@
 	}
 
 	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_TRANSPORT_INVALID;
-	}
 
 	if (incoming_encryption == endpoint->media_encryption) {
 		return incoming_encryption;
 	}
 
 	return AST_SIP_MEDIA_TRANSPORT_INVALID;
+}
+
+static int setup_srtp(struct ast_sip_session_media *session_media)
+{
+	if (!session_media->srtp) {
+		session_media->srtp = ast_sdp_srtp_alloc();
+		if (!session_media->srtp) {
+			return -1;
+		}
+	}
+
+	if (!session_media->srtp->crypto) {
+		session_media->srtp->crypto = ast_sdp_crypto_alloc();
+		if (!session_media->srtp->crypto) {
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int setup_dtls_srtp(struct ast_sip_session *session,
+	struct ast_sip_session_media *session_media)
+{
+	struct ast_rtp_engine_dtls *dtls;
+
+	if (!session->dtls_cfg.enabled || !session_media->rtp) {
+		return -1;
+	}
+
+	dtls = ast_rtp_instance_get_dtls(session_media->rtp);
+	if (!dtls) {
+		return -1;
+	}
+
+	if (dtls->set_configuration(session_media->rtp, &session->dtls_cfg)) {
+		ast_log(LOG_ERROR, "Attempted to set an invalid DTLS-SRTP configuration on RTP instance '%p'\n",
+			session_media->rtp);
+		return -1;
+	}
+
+	if (setup_srtp(session_media)) {
+		return -1;
+	}
+	return 0;
+}
+
+static int parse_dtls_attrib(struct ast_sip_session_media *session_media,
+	const struct pjmedia_sdp_media *stream)
+{
+	int i;
+	struct ast_rtp_engine_dtls *dtls = ast_rtp_instance_get_dtls(session_media->rtp);
+
+	for (i = 0; i < stream->attr_count; i++) {
+		pjmedia_sdp_attr *attr = stream->attr[i];
+		pj_str_t *value = pj_strtrim(&attr->value);
+
+		if (!pj_strcmp2(&attr->name, "setup")) {
+			RAII_VAR(char *, setup_type, ast_strndup(value->ptr, value->slen), ast_free);
+			if (!setup_type) {
+				return -1;
+			}
+
+			if (!strcasecmp(setup_type, "active")) {
+				dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_ACTIVE);
+			} else if (!strcasecmp(setup_type, "passive")) {
+				dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_PASSIVE);
+			} else if (!strcasecmp(setup_type, "actpass")) {
+				dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_ACTPASS);
+			} else if (!strcasecmp(setup_type, "holdconn")) {
+				dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_HOLDCONN);
+			} else {
+				ast_log(LOG_WARNING, "Unsupported setup attribute value '%s'\n", setup_type);
+			}
+		} else if (!pj_strcmp2(&attr->name, "connection")) {
+			RAII_VAR(char *, connection_type, ast_strndup(value->ptr, value->slen), ast_free);
+			if (!connection_type) {
+				return -1;
+			}
+
+			if (!strcasecmp(connection_type, "new")) {
+				dtls->reset(session_media->rtp);
+			} else if (!strcasecmp(connection_type, "existing")) {
+				/* Do nothing */
+			} else {
+				ast_log(LOG_WARNING, "Unsupported connection attribute value '%s'\n", connection_type);
+			}
+		} else if (!pj_strcmp2(&attr->name, "fingerprint")) {
+			char hash_value[256], hash[6];
+			RAII_VAR(char *, fingerprint_text, ast_strndup(value->ptr, value->slen), ast_free);
+
+			if (!fingerprint_text) {
+				return -1;
+			}
+
+			if (sscanf(fingerprint_text, "%5s %255s", hash, hash_value) == 2) {
+				if (!strcasecmp(hash, "sha-1")) {
+					dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA1, hash_value);
+				} else {
+					ast_log(LOG_WARNING, "Unsupported fingerprint hash type '%s'\n",
+					hash);
+				}
+			}
+		}
+	}
+	ast_set_flag(session_media->srtp, AST_SRTP_CRYPTO_OFFER_OK);
+
+	return 0;
 }
 
 static int setup_sdes_srtp(struct ast_sip_session_media *session_media,
@@ -546,18 +650,8 @@
 			return -1;
 		}
 
-		if (!session_media->srtp) {
-			session_media->srtp = ast_sdp_srtp_alloc();
-			if (!session_media->srtp) {
-				return -1;
-			}
-		}
-
-		if (!session_media->srtp->crypto) {
-			session_media->srtp->crypto = ast_sdp_crypto_alloc();
-			if (!session_media->srtp->crypto) {
-				return -1;
-			}
+		if (setup_srtp(session_media)) {
+			return -1;
 		}
 
 		if (!ast_sdp_crypto_process(session_media->rtp, session_media->srtp, crypto_str)) {
@@ -605,9 +699,24 @@
 		return -1;
 	}
 
-	if (incoming_encryption == AST_SIP_MEDIA_ENCRYPT_SDES
-			&& setup_sdes_srtp(session_media, stream)) {
-		return -1;
+	switch (incoming_encryption) {
+	case AST_SIP_MEDIA_ENCRYPT_SDES:
+		if (setup_sdes_srtp(session_media, stream)) {
+			return -1;
+		}
+		break;
+	case AST_SIP_MEDIA_ENCRYPT_DTLS:
+		if (setup_dtls_srtp(session, session_media)) {
+			return -1;
+		}
+		if (parse_dtls_attrib(session_media, stream)) {
+			return -1;
+		}
+		break;
+	case AST_SIP_MEDIA_TRANSPORT_INVALID:
+		/* Already handled above, fallthrough */
+	case AST_SIP_MEDIA_ENCRYPT_NONE:
+		break;
 	}
 
 	return set_caps(session, session_media, stream);
@@ -621,7 +730,14 @@
 	pjmedia_sdp_attr *attr;
 	const char *crypto_attribute;
 
-	if (!session_media->srtp && session->endpoint->media_encryption != AST_SIP_MEDIA_ENCRYPT_NONE) {
+	if (session->endpoint->media_encryption == AST_SIP_MEDIA_ENCRYPT_DTLS) {
+		if (setup_dtls_srtp(session, session_media)) {
+			return -1;
+		}
+		return 0;
+	}
+
+	if (!session_media->srtp && session->endpoint->media_encryption == AST_SIP_MEDIA_ENCRYPT_SDES) {
 		session_media->srtp = ast_sdp_srtp_alloc();
 		if (!session_media->srtp) {
 			return -1;
@@ -629,7 +745,7 @@
 	}
 
 	crypto_attribute = ast_sdp_srtp_get_attrib(session_media->srtp,
-		0 /* DTLS can not be enabled for res_sip */,
+		session->endpoint->media_encryption == AST_SIP_MEDIA_ENCRYPT_DTLS /* DTLS running? */,
 		0 /* don't prefer 32byte tag length */);
 	if (!crypto_attribute) {
 		/* No crypto attribute to add */

Modified: team/kmoore/pjsip_dtls/res/res_sip_session.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_dtls/res/res_sip_session.c?view=diff&rev=394495&r1=394494&r2=394495
==============================================================================
--- team/kmoore/pjsip_dtls/res/res_sip_session.c (original)
+++ team/kmoore/pjsip_dtls/res/res_sip_session.c Tue Jul 16 15:17:50 2013
@@ -854,6 +854,8 @@
 	ast_taskprocessor_unreference(session->serializer);
 	ao2_cleanup(session->datastores);
 	ao2_cleanup(session->media);
+	ast_rtp_dtls_cfg_free(&session->dtls_cfg);
+
 	AST_LIST_HEAD_DESTROY(&session->supplements);
 	while ((delay = AST_LIST_REMOVE_HEAD(&session->delayed_requests, next))) {
 		ast_free(delay);
@@ -920,6 +922,8 @@
 	}
 	/* fill session->media with available types */
 	ao2_callback(sdp_handlers, OBJ_NODATA, add_session_media, session);
+
+	ast_rtp_dtls_cfg_copy(&endpoint->dtls_cfg, &session->dtls_cfg);
 
 	session->serializer = ast_sip_create_serializer();
 	if (!session->serializer) {




More information about the asterisk-commits mailing list