mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-02-07 14:18:25 +00:00
Manage zrtp-hash attribute
- ZRTP engine is always initialised even when not selected
This commit is contained in:
parent
9b6ebbc00c
commit
02ebeac3f1
7 changed files with 146 additions and 80 deletions
|
|
@ -288,6 +288,11 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session
|
|||
ms_free(ssrc_attribute);
|
||||
}
|
||||
|
||||
/* insert zrtp-hash attribute if needed */
|
||||
if (stream->haveZrtpHash == 1) {
|
||||
belle_sdp_media_description_add_attribute(media_desc, belle_sdp_attribute_create("zrtp-hash", (const char *)(stream->zrtphash)));
|
||||
}
|
||||
|
||||
switch ( stream->dir ) {
|
||||
case SalStreamSendRecv:
|
||||
/*dir="sendrecv";*/
|
||||
|
|
@ -834,6 +839,14 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md,
|
|||
sdp_parse_media_crypto_parameters(media_desc, stream);
|
||||
}
|
||||
|
||||
/* Read zrtp-hash attribute */
|
||||
if ((attribute=belle_sdp_media_description_get_attribute(media_desc,"zrtp-hash"))!=NULL) {
|
||||
if ((value=belle_sdp_attribute_get_value(attribute))!=NULL) {
|
||||
strncpy((char *)(stream->zrtphash), belle_sdp_attribute_get_value(attribute),sizeof(stream->zrtphash));
|
||||
stream->haveZrtpHash = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get ICE candidate attributes if any */
|
||||
sdp_parse_media_ice_parameters(media_desc, stream);
|
||||
|
||||
|
|
|
|||
|
|
@ -211,13 +211,11 @@ static void linphone_call_audiostream_encryption_changed(void *data, bool_t encr
|
|||
|
||||
#ifdef VIDEO_ENABLED
|
||||
// Enable video encryption
|
||||
{
|
||||
if (call->params->media_encryption==LinphoneMediaEncryptionZRTP) {
|
||||
const LinphoneCallParams *params=linphone_call_get_current_params(call);
|
||||
if (params->has_video) {
|
||||
MSZrtpParams params;
|
||||
ms_message("Trying to enable encryption on video stream");
|
||||
params.zid_file=NULL; //unused
|
||||
video_stream_enable_zrtp(call->videostream,call->audiostream,¶ms);
|
||||
ms_message("Trying to start ZRTP encryption on video stream");
|
||||
video_stream_start_zrtp(call->videostream);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -523,6 +521,22 @@ static void setup_encryption_keys(LinphoneCall *call, SalMediaDescription *md){
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void setup_zrtp_hash(LinphoneCall *call, SalMediaDescription *md) {
|
||||
int i;
|
||||
if (call->params->media_encryption==LinphoneMediaEncryptionZRTP) {
|
||||
for(i=0; i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) {
|
||||
if (!sal_stream_description_active(&md->streams[i])) continue;
|
||||
if (call->sessions[i].zrtp_context!=NULL) {
|
||||
ms_zrtp_getHelloHash(call->sessions[i].zrtp_context, md->streams[i].zrtphash, 128);
|
||||
md->streams[i].haveZrtpHash = 1;
|
||||
} else {
|
||||
md->streams[i].haveZrtpHash = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_rtcp_fb(LinphoneCall *call, SalMediaDescription *md) {
|
||||
MSList *pt_it;
|
||||
PayloadType *pt;
|
||||
|
|
@ -837,6 +851,7 @@ void linphone_call_make_local_media_description(LinphoneCall *call) {
|
|||
}
|
||||
setup_encryption_keys(call,md);
|
||||
setup_dtls_keys(call,md);
|
||||
setup_zrtp_hash(call, md);
|
||||
|
||||
setup_rtcp_fb(call, md);
|
||||
setup_rtcp_xr(call, md);
|
||||
|
|
@ -2333,6 +2348,62 @@ static void setup_dtls_params(LinphoneCall *call, MediaStream* stream) {
|
|||
}
|
||||
}
|
||||
|
||||
static void setZrtpCryptoTypesParameters(MSZrtpParams *params, LinphoneCore *lc)
|
||||
{
|
||||
int i;
|
||||
const MSCryptoSuite *srtp_suites;
|
||||
MsZrtpCryptoTypesCount ciphersCount, authTagsCount;
|
||||
|
||||
if (params == NULL) return;
|
||||
if (lc == NULL) return;
|
||||
|
||||
srtp_suites = linphone_core_get_srtp_crypto_suites(lc);
|
||||
if (srtp_suites!=NULL) {
|
||||
for(i=0; srtp_suites[i]!=MS_CRYPTO_SUITE_INVALID && i<SAL_CRYPTO_ALGO_MAX && i<MS_MAX_ZRTP_CRYPTO_TYPES; ++i){
|
||||
switch (srtp_suites[i]) {
|
||||
case MS_AES_128_SHA1_32:
|
||||
params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1;
|
||||
params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS32;
|
||||
break;
|
||||
case MS_AES_128_NO_AUTH:
|
||||
params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1;
|
||||
break;
|
||||
case MS_NO_CIPHER_SHA1_80:
|
||||
params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80;
|
||||
break;
|
||||
case MS_AES_128_SHA1_80:
|
||||
params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1;
|
||||
params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80;
|
||||
break;
|
||||
case MS_AES_256_SHA1_80:
|
||||
params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES3;
|
||||
params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80;
|
||||
break;
|
||||
case MS_AES_256_SHA1_32:
|
||||
params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES3;
|
||||
params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS32;
|
||||
break;
|
||||
case MS_CRYPTO_SUITE_INVALID:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* linphone_core_get_srtp_crypto_suites is used to determine sensible defaults; here each can be overridden */
|
||||
ciphersCount = linphone_core_get_zrtp_cipher_suites(lc, params->ciphers); /* if not present in config file, params->ciphers is not modified */
|
||||
if (ciphersCount!=0) { /* use zrtp_cipher_suites config only when present, keep config from srtp_crypto_suite otherwise */
|
||||
params->ciphersCount = ciphersCount;
|
||||
}
|
||||
params->hashesCount = linphone_core_get_zrtp_hash_suites(lc, params->hashes);
|
||||
authTagsCount = linphone_core_get_zrtp_auth_suites(lc, params->authTags); /* if not present in config file, params->authTags is not modified */
|
||||
if (authTagsCount!=0) {
|
||||
params->authTagsCount = authTagsCount; /* use zrtp_auth_suites config only when present, keep config from srtp_crypto_suite otherwise */
|
||||
}
|
||||
params->sasTypesCount = linphone_core_get_zrtp_sas_suites(lc, params->sasTypes);
|
||||
params->keyAgreementsCount = linphone_core_get_zrtp_key_agreement_suites(lc, params->keyAgreements);
|
||||
}
|
||||
|
||||
|
||||
void linphone_call_init_audio_stream(LinphoneCall *call){
|
||||
LinphoneCore *lc=call->core;
|
||||
AudioStream *audiostream;
|
||||
|
|
@ -2361,6 +2432,18 @@ void linphone_call_init_audio_stream(LinphoneCall *call){
|
|||
ms_free(cname);
|
||||
rtp_session_set_symmetric_rtp(audiostream->ms.sessions.rtp_session,linphone_core_symmetric_rtp_enabled(lc));
|
||||
setup_dtls_params(call, &audiostream->ms);
|
||||
|
||||
/* init zrtp even if we didn't explicitely set it, just in case peer offers it */
|
||||
if (ms_zrtp_available()) {
|
||||
MSZrtpParams params;
|
||||
memset(¶ms,0,sizeof(MSZrtpParams));
|
||||
/*call->current_params.media_encryption will be set later when zrtp is activated*/
|
||||
params.zid_file=lc->zrtp_secrets_cache;
|
||||
params.uri= linphone_address_as_string_uri_only((call->dir==LinphoneCallIncoming) ? call->log->from : call->log->to);
|
||||
setZrtpCryptoTypesParameters(¶ms,call->core);
|
||||
audio_stream_enable_zrtp(call->audiostream,¶ms);
|
||||
}
|
||||
|
||||
media_stream_reclaim_sessions(&audiostream->ms, &call->sessions[call->main_audio_stream_index]);
|
||||
}else{
|
||||
call->audiostream=audio_stream_new_with_sessions(lc->factory, &call->sessions[call->main_audio_stream_index]);
|
||||
|
|
@ -2461,6 +2544,11 @@ void linphone_call_init_video_stream(LinphoneCall *call){
|
|||
ms_free(cname);
|
||||
rtp_session_set_symmetric_rtp(call->videostream->ms.sessions.rtp_session,linphone_core_symmetric_rtp_enabled(lc));
|
||||
setup_dtls_params(call, &call->videostream->ms);
|
||||
/* init zrtp even if we didn't explicitely set it, just in case peer offers it */
|
||||
if (ms_zrtp_available()) {
|
||||
video_stream_enable_zrtp(call->videostream, call->audiostream);
|
||||
}
|
||||
|
||||
media_stream_reclaim_sessions(&call->videostream->ms, &call->sessions[call->main_video_stream_index]);
|
||||
}else{
|
||||
call->videostream=video_stream_new_with_sessions(lc->factory, &call->sessions[call->main_video_stream_index]);
|
||||
|
|
@ -2993,6 +3081,10 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, LinphoneCallSta
|
|||
|
||||
stream = sal_media_description_find_best_stream(call->resultdesc, SalAudio);
|
||||
if (stream && stream->dir!=SalStreamInactive && stream->rtp_port!=0){
|
||||
/* get remote stream description to check for zrtp-hash presence */
|
||||
SalMediaDescription *remote_desc = sal_call_get_remote_media_description(call->op);
|
||||
const SalStreamDescription *remote_stream = sal_media_description_find_best_stream(remote_desc, SalAudio);
|
||||
|
||||
const char *rtp_addr=stream->rtp_addr[0]!='\0' ? stream->rtp_addr : call->resultdesc->addr;
|
||||
bool_t is_multicast=ms_is_multicast(rtp_addr);
|
||||
playcard=lc->sound_conf.lsd_card ?
|
||||
|
|
@ -3132,9 +3224,21 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, LinphoneCallSta
|
|||
}
|
||||
call->current_params->in_conference=call->params->in_conference;
|
||||
call->current_params->low_bandwidth=call->params->low_bandwidth;
|
||||
|
||||
/* start ZRTP engine if needed : set here or remote have a zrtp-hash attribute */
|
||||
if (call->params->media_encryption==LinphoneMediaEncryptionZRTP || remote_stream->haveZrtpHash==1) {
|
||||
audio_stream_start_zrtp(call->audiostream);
|
||||
if (remote_stream->haveZrtpHash == 1) {
|
||||
int retval;
|
||||
if ((retval = ms_zrtp_setPeerHelloHash(call->audiostream->ms.sessions.zrtp_context, (uint8_t *)remote_stream->zrtphash, strlen((const char *)(remote_stream->zrtphash)))) != 0) {
|
||||
ms_error("Zrtp hash mismatch 0x%x", retval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else ms_warning("No audio stream accepted ?");
|
||||
}
|
||||
linphone_call_set_on_hold_file(call, file_to_play);
|
||||
|
||||
}
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
|
|
@ -3296,6 +3400,14 @@ static void linphone_call_start_video_stream(LinphoneCall *call, LinphoneCallSta
|
|||
}
|
||||
ms_media_stream_sessions_set_encryption_mandatory(&call->videostream->ms.sessions,call->current_params->encryption_mandatory);
|
||||
_linphone_call_set_next_video_frame_decoded_trigger(call);
|
||||
|
||||
/* start ZRTP if needed */
|
||||
if (call->params->media_encryption==LinphoneMediaEncryptionZRTP) {
|
||||
/*audio stream is already encrypted and video stream is active*/
|
||||
if (media_stream_secured((MediaStream *)call->audiostream) && media_stream_get_state((MediaStream *)call->videostream) == MSStreamStarted) {
|
||||
video_stream_start_zrtp(call->videostream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else ms_warning("No video stream accepted.");
|
||||
}else{
|
||||
|
|
@ -3306,6 +3418,7 @@ static void linphone_call_start_video_stream(LinphoneCall *call, LinphoneCallSta
|
|||
ms_warning("Video preview (%p) not reused: destroying it.", source);
|
||||
ms_filter_destroy(source);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -3359,61 +3472,6 @@ static void linphone_call_start_text_stream(LinphoneCall *call) {
|
|||
}
|
||||
}
|
||||
|
||||
static void setZrtpCryptoTypesParameters(MSZrtpParams *params, LinphoneCore *lc)
|
||||
{
|
||||
int i;
|
||||
const MSCryptoSuite *srtp_suites;
|
||||
MsZrtpCryptoTypesCount ciphersCount, authTagsCount;
|
||||
|
||||
if (params == NULL) return;
|
||||
if (lc == NULL) return;
|
||||
|
||||
srtp_suites = linphone_core_get_srtp_crypto_suites(lc);
|
||||
if (srtp_suites!=NULL) {
|
||||
for(i=0; srtp_suites[i]!=MS_CRYPTO_SUITE_INVALID && i<SAL_CRYPTO_ALGO_MAX && i<MS_MAX_ZRTP_CRYPTO_TYPES; ++i){
|
||||
switch (srtp_suites[i]) {
|
||||
case MS_AES_128_SHA1_32:
|
||||
params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1;
|
||||
params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS32;
|
||||
break;
|
||||
case MS_AES_128_NO_AUTH:
|
||||
params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1;
|
||||
break;
|
||||
case MS_NO_CIPHER_SHA1_80:
|
||||
params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80;
|
||||
break;
|
||||
case MS_AES_128_SHA1_80:
|
||||
params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1;
|
||||
params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80;
|
||||
break;
|
||||
case MS_AES_256_SHA1_80:
|
||||
params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES3;
|
||||
params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80;
|
||||
break;
|
||||
case MS_AES_256_SHA1_32:
|
||||
params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES3;
|
||||
params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80;
|
||||
break;
|
||||
case MS_CRYPTO_SUITE_INVALID:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* linphone_core_get_srtp_crypto_suites is used to determine sensible defaults; here each can be overridden */
|
||||
ciphersCount = linphone_core_get_zrtp_cipher_suites(lc, params->ciphers); /* if not present in config file, params->ciphers is not modified */
|
||||
if (ciphersCount!=0) { /* use zrtp_cipher_suites config only when present, keep config from srtp_crypto_suite otherwise */
|
||||
params->ciphersCount = ciphersCount;
|
||||
}
|
||||
params->hashesCount = linphone_core_get_zrtp_hash_suites(lc, params->hashes);
|
||||
authTagsCount = linphone_core_get_zrtp_auth_suites(lc, params->authTags); /* if not present in config file, params->authTags is not modified */
|
||||
if (authTagsCount!=0) {
|
||||
params->authTagsCount = authTagsCount; /* use zrtp_auth_suites config only when present, keep config from srtp_crypto_suite otherwise */
|
||||
}
|
||||
params->sasTypesCount = linphone_core_get_zrtp_sas_suites(lc, params->sasTypes);
|
||||
params->keyAgreementsCount = linphone_core_get_zrtp_key_agreement_suites(lc, params->keyAgreements);
|
||||
}
|
||||
|
||||
static void linphone_call_set_symmetric_rtp(LinphoneCall *call, bool_t val){
|
||||
int i;
|
||||
for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++i){
|
||||
|
|
@ -3499,24 +3557,6 @@ void linphone_call_start_media_streams(LinphoneCall *call, LinphoneCallState nex
|
|||
|
||||
call->up_bw=linphone_core_get_upload_bandwidth(lc);
|
||||
|
||||
/*might be moved in audio/video stream_start*/
|
||||
if (call->params->media_encryption==LinphoneMediaEncryptionZRTP) {
|
||||
MSZrtpParams params;
|
||||
memset(¶ms,0,sizeof(MSZrtpParams));
|
||||
/*call->current_params.media_encryption will be set later when zrtp is activated*/
|
||||
params.zid_file=lc->zrtp_secrets_cache;
|
||||
params.uri= linphone_address_as_string_uri_only((call->dir==LinphoneCallIncoming) ? call->log->from : call->log->to);
|
||||
setZrtpCryptoTypesParameters(¶ms,call->core);
|
||||
audio_stream_enable_zrtp(call->audiostream,¶ms);
|
||||
#if VIDEO_ENABLED
|
||||
if (media_stream_secured((MediaStream *)call->audiostream) && media_stream_get_state((MediaStream *)call->videostream) == MSStreamStarted) {
|
||||
/*audio stream is already encrypted and video stream is active*/
|
||||
memset(¶ms,0,sizeof(MSZrtpParams));
|
||||
video_stream_enable_zrtp(call->videostream,call->audiostream,¶ms);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (call->params->realtimetext_enabled) {
|
||||
linphone_call_start_text_stream(call);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -477,6 +477,7 @@ static void initiate_incoming(MSFactory *factory, const SalStreamDescription *lo
|
|||
result->bandwidth=local_cap->bandwidth;
|
||||
result->ptime=local_cap->ptime;
|
||||
}
|
||||
|
||||
if (sal_stream_description_has_srtp(result) == TRUE) {
|
||||
/* select crypto algo */
|
||||
memset(result->crypto, 0, sizeof(result->crypto));
|
||||
|
|
@ -486,6 +487,15 @@ static void initiate_incoming(MSFactory *factory, const SalStreamDescription *lo
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
if (remote_offer->haveZrtpHash == 1) {
|
||||
if (local_cap->haveZrtpHash == 1) {
|
||||
strncpy((char *)(result->zrtphash), (char *)(local_cap->zrtphash), sizeof(local_cap->zrtphash));
|
||||
result->haveZrtpHash = 1;
|
||||
}
|
||||
/* TODO: what if remote offer a zrtp-hash but we don't have it in local */
|
||||
}
|
||||
|
||||
strcpy(result->ice_pwd, local_cap->ice_pwd);
|
||||
strcpy(result->ice_ufrag, local_cap->ice_ufrag);
|
||||
result->ice_mismatch = local_cap->ice_mismatch;
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ SalMediaDescription *sal_media_description_new(){
|
|||
md->streams[i].dir=SalStreamInactive;
|
||||
md->streams[i].rtp_port = 0;
|
||||
md->streams[i].rtcp_port = 0;
|
||||
md->streams[i].haveZrtpHash = 0;
|
||||
}
|
||||
return md;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -261,6 +261,8 @@ typedef struct SalStreamDescription{
|
|||
bool_t pad[1];
|
||||
char dtls_fingerprint[256];
|
||||
SalDtlsRole dtls_role;
|
||||
uint8_t zrtphash[128];
|
||||
uint8_t haveZrtpHash; /**< flag for zrtp hash presence */
|
||||
int ttl; /*for multicast -1 to disable*/
|
||||
SalMulticastRole multicast_role;
|
||||
} SalStreamDescription;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 018228fe85cd4c2f0e0882b11d53f0b4df172974
|
||||
Subproject commit 2abbb7ae3c3585533c0f731f2fc56611597e9158
|
||||
2
oRTP
2
oRTP
|
|
@ -1 +1 @@
|
|||
Subproject commit 40feb7a5001060c6d13d563880828be59ff0381a
|
||||
Subproject commit 146a8b2bf5f8768aa7596f48084f783bf31d1bf0
|
||||
Loading…
Add table
Reference in a new issue