on 02-25-2011 08:07 AM
This information has been translated from http://blog.voz-ip.com/2011/tlssrtp-en-asterisk-1-8/
Thanks to Gorka Gorrotxategi from Irontec (Spain), for his work on this setup
Here we come with a short post about how to configure one of the new Asterisk 1.8 features: Secure Communications via TLS and SRTP, providing ciphering and security.
These tests have been performed with Cisco SPA5XX IP Phones, and requires a small patch on Asterisk code (we will see below the reasons for the patch). It also work with other terminals such as Snom and Blink softphone.
The configuration will be explained briefly, as it explained in other places of the web.
[toc:faq]
Following are the commands required to compile the library
wget http://srtp.sourceforge.net/srtp-1.4.2.tgz
tar zxvf srtp-1.4.2.tgz
cd srtp/
CFLAGS="-Wall -O4 -fexpensive-optimizations -funroll-loops -fPIC" ./configure
make && make install
Following are the commands required to download and compile Asterisk
svn co http://svn.asterisk.org/svn/asterisk/tags/1.8.2.3/ asterisk18
cd asterisk18
./configure
make menuselect
(ensure that res_srtp is active on 'Resource Modules')
We now need to apply the patch mentioned before, why? The SPA5XX sends two lines with the crypto attribute:
a=crypto:1 AES_CM_128_HMAC_SHA1_32 inline:Ud154Hz42jLai6YI7RBcKtctTHBzIKjiHM6nGD36.
a=crypto:2 AES_CM_128_HMAC_SHA1_80 inline:Ud154Hz42jLai6YI7RBcKtctTHBzIKjiHM6nGD36.
Asterisk default code is not able to negotiate which method (AES_32 or AES_80) is going to be used for the ciphering. In fact, it always select the first one, and this is AES_32. Here the issue, Asterisk is able to handle both types, both offers only one of them, AES_80. The Asterisk patch force to signal the AES_32 method, to avoid audio issues due to different ciphering method used on each path. When this happens there is a non-ending warning message (30 per sec) on the CLI:
WARNING[25205]: res_srtp.c:338 ast_srtp_unprotect: SRTP unprotect: authentication failure
More Info is available on the Digium's bug tracker
We can see this problem clear on SIP traces (first INVITE from SPA then INVITE from Asterisk to destination):
INVITE sip:200@10.10.0.165 SIP/2.0.
From: ;tag=630e30c1d5621880o3.
To: "200" .
m=audio 16890 RTP/SAVP 8 0 9 18.
a=crypto:1 AES_CM_128_HMAC_SHA1_32 inline:hE+4XPMbPaF9/XEgIek7rUJiqoTEpLGZ1YXNiJhS.
a=crypto:2 AES_CM_128_HMAC_SHA1_80 inline:hE+4XPMbPaF9/XEgIek7rUJiqoTEpLGZ1YXNiJhS.
INVITE sip:200@10.10.0.177:5063 SIP/2.0.
From: "100" ;tag=as72caceda.
To: .
Contact: .
User-Agent: Asterisk PBX 1.8.2.3.
Remote-Party-ID: "100" ;party=calling;privacy=off;screen=no.
m=audio 12202 RTP/SAVP 8.
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:5uWtfxfK0vE90lTrgLTr83bRWTL2nCEFJ6NlXWjq.
The patch is really simple:
--- channels/sip/sdp_crypto.c 2010-06-08 07:29:08.708826000 +0200 +++ channels/sip/sdp_crypto.c 2011-02-24 17:37:00.514711568 +0100 @@ -287,7 +287,8 @@ int sdp_crypto_offer(struct sdp_crypto *p) { char crypto_buf[128]; - const char *crypto_suite = "AES_CM_128_HMAC_SHA1_80"; /* Crypto offer */ + //const char *crypto_suite = "AES_CM_128_HMAC_SHA1_80"; /* Crypto offer */ + const char *crypto_suite = "AES_CM_128_HMAC_SHA1_32"; /* Crypto offer */ if (p->a_crypto) { ast_free(p->a_crypto);
Then apply the patch (we named it sdp_crypto.patch):
patch -p0 < sdp_crypto.patch
(assuming we are on /usr/src/asterisk18 and have the patch on same folder)
Asterisk is patched!!! Now we can compile and install:
make && make install
openssl genrsa 1024 > host.key
openssl req -new -x509 -nodes -sha1 -days 365 -key host.key > host.cert
cat host.cert host.key > asterisk.pem
mv asterisk.pem /etc/asterisk/keys/
tlsenable=yes
tlsbindaddr=0.0.0.0
tlscertfile=/etc/asterisk/keys/asterisk.pem
transport=tls
(UDP is used by default)
After this configuration, we have secure signaling using TLS between Asterisk and the IP Phones. If you capture port 5061, you will see ciphered text.
....J...F..Mg|.L^
...E}.....A...d.|.~...... l..i9.j,..q"..............&./....5................0..~0...................0...*.H........0..1.0...U....ES1.0...U....Vizcaya1.0...U....Erandio1.0...U.
..Irontec1.0...U....VozIP1.0...U....Irontec1 0...*.H........vozip@irontec.com0...110215125446Z..210212125446Z0..1.0...U....ES1.0...U....Vizcaya1.0...U....Erandio1.0...U.
..Irontec1.0...U....VozIP1.0...U....Irontec1 0...*.H........vozip@irontec.com0..0...*.H............0........>.S.51...bND.J..Q..O.).-t.."~x..g&^t....E.*..@..n.jF...v.t.<....Zf...%Y.......[...[....HE.e....9..8...qc..|(...P.....*.c4>.V..........0..0...U.........En?.0.%.^......
.0....U.#...0.......En?.0.%.^......
.......0..1.0...U....ES1.0...U....Vizcaya1.0...U....Erandio1.0...U.
..Irontec1.0...U....VozIP1.0...U....Irontec1 0...*.H........vozip@irontec.com...........0...U....0....0...*.H............T.-F....R..2%.....T......=9.ye.z..6.0............i...O;.../s..e.........S.6.31......!iT......N....]........>XNt....Z...MHKH3...K.........
encryption=yes;
Voila! SRTP is configured!
Note: There is no optional SRTP mode in Asterisk, i.e. if encryption is active on peer, it will not accept non-ciphered audio and viceversa. On the IP phones, however, it is possible to have unsecure calls if the other peer does not support SRTP, i.e. incoming calls may work, but not outgoing calls. This is an Asterisk limitation (Snom supports also the “optional”mode on SRTP sending two m=audio attributes, but Asterisk does not know how to handle those descriptors).
The easiest test is to capture network traffic and verify with WireShark or similar software to check if signaling or RTP is clear text/audio or ciphered.
In our tests, we found an intermittent Warning on Asterisk CLI, but it does not seems to affect operation
WARNING[25205]: res_srtp.c:338 ast_srtp_unprotect: SRTP unprotect: authentication failure
We are still debugging this issue to understand what is causing it.
<end>
I have tried it step by step, at the moment I try to patch, I get a message:
root@pbx:/usr/src/asterisk18 $ patch -p0 < sdp_crypto.patch
patching file channels/sip/sdp_crypto.c
patch: **** malformed patch at line 4: int sdp_crypto_offer(struct sdp_crypto *p)
root@pbx:/usr/src/asterisk18 $
I am running Freepbx with Asterisk 1.8.28.0
The patch file must be created carefully to follow 'patch' program requirements. It seems you failed to do it properly.
If you are unable to prepare correct patch, then you can patch sources manually, according the instructions from patch file.
So, search for sdp_crypto_offer
function in channels/sip/sdp_crypto.c
source file, search for
const char *crypto_suite = "AES_CM_128_HMAC_SHA1_80"; /* Crypto offer */
line within it and replace the AES_CM_128_HMAC_SHA1_80 constant with AES_CM_128_HMAC_SHA1_32
That it is.
Thank you so much for your quick reply. I'm sorry to keep asking such questions, but I can't find such line.
This is what the function looks like in my sdp_crypto.c:
int sdp_crypto_offer(struct sdp_crypto *p)
{
if (ast_strlen_zero(p->suite)) {
/* Default crypto offer */
strcpy(p->suite, "AES_CM_128_HMAC_SHA1_32");
}
/* Rebuild the crypto line */
if (p->a_crypto) {
ast_free(p->a_crypto);
}
if (ast_asprintf(&p->a_crypto, "a=crypto:%s %s inline:%s\r\n",
p->tag ? p->tag : "1", p->suite, p->local_key64) == -1) {
ast_log(LOG_ERROR, "Could not allocate memory for crypto line\n");
return -1;
}
ast_log(LOG_DEBUG, "Crypto line: %s", p->a_crypto);
return 0;
}
const char *sdp_crypto_attrib(struct sdp_crypto *p)
{
return p->a_crypto;
}
The patch has been created for Asterisk 1.8.2.3
It seems that required change is already done in your's 1.8.28 version.
Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: