Browse Source

TT#81850 fix SRTP re-offer and RTP to SRTP switch

1) In an SRTP re-invite offer, fixes not a full set of crypto suites
   being present
2) In a re-invite offer that switches from RTP to SRTP, fixes SRTP not
   being initialised at all

Change-Id: I911442d2cba17ecf6af482cfe922d4e9db2eda8d
changes/09/40109/4
Richard Fuchs 6 years ago
parent
commit
89175c8564
2 changed files with 317 additions and 42 deletions
  1. +66
    -42
      daemon/call.c
  2. +251
    -0
      t/auto-daemon-tests.pl

+ 66
- 42
daemon/call.c View File

@ -1317,7 +1317,7 @@ static void __generate_crypto(const struct sdp_ng_flags *flags, struct call_medi
MEDIA_CLEAR(this, SETUP_PASSIVE); 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 */ /* we offer both DTLS and SDES by default */
/* unless this is overridden by flags */ /* unless this is overridden by flags */
if (!flags->dtls_off) if (!flags->dtls_off)
@ -1344,60 +1344,84 @@ static void __generate_crypto(const struct sdp_ng_flags *flags, struct call_medi
/* SDES parameters below */ /* SDES parameters below */
if (flags->opmode == OP_OFFER) { 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 else { // OP_ANSWER


+ 251
- 0
t/auto-daemon-tests.pl View File

@ -35,6 +35,257 @@ my ($sock_a, $sock_b, $port_a, $port_b, $ssrc, $resp,
# RTP to SRTP switch (and SRTP re-invite) TT#81850
new_call;
(undef, undef, $srtp_key_a) = offer('RTP to SRTP switch (and SRTP re-invite)',
{ "transport-protocol" => "RTP/SAVP", "ICE" => "remove", "rtcp-mux" => [ "demux" ],
DTLS => 'off',
"replace" => [ "origin", "session-connection" ],
"via-branch" => "z9hG4bK0ae8.cc3c994fa8d0c0f1f2536bba541306fb.0",
}, <<SDP);
v=0
o=- 3516723349074626749 3516723349074626751 IN IP4 198.51.100.1
s=
c=IN IP4 198.51.100.1
t=0 0
m=audio 31530 RTP/AVP 0 101
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=direction:both
a=sendrecv
a=rtcp:31531
a=silenceSupp:off - - - -
a=mptime:20 -
a=oldmediaip:10.50.3.190
a=ptime:20
----------------------------------
v=0
o=- 3516723349074626749 3516723349074626751 IN IP4 203.0.113.1
s=
c=IN IP4 203.0.113.1
t=0 0
m=audio PORT RTP/SAVP 0 101
a=direction:both
a=silenceSupp:off - - - -
a=mptime:20 -
a=oldmediaip:10.50.3.190
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=sendrecv
a=rtcp:PORT
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:CRYPTO128
a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192
a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192
a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256
a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256
a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128
a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128
a=ptime:20
SDP
answer('RTP to SRTP switch (and SRTP re-invite)',
{ "ICE" => "remove", "rtcp-mux" => [ "demux" ],
DTLS => 'off',
"replace" => [ "origin", "session-connection" ],
"via-branch" => "z9hG4bK0ae8.cc3c994fa8d0c0f1f2536bba541306fb.0",
}, <<SDP);
v=0
o=- 1889691184267178502 1889691184267178505 IN IP4 198.51.100.1
s=
c=IN IP4 198.51.100.1
t=0 0
m=audio 31498 RTP/SAVP 0 101
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=direction:both
a=sendrecv
a=rtcp:31499
a=silenceSupp:off - - - -
a=mptime:20 -
a=oldmediaip:10.50.3.218
a=ptime:20
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:zC6Ea9EK/7YmDM79CK+TAnNXTI1pVmZuCMjUPMph
----------------------------------
v=0
o=- 1889691184267178502 1889691184267178505 IN IP4 203.0.113.1
s=
c=IN IP4 203.0.113.1
t=0 0
m=audio PORT RTP/AVP 0 101
a=direction:both
a=silenceSupp:off - - - -
a=mptime:20 -
a=oldmediaip:10.50.3.218
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=sendrecv
a=rtcp:PORT
a=ptime:20
SDP
offer('RTP to SRTP switch (and SRTP re-invite)',
{ "transport-protocol" => "RTP/SAVP", "ICE" => "remove", "rtcp-mux" => [ "demux" ],
DTLS => 'off',
"replace" => [ "origin", "session-connection" ],
"via-branch" => "z9hG4bK0ae8.cc3c994fa8d0c0f1f2536bba541306fb.0",
'to-tag' => tt(),
}, <<SDP);
v=0
o=- 3516723349074626749 3516723349074626751 IN IP4 198.51.100.1
s=
c=IN IP4 198.51.100.1
t=0 0
m=audio 31530 RTP/AVP 0 101
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=direction:both
a=sendrecv
a=rtcp:31531
a=silenceSupp:off - - - -
a=mptime:20 -
a=oldmediaip:10.50.3.190
a=ptime:20
----------------------------------
v=0
o=- 3516723349074626749 3516723349074626751 IN IP4 203.0.113.1
s=
c=IN IP4 203.0.113.1
t=0 0
m=audio PORT RTP/SAVP 0 101
a=direction:both
a=silenceSupp:off - - - -
a=mptime:20 -
a=oldmediaip:10.50.3.190
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=sendrecv
a=rtcp:PORT
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:$srtp_key_a
a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:CRYPTO128
a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192
a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192
a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256
a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256
a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128
a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128
a=ptime:20
SDP
answer('RTP to SRTP switch (and SRTP re-invite)',
{ "ICE" => "remove", "rtcp-mux" => [ "demux" ],
DTLS => 'off',
"replace" => [ "origin", "session-connection" ],
"via-branch" => "z9hG4bK0ae8.cc3c994fa8d0c0f1f2536bba541306fb.0",
}, <<SDP);
v=0
o=- 1889691184267178502 1889691184267178505 IN IP4 198.51.100.1
s=
c=IN IP4 198.51.100.1
t=0 0
m=audio 31498 RTP/SAVP 0 101
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=direction:both
a=sendrecv
a=rtcp:31499
a=silenceSupp:off - - - -
a=mptime:20 -
a=oldmediaip:10.50.3.218
a=ptime:20
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:zC6Ea9EK/7YmDM79CK+TAnNXTI1pVmZuCMjUPMph
----------------------------------
v=0
o=- 1889691184267178502 1889691184267178505 IN IP4 203.0.113.1
s=
c=IN IP4 203.0.113.1
t=0 0
m=audio PORT RTP/AVP 0 101
a=direction:both
a=silenceSupp:off - - - -
a=mptime:20 -
a=oldmediaip:10.50.3.218
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=sendrecv
a=rtcp:PORT
a=ptime:20
SDP
# reverse re-invite from RTP to SRTP
reverse_tags();
offer('RTP to SRTP switch (and SRTP re-invite)',
{ "transport-protocol" => "RTP/SAVP", "ICE" => "remove", "rtcp-mux" => [ "demux" ],
DTLS => 'off',
"replace" => [ "origin", "session-connection" ],
"via-branch" => "z9hG4bK0ae8.cc3c994fa8d0c0f1f2536bba541306fb.0",
'to-tag' => tt(),
}, <<SDP);
v=0
o=- 1889691184267178502 1889691184267178505 IN IP4 198.51.100.1
s=
c=IN IP4 198.51.100.1
t=0 0
m=audio 31498 RTP/SAVP 0 101
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=direction:both
a=sendrecv
a=rtcp:31499
a=silenceSupp:off - - - -
a=mptime:20 -
a=oldmediaip:10.50.3.218
a=ptime:20
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:zC6Ea9EK/7YmDM79CK+TAnNXTI1pVmZuCMjUPMph
----------------------------------
v=0
o=- 1889691184267178502 1889691184267178505 IN IP4 203.0.113.1
s=
c=IN IP4 203.0.113.1
t=0 0
m=audio PORT RTP/SAVP 0 101
a=direction:both
a=silenceSupp:off - - - -
a=mptime:20 -
a=oldmediaip:10.50.3.218
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=sendrecv
a=rtcp:PORT
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:zC6Ea9EK/7YmDM79CK+TAnNXTI1pVmZuCMjUPMph
a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:CRYPTO128
a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192
a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192
a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256
a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256
a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128
a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128
a=ptime:20
SDP
# SRTP w/ DTMF injection (TT#81600) # SRTP w/ DTMF injection (TT#81600)
($sock_a, $sock_b) = new_call([qw(198.51.100.1 4328)], [qw(198.51.100.3 4330)]); ($sock_a, $sock_b) = new_call([qw(198.51.100.1 4328)], [qw(198.51.100.3 4330)]);


Loading…
Cancel
Save