diff --git a/daemon/call.c b/daemon/call.c index ab3d86d04..9d2e5cb9b 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -2917,6 +2917,12 @@ static void __media_init_from_flags(struct call_media *other_media, struct call_ other_media->bandwidth_as = sp->media_session_as; other_media->bandwidth_rr = sp->media_session_rr; other_media->bandwidth_rs = sp->media_session_rs; + + if (flags->recrypt) { + MEDIA_SET(other_media, RECRYPT); + if (media) + MEDIA_SET(media, RECRYPT); + } } unsigned int proto_num_ports(unsigned int sp_ports, struct call_media *media, sdp_ng_flags *flags, diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 5a64a74e8..4056a3ea0 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -1155,6 +1155,9 @@ void call_ng_flags_flags(sdp_ng_flags *out, str *s, helper_arg dummy) { case CSH_LOOKUP("recording-announcement"): out->recording_announcement = 1; break; + case CSH_LOOKUP("recrypt"): + out->recrypt = true; + break; case CSH_LOOKUP("reorder-codecs"): ilog(LOG_INFO, "Ignoring obsolete flag `reorder-codecs`"); break; diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 518500ff0..e6d757ebb 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1936,7 +1936,7 @@ static const struct streamhandler *__determine_handler(struct packet_stream *in, must_recrypt = true; else if (dtmf_do_logging(in->call, false)) must_recrypt = true; - else if (MEDIA_ISSET(in->media, DTLS) || (out && MEDIA_ISSET(out->media, DTLS))) + else if (MEDIA_ISSET2(in->media, DTLS, RECRYPT) || (out && MEDIA_ISSET2(out->media, DTLS, RECRYPT))) must_recrypt = true; else if (ML_ISSET(in->media->monologue, INJECT_DTMF) || (out && ML_ISSET(out->media->monologue, INJECT_DTMF))) must_recrypt = true; diff --git a/docs/ng_control_protocol.md b/docs/ng_control_protocol.md index c7910e01f..a59c4982e 100644 --- a/docs/ng_control_protocol.md +++ b/docs/ng_control_protocol.md @@ -1067,6 +1067,27 @@ Spaces in each string may be replaced by hyphens. flag must be set for all call parties which are meant to hear the announcement. +* `recrypt` + + If set, forces decryption and re-encryption of all SRTP, even if + passthrough is possible. + + Without this flag set, in situations where SRTP is in use on both sides of + a call, and if the SRTP keys are the same on both sides (commonly the case + with SDES), and if no other media manipulations are required, *rtpengine* + would simply pass through all media packets directly, without getting + involved in the encryption. This saves CPU time as there's no point in + decypting each packet, only to encrypt it again using the same SRTP key. + The side effect is that even non-SRTP packets, as well as SRTP packets with + an invalid encryption, are passed through, as no verification of the SRTP + encryption takes place. This can have security implications, as then any + and all media packets are considered for endpoint learning purposes, + regardless of whether they have an intact SRTP authentication tag. + + Setting this flag forces decryption and re-encryption of all SRTP packets, + validating the authentication tag in the process, and discarding packets + without a valid tag. + * `reject ICE` Useful for `offer` messages that advertise support for ICE. diff --git a/include/call.h b/include/call.h index 2b40edf9f..a100a9722 100644 --- a/include/call.h +++ b/include/call.h @@ -233,6 +233,7 @@ enum { #define MEDIA_FLAG_LEGACY_OSRTP_REV SHARED_FLAG_LEGACY_OSRTP_REV #define MEDIA_FLAG_TRANSCODING 0x100000000LL #define MEDIA_FLAG_BLOCK_EGRESS 0x200000000LL +#define MEDIA_FLAG_RECRYPT (1LL << 37) /* struct call_monologue */ #define ML_FLAG_REC_FORWARDING 0x00010000 diff --git a/include/call_interfaces.h b/include/call_interfaces.h index 22ff824cf..90a53aa69 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -228,6 +228,7 @@ struct sdp_ng_flags { sdes_static:1, sdes_nonew:1, sdes_prefer:1, + recrypt:1, drop_traffic_start:1, drop_traffic_stop:1, passthrough_on:1,