From f40bd13c63ad81dd66d47db8ab71dc0f4e06a79f Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Thu, 1 Mar 2012 10:46:22 +0100 Subject: [PATCH] srtp: fix crypto line tag handling We were answering with the local tag index matching the remote crypto algo; instead of using the remote tag --- coreapi/linphonecall.c | 38 +++++++++++++++++++++++--------------- coreapi/offeranswer.c | 20 +++++++++++++------- coreapi/sal.h | 1 + 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 2cd4a78cd..08c5ad930 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1086,13 +1086,13 @@ static bool_t linphone_call_sound_resources_available(LinphoneCall *call){ (current==NULL || current==call); } static int find_crypto_index_from_tag(const SalSrtpCryptoAlgo crypto[],unsigned char tag) { - int i; - for(i=0; icore; @@ -1181,15 +1181,23 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cna } audio_stream_set_rtcp_information(call->audiostream, cname, LINPHONE_RTCP_SDES_TOOL); + /* valid local tags are > 0 */ if (stream->proto == SalProtoRtpSavp) { - const SalStreamDescription *local_st_desc=sal_media_description_find_stream(call->localdesc, - SalProtoRtpSavp,SalAudio); - audio_stream_enable_strp( - call->audiostream, - stream->crypto[0].algo, - local_st_desc->crypto[find_crypto_index_from_tag(local_st_desc->crypto,stream->crypto[0].tag)].master_key, - stream->crypto[0].master_key); - call->audiostream_encrypted=TRUE; + const SalStreamDescription *local_st_desc=sal_media_description_find_stream(call->localdesc, + SalProtoRtpSavp,SalAudio); + int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, stream->crypto_local_tag); + + if (crypto_idx >= 0) { + audio_stream_enable_strp( + call->audiostream, + stream->crypto[0].algo, + local_st_desc->crypto[crypto_idx].master_key, + stream->crypto[0].master_key); + call->audiostream_encrypted=TRUE; + } else { + ms_warning("Failed to find local crypto algo with tag: %d", stream->crypto_local_tag); + call->audiostream_encrypted=FALSE; + } }else call->audiostream_encrypted=FALSE; if (call->params.in_conference){ /*transform the graph to connect it to the conference filter */ diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index 5acf0402a..fd0196782 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -129,21 +129,27 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t } static bool_t match_crypto_algo(const SalSrtpCryptoAlgo* local, const SalSrtpCryptoAlgo* remote, - SalSrtpCryptoAlgo* result, bool_t use_local_key) { + SalSrtpCryptoAlgo* result, unsigned int* choosen_local_tag, bool_t use_local_key) { int i,j; for(i=0; ialgo = remote[i].algo; + /* We're answering an SDP offer. Supply our master key, associated with the remote supplied tag */ if (use_local_key) { strncpy(result->master_key, local[j].master_key, 41); - result->tag = local[j].tag; - } else { - strncpy(result->master_key, remote[i].master_key, 41); result->tag = remote[i].tag; + *choosen_local_tag = local[j].tag; + } + /* We received an answer to our SDP crypto proposal. Copy matching algo remote master key to result, and memorize local tag */ + else { + strncpy(result->master_key, remote[i].master_key, 41); + result->tag = local[j].tag; + *choosen_local_tag = local[j].tag; } result->master_key[40] = '\0'; return TRUE; @@ -214,7 +220,7 @@ static void initiate_outgoing(const SalStreamDescription *local_offer, if (result->proto == SalProtoRtpSavp) { /* verify crypto algo */ memset(result->crypto, 0, sizeof(result->crypto)); - if (!match_crypto_algo(local_offer->crypto, remote_answer->crypto, &result->crypto[0], FALSE)) + if (!match_crypto_algo(local_offer->crypto, remote_answer->crypto, &result->crypto[0], &result->crypto_local_tag, FALSE)) result->port = 0; } } @@ -239,7 +245,7 @@ static void initiate_incoming(const SalStreamDescription *local_cap, if (result->proto == SalProtoRtpSavp) { /* select crypto algo */ memset(result->crypto, 0, sizeof(result->crypto)); - if (!match_crypto_algo(local_cap->crypto, remote_offer->crypto, &result->crypto[0], TRUE)) + if (!match_crypto_algo(local_cap->crypto, remote_offer->crypto, &result->crypto[0], &result->crypto_local_tag, TRUE)) result->port = 0; } diff --git a/coreapi/sal.h b/coreapi/sal.h index 8b0988b08..1ae18a9d4 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -133,6 +133,7 @@ typedef struct SalStreamDescription{ SalEndpointCandidate candidates[SAL_ENDPOINT_CANDIDATE_MAX]; SalStreamDir dir; SalSrtpCryptoAlgo crypto[SAL_CRYPTO_ALGO_MAX]; + unsigned int crypto_local_tag; } SalStreamDescription; #define SAL_MEDIA_DESCRIPTION_MAX_STREAMS 4