From 0ad968df367f5a44c568329834115018866ff8b9 Mon Sep 17 00:00:00 2001 From: fiaxh Date: Fri, 30 Apr 2021 21:37:02 +0200 Subject: Use the same DTLS fingerprint in all contents. Display audio+video enc keys in UI if they differ. --- plugins/ice/src/dtls_srtp.vala | 35 ++++++++++++++++++++----------- plugins/ice/src/module.vala | 17 +++++++++++++-- plugins/ice/src/transport_parameters.vala | 8 +++---- 3 files changed, 42 insertions(+), 18 deletions(-) (limited to 'plugins') diff --git a/plugins/ice/src/dtls_srtp.vala b/plugins/ice/src/dtls_srtp.vala index f5ef830a..0254351d 100644 --- a/plugins/ice/src/dtls_srtp.vala +++ b/plugins/ice/src/dtls_srtp.vala @@ -2,10 +2,10 @@ using GnuTLS; namespace Dino.Plugins.Ice.DtlsSrtp { -public static Handler setup() throws GLib.Error { - var obj = new Handler(); - obj.generate_credentials(); - return obj; +public class CredentialsCapsule { + public uint8[] own_fingerprint; + public X509.Certificate[] own_cert; + public X509.PrivateKey private_key; } public class Handler { @@ -21,8 +21,7 @@ public class Handler { public uint8[] peer_fingerprint { get; set; } public string peer_fp_algo { get; set; } - private X509.Certificate[] own_cert; - private X509.PrivateKey private_key; + private CredentialsCapsule credentials; private Cond buffer_cond = Cond(); private Mutex buffer_mutex = Mutex(); private Gee.LinkedList buffer_queue = new Gee.LinkedList(); @@ -33,6 +32,11 @@ public class Handler { private Crypto.Srtp.Session srtp_session = new Crypto.Srtp.Session(); + public Handler.with_cert(CredentialsCapsule creds) { + this.credentials = creds; + this.own_fingerprint = creds.own_fingerprint; + } + public uint8[]? process_incoming_data(uint component_id, uint8[] data) { if (srtp_session.has_decrypt) { try { @@ -78,10 +82,10 @@ public class Handler { buffer_mutex.unlock(); } - internal void generate_credentials() throws GLib.Error { + internal static CredentialsCapsule generate_credentials() throws GLib.Error { int err = 0; - private_key = X509.PrivateKey.create(); + X509.PrivateKey private_key = X509.PrivateKey.create(); err = private_key.generate(PKAlgorithm.RSA, 2048); throw_if_error(err); @@ -99,8 +103,15 @@ public class Handler { cert.sign(cert, private_key); - own_fingerprint = get_fingerprint(cert, DigestAlgorithm.SHA256); - own_cert = new X509.Certificate[] { (owned)cert }; + uint8[] own_fingerprint = get_fingerprint(cert, DigestAlgorithm.SHA256); + X509.Certificate[] own_cert = new X509.Certificate[] { (owned)cert }; + + var creds = new CredentialsCapsule(); + creds.own_fingerprint = own_fingerprint; + creds.own_cert = (owned) own_cert; + creds.private_key = (owned) private_key; + + return creds; } public void stop_dtls_connection() { @@ -129,7 +140,7 @@ public class Handler { debug("Setting up DTLS connection. We're %s", mode.to_string()); CertificateCredentials cert_cred = CertificateCredentials.create(); - int err = cert_cred.set_x509_key(own_cert, private_key); + int err = cert_cred.set_x509_key(credentials.own_cert, credentials.private_key); throw_if_error(err); Session? session = Session.create(server_or_client | InitFlags.DATAGRAM); @@ -200,7 +211,7 @@ public class Handler { srtp_session.set_encryption_key(Crypto.Srtp.AES_CM_128_HMAC_SHA1_80, client_key.extract(), client_salt.extract()); srtp_session.set_decryption_key(Crypto.Srtp.AES_CM_128_HMAC_SHA1_80, server_key.extract(), server_salt.extract()); } - return new Xmpp.Xep.Jingle.ContentEncryption() { encryption_ns=Xmpp.Xep.JingleIceUdp.DTLS_NS_URI, encryption_name = "DTLS-SRTP", our_key=own_fingerprint, peer_key=peer_fingerprint }; + return new Xmpp.Xep.Jingle.ContentEncryption() { encryption_ns=Xmpp.Xep.JingleIceUdp.DTLS_NS_URI, encryption_name = "DTLS-SRTP", our_key=credentials.own_fingerprint, peer_key=peer_fingerprint }; } private static ssize_t pull_function(void* transport_ptr, uint8[] buffer) { diff --git a/plugins/ice/src/module.vala b/plugins/ice/src/module.vala index e961ffb6..2645d7dc 100644 --- a/plugins/ice/src/module.vala +++ b/plugins/ice/src/module.vala @@ -10,6 +10,7 @@ public class Dino.Plugins.Ice.Module : JingleIceUdp.Module { public Xep.ExternalServiceDiscovery.Service? turn_service = null; private weak Nice.Agent? agent; + private HashMap cerds = new HashMap(); private Nice.Agent get_agent() { Nice.Agent? agent = this.agent; @@ -29,11 +30,23 @@ public class Dino.Plugins.Ice.Module : JingleIceUdp.Module { } public override Jingle.TransportParameters create_transport_parameters(XmppStream stream, uint8 components, Jid local_full_jid, Jid peer_full_jid) { - return new TransportParameters(get_agent(), turn_service, turn_ip, components, local_full_jid, peer_full_jid); + DtlsSrtp.CredentialsCapsule? cred = get_create_credentials(local_full_jid, peer_full_jid); + return new TransportParameters(get_agent(), cred, turn_service, turn_ip, components, local_full_jid, peer_full_jid); } public override Jingle.TransportParameters parse_transport_parameters(XmppStream stream, uint8 components, Jid local_full_jid, Jid peer_full_jid, StanzaNode transport) throws Jingle.IqError { - return new TransportParameters(get_agent(), turn_service, turn_ip, components, local_full_jid, peer_full_jid, transport); + DtlsSrtp.CredentialsCapsule? cred = get_create_credentials(local_full_jid, peer_full_jid); + return new TransportParameters(get_agent(), cred, turn_service, turn_ip, components, local_full_jid, peer_full_jid, transport); + } + + private DtlsSrtp.CredentialsCapsule? get_create_credentials(Jid local_full_jid, Jid peer_full_jid) { + string from_to_id = local_full_jid.to_string() + peer_full_jid.to_string(); + try { + if (!cerds.has_key(from_to_id)) cerds[from_to_id] = DtlsSrtp.Handler.generate_credentials(); + } catch (Error e) { + warning("Error creating dtls credentials: %s", e.message); + } + return cerds[from_to_id]; } private void agent_unweak() { diff --git a/plugins/ice/src/transport_parameters.vala b/plugins/ice/src/transport_parameters.vala index 38652952..62c04906 100644 --- a/plugins/ice/src/transport_parameters.vala +++ b/plugins/ice/src/transport_parameters.vala @@ -60,13 +60,13 @@ public class Dino.Plugins.Ice.TransportParameters : JingleIceUdp.IceUdpTransport } } - public TransportParameters(Nice.Agent agent, Xep.ExternalServiceDiscovery.Service? turn_service, string? turn_ip, uint8 components, Jid local_full_jid, Jid peer_full_jid, StanzaNode? node = null) { + public TransportParameters(Nice.Agent agent, DtlsSrtp.CredentialsCapsule? credentials, Xep.ExternalServiceDiscovery.Service? turn_service, string? turn_ip, uint8 components, Jid local_full_jid, Jid peer_full_jid, StanzaNode? node = null) { base(components, local_full_jid, peer_full_jid, node); this.we_want_connection = (node == null); this.agent = agent; if (this.peer_fingerprint != null || !incoming) { - dtls_srtp_handler = setup_dtls(this); + dtls_srtp_handler = setup_dtls(this, credentials); own_fingerprint = dtls_srtp_handler.own_fingerprint; if (incoming) { own_setup = "active"; @@ -113,9 +113,9 @@ public class Dino.Plugins.Ice.TransportParameters : JingleIceUdp.IceUdpTransport agent.gather_candidates(stream_id); } - private static DtlsSrtp.Handler setup_dtls(TransportParameters tp) { + private static DtlsSrtp.Handler setup_dtls(TransportParameters tp, DtlsSrtp.CredentialsCapsule credentials) { var weak_self = WeakRef(tp); - DtlsSrtp.Handler dtls_srtp = DtlsSrtp.setup(); + DtlsSrtp.Handler dtls_srtp = new DtlsSrtp.Handler.with_cert(credentials); dtls_srtp.send_data.connect((data) => { TransportParameters self = (TransportParameters) weak_self.get(); if (self != null) self.agent.send(self.stream_id, 1, data); -- cgit v1.2.3-54-g00ecf