Commit a8176a39 authored by Simon Morlat's avatar Simon Morlat

rework SRTP support so that recv and send key can be set and updated independently.

parent 0c68cdcf
......@@ -680,6 +680,39 @@ AC_SUBST(STRICT_OPTIONS)
top_srcdir=`dirname $0`
AC_ARG_ENABLE(external-ortp,
[AS_HELP_STRING([--enable-external-ortp], [Use external oRTP library])],
[case "${enableval}" in
yes) external_ortp=true ;;
no) external_ortp=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-external-ortp) ;;
esac],
[external_ortp=false]
)
if test "$external_ortp" = 'true'; then
PKG_CHECK_MODULES([ORTP], [ortp >= 0.23.0])
ORTP_VERSION=`$PKG_CONFIG --modversion ortp`
else
AC_CONFIG_SUBDIRS( oRTP )
ORTP_CFLAGS="-I\$(top_srcdir)/oRTP/include"
ORTP_LIBS="\$(top_builddir)/oRTP/src/libortp.la"
if test x$ac_cv_c_bigendian = xyes ; then
ORTP_CFLAGS="$ORTP_CFLAGS -DORTP_BIGENDIAN"
fi
if test x$ntptimestamp = xtrue ; then
ORTP_CFLAGS="$ORTP_CFLAGS -DORTP_TIMESTAMP"
fi
ORTP_DIR=oRTP
changequote(<<, >>)
ORTP_VERSION=`grep -E ^[AC]+_INIT ${top_srcdir}/oRTP/configure.ac | sed -e 's:^.*_INIT(.*,\[\(.*\)\]):\1:g'`
changequote([, ])
fi
AC_SUBST(ORTP_CFLAGS)
AC_SUBST(ORTP_LIBS)
AC_SUBST([ORTP_VERSION])
AC_SUBST([ORTP_DIR])
AC_ARG_ENABLE([external-mediastreamer],
[AS_HELP_STRING([--enable-external-mediastreamer],[Use external mediastreamer library])],,
[enable_external_mediastreamer=no]
......@@ -778,38 +811,7 @@ AC_DEFINE_UNQUOTED(LINPHONE_PLUGINS_DIR, "${package_prefix}/lib/liblinphone/plug
LINPHONE_PLUGINS_DIR="${package_prefix}/lib/liblinphone/plugins"
AC_SUBST(LINPHONE_PLUGINS_DIR)
AC_ARG_ENABLE(external-ortp,
[AS_HELP_STRING([--enable-external-ortp], [Use external oRTP library])],
[case "${enableval}" in
yes) external_ortp=true ;;
no) external_ortp=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-external-ortp) ;;
esac],
[external_ortp=false]
)
if test "$external_ortp" = 'true'; then
PKG_CHECK_MODULES([ORTP], [ortp >= 0.23.0])
ORTP_VERSION=`$PKG_CONFIG --modversion ortp`
else
AC_CONFIG_SUBDIRS( oRTP )
ORTP_CFLAGS="-I\$(top_srcdir)/oRTP/include"
ORTP_LIBS="\$(top_builddir)/oRTP/src/libortp.la"
if test x$ac_cv_c_bigendian = xyes ; then
ORTP_CFLAGS="$ORTP_CFLAGS -DORTP_BIGENDIAN"
fi
if test x$ntptimestamp = xtrue ; then
ORTP_CFLAGS="$ORTP_CFLAGS -DORTP_TIMESTAMP"
fi
ORTP_DIR=oRTP
changequote(<<, >>)
ORTP_VERSION=`grep -E ^[AC]+_INIT ${top_srcdir}/oRTP/configure.ac | sed -e 's:^.*_INIT(.*,\[\(.*\)\]):\1:g'`
changequote([, ])
fi
AC_SUBST(ORTP_CFLAGS)
AC_SUBST(ORTP_LIBS)
AC_SUBST([ORTP_VERSION])
AC_SUBST([ORTP_DIR])
AC_ARG_ENABLE(tutorials,
[AS_HELP_STRING([--disable-tutorials], [Disable compilation of tutorials])],
......
......@@ -146,17 +146,20 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session
if ( stream->proto == SalProtoRtpSavp ) {
/* add crypto lines */
for ( j=0; j<SAL_CRYPTO_ALGO_MAX; j++ ) {
const char *enc_name=NULL;
switch ( stream->crypto[j].algo ) {
case AES_128_SHA1_80:
snprintf ( buffer, sizeof ( buffer ), "%d %s inline:%s",
stream->crypto[j].tag, "AES_CM_128_HMAC_SHA1_80", stream->crypto[j].master_key );
belle_sdp_media_description_add_attribute ( media_desc,belle_sdp_attribute_create ( "crypto",buffer ) );
enc_name="AES_CM_128_HMAC_SHA1_80";
break;
case AES_128_SHA1_32:
snprintf ( buffer, sizeof ( buffer ), "%d %s inline:%s",
stream->crypto[j].tag, "AES_CM_128_HMAC_SHA1_32", stream->crypto[j].master_key );
belle_sdp_media_description_add_attribute ( media_desc,belle_sdp_attribute_create ( "crypto",buffer ) );
enc_name="AES_CM_128_HMAC_SHA1_32";
break;
case AES_256_SHA1_32:
enc_name="AES_CM_256_HMAC_SHA1_32";
break;
case AES_256_SHA1_80:
enc_name="AES_CM_256_HMAC_SHA1_32";
break;
case AES_128_NO_AUTH:
ms_warning ( "Unsupported crypto suite: AES_128_NO_AUTH" );
......@@ -168,6 +171,11 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session
j = SAL_CRYPTO_ALGO_MAX;
/* no break */
}
if (enc_name){
snprintf ( buffer, sizeof ( buffer )-1, "%d %s inline:%s",
stream->crypto[j].tag, enc_name, stream->crypto[j].master_key );
belle_sdp_media_description_add_attribute ( media_desc,belle_sdp_attribute_create ( "crypto",buffer ) );
}
}
}
switch ( stream->dir ) {
......@@ -342,11 +350,15 @@ static void sdp_parse_media_crypto_parameters(belle_sdp_media_description_t *med
tmp,
tmp2 );
if ( nb == 3 ) {
if ( keywordcmp ( "AES_CM_128_HMAC_SHA1_80",tmp ) == 0 )
if ( keywordcmp ( "AES_CM_128_HMAC_SHA1_80",tmp ) == 0 ){
stream->crypto[valid_count].algo = AES_128_SHA1_80;
else if ( keywordcmp ( "AES_CM_128_HMAC_SHA1_32",tmp ) == 0 )
}else if ( keywordcmp ( "AES_CM_128_HMAC_SHA1_32",tmp ) == 0 ){
stream->crypto[valid_count].algo = AES_128_SHA1_32;
else {
}else if ( keywordcmp ( "AES_CM_256_HMAC_SHA1_32",tmp ) == 0 ){
stream->crypto[valid_count].algo = AES_256_SHA1_32;
}else if ( keywordcmp ( "AES_CM_256_HMAC_SHA1_80",tmp ) == 0 ){
stream->crypto[valid_count].algo = AES_256_SHA1_80;
}else {
ms_warning ( "Failed to parse crypto-algo: '%s'", tmp );
stream->crypto[valid_count].algo = 0;
}
......
......@@ -1873,11 +1873,8 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cna
crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, stream->crypto_local_tag);
if (crypto_idx >= 0) {
audio_stream_enable_srtp(
call->audiostream,
stream->crypto[0].algo,
local_st_desc->crypto[crypto_idx].master_key,
stream->crypto[0].master_key);
media_stream_set_srtp_recv_key(&call->audiostream->ms,stream->crypto[0].algo,stream->crypto[0].master_key);
media_stream_set_srtp_send_key(&call->audiostream->ms,stream->crypto[0].algo,local_st_desc->crypto[crypto_idx].master_key);
call->audiostream_encrypted=TRUE;
} else {
ms_warning("Failed to find local crypto algo with tag: %d", stream->crypto_local_tag);
......@@ -1996,13 +1993,13 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna
}
if (!is_inactive){
if (vstream->proto == SalProtoRtpSavp) {
video_stream_enable_strp(
call->videostream,
vstream->crypto[0].algo,
local_st_desc->crypto[0].master_key,
vstream->crypto[0].master_key
);
call->videostream_encrypted=TRUE;
int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, vstream->crypto_local_tag);
if (crypto_idx >= 0) {
media_stream_set_srtp_recv_key(&call->videostream->ms,vstream->crypto[0].algo,vstream->crypto[0].master_key);
media_stream_set_srtp_send_key(&call->videostream->ms,vstream->crypto[0].algo,local_st_desc->crypto[crypto_idx].master_key);
call->videostream_encrypted=TRUE;
}else call->videostream_encrypted=FALSE;
}else{
call->videostream_encrypted=FALSE;
}
......@@ -2103,42 +2100,43 @@ void linphone_call_stop_media_streams_for_ice_gathering(LinphoneCall *call){
#endif
}
static bool_t update_stream_crypto_params(LinphoneCall *call, const SalStreamDescription *local_st_desc, SalStreamDescription *old_stream, SalStreamDescription *new_stream, MediaStream *ms){
int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, new_stream->crypto_local_tag);
if (crypto_idx >= 0) {
if (call->localdesc_changed & SAL_MEDIA_DESCRIPTION_CRYPTO_CHANGED)
media_stream_set_srtp_send_key(ms,new_stream->crypto[0].algo,local_st_desc->crypto[crypto_idx].master_key);
if (strcmp(old_stream->crypto[0].master_key,new_stream->crypto[0].master_key)!=0){
media_stream_set_srtp_recv_key(ms,new_stream->crypto[0].algo,new_stream->crypto[0].master_key);
}
return TRUE;
} else {
ms_warning("Failed to find local crypto algo with tag: %d", new_stream->crypto_local_tag);
}
return FALSE;
}
void linphone_call_update_crypto_parameters(LinphoneCall *call, SalMediaDescription *old_md, SalMediaDescription *new_md) {
SalStreamDescription *old_stream;
SalStreamDescription *new_stream;
const SalStreamDescription *local_st_desc;
local_st_desc = sal_media_description_find_stream(call->localdesc, SalProtoRtpSavp, SalAudio);
old_stream = sal_media_description_find_stream(old_md, SalProtoRtpSavp, SalAudio);
new_stream = sal_media_description_find_stream(new_md, SalProtoRtpSavp, SalAudio);
if (old_stream && new_stream) {
const SalStreamDescription *local_st_desc = sal_media_description_find_stream(call->localdesc, SalProtoRtpSavp, SalAudio);
if (local_st_desc) {
int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, new_stream->crypto_local_tag);
if (crypto_idx >= 0) {
audio_stream_enable_srtp(call->audiostream, new_stream->crypto[0].algo, local_st_desc->crypto[crypto_idx].master_key, new_stream->crypto[0].master_key);
call->audiostream_encrypted = TRUE;
} else {
ms_warning("Failed to find local crypto algo with tag: %d", new_stream->crypto_local_tag);
call->audiostream_encrypted = FALSE;
}
}
}
if (call->audiostream && local_st_desc && old_stream && new_stream &&
update_stream_crypto_params(call,local_st_desc,old_stream,new_stream,&call->audiostream->ms)){
call->audiostream_encrypted = TRUE;
}else call->audiostream_encrypted = FALSE;
#ifdef VIDEO_ENABLED
local_st_desc = sal_media_description_find_stream(call->localdesc, SalProtoRtpSavp, SalVideo);
old_stream = sal_media_description_find_stream(old_md, SalProtoRtpSavp, SalVideo);
new_stream = sal_media_description_find_stream(new_md, SalProtoRtpSavp, SalVideo);
if (old_stream && new_stream) {
const SalStreamDescription *local_st_desc = sal_media_description_find_stream(call->localdesc, SalProtoRtpSavp, SalVideo);
if (local_st_desc) {
int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, new_stream->crypto_local_tag);
if (crypto_idx >= 0) {
video_stream_enable_strp(call->videostream, new_stream->crypto[0].algo, local_st_desc->crypto[crypto_idx].master_key, new_stream->crypto[0].master_key);
call->videostream_encrypted = TRUE;
} else {
ms_warning("Failed to find local crypto algo with tag: %d", new_stream->crypto_local_tag);
call->videostream_encrypted = FALSE;
}
}
if (call->videostream && local_st_desc && old_stream && new_stream &&
update_stream_crypto_params(call,local_st_desc,old_stream,new_stream,&call->videostream->ms)){
call->videostream_encrypted = TRUE;
}
call->videostream_encrypted = FALSE;
#endif
}
......
......@@ -6380,6 +6380,7 @@ const char *linphone_media_encryption_to_string(LinphoneMediaEncryption menc){
case LinphoneMediaEncryptionNone:
return "LinphoneMediaEncryptionNone";
}
ms_error("Invalid LinphoneMediaEncryption value %i",(int)menc);
return "INVALID";
}
......@@ -6389,7 +6390,7 @@ const char *linphone_media_encryption_to_string(LinphoneMediaEncryption menc){
bool_t linphone_core_media_encryption_supported(const LinphoneCore *lc, LinphoneMediaEncryption menc){
switch(menc){
case LinphoneMediaEncryptionSRTP:
return ortp_srtp_supported();
return media_stream_srtp_supported();
case LinphoneMediaEncryptionZRTP:
return ortp_zrtp_available();
case LinphoneMediaEncryptionNone:
......@@ -6402,7 +6403,7 @@ int linphone_core_set_media_encryption(LinphoneCore *lc, LinphoneMediaEncryption
const char *type="none";
int ret=0;
if (menc == LinphoneMediaEncryptionSRTP){
if (!ortp_srtp_supported()){
if (!media_stream_srtp_supported()){
ms_warning("SRTP not supported by library.");
type="none";
ret=-1;
......
......@@ -62,10 +62,15 @@ static int linphone_remote_provisioning_load_file( LinphoneCore* lc, const char*
fseek(f, 0, SEEK_SET);
char* provisioning = ms_malloc(fsize + 1);
fread(provisioning, fsize, 1, f);
if (fread(provisioning, fsize, 1, f)==0){
ms_error("Could not read xml provisioning file from %s",file_path);
status=-1;
}else{
linphone_remote_provisioning_apply(lc, provisioning);
status = 0;
}
ms_free(provisioning);
fclose(f);
linphone_remote_provisioning_apply(lc, provisioning);
status = 0;
} else {
ms_error("Couldn't open file %s for provisioning", file_path);
}
......
......@@ -166,12 +166,12 @@ typedef struct SalIceRemoteCandidate {
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_UFRAG_LEN 256
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_PWD_LEN 256
#define SAL_SRTP_KEY_SIZE 41
/*sufficient for 256bit keys encoded in base 64*/
#define SAL_SRTP_KEY_SIZE 64
typedef struct SalSrtpCryptoAlgo {
unsigned int tag;
enum ortp_srtp_crypto_suite_t algo;
/* 41= 40 max(key_length for all algo) + '\0' */
char master_key[SAL_SRTP_KEY_SIZE];
} SalSrtpCryptoAlgo;
......
mediastreamer2 @ 8858dc19
Subproject commit e51c106c7e48cfc961fbd74b5c8d5a0588a21080
Subproject commit 8858dc1938b14d2a84773052fa3bc87fd0950800
oRTP @ daa314ae
Subproject commit 5008a70e077b3706de4a48374f162f93071b4d08
Subproject commit daa314ae9c0ba46910299ebc70301897aea7448f
......@@ -1155,6 +1155,7 @@ static void encrypted_call(LinphoneMediaEncryption mode) {
CU_ASSERT_STRING_EQUAL(linphone_call_get_authentication_token(linphone_core_get_current_call(pauline->lc))
,linphone_call_get_authentication_token(linphone_core_get_current_call(marie->lc)));
}
liblinphone_tester_check_rtcp(pauline,marie);
/*just to sleep*/
linphone_core_terminate_all_calls(marie->lc);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1));
......@@ -1165,13 +1166,14 @@ static void encrypted_call(LinphoneMediaEncryption mode) {
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void srtp_call(LinphoneMediaEncryptionSRTP) {
static void srtp_call() {
encrypted_call(LinphoneMediaEncryptionSRTP);
}
/*
* futur work
static void zrtp_call(LinphoneMediaEncryptionSRTP) {
* future work
static void zrtp_call() {
encrypted_call(LinphoneMediaEncryptionZRTP);
}*/
......
......@@ -42,8 +42,8 @@ void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMess
counters = get_stats(lc);
counters->number_of_LinphoneMessageReceived++;
if (linphone_chat_message_get_external_body_url(message)) {
counters->number_of_LinphoneMessageExtBodyReceived++;
CU_ASSERT_STRING_EQUAL(linphone_chat_message_get_external_body_url(message),message_external_body_url);
counters->number_of_LinphoneMessageExtBodyReceived++;
CU_ASSERT_STRING_EQUAL(linphone_chat_message_get_external_body_url(message),message_external_body_url);
}
}
......
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