pjproject/pjmedia/include/pjmedia/transport_srtp.h

580 lines
18 KiB
C

/*
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
*
* 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 <pjmedia/transport.h>
/**
* @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:
*
\img{pjmedia/docs/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:
*
\img{pjmedia/docs/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 setting is unknown. This is to set
* the initial remote's SRTP usage. It will be set later after remote's
* policy in the SDP is received.
*/
PJMEDIA_SRTP_UNKNOWN = 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;
/**
* RTP sequence rollover counter settings.
*/
typedef struct pjmedia_srtp_roc
{
/**
* The synchronization source.
*/
pj_uint32_t ssrc;
/**
* The rollover counter.
*/
pj_uint32_t roc;
} pjmedia_srtp_roc;
/**
* 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];
/**
* RTP sequence rollover counter initialization value for incoming
* direction. This is useful to maintain ROC after media transport
* recreation such as in IP change scenario.
*/
pjmedia_srtp_roc rx_roc;
/**
* The previous value of RTP sequence rollover counter. This is
* useful in situations when we expect the remote to reset/maintain
* ROC but for some reason, they don't. Thus, when we encounter
* SRTP packet unprotect failure during probation, we will retry to
* unprotect with this ROC value as well.
* Set prev_rx_roc.ssrc to 0 to disable this feature.
*/
pjmedia_srtp_roc prev_rx_roc;
/**
* RTP sequence rollover counter initialization value for outgoing
* direction. This is useful to maintain ROC after media transport
* recreation such as in IP change scenario.
*/
pjmedia_srtp_roc tx_roc;
/**
* 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;
/**
* RTP sequence rollover counter info for incoming direction.
*/
pjmedia_srtp_roc rx_roc;
/**
* RTP sequence rollover counter info for outgoing direction.
*/
pjmedia_srtp_roc tx_roc;
} 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 keying 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 current SRTP media transport setting.
*
* @param srtp The SRTP transport.
* @param opt Structure to receive the SRTP setting
*
* @return PJ_SUCCESS on success.
*/
PJ_DECL(pj_status_t) pjmedia_transport_srtp_get_setting(
pjmedia_transport *srtp,
pjmedia_srtp_setting *opt);
/**
* Modify SRTP media transport setting.
*
* @param srtp The SRTP transport.
* @param opt New setting
*
* @return PJ_SUCCESS on success.
*/
PJ_DECL(pj_status_t) pjmedia_transport_srtp_modify_setting(
pjmedia_transport *srtp,
const pjmedia_srtp_setting *opt);
/**
* 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__ */