[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