`UseSRTP` Extension
ShadowJonathan opened this issue · 5 comments
Implement the use_srtp
extension as per RFC 5764
For this we also need a usable SRTP library, i'll probably also put this behind an optional crate feature strp
(or ext-srtp
, depending on what naming convention i'll settle on)
I'm currently looking at two, but i'm not sure which one i could work with;
- HyeonuPark/srtp (
srtp
), seems a bit unmaintained - webrtc-rs/srtp (
webrtc_srtp
), seems very fused to their DTLS crate as well.
I guess dtls-rs only needs to include the use_srtp related functionality in the key exchange. Either by having a fixed set of supported extensions or a dynamic way to add those extensions (which might be harder).
After that the normal key exporters (RFC5705) (rustls seems to support this I think) can be used to do the rest independent from the used srtp crate (See 4.2). It would be part of the SRTP crate to derive its key based on the extracted DTLS master key and salt. Or dtls-rs could offer a SRTP KDF per spec.
Huh, it does look like that this is basically hijacking a DTLS handshake, and then extracting the resultant secrets/master key to pass onto its own stack.
I'm a bit unsure on how to handle the resultant parts from the handshake then, I have a feeling that it should just output a normal DTLSClientConnection
, which is then used to signal alerts and process data over a same connection (which could be used as a sort of data channel).
I think in the case of SRTP multiplexing, the application should define its own router, as per the following forwarding diagram;
+----------------+
| 127 < B < 192 -+--> forward to RTP
| |
packet --> | 19 < B < 64 -+--> forward to DTLS
| |
| B < 2 -+--> forward to STUN
+----------------+
If SRTP provides its own lifetime signalling, it may even be possible to drop the ClientConnection
object after creation, or only be used to extract the required SRTP parameters. This would transform DTLS effectively into a bootstrapping platform, which ends after it successfully obtains secrets.
I'll have to give a closer look at the RFC before I give my full thoughts on the matter though, but so far it seems forseeable.
Furthermore for this, i'd need to expose the rustls export_keying_material
function on D*Connection
, which is something i was going to come across anyways.
The only thing left then would be how I'll expose the extension, I'm thinking to allow either raw u16
vecs and SrtpProtectionProfile
profile vecs as inputs to the extension, so that the library may provide (defined) defaults, but that a consuming library isn't necessarily dependent on it.
Though I'm inclined to just go with u16
s for the moment though, I'm not 100% sure about namespacing protection profile enums for SRTP in the library necessarily, that is something that could be in a "batteries-included" module.
Edit: Yeah, i'll probably do something along the lines of;
impl UseSRTPExtension {
pub fn new<P: Into<u16>>(profiles: Vec<P>, mki: Option<Vec<u8>>) -> Self {}
}
So far, SRTP basically piggybacks off of 3 points in a DTLS connection;
- Extension inputs to handshake (profiles, MKI)
- Server callback/checking to process the UseSRTP extensions
- Keying material export off of the finished connections
The rest (in-band SRTP packets) is solved with #15, because while the SRTP stream may use the same socket, it is thereafter not related to the DTLS connection. (Unless I'm missing something wrt lifecycle management)
There is an update regarding the SRTP DeMux: rfc7983