= SRTP Support in PJSIP = This article describes about SRTP support in PJSIP. SRTP support is included in version 0.9 (see ticket #61). '''Table of Contents''' [[PageOutline(2-3,,inline)]] ---- == Features == The SRTP functionality in PJSIP has the following features: - SRTP ([http://www.ietf.org/rfc/rfc3711.txt RFC 3711]), using the Open Source [http://sourceforge.net/projects/srtp/ libsrtp] library. - Keys exchange using Security Descriptions for Media Streams (SDESC, [http://www.ietf.org/rfc/rfc4568.txt RFC 4568]) - Supported cryptos: - AES_CM_128_HMAC_SHA1_80 - AES_CM_128_HMAC_SHA1_32 - Secure RTCP (SRTCP) is supported. Negotiation of crypto session parameters in SDP is currently not supported. ---- == Compatibility Info == Few notes regarding compatibility with previous PJSIP code. === Build Systems === There is a new third party library in the distribution, namely '''{{{libsrtp}}}''', you will need to add this library into your application's input libraries specification. '''For GNU build systems:''' 1. You will need to re-run {{{./configure}}}, {{{make dep}}} and {{{make}}} to update {{{build.mak}}} and rebuild the project dependencies. 1. If your Makefile includes {{{build.mak}}} (as explained in [wiki:Getting_Started_Using Getting Started part 2]), you just need to rebuild your application as the input libraries will be updated automatically (by {{{build.mak}}}). 1. If you maintain your own independent Makefile, please add {{{libsrtp-$(TARGET)}}} from {{{third_party/lib}}} directory to your input libraries. '''For Visual Studio 6 and 2005:''' 1. New {{{libsrtp}}} project has been added into '''pjproject.dsw''' and '''pjproject-vs8.sln''' workspace. 1. If you maintain your own application workspace, you need to add {{{libsrtp}}} project into your application. The {{{libsrtp}}} project files are in {{{third_party/build/srtp}}} directory. '''For Windows Mobile developments:''' 1. New {{{libsrtp}}} project has been added into '''wince_demos.vcw''' workspace (the workspace is located in {{{pjsip-apps/build/wince-evc4}}} directory). 1. If you maintain your own application workspace, you need to add '''{{{libsrtp.vcp}}}''' project into your application. The {{{libsrtp}}} project files are in {{{third_party/build/srtp}}} directory. 1. If you're using Visual Studio rather than Embedded Visual C++ 4, make sure you import the Embedded Visual Studio project ({{{libsrtp.vcp}}}) rather than the Visual Studio ({{{libsrtp.vcproj}}}) project! '''Symbian:''' ''Updated 2009/01/15:'' 1. The {{{libsrtp.mmp}}} has been added to {{{bld.inf}}} on June '08 for version 0.9. It should be shown in your Carbide or !CodeWarrior workspace when you import the {{{bld.inf}}}. === API Changes === Changes: - New callbacks have been added in media transport interface which may break your application, depending on the API level that you use. The changes will be explained in [#med-tp-changes Changes in Media Transport Interface] section below. - Removed const specification from media transport's RTP and RTCP callback to allow packets to be modified in place. If you are working directly with PJMEDIA transport API, there may be changes required in your code. If you are working on PJSUA-LIB API level, there should be no changes in your application. ---- == Requirements == SRTP feature in PJSIP uses the Open Source [http://sourceforge.net/projects/srtp/ libsrtp] library created by David A. !McGrew of Cisco Systems, Inc. Copy of [http://sourceforge.net/projects/srtp/ libsrtp] is included in PJSIP source tree in {{{third_party/srtp}}} directory. There is no other software to download. [http://sourceforge.net/projects/srtp/ libsrtp] is distributed under BSD-like license, you must satisfy the license requirements if you incorporate SRTP in your application. Please see [http://www.pjsip.org/licensing.htm PJSIP licensing] page for more information about this and other third party libraries licensing in PJSIP. ---- == Building PJSIP with SRTP Support == === Availability === SRTP feature is currently available in: - Visual C++ 6 and 2005 (for Windows targets) - GNU based build system (for Linux, including uC-Linux for embedded systems, Mingw, MacOS X, and *nix based platforms) - Windows Mobile targets - Symbian targets === Building === libsrtp is always built by default, from {{{third_party/build/srtp}}} directory. Support for SRTP is enabled by default in PJMEDIA and PJSUA-LIB. To '''disable''' this feature, declare this in your {{{config_site.h}}}: {{{ #define PJMEDIA_HAS_SRTP 0 }}} ---- == Using SRTP == SRTP is implemented as media transport in PJMEDIA. In the high level [http://www.pjsip.org/pjsip/docs/html/group__PJSUA__LIB.htm PJSUA-LIB API], the use of SRTP is controlled by couple of settings as explained below. === Using SRTP in PJSUA-LIB === In [http://www.pjsip.org/pjsip/docs/html/group__PJSUA__LIB.htm PJSUA-LIB], the use of SRTP is controlled by settings in both [http://www.pjsip.org/pjsip/docs/html/structpjsua__config.htm pjsua_config] and [http://www.pjsip.org/pjsip/docs/html/structpjsua__acc__config.htm pjsua_acc_config]. The settings in [http://www.pjsip.org/pjsip/docs/html/structpjsua__config.htm pjsua_config] specify the default settings for all accounts, and the settings in [http://www.pjsip.org/pjsip/docs/html/structpjsua__acc__config.htm pjsua_acc_config] can be used to further set the behavior for that specific account. In both {{{pjsua_config}}} and {{{pjsua_acc_config}}}, there are two configuration items related to SRTP: '''{{{use_srtp}}}''':: This option controls whether secure media transport (SRTP) should be used for this account. Valid values are: - {{{PJMEDIA_SRTP_DISABLED}}} (0): SRTP is disabled, and incoming call with RTP/SAVP transport will be rejected with 488/Not Acceptable Here response. - {{{PJMEDIA_SRTP_OPTIONAL}}} (1): SRTP will be advertised and SRTP will be used if remote supports it, but the call may fall back to unsecure media. Incoming call with RTP/SAVP is accepted and responded with RTP/SAVP too. - {{{PJMEDIA_SRTP_MANDATORY}}} (2): secure media is mandatory, and the call can only proceed if secure media can be established. The default value for this option is {{{PJSUA_DEFAULT_USE_SRTP}}}, which is zero (disabled). '''{{{srtp_secure_signaling}}}''':: This option controls whether SRTP requires secure signaling to be used. This option is only used when {{{use_srtp}}} option above is non-zero. Valid values are: - 0: SRTP does not require secure signaling (not recommended) - 1: SRTP requires secure transport such as TLS to be used. - 2: SRTP requires secure end-to-end transport ('''sips:''' URI scheme) to be used. The default value for this option is {{{PJSUA_DEFAULT_SRTP_SECURE_SIGNALING}}}, which is 1 (require TLS transport). === pjsua === Two new options were added to [http://www.pjsip.org/pjsua.htm pjsua]: '''{{{--use-srtp=N}}}''' This corresponds to {{{use_srtp}}} setting above. Valid values are 0, 1, or 2. Default value is 0. '''{{{--srtp-secure=N}}}''' This corresponds to {{{srtp_secure_signaling}}} setting above. Valid values are 0, 1, or 2. Default value is 1. Sample usage: {{{ $ ./pjsua --use-tls --use-srtp=1 sip:alice@example.com;transport=tls }}} === Using SRTP Transport Directly === The SRTP transport may also be used directly without having to involve SDP negotiations (for example, to use SRTP without SIP). Please see '''[http://www.pjsip.org/pjmedia/docs/html/page_pjmedia_samples_streamutil_c.htm streamutil]''' from the samples collection for a sample application. For this to work, you will need to have a different mechanism to exchange keys between endpoints. To use SRTP transport directly: - Call [http://www.pjsip.org/pjmedia/docs/html/group__PJMEDIA__TRANSPORT.htm#gf4a10278c4586f5239ee7a698aa4a85d pjmedia_transport_srtp_create()] to create the SRTP adapter, giving it the actual media transport instance (such as UDP transport). - Call [http://www.pjsip.org/pjmedia/docs/html/group__PJMEDIA__TRANSPORT__SRTP.htm#gb603d4f070665cb1a8038c021a6019e6 pjmedia_transport_srtp_start()] to active SRTP session, giving it both local and remote crypto settings and keys. - Call [http://www.pjsip.org/pjmedia/docs/html/group__PJMEDIA__TRANSPORT.htm#g13bbd87a2d4868229c95711065905cfa pjmedia_transport_attach()] to configure the remote RTP/RTCP addresses and attach your RTP and RTCP callbacks. - Call [http://www.pjsip.org/pjmedia/docs/html/group__PJMEDIA__TRANSPORT.htm#g79db5c82268501ec3bf7c1897c0b3626 pjmedia_transport_send_rtp()] and [http://www.pjsip.org/pjmedia/docs/html/group__PJMEDIA__TRANSPORT.htm#g5fe97ac16287563420950a8b87d247b4 pjmedia_transport_send_rtcp()] to send RTP/RTCP packets. - Once you done with your session, call [http://www.pjsip.org/pjmedia/docs/html/group__PJMEDIA__TRANSPORT.htm#g0114fa7e20cb17c645701b2dbda96452 pjmedia_transport_close()] to destroy the SRTP adapter (and optionally the actual transport which is attached to the SRTP adapter, depending on whether ''close_member_tp'' flag is set in the [http://www.pjsip.org/pjmedia/docs/html/structpjmedia__srtp__setting.htm pjmedia_srtp_setting] when creating the SRTP adapter). ---- == Implementation Notes == === Changes in Media Transport Interface === #med-tp-changes Since the availability of SRTP changes SDP (Session Description Protocol) contents and the SDP negotiation, we needed to modify/add new interfaces in PJMEDIA transport API to allow media transport to modify and negotiate SDP. Incidently this would work well with ICE too (previously we treat ICE as a special kind of media transport so it is treated differently, but with this new interfaces, all media transports will behave uniformly (anyway that's what API abstraction is for!)). New interfaces in media transport are as follows (please consult the PJMEDIA transport documentation for more info): '''[http://www.pjsip.org/pjmedia/docs/html/group__PJMEDIA__TRANSPORT.htm#gf4a10278c4586f5239ee7a698aa4a85d media_create()]''':: This callback is called by application (or PJSUA-LIB) to allow the media transport to add more information in the SDP offer, before the offer is sent to remote. Additionally, for answerer side, this callback allows the media transport to reject the offer before this offer is processed by the SDP negotiator. '''[http://www.pjsip.org/pjmedia/docs/html/group__PJMEDIA__TRANSPORT.htm#g8031382904162781e4b58fcee0a62dcd media_start()]''':: This callback is called after offer and answer are negotiated, and both SDPs are available, and before the media is started. For answerer side, this callback will be called before the answer is sent to remote, to allow media transport to put additional info in the SDP. For offerer side, this callback will be called after SDP answer is received. In this callback, the media transport has the final chance to negotiate/validate the offer and answer before media is really started (and answer is sent, for answerer side). '''[http://www.pjsip.org/pjmedia/docs/html/group__PJMEDIA__TRANSPORT.htm#ged068de25cc5cbda27c1b7058597d3b5 media_stop()]''':: This callback is called when the media is stopped, to allow the media transport to release its resources. '''[http://www.pjsip.org/pjmedia/docs/html/group__PJMEDIA__TRANSPORT.htm#g30e410ca02a4e815346b5e5fa505e7b5 simulate_lost()]''':: This has nothing to do with SRTP, but since all media transports support this feature (packet loss simulation), we added this as a new interface. === pjmedia_transport_srtp Implementation === As we know, media transport is separated from the stream object (which does the encoding/decoding of PCM frames, (de)packetization of RTP/RTCP packets, and de-jitter buffering). The connection between stream and media transport is established when the stream is created (we need to specify media transport during stream creation), and the interconnection can be depicted from the diagram below: [[Image(media-transport.PNG)]] I think the diagram above is self-explanatory. SRTP functionality is implemented as some kind of "adapter", which is plugged between the stream and the actual media transport that does sending/receiving RTP/RTCP packets. When SRTP is used, the interconnection between stream and transport is like the diagram below: [[Image(media-srtp-transport.PNG)]] So to stream, the SRTP transport behaves as if it is a media transport (because it '''is''' a media transport), and to the media transport it behaves as if it is a stream. The SRTP object then forwards RTP packets back and forth between stream and the actual transport, encrypting/decrypting the RTP/RTCP packets as necessary. The neat thing about this design is the SRTP "adapter" then can be used to encrypt any kind of media transports. We currently have UDP and ICE media transports that can benefit SRTP, and we could add SRTP to any media transports that will be added in the future. === AES-GCM support === Pjsip 2.6 enabled the support for AES-GCM (#1943), however the bundled libSRTP (1.5.4) at that time has compatibility issue with OpenSSL 1.1.0. Updating the libSRTP was done in #1993, included in 2.7. As an alternative to the bundled libSRTP, users are also allowed to use external libSRTP by specifying `--with-external-srtp`. Using #2050, it's been tested to work with external libSRTP 1.5.4 and 2.1.0. Note about this option, using libSRTP with AES-GCM would also require the user to enable building pjsip with ssl.