Commit 5c5f7c82 authored by johan's avatar johan
Browse files

move ZRTP management from oRTP to Mediastreamer2 using transport modifier

parent 5581a7cd
......@@ -1006,6 +1006,31 @@ case "$target_os" in
;;
esac
dnl check for libzrtp support (RFC 6189: Media Path Key Agreement for Unicast Secure RTP)
AC_ARG_ENABLE(zrtp,
[AS_HELP_STRING([--enable-zrtp], [Turn on or off compilation of zrtp (default=no)])],
[case "${enableval}" in
yes) zrtp=true ;;
no) zrtp=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-zrtp) ;;
esac],
[zrtp=false]
)
if test "$zrtp" = "true" ; then
PKG_CHECK_MODULES(LIBBZRTP, libbzrtp >= 0.0.0)
if test "$have_srtp" = "no" ; then
AC_MSG_ERROR("ZRTP requires SRTP")
fi
AC_DEFINE(HAVE_zrtp, 1, [Defined when zrtp support is compiled])
LIBS="$LIBS $LIBBZRTP_LIBS"
CFLAGS="$CFLAGS $LIBBZRTP_CFLAGS"
else
echo "ZRTP compilation is disabled."
fi
AM_CONDITIONAL(LIBBZRTP,test x$zrtp != xfalse)
dnl ##################################################
dnl # Check for doxygen
dnl ##################################################
......
......@@ -23,7 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <ortp/ortp.h>
#include <ortp/event.h>
#include <ortp/zrtp.h>
/* defined in srtp.h*/
typedef struct srtp_ctx_t *MSSrtpCtx;
......@@ -35,6 +34,7 @@ typedef struct srtp_ctx_t *MSSrtpCtx;
#include <mediastreamer2/bitratecontrol.h>
#include <mediastreamer2/qualityindicator.h>
#include <mediastreamer2/ice.h>
#include <mediastreamer2/zrtp.h>
#define PAYLOAD_TYPE_FLAG_CAN_RECV PAYLOAD_TYPE_USER_FLAG_1
......@@ -101,7 +101,7 @@ typedef void (*media_stream_process_rtcp_callback_t)(MediaStream *stream, mblk_t
struct _MSMediaStreamSessions{
RtpSession *rtp_session;
MSSrtpCtx srtp_session;
OrtpZrtpContext *zrtp_context;
MSZrtpContext *zrtp_context;
MSTicker *ticker;
bool_t is_secured;
};
......@@ -177,9 +177,9 @@ MS2_PUBLIC void media_stream_enable_adaptive_jittcomp(MediaStream *stream, bool_
**/
MS2_PUBLIC bool_t media_stream_enable_srtp(MediaStream* stream, MSCryptoSuite suite, const char* snd_key, const char* rcv_key);
MS2_PUBLIC int media_stream_set_srtp_recv_key(MediaStream *stream, MSCryptoSuite suite, const char* key);
MS2_PUBLIC int media_stream_set_srtp_recv_key(MediaStream *stream, MSCryptoSuite suite, const char* key, bool_t keyisb64);
MS2_PUBLIC int media_stream_set_srtp_send_key(MediaStream *stream, MSCryptoSuite suite, const char* key);
MS2_PUBLIC int media_stream_set_srtp_send_key(MediaStream *stream, MSCryptoSuite suite, const char* key, bool_t keyisb64);
/**
* @param[in] stream MediaStream object
* @return true if stream is encrypted
......@@ -558,7 +558,7 @@ MS2_PUBLIC float audio_stream_get_lq_quality_rating(AudioStream *stream);
MS2_PUBLIC float audio_stream_get_average_lq_quality_rating(AudioStream *stream);
/* enable ZRTP on the audio stream */
MS2_PUBLIC void audio_stream_enable_zrtp(AudioStream *stream, OrtpZrtpParams *params);
MS2_PUBLIC void audio_stream_enable_zrtp(AudioStream *stream, MSZrtpParams *params);
/**
* return TRUE if zrtp is enabled, it does not mean that stream is encrypted, but only that zrtp is configured to know encryption status, uses #
* */
......@@ -756,7 +756,7 @@ MS2_PUBLIC void video_stream_recv_only_stop(VideoStream *vs);
MS2_PUBLIC void video_stream_send_only_stop(VideoStream *vs);
/* enable ZRTP on the video stream using information from the audio stream */
MS2_PUBLIC void video_stream_enable_zrtp(VideoStream *vstream, AudioStream *astream, OrtpZrtpParams *param);
MS2_PUBLIC void video_stream_enable_zrtp(VideoStream *vstream, AudioStream *astream, MSZrtpParams *param);
/* enable SRTP on the video stream */
static MS2_INLINE bool_t video_stream_enable_strp(VideoStream* stream, MSCryptoSuite suite, const char* snd_key, const char* rcv_key) {
......
/*
mediastreamer2 library - modular sound and video processing and streaming
Copyright (C) 2014 Belledonne Communications
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef ms_zrtp_h
#define ms_zrtp_h
#include <ortp/rtpsession.h>
#include "mediastreamer2/mscommon.h"
#ifdef __cplusplus
extern "C"{
#endif
/* defined in mediastream.h */
typedef struct _MediaStream MediaStream;
typedef struct MSZrtpParams {
const char *zid_file; // File where to store secrets and other information
const char *uri; /* the sip URI of correspondant */
} MSZrtpParams;
typedef struct _MSZrtpContext MSZrtpContext ;
MS2_PUBLIC bool_t ms_zrtp_available(void);
/**
* @deprecated Use ms_zrtp_transport_modifier_new() instead. Using #srtp_transport_new will prevent usage of multiple
* encryptions and/or custom packets transmission.
*/
MS2_PUBLIC MSZrtpContext* ms_zrtp_context_new(MediaStream *stream, RtpSession *s, MSZrtpParams *params);
MS2_PUBLIC void ms_zrtp_context_destroy(MSZrtpContext *ctx);
/**
* can be used to give more time for establishing zrtp session
* */
MS2_PUBLIC void ms_zrtp_reset_transmition_timer(MSZrtpContext* ctx, RtpSession *s);
MS2_PUBLIC MSZrtpContext* ms_zrtp_multistream_new(MediaStream *stream, MSZrtpContext* activeContext, RtpSession *s, MSZrtpParams *params);
MS2_PUBLIC void ms_zrtp_sas_verified(MSZrtpContext* ctx);
MS2_PUBLIC void ms_zrtp_sas_reset_verified(MSZrtpContext* ctx);
MS2_PUBLIC int ms_zrtp_transport_modifier_new(MSZrtpContext* ctx, RtpTransportModifier **rtpt, RtpTransportModifier **rtcpt );
MS2_PUBLIC void ms_zrtp_transport_modifier_destroy(RtpTransportModifier *tp);
#ifdef __cplusplus
}
#endif
#endif /* ms_zrtp_h */
......@@ -54,6 +54,10 @@ libmediastreamer_voip_la_LIBADD= libmediastreamer_base.la \
$(OPUS_LIBS)
if LIBBZRTP
libmediastreamer_voip_la_LIBADD+=$(LIBBZRTP_LIB)
endif
lib_LTLIBRARIES=libmediastreamer_base.la
if BUILD_VOIP_LIBRARY
lib_LTLIBRARIES+=libmediastreamer_voip.la
......@@ -104,6 +108,12 @@ libmediastreamer_base_la_SOURCES+= ortp-deps/b64.c \
endif
endif
if LIBBZRTP
libmediastreamer_voip_la_SOURCES+=voip/zrtp.c
endif
if MS2_FILTERS
libmediastreamer_voip_la_SOURCES+= audiofilters/alaw.c \
audiofilters/ulaw.c \
......@@ -394,6 +404,9 @@ if BUILD_VIDEO
AM_CFLAGS+=$(VIDEO_CFLAGS) $(GLEW_CFLAGS)
endif
if LIBBZRTP
AM_CFLAGS+=$(LIBBZRTP_CFLAGS)
endif
if BUILD_WIN32
libmediastreamer_voip_la_LIBADD+= -lole32 \
......
......@@ -1345,11 +1345,11 @@ float audio_stream_get_average_lq_quality_rating(AudioStream *stream) {
return media_stream_get_average_lq_quality_rating(&stream->ms);
}
void audio_stream_enable_zrtp(AudioStream *stream, OrtpZrtpParams *params){
void audio_stream_enable_zrtp(AudioStream *stream, MSZrtpParams *params){
if (stream->ms.sessions.zrtp_context==NULL)
stream->ms.sessions.zrtp_context=ortp_zrtp_context_new(stream->ms.sessions.rtp_session, params);
stream->ms.sessions.zrtp_context=ms_zrtp_context_new((MediaStream *)stream, stream->ms.sessions.rtp_session, params);
else if (!stream->ms.sessions.is_secured)
ortp_zrtp_reset_transmition_timer(stream->ms.sessions.zrtp_context,stream->ms.sessions.rtp_session);
ms_zrtp_reset_transmition_timer(stream->ms.sessions.zrtp_context,stream->ms.sessions.rtp_session);
}
bool_t audio_stream_zrtp_enabled(const AudioStream *stream) {
......
......@@ -193,7 +193,7 @@ void ms_media_stream_sessions_uninit(MSMediaStreamSessions *sessions){
sessions->rtp_session=NULL;
}
if (sessions->zrtp_context != NULL) {
ortp_zrtp_context_destroy(sessions->zrtp_context);
ms_zrtp_context_destroy(sessions->zrtp_context);
sessions->zrtp_context = NULL;
}
if (sessions->ticker){
......@@ -280,13 +280,13 @@ static int check_srtp_session_created(MediaStream *stream){
return 0;
}
static int add_srtp_stream(srtp_t srtp, MSCryptoSuite suite, uint32_t ssrc, const char* b64_key, bool_t inbound)
static int add_srtp_stream(srtp_t srtp, MSCryptoSuite suite, uint32_t ssrc, const char* b64_key, bool_t keyisb64, bool_t inbound)
{
srtp_policy_t policy;
uint8_t* key;
int key_size;
err_status_t err;
unsigned b64_key_length = strlen(b64_key);
unsigned b64_key_length;
ssrc_t ssrc_conf;
memset(&policy,0,sizeof(policy));
......@@ -322,18 +322,24 @@ static int add_srtp_stream(srtp_t srtp, MSCryptoSuite suite, uint32_t ssrc, cons
return -1;
break;
}
key_size = b64_decode(b64_key, b64_key_length, 0, 0);
if (key_size != policy.rtp.cipher_key_len) {
ortp_error("Key size (%d) doesn't match the selected srtp profile (required %d)",
key_size,
policy.rtp.cipher_key_len);
if (keyisb64==TRUE) {
b64_key_length = strlen(b64_key);
key_size = b64_decode(b64_key, b64_key_length, 0, 0);
if (key_size != policy.rtp.cipher_key_len) {
ortp_error("Key size (%d) doesn't match the selected srtp profile (required %d)",
key_size,
policy.rtp.cipher_key_len);
return -1;
}
key = (uint8_t*) ortp_malloc0(key_size+2); /*srtp uses padding*/
if (b64_decode(b64_key, b64_key_length, key, key_size) != key_size) {
ortp_error("Error decoding key");
ortp_free(key);
return -1;
}
key = (uint8_t*) ortp_malloc0(key_size+2); /*srtp uses padding*/
if (b64_decode(b64_key, b64_key_length, key, key_size) != key_size) {
ortp_error("Error decoding key");
ortp_free(key);
return -1;
}
} else {
key=(uint8_t *)b64_key;
}
if (!inbound)
policy.allow_repeat_tx=1; /*necessary for telephone-events*/
......@@ -349,11 +355,15 @@ static int add_srtp_stream(srtp_t srtp, MSCryptoSuite suite, uint32_t ssrc, cons
err = srtp_add_stream(srtp, &policy);
if (err != err_status_ok) {
ortp_error("Failed to add stream to srtp session (%d)", err);
ortp_free(key);
if (keyisb64==TRUE) {
ortp_free(key);
}
return -1;
}
ortp_free(key);
if (keyisb64==TRUE) {
ortp_free(key);
}
return 0;
}
......@@ -377,7 +387,7 @@ bool_t media_stream_srtp_supported(void){
return _ORTP_HAVE_SRTP & ortp_srtp_supported();
}
int media_stream_set_srtp_recv_key(MediaStream *stream, MSCryptoSuite suite, const char* key){
int media_stream_set_srtp_recv_key(MediaStream *stream, MSCryptoSuite suite, const char* key, bool_t keyisb64){
if (!media_stream_srtp_supported()) {
ms_error("ortp srtp support disabled in oRTP or mediastreamer2");
......@@ -400,14 +410,14 @@ int media_stream_set_srtp_recv_key(MediaStream *stream, MSCryptoSuite suite, con
updated=TRUE;
ssrc=rtp_session_get_recv_ssrc(stream->sessions.rtp_session);
ms_message("media_stream_set_srtp_recv_key(): %s key %s",updated ? "changing to" : "starting with", key);
return add_srtp_stream(stream->sessions.srtp_session,suite,ssrc,key,TRUE);
return add_srtp_stream(stream->sessions.srtp_session,suite,ssrc,key,keyisb64,TRUE);
}
#else
return -1;
#endif
}
int media_stream_set_srtp_send_key(MediaStream *stream, MSCryptoSuite suite, const char* key){
int media_stream_set_srtp_send_key(MediaStream *stream, MSCryptoSuite suite, const char* key, bool_t keyisb64){
if (!media_stream_srtp_supported()) {
ms_error("ortp srtp support disabled in oRTP or mediastreamer2");
......@@ -430,7 +440,7 @@ int media_stream_set_srtp_send_key(MediaStream *stream, MSCryptoSuite suite, con
updated=TRUE;
}
ms_message("media_stream_set_srtp_send_key(): %s key %s",updated ? "changing to" : "starting with", key);
return add_srtp_stream(stream->sessions.srtp_session,suite,ssrc,key,FALSE);
return add_srtp_stream(stream->sessions.srtp_session,suite,ssrc,key,keyisb64,FALSE);
}
#else
return -1;
......@@ -439,7 +449,7 @@ int media_stream_set_srtp_send_key(MediaStream *stream, MSCryptoSuite suite, con
/*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(stream,suite,rcv_key)==0 && media_stream_set_srtp_send_key(stream,suite,snd_key)==0;
return media_stream_set_srtp_recv_key(stream,suite,rcv_key,TRUE)==0 && media_stream_set_srtp_send_key(stream,suite,snd_key,TRUE)==0;
}
const MSQualityIndicator *media_stream_get_quality_indicator(MediaStream *stream){
......
......@@ -27,9 +27,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/msvideoout.h"
#include "mediastreamer2/msextdisplay.h"
#include "mediastreamer2/msitc.h"
#include "mediastreamer2/zrtp.h"
#include "private.h"
#include <ortp/zrtp.h>
static void configure_itc(VideoStream *stream);
......@@ -1245,11 +1245,11 @@ void video_stream_send_only_stop(VideoStream *vs){
}
/* enable ZRTP on the video stream using information from the audio stream */
void video_stream_enable_zrtp(VideoStream *vstream, AudioStream *astream, OrtpZrtpParams *param){
void video_stream_enable_zrtp(VideoStream *vstream, AudioStream *astream, MSZrtpParams *param){
if (astream->ms.sessions.zrtp_context != NULL && vstream->ms.sessions.zrtp_context == NULL) {
vstream->ms.sessions.zrtp_context=ortp_zrtp_multistream_new(astream->ms.sessions.zrtp_context, vstream->ms.sessions.rtp_session, param);
vstream->ms.sessions.zrtp_context=ms_zrtp_multistream_new((MediaStream *)vstream, astream->ms.sessions.zrtp_context, vstream->ms.sessions.rtp_session, param);
} else if (vstream->ms.sessions.zrtp_context && !vstream->ms.sessions.is_secured)
ortp_zrtp_reset_transmition_timer(vstream->ms.sessions.zrtp_context,vstream->ms.sessions.rtp_session);
ms_zrtp_reset_transmition_timer(vstream->ms.sessions.zrtp_context,vstream->ms.sessions.rtp_session);
}
void video_stream_enable_display_filter_auto_rotate(VideoStream* stream, bool_t enable) {
......
/*
mediastreamer2 library - modular sound and video processing and streaming
Copyright (C) 2014 Belledonne Communications
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "mediastreamer2/zrtp.h"
#include "mediastreamer2/mediastream.h"
#ifdef WIN32
#include <malloc.h>
#endif
#ifdef HAVE_zrtp
#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION
#include <srtp/srtp.h>
#include <bzrtp/bzrtp.h>
struct _MSZrtpContext{
RtpSession *session;
MediaStream *stream;
RtpTransportModifier *rtp_modifier;
bzrtpContext_t *zrtpContext; // back link
char *zidFilename;
char *peerURI;
};
typedef enum {
rtp_stream,
rtcp_stream
} stream_type;
// Helper functions
static ORTP_INLINE uint64_t get_timeval_in_millis() {
struct timeval t;
ortp_gettimeofday(&t,NULL);
return (1000LL*t.tv_sec)+(t.tv_usec/1000LL);
}
/* ZRTP library Callbacks implementation */
/**
* Send a ZRTP packet via RTP.
*
* ZRTP calls this method to send a ZRTP packet via the RTP session.
*
* @param ctx
* Pointer to the opaque ZrtpContext structure.
* @param data
* Points to ZRTP message to send.
* @param length
* The length in bytes of the data
* @return
* zero if sending failed, one if packet was sent
*/
static int32_t ms_zrtp_sendDataZRTP (void *clientData, uint8_t* data, int32_t length ){
MSZrtpContext *userData = (MSZrtpContext *)clientData;
RtpSession *session = userData->session;
RtpTransport *rtpt=NULL;
mblk_t *msg;
ms_message("ZRTP Send packet type %.8s", data+16);
/* get RTP transport from session */
rtp_session_get_transports(session,&rtpt,NULL);
/* generate message from raw data */
msg = rtp_session_create_packet_raw(data, length);
meta_rtp_transport_modifier_inject_packet(rtpt, userData->rtp_modifier, msg , 0);
return 0;
}
/**
* This function is called by ZRTP engine as soon as SRTP secrets are ready to be used
* Depending on which role we assume in the ZRTP protocol (Initiator or Responder, randomly selected)
* both secrets may not be available at the same time, the part argument is either
* ZRTP_SRTP_SECRETS_FOR_SENDER or ZRTP_SRTP_SECRETS_FOR_RECEIVER
*/
static int32_t ms_zrtp_srtpSecretsAvailable(void* clientData, bzrtpSrtpSecrets_t* secrets, uint8_t part) {
MSZrtpContext *userData = (MSZrtpContext *)clientData;
// Get authentication and cipher algorithms in srtp format
if ((secrets->authTagAlgo != ZRTP_AUTHTAG_HS32) && ((secrets->authTagAlgo != ZRTP_AUTHTAG_HS80))) {
ms_fatal("unsupported authentication algorithm by srtp");
}
if ((secrets->cipherAlgo != ZRTP_CIPHER_AES1) && (secrets->cipherAlgo != ZRTP_CIPHER_AES2) && (secrets->cipherAlgo != ZRTP_CIPHER_AES3)) {
ms_fatal("unsupported cipher algorithm by srtp");
}
ms_message("ZRTP secrets are ready for %s; auth tag algo is %s", (part==ZRTP_SRTP_SECRETS_FOR_SENDER)?"sender":"receiver", (secrets->authTagAlgo==ZRTP_AUTHTAG_HS32)?"HS32":"HS80");
if (part==ZRTP_SRTP_SECRETS_FOR_RECEIVER) {
uint8_t *key = (uint8_t *)ms_malloc0((secrets->peerSrtpKeyLength+secrets->peerSrtpSaltLength+16)*sizeof(uint8_t));
memcpy(key, secrets->peerSrtpKey, secrets->peerSrtpKeyLength);
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, FALSE);
}else if (secrets->authTagAlgo == ZRTP_AUTHTAG_HS80){
media_stream_set_srtp_recv_key(userData->stream, MS_AES_128_SHA1_80, (const char *)key, FALSE);
}else{
ms_fatal("unsupported auth tag");
}
ms_free(key);
}
if (part==ZRTP_SRTP_SECRETS_FOR_SENDER) {
uint8_t *key = (uint8_t *)ms_malloc0((secrets->selfSrtpKeyLength+secrets->selfSrtpSaltLength+16)*sizeof(uint8_t));
memcpy(key, secrets->selfSrtpKey, secrets->selfSrtpKeyLength);
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, FALSE);
}else if (secrets->authTagAlgo == ZRTP_AUTHTAG_HS80){
media_stream_set_srtp_send_key(userData->stream, MS_AES_128_SHA1_80, (const char *)key, FALSE);
}else{
ms_fatal("unsupported auth tag");
}
ms_free(key);
}
return 0;
}
/**
* Switch on the security.
*
* ZRTP calls this method after it has computed the SAS and check
* if it is verified or not. In addition ZRTP provides information
* about the cipher algorithm and key length for the SRTP session.
*
* This method must enable SRTP processing if it was not enabled
* during sertSecretsReady().
*
* @param ctx
* Pointer to the opaque ZrtpContext structure.
* @param c The name of the used cipher algorithm and mode, or
* NULL
*
* @param s The SAS string
*
* @param verified if <code>verified</code> is true then SAS was
* verified by both parties during a previous call.
*/
static int ms_zrtp_startSrtpSession(void *clientData, char* sas, int32_t verified ){
MSZrtpContext *userData = (MSZrtpContext *)clientData;
// srtp processing is enabled in SecretsReady fuction when receiver secrets are ready
// Indeed, the secrets on is called before both parts are given to secretsReady.
OrtpEventData *eventData;
OrtpEvent *ev;
if (sas != NULL) {
ev=ortp_event_new(ORTP_EVENT_ZRTP_SAS_READY);
eventData=ortp_event_get_data(ev);
memcpy(eventData->info.zrtp_sas.sas,sas,4);
eventData->info.zrtp_sas.sas[4]=0;
eventData->info.zrtp_sas.verified=(verified != 0) ? TRUE : FALSE;
rtp_session_dispatch_event(userData->session, ev);
ms_message("ZRTP secrets on: SAS is %.4s previously verified %s", sas, verified == 0 ? "no" : "yes");
}
ev=ortp_event_new(ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED);
eventData=ortp_event_get_data(ev);
eventData->info.zrtp_stream_encrypted=1;
rtp_session_dispatch_event(userData->session, ev);
ms_message("Event dispatched to all: secrets are on");
return 0;
}
static int ms_zrtp_loadCache(void *clientData, uint8_t** output, uint32_t *outputSize) {
/* get filename from ClientData */
MSZrtpContext *userData = (MSZrtpContext *)clientData;
char *filename = userData->zidFilename;
FILE *CACHEFD = fopen(filename, "r+");
if (CACHEFD == NULL) { /* file doesn't seem to exist, try to create it */
CACHEFD = fopen(filename, "w");
if (CACHEFD != NULL) { /* file created with success */
*output = NULL;
*outputSize = 0;
fclose(CACHEFD);
return 0;
}
return -1;
}
fseek(CACHEFD, 0L, SEEK_END); /* Position to end of file */
*outputSize = ftell(CACHEFD); /* Get file length */
rewind(CACHEFD); /* Back to start of file */
*output = (uint8_t *)malloc(*outputSize*sizeof(uint8_t)+1); /* string must be null terminated */
fread(*output, 1, *outputSize, CACHEFD);
*(*output+*outputSize) = '\0';
*outputSize += 1;
fclose(CACHEFD);
return *outputSize;
}
static int ms_zrtp_writeCache(void *clientData, uint8_t* input, uint32_t inputSize) {
/* get filename from ClientData */
MSZrtpContext *userData = (MSZrtpContext *)clientData;
char *filename = userData->zidFilename;
FILE *CACHEFD = fopen(filename, "w+");
int retval = fwrite(input, 1, inputSize, CACHEFD);
fclose(CACHEFD);
return retval;
}
/**
* @brief This callback is called when context is ready to compute exported keys as in rfc6189 section 4.5.2
* Computed keys are added to zid cache with sip URI of peer(found in client Data) to be used for IM ciphering
*
* @param[in] clientData Contains opaque zrtp context but also peer sip URI
* @param[in] peerZid Peer ZID to address correct node in zid cache
* @param[in] role RESPONDER or INITIATOR, needed to compute the pair of keys for IM ciphering
*
* @return 0 on success
*/
static int ms_zrtp_addExportedKeysInZidCache(void *clientData, uint8_t peerZid[12], uint8_t role) {
MSZrtpContext *userData = (MSZrtpContext *)clientData;
bzrtpContext_t *zrtpContext = userData->zrtpContext;
if (userData->peerURI) {
/* Write the peer sip URI in cache */
bzrtp_addCustomDataInCache(zrtpContext, peerZid, (uint8_t *)"uri", 3, (uint8_t *)(userData->peerURI), strlen(userData->peerURI), 0, BZRTP_CUSTOMCACHE_PLAINDATA, BZRTP_CACHE_LOADFILE|BZRTP_CACHE_DONTWRITEFILE);
}
/* Derive the master keys and session Id 32 bytes each */
bzrtp_addCustomDataInCache(zrtpContext, peerZid, (uint8_t *)"sndKey", 6, (uint8_t *)((role==RESPONDER)?"ResponderKey":"InitiatorKey"), 12, 32, BZRTP_CUSTOMCACHE_USEKDF, BZRTP_CACHE_DONTLOADFILE|BZRTP_CACHE_DONTWRITEFILE);
bzrtp_addCustomDataInCache(zrtpContext, peerZid, (uint8_t *)"rcvKey", 6, (uint8_t *)((role==RESPONDER)?"InitiatorKey":"ResponderKey"), 12, 32, BZRTP_CUSTOMCACHE_USEKDF, BZRTP_CACHE_DONTLOADFILE|BZRTP_CACHE_DONTWRITEFILE);
bzrtp_addCustomDataInCache(zrtpContext, peerZid, (uint8_t *)"sndSId", 6, (uint8_t *)((role==RESPONDER)?"ResponderSId":"InitiatorSId"), 12, 32, BZRTP_CUSTOMCACHE_USEKDF, BZRTP_CACHE_DONTLOADFILE|BZRTP_CACHE_DONTWRITEFILE);
bzrtp_addCustomDataInCache(zrtpContext, peerZid, (uint8_t *)"rcvSId", 6, (uint8_t *)((role==RESPONDER)?"InitiatorSId":"ResponderSId"), 12, 32, BZRTP_CUSTOMCACHE_USEKDF, BZRTP_CACHE_DONTLOADFILE|BZRTP_CACHE_DONTWRITEFILE);
/* Derive session index, 4 bytes */
bzrtp_addCustomDataInCache(zrtpContext, peerZid, (uint8_t *)"sndIndex", 6, (uint8_t *)((role==RESPONDER)?"ResponderIndex":"InitiatorIndex"), 14, 4, BZRTP_CUSTOMCACHE_USEKDF, BZRTP_CACHE_DONTLOADFILE|BZRTP_CACHE_DONTWRITEFILE);
bzrtp_addCustomDataInCache(zrtpContext, peerZid, (uint8_t *)"rcvIndex", 6, (uint8_t *)((role==RESPONDER)?"InitiatorIndex":"ResponderIndex"), 14, 4, BZRTP_CUSTOMCACHE_USEKDF, BZRTP_CACHE_DONTLOADFILE|BZRTP_CACHE_WRITEFILE);