[asterisk-bugs] [JIRA] (ASTERISK-30477) res_srtp: ROC reset bugs

Joshua C. Colp (JIRA) noreply at issues.asterisk.org
Thu Mar 23 14:44:03 CDT 2023


     [ https://issues.asterisk.org/jira/browse/ASTERISK-30477?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Joshua C. Colp updated ASTERISK-30477:
--------------------------------------

    Assignee: Phil Lavin
      Status: Waiting for Feedback  (was: Triage)

Just so you're aware, Asterisk 16 does not receive bug fixes. It is in security fix only status. Any changes will not be applied to it. Asterisk also supports older versions of libsrtp before 2, so any changes that are not backwards compatible would not be accepted.

Changing the SSRC is something that has been done in the past for other purposes, with variable results sometimes causing issues and sometimes not depending on the remote endpoint. I think if that were done it would need to be behind an option in case it breaks existing working SRTP sessions with endpoints.

I don't think there is a "best" option. There's just various options with tradeoffs, but trying the SSRC option may be the best to ensure compatibility across different versions of libsrtp - if it works.

> res_srtp: ROC reset bugs 
> -------------------------
>
>                 Key: ASTERISK-30477
>                 URL: https://issues.asterisk.org/jira/browse/ASTERISK-30477
>             Project: Asterisk
>          Issue Type: Bug
>      Security Level: None
>          Components: Resources/res_srtp
>    Affects Versions: 16.30.0
>         Environment: Debian 11
>            Reporter: Phil Lavin
>            Assignee: Phil Lavin
>
> I think https://issues.asterisk.org/jira/browse/ASTERISK-29519 noticed the issue but didn't describe the root cause correctly or provide useful analysis.
> There are two separate cases where Asterisk resets the rollover counter (ROC) on the SRTP stream it outputs, meaning the stream has invalid auth tags and is rejected by remote parties who verify the SRTP auth tags (e.g. Oracle SBCs).
> The first is here: https://github.com/asterisk/asterisk/blob/16.30/main/rtp_engine.c#L2744
> When using chan_sip (I haven't tested pjsip), ast_rtp_instance_add_srtp_policy() is called when the remote party sends a re-INVITE which re-keys the SRTP stream (see backtrace [1] below). ast_rtp_instance_add_srtp_policy() replaces the libsrtp resource, adding the remote stream at the same time. It then re-adds the local stream. If the local stream's sequence has rolled over by this point, its ROC was 1 however the act of re-creating the libsrtp resource resets it back to 0 and outputs invalid auth tags.
> The second is here:
> https://github.com/asterisk/asterisk/blob/16.30/res/res_srtp.c#L424
> When Asterisk gets back an err_status_replay_old from libsrtp, it resets the libsrtp session and re-adds both remote and local stream. As above, local stream ROC is reset back to 0 at this point. This was initially discovered because the remote SBC (our friends Oracle, again) incorrectly reset the RTCP index on every re-INVITE. This triggers the replay_old error and subsequently triggers Asterisk to reset the stream.
> I have automated tests to replicate both issues. In essence, they make a sip call to Asterisk using sipp, capture the media IP/port and crypto key from the 200 response, start a tcpdump, wait 23 minutes, re-key or send invalid RTCP (depending on which test), hang up the call, run the tcpdump capture through libsrtp rtp_decode and then analyse the auth tags. This issue can be replicated every time, on Asterisk 16.
> I have a working patch for Asterisk 1.8 (don't ask!) which may better help understand what the issue is but isn't entirely applicable to Asterisk 16. It's hacky in such that it uses libsrtp "private" internals to preserve the index across sessions. libsrtp 2.1 added functions to get and set the roc (https://github.com/cisco/libsrtp/pull/289), which makes it cleaner for Asterisk 16. I'm happy to create and test a patch for Asterisk 16 which uses the libsrtp 2.1 functions, if you think this is the right approach.
> Another approach would be to ensure that Asterisk always changes the ssrc of its stream when it resets it and, as such, a ROC value of 0 would be valid. A further approach would be to stop using "wildcard" ssrc for the remote stream in libsrtp and, rather, use an ssrc-specific stream. This means that stream could be replaced without having to replace the whole libsrtp session.
> Happy to take some guidance on the optimal solution then crack on with the patch.
> I'm reasonably sure this bug applies all the way up to Asterisk 20 because the code is the same in the affected areas, though I haven't tested it.
> [1]
> (gdb) bt
> #0  0x00007fe37ecd2b78 in srtp_stream_init () from /lib/libsrtp.so.1
> #1  0x00007fe37ecd4a6b in srtp_add_stream () from /lib/libsrtp.so.1
> #2  0x00007fe37ecf961d in ast_srtp_add_stream (srtp=0x7fe34c07b4a0, policy=0x7fe34c054228) at res_srtp.c:509
> #3  0x0000000000523927 in ast_rtp_instance_add_srtp_policy (instance=0x7fe34c0779b8, remote_policy=0x7fe34c103998, local_policy=0x7fe34c054228) at rtp_engine.c:1843
> #4  0x00007fe37e9f6599 in sdp_crypto_activate (p=0x7fe34c07b260, suite_val=1, remote_key=0x7fe37e281270 "\345Q\020\351|\266s\215\202\334\350\315.\343Q\351ad\217\f\303\070\260\340\247>\265m\364\004", rtp=0x7fe34c0779b8) at sip/sdp_crypto.c:172
> #5  0x00007fe37e9f6baa in sdp_crypto_process (p=0x7fe34c07b260, attr=0x7fe34c2f427b "crypto:1 AES_CM_128_HMAC_SHA1_80 inline:5VEQ6Xy2c42C3OjNLuNR6WFkjwzDOLDgpz61bfQE", rtp=0x7fe34c0779b8) at sip/sdp_crypto.c:278
> #6  0x00007fe37e9f26d1 in process_crypto (p=0x7fe34c075308, rtp=0x7fe34c0779b8, srtp=0x7fe34c0767b0, a=0x7fe34c2f427b "crypto:1 AES_CM_128_HMAC_SHA1_80 inline:5VEQ6Xy2c42C3OjNLuNR6WFkjwzDOLDgpz61bfQE") at chan_sip.c:30593
> #7  0x00007fe37e988062 in process_sdp (p=0x7fe34c075308, req=0x7fe37e286330, t38action=1) at chan_sip.c:9454
> #8  0x00007fe37e9cd418 in handle_request_invite (p=0x7fe34c075308, req=0x7fe37e286330, debug=0, seqno=11, addr=0x7fe37e2862a0, recount=0x7fe37e28624c, e=0x7fe34c2f3e6f "sip:15555551234 at 172.19.149.244:5060", nounlock=0x7fe37e286248) at chan_sip.c:23478
> #9  0x00007fe37e9d7f60 in handle_incoming (p=0x7fe34c075308, req=0x7fe37e286330, addr=0x7fe37e2862a0, recount=0x7fe37e28624c, nounlock=0x7fe37e286248) at chan_sip.c:26032
> #10 0x00007fe37e9d8984 in handle_request_do (req=0x7fe37e286330, addr=0x7fe37e2862a0) at chan_sip.c:26218
> #11 0x00007fe37e9d8599 in sipsock_read (id=0x2a75360, fd=10, events=1, ignore=0x0) at chan_sip.c:26151
> #12 0x00000000004da609 in ast_io_wait (ioc=0x2a60fb0, howlong=649) at io.c:292
> #13 0x00007fe37e9da2d4 in do_monitor (data=0x0) at chan_sip.c:26704
> #14 0x000000000055e8d2 in dummy_start (data=0x2a75360) at utils.c:1173
> #15 0x00007fe382068fa3 in start_thread (arg=<optimized out>) at pthread_create.c:486
> #16 0x00007fe38232b06f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95



--
This message was sent by Atlassian JIRA
(v6.2#6252)



More information about the asterisk-bugs mailing list