@ -1288,7 +1288,7 @@ static void __generate_crypto(const struct sdp_ng_flags *flags, struct call_medi
MEDIA_CLEAR ( this , SETUP_PASSIVE ) ;
}
if ( ! MEDIA_ ISSET( this , INITIALIZED ) ) {
if ( ! MEDIA_ ARESET2( this , DTLS , SDES ) & & flags - > opmode = = OP_OFFER ) {
/* we offer both DTLS and SDES by default */
/* unless this is overridden by flags */
if ( ! flags - > dtls_off )
@ -1315,60 +1315,84 @@ static void __generate_crypto(const struct sdp_ng_flags *flags, struct call_medi
/* SDES parameters below */
if ( flags - > opmode = = OP_OFFER ) {
if ( ! cpq - > head ) {
// generate a new set of params
// if we were offered some crypto suites, copy those first into our offer
unsigned int c_tag = 1 ; // tag for next crypto suite generated by us
unsigned long types_offered = 0 ;
// generate full set of params
// re-create the entire list - steal for later flushing
GQueue cpq_orig = * cpq ;
g_queue_init ( cpq ) ;
// make sure our bit field is large enough
assert ( num_crypto_suites < = sizeof ( types_offered ) * 8 ) ;
// if we were offered some crypto suites, copy those first into our offer
unsigned int c_tag = 1 ; // tag for next crypto suite generated by us
unsigned long types_offered = 0 ;
for ( GList * l = offered_cpq - > head ; l ; l = l - > next ) {
struct crypto_params_sdes * offered_cps = l - > data ;
// make sure our bit field is large enough
assert ( num_crypto_suites < = sizeof ( types_offered ) * 8 ) ;
struct crypto_params_sdes * cps = g_slice_alloc0 ( sizeof ( * cps ) ) ;
g_queue_push_tail ( cpq , cps ) ;
for ( GList * l = offered_cpq - > head ; l ; l = l - > next ) {
struct crypto_params_sdes * offered_cps = l - > data ;
cps - > tag = offered_cps - > tag ;
// our own offered tags will be higher than the ones we received
if ( cps - > tag > = c_tag )
c_tag = cps - > tag + 1 ;
crypto_params_copy ( & cps - > params , & offered_cps - > params , 1 ) ;
struct crypto_params_sdes * cps = g_slice_alloc0 ( sizeof ( * cps ) ) ;
g_queue_push_tail ( cpq , cps ) ;
cps - > tag = offered_cps - > tag ;
// our own offered tags will be higher than the ones we received
if ( cps - > tag > = c_tag )
c_tag = cps - > tag + 1 ;
crypto_params_copy ( & cps - > params , & offered_cps - > params , 1 ) ;
// we use a bit field to keep track of which types we've seen here
types_offered | = 1 < < cps - > params . crypto_suite - > idx ;
// we use a bit field to keep track of which types we've seen here
types_offered | = 1 < < cps - > params . crypto_suite - > idx ;
__sdes_flags ( cps , flags ) ;
}
__sdes_flags ( cps , flags ) ;
// if we had any suites added before, re-add those that aren't there yet
struct crypto_params_sdes * cps_orig ;
while ( ( cps_orig = g_queue_pop_head ( & cpq_orig ) ) ) {
if ( ( types_offered & ( 1 < < cps_orig - > params . crypto_suite - > idx ) ) ) {
crypto_params_sdes_free ( cps_orig ) ;
continue ;
}
// generate crypto suite offers for any types that we haven't seen above
for ( unsigned int i = 0 ; i < num_crypto_suites ; i + + ) {
if ( ( types_offered & ( 1 < < i ) ) )
continue ;
// make sure our tag is higher than what we've seen
if ( cps_orig - > tag < c_tag )
cps_orig - > tag = c_tag ;
if ( cps_orig - > tag > = c_tag )
c_tag = cps_orig - > tag + 1 ;
if ( flags - > sdes_no & & g_hash_table_lookup ( flags - > sdes_no ,
& crypto_suites [ i ] . name_str ) )
{
ilog ( LOG_DEBUG , " Not offering crypto suite '%s' "
" due to 'SDES-no' option " ,
crypto_suites [ i ] . name ) ;
continue ;
}
g_queue_push_tail ( cpq , cps_orig ) ;
struct crypto_params_sdes * cps = g_slice_alloc0 ( sizeof ( * cps ) ) ;
g_queue_push_tail ( cpq , cps ) ;
types_offered | = 1 < < cps_orig - > params . crypto_suite - > idx ;
}
cps - > tag = c_tag + + ;
cps - > params . crypto_suite = & crypto_suites [ i ] ;
random_string ( ( unsigned char * ) cps - > params . master_key ,
cps - > params . crypto_suite - > master_key_len ) ;
random_string ( ( unsigned char * ) cps - > params . master_salt ,
cps - > params . crypto_suite - > master_salt_len ) ;
/* mki = mki_len = 0 */
// generate crypto suite offers for any types that we haven't seen above
// XXX for re-invites, this always creates new crypto keys for suites
// that weren't accepted before, instead of re-using the same keys (and
// suites) that were previously offered but not accepted
for ( unsigned int i = 0 ; i < num_crypto_suites ; i + + ) {
if ( ( types_offered & ( 1 < < i ) ) )
continue ;
__sdes_flags ( cps , flags ) ;
if ( flags - > sdes_no & & g_hash_table_lookup ( flags - > sdes_no ,
& crypto_suites [ i ] . name_str ) )
{
ilog ( LOG_DEBUG , " Not offering crypto suite '%s' "
" due to 'SDES-no' option " ,
crypto_suites [ i ] . name ) ;
continue ;
}
struct crypto_params_sdes * cps = g_slice_alloc0 ( sizeof ( * cps ) ) ;
g_queue_push_tail ( cpq , cps ) ;
cps - > tag = c_tag + + ;
cps - > params . crypto_suite = & crypto_suites [ i ] ;
random_string ( ( unsigned char * ) cps - > params . master_key ,
cps - > params . crypto_suite - > master_key_len ) ;
random_string ( ( unsigned char * ) cps - > params . master_salt ,
cps - > params . crypto_suite - > master_salt_len ) ;
/* mki = mki_len = 0 */
__sdes_flags ( cps , flags ) ;
}
}
else { // OP_ANSWER