Commit 44b25ea4 authored by johan's avatar johan

Update srtp to rely on stream sessions structure and not complete stream structure

- needed to support reinvite and new stream creation keeping current session
parent 7060908c
......@@ -28,7 +28,7 @@ extern "C"{
#endif
/* defined in mediastream.h */
struct _MediaStream;
struct _MSMediaStreamSessions;
typedef enum {
MSDtlsSrtpRoleInvalid,
......@@ -47,13 +47,12 @@ typedef struct _MSDtlsSrtpContext MSDtlsSrtpContext;
MS2_PUBLIC bool_t ms_dtls_available(void);
MS2_PUBLIC MSDtlsSrtpContext* ms_dtls_srtp_context_new(struct _MediaStream *stream, MSDtlsSrtpParams *params);
MS2_PUBLIC MSDtlsSrtpContext* ms_dtls_srtp_context_new(struct _MSMediaStreamSessions *sessions, MSDtlsSrtpParams *params);
MS2_PUBLIC void ms_dtls_srtp_start(MSDtlsSrtpContext* context);
MS2_PUBLIC void ms_dtls_srtp_context_destroy(MSDtlsSrtpContext *ctx);
MS2_PUBLIC void ms_dtls_srtp_set_role(MSDtlsSrtpContext *context, MSDtlsSrtpRole role);
MS2_PUBLIC MSDtlsSrtpRole ms_dtls_srtp_get_role(MSDtlsSrtpContext *context);
MS2_PUBLIC MSDtlsSrtpContext* ms_dtls_multistream_new(struct _MediaStream *stream, MSDtlsSrtpContext* activeContext, RtpSession *s, MSDtlsSrtpParams *params);
MS2_PUBLIC void ms_dtls_srtp_set_peer_fingerprint(MSDtlsSrtpContext *context, const char *peer_fingerprint);
MS2_PUBLIC int ms_dtls_srtp_generate_self_signed_certificate(char *certif, char *pkey, char *fingerprint);
......
......@@ -27,7 +27,7 @@
extern "C"{
#endif
/* defined in mediastream.h */
struct _MediaStream;
struct _MSMediaStreamSessions;
/*
* Crypto suite used configure encrypted stream*/
......@@ -68,49 +68,49 @@ MS2_PUBLIC bool_t ms_srtp_supported(void);
* Set srtp receiver key for the given media stream.
* If no srtp session exists on the stream it is created, if it already exists srtp policy is created/modified for the receiver side of the stream.
*
* @param[in/out] stream The mediastream to operate on
* @param[in] suite The srtp crypto suite to use
* @param[in] key Srtp master key and master salt in a base 64 NULL terminated string
* @param[in/out] sessions The sessions associated to the current media stream
* @param[in] suite The srtp crypto suite to use
* @param[in] key Srtp master key and master salt in a base 64 NULL terminated string
* @return 0 on success, error code otherwise
*/
MS2_PUBLIC int media_stream_set_srtp_recv_key_b64(struct _MediaStream *stream, MSCryptoSuite suite, const char* key);
MS2_PUBLIC int media_stream_set_srtp_recv_key_b64(struct _MSMediaStreamSessions *sessions, MSCryptoSuite suite, const char* key);
/**
* Set srtp receiver key for the given media stream.
* If no srtp session exists on the stream it is created, if it already exists srtp policy is created/modified for the receiver side of the stream.
*
* @param[in/out] stream The mediastream to operate on
* @param[in/out] sessions The sessions associated to the current media stream
* @param[in] suite The srtp crypto suite to use
* @param[in] key Srtp master key and master salt
* @param[in] key_length key buffer length
* @param[in] stream_type Srtp suite is applied to RTP stream, RTCP stream or both
* @return 0 on success, error code otherwise
*/
MS2_PUBLIC int media_stream_set_srtp_recv_key(struct _MediaStream *stream, MSCryptoSuite suite, const char* key, size_t key_length, MSSrtpStreamType stream_type);
MS2_PUBLIC int media_stream_set_srtp_recv_key(struct _MSMediaStreamSessions *sessions, MSCryptoSuite suite, const char* key, size_t key_length, MSSrtpStreamType stream_type);
/**
* Set srtp sender key for the given media stream.
* If no srtp session exists on the stream it is created, if it already exists srtp policy is created/modified for the sender side of the stream.
*
* @param[in/out] stream The mediastream to operate on
* @param[in/out] sessions The sessions associated to the current media stream
* @param[in] suite The srtp crypto suite to use
* @param[in] key Srtp master key and master salt in a base 64 NULL terminated string
* @return 0 on success, error code otherwise
*/
MS2_PUBLIC int media_stream_set_srtp_send_key_b64(struct _MediaStream *stream, MSCryptoSuite suite, const char* key);
MS2_PUBLIC int media_stream_set_srtp_send_key_b64(struct _MSMediaStreamSessions *sessions, MSCryptoSuite suite, const char* key);
/**
* Set srtp sender key for the given media stream.
* If no srtp session exists on the stream it is created, if it already exists srtp policy is created/modified for the sender side of the stream.
*
* @param[in/out] stream The mediastream to operate on
* @param[in/out] stream The mediastream to operate on
* @param[in] suite The srtp crypto suite to use
* @param[in] key Srtp master key and master salt
* @param[in] key_length key buffer length
* @param[in] stream_type Srtp suite is applied to RTP stream, RTCP stream or both
* @return 0 on success, error code otherwise
*/
MS2_PUBLIC int media_stream_set_srtp_send_key(struct _MediaStream *stream, MSCryptoSuite suite, const char* key, size_t key_length, MSSrtpStreamType stream_type);
MS2_PUBLIC int media_stream_set_srtp_send_key(struct _MSMediaStreamSessions *sessions, MSCryptoSuite suite, const char* key, size_t key_length, MSSrtpStreamType stream_type);
/**
* Deallocate ressources for a srtp session
......
......@@ -188,71 +188,71 @@ static int ms_srtp_transport_modifier_new(srtp_t srtp, RtpTransportModifier **rt
return 0;
}
static int ms_check_srtp_session_created(struct _MediaStream *stream, MSSrtpStreamType stream_type){
static int ms_check_srtp_session_created(struct _MSMediaStreamSessions *sessions, MSSrtpStreamType stream_type){
if (stream_type == MSSRTP_ALL_STREAMS) { /* This is the usual case when both RTP and RTCP share the same key */
if (stream->sessions.srtp_session==NULL){
if (sessions->srtp_session==NULL){
err_status_t err;
srtp_t session;
srtp_t srtp_session;
RtpTransport *rtp=NULL,*rtcp=NULL;
RtpTransportModifier *rtp_modifier, *rtcp_modifier;
err = srtp_create(&session, NULL);
err = srtp_create(&srtp_session, NULL);
if (err != 0) {
ms_error("Failed to create srtp session (%d)", err);
return -1;
}
stream->sessions.srtp_session=session;
ms_srtp_transport_modifier_new(session,&rtp_modifier,&rtcp_modifier);
rtp_session_get_transports(stream->sessions.rtp_session,&rtp,&rtcp);
sessions->srtp_session=srtp_session;
ms_srtp_transport_modifier_new(srtp_session,&rtp_modifier,&rtcp_modifier);
rtp_session_get_transports(sessions->rtp_session,&rtp,&rtcp);
meta_rtp_transport_append_modifier(rtp, rtp_modifier);
meta_rtp_transport_append_modifier(rtcp, rtcp_modifier);
stream->sessions.is_secured=TRUE;
sessions->is_secured=TRUE;
}
} else if (stream_type == MSSRTP_RTP_STREAM) { /* Allocate only the RTP stream */
if (stream->sessions.srtp_session==NULL){
if (sessions->srtp_session==NULL){
err_status_t err;
srtp_t session;
srtp_t srtp_session;
RtpTransport *rtp=NULL;
RtpTransportModifier *rtp_modifier;
err = srtp_create(&session, NULL);
err = srtp_create(&srtp_session, NULL);
if (err != 0) {
ms_error("Failed to create srtp session (%d)", err);
return -1;
}
stream->sessions.srtp_session=session;
ms_srtp_transport_modifier_new(session,&rtp_modifier, NULL);
rtp_session_get_transports(stream->sessions.rtp_session,&rtp,NULL);
sessions->srtp_session=srtp_session;
ms_srtp_transport_modifier_new(srtp_session,&rtp_modifier, NULL);
rtp_session_get_transports(sessions->rtp_session,&rtp,NULL);
meta_rtp_transport_append_modifier(rtp, rtp_modifier);
if (stream->sessions.srtp_rtcp_session!=NULL) {
stream->sessions.is_secured=TRUE;
if (sessions->srtp_rtcp_session!=NULL) {
sessions->is_secured=TRUE;
} else {
stream->sessions.is_secured=FALSE;
sessions->is_secured=FALSE;
}
}
} else if (stream_type == MSSRTP_RTCP_STREAM) { /* Allocate only the RTCP stream */
if (stream->sessions.srtp_rtcp_session==NULL){
if (sessions->srtp_rtcp_session==NULL){
err_status_t err;
srtp_t session;
srtp_t srtp_session;
RtpTransport *rtcp=NULL;
RtpTransportModifier *rtcp_modifier;
err = srtp_create(&session, NULL);
err = srtp_create(&srtp_session, NULL);
if (err != 0) {
ms_error("Failed to create srtp session (%d)", err);
return -1;
}
stream->sessions.srtp_rtcp_session=session;
ms_srtp_transport_modifier_new(session,NULL,&rtcp_modifier);
rtp_session_get_transports(stream->sessions.rtp_session,NULL,&rtcp);
sessions->srtp_rtcp_session=srtp_session;
ms_srtp_transport_modifier_new(srtp_session,NULL,&rtcp_modifier);
rtp_session_get_transports(sessions->rtp_session,NULL,&rtcp);
meta_rtp_transport_append_modifier(rtcp, rtcp_modifier);
if (stream->sessions.srtp_session!=NULL) {
stream->sessions.is_secured=TRUE;
if (sessions->srtp_session!=NULL) {
sessions->is_secured=TRUE;
} else {
stream->sessions.is_secured=FALSE;
sessions->is_secured=FALSE;
}
}
}
......@@ -394,7 +394,7 @@ bool_t ms_srtp_supported(void){
}
int media_stream_set_srtp_recv_key_b64(struct _MediaStream *stream, MSCryptoSuite suite, const char* b64_key){
int media_stream_set_srtp_recv_key_b64(struct _MSMediaStreamSessions *sessions, MSCryptoSuite suite, const char* b64_key){
int retval;
/* decode b64 key */
......@@ -408,39 +408,39 @@ int media_stream_set_srtp_recv_key_b64(struct _MediaStream *stream, MSCryptoSuit
}
/* pass decoded key to set_recv_key function */
retval = media_stream_set_srtp_recv_key(stream, suite, key, key_length, MSSRTP_ALL_STREAMS);
retval = media_stream_set_srtp_recv_key(sessions, suite, key, key_length, MSSRTP_ALL_STREAMS);
ms_free(key);
return retval;
}
int media_stream_set_srtp_recv_key(struct _MediaStream *stream, MSCryptoSuite suite, const char* key, size_t key_length, MSSrtpStreamType stream_type){
int media_stream_set_srtp_recv_key(struct _MSMediaStreamSessions *sessions, MSCryptoSuite suite, const char* key, size_t key_length, MSSrtpStreamType stream_type){
uint32_t ssrc,send_ssrc;
srtp_stream_ctx_t *srtp_stream = NULL;
bool_t updated=FALSE;
srtp_t srtp_session;
if (ms_check_srtp_session_created(stream, stream_type)==-1) {
if (ms_check_srtp_session_created(sessions, stream_type)==-1) {
return -1;
}
switch(stream_type){
case MSSRTP_ALL_STREAMS:
case MSSRTP_RTP_STREAM:
srtp_session = stream->sessions.srtp_session;
srtp_session = sessions->srtp_session;
break;
case MSSRTP_RTCP_STREAM:
srtp_session = stream->sessions.srtp_rtcp_session;
srtp_session = sessions->srtp_rtcp_session;
break;
default:
ms_error("Invalid stream_type %d in set_srtp_recv_key on stream [%p]", stream_type, stream);
ms_error("Invalid stream_type %d in set_srtp_recv_key on sessions [%p]", stream_type, sessions);
return -1;
}
/*check if a previous key was configured, in which case remove it*/
send_ssrc=rtp_session_get_send_ssrc(stream->sessions.rtp_session);
send_ssrc=rtp_session_get_send_ssrc(sessions->rtp_session);
srtp_stream = find_other_ssrc(srtp_session,htonl(send_ssrc));
if (srtp_stream != NULL) {
ssrc = srtp_stream->ssrc;
......@@ -452,13 +452,13 @@ int media_stream_set_srtp_recv_key(struct _MediaStream *stream, MSCryptoSuite su
if (srtp_remove_stream(srtp_session, htonl(ssrc))==0) {
updated=TRUE;
}
ssrc=rtp_session_get_recv_ssrc(stream->sessions.rtp_session);
ssrc=rtp_session_get_recv_ssrc(sessions->rtp_session);
ms_message("media_stream_set_srtp_recv_key(): %s key %02x..%02x\nsrtp session is %p ssrc %08x",updated ? "changing to" : "starting with", (uint8_t)key[0], (uint8_t)key[key_length-1], srtp_session, ssrc);
return ms_add_srtp_stream(srtp_session,suite, ssrc, key, key_length, TRUE, stream_type);
}
int media_stream_set_srtp_send_key_b64(struct _MediaStream *stream, MSCryptoSuite suite, const char* b64_key){
int media_stream_set_srtp_send_key_b64(struct _MSMediaStreamSessions *sessions, MSCryptoSuite suite, const char* b64_key){
int retval;
/* decode b64 key */
......@@ -472,38 +472,38 @@ int media_stream_set_srtp_send_key_b64(struct _MediaStream *stream, MSCryptoSuit
}
/* pass decoded key to set_send_key function */
retval = media_stream_set_srtp_send_key(stream, suite, key, key_length, MSSRTP_ALL_STREAMS);
retval = media_stream_set_srtp_send_key(sessions, suite, key, key_length, MSSRTP_ALL_STREAMS);
ms_free(key);
return retval;
}
int media_stream_set_srtp_send_key(struct _MediaStream *stream, MSCryptoSuite suite, const char* key, size_t key_length, MSSrtpStreamType stream_type){
int media_stream_set_srtp_send_key(struct _MSMediaStreamSessions *sessions, MSCryptoSuite suite, const char* key, size_t key_length, MSSrtpStreamType stream_type){
uint32_t ssrc;
bool_t updated=FALSE;
srtp_t srtp_session;
if (ms_check_srtp_session_created(stream, stream_type)==-1) {
if (ms_check_srtp_session_created(sessions, stream_type)==-1) {
return -1;
}
switch(stream_type){
case MSSRTP_ALL_STREAMS:
case MSSRTP_RTP_STREAM:
srtp_session = stream->sessions.srtp_session;
srtp_session = sessions->srtp_session;
break;
case MSSRTP_RTCP_STREAM:
srtp_session = stream->sessions.srtp_rtcp_session;
srtp_session = sessions->srtp_rtcp_session;
break;
default:
ms_error("Invalid stream_type %d in set_srtp_send_key on stream [%p]", stream_type, stream);
ms_error("Invalid stream_type %d in set_srtp_send_key on sessions [%p]", stream_type, sessions);
return -1;
}
/*check if a previous key was configured, in which case remove it*/
ssrc=rtp_session_get_send_ssrc(stream->sessions.rtp_session);
ssrc=rtp_session_get_send_ssrc(sessions->rtp_session);
if (ssrc!=0){
/*careful: remove_stream takes the SSRC in network byte order...*/
if (srtp_remove_stream(srtp_session,htonl(ssrc))==0)
......
......@@ -1112,6 +1112,9 @@ AudioStream *audio_stream_new_with_sessions(const MSMediaStreamSessions *session
stream->ms.type = MSAudio;
stream->ms.sessions=*sessions;
if (sessions->dtls_context != NULL) {
ms_dtls_srtp_set_stream_sessions(sessions->dtls_context, &(stream->ms.sessions));
}
rtp_session_resync(stream->ms.sessions.rtp_session);
/*some filters are created right now to allow configuration by the application before start() */
stream->ms.rtpsend=ms_filter_new(MS_RTP_SEND_ID);
......@@ -1361,7 +1364,8 @@ bool_t audio_stream_zrtp_enabled(const AudioStream *stream) {
void audio_stream_enable_dtls(AudioStream *stream, MSDtlsSrtpParams *params){
#ifdef HAVE_DTLS
if (stream->ms.sessions.dtls_context==NULL) {
stream->ms.sessions.dtls_context=ms_dtls_srtp_context_new((MediaStream *)stream, params);
printf("Start DTLS audio stream context\n");
stream->ms.sessions.dtls_context=ms_dtls_srtp_context_new(&(stream->ms.sessions), params);
}
#endif
}
......
This diff is collapsed.
......@@ -246,7 +246,7 @@ bool_t media_stream_dtls_supported(void){
/*deprecated*/
bool_t media_stream_enable_srtp(MediaStream *stream, MSCryptoSuite suite, const char *snd_key, const char *rcv_key) {
return media_stream_set_srtp_recv_key_b64(stream,suite,rcv_key)==0 && media_stream_set_srtp_send_key_b64(stream,suite,snd_key)==0;
return media_stream_set_srtp_recv_key_b64(&(stream->sessions),suite,rcv_key)==0 && media_stream_set_srtp_send_key_b64(&(stream->sessions),suite,snd_key)==0;
}
const MSQualityIndicator *media_stream_get_quality_indicator(MediaStream *stream){
......
......@@ -97,6 +97,12 @@ MS2_PUBLIC int ms_srtp_init(void);
*/
MS2_PUBLIC void ms_srtp_shutdown(void);
/**
* Set the backlink in dtls_context to stream sessions context. Used when reinvite force creation of a new stream with same session data
* @param[in/out] dtls_context Dtls context, contains a link to stream session context needed to access srtp context
* @param[in] stream_sessions Pointer to the new stream session structure
*/
MS2_PUBLIC void ms_dtls_srtp_set_stream_sessions(MSDtlsSrtpContext *dtls_context, MSMediaStreamSessions *stream_sessions);
#ifdef __cplusplus
}
#endif
......
......@@ -253,6 +253,9 @@ VideoStream *video_stream_new_with_sessions(const MSMediaStreamSessions *session
stream->ms.type = MSVideo;
stream->ms.sessions=*sessions;
if (sessions->dtls_context != NULL) {
ms_dtls_srtp_set_stream_sessions(sessions->dtls_context, &(stream->ms.sessions));
}
rtp_session_resync(stream->ms.sessions.rtp_session);
stream->ms.qi=ms_quality_indicator_new(stream->ms.sessions.rtp_session);
ms_quality_indicator_set_label(stream->ms.qi,"video");
......@@ -1263,7 +1266,8 @@ void video_stream_enable_zrtp(VideoStream *vstream, AudioStream *astream, MSZrtp
void video_stream_enable_dtls(VideoStream *stream, MSDtlsSrtpParams *params){
if (stream->ms.sessions.dtls_context==NULL) {
stream->ms.sessions.dtls_context=ms_dtls_srtp_context_new((MediaStream *)stream, params);
printf("Start DTLS video stream context\n");
stream->ms.sessions.dtls_context=ms_dtls_srtp_context_new(&(stream->ms.sessions), params);
}
}
......
......@@ -118,9 +118,9 @@ static int32_t ms_zrtp_srtpSecretsAvailable(void* clientData, bzrtpSrtpSecrets_t
memcpy(key + secrets->peerSrtpKeyLength, secrets->peerSrtpSalt, secrets->peerSrtpSaltLength);
if (secrets->authTagAlgo == ZRTP_AUTHTAG_HS32){
media_stream_set_srtp_recv_key(userData->stream, MS_AES_128_SHA1_32, (const char *)key, (secrets->peerSrtpKeyLength+secrets->peerSrtpSaltLength), MSSRTP_ALL_STREAMS);
media_stream_set_srtp_recv_key(&(userData->stream->sessions), MS_AES_128_SHA1_32, (const char *)key, (secrets->peerSrtpKeyLength+secrets->peerSrtpSaltLength), MSSRTP_ALL_STREAMS);
}else if (secrets->authTagAlgo == ZRTP_AUTHTAG_HS80){
media_stream_set_srtp_recv_key(userData->stream, MS_AES_128_SHA1_80, (const char *)key, (secrets->peerSrtpKeyLength+secrets->peerSrtpSaltLength), MSSRTP_ALL_STREAMS);
media_stream_set_srtp_recv_key(&(userData->stream->sessions), MS_AES_128_SHA1_80, (const char *)key, (secrets->peerSrtpKeyLength+secrets->peerSrtpSaltLength), MSSRTP_ALL_STREAMS);
}else{
ms_fatal("unsupported auth tag");
}
......@@ -133,9 +133,9 @@ static int32_t ms_zrtp_srtpSecretsAvailable(void* clientData, bzrtpSrtpSecrets_t
memcpy(key + secrets->selfSrtpKeyLength, secrets->selfSrtpSalt, secrets->selfSrtpSaltLength);
if (secrets->authTagAlgo == ZRTP_AUTHTAG_HS32){
media_stream_set_srtp_send_key(userData->stream, MS_AES_128_SHA1_32, (const char *)key, (secrets->selfSrtpKeyLength+secrets->selfSrtpSaltLength), MSSRTP_ALL_STREAMS);
media_stream_set_srtp_send_key(&(userData->stream->sessions), MS_AES_128_SHA1_32, (const char *)key, (secrets->selfSrtpKeyLength+secrets->selfSrtpSaltLength), MSSRTP_ALL_STREAMS);
}else if (secrets->authTagAlgo == ZRTP_AUTHTAG_HS80){
media_stream_set_srtp_send_key(userData->stream, MS_AES_128_SHA1_80, (const char *)key, (secrets->selfSrtpKeyLength+secrets->selfSrtpSaltLength), MSSRTP_ALL_STREAMS);
media_stream_set_srtp_send_key(&(userData->stream->sessions), MS_AES_128_SHA1_80, (const char *)key, (secrets->selfSrtpKeyLength+secrets->selfSrtpSaltLength), MSSRTP_ALL_STREAMS);
}else{
ms_fatal("unsupported auth tag");
}
......
......@@ -198,8 +198,8 @@ static void encrypted_audio_stream() {
, NULL
, 0),0);
CU_ASSERT_FATAL(media_stream_set_srtp_send_key_b64((MediaStream *)marielle, MS_AES_128_SHA1_32, "d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj") == 0);
CU_ASSERT_FATAL(media_stream_set_srtp_recv_key_b64((MediaStream *)margaux, MS_AES_128_SHA1_32, "d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj") ==0);
CU_ASSERT_FATAL(media_stream_set_srtp_send_key_b64(&(marielle->ms.sessions), MS_AES_128_SHA1_32, "d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj") == 0);
CU_ASSERT_FATAL(media_stream_set_srtp_recv_key_b64(&(margaux->ms.sessions), MS_AES_128_SHA1_32, "d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj") ==0);
ms_filter_add_notify_callback(marielle->soundread, notify_cb, &marielle_stats,TRUE);
......
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