cisco / libsrtp

Library for SRTP (Secure Realtime Transport Protocol)
Other
1.19k stars 472 forks source link

Late join: use external ROC when unprotecting a stream with ssrc type set to "ssrc_any_inbound" + mki #608

Closed pbodilis closed 1 year ago

pbodilis commented 2 years ago

scenario: policy's are described with ssrc type to ssrc_any_outbound for sender, ssrc_any_inbound for receivers A (sender) and B (receiver) are in an srtp session A sends so much data its ROC increments (that's ~22 minutes of talk with ptime = 20) B receives data, and is in sync with A => no problem, its own ROC increments with A's C (receiver) joins after 22 min, and out of sync with A, can't unprotect anything.

We could live with a workaround, call srtp_add_stream with ssrc type set to specific and value taken from RTP packet when receiving unknown stream, but this seems less straightforward than giving directly the roc.

paulej commented 1 year ago

Seems like calling a function to add a stream and/or calling srtp_set_stream_roc() would be good options here. While not a flaw, having to know the SSRC is a bit of a pain. People do it, but why not re-key the conference and start anew with the ROC==0?

EKT is a good choice for that, though EKT doesn't presently support sending keys via RTCP. It would be a nice addition, though. In any case, EKT addresses this late-joiner issue very well.

pbodilis commented 1 year ago

libsrtp doesn't seem to support ekt at the moment, does it? rekeying in this case doesn't cut it for me, as rekeying in large PTT groups (>7000) would generate way too much traffic. I thought of using srtp_add_stream/srtp_set_stream_roc, but this seems hack-ish at best :/

pabuhler commented 1 year ago

I do not like adding more srtp_unprotect_roc_mki type functions, especially when the ROC param only has meaning at exactly one point in time for one specific SSRC. You would need to pre check every packet to pass the correct ROC so passing it all the time is hackish in my eyes.

The ROC and the SSRC are tightly coupled so if knowing the ROC is an integral part of your solution (ie it is signaled explicitly some how) then you will always also have to know the SSRC upfront. In that case either you use the srtp_add_stream/srtp_set_stream_roc that is there today with ssrc_specific or if you have a lot of SSRC's with the same keys and you feel the need to use ssrc_any_inbound then I guess it is possible to find a way to use srtp_add_stream or a similar function to pre allocate space for a specific SSRC and then use srtp_set_stream_roc to prime it. Either way needing to join a ongoing session with a predetermined ROC requires explicit SSRC management.

paulej commented 1 year ago

libsrtp doesn't seem to support ekt at the moment, does it? rekeying in this case doesn't cut it for me, as rekeying in large PTT groups (>7000) would generate way too much traffic. I thought of using srtp_add_stream/srtp_set_stream_roc, but this seems hack-ish at best :/

It doesn't, nor does it really need to. I implemented EKT recently and my code manages the SRTP context as a part of that. Except for the RTCP limitation, it worked well. It would be nice if we modified EKT to (again) support RTCP to send keys. I forget why that was removed, but it wasn't a showstopper in my use case. It might be for others, though.

pbodilis commented 1 year ago

Alright then, I guess I'll have to live with it :)