Telephony spam and spoofed caller ID underpin the robocall menace, allowing scammers to disguise phone numbers and evade detection. STIR/SHAKEN — a framework of protocols that digitally signs and verifies caller identity using cryptographic certificates — increases trust in caller ID, making it harder for illegal robocalls to succeed. SignalWire sponsors and develops libstirshaken, an open-source STIR/SHAKEN implementation that lets developers integrate caller ID authentication into VoIP applications to help combat robocalls at scale.
The telephony industry has struggled with spam calls and robocalling almost since its inception. As soon as someone had a phone number, they could be called by anyone, and the caller could pretend to have any identity.
The number and identity of the caller, known as Caller ID, are relatively easy to falsify or “spoof” as that action is known in VoIP circles. This leads to difficult situations when it comes to filtering calls, because it used to be hard to verify the claim that the call was indeed coming from a legitimate party.
SignalWire has been contributing to the mitigation of that problem with the development of libstirshaken, the open source implementation of the STIR/SHAKEN protocol.
How does the protocol work?
When signing a call, the caller uses a certificate they received from an FCC authority to create block of data that is included in the call header.
On reception, the callee will verify that block of data using the referenced certificate that was used to create the signed data.
Everything is very simple and transparent to end users, who enjoy enhanced security without any changes to their usual call flow.
What is STIR/SHAKEN?
STIR/SHAKEN is a technology to mitigate caller ID spoofing, and its acronym is quite explanatory despite being a bit contrived.
STIR, short for Secure Telephony Identity Revisited, is a set of RFC standard documents that define how authenticity certificates should be added to the SIP protocol and verified when a call is received.
By itself, that would solve the problem of falsified caller IDs in Voice over IP calls, but it does not handle the case of a PSTN call routed over SS7, because the special headers and certificates would be missing.
SHAKEN, short for Signature-based Handling of Asserted information using toKENs, is a set of recommendations to deal with calls on the public switched network, mainly through the addition of special information to CNAM records, which are normally used to verify and display caller ID on the PSTN.
STIR/SHAKEN does not only specify a way to verify a caller ID certificate, but also mechanisms to attach other information to the call. This Rich Call Data (RCD) payload could for example contain a picture of the caller, or some other extra information.
Mode of operation
STIR uses JSON objects (called PASSporTS) to convey cryptographically signed information about a call.
These PASSporTs are signed with private keys associated with certificates to which a link is embedded in PASSporTs, so that during a process of verification of PASSporT those SSL certificates are downloaded and can be checked for authenticity.
They must be special SHAKEN certificates, which means they have been issued by a certified SHAKEN certificate authority (CA).
Why STIR/SHAKEN matters
“The FCC’s Second Order for the TRACED Act mandates that calls from any voice service provider not registered with the new FCC SHAKEN/Robocall Mitigation Database by June 30, 2021 must be blocked.”
SITR/SHAKEN provides a few main features out of the box:
1. Information about the call can be sent along with a SIP message and verified at the terminating point, so it is known that it couldn’t possibly have been changed. Aside from simple caller ID verification, the information contains the intended destination, and the originating point. Thus, if all of the information in the PASSporT header matches, the identity of the caller and the call path are confirmed as valid.
This simple integrity check is performed by decoding PASSporT with a public key taken from the certificate that the header references. This confirms the call path has not been tampered with, and might be enough for simple usage, provided the entity who signed that particular PASSporT is trusted.
2. To find out if the call origin is trustable, we need to validate the STIR/SHAKEN certificate that signed the call PASSporT. It should have been signed by a dedicated Certificate Authority, who in turn must have received its credentials by the trusted network, consisting of entities who possess certificates signed by the STIR/SHAKEN root certificates. This has many similarities with how HTTPS operates.
In the United States the STIR/SHAKEN network is built and managed by the FCC. The root authority is Iconectiv and there will be many CAs started by other entities. This initiative intends to be the global authority for STIR/SHAKEN, but technically it is possible for other trust networks to (co)exist. The only requirement is that end entity certificates (service provider certificates) must be derived from root CA certificates, and root CA certificates are managed properly both during creation and storage.
These X.509 certificates are checked as part of the verification process together with the service provider’s own certificate. This means that the process will eventually encounter a trusted party up the chain, including the root CA, and will be able to trust the entire chain.
3. The last part of a STIR/SHAKEN check will be the verification of authority of the Service Provider over the telephone number given as orig grant in PASSporT (caller ID). The exact way the authority check is going to be performed has not been defined, but there is most likely going to be one or more central databases, similar to the FCC registry for robocallers, but containing information about which provider manages each phone number.
The open-source implementation of STIR/SHAKEN: libstirshaken
Libstirshaken is an open-source library sponsored by SignalWire, implementing all of the building blocks of STIR/SHAKEN. Its goal is to make it easy to integrate STIR/SHAKEN in telephony applications.
It can be used in two main modes. The first, which is the most common, is to use libstirshaken to sign and verify calls on the official FCC network, to provide better security to users and customers. The library can also be used effectively as a Letsencrypt-style tool, to generate child certificates from a FCC-certified parent obtained from a verified CA.
Usage examples
We will be now looking at the basic usage of libstirshaken via its bundled command line tool, as an easy way to start integrating STIR/SHAKEN in your application.
Signing the call
In our scenario, a user named Bob calls Alice through a service hosted on SignalWire. The service would like to sign the call on behalf of Bob using the SHAKEN certificate it obtained from a FCC-certified CA.
The “stirshaken” command line tool would be used in the following way. Say Bob calls Alice and we got our private SSL key which is associated with our Shaken certificate that we obtained from CA. We create then PASSporT:
./stirshaken passport-create --privkey test/ref/sp/certificate.priv --url https://shaken.signalwire.clou... --attest B --origtn bob --desttn alice --origid e1532d44-f4db-4788-8ae5-e9442412510a -f passport.txt --vvv
In readable form, the PASSporT generated is:
{
"alg": "ES256",
"ppt": "shaken",
"typ": "passport",
"x5u": "https://shaken.signalwire.clou..."
}
.
{
"attest": "B",
"dest": {
"tn": [
"alice"
]
},
"iat": 1617028773,
"orig": {
"tn": "bob"
},
"origid": "e1532d44-f4db-4788-8ae5-e9442412510a"
}After signing, the JSON above is encoded in a format suitable for including in a SIP INVITE. Note that the above command generates both the signed and unsigned version in the same output file we specify with “-f”.
Additionally, to be sent over SIP we need to add an info field with the necessary PEM information:
info=<https://shaken.signalwire.cloud/sp.pem>;alg=ES256;ppt=shaken
With the final output being:
eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly9zaGFrZW4uc2lnbmFsd2lyZS5jbG91ZC9zdGlyX3NoYWtlbi9zcC5wZW0ifQ.eyJhdHRlc3QiOiJCIiwiZGVzdCI6eyJ0biI6WyJhbGljZSJdfSwiaWF0IjoxNjE3MDI4NzczLCJvcmlnIjp7InRuIjoiYm9iIn0sIm9yaWdpZCI6ImUxNTMyZDQ0LWY0ZGItNDc4OC04YWU1LWU5NDQyNDEyNTEwYSJ9.C0_NbMmVwdcV645sru8SeIfWEeg_ARwLCjtVbUDHtSH_PVX5vErWKe6BnxSWHQu_Vc2e6ZrZKUJLoxSiamAjkg;info=<;;alg=ES256;ppt=shaken
In this form it may be sent down the protocol stack. In the case the header’s size becomes too large to be sent over UDP, it can be transmitted out of band using mechanisms such as the Call Placement Service specified in the STIR OOB draft.
The SIP Invite would look similar to this:
INVITE sip:alice@190.102.98.199:5960 SIP/2.0 Via: SIP/2.0/UDP 3.8.193.142:5580;rport;branch=z9hG4bK62acZ0175HStD Max-Forwards: 70 From: <sip:bob@3.8.193.142>;tag=3U8B9aUFar8Fj To: <sip:alice@190.102.98.199:5960> Call-ID: 6aff79fa-0b3f-123a-1a91-0210aa0ae2ba CSeq: 33960594 INVITE Identity: eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly9zaGFrZW4uc2lnbmFsd2lyZS5jbG91ZC9zdGlyX3NoYWtlbi9zcC5wZW0ifQ.eyJhdHRlc3QiOiJCIiwiZGVzdCI6eyJ0biI6WyJhbGljZSJdfSwiaWF0IjoxNjE3MDI4NzczLCJvcmlnIjp7InRuIjoiYm9iIn0sIm9yaWdpZCI6ImUxNTMyZDQ0LWY0ZGItNDc4OC04YWU1LWU5NDQyNDEyNTEwYSJ9.C0_NbMmVwdcV645sru8SeIfWEeg_ARwLCjtVbUDHtSH_PVX5vErWKe6BnxSWHQu_Vc2e6ZrZKUJLoxSiamAjkg;info=<;;alg=ES256;ppt=shaken Contact: <sip:mod_sofia@3.8.193.142:5580> Date: Mon, 29 Mar 2021 14:39:33 GMT User-Agent: FreeSWITCH-mod_sofia/20.20.8-dev+git~20210211T195954Z~b374add1ef~64bit Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY Supported: timer, path, replaces Allow-Events: talk, hold, conference, refer Content-Type: application/sdp Content-Disposition: session Content-Length: 740 X-FS-Support: update_display,send_info Remote-Party-ID: <sip:bob@3.8.193.142>;party=calling;screen=yes;privacy=off [...SDP omitted for brevity…]
Verification of a call
Alice or her provider will perform the following checks on the terminating side:
1. Extract PASSporT
2. Download referenced certificate
3. Check signature using public key from downloaded certificate
4. Check if certificate was signed by one of trusted CA roots
This can be done with:
./stirshaken jwt-check --jwt eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly9zaGFrZW4uc2lnbmFsd2lyZS5jbG91ZC9zcC5wZW0ifQ.eyJhdHRlc3QiOiJCIiwiZGVzdCI6eyJ0biI6WyJBbGljZSJdfSwiaWF0IjoxNjE1OTM2MjQ1LCJvcmlnIjp7InRuIjoiQm9iIn0sIm9yaWdpZCI6ImUzMmY0MTg5LWNiODYtNDYwZi1iYjkyLWJkM2FjYjg5ZjI5YyJ9.jJSEUTpKlBuSGT_eoyWB6ngHl5J5OA0yAbDPMq8mjO1SkHaXxh8aL1oJ2Gl2qmqmMJNXMQeeA6KKZphensxljg;info=<;;alg=ES256;ppt=shaken --ca_dir test/ref/ca --vvv
With the redacted output being:
+ Processing OPTION 18 (jwt)
[...]
PASSporT is:
{
"alg": "ES256",
"ppt": "shaken",
"typ": "passport",
"x5u": "https://shaken.signalwire.clou..."
}
.
{
"attest": "B",
"dest": {
"tn": [
"Alice"
]
},
"iat": 1615936245,
"orig": {
"tn": "Bob"
},
"origid": "e32f4189-cb86-460f-bb92-bd3acb89f29c"
}
[...]
Verified. JWT matches the referenced certificate
=== Done. Thank you.The “Letsencrypt” of STIR/SHAKEN
There are many possible application of libstirshaken and the related CLI tools:
generating SSL keys
generating CSR
generating SSL certificates (end entity, self issued and self signed)
generate PASSporT for a call
run a simplified demo CA
obtain SP (end entity) certificate from that CA, simulating ACME
- verify PASSporT:
(optionally) with X509 cert path check
(optionally) caching supplying certificates from cache through your callback
dump PASSporT (input is encoded JWT, output is human readable headers and grants)
specify connect timeout on http(s) request
Save CA certificate with hashed name (necessary when using CA dir)
Using libstirshaken, it is possible to build out an entire STIR/SHAKEN infrastructure to support your use cases or even third parties.
In this phase in the industry, robo-calls and spammers will start meeting the same countermeasures that email users have enjoyed for years. Join our community of developers on Discord to be part of the conversation.
Frequently asked questions
What is STIR/SHAKEN?
STIR/SHAKEN is a suite of standards and protocols designed to authenticate caller ID information by digitally signing calls with cryptographic certificates so that terminating networks can verify whether caller identity is legitimate or spoofed.
Why does caller ID spoofing matter?
Caller ID spoofing lets robocallers make calls appear to come from innocuous or local numbers, increasing the likelihood that recipients will answer and exposing them to scams or spam.
How does STIR/SHAKEN reduce robocalls?
By signing outbound calls and verifying signatures on inbound calls, STIR/SHAKEN enables networks and phones to tell whether a call’s presented number has been authenticated, helping block or label calls with spoofed identities.
What is libstirshaken?
libstirshaken is an open-source implementation of the STIR/SHAKEN framework sponsored by SignalWire that developers can use to add caller ID authentication and verification into their telephony applications.
Does STIR/SHAKEN eliminate all illegal robocalls?
No. STIR/SHAKEN reduces spoofed caller ID and makes illegal robocalls harder to operate, but it does not by itself stop all unwanted calls — it’s one tool among many in the broader fight against spam calls.