Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
liblinphone
Commits
0a0f714c
Commit
0a0f714c
authored
Apr 15, 2016
by
johan
Browse files
improve ZRTP hash management
- start ZRTP on incoming zrtp-hash even when not selected locally
parent
83f861b3
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
123 additions
and
21 deletions
+123
-21
coreapi/linphonecall.c
coreapi/linphonecall.c
+27
-6
coreapi/offeranswer.c
coreapi/offeranswer.c
+1
-2
coreapi/sal.c
coreapi/sal.c
+15
-0
include/sal/sal.h
include/sal/sal.h
+1
-0
tester/call_tester.c
tester/call_tester.c
+79
-13
No files found.
coreapi/linphonecall.c
View file @
0a0f714c
...
...
@@ -524,12 +524,16 @@ 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
)
{
if
(
ms_zrtp_available
())
{
/* set the hello hash for all streams */
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
;
if
(
call
->
params
->
media_encryption
==
LinphoneMediaEncryptionZRTP
)
{
/* turn on the flag to use it if ZRTP is set */
md
->
streams
[
i
].
haveZrtpHash
=
1
;
}
else
{
md
->
streams
[
i
].
haveZrtpHash
=
0
;
}
}
else
{
md
->
streams
[
i
].
haveZrtpHash
=
0
;
}
...
...
@@ -1179,7 +1183,9 @@ void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, S
call
->
params
->
avpf_rr_interval
=
linphone_core_get_avpf_rr_interval
(
call
->
core
)
*
1000
;
}
}
if
((
sal_media_description_has_dtls
(
md
)
==
TRUE
)
&&
(
media_stream_dtls_supported
()
==
TRUE
))
{
if
((
sal_media_description_has_zrtp
(
md
)
==
TRUE
)
&&
(
ms_zrtp_available
()
==
TRUE
))
{
call
->
params
->
media_encryption
=
LinphoneMediaEncryptionZRTP
;
}
else
if
((
sal_media_description_has_dtls
(
md
)
==
TRUE
)
&&
(
media_stream_dtls_supported
()
==
TRUE
))
{
call
->
params
->
media_encryption
=
LinphoneMediaEncryptionDTLS
;
}
else
if
((
sal_media_description_has_srtp
(
md
)
==
TRUE
)
&&
(
ms_srtp_supported
()
==
TRUE
))
{
call
->
params
->
media_encryption
=
LinphoneMediaEncryptionSRTP
;
...
...
@@ -1815,7 +1821,12 @@ const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){
}
//else don't update the state if all streams are shutdown.
break
;
case
LinphoneMediaEncryptionNone
:
call
->
current_params
->
media_encryption
=
LinphoneMediaEncryptionNone
;
/* check if we actually switched to ZRTP */
if
(
at_least_one_stream_started
(
call
)
&&
(
all_streams_encrypted
=
linphone_call_all_streams_encrypted
(
call
))
&&
linphone_call_get_authentication_token
(
call
))
{
call
->
current_params
->
media_encryption
=
LinphoneMediaEncryptionZRTP
;
}
else
{
call
->
current_params
->
media_encryption
=
LinphoneMediaEncryptionNone
;
}
break
;
}
call
->
current_params
->
avpf_enabled
=
linphone_call_all_streams_avpf_enabled
(
call
)
&&
sal_media_description_has_avpf
(
md
);
...
...
@@ -3360,6 +3371,10 @@ static void linphone_call_start_video_stream(LinphoneCall *call, LinphoneCallSta
}
cam
=
linphone_call_get_video_device
(
call
);
if
(
!
is_inactive
){
/* 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
,
SalVideo
);
if
(
sal_stream_description_has_srtp
(
vstream
)
==
TRUE
)
{
int
crypto_idx
=
find_crypto_index_from_tag
(
local_st_desc
->
crypto
,
vstream
->
crypto_local_tag
);
if
(
crypto_idx
>=
0
)
{
...
...
@@ -3412,11 +3427,17 @@ 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
)
{
/* 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 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
);
if
(
remote_stream
->
haveZrtpHash
==
1
)
{
int
retval
;
if
((
retval
=
ms_zrtp_setPeerHelloHash
(
call
->
videostream
->
ms
.
sessions
.
zrtp_context
,
(
uint8_t
*
)
remote_stream
->
zrtphash
,
strlen
((
const
char
*
)(
remote_stream
->
zrtphash
))))
!=
0
)
{
ms_error
(
"video stream ZRTP hash mismatch 0x%x"
,
retval
);
}
}
}
}
}
...
...
coreapi/offeranswer.c
View file @
0a0f714c
...
...
@@ -489,11 +489,10 @@ static void initiate_incoming(MSFactory *factory, const SalStreamDescription *lo
}
if
(
remote_offer
->
haveZrtpHash
==
1
)
{
if
(
local_cap
->
haveZ
rtp
H
ash
==
1
)
{
if
(
ms_zrtp_available
())
{
/* if ZRTP is available, set the z
rtp
h
ash
even if it is not selected */
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
);
...
...
coreapi/sal.c
View file @
0a0f714c
...
...
@@ -257,6 +257,11 @@ bool_t sal_stream_description_has_dtls(const SalStreamDescription *sd) {
return
FALSE
;
}
bool_t
sal_stream_description_has_zrtp
(
const
SalStreamDescription
*
sd
)
{
if
(
sd
->
haveZrtpHash
==
1
)
return
TRUE
;
return
FALSE
;
}
bool_t
sal_media_description_has_avpf
(
const
SalMediaDescription
*
md
)
{
int
i
;
if
(
md
->
nb_streams
==
0
)
return
FALSE
;
...
...
@@ -297,6 +302,16 @@ bool_t sal_media_description_has_dtls(const SalMediaDescription *md) {
return
TRUE
;
}
bool_t
sal_media_description_has_zrtp
(
const
SalMediaDescription
*
md
)
{
int
i
;
if
(
md
->
nb_streams
==
0
)
return
FALSE
;
for
(
i
=
0
;
i
<
SAL_MEDIA_DESCRIPTION_MAX_STREAMS
;
i
++
)
{
if
(
!
sal_stream_description_active
(
&
md
->
streams
[
i
]))
continue
;
if
(
sal_stream_description_has_zrtp
(
&
md
->
streams
[
i
])
!=
TRUE
)
return
FALSE
;
}
return
TRUE
;
}
/*
static bool_t fmtp_equals(const char *p1, const char *p2){
if (p1 && p2 && strcmp(p1,p2)==0) return TRUE;
...
...
include/sal/sal.h
View file @
0a0f714c
...
...
@@ -330,6 +330,7 @@ bool_t sal_media_description_has_avpf(const SalMediaDescription *md);
bool_t
sal_media_description_has_implicit_avpf
(
const
SalMediaDescription
*
md
);
bool_t
sal_media_description_has_srtp
(
const
SalMediaDescription
*
md
);
bool_t
sal_media_description_has_dtls
(
const
SalMediaDescription
*
md
);
bool_t
sal_media_description_has_zrtp
(
const
SalMediaDescription
*
md
);
int
sal_media_description_get_nb_active_streams
(
const
SalMediaDescription
*
md
);
struct
SalOpBase
;
...
...
tester/call_tester.c
View file @
0a0f714c
...
...
@@ -331,13 +331,22 @@ bool_t call_with_params2(LinphoneCoreManager* caller_mgr
||
linphone_core_get_media_encryption
(
callee_mgr
->
lc
)
!=
LinphoneMediaEncryptionNone
)
{
/*wait for encryption to be on, in case of zrtp or dtls, it can take a few seconds*/
if
(
(
linphone_core_get_media_encryption
(
caller_mgr
->
lc
)
==
LinphoneMediaEncryptionZRTP
)
||
(
linphone_core_get_media_encryption
(
callee_mgr
->
lc
)
==
LinphoneMediaEncryptionZRTP
)
/* is callee is ZRTP, wait for it */
||
(
linphone_core_get_media_encryption
(
caller_mgr
->
lc
)
==
LinphoneMediaEncryptionDTLS
))
wait_for
(
callee_mgr
->
lc
,
caller_mgr
->
lc
,
&
caller_mgr
->
stat
.
number_of_LinphoneCallEncryptedOn
,
initial_caller
.
number_of_LinphoneCallEncryptedOn
+
1
);
if
((
linphone_core_get_media_encryption
(
callee_mgr
->
lc
)
==
LinphoneMediaEncryptionZRTP
)
||
(
linphone_core_get_media_encryption
(
callee_mgr
->
lc
)
==
LinphoneMediaEncryptionDTLS
)
||
(
linphone_core_get_media_encryption
(
caller_mgr
->
lc
)
==
LinphoneMediaEncryptionZRTP
)
||
(
linphone_core_get_media_encryption
(
caller_mgr
->
lc
)
==
LinphoneMediaEncryptionDTLS
)
/*also take care of caller policy*/
)
wait_for
(
callee_mgr
->
lc
,
caller_mgr
->
lc
,
&
callee_mgr
->
stat
.
number_of_LinphoneCallEncryptedOn
,
initial_callee
.
number_of_LinphoneCallEncryptedOn
+
1
);
{
/* when caller is encryptionNone but callee is ZRTP, we expect ZRTP to take place */
if
((
linphone_core_get_media_encryption
(
caller_mgr
->
lc
)
==
LinphoneMediaEncryptionNone
)
&&
(
linphone_core_get_media_encryption
(
callee_mgr
->
lc
)
==
LinphoneMediaEncryptionZRTP
))
{
const
LinphoneCallParams
*
call_param
=
linphone_call_get_current_params
(
callee_call
);
BC_ASSERT_EQUAL
(
linphone_call_params_get_media_encryption
(
call_param
),
LinphoneMediaEncryptionZRTP
,
int
,
"%d"
);
call_param
=
linphone_call_get_current_params
(
linphone_core_get_current_call
(
caller_mgr
->
lc
));
BC_ASSERT_EQUAL
(
linphone_call_params_get_media_encryption
(
call_param
),
LinphoneMediaEncryptionZRTP
,
int
,
"%d"
);
}
else
{
/* otherwise, final status shall stick to caller core parameter */
const
LinphoneCallParams
*
call_param
=
linphone_call_get_current_params
(
callee_call
);
BC_ASSERT_EQUAL
(
linphone_call_params_get_media_encryption
(
call_param
),
linphone_core_get_media_encryption
(
caller_mgr
->
lc
),
int
,
"%d"
);
call_param
=
linphone_call_get_current_params
(
linphone_core_get_current_call
(
caller_mgr
->
lc
));
...
...
@@ -3134,8 +3143,9 @@ void call_base_with_configfile(LinphoneMediaEncryption mode, bool_t enable_video
BC_ASSERT_TRUE
((
call_ok
=
call
(
pauline
,
marie
)));
if
(
!
call_ok
)
goto
end
;
if
(
linphone_core_get_media_encryption
(
pauline
->
lc
)
==
LinphoneMediaEncryptionZRTP
&&
linphone_core_get_media_encryption
(
pauline
->
lc
)
==
LinphoneMediaEncryptionZRTP
)
{
/* if caller set ZRTP or (callee set ZRTP and caller has no encryption requested), ZRTP shall take place, wait for the SAS */
if
((
linphone_core_get_media_encryption
(
pauline
->
lc
)
==
LinphoneMediaEncryptionZRTP
)
||
((
linphone_core_get_media_encryption
(
marie
->
lc
)
==
LinphoneMediaEncryptionZRTP
)
&&
(
linphone_core_get_media_encryption
(
pauline
->
lc
)
==
LinphoneMediaEncryptionNone
)))
{
/*wait for SAS*/
int
i
;
for
(
i
=
0
;
i
<
100
;
i
++
)
{
...
...
@@ -6078,21 +6088,45 @@ static void call_with_ice_and_rtcp_mux_without_reinvite(void){
}
static
void
call_with_zrtp_configured_calling_base
(
LinphoneCoreManager
*
marie
,
LinphoneCoreManager
*
pauline
)
{
bool_t
call_ok
;
if
(
ms_zrtp_available
())
{
bool_t
call_ok
;
linphone_core_set_media_encryption
(
mari
e
->
lc
,
LinphoneMediaEncryptionZRTP
);
BC_ASSERT_TRUE
((
call_ok
=
call
(
pauline
,
marie
)));
linphone_core_set_media_encryption
(
paulin
e
->
lc
,
LinphoneMediaEncryptionZRTP
);
BC_ASSERT_TRUE
((
call_ok
=
call
(
pauline
,
marie
)));
liblinphone_tester_check_rtcp
(
marie
,
pauline
);
liblinphone_tester_check_rtcp
(
marie
,
pauline
);
BC_ASSERT_EQUAL
(
linphone_call_params_get_media_encryption
(
linphone_call_get_current_params
(
linphone_core_get_current_call
(
marie
->
lc
)))
,
LinphoneMediaEncryptionNone
,
int
,
"%i"
);
BC_ASSERT_EQUAL
(
linphone_call_params_get_media_encryption
(
linphone_call_get_current_params
(
linphone_core_get_current_call
(
pauline
->
lc
)))
,
LinphoneMediaEncryptionNone
,
int
,
"%i"
);
end_call
(
pauline
,
marie
);
BC_ASSERT_EQUAL
(
linphone_call_params_get_media_encryption
(
linphone_call_get_current_params
(
linphone_core_get_current_call
(
marie
->
lc
)))
,
LinphoneMediaEncryptionZRTP
,
int
,
"%i"
);
BC_ASSERT_EQUAL
(
linphone_call_params_get_media_encryption
(
linphone_call_get_current_params
(
linphone_core_get_current_call
(
pauline
->
lc
)))
,
LinphoneMediaEncryptionZRTP
,
int
,
"%i"
);
end_call
(
pauline
,
marie
);
}
else
{
ms_warning
(
"Test skipped, ZRTP not available"
);
}
}
static
void
call_with_zrtp_configured_callee_base
(
LinphoneCoreManager
*
marie
,
LinphoneCoreManager
*
pauline
)
{
if
(
ms_zrtp_available
())
{
bool_t
call_ok
;
linphone_core_set_media_encryption
(
marie
->
lc
,
LinphoneMediaEncryptionZRTP
);
BC_ASSERT_TRUE
((
call_ok
=
call
(
pauline
,
marie
)));
liblinphone_tester_check_rtcp
(
marie
,
pauline
);
BC_ASSERT_EQUAL
(
linphone_call_params_get_media_encryption
(
linphone_call_get_current_params
(
linphone_core_get_current_call
(
marie
->
lc
)))
,
LinphoneMediaEncryptionZRTP
,
int
,
"%i"
);
BC_ASSERT_EQUAL
(
linphone_call_params_get_media_encryption
(
linphone_call_get_current_params
(
linphone_core_get_current_call
(
pauline
->
lc
)))
,
LinphoneMediaEncryptionZRTP
,
int
,
"%i"
);
end_call
(
pauline
,
marie
);
}
else
{
ms_warning
(
"Test skipped, ZRTP not available"
);
}
}
/*
* this test checks the 'dont_default_to_stun_candidates' mode, where the c= line is left to host
* ip instead of stun candidate when ice is enabled*/
...
...
@@ -6137,6 +6171,16 @@ static void call_with_zrtp_configured_calling_side(void) {
call_with_zrtp_configured_calling_base
(
marie
,
pauline
);
/* now set other encryptions mode for receiver(marie), we shall always fall back to caller preference: ZRTP */
linphone_core_set_media_encryption
(
marie
->
lc
,
LinphoneMediaEncryptionDTLS
);
call_with_zrtp_configured_calling_base
(
marie
,
pauline
);
linphone_core_set_media_encryption
(
marie
->
lc
,
LinphoneMediaEncryptionSRTP
);
call_with_zrtp_configured_calling_base
(
marie
,
pauline
);
linphone_core_set_media_encryption
(
marie
->
lc
,
LinphoneMediaEncryptionNone
);
linphone_core_set_user_agent
(
pauline
->
lc
,
"Natted Linphone"
,
NULL
);
linphone_core_set_user_agent
(
marie
->
lc
,
"Natted Linphone"
,
NULL
);
call_with_zrtp_configured_calling_base
(
marie
,
pauline
);
...
...
@@ -6150,6 +6194,27 @@ static void call_with_zrtp_configured_calling_side(void) {
}
static
void
call_with_zrtp_configured_callee_side
(
void
)
{
LinphoneCoreManager
*
marie
=
linphone_core_manager_new
(
"marie_rc"
);
LinphoneCoreManager
*
pauline
=
linphone_core_manager_new
(
transport_supported
(
LinphoneTransportTls
)
?
"pauline_rc"
:
"pauline_tcp_rc"
);
call_with_zrtp_configured_callee_base
(
marie
,
pauline
);
linphone_core_set_user_agent
(
pauline
->
lc
,
"Natted Linphone"
,
NULL
);
linphone_core_set_user_agent
(
marie
->
lc
,
"Natted Linphone"
,
NULL
);
call_with_zrtp_configured_callee_base
(
marie
,
pauline
);
linphone_core_set_firewall_policy
(
marie
->
lc
,
LinphonePolicyUseIce
);
linphone_core_set_firewall_policy
(
pauline
->
lc
,
LinphonePolicyUseIce
);
call_with_zrtp_configured_callee_base
(
marie
,
pauline
);
linphone_core_manager_destroy
(
marie
);
linphone_core_manager_destroy
(
pauline
);
}
test_t
call_tests
[]
=
{
TEST_NO_TAG
(
"Early declined call"
,
early_declined_call
),
TEST_NO_TAG
(
"Call declined"
,
call_declined
),
...
...
@@ -6331,7 +6396,8 @@ test_t call_tests[] = {
TEST_ONE_TAG
(
"Call with ICE and rtcp-mux without ICE re-invite"
,
call_with_ice_and_rtcp_mux_without_reinvite
,
"ICE"
),
TEST_ONE_TAG
(
"Call with ICE with default candidate not stun"
,
call_with_ice_with_default_candidate_not_stun
,
"ICE"
),
TEST_ONE_TAG
(
"Call with ICE without stun server"
,
call_with_ice_without_stun
,
"ICE"
),
TEST_NO_TAG
(
"call with ZRTP configured calling side only"
,
call_with_zrtp_configured_calling_side
)
TEST_NO_TAG
(
"call with ZRTP configured calling side only"
,
call_with_zrtp_configured_calling_side
),
TEST_NO_TAG
(
"call with ZRTP configured receiver side only"
,
call_with_zrtp_configured_callee_side
)
};
test_suite_t
call_test_suite
=
{
"Single Call"
,
NULL
,
NULL
,
liblinphone_tester_before_each
,
liblinphone_tester_after_each
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment