mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-26 15:48:09 +00:00
allow crypto lines to be configured from linphonerc, and improve code handling SRTP crypto lines
This commit is contained in:
parent
cc5570cae5
commit
fbc8f77e3a
10 changed files with 118 additions and 69 deletions
|
|
@ -999,3 +999,4 @@ void sal_cancel_timer(Sal *sal, belle_sip_source_t *timer) {
|
|||
belle_sip_main_loop_t *ml = belle_sip_stack_get_main_loop(sal->stack);
|
||||
belle_sip_main_loop_remove_source(ml, timer);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -146,36 +146,15 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session
|
|||
if ( stream->proto == SalProtoRtpSavp ) {
|
||||
/* add crypto lines */
|
||||
for ( j=0; j<SAL_CRYPTO_ALGO_MAX; j++ ) {
|
||||
const char *enc_name=NULL;
|
||||
|
||||
switch ( stream->crypto[j].algo ) {
|
||||
case MS_AES_128_SHA1_80:
|
||||
enc_name="AES_CM_128_HMAC_SHA1_80";
|
||||
break;
|
||||
case MS_AES_128_SHA1_32:
|
||||
enc_name="AES_CM_128_HMAC_SHA1_32";
|
||||
break;
|
||||
case MS_AES_256_SHA1_32:
|
||||
enc_name="AES_CM_256_HMAC_SHA1_32";
|
||||
break;
|
||||
case MS_AES_256_SHA1_80:
|
||||
enc_name="AES_CM_256_HMAC_SHA1_32";
|
||||
break;
|
||||
case MS_AES_128_NO_AUTH:
|
||||
ms_warning ( "Unsupported crypto suite: AES_128_NO_AUTH" );
|
||||
break;
|
||||
case MS_NO_CIPHER_SHA1_80:
|
||||
ms_warning ( "Unsupported crypto suite: NO_CIPHER_SHA1_80" );
|
||||
break;
|
||||
default:
|
||||
j = SAL_CRYPTO_ALGO_MAX;
|
||||
/* no break */
|
||||
}
|
||||
if (enc_name){
|
||||
snprintf ( buffer, sizeof ( buffer )-1, "%d %s inline:%s",
|
||||
stream->crypto[j].tag, enc_name, stream->crypto[j].master_key );
|
||||
belle_sdp_media_description_add_attribute ( media_desc,belle_sdp_attribute_create ( "crypto",buffer ) );
|
||||
}
|
||||
MSCryptoSuiteNameParams desc;
|
||||
if (ms_crypto_suite_to_name_params(stream->crypto[j].algo,&desc)==0){
|
||||
if (desc.params)
|
||||
snprintf ( buffer, sizeof ( buffer )-1, "%d %s inline:%s %s", stream->crypto[j].tag, desc.name, stream->crypto[j].master_key,desc.params);
|
||||
else
|
||||
snprintf ( buffer, sizeof ( buffer )-1, "%d %s inline:%s", stream->crypto[j].tag, desc.name, stream->crypto[j].master_key );
|
||||
|
||||
belle_sdp_media_description_add_attribute( media_desc,belle_sdp_attribute_create ("crypto", buffer));
|
||||
}else break;
|
||||
}
|
||||
}
|
||||
switch ( stream->dir ) {
|
||||
|
|
@ -330,7 +309,7 @@ static void sdp_parse_payload_types(belle_sdp_media_description_t *media_desc, S
|
|||
static void sdp_parse_media_crypto_parameters(belle_sdp_media_description_t *media_desc, SalStreamDescription *stream) {
|
||||
belle_sip_list_t *attribute_it;
|
||||
belle_sdp_attribute_t *attribute;
|
||||
char tmp[256], tmp2[256];
|
||||
char tmp[256], tmp2[256], parameters[256]={0};
|
||||
int valid_count = 0;
|
||||
int nb;
|
||||
|
||||
|
|
@ -341,42 +320,39 @@ static void sdp_parse_media_crypto_parameters(belle_sdp_media_description_t *med
|
|||
attribute=BELLE_SDP_ATTRIBUTE ( attribute_it->data );
|
||||
|
||||
if ( keywordcmp ( "crypto",belle_sdp_attribute_get_name ( attribute ) ) ==0 && belle_sdp_attribute_get_value ( attribute ) !=NULL ) {
|
||||
nb = sscanf ( belle_sdp_attribute_get_value ( attribute ), "%d %256s inline:%256s",
|
||||
nb = sscanf ( belle_sdp_attribute_get_value ( attribute ), "%d %256s inline:%256s %256s",
|
||||
&stream->crypto[valid_count].tag,
|
||||
tmp,
|
||||
tmp2 );
|
||||
ms_message ( "Found valid crypto line (tag:%d algo:'%s' key:'%s'",
|
||||
stream->crypto[valid_count].tag,
|
||||
tmp,
|
||||
tmp2 );
|
||||
if ( nb == 3 ) {
|
||||
if ( keywordcmp ( "AES_CM_128_HMAC_SHA1_80",tmp ) == 0 ){
|
||||
stream->crypto[valid_count].algo = MS_AES_128_SHA1_80;
|
||||
}else if ( keywordcmp ( "AES_CM_128_HMAC_SHA1_32",tmp ) == 0 ){
|
||||
stream->crypto[valid_count].algo = MS_AES_128_SHA1_32;
|
||||
}else if ( keywordcmp ( "AES_CM_256_HMAC_SHA1_32",tmp ) == 0 ){
|
||||
stream->crypto[valid_count].algo = MS_AES_256_SHA1_32;
|
||||
}else if ( keywordcmp ( "AES_CM_256_HMAC_SHA1_80",tmp ) == 0 ){
|
||||
stream->crypto[valid_count].algo = MS_AES_256_SHA1_80;
|
||||
}else {
|
||||
tmp2, parameters );
|
||||
|
||||
if ( nb >= 3 ) {
|
||||
MSCryptoSuite cs;
|
||||
MSCryptoSuiteNameParams np;
|
||||
|
||||
np.name=tmp;
|
||||
np.params=parameters[0]!='\0' ? parameters : NULL;
|
||||
cs=ms_crypto_suite_build_from_name_params(&np);
|
||||
if (cs==MS_CRYPTO_SUITE_INVALID){
|
||||
ms_warning ( "Failed to parse crypto-algo: '%s'", tmp );
|
||||
stream->crypto[valid_count].algo = 0;
|
||||
}
|
||||
if ( stream->crypto[valid_count].algo ) {
|
||||
strncpy ( stream->crypto[valid_count].master_key, tmp2, 41 );
|
||||
stream->crypto[valid_count].master_key[40] = '\0';
|
||||
}else{
|
||||
char *sep;
|
||||
strncpy ( stream->crypto[valid_count].master_key, tmp2, sizeof(stream->crypto[valid_count].master_key)-1 );
|
||||
sep=strchr(stream->crypto[valid_count].master_key,'|');
|
||||
if (sep) *sep='\0';
|
||||
stream->crypto[valid_count].algo = cs;
|
||||
ms_message ( "Found valid crypto line (tag:%d algo:'%s' key:'%s'",
|
||||
stream->crypto[valid_count].tag,
|
||||
tmp,
|
||||
stream->crypto[valid_count].master_key );
|
||||
valid_count++;
|
||||
}
|
||||
} else {
|
||||
}else{
|
||||
ms_warning ( "sdp has a strange a= line (%s) nb=%i",belle_sdp_attribute_get_value ( attribute ),nb );
|
||||
}
|
||||
}
|
||||
}
|
||||
ms_message ( "Found: %d valid crypto lines", valid_count );
|
||||
ms_message("Found: %d valid crypto lines", valid_count );
|
||||
}
|
||||
|
||||
static void sdp_parse_media_ice_parameters(belle_sdp_media_description_t *media_desc, SalStreamDescription *stream) {
|
||||
|
|
|
|||
|
|
@ -232,9 +232,35 @@ static void update_media_description_from_stun(SalMediaDescription *md, const St
|
|||
}
|
||||
}
|
||||
|
||||
static int setup_encryption_key(SalSrtpCryptoAlgo *crypto, MSCryptoSuite suite, unsigned int tag){
|
||||
int keylen=0;
|
||||
crypto->tag=tag;
|
||||
crypto->algo=suite;
|
||||
switch(suite){
|
||||
case MS_AES_128_SHA1_80:
|
||||
case MS_AES_128_SHA1_32:
|
||||
case MS_AES_128_NO_AUTH:
|
||||
case MS_NO_CIPHER_SHA1_80: /*not sure for this one*/
|
||||
keylen=30;
|
||||
break;
|
||||
case MS_AES_256_SHA1_80:
|
||||
case MS_AES_256_SHA1_32:
|
||||
keylen=46;
|
||||
break;
|
||||
case MS_CRYPTO_SUITE_INVALID:
|
||||
break;
|
||||
}
|
||||
if (keylen==0 || !generate_b64_crypto_key(30, crypto->master_key, SAL_SRTP_KEY_SIZE)){
|
||||
ms_error("Could not generate SRTP key.");
|
||||
crypto->algo = 0;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void setup_encryption_keys(LinphoneCall *call, SalMediaDescription *md){
|
||||
LinphoneCore *lc=call->core;
|
||||
int i;
|
||||
int i,j;
|
||||
SalMediaDescription *old_md=call->localdesc;
|
||||
bool_t keep_srtp_keys=lp_config_get_int(lc->config,"sip","keep_srtp_keys",1);
|
||||
|
||||
|
|
@ -247,15 +273,10 @@ static void setup_encryption_keys(LinphoneCall *call, SalMediaDescription *md){
|
|||
memcpy(&md->streams[i].crypto[j],&old_md->streams[i].crypto[j],sizeof(SalSrtpCryptoAlgo));
|
||||
}
|
||||
}else{
|
||||
md->streams[i].crypto[0].tag = 1;
|
||||
md->streams[i].crypto[0].algo = MS_AES_128_SHA1_80;
|
||||
if (!generate_b64_crypto_key(30, md->streams[i].crypto[0].master_key, SAL_SRTP_KEY_SIZE))
|
||||
md->streams[i].crypto[0].algo = 0;
|
||||
md->streams[i].crypto[1].tag = 2;
|
||||
md->streams[i].crypto[1].algo = MS_AES_128_SHA1_32;
|
||||
if (!generate_b64_crypto_key(30, md->streams[i].crypto[1].master_key, SAL_SRTP_KEY_SIZE))
|
||||
md->streams[i].crypto[1].algo = 0;
|
||||
md->streams[i].crypto[2].algo = 0;
|
||||
const MSCryptoSuite *suites=linphone_core_get_srtp_crypto_suites(lc);
|
||||
for(j=0;suites!=NULL && suites[j]!=MS_CRYPTO_SUITE_INVALID && j<SAL_CRYPTO_ALGO_MAX;++j){
|
||||
setup_encryption_key(&md->streams[i].crypto[j],suites[j],j+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5738,6 +5738,7 @@ void rtp_config_uninit(LinphoneCore *lc)
|
|||
lp_config_set_int(lc->config,"rtp","nortp_timeout",config->nortp_timeout);
|
||||
lp_config_set_int(lc->config,"rtp","audio_adaptive_jitt_comp_enabled",config->audio_adaptive_jitt_comp_enabled);
|
||||
lp_config_set_int(lc->config,"rtp","video_adaptive_jitt_comp_enabled",config->video_adaptive_jitt_comp_enabled);
|
||||
ms_free(config->srtp_suites);
|
||||
}
|
||||
|
||||
static void sound_config_uninit(LinphoneCore *lc)
|
||||
|
|
|
|||
|
|
@ -1471,3 +1471,52 @@ void linphone_core_set_tone(LinphoneCore *lc, LinphoneToneID id, const char *aud
|
|||
_linphone_core_set_tone(lc, LinphoneReasonNone, id, audiofile);
|
||||
}
|
||||
|
||||
const MSCryptoSuite * linphone_core_get_srtp_crypto_suites(LinphoneCore *lc){
|
||||
const char *config=lp_config_get_string(lc->config,"sip","srtp_crypto_suites","AES_CM_128_HMAC_SHA1_80, AES_CM_128_HMAC_SHA1_32");
|
||||
char *tmp=ms_strdup(config);
|
||||
char *sep;
|
||||
char *pos;
|
||||
char *nextpos;
|
||||
char *params;
|
||||
int found=0;
|
||||
MSCryptoSuite *result=NULL;
|
||||
pos=tmp;
|
||||
do{
|
||||
sep=strchr(pos,',');
|
||||
if (!sep) {
|
||||
sep=pos+strlen(pos);
|
||||
nextpos=NULL;
|
||||
}else {
|
||||
*sep='\0';
|
||||
nextpos=sep+1;
|
||||
}
|
||||
while(*pos==' ') ++pos; /*strip leading spaces*/
|
||||
params=strchr(pos,' '); /*look for params that arrive after crypto suite name*/
|
||||
if (params){
|
||||
while(*params==' ') ++params; /*strip parameters leading space*/
|
||||
}
|
||||
if (sep-pos>0){
|
||||
MSCryptoSuiteNameParams np;
|
||||
MSCryptoSuite suite;
|
||||
np.name=pos;
|
||||
np.params=params;
|
||||
suite=ms_crypto_suite_build_from_name_params(&np);
|
||||
if (suite!=MS_CRYPTO_SUITE_INVALID){
|
||||
result=ms_realloc(result,found+1+1);
|
||||
result[found]=suite;
|
||||
result[found+1]=MS_CRYPTO_SUITE_INVALID;
|
||||
found++;
|
||||
ms_message("Configured srtp crypto suite: %s %s",np.name,np.params ? np.params : "");
|
||||
}
|
||||
}
|
||||
pos=nextpos;
|
||||
}while(pos);
|
||||
ms_free(tmp);
|
||||
if (lc->rtp_conf.srtp_suites){
|
||||
ms_free(lc->rtp_conf.srtp_suites);
|
||||
lc->rtp_conf.srtp_suites=NULL;
|
||||
}
|
||||
lc->rtp_conf.srtp_suites=result;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -156,17 +156,16 @@ static bool_t match_crypto_algo(const SalSrtpCryptoAlgo* local, const SalSrtpCry
|
|||
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);
|
||||
strncpy(result->master_key, local[j].master_key, sizeof(result->master_key) );
|
||||
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);
|
||||
strncpy(result->master_key, remote[i].master_key, sizeof(result->master_key));
|
||||
result->tag = local[j].tag;
|
||||
*choosen_local_tag = local[j].tag;
|
||||
}
|
||||
result->master_key[40] = '\0';
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -519,6 +519,7 @@ typedef struct rtp_config
|
|||
int video_jitt_comp; /*jitter compensation*/
|
||||
int nortp_timeout;
|
||||
int disable_upnp;
|
||||
MSCryptoSuite *srtp_suites;
|
||||
bool_t rtp_no_xmit_on_audio_mute;
|
||||
/* stop rtp xmit when audio muted */
|
||||
bool_t audio_adaptive_jitt_comp_enabled;
|
||||
|
|
@ -886,6 +887,7 @@ static inline const LinphoneErrorInfo *linphone_error_info_from_sal_op(const Sal
|
|||
return (const LinphoneErrorInfo*)sal_op_get_error_info(op);
|
||||
}
|
||||
|
||||
const MSCryptoSuite * linphone_core_get_srtp_crypto_suites(LinphoneCore *lc);
|
||||
|
||||
/** Belle Sip-based objects need unique ids
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ typedef struct SalIceRemoteCandidate {
|
|||
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_PWD_LEN 256
|
||||
|
||||
/*sufficient for 256bit keys encoded in base 64*/
|
||||
#define SAL_SRTP_KEY_SIZE 64
|
||||
#define SAL_SRTP_KEY_SIZE 128
|
||||
|
||||
typedef struct SalSrtpCryptoAlgo {
|
||||
unsigned int tag;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit ad376cf215143507c1f8e297084e210939e7f31b
|
||||
Subproject commit b6ad773d4896b36fd707b6fc4f743b6b7df7325a
|
||||
2
oRTP
2
oRTP
|
|
@ -1 +1 @@
|
|||
Subproject commit 73317c9bf59700b44f85008f6e254476bbe756eb
|
||||
Subproject commit e4f28d1434b8f18061fb6a45a80649c4bc13cf9a
|
||||
Loading…
Add table
Reference in a new issue