Commit daa314ae authored by Simon Morlat's avatar Simon Morlat

rework SRTP in order to allow reconfiguration of an srtp session.

parent 393857c0
......@@ -249,6 +249,7 @@ if test "${srtp_prefix}" != "none" ; then
LIBS=$LIBS_save
fi
AC_DEFINE(HAVE_SRTP, 1, [Defined when srtp support is compiled])
ORTP_DEFS="$ORTP_DEFS -DORTP_HAVE_SRTP"
else
AC_MSG_NOTICE([Could not find libsrtp headers or lib, cryto transport disabled.])
SRTP_CFLAGS=
......@@ -289,8 +290,9 @@ AM_CONDITIONAL(LIBBZRTP,test x$zrtp != xfalse)
if test $debug_enabled = "yes"; then
ORTP_DEFS="$ORTP_DEFS -DORTP_DEBUG_MODE -g"
ORTP_DEFS="$ORTP_DEFS -DORTP_DEBUG_MODE"
CFLAGS=`echo $CFLAGS | sed 's/-O.//'`
CFLAGS="$CFLAGS -g"
fi
......
......@@ -20,7 +20,7 @@
#ifndef ortp_srtp_h
#define ortp_srtp_h
#ifdef HAVE_SRTP
#if defined(HAVE_SRTP) || defined(ORTP_HAVE_SRTP)
#if defined(ANDROID) || defined(WINAPI_FAMILY_PHONE_APP)
// Android and Windows phone don't use make install
#include <srtp.h>
......@@ -31,12 +31,10 @@
typedef void* srtp_t;
typedef int err_status_t;
typedef int srtp_policy_t;
typedef struct srtp_policy srtp_policy_t;
#endif
#include <ortp/rtpsession.h>
/*srtp defines all this stuff*/
#undef PACKAGE_BUGREPORT
#undef PACKAGE_NAME
......@@ -44,6 +42,10 @@ typedef int srtp_policy_t;
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION
#include <ortp/rtpsession.h>
#ifdef __cplusplus
extern "C"{
#endif
......@@ -52,18 +54,21 @@ enum ortp_srtp_crypto_suite_t {
AES_128_SHA1_80 = 1,
AES_128_SHA1_32,
AES_128_NO_AUTH,
NO_CIPHER_SHA1_80
NO_CIPHER_SHA1_80,
AES_256_SHA1_80,
AES_256_SHA1_32
};
ORTP_PUBLIC err_status_t ortp_srtp_init(void);
ORTP_PUBLIC err_status_t ortp_srtp_create(srtp_t *session, const srtp_policy_t *policy);
ORTP_PUBLIC err_status_t ortp_srtp_dealloc(srtp_t session);
ORTP_PUBLIC err_status_t ortp_srtp_add_stream(srtp_t session, const srtp_policy_t *policy);
ORTP_PUBLIC err_status_t ortp_srtp_remove_stream(srtp_t session, uint32_t ssrc);
ORTP_PUBLIC err_status_t ortp_crypto_get_random(uint8_t *tmp, int size);
ORTP_PUBLIC bool_t ortp_srtp_supported(void);
ORTP_PUBLIC int srtp_transport_new(srtp_t srtp, RtpTransport **rtpt, RtpTransport **rtcpt );
ORTP_PUBLIC void srtp_transport_destroy(RtpTransport *tp);
ORTP_PUBLIC srtp_t ortp_srtp_create_configure_session(enum ortp_srtp_crypto_suite_t suite, uint32_t ssrc, const char* snd_key, const char* rcv_key);
ORTP_PUBLIC void ortp_srtp_shutdown(void);
......
......@@ -376,7 +376,7 @@ ORTP_PUBLIC int rtp_session_set_remote_addr(RtpSession *session,const char *addr
a valid socket (potentially connect()ed )to be used by the RtpSession */
ORTP_PUBLIC void rtp_session_set_sockets(RtpSession *session, int rtpfd, int rtcpfd);
ORTP_PUBLIC void rtp_session_set_transports(RtpSession *session, RtpTransport *rtptr, RtpTransport *rtcptr);
ORTP_PUBLIC void rtp_session_get_transports(RtpSession *session, RtpTransport **rtptr, RtpTransport **rtcptr);
/*those methods are provided for people who wants to send non-RTP messages using the RTP/RTCP sockets */
ORTP_PUBLIC ortp_socket_t rtp_session_get_rtp_socket(const RtpSession *session);
ORTP_PUBLIC ortp_socket_t rtp_session_get_rtcp_socket(const RtpSession *session);
......
......@@ -30,9 +30,18 @@
#undef PACKAGE_VERSION
#include "ortp/ortp_srtp.h"
#include "rtpsession_priv.h"
#ifdef HAVE_SRTP
#if defined(ANDROID) || defined(WINAPI_FAMILY_PHONE_APP)
// Android and Windows phone don't use make install
#include <srtp_priv.h>
#else
#include <srtp/srtp_priv.h>
#endif
#include "ortp/b64.h"
#define SRTP_PAD_BYTES (SRTP_MAX_TRAILER_LEN + 4)
......@@ -41,37 +50,66 @@ static int srtp_sendto(RtpTransport *t, mblk_t *m, int flags, const struct sock
srtp_t srtp=(srtp_t)t->data;
int slen;
err_status_t err;
rtp_header_t *header=(rtp_header_t*)m->b_rptr;
/* enlarge the buffer for srtp to write its data */
slen=msgdsize(m);
/*only encrypt real RTP packets*/
if (slen>RTP_FIXED_HEADER_SIZE && header->version==2){
msgpullup(m,slen+SRTP_PAD_BYTES);
err=srtp_protect(srtp,m->b_rptr,&slen);
if (err==err_status_ok){
return sendto(t->session->rtp.socket,(void*)m->b_rptr,slen,flags,to,tolen);
}
ortp_error("srtp_protect() failed (%d)", err);
}else return sendto(t->session->rtp.socket,(void*)m->b_rptr,slen,flags,to,tolen);
return -1;
}
static srtp_stream_ctx_t * find_other_ssrc(srtp_t srtp, uint32_t ssrc){
srtp_stream_ctx_t *stream;
for (stream=srtp->stream_list;stream!=NULL;stream=stream->next){
if (stream->ssrc!=ssrc) return stream;
}
return stream;
}
/*
* The ssrc_any_inbound feature of the libsrtp is not working good.
* It cannot be changed dynamically nor removed.
* As a result we prefer not to use it, but instead the recv stream is configured with a dummy SSRC value.
* When the first packet arrives, or when the SSRC changes, then we change the ssrc value inside the srtp stream context,
* so that the stream that was configured with the dummy SSRC value becomes now fully valid.
*/
static void update_recv_stream(RtpSession *session, srtp_t srtp, uint32_t new_ssrc){
uint32_t send_ssrc=rtp_session_get_send_ssrc(session);
srtp_stream_ctx_t *recvstream=find_other_ssrc(srtp,htonl(send_ssrc));
if (recvstream){
recvstream->ssrc=new_ssrc;
}
}
static int srtp_recvfrom(RtpTransport *t, mblk_t *m, int flags, struct sockaddr *from, socklen_t *fromlen){
srtp_t srtp=(srtp_t)t->data;
int err;
int slen;
err=rtp_session_rtp_recv_abstract(t->session->rtp.socket,m,flags,from,fromlen);
if (err>0){
err_status_t srtp_err;
/* keep NON-RTP data unencrypted */
rtp_header_t *rtp;
if (err>=RTP_FIXED_HEADER_SIZE)
{
rtp = (rtp_header_t*)m->b_wptr;
if (rtp->version!=2)
{
rtp_header_t *rtp=(rtp_header_t*)m->b_wptr;
if (err<RTP_FIXED_HEADER_SIZE || rtp->version!=2 )
return err;
}
}
slen=err;
srtp_err = srtp_unprotect(srtp,m->b_wptr,&slen);
if (srtp_err==err_status_no_ctx){
update_recv_stream(t->session,srtp,rtp->ssrc);
slen=err;
srtp_err = srtp_unprotect(srtp,m->b_wptr,&slen);
}
if (srtp_err==err_status_ok)
return slen;
else {
......@@ -104,19 +142,21 @@ static int srtcp_recvfrom(RtpTransport *t, mblk_t *m, int flags, struct sockaddr
err=rtp_session_rtp_recv_abstract(t->session->rtcp.socket,m,flags,from,fromlen);
if (err>0){
err_status_t srtp_err;
uint32_t new_ssrc;
/* keep NON-RTP data unencrypted */
rtcp_common_header_t *rtcp;
if (err>=RTCP_COMMON_HEADER_SIZE)
{
rtcp = (rtcp_common_header_t*)m->b_wptr;
if (rtcp->version!=2)
{
rtcp_common_header_t *rtcp=(rtcp_common_header_t*)m->b_wptr;
if (err<(sizeof(rtcp_common_header_t)+4) || rtcp->version!=2 )
return err;
}
}
slen=err;
srtp_err=srtp_unprotect_rtcp(srtp,m->b_wptr,&slen);
if (srtp_err==err_status_no_ctx){
new_ssrc=*(uint32_t*)(m->b_wptr+sizeof(rtcp_common_header_t));
update_recv_stream(t->session,srtp,new_ssrc);
slen=err;
srtp_err=srtp_unprotect_rtcp(srtp,m->b_wptr,&slen);
}
if (srtp_err==err_status_ok)
return slen;
else {
......@@ -165,6 +205,10 @@ int srtp_transport_new(srtp_t srtp, RtpTransport **rtpt, RtpTransport **rtcpt ){
return 0;
}
void srtp_transport_destroy(RtpTransport *tp){
ortp_free(tp);
}
static int srtp_init_done=0;
err_status_t ortp_srtp_init(void)
......@@ -210,11 +254,15 @@ err_status_t ortp_srtp_add_stream(srtp_t session, const srtp_policy_t *policy)
return srtp_add_stream(session, policy);
}
err_status_t ortp_srtp_remove_stream(srtp_t session, uint32_t ssrc){
return srtp_remove_stream(session,ssrc);
}
bool_t ortp_srtp_supported(void){
return TRUE;
}
static bool_t ortp_init_srtp_policy(srtp_t srtp, srtp_policy_t* policy, enum ortp_srtp_crypto_suite_t suite, ssrc_t ssrc, const char* b64_key)
bool_t ortp_init_srtp_policy(srtp_t srtp, srtp_policy_t* policy, enum ortp_srtp_crypto_suite_t suite, ssrc_t ssrc, const char* b64_key)
{
uint8_t* key;
int key_size;
......@@ -237,9 +285,17 @@ static bool_t ortp_init_srtp_policy(srtp_t srtp, srtp_policy_t* policy, enum ort
crypto_policy_set_null_cipher_hmac_sha1_80(&policy->rtcp);
break;
case AES_128_SHA1_80: /*default mode*/
default:
crypto_policy_set_rtp_default(&policy->rtp);
crypto_policy_set_rtcp_default(&policy->rtcp);
crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy->rtp);
crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy->rtcp);
break;
case AES_256_SHA1_80:
crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy->rtp);
crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy->rtcp);
break;
case AES_256_SHA1_32:
crypto_policy_set_aes_cm_256_hmac_sha1_32(&policy->rtp);
crypto_policy_set_aes_cm_256_hmac_sha1_32(&policy->rtcp);
break;
}
key_size = b64_decode(b64_key, b64_key_length, 0, 0);
if (key_size != policy->rtp.cipher_key_len) {
......@@ -319,6 +375,7 @@ srtp_t ortp_srtp_create_configure_session(enum ortp_srtp_crypto_suite_t suite, u
return session;
}
#else
err_status_t ortp_srtp_init(void) {
......@@ -349,8 +406,11 @@ err_status_t ortp_srtp_dealloc(srtp_t session)
return -1;
}
err_status_t ortp_srtp_add_stream(srtp_t session, const srtp_policy_t *policy)
{
err_status_t ortp_srtp_add_stream(srtp_t session, const srtp_policy_t *policy){
return -1;
}
err_status_t ortp_srtp_remove_stream(srtp_t session, uint32_t ssrc){
return -1;
}
......@@ -362,5 +422,8 @@ srtp_t ortp_srtp_create_configure_session(enum ortp_srtp_crypto_suite_t suite, u
void ortp_srtp_shutdown(void){
}
void srtp_transport_destroy(RtpTransport *tp){
}
#endif
......@@ -224,13 +224,11 @@ void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_t
freemsg(mp);
return;
}
}
else{
} else{
/* The SSRC change must not happen if we still receive
ssrc from the initial source. */
session->inc_same_ssrc_count=0;
}
}else{
session->ssrc_set=TRUE;
session->rcv.ssrc=rtp->ssrc;
......
......@@ -838,6 +838,10 @@ void rtp_session_set_transports(RtpSession *session, struct _RtpTransport *rtptr
else session->flags&=~(RTP_SESSION_USING_TRANSPORT);
}
void rtp_session_get_transports(RtpSession *session, RtpTransport **rtptr, RtpTransport **rtcptr){
if (rtptr) *rtptr=session->rtp.tr;
if (rtcptr) *rtcptr=session->rtcp.tr;
}
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment