Robocalling, or the automated generation of calls - combined with spoofed caller ids (calling party numbers) - is illegal in most of the countries, but is still rising especially in the US.

STIR (Secure Telephony Identity Revisited) and SHAKEN (Secure Handling of Asserted information using toKENs) are the standardized frameworks to fight these illegally spoofed calls.

Sipfront supports this initiative by contributing an implementation to support STIR/SHAKEN in SIPp, the widely popular VoIP tester. This will allow vendors and operators around the world to easily verify and benchmark their STIR/SHAKEN implementation.

How STIR/SHAKEN works

STIR/SHAKEN utilizes JWT (JSON Web Tokens), which is based on public key cryptography, to verify the validity of caller ids. This is done between Telco operators, where the originating side accepts a call from a customer, validates the provided calling and called party numbers, and signs them cryptographically before sending the call to the next hop.

On the terminating side, a Telco operator can validate the numbers by verifying the cryptographic signature to ensure the validity of the caller id.

STIR/SHAKEN in SIP

The originating Telco operator takes an incoming INVITE from a customer, authenticates and authorizes the call, and validates and potentially modifies the caller id in the From and/or P-Preferred-Identity or P-Asserted-Identity headers before forwarding the call to the next hop.

INVITE sip:bob@other.example.com SIP/2.0
From: "+12345" <sip:alice@our.example.com>;tag=19
To: "+54321" <sip:bob@other.example.com>

By using the information of the From and To Display-Name fields and interpreting them as phone numbers, the originating Telco creates a so-called JSON Passport.

{
    "alg": "ES256",
    "ppt": "shaken",
    "typ": "passport",
    "x5u": "https://our.example.com/public.pem"
}
{
    "attest": "B",
    "dest": {
        "tn": [
            "+54321"
        ]
    },
    "iat": 1617996364,
    "orig": {
        "tn": "+12345"
    },
    "origid": "79da65cc-5ce6-4605-91be-f3ca20ab619e"
}

These two JSON objects contain a link to the own public certificate (x5u) for verification, as well as the attestation type (A for full attestation of having authenticated and authorized the use of the caller ids, B for partial attestation of having authenticated the user, but not verified the authorization to use the caller ids, or C for gateway attestation having authenticated where it received the call from, but not being able to to authenticate the actual calling party) and the origination and destination number, and the current time stamp (iat). This information is encoded into a JWT and packed into the SIP Identity header and sent to the next hop.

INVITE sip:bob@other.example.com SIP/2.0
From: "+12345" <sip:alice@our.example.com>;tag=19
To: "+54321" <sip:bob@other.example.com>
Identity: eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cDovL2FwaS5kZXYuc2lwZnJvbnQuY29tL3N0aXJzaGFrZW4ucHViIn0.eyJhdHRlc3QiOiJCIiwiZGVzdCI6eyJ0biI6WyI0Mzk5OTEwMDEiXX0sImlhdCI6MTYxNzk5NjA3MCwib3JpZyI6eyJ0biI6IjQzOTk5MTAwMSJ9LCJvcmlnaWQiOiJjMWVjMTIyYi05MGVmLTRmMzQtYmVkZi02NGExNjI4NjQwNDUifQ.iUECpCl1lZdTLeCiZWBNqDh0XNmA3yPIws_zOXy3N1XheA2sRuZOtimOEdjbNRGV3c9t_VSRf822zddBPwPYjw;info=<https://our.example.com/public.pem>;alg=ES256;ppt=shaken

The next hop will decode the JWT in the Identity header, and both verify the certificate of the originating party to ensure it’s signed by a trusted CA, and also check the origination and destination number.

Generating the Identity header with SIPp

One part of our contribution is to be able to dynamically generate the Identity header in SIPp scenarios, so you’re able to test both valid and invalid call scenarios.

To add an Identity header to your outbound SIP messages, you can put an identity keyword into your XML scenarios as described below.

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE scenario SYSTEM "sipp.dtd">
<scenario name="call-stirshaken">
    ...
    <send>
        <![CDATA[
            INVITE sip:bob@other.example.com SIP/2.0
            From: "+12345" <sip:alice@our.example.com>;tag=19
            To: "+54321" <sip:bob@other.example.com>
            ...
            [identity x5u="https://our.example.com/public.pem" attest="B" origtn="+12345" desttn="+54321" keypath="/path/to/priv.key"]
        ]]>
    </send>
    ...
</scenario>

Since SIPp is typically used to simulate thousands of calls with varying calling and called parties, you can specify files and fields as you would do in your R-URI, From and To headers.

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE scenario SYSTEM "sipp.dtd">
<scenario name="call-stirshaken">
    ...
    <send>
        <![CDATA[
            INVITE sip:[field1 file="callee.csv"]@other.example.com SIP/2.0
            From: "[field0 file="caller.csv"]" <sip:[field1 file="caller.csv"]@our.example.com>;tag=19
            To: "[field0 file="callee.csv"]" <sip:[field1 file="callee.csv"]@other.example.com>
            ...
            [identity x5u="https://our.example.com/public.pem" attest="B" origtn_file="caller.csv" origtn_field="0" desttn_file="callee.csv" desttn_field="0" keypath="/path/to/priv.key"]
        ]]>
    </send>
    ...
</scenario>

Now you would execute the sipp scenario as usual.

sipp ... \
    -inf /path/to/caller.csv -inf /path/to/callee.csv \
    -sf /path/to/call-stirshaken.xml \
    other.example.com

This will generate SIP messages with orign.tn and dest.tn values of the encoded Identity header matching the From/To Display-Name fields.

The corresponding CSV files look similar to the following from a formatting point of view.

RANDOM
+123451,user1
+123452,user2
+123453,user3
...

How to test it?

The new feature will first be verified and tested officially at OpenSipIt'01 from April 12th to April 14th 2021. Once validated, we will provide a pull request for the upstream repository for main-line integration.

Of course, we will provide test cases for the Sipfront Cloud as well, so you don’t have to deal with low-level SIPp, but can run your tests via the Web UI and the API.

What’s next?

Part 2 will cover the verification part of STIR/SHAKEN, showing how to validate a received Identity header with SIPp. Stay tuned.

comments powered by Disqus