]> sjero.net Git - linphone/commitdiff
srtp: fix crypto line tag handling
authorPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@linphone.org>
Thu, 1 Mar 2012 09:46:22 +0000 (10:46 +0100)
committerPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@linphone.org>
Fri, 2 Mar 2012 13:45:34 +0000 (14:45 +0100)
We were answering with the local tag index matching the remote crypto
algo; instead of using the remote tag

coreapi/linphonecall.c
coreapi/offeranswer.c
coreapi/sal.h

index 2cd4a78cd3635e9cb1a72286864839990e5f73da..08c5ad930a6dce585b3ac340c2ffbe265d7f1756 100644 (file)
@@ -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; i<SAL_CRYPTO_ALGO_MAX; i++) {
-               if (crypto[i].tag == tag) {
-                       return i;
-               }
-       }
-       return -1;
+    int i;
+    for(i=0; i<SAL_CRYPTO_ALGO_MAX; i++) {
+        if (crypto[i].tag == tag) {
+            return i;
+        }
+    }
+    return -1;
 }
 static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cname, bool_t muted, bool_t send_ringbacktone, bool_t use_arc){
        LinphoneCore *lc=call->core;
@@ -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 */
index 5acf0402a5203f36aba3d43645742cac665690fe..fd0196782eebbe4240f6041b4e18de8e05802a54 100644 (file)
@@ -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; i<SAL_CRYPTO_ALGO_MAX; i++) {
                if (remote[i].algo == 0)
                        break;
-                       
+
+        /* Look for a local enabled crypto algo that matches one of the proposed by remote */
                for(j=0; j<SAL_CRYPTO_ALGO_MAX; j++) {
                        if (remote[i].algo == local[j].algo) {
                                result->algo = 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; 
                
        }
index 8b0988b08b8d6f0dba5d4a7dc5b21da3929ba9c3..1ae18a9d4ebe4bdd37663f87446c0b4ff588b04e 100644 (file)
@@ -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