/* $Id$ */ /* * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) * Copyright (C) 2003-2008 Benny Prijono * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PJMEDIA_TRANSPORT_SRTP_H__ #define __PJMEDIA_TRANSPORT_SRTP_H__ /** * @file transport_srtp.h * @brief Secure RTP (SRTP) transport. */ #include /** * @defgroup PJMEDIA_TRANSPORT_SRTP Secure RTP (SRTP) Media Transport * @ingroup PJMEDIA_TRANSPORT * @brief Media transport adapter to add SRTP feature to existing transports * @{ * * This module implements SRTP as described by RFC 3711, using RFC 4568 as * key exchange method. It implements \ref PJMEDIA_TRANSPORT to integrate * with the rest of PJMEDIA framework. * * 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 html 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 html 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. */ PJ_BEGIN_DECL /** * Crypto option. */ typedef enum pjmedia_srtp_crypto_option { /** When this flag is specified, encryption will be disabled. */ PJMEDIA_SRTP_NO_ENCRYPTION = 1, /** When this flag is specified, authentication will be disabled. */ PJMEDIA_SRTP_NO_AUTHENTICATION = 2 } pjmedia_srtp_crypto_option; /** * This structure describes an individual crypto setting. */ typedef struct pjmedia_srtp_crypto { /** Optional key. If empty, a random key will be autogenerated. */ pj_str_t key; /** Crypto name. */ pj_str_t name; /** Flags, bitmask from #pjmedia_srtp_crypto_option */ unsigned flags; } pjmedia_srtp_crypto; /** * This enumeration specifies the behavior of the SRTP transport regarding * media security offer and answer. */ typedef enum pjmedia_srtp_use { /** * When this flag is specified, SRTP will be disabled, and the transport * will reject RTP/SAVP offer. */ PJMEDIA_SRTP_DISABLED, /** * When this flag is specified, SRTP will be advertised as optional and * incoming SRTP offer will be accepted. */ PJMEDIA_SRTP_OPTIONAL, /** * When this flag is specified, the transport will require that RTP/SAVP * media shall be used. */ PJMEDIA_SRTP_MANDATORY } pjmedia_srtp_use; /** * This enumeration specifies SRTP keying methods. */ typedef enum pjmedia_srtp_keying_method { /** * Session Description (SDES). */ PJMEDIA_SRTP_KEYING_SDES, /** * DTLS-SRTP. */ PJMEDIA_SRTP_KEYING_DTLS_SRTP, /** * Number of keying method. */ PJMEDIA_SRTP_KEYINGS_COUNT } pjmedia_srtp_keying_method; /** * Structure containing callbacks to receive SRTP notifications. */ typedef struct pjmedia_srtp_cb { /** * This callback will be called when SRTP negotiation completes. This * callback will be invoked when the negotiation is done outside of * the SDP signalling, such as in DTLS-SRTP. * * @param tp PJMEDIA SRTP transport. * @param status Operation status. */ void (*on_srtp_nego_complete)(pjmedia_transport *tp, pj_status_t status); } pjmedia_srtp_cb; /** * Settings to be given when creating SRTP transport. Application should call * #pjmedia_srtp_setting_default() to initialize this structure with its * default values. */ typedef struct pjmedia_srtp_setting { /** * Specify the usage policy. Default is PJMEDIA_SRTP_OPTIONAL. */ pjmedia_srtp_use use; /** * Specify whether the SRTP transport should close the member transport * when it is destroyed. Default: PJ_TRUE. */ pj_bool_t close_member_tp; /** * Specify the number of crypto suite settings. If set to zero, all * available cryptos will be enabled. Default: zero. */ unsigned crypto_count; /** * Specify individual crypto suite setting and its priority order. * * Notes for DTLS-SRTP keying: * - Currently only supports these cryptos: AES_CM_128_HMAC_SHA1_80, * AES_CM_128_HMAC_SHA1_32, AEAD_AES_256_GCM, and AEAD_AES_128_GCM. * - SRTP key is not configurable. */ pjmedia_srtp_crypto crypto[PJMEDIA_SRTP_MAX_CRYPTOS]; /** * Specify the number of enabled keying methods. If set to zero, all * keyings will be enabled. Maximum value is PJMEDIA_SRTP_MAX_KEYINGS. * * Default is zero (all keyings are enabled with priority order: * SDES, DTLS-SRTP). */ unsigned keying_count; /** * Specify enabled keying methods and its priority order. Keying method * with higher priority will be given earlier chance to process the SDP, * for example as currently only one keying is supported in the SDP offer, * keying with first priority will be likely used in the SDP offer. */ pjmedia_srtp_keying_method keying[PJMEDIA_SRTP_KEYINGS_COUNT]; /** * Specify SRTP callback. */ pjmedia_srtp_cb cb; /** * Specify SRTP transport user data. */ void *user_data; } pjmedia_srtp_setting; /** * This structure specifies SRTP transport specific info. This will fit * into \a buffer field of pjmedia_transport_specific_info. */ typedef struct pjmedia_srtp_info { /** * Specify whether the SRTP transport is active for SRTP session. */ pj_bool_t active; /** * Specify the policy used by the SRTP session for receive direction. */ pjmedia_srtp_crypto rx_policy; /** * Specify the policy used by the SRTP session for transmit direction. */ pjmedia_srtp_crypto tx_policy; /** * Specify the usage policy. */ pjmedia_srtp_use use; /** * Specify the peer's usage policy. */ pjmedia_srtp_use peer_use; } pjmedia_srtp_info; /** * This structure specifies DTLS-SRTP negotiation parameters. */ typedef struct pjmedia_srtp_dtls_nego_param { /** * Fingerprint of remote certificate, should be formatted as * "SHA-256/1 XX:XX:XX...". If this is not set, fingerprint verification * will not be performed. */ pj_str_t rem_fingerprint; /** * Remote address and port. */ pj_sockaddr rem_addr; /** * Remote RTCP address and port. */ pj_sockaddr rem_rtcp; /** * Set to PJ_TRUE if our role is active. Active role will initiates * the DTLS negotiation. Passive role will wait for incoming DTLS * negotiation packet. */ pj_bool_t is_role_active; } pjmedia_srtp_dtls_nego_param; /** * Initialize SRTP library. This function should be called before * any SRTP functions, however calling #pjmedia_transport_srtp_create() * will also invoke this function. This function will also register SRTP * library deinitialization to #pj_atexit(), so the deinitialization * of SRTP library will be performed automatically by PJLIB destructor. * * @param endpt The media endpoint instance. * * @return PJ_SUCCESS on success. */ PJ_DECL(pj_status_t) pjmedia_srtp_init_lib(pjmedia_endpt *endpt); /** * Initialize SRTP setting with its default values. * * @param opt SRTP setting to be initialized. */ PJ_DECL(void) pjmedia_srtp_setting_default(pjmedia_srtp_setting *opt); /** * Enumerate available SRTP crypto name. * * @param count On input, specifies the maximum length of crypto * array. On output, the number of available crypto * initialized by this function. * @param crypto The SRTP crypto array output. * * @return PJ_SUCCESS on success. */ PJ_DECL(pj_status_t) pjmedia_srtp_enum_crypto(unsigned *count, pjmedia_srtp_crypto crypto[]); /** * Enumerate available SRTP keying methods. * * @param count On input, specifies the maximum length of keying method * array. On output, the number of available keying method * initialized by this function. * @param crypto The SRTP keying method array output. * * @return PJ_SUCCESS on success. */ PJ_DECL(pj_status_t) pjmedia_srtp_enum_keying(unsigned *count, pjmedia_srtp_keying_method keying[]); /** * Create an SRTP media transport. * * @param endpt The media endpoint instance. * @param tp The actual media transport to send and receive * RTP/RTCP packets. This media transport will be * kept as member transport of this SRTP instance. * @param opt Optional settings. If NULL is given, default * settings will be used. * @param p_tp Pointer to receive the transport SRTP instance. * * @return PJ_SUCCESS on success. */ PJ_DECL(pj_status_t) pjmedia_transport_srtp_create( pjmedia_endpt *endpt, pjmedia_transport *tp, const pjmedia_srtp_setting *opt, pjmedia_transport **p_tp); /** * Get fingerprint of local DTLS-SRTP certificate. * * @param srtp The SRTP transport. * @param hash Fingerprint hash algorithm, currently valid values are * "SHA-256" and "SHA-1". * @param buf Buffer for fingerprint output. The output will be * formatted as "SHA-256/1 XX:XX:XX..." and null terminated. * @param len On input, the size of the buffer. * On output, the length of the fingerprint. * * @return PJ_SUCCESS on success. */ PJ_DECL(pj_status_t) pjmedia_transport_srtp_dtls_get_fingerprint( pjmedia_transport *srtp, const char *hash, char *buf, pj_size_t *len); /** * Manually start DTLS-SRTP negotiation with the given parameters. Application * only needs to call this function when the SRTP transport is used without * SDP offer/answer. When SDP offer/answer framework is used, the DTLS-SRTP * negotiation will be handled by pjmedia_transport_media_create(), * pjmedia_transport_media_start(), pjmedia_transport_media_encode_sdp(), and * pjmedia_transport_media_stop(). * * When the negotiation completes, application will be notified via SRTP * callback on_srtp_nego_complete(), if set. If the negotiation is successful, * SRTP will be automatically started. * * Note that if the SRTP member transport is an ICE transport, application * should only call this function after ICE negotiation is completed * successfully. * * @param srtp The SRTP transport. * @param param DTLS-SRTP nego parameter. * * @return PJ_SUCCESS on success. */ PJ_DECL(pj_status_t) pjmedia_transport_srtp_dtls_start_nego( pjmedia_transport *srtp, const pjmedia_srtp_dtls_nego_param *param); /** * Manually start SRTP session with the given parameters. Application only * needs to call this function when the SRTP transport is used without SDP * offer/answer. When SDP offer/answer framework is used, the SRTP transport * will be started/stopped by #pjmedia_transport_media_start() and * #pjmedia_transport_media_stop() respectively. * * Please note that even if an RTP stream is only one direction, application * will still need to provide both crypto suites, because it is needed by * RTCP. * If application specifies the crypto keys, the keys for transmit and receive * direction MUST be different. * * @param srtp The SRTP transport. * @param tx Crypto suite setting for transmit direction. * @param rx Crypto suite setting for receive direction. * * @return PJ_SUCCESS on success. */ PJ_DECL(pj_status_t) pjmedia_transport_srtp_start( pjmedia_transport *srtp, const pjmedia_srtp_crypto *tx, const pjmedia_srtp_crypto *rx); /** * Stop SRTP session. * * @param srtp The SRTP media transport. * * @return PJ_SUCCESS on success. * * @see #pjmedia_transport_srtp_start() */ PJ_DECL(pj_status_t) pjmedia_transport_srtp_stop(pjmedia_transport *srtp); /** * This is a utility function to decrypt SRTP packet using SRTP transport. * This function is not part of SRTP transport's API, but it can be used * to decrypt SRTP packets from non-network (for example, from a saved file) * without having to use the transport framework. See pcaputil.c in the * samples collection on how to use this function. * * @param tp The SRTP transport. * @param is_rtp Set to non-zero if the packet is SRTP, otherwise set * to zero if the packet is SRTCP. * @param pkt On input, it contains SRTP or SRTCP packet. On * output, it contains the decrypted RTP/RTCP packet. * @param pkt_len On input, specify the length of the buffer. On * output, it will be filled with the actual length * of decrypted packet. * * @return PJ_SUCCESS on success. */ PJ_DECL(pj_status_t) pjmedia_transport_srtp_decrypt_pkt(pjmedia_transport *tp, pj_bool_t is_rtp, void *pkt, int *pkt_len); /** * Query member transport of SRTP. * * @param srtp The SRTP media transport. * * @return member media transport. */ PJ_DECL(pjmedia_transport*) pjmedia_transport_srtp_get_member( pjmedia_transport *srtp); PJ_END_DECL /** * @} */ #endif /* __PJMEDIA_TRANSPORT_SRTP_H__ */