From b393d4160182873ea2acd9fbc6421f7e1a3adb9e Mon Sep 17 00:00:00 2001 From: Marvin W Date: Tue, 23 Mar 2021 15:05:50 +0100 Subject: Add support for SRTP --- .../xep/0167_jingle_rtp/content_parameters.vala | 46 ++++++++++++++++++++-- 1 file changed, 42 insertions(+), 4 deletions(-) (limited to 'xmpp-vala/src/module/xep/0167_jingle_rtp/content_parameters.vala') diff --git a/xmpp-vala/src/module/xep/0167_jingle_rtp/content_parameters.vala b/xmpp-vala/src/module/xep/0167_jingle_rtp/content_parameters.vala index 8a3668b2..cca03543 100644 --- a/xmpp-vala/src/module/xep/0167_jingle_rtp/content_parameters.vala +++ b/xmpp-vala/src/module/xep/0167_jingle_rtp/content_parameters.vala @@ -17,7 +17,9 @@ public class Xmpp.Xep.JingleRtp.Parameters : Jingle.ContentParameters, Object { public bool encryption_required { get; private set; default = false; } public PayloadType? agreed_payload_type { get; private set; } public Gee.List payload_types = new ArrayList(PayloadType.equals_func); - public Gee.List cryptos = new ArrayList(); + public Gee.List remote_cryptos = new ArrayList(); + public Crypto? local_crypto = null; + public Crypto? remote_crypto = null; public weak Stream? stream { get; private set; } @@ -27,7 +29,7 @@ public class Xmpp.Xep.JingleRtp.Parameters : Jingle.ContentParameters, Object { string media, Gee.List payload_types, string? ssrc = null, bool rtcp_mux = false, string? bandwidth = null, string? bandwidth_type = null, - bool encryption_required = false, Gee.List cryptos = new ArrayList() + bool encryption_required = false, Crypto? local_crypto = null ) { this.parent = parent; this.media = media; @@ -37,7 +39,7 @@ public class Xmpp.Xep.JingleRtp.Parameters : Jingle.ContentParameters, Object { this.bandwidth_type = bandwidth_type; this.encryption_required = encryption_required; this.payload_types = payload_types; - this.cryptos = cryptos; + this.local_crypto = local_crypto; } public Parameters.from_node(Module parent, StanzaNode node) throws Jingle.IqError { @@ -49,7 +51,7 @@ public class Xmpp.Xep.JingleRtp.Parameters : Jingle.ContentParameters, Object { if (encryption != null) { this.encryption_required = encryption.get_attribute_bool("required", this.encryption_required); foreach (StanzaNode crypto in encryption.get_subnodes("crypto")) { - this.cryptos.add(Crypto.parse(crypto)); + this.remote_cryptos.add(Crypto.parse(crypto)); } } foreach (StanzaNode payloadType in node.get_subnodes("payload-type")) { @@ -64,6 +66,15 @@ public class Xmpp.Xep.JingleRtp.Parameters : Jingle.ContentParameters, Object { content.reject(); return; } + remote_crypto = parent.pick_remote_crypto(remote_cryptos); + if (local_crypto == null && remote_crypto != null) { + local_crypto = parent.pick_local_crypto(remote_crypto); + } + if ((local_crypto == null || remote_crypto == null) && encryption_required) { + debug("no usable encryption, but encryption required"); + content.reject(); + return; + } } public void accept(XmppStream stream, Jingle.Session session, Jingle.Content content) { @@ -97,6 +108,15 @@ public class Xmpp.Xep.JingleRtp.Parameters : Jingle.ContentParameters, Object { } }); + if (remote_crypto == null || local_crypto == null) { + if (encryption_required) { + warning("Encryption required but not provided in both directions"); + return; + } + remote_crypto = null; + local_crypto = null; + } + this.stream = parent.create_stream(content); rtp_datagram.datagram_received.connect(this.stream.on_recv_rtp_data); rtcp_datagram.datagram_received.connect(this.stream.on_recv_rtcp_data); @@ -118,6 +138,20 @@ public class Xmpp.Xep.JingleRtp.Parameters : Jingle.ContentParameters, Object { } agreed_payload_type = preferred_payload_type; + Gee.List crypto_nodes = description_node.get_deep_subnodes("encryption", "crypto"); + if (crypto_nodes.size == 0) { + warning("Counterpart didn't include any cryptos"); + if (encryption_required) { + return; + } + } else { + Crypto preferred_crypto = Crypto.parse(crypto_nodes[0]); + if (local_crypto.crypto_suite != preferred_crypto.crypto_suite) { + warning("Counterpart's crypto suite doesn't match any of our sent ones"); + } + remote_crypto = preferred_crypto; + } + accept(stream, session, content); } @@ -137,6 +171,10 @@ public class Xmpp.Xep.JingleRtp.Parameters : Jingle.ContentParameters, Object { ret.put_node(payload_type.to_xml()); } } + if (local_crypto != null) { + ret.put_node(new StanzaNode.build("encryption", NS_URI) + .put_node(local_crypto.to_xml())); + } return ret; } } \ No newline at end of file -- cgit v1.2.3-70-g09d2