<p>George Joseph <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/15457">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  George Joseph: Looks good to me, approved; Approved for Submit
  Friendly Automation: Verified

</div><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, 43 insertions(+), 4 deletions(-)<br><br></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 f002449..7ab81b3 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 29ffffc..ad9cb7d 100644</span><br><span>--- a/res/res_rtp_asterisk.c</span><br><span>+++ b/res/res_rtp_asterisk.c</span><br><span>@@ -181,6 +181,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>@@ -203,6 +204,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>@@ -6082,7 +6084,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>@@ -7170,7 +7172,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>@@ -8958,6 +8960,8 @@</span><br><span>        if (strictrtp) {</span><br><span>             ast_cli(a->fd, "  Probation:       %d frames\n", learning_min_sequential);</span><br><span>      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_cli(a->fd, "  Replay Protect:  %s\n", AST_CLI_YESNO(srtp_replay_protection));</span><br><span> #ifdef HAVE_PJPROJECT</span><br><span>      ast_cli(a->fd, "  ICE support:     %s\n", AST_CLI_YESNO(icesupport));</span><br><span> #endif</span><br><span>@@ -9060,6 +9064,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>@@ -9139,6 +9144,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 7874216..3519def 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/+/15457">change 15457</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/+/15457"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16 </div>
<div style="display:none"> Gerrit-Change-Id: I5cd346e3c6b6812039d1901aa4b7be688173b458 </div>
<div style="display:none"> Gerrit-Change-Number: 15457 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </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-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>