[asterisk-commits] twilson: branch group/srtp r165075 - in /team/group/srtp: ./ build_tools/ cha...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Dec 16 23:36:04 CST 2008
Author: twilson
Date: Tue Dec 16 23:36:03 2008
New Revision: 165075
URL: http://svn.digium.com/view/asterisk?view=rev&rev=165075
Log:
The old SRTP branch has gotten so far out of sync with trunk that it seems like svnmerge just wasn't able to handle the merge...it pretended to, but missed all kinds of things. So, I took the diff against trunk at the last successful merge, checked out trunk, and applied the diff. Then svn update, fix conflicts, svn add new files and made some changes to actually get it to compile under dev mode.
I have not done any testing other than it compiles and loads. Also to note is the the libsrtp1-dev package in 64-bit Ubuntu creat
es a static library that is not compiled with -fPIC, so building it from source and manually adding -fPIC to CFLAGS was necessary.
Added:
team/group/srtp/channels/sdp_crypto.c (with props)
team/group/srtp/channels/sdp_crypto.h (with props)
team/group/srtp/channels/sdp_mikey.c (with props)
team/group/srtp/channels/sdp_mikey.h (with props)
team/group/srtp/channels/sip_srtp.c (with props)
team/group/srtp/channels/sip_srtp.h (with props)
team/group/srtp/include/asterisk/mikey.h (with props)
team/group/srtp/res/mikey.cc (with props)
team/group/srtp/res/mikey.h (with props)
team/group/srtp/res/res_mikey.c (with props)
team/group/srtp/res/res_srtp.c (with props)
Modified:
team/group/srtp/CREDITS
team/group/srtp/build_tools/menuselect-deps.in
team/group/srtp/channels/Makefile
team/group/srtp/channels/chan_sip.c
team/group/srtp/configure
team/group/srtp/configure.ac
team/group/srtp/include/asterisk/aes_internal.h
team/group/srtp/include/asterisk/autoconfig.h.in
team/group/srtp/include/asterisk/rtp.h
team/group/srtp/main/cryptostub.c
team/group/srtp/main/rtp.c
team/group/srtp/makeopts.in
team/group/srtp/res/Makefile
Modified: team/group/srtp/CREDITS
URL: http://svn.digium.com/view/asterisk/team/group/srtp/CREDITS?view=diff&rev=165075&r1=165074&r2=165075
==============================================================================
--- team/group/srtp/CREDITS (original)
+++ team/group/srtp/CREDITS Tue Dec 16 23:36:03 2008
@@ -153,6 +153,9 @@
George Konstantoulakis - Support for Greek in voicemail added by InAccess
Networks (work funded by HOL, www.hol.gr) gkon(AT)inaccessnetworks.com
+Mikael Magnusson - Provided SRTP support in RTP, and SRTP and MIKEY support in the SIP channel
+ mikma at users.sourceforge.net
+
Daniel Nylander - Support for Swedish and Norwegian languages in voicemail.
http://www.danielnylander.se/
Modified: team/group/srtp/build_tools/menuselect-deps.in
URL: http://svn.digium.com/view/asterisk/team/group/srtp/build_tools/menuselect-deps.in?view=diff&rev=165075&r1=165074&r2=165075
==============================================================================
--- team/group/srtp/build_tools/menuselect-deps.in (original)
+++ team/group/srtp/build_tools/menuselect-deps.in Tue Dec 16 23:36:03 2008
@@ -20,7 +20,11 @@
LDAP=@PBX_LDAP@
LTDL=@PBX_LTDL@
LUA=@PBX_LUA@
+MCRYPTO=@PBX_MCRYPTO@
+MIKEY=@PBX_MIKEY@
MISDN=@PBX_MISDN@
+MNETUTIL=@PBX_MNETUTIL@
+MUTIL=@PBX_MUTIL@
NBS=@PBX_NBS@
NETSNMP=@PBX_NETSNMP@
NEWT=@PBX_NEWT@
@@ -42,6 +46,7 @@
SPEEX_PREPROCESS=@PBX_SPEEX_PREPROCESS@
SQLITE3=@PBX_SQLITE3@
SQLITE=@PBX_SQLITE@
+SRTP=@PBX_SRTP@
SS7=@PBX_SS7@
OPENSSL=@PBX_OPENSSL@
SUPPSERV=@PBX_SUPPSERV@
Modified: team/group/srtp/channels/Makefile
URL: http://svn.digium.com/view/asterisk/team/group/srtp/channels/Makefile?view=diff&rev=165075&r1=165074&r2=165075
==============================================================================
--- team/group/srtp/channels/Makefile (original)
+++ team/group/srtp/channels/Makefile Tue Dec 16 23:36:03 2008
@@ -92,6 +92,8 @@
$(CMD_PREFIX) $(CXX) $(PTHREAD_CFLAGS) $(ASTLDFLAGS) $(SOLINK) -o $@ $< h323/libchanh323.a $(CHANH323LIB) -L$(PWLIBDIR)/lib $(PTLIB) -L$(OPENH323DIR)/lib $(H323LIB) -L/usr/lib -lcrypto -lssl -lexpat
endif
+chan_sip.so: sip_srtp.o sdp_crypto.o sdp_mikey.o
+
chan_misdn.o: ASTCFLAGS+=-Imisdn
misdn_config.o: ASTCFLAGS+=-Imisdn
Modified: team/group/srtp/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/group/srtp/channels/chan_sip.c?view=diff&rev=165075&r1=165074&r2=165075
==============================================================================
--- team/group/srtp/channels/chan_sip.c (original)
+++ team/group/srtp/channels/chan_sip.c Tue Dec 16 23:36:03 2008
@@ -266,6 +266,10 @@
#include "asterisk/ast_version.h"
#include "asterisk/event.h"
#include "asterisk/tcptls.h"
+
+#include "sip_srtp.h"
+#include "sdp_crypto.h"
+#include "sdp_mikey.h"
/*** DOCUMENTATION
<application name="SIPDtmfMode" language="en_US">
@@ -1661,6 +1665,7 @@
(A bit unsure of this, please correct if
you know more) */
struct sip_st_dlg *stimer; /*!< SIP Session-Timers */
+ struct sip_srtp *srtp; /*!< Structure for Secure RTP session data */
int red; /*!< T.140 RTP Redundancy */
@@ -2511,6 +2516,11 @@
static int sip_get_codec(struct ast_channel *chan);
static struct ast_frame *sip_rtp_read(struct ast_channel *ast, struct sip_pvt *p, int *faxdetect);
+/*----- SRTP interface functions */
+static int setup_srtp(struct sip_pvt *p);
+static int process_crypto(struct sip_pvt *p, const char *a);
+static int process_mikey(struct sip_pvt *p, const char *a);
+
/*------ T38 Support --------- */
static int sip_handle_t38_reinvite(struct ast_channel *chan, struct sip_pvt *pvt, int reinvite);
static int transmit_response_with_t38_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, int retrans);
@@ -4885,6 +4895,53 @@
} else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) {
/* We're replacing a call. */
p->options->replaces = ast_var_value(current);
+ } else if (!strcasecmp(ast_var_name(current), "SIPSRTP")) {
+ ast_log(LOG_NOTICE, "SIPSRTP\n");
+
+ if (!p->srtp) {
+ if (setup_srtp(p) < 0) {
+ ast_log(LOG_WARNING, "SRTP 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), "SIPSRTP_CRYPTO")) {
+ ast_log(LOG_NOTICE, "SIPSRTP_CRYPTO\n");
+
+ if (!p->srtp) {
+ if (setup_srtp(p) < 0) {
+ ast_log(LOG_WARNING, "SRTP setup failed\n");
+ return -1;
+ }
+ }
+
+ if (!strcasecmp(ast_var_value(current), "enable")) {
+ ast_set_flag(p->srtp, SRTP_CRYPTO_ENABLE);
+ } else if (!strcasecmp(ast_var_value(current), "disable")) {
+ ast_clear_flag(p->srtp, SRTP_CRYPTO_ENABLE);
+ } else {
+ ast_log(LOG_WARNING,"Invalid SIPSRTP_CRYPTO value (%s), enable or disable expected\n", ast_var_value(current));
+ }
+ } else if (!strcasecmp(ast_var_name(current), "SIPSRTP_MIKEY")) {
+ ast_log(LOG_NOTICE, "SIPSRTP_MIKEY\n");
+
+ if (!p->srtp) {
+ if (setup_srtp(p) < 0) {
+ ast_log(LOG_WARNING, "SRTP setup failed\n");
+ return -1;
+ }
+ }
+
+ if (!strcasecmp(ast_var_value(current), "enable")) {
+ ast_set_flag(p->srtp, SRTP_MIKEY_ENABLE);
+ } else if (!strcasecmp(ast_var_value(current), "disable")) {
+ ast_clear_flag(p->srtp, SRTP_MIKEY_ENABLE);
+ } else {
+ ast_log(LOG_WARNING,"Invalid SIPSRTP_MIKEY value (%s), enable or disable expected\n", ast_var_value(current));
+ }
} else if (!strcasecmp(ast_var_name(current), "T38CALL")) {
p->t38.state = T38_LOCAL_DIRECT;
ast_debug(1, "T38State change to %d on channel %s\n", p->t38.state, ast->name);
@@ -5084,6 +5141,10 @@
if (p->chanvars) {
ast_variables_destroy(p->chanvars);
p->chanvars = NULL;
+ }
+ if (p->srtp) {
+ sip_srtp_destroy(p->srtp);
+ p->srtp = NULL;
}
ast_string_field_free_memory(p);
@@ -7255,7 +7316,9 @@
int newnoncodeccapability;
int numberofmediastreams = 0;
int debug = sip_debug_test_pvt(p);
-
+ int secure_audio = FALSE;
+ int secure_video = FALSE;
+
int found_rtpmap_codecs[SDP_MAX_RTPMAP_CODECS];
int last_rtpmap_codec=0;
@@ -7391,11 +7454,22 @@
int audio = FALSE;
int video = FALSE;
int text = FALSE;
+ char protocol[5] = "";
numberofports = 1;
len = -1;
- if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
- (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1 && len > 0)) {
+ if ((sscanf(m, "audio %d/%d RTP/%4s %n", &x, &numberofports, protocol, &len) == 3) ||
+ (sscanf(m, "audio %d RTP/%4s %n", &x, protocol, &len) == 2)) {
+ if (!strcmp(protocol, "SAVP"))
+ secure_audio = 1;
+ else if (strcmp(protocol, "AVP")) {
+ ast_log(LOG_WARNING, "Unknown SDP media protocol in offer: %s\n", protocol);
+ continue;
+ }
+ if (len < 0) {
+ ast_log(LOG_WARNING, "Unknown SDP media type in offer: %s\n", m);
+ continue;
+ }
audio = TRUE;
numberofmediastreams++;
/* Found audio stream in this media definition */
@@ -7410,8 +7484,18 @@
ast_verbose("Found RTP audio format %d\n", codec);
ast_rtp_set_m_type(newaudiortp, codec);
}
- } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
- (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1 && len >= 0)) {
+ } else if ((sscanf(m, "video %d/%d RTP/%4s %n", &x, &numberofports, protocol, &len) == 3) ||
+ (sscanf(m, "video %d RTP/%4s %n", &x, protocol, &len) == 2)) {
+ if (!strcmp(protocol, "SAVP"))
+ secure_video = 1;
+ else if (strcmp(protocol, "AVP")) {
+ ast_log(LOG_WARNING, "Unknown SDP media protocol for video in offer: %s\n", protocol);
+ continue;
+ }
+ if (len < 0) {
+ ast_log(LOG_WARNING, "Unknown SDP media type for video in offer: %s\n", m);
+ continue;
+ }
video = TRUE;
p->novideo = FALSE;
numberofmediastreams++;
@@ -7583,11 +7667,6 @@
if (debug)
ast_verbose("Got unsupported a:maxprate in SDP offer \n");
breakout = TRUE;
- } else if (!strncasecmp(a, "crypto:", (size_t) 7)) {
- /* SRTP stuff, not yet supported */
- if (debug)
- ast_verbose("Got unsupported a:crypto in SDP offer \n");
- breakout = TRUE;
}
if (breakout) /* We have a match, skip to next header */
continue;
@@ -7595,6 +7674,12 @@
if (!strcasecmp(a, "sendonly")) {
if (sendonly == -1)
sendonly = 1;
+ continue;
+ } else if (!strncasecmp(a, "crypto:", (size_t) 7)) {
+ process_crypto(p, a);
+ continue;
+ } else if (!strncasecmp(a, "key-mgmt:mikey ", (size_t) 15)) {
+ process_mikey(p, a);
continue;
} else if (!strcasecmp(a, "inactive")) {
if (sendonly == -1)
@@ -7694,6 +7779,11 @@
}
}
+ }
+
+ if (secure_audio && !(p->srtp && (ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK) || ast_test_flag(p->srtp, SRTP_MIKEY_OFFER_OK)))) {
+ ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n");
+ return -2;
}
if (udptlportno != -1) {
@@ -7807,6 +7897,11 @@
change_t38_state(p, T38_DISABLED);
}
+ if (secure_video && !(p->srtp && (ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK) || ast_test_flag(p->srtp, SRTP_MIKEY_OFFER_OK)))) {
+ 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: */
ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability);
ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability);
@@ -9012,13 +9107,19 @@
struct ast_str *a_audio = ast_str_alloca(1024); /* Attributes for audio */
struct ast_str *a_video = ast_str_alloca(1024); /* Attributes for video */
struct ast_str *a_text = ast_str_alloca(1024); /* Attributes for text */
+ const char *a_crypto = NULL;
+ const char *a_mikey = NULL;
+
int x;
int capability;
+ const char *protocol = NULL;
+ struct sip_srtp *srtp = p->srtp;
int needaudio = FALSE;
int needvideo = FALSE;
int needtext = FALSE;
int debug = sip_debug_test_pvt(p);
+ const char a_encr_optional[] = "a=encryption:optional\r\n";
int min_audio_packet_size = 0;
int min_video_packet_size = 0;
int min_text_packet_size = 0;
@@ -9075,13 +9176,49 @@
/* Get our media addresses */
get_our_media_address(p, needvideo, &sin, &vsin, &tsin, &dest, &vdest);
+ /* Set encryption properties */
+ if (srtp) {
+ if (srtp->mikey) {
+ a_mikey = sdp_mikey_attrib(srtp->mikey);
+ } else if (srtp->crypto) {
+ a_crypto = sdp_crypto_attrib(srtp->crypto);
+ } else {
+ if (ast_test_flag(p->srtp, SRTP_CRYPTO_ENABLE)) {
+ srtp->crypto = sdp_crypto_setup();
+
+ if (srtp->crypto && (sdp_crypto_offer(srtp->crypto) >= 0)) {
+ a_crypto = sdp_crypto_attrib(srtp->crypto);
+ }
+ }
+
+ if (ast_test_flag(p->srtp, SRTP_MIKEY_ENABLE)) {
+ srtp->mikey = sdp_mikey_setup(p->peersecret, p->rtp);
+ if (srtp->mikey && (sdp_mikey_offer(srtp->mikey, p->rtp) >= 0)) {
+ a_mikey = sdp_mikey_attrib(srtp->mikey);
+ }
+ }
+ }
+
+ if (!a_crypto && !a_mikey) {
+ ast_log(LOG_WARNING, "No SRTP key management enabled (MIKEY or CRYPTO)\n");
+ }
+ }
+
+ if ((a_crypto || a_mikey) && !ast_test_flag(srtp, SRTP_ENCR_OPTIONAL)) {
+ protocol = "SAVP";
+ } else {
+ protocol = "AVP";
+ }
+
+
+
if (debug)
ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(sin.sin_port));
/* 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. */
if (needvideo) {
- ast_str_append(&m_video, 0, "m=video %d RTP/AVP", ntohs(vdest.sin_port));
+ ast_str_append(&m_video, 0, "m=video %d RTP/%s", ntohs(vdest.sin_port), protocol);
/* Build max bitrate string */
if (p->maxcallbitrate)
@@ -9130,7 +9267,7 @@
snprintf(owner, sizeof(owner), "o=%s %d %d IN IP4 %s\r\n", ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner, p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr));
snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
- ast_str_append(&m_audio, 0, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
+ ast_str_append(&m_audio, 0, "m=audio %d RTP/%s", ntohs(dest.sin_port), protocol);
if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR)
hold = "a=recvonly\r\n";
@@ -9239,6 +9376,16 @@
len += m_video->used + a_video->used + strlen(bandwidth) + strlen(hold);
if (needtext) /* only if text response is appropriate */
len += m_text->used + a_text->used + strlen(hold);
+
+ if (a_crypto) {
+ len += strlen(a_crypto);
+ if (ast_test_flag(srtp, SRTP_ENCR_OPTIONAL)) {
+ len += strlen(a_encr_optional);
+ }
+ }
+
+ if (a_mikey)
+ len += strlen(a_mikey);
add_header(resp, "Content-Type", "application/sdp");
add_header_contentLength(resp, len);
@@ -9263,6 +9410,15 @@
add_line(resp, m_text->str);
add_line(resp, a_text->str);
add_line(resp, hold); /* Repeat hold for the text stream */
+ }
+ if (a_mikey) {
+ add_line(resp, a_mikey);
+ }
+ if (a_crypto) {
+ add_line(resp, a_crypto);
+ if (ast_test_flag(srtp, SRTP_ENCR_OPTIONAL)) {
+ add_line(resp, a_encr_optional);
+ }
}
/* Update lastrtprx when we send our SDP */
@@ -23751,6 +23907,77 @@
);
}
+/*
+ * SRTP
+ */
+
+static int setup_srtp(struct sip_pvt *p)
+{
+ if (!ast_srtp_is_registered()) {
+ ast_log(LOG_ERROR, "No SRTP module loaded, can't setup SRTP session.\n");
+ return -1;
+ }
+
+ p->srtp = sip_srtp_alloc(); /* Allocate SRTP data structure */
+ if (!p->srtp)
+ return -1;
+
+ return 0;
+}
+
+static int process_crypto(struct sip_pvt *p, const char *a)
+{
+ if (!p->srtp) {
+ if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
+ ast_log(LOG_WARNING, "Ignoring unexpected crypto attribute in SDP answer\n");
+ return -1;
+ }
+
+ if (setup_srtp(p) < 0)
+ return -1;
+ }
+
+ if (!p->srtp->crypto)
+ p->srtp->crypto = sdp_crypto_setup();
+
+ if (!p->srtp->crypto)
+ return -1;
+
+ if (sdp_crypto_process(p->srtp->crypto, a, p->rtp) < 0)
+ return -1;
+
+ ast_set_flag(p->srtp, SRTP_CRYPTO_OFFER_OK);
+ return 0;
+}
+
+static int process_mikey(struct sip_pvt *p, const char *a)
+{
+ if (!p->srtp) {
+ if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
+ ast_log(LOG_WARNING, "Ignoring unexpected mikey attribute in SDP answer\n");
+ return -1;
+ }
+
+ if (setup_srtp(p) < 0) {
+ ast_log(LOG_WARNING, "Can't setup crypto\n");
+ return -1;
+ }
+ }
+ if (!p->srtp->mikey) {
+ p->srtp->mikey = sdp_mikey_setup(p->peersecret, p->rtp);
+ if (!p->srtp->mikey) {
+ ast_log(LOG_WARNING, "Can't setup MIKEY\n");
+ return -1;
+ }
+ }
+
+ if (sdp_mikey_process(p->srtp->mikey, a + 15, p->rtp) < 0)
+ return -1;
+
+ ast_set_flag(p->srtp, SRTP_MIKEY_OFFER_OK);
+ return -1;
+}
+
/*! \brief Send all MWI subscriptions */
static void sip_send_all_mwi_subscriptions(void)
{
@@ -23861,6 +24088,7 @@
static int load_module(void)
{
ast_verbose("SIP channel loading...\n");
+ sdp_mikey_init();
/* the fact that ao2_containers can't resize automatically is a major worry! */
/* if the number of objects gets above MAX_XXX_BUCKETS, things will slow down */
peers = ao2_t_container_alloc(hash_peer_size, peer_hash_cb, peer_cmp_cb, "allocate peers");
@@ -24067,6 +24295,8 @@
ast_unload_realtime("sipregs");
ast_unload_realtime("sippeers");
+ sdp_mikey_uninit();
+
return 0;
}
Added: team/group/srtp/channels/sdp_crypto.c
URL: http://svn.digium.com/view/asterisk/team/group/srtp/channels/sdp_crypto.c?view=auto&rev=165075
==============================================================================
--- team/group/srtp/channels/sdp_crypto.c (added)
+++ team/group/srtp/channels/sdp_crypto.c Tue Dec 16 23:36:03 2008
@@ -1,0 +1,309 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006 - 2007, 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.
+ */
+
+/*! \file sdp_crypto.c
+ *
+ * \brief SDP Security descriptions
+ *
+ * Specified in RFC 4568
+ *
+ * \author Mikael Magnusson <mikma at users.sourceforge.net>
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/options.h"
+#include "sdp_crypto.h"
+
+#define SRTP_MASTER_LEN 30
+#define SRTP_MASTERKEY_LEN 16
+#define SRTP_MASTERSALT_LEN (SRTP_MASTER_LEN - SRTP_MASTERKEY_LEN)
+#define SRTP_MASTER_LEN64 ((SRTP_MASTER_LEN * 8 + 5) / 6 + 1)
+
+struct sdp_crypto {
+ char *a_crypto;
+ unsigned char local_key[SRTP_MASTER_LEN];
+ char local_key64[SRTP_MASTER_LEN64];
+};
+
+static int set_crypto_policy(struct ast_srtp_policy *policy,
+ int suite_val, const unsigned char *master_key,
+ unsigned long ssrc, int inbound);
+
+
+static struct sdp_crypto *sdp_crypto_alloc(void)
+{
+ struct sdp_crypto *crypto = malloc(sizeof(*crypto));
+
+ if (crypto)
+ memset(crypto, 0, sizeof(*crypto));
+ else
+ ast_log(LOG_ERROR, "Out of memory, can't allocate crypto structure\n");
+
+ return crypto;
+}
+
+void sdp_crypto_destroy(struct sdp_crypto *crypto)
+{
+ if (crypto->a_crypto)
+ free(crypto->a_crypto);
+ crypto->a_crypto = NULL;
+ free(crypto);
+}
+
+struct sdp_crypto *sdp_crypto_setup(void)
+{
+ struct sdp_crypto *p = sdp_crypto_alloc();
+
+ if (!p)
+ return NULL;
+
+ if (ast_srtp_get_random(p->local_key, sizeof(p->local_key)) < 0) {
+ sdp_crypto_destroy(p);
+ return NULL;
+ }
+
+ ast_base64encode(p->local_key64, p->local_key,
+ SRTP_MASTER_LEN, sizeof(p->local_key64));
+
+ {
+ /* FIXME mikma, remove block */
+ int key_len;
+ unsigned char remote_key[SRTP_MASTER_LEN];
+
+ key_len = ast_base64decode(remote_key, p->local_key64, sizeof(remote_key));
+
+ if (key_len != SRTP_MASTER_LEN)
+ ast_log(LOG_ERROR, "base64 encode/decode bad len %d != %d\n", key_len, SRTP_MASTER_LEN);
+
+ if (memcmp(remote_key, p->local_key, SRTP_MASTER_LEN))
+ ast_log(LOG_ERROR, "base64 encode/decode bad key\n");
+ }
+
+ ast_log(LOG_DEBUG, "local_key64 %s len %zu\n", p->local_key64, strlen(p->local_key64));
+ return p;
+}
+
+static int set_crypto_policy(struct ast_srtp_policy *policy,
+ int suite_val, const unsigned char *master_key,
+ unsigned long ssrc, int inbound)
+{
+ const unsigned char *master_salt = NULL;
+
+ master_salt = master_key + SRTP_MASTERKEY_LEN;
+ if (ast_srtp_policy_set_master_key(policy,
+ master_key, SRTP_MASTERKEY_LEN,
+ master_salt, SRTP_MASTERSALT_LEN) < 0)
+ return -1;
+
+
+ if (ast_srtp_policy_set_suite(policy, suite_val)) {
+ ast_log(LOG_WARNING, "Could not set remote SRTP suite\n");
+ return -1;
+ }
+
+ ast_srtp_policy_set_ssrc(policy, ssrc, inbound);
+
+ return 0;
+}
+
+static int sdp_crypto_activate(struct sdp_crypto *p, int suite_val,
+ unsigned char *remote_key,
+ struct ast_rtp *rtp)
+{
+ struct ast_srtp_policy *local_policy = NULL;
+ struct ast_srtp_policy *remote_policy = NULL;
+ int res = -1;
+
+ if (!p)
+ return -1;
+
+ local_policy = ast_srtp_policy_alloc();
+ if (!local_policy)
+ goto err;
+
+ remote_policy = ast_srtp_policy_alloc();
+ if (!remote_policy) {
+ goto err;
+ }
+
+ if (set_crypto_policy(local_policy, suite_val, p->local_key,
+ ast_rtp_get_ssrc(rtp), 0) < 0)
+ goto err;
+
+ if (set_crypto_policy(remote_policy, suite_val, remote_key, 0, 1) < 0)
+ goto err;
+
+/* FIXME MIKMA */
+ if (ast_rtp_add_srtp_policy(rtp, local_policy)) {
+ ast_log(LOG_WARNING, "Could not set local SRTP policy\n");
+ goto err;
+ }
+
+ if (ast_rtp_add_srtp_policy(rtp, remote_policy)) {
+ ast_log(LOG_WARNING, "Could not set remote SRTP policy\n");
+ goto err;
+ }
+
+
+ if (option_debug > 1)
+ ast_log(LOG_DEBUG, "SRTP policy activated\n");
+ res = 0;
+
+err:
+ if (local_policy)
+ ast_srtp_policy_destroy(local_policy);
+
+ if (remote_policy)
+ ast_srtp_policy_destroy(remote_policy);
+ return res;
+}
+
+int sdp_crypto_process(struct sdp_crypto *p, const char *attr,
+ struct ast_rtp *rtp)
+{
+ char *str = NULL;
+ char *name = NULL;
+ char *tag = NULL;
+ char *suite = NULL;
+ char *key_params = NULL;
+ char *key_param = NULL;
+ char *session_params = NULL;
+ char *key_salt = NULL;
+ char *lifetime = NULL;
+ int found = 0;
+ int attr_len = strlen(attr);
+ int key_len = 0;
+ unsigned char remote_key[SRTP_MASTER_LEN];
+ int suite_val = 0;
+
+ if (!ast_srtp_is_registered())
+ return -1;
+
+ /* Crypto already accepted */
+/* if (p && p->a_crypto) */
+/* return -1; */
+
+ str = ast_strdupa(attr);
+
+ name = strsep(&str, ":");
+ tag = strsep(&str, " ");
+ suite = strsep(&str, " ");
+ key_params = strsep(&str, " ");
+ session_params = strsep(&str, " ");
+
+ if (!tag || !suite) {
+ ast_log(LOG_WARNING, "Unrecognized a=%s", attr);
+ return -1;
+ }
+
+ if (session_params) {
+ ast_log(LOG_WARNING, "Unsupported crypto parameters: %s",
+ session_params);
+ return -1;
+ }
+
+ if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80")) {
+ suite_val = AST_AES_CM_128_HMAC_SHA1_80;
+ } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
+ suite_val = AST_AES_CM_128_HMAC_SHA1_32;
+ } else {
+ ast_log(LOG_WARNING, "Unsupported crypto suite: %s",
+ suite);
+ return -1;
+ }
+
+ while ((key_param = strsep(&key_params, ";"))) {
+ char *method = NULL;
+ char *info = NULL;
+
+ method = strsep(&key_param, ":");
+ info = strsep(&key_param, ";");
+
+ if (!strcmp(method, "inline")) {
+ key_salt = strsep(&info, "|");
+ lifetime = strsep(&info, "|");
+
+ if (lifetime) {
+ ast_log(LOG_NOTICE, "Crypto life time unsupported: %s\n",
+ attr);
+ continue;
+ }
+
+/* if (info || strncmp(lifetime, "2^", 2)) { */
+/* ast_log(LOG_NOTICE, "MKI unsupported: %s\n", */
+/* attr); */
+/* continue; */
+/* } */
+
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ ast_log(LOG_NOTICE, "SRTP crypto offer not acceptable\n");
+ return -1;
+ }
+
+ key_len = ast_base64decode(remote_key, key_salt, sizeof(remote_key));
+ if (key_len != SRTP_MASTER_LEN) {
+ ast_log(LOG_WARNING, "SRTP sdescriptions key %d != %d\n",
+ key_len, SRTP_MASTER_LEN);
+ return -1;
+ }
+
+ if (sdp_crypto_activate(p, suite_val, remote_key, rtp) < 0)
+ return -1;
+
+ if (!p->a_crypto) {
+ free(p->a_crypto);
+
+ p->a_crypto = malloc(attr_len+11);
+ snprintf(p->a_crypto, attr_len+10,
+ "a=crypto:%s %s inline:%s\r\n",
+ tag, suite, p->local_key64);
+ }
+
+ return 0;
+}
+
+int sdp_crypto_offer(struct sdp_crypto *p)
+{
+ char crypto_buf[128];
+
+ /* Crypto offer */
+ const char *crypto_suite = "AES_CM_128_HMAC_SHA1_80";
+
+ if (p->a_crypto)
+ free(p->a_crypto);
+
+ snprintf(crypto_buf, sizeof(crypto_buf),
+ "a=crypto:1 %s inline:%s\r\n",
+ crypto_suite, p->local_key64);
+ p->a_crypto = strdup(crypto_buf);
+
+ return 0;
+}
+
+const char *sdp_crypto_attrib(struct sdp_crypto *p)
+{
+ return p->a_crypto;
+}
Propchange: team/group/srtp/channels/sdp_crypto.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/group/srtp/channels/sdp_crypto.c
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Propchange: team/group/srtp/channels/sdp_crypto.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/group/srtp/channels/sdp_crypto.h
URL: http://svn.digium.com/view/asterisk/team/group/srtp/channels/sdp_crypto.h?view=auto&rev=165075
==============================================================================
--- team/group/srtp/channels/sdp_crypto.h (added)
+++ team/group/srtp/channels/sdp_crypto.h Tue Dec 16 23:36:03 2008
@@ -1,0 +1,46 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006 - 2007, 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.
+ */
+
+/*! \file sdp_crypto.h
+ *
+ * \brief SDP Security descriptions
+ *
+ * Specified in RFC 4568
+ *
+ * \author Mikael Magnusson <mikma at users.sourceforge.net>
+ */
+
+#ifndef _SDP_CRYPTO_H
+#define _SDP_CRYPTO_H
+
+#include <asterisk/rtp.h>
+
+struct sdp_crypto;
+
+struct sdp_crypto *sdp_crypto_setup(void);
+void sdp_crypto_destroy(struct sdp_crypto *crypto);
+
+/* int sdp_crypto_activate(struct sdp_crypto *p, int suite_val, */
+/* unsigned char *remote_key, */
+/* struct ast_rtp *rtp); */
+int sdp_crypto_process(struct sdp_crypto *p, const char *attr,
+ struct ast_rtp *rtp);
+int sdp_crypto_offer(struct sdp_crypto *p);
+const char *sdp_crypto_attrib(struct sdp_crypto *p);
+
+#endif /* _SDP_CRYPTO_H */
Propchange: team/group/srtp/channels/sdp_crypto.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/group/srtp/channels/sdp_crypto.h
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Propchange: team/group/srtp/channels/sdp_crypto.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/group/srtp/channels/sdp_mikey.c
URL: http://svn.digium.com/view/asterisk/team/group/srtp/channels/sdp_mikey.c?view=auto&rev=165075
==============================================================================
--- team/group/srtp/channels/sdp_mikey.c (added)
+++ team/group/srtp/channels/sdp_mikey.c Tue Dec 16 23:36:03 2008
@@ -1,0 +1,275 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006 - 2007, 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.
+ */
+
+/*! \file sdp_mikey.c
+ *
+ * \brief SDP MIKEY key management
+ *
+ * SDP MIKEY key management
+ * Specified in RFC 3830 and 4567
+ *
+ * \author Mikael Magnusson <mikma at users.sourceforge.net>
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/options.h"
+#include "asterisk/rtp.h"
+#include "asterisk/mikey.h"
+#include "sdp_mikey.h"
+
+/*
+ MIKEY
+ Specified in: RFC 3830, RFC 4567
+*/
+
+/*
+ TODO disable rtp until keys are available.
+ TODO sometimes first RTP packet is received before rtp callback
+ is installed, leads to that ssrc not being activated.
+ */
+
+struct sdp_mikey {
+ struct mikey *mikey;
+ char *a_mikey;
+};
+
+static int sdp_mikey_activate(struct sdp_mikey *p, struct ast_rtp *rtp);
+
+
+int sdp_mikey_init(void)
+{
+ return 0;
+}
+
+void sdp_mikey_uninit(void)
+{
+}
+
+static struct sdp_mikey *sdp_mikey_alloc(void)
+{
+ struct ast_mikey_res *res = ast_get_mikey();
+ struct sdp_mikey *mikey;
+
+ if (!res) {
+ ast_log(LOG_ERROR, "res_mikey not loaded\n");
+ return NULL;
+ }
+
+ mikey = malloc(sizeof(*mikey));
+
+ if (mikey)
+ memset(mikey, 0, sizeof(*mikey));
+ else
+ ast_log(LOG_ERROR, "Out of memory, can't allocate mikey structure\n");
+
+ return mikey;
+}
+
+void sdp_mikey_destroy(struct sdp_mikey *p)
+{
+ struct ast_mikey_res *res = ast_get_mikey();
+
+ if (p->mikey)
+ res->mikey_destroy(p->mikey);
+ p->mikey = NULL;
+
+ if (p->a_mikey)
+ free(p->a_mikey);
+ p->a_mikey = NULL;
+
+ free(p);
+}
+
+struct sdp_mikey *sdp_mikey_setup(const char *peersecret,
+ struct ast_rtp *rtp)
+{
+ struct ast_mikey_res *res = ast_get_mikey();
+ struct sdp_mikey *p = sdp_mikey_alloc();
+
+ if (!p)
+ return NULL;
+
+ p->mikey = res->mikey_alloc();
+ if (peersecret) {
+ ast_log(LOG_NOTICE, "Using MIKEY PSK %s\n", peersecret);
+ res->mikey_set_psk_secret(p->mikey, (unsigned char*)peersecret,
+ strlen(peersecret));
+ }
+ else {
+ ast_log(LOG_NOTICE, "Now MIKEY PSK available\n");
+ }
+
+ res->mikey_set_ssrc(p->mikey, ast_rtp_get_ssrc(rtp));
+
+ return p;
+}
+
+int sdp_mikey_process(struct sdp_mikey *p, const char *attr,
+ struct ast_rtp *rtp)
+{
+ struct ast_mikey_res *mod = ast_get_mikey();
+ char buf[8192] = "a=key-mgmt:mikey ";
+ size_t prefixlen = strlen(buf);
+ size_t buflen = sizeof(buf) - prefixlen - 2;
+ int res;
+
+ if (!p->mikey) {
+ ast_log(LOG_ERROR, "No MIKEY object\n");
+ return -1;
+ }
+
+ ast_log(LOG_DEBUG, "%s\n", attr);
+
+ res = mod->mikey_process(p->mikey, attr, buf + prefixlen, buflen);
+
+ if (res < 0) {
+ ast_log(LOG_NOTICE, "Couldn't parse MIKEY offer\n");
+ return -1;
+ }
+
+ if (p->a_mikey)
+ free(p->a_mikey);
+ p->a_mikey = NULL;
+
+ if (sdp_mikey_activate(p, rtp) < 0)
+ return -1;
+
+ if (res > 0) {
+ /* Parsed offer, built response */
+ strcat(buf, "\r\n");
+
+ p->a_mikey = strdup(buf);
+ }
+ return 0;
+}
+
+int sdp_mikey_offer(struct sdp_mikey *p, struct ast_rtp *rtp)
+{
+ struct ast_mikey_res *mod = ast_get_mikey();
+ char buf[8192] = "a=key-mgmt:mikey ";
+ size_t prefixlen = strlen(buf);
+ size_t buflen = sizeof(buf) - prefixlen - 2;
+ int res;
+
+ /* Crypto already accepted */
+ if (p && p->a_mikey)
+ return -1;
+
+ res = mod->mikey_build_offer(p->mikey, buf + prefixlen, buflen, AST_MIKEY_TYPE_DH_HMAC);
+
+ if (res < 0) {
+ ast_log(LOG_NOTICE, "Couldn't build MIKEY offer\n");
+ return -1;
+ }
+
+ if (sdp_mikey_activate(p, rtp) < 0)
+ return -1;
+
+ strcat(buf, "\r\n");
+
+ if (p->a_mikey)
+ free(p->a_mikey);
+
+ p->a_mikey = strdup(buf);
+ return 0;
+}
+
+static int cb_no_ctx(struct ast_rtp *rtp, unsigned long ssrc, void *data)
+{
+ struct ast_mikey_res *mod = ast_get_mikey();
+ struct sdp_mikey *p = data;
+ struct ast_srtp_policy *policy = NULL;
+ int res = -1;
+
+ ast_log(LOG_DEBUG, "SRTP cb\n");
+
+ if (!p) {
+ ast_log(LOG_WARNING, "No pvt\n");
+ goto err;
+ }
+
+ if (!p->mikey) {
+ ast_log(LOG_WARNING, "No mikey\n");
+ goto err;
+ }
+
+ policy = mod->mikey_create_policy(p->mikey, ssrc);
+ if (!policy) {
+ ast_log(LOG_ERROR, "Could not create MIKEY policy\n");
+ goto err;
+ }
+
+ /* was p->rtp */
+ if (ast_rtp_add_srtp_policy(rtp, policy)) {
+ ast_log(LOG_ERROR, "Could not set SRTP policy\n");
+ goto err;
+ }
+
+ res = 0;
+
+err:
+ if (policy)
+ ast_srtp_policy_destroy(policy);
+ return res;
+}
+
+struct ast_srtp_cb srtp_cb = {
+ no_ctx: cb_no_ctx
+};
+
+static int sdp_mikey_activate(struct sdp_mikey *p, struct ast_rtp *rtp)
+{
+ struct ast_mikey_res *mod = ast_get_mikey();
+ struct ast_srtp_policy *policy = NULL;
+ int res = -1;
+
+ if (!p || !p->mikey)
+ return -1;
+
+ policy = mod->mikey_create_policy(p->mikey, ast_rtp_get_ssrc(rtp));
+ if (!policy) {
+ ast_log(LOG_ERROR, "Could not create MIKEY policy\n");
+ goto err;
+ }
+
+ if (ast_rtp_add_srtp_policy(rtp, policy)) {
+ ast_log(LOG_ERROR, "Could not set local SRTP policy\n");
+ goto err;
+ }
+
+ ast_rtp_set_srtp_cb(rtp, &srtp_cb, p);
+
+ if (option_debug > 1)
+ ast_log(LOG_NOTICE, "SRTP policy activated\n");
+ res = 0;
+
+err:
+ if (policy)
+ ast_srtp_policy_destroy(policy);
+ return res;
+}
+
+const char *sdp_mikey_attrib(struct sdp_mikey *p)
+{
+ ast_log(LOG_DEBUG, "Return mikey attrib %s\n", p->a_mikey);
+
+ return p->a_mikey;
+}
Propchange: team/group/srtp/channels/sdp_mikey.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/group/srtp/channels/sdp_mikey.c
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Propchange: team/group/srtp/channels/sdp_mikey.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/group/srtp/channels/sdp_mikey.h
URL: http://svn.digium.com/view/asterisk/team/group/srtp/channels/sdp_mikey.h?view=auto&rev=165075
==============================================================================
--- team/group/srtp/channels/sdp_mikey.h (added)
+++ team/group/srtp/channels/sdp_mikey.h Tue Dec 16 23:36:03 2008
@@ -1,0 +1,48 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006 - 2007, 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.
+ */
+
+/*! \file sdp_mikey.h
+ *
+ * \brief SDP MIKEY key management
+ *
+ * SDP MIKEY key management
+ * Specified in RFC 3830 and 4567
+ *
+ * \author Mikael Magnusson <mikma at users.sourceforge.net>
+ */
+
+#ifndef _SDP_MIKEY_H
+#define _SDP_MIKEY_H
+
+#include <asterisk/rtp.h>
+
+struct sdp_mikey;
+
+int sdp_mikey_init(void);
+void sdp_mikey_uninit(void);
+
+struct sdp_mikey *sdp_mikey_setup(const char *peersecret,
+ struct ast_rtp *rtp);
+void sdp_mikey_destroy(struct sdp_mikey *p);
+/* int sdp_mikey_activate(struct sdp_mikey *p, struct ast_rtp *rtp); */
+int sdp_mikey_offer(struct sdp_mikey *p, struct ast_rtp *rtp);
+int sdp_mikey_process(struct sdp_mikey *p, const char *attr,
+ struct ast_rtp *rtp);
+const char *sdp_mikey_attrib(struct sdp_mikey *p);
+
+#endif /* _SDP_MIKEY_H */
Propchange: team/group/srtp/channels/sdp_mikey.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/group/srtp/channels/sdp_mikey.h
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Propchange: team/group/srtp/channels/sdp_mikey.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/group/srtp/channels/sip_srtp.c
URL: http://svn.digium.com/view/asterisk/team/group/srtp/channels/sip_srtp.c?view=auto&rev=165075
==============================================================================
--- team/group/srtp/channels/sip_srtp.c (added)
+++ team/group/srtp/channels/sip_srtp.c Tue Dec 16 23:36:03 2008
@@ -1,0 +1,54 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006 - 2007, 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.
+ */
+
+/*! \file sip_srtp.c
+ *
+ * \brief SIP Secure RTP (SRTP)
+ *
+ * Specified in RFC 3711
+ *
+ * \author Mikael Magnusson <mikma at users.sourceforge.net>
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "sip_srtp.h"
+
+struct sip_srtp *sip_srtp_alloc(void)
+{
+ struct sip_srtp *srtp = malloc(sizeof(*srtp));
+
+ if (srtp)
+ memset(srtp, 0, sizeof(*srtp));
+ else
+ ast_log(LOG_ERROR, "Out of memory, can't allocate srtp structure\n");
+ return srtp;
+}
+
+void sip_srtp_destroy(struct sip_srtp *srtp)
+{
+ if (srtp->crypto)
+ sdp_crypto_destroy(srtp->crypto);
+ srtp->crypto = NULL;
+
+ if (srtp->mikey)
+ sdp_mikey_destroy(srtp->mikey);
+ srtp->mikey = NULL;
+}
Propchange: team/group/srtp/channels/sip_srtp.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/group/srtp/channels/sip_srtp.c
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Propchange: team/group/srtp/channels/sip_srtp.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/group/srtp/channels/sip_srtp.h
URL: http://svn.digium.com/view/asterisk/team/group/srtp/channels/sip_srtp.h?view=auto&rev=165075
==============================================================================
--- team/group/srtp/channels/sip_srtp.h (added)
+++ team/group/srtp/channels/sip_srtp.h Tue Dec 16 23:36:03 2008
@@ -1,0 +1,69 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006 - 2007, 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.
+ */
+
+/*! \file sip_srtp.h
+ *
+ * \brief SIP Secure RTP (SRTP)
+ *
[... 2490 lines stripped ...]
More information about the asterisk-commits
mailing list