Hello,
This post is fairly long, and we expect that some of the subsequent posts will also be long, so we are creating and maintaining a document on our ftp site with the same information as in the posts. This document can be accessed at
ftp://ftp.signalogic.com/mailing_lists/sr-dev_post_24Mar10.pdf
Current Work ------------
Below I have tried to summarize modifications made to nathelper, Rtpproxy and Kamailio.cfg to support encryption/decryption below
1) Nathelper
Nathelper defines a new function force_rtp_proxy_ex(). This function is an extension of the existing force_rtp_proxy(). force_rtp_proxy_ex() has the following additional features when compared to force_rtp_proxy()
(a) force_rtp_proxy_ex() takes an additional flag '_' as input. The presence of this flag indicates that rtp streams being setup by associated SIP messages are encrypted using a custom encryption algorithm. The '_' flag is in place only because SDP contains no information regarding encryption.
(b) Number of elements in struct iovec array, has been increased to include more information to rtpproxy while passing commands. Additional information that is passed to rtpproxy includes common SRTP parameters like
(i) Encryption type (ii) Encryption key scheme (iii) Encryption authorization type (iv) Salt size (v) Encryption mode (vi) Encryption key length
(c) Duplicated functions force_rtp_proxy0_f(), force_rtp_proxy1_f(), force_rtp_proxy2_f()for use with force_rtp_proxy_ex()
2) Rtpproxy
Rtpproxy now includes a sub-structure in the rtpp_session structure. Implementation details are given below
(a) rtpp_session.h defines a new sub-structure 'struct DS_Encryption_attributes' under the rtpp_session structure. The DS_Encryption_Attributes structure is detailed below. All relevant enum types have also been defined in rtpp_session.h
struct DS_Encryption_Attributes{ DS_ENCRYPTION_TYPE EncryptionType; char *EncryptionKey; short KeyLengthU8; short SaltSizeU8; DS_ENCRYPTION_MODE EncryptionMode; DS_ENCRYPTION_KEY_SCHEME KeyScheme; DS_ENCRYPTION_AUTH_TYPE AuthType; };
(b) rtpp_command.c modified to understand the '_' flag in nathelper's new command. Upon receiving the '_' command from nathelper, rtpproxy now populates the DS_Encryption_Attributes structure associated with the appropriate rtp session.
(c) main.c modified to decrypt/encrypt rtp packets soon after reception or just before sending respectively, if valid parameters have been defined in the sessions encryption attributes. main.c defines a new include file, that contains the actual encryption/decryption algorithm.
3)Kamailo.cfg
Kamailio's configuration file now takes a new function call force_rtp_proxy_ex(). It accepts all the same flags and parameters as force_rtp_proxy() excepting for an additional '_' flag followed by an encryption key. This key is then passed onto rtpproxy through nathelper where rtpproxy populates the EncryptionKey field of the appropriate rtp session's DS_Encryption_Attributes structure using the string that appears after the '_' flag.
4)Encryption module
The encryption module is a C implementation of the encryption/decryption algorithm and is included as #include "crypt.h" within main.c of rtpproxy. The API used while making calls to the encryption/decryption function is given below
void crypt(unsigned char *rtp_payload,unsigned int pkt_length, struct DS_Encryption_Attributes enc_attr);
The encryption/decryption is just a first step. For now these are simple, packet based APIs. However in order to support high capacity server acceleration cards that have their own GbE interface, we are also adding call-based APIs, which can be used to establish a sequence of processing operations and data flow, including GbE termination with fully formed IP/UDP/RTP packets.
Hopefully the above summary is useful. After some discussion here, we feel this type of "start simple" sequence allows us to (i) get a good understanding of how Kamailio and rtpproxy work at a basic level, such that our changes hold up over the long term, and (ii) have a good chance to get feedback and constructive criticism from the group
Long-Term Concerns ------------------ Our efforts so far have primarily been customer driven. But as you know we’re worried about correct implementation that meets with approval of the developers’ group, and holds up over the long term. Some of our larger concerns include:
(a) Transcoding. What would be the best way to handle scenarios such as (i) Two endpoints that do not have a codec in common, but still want to communicate through a proxy server capable of transcoding. How do we “spoof” one or both endpoints? Or does the proxy somehow “advertise” its capabilities? (ii) Encode only to satisfy need to record at lower bitrate to conserve disk space (iii) Decode only to satisfy lawful interception or other “third party” requirement
(b) Incorporating Kamailio / SIP proxy level support for SRTP. Our main area of worry is key management protocol and distribution. Here are a couple of scenarios: (i) A proxy needs to know the encryption keys (one example lawful interception) (ii) One or both endpoints of a call cannot handle SRTP so the proxy must implement encryption/decryption for one or both endpoints
Any comments/suggestions on the above will be appreciated.
Thanks and Regards, Vikram.