<p>George Joseph would like Alexander Traud to <strong>review</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/15460">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">rtp:  Enable srtp replay protection<br><br>Add option "srtpreplayprotection" rtp.conf to enable srtp<br>replay protection.<br><br>ASTERISK-29260<br>Reported by: Alexander Traud<br><br>Change-Id: I5cd346e3c6b6812039d1901aa4b7be688173b458<br>---<br>M configs/samples/rtp.conf.sample<br>A doc/CHANGES-staging/srtp_replay_protection.txt<br>A doc/UPGRADE-staging/srtp_replay_protection.txt<br>M res/res_rtp_asterisk.c<br>M res/res_srtp.c<br>5 files changed, 41 insertions(+), 4 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/60/15460/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/configs/samples/rtp.conf.sample b/configs/samples/rtp.conf.sample</span><br><span>index a94707e..c601677 100644</span><br><span>--- a/configs/samples/rtp.conf.sample</span><br><span>+++ b/configs/samples/rtp.conf.sample</span><br><span>@@ -45,6 +45,18 @@</span><br><span> ; connected. This option is set to 4 by default.</span><br><span> ; probation=8</span><br><span> ;</span><br><span style="color: hsl(120, 100%, 40%);">+; Enable sRTP replay protection. Buggy SIP user agents (UAs) reset the</span><br><span style="color: hsl(120, 100%, 40%);">+; sequence number (RTP-SEQ) on a re-INVITE, for example, with Session Timers</span><br><span style="color: hsl(120, 100%, 40%);">+; or on Call Hold/Resume, but keep the synchronization source (RTP-SSRC). If</span><br><span style="color: hsl(120, 100%, 40%);">+; the new RTP-SEQ is higher than the previous one, the call continues if the</span><br><span style="color: hsl(120, 100%, 40%);">+; roll-over counter (sRTP-ROC) is zero (the call lasted less than 22 minutes).</span><br><span style="color: hsl(120, 100%, 40%);">+; In all other cases, the call faces one-way audio or even no audio at all.</span><br><span style="color: hsl(120, 100%, 40%);">+; "replay check failed (index too old)" gets printed continuously. This is a</span><br><span style="color: hsl(120, 100%, 40%);">+; software bug. You have to report this to the creator of that UA. Until it is</span><br><span style="color: hsl(120, 100%, 40%);">+; fixed, you could disable sRTP replay protection (see RFC 3711 section 3.3.2).</span><br><span style="color: hsl(120, 100%, 40%);">+; This option is enabled by default.</span><br><span style="color: hsl(120, 100%, 40%);">+; srtpreplayprotection=yes</span><br><span style="color: hsl(120, 100%, 40%);">+;</span><br><span> ; Whether to enable or disable ICE support. This option is enabled by default.</span><br><span> ; icesupport=false</span><br><span> ;</span><br><span>diff --git a/doc/CHANGES-staging/srtp_replay_protection.txt b/doc/CHANGES-staging/srtp_replay_protection.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..945ddb5</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/srtp_replay_protection.txt</span><br><span>@@ -0,0 +1,9 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: res_srtp</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+SRTP replay protection has been added to res_srtp and</span><br><span style="color: hsl(120, 100%, 40%);">+a new configuration option "srtpreplayprotection" has</span><br><span style="color: hsl(120, 100%, 40%);">+been added to the rtp.conf config file.  For security</span><br><span style="color: hsl(120, 100%, 40%);">+reasons, the default setting is "yes".  Buggy clients</span><br><span style="color: hsl(120, 100%, 40%);">+may not handle this correctly which could result in</span><br><span style="color: hsl(120, 100%, 40%);">+no, or one way, audio and Asterisk error messages like</span><br><span style="color: hsl(120, 100%, 40%);">+"replay check failed".</span><br><span>diff --git a/doc/UPGRADE-staging/srtp_replay_protection.txt b/doc/UPGRADE-staging/srtp_replay_protection.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..945ddb5</span><br><span>--- /dev/null</span><br><span>+++ b/doc/UPGRADE-staging/srtp_replay_protection.txt</span><br><span>@@ -0,0 +1,9 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: res_srtp</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+SRTP replay protection has been added to res_srtp and</span><br><span style="color: hsl(120, 100%, 40%);">+a new configuration option "srtpreplayprotection" has</span><br><span style="color: hsl(120, 100%, 40%);">+been added to the rtp.conf config file.  For security</span><br><span style="color: hsl(120, 100%, 40%);">+reasons, the default setting is "yes".  Buggy clients</span><br><span style="color: hsl(120, 100%, 40%);">+may not handle this correctly which could result in</span><br><span style="color: hsl(120, 100%, 40%);">+no, or one way, audio and Asterisk error messages like</span><br><span style="color: hsl(120, 100%, 40%);">+"replay check failed".</span><br><span>diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c</span><br><span>index 6004a2f..4505e0a 100644</span><br><span>--- a/res/res_rtp_asterisk.c</span><br><span>+++ b/res/res_rtp_asterisk.c</span><br><span>@@ -178,6 +178,7 @@</span><br><span> #define STRICT_RTP_LEARN_TIMEOUT      5000</span><br><span> </span><br><span> #define DEFAULT_STRICT_RTP STRICT_RTP_YES   /*!< Enabled by default */</span><br><span style="color: hsl(120, 100%, 40%);">+#define DEFAULT_SRTP_REPLAY_PROTECTION 1</span><br><span> #define DEFAULT_ICESUPPORT 1</span><br><span> #define DEFAULT_DTLS_MTU 1200</span><br><span> </span><br><span>@@ -202,6 +203,7 @@</span><br><span> static int strictrtp = DEFAULT_STRICT_RTP; /*!< Only accept RTP frames from a defined source. If we receive an indication of a changing source, enter learning mode. */</span><br><span> static int learning_min_sequential = DEFAULT_LEARNING_MIN_SEQUENTIAL; /*!< Number of sequential RTP frames needed from a single source during learning mode to accept new source. */</span><br><span> static int learning_min_duration = DEFAULT_LEARNING_MIN_DURATION; /*!< Lowest acceptable timeout between the first and the last sequential RTP frame. */</span><br><span style="color: hsl(120, 100%, 40%);">+static int srtp_replay_protection = DEFAULT_SRTP_REPLAY_PROTECTION;</span><br><span> #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)</span><br><span> static int dtls_mtu = DEFAULT_DTLS_MTU;</span><br><span> #endif</span><br><span>@@ -5927,7 +5929,7 @@</span><br><span> </span><br><span>     /* If this is encrypted then decrypt the payload */</span><br><span>  if ((*rtcpheader & 0xC0) && res_srtp && srtp && res_srtp->unprotect(</span><br><span style="color: hsl(0, 100%, 40%);">-                 srtp, rtcpheader, &len, 1) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              srtp, rtcpheader, &len, 1 | (srtp_replay_protection << 1)) < 0) {</span><br><span>      return &ast_null_frame;</span><br><span>       }</span><br><span> </span><br><span>@@ -7009,7 +7011,7 @@</span><br><span> </span><br><span>    /* If this payload is encrypted then decrypt it using the given SRTP instance */</span><br><span>     if ((*read_area & 0xC0) && res_srtp && srtp && res_srtp->unprotect(</span><br><span style="color: hsl(0, 100%, 40%);">-                  srtp, read_area, &res, 0) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               srtp, read_area, &res, 0 | (srtp_replay_protection << 1)) < 0) {</span><br><span>            return &ast_null_frame;</span><br><span>  }</span><br><span> </span><br><span>@@ -8919,6 +8921,7 @@</span><br><span>        strictrtp = DEFAULT_STRICT_RTP;</span><br><span>      learning_min_sequential = DEFAULT_LEARNING_MIN_SEQUENTIAL;</span><br><span>   learning_min_duration = DEFAULT_LEARNING_MIN_DURATION;</span><br><span style="color: hsl(120, 100%, 40%);">+        srtp_replay_protection = DEFAULT_SRTP_REPLAY_PROTECTION;</span><br><span> </span><br><span>         /** This resource is not "reloaded" so much as unloaded and loaded again.</span><br><span>   * In the case of the TURN related variables, the memory referenced by a</span><br><span>@@ -9000,6 +9003,9 @@</span><br><span>             }</span><br><span>            learning_min_duration = CALC_LEARNING_MIN_DURATION(learning_min_sequential);</span><br><span>         }</span><br><span style="color: hsl(120, 100%, 40%);">+     if ((s = ast_variable_retrieve(cfg, "general", "srtpreplayprotection"))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                srtp_replay_protection = ast_true(s);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> #ifdef HAVE_PJPROJECT</span><br><span>   if ((s = ast_variable_retrieve(cfg, "general", "icesupport"))) {</span><br><span>                 icesupport = ast_true(s);</span><br><span>diff --git a/res/res_srtp.c b/res/res_srtp.c</span><br><span>index 3e4b51f..7098621 100644</span><br><span>--- a/res/res_srtp.c</span><br><span>+++ b/res/res_srtp.c</span><br><span>@@ -364,11 +364,12 @@</span><br><span> }</span><br><span> </span><br><span> /* Vtable functions */</span><br><span style="color: hsl(0, 100%, 40%);">-static int ast_srtp_unprotect(struct ast_srtp *srtp, void *buf, int *len, int rtcp)</span><br><span style="color: hsl(120, 100%, 40%);">+static int ast_srtp_unprotect(struct ast_srtp *srtp, void *buf, int *len, int flags)</span><br><span> {</span><br><span>      int res = 0;</span><br><span>         int i;</span><br><span style="color: hsl(0, 100%, 40%);">-  int retry = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+        int rtcp  = (flags & 0x01) >> 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    int retry = (flags & 0x02) >> 1;</span><br><span>   struct ast_rtp_instance_stats stats = {0,};</span><br><span> </span><br><span> tryagain:</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/15460">change 15460</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/15460"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: certified/16.8 </div>
<div style="display:none"> Gerrit-Change-Id: I5cd346e3c6b6812039d1901aa4b7be688173b458 </div>
<div style="display:none"> Gerrit-Change-Number: 15460 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Alexander Traud <pabstraud@compuserve.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>