Last week, I had the honor to represent the OpenSIPS project in a multi-day, cross-project SIP testing event that took place online, called OpenSIPIt! With a pilot edition of the event dubbed “OpenSIPIt#00” having already taken place last year, right after the OpenSIPS Summit, everyone had much better expectations for why they were gathered here and what they wanted to get out of it.
Moderated by an energetic Maksym Sobolyev (founder of the event), a cheerful David Duffet and yours truly (Liviu Chircu), the event brought together talented open-source developers from a variety of projects:
- George Joseph and Ben Ford (Asterisk project and Sangoma)
- Sandro Gauci and Alfred Farrugia (Enable Security, a.k.a. “makers of sipvicious”)
- Mike Jerris, Chris Rienzo, Dragoș Oancea and Andrew Volk (FreeSWITCH project and Signalwire)
- Andreas Granig (Kamailio project and SIPFront)
- myself and Bogdan-Andrei Iancu (OpenSIPS project and OpenSIPS Solutions)
- Giovanni Maruzzelli (OpenTelecom.IT, a.k.a. “maker of SaraPhone”)
- Maksym Sobolyev, Pavel Bussel and Andriy Pylypenko (Sippy Software)
A solid line-up, with good all-around open-source project representation. Below is an assessment of each day from our project’s perspective, along with some final conclusions.
Day 1 – Digesting RFC 8760
The main topic of Day 1 was RFC 8760. In short, it is an extension to the main SIP specification (RFC 3261) which aims to improve the security of the underlying digest authentication mechanism (the same as HTTP digest auth). When the original specs were written, MD5 was considered to be a strong digest algorithm. Fast forward 20 years later and MD5 has become quite susceptible to brute-force attacks, rainbow table lookups, you name it: its 128-bit signature is simply too weak! The signature length is the first thing that the newer SHA-256 and SHA-512/256 signatures improve upon: they double its size, to 256 bits. Should be enough to last us at least 20 more years, right?
The new digest authentication algorithms should be backwards-compatible with existing (legacy) SIP implementations. That was one of the objectives of the testing session. The other one, of course, was to see whether the RFC 8760 implementations of different teams would interoperate with each other. For completeness’ sake, here is what the new challenge headers look like:
All in all, the testing for the new RFC 8760 code in the upcoming OpenSIPS 3.2 LTS went quite smoothly, except for one minor implementation error which got fixed live, as the testing was taking place. Ultimately, OpenSIPS played well with FreeSWITCH (both UAC and UAS), Sippy Go-B2BUA (both UAC and UAS) and SipVicious (UAC only), as all involved teams found the correct fine-tunings (bugfixes? 🙂 ) for their setups.
We would like to give a big shout-out to Maksym Sobolyev for developing and contributing the RFC 8760 implementation in the upcoming OpenSIPS 3.2! Thank you!
Day 2 – Stir, Shake and Bake!
For Day 2, the topic at hand was STIR/SHAKEN, which is a framework designed to minimize the impact of robocalling. By leveraging the STIR/SHAKEN framework, service providers can add a digital signature to each call using public/private key cryptography, thus attesting whether or not they own the source number (calling identity). This signature comes in the form of the newly introduced SIP Identity header (a.k.a. “a big, problematic wall of gibberish data”). Once all originating service providers enable STIR/SHAKEN in their networks, terminating providers will have a lot more control both over which calls they should pass through or not, as well as which provider to trace a call back to once the proverbial remnant hits the ventilator.
However fun it may be to pronounce, STIR/SHAKEN is by no means an easy spec to get right from the get-go, from an interoperability point of view. That’s because it is comprised of handfuls of documents from differing organizations (i.e. IETF and ATIS), each with their unique style of writing unambiguous SIP specifications. Let’s take a look at the major types of issues we discovered during the interop tests:
Establishing the CLI and CLD
While RFC 8224 clearly describes the syntax of a PASSporT payload’s “orig” (originator number) and “dest” (destination number) claims, not the same can be said about an algorithm of extracting the same information (Calling Line Identity and Calling Line Destination) from a SIP message. Some example questions:
- when extracting the CLI, should the display name, if present, take precedence over the URI username, for either of the P-Asserted-Identity or From SIP headers?
- when extracting the CLD, which of the display name or username of the To SIP header or username of the Request-URI takes precedence?
The general consensus what that the answers to the above questions will most likely boil down to service provider policies or interconnect agreements, and that imposing a specific methodology is likely going to produce more bad than good.
The SIP Date Header Field
An easy step to overlook in your STIR/SHAKEN implementation, the addition of the Date header field is a mandatory requirement, per RFC 8224 § 6.1. Additionally, make sure to use the RFC-provided formatting of the header’s date content, otherwise you may again run into interoperability issues. Example correct formatting: “Date: Wed, 14 Apr 2021 13:17:35 GMT”.
Base64URL Encoding, not Base64!
There is definitely a hidden “gotcha!” here, as RFC 8224 speaks about “base64 encoding” of the PASSporT’s components, while RFC 8225 (the PASSporT specification) describes a “base64url encoding” of them. And while the difference between base64() and base64url() is small (just 2 / 64 characters), it is more than enough to break the interop with another implementation.
STIR/SHAKEN Interop Status
After having gone through all of the above quirks with the various STIR/SHAKEN teams on day 2, OpenSIPS 3.2 successfully passed the interop test with all participating teams, i.e. FreeSWITCH (VS side, based on Signalwire’s libstirshaken), Kamailio (both AS and VS, based on libstirshaken), Sippy Go-B2BUA (both AS and VS), sipp (SIPFront as AS, based on libstirshaken) and sipvicious (AS side)!
Congratulations to all teams for the successful result and hats off to Vlad Pătrașcu for his accurate, down-to-the-word implementation of the STIR/SHAKEN specs in the stir_shaken OpenSIPS module!
Day 3 – When things get fuzzy…
The highlight of the final day of the event was definitely the work of Alfred and Sandro. They had prepared, in advance, a set of STIR/SHAKEN tests with malicious input (bad JSONs, bad URLs, etc.), as well as a pure fuzzing stress-test tool for both RFC 8760 and STIR/SHAKEN SIP headers:
On the OpenSIPS side, the RFC 8760 implementation was crystal clear, no crashes at all! Well done, Max!
For the OpenSIPS stir_shaken module, each of the tests caused a crash, both of which were fixed relatively shortly (see commits #1 and #2). Once the fixes were in place, all testing passed without any further incidents. We are extremely pleased with the result! Thank you again Sandro and Alfred for making OpenSIPS better!
All other teams reportedly managed to squash some bugs as well during day 3, cementing a significant contribution to the event by Enable Security.
For the OpenSIPS project, the OpenSIPIt’01 testing event was a big success, as we managed to both offer help, receive help as well as have loads of fun while doing so! For anyone implementing new SIP specifications, OpenSIPIt is the place to test them out with fellow developers, all from the comfort of your own home.
Thank you all! And thanks again, Max!