(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;
}
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 */
}
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;
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;
}
}
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;
}
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