STIR/SHAKEN
Have you ever received a call from someone with a caller ID which looked like the one you know but appeared not what you expected? Or had dozens of spam calls during a day? This can be utterly annoying, isn’t it?
You are right, unwanted calls can be a real pain in the neck. But they can also become a threat to the called party because fraudulent calls are often used to steal your sensitive data and use it against you.
Robocalls and Caller ID Spoofing Problems
Security is very important for VoIP calls. As the call sometimes originates not from a regular phone connected via the PSTN but from a software phone, the caller ID might be controlled not by the originating service provider but can be incredibly easily software-modified. In this case the caller ID will be different from what it originally is, and alas: you see a known caller ID on your phone screen, pick up the phone, and become a new victim to the telephone fraud.
Robocallers fake (or spoof) the caller ID to increase the chance that the called party will answer a robocall. Fraudsters may impersonate a legitimate source and ask for some data, which can be then used to steal something from you.
Caller ID spoofing often pretends the call to be from a nearby phone number with the same area code that you have. Once the caller ID is spoofed to look like something familiar, the consumers are more likely to pick up the telephone call. With calls originating from VoIP systems, the caller can be located in another part of the world.
Criminals are unscrupulous, and you cannot be sure that the calling number is what you expect it to be unless there is a mechanism to verify the caller. As with email spam, we cannot totally eliminate the threat but CarrierX can dramatically reduce the chances of this happening.
How STIR/SHAKEN Works
STIR/SHAKEN is a complex of protocols and procedures intended to fight caller ID spoofing on telephone networks. It enables telephone service providers to authenticate and verify caller identities to mitigate caller ID spoofing. It is a certificate-based technology that uses private and public keys to identify the source of a call.
STIR stands for Secure Telephony Identity Revisited. This is a series of RFC standards documents, defining a protocol for creating a digital signature with the calling party. It also allows this digital signature to be created and verified in various locations.
SHAKEN stands for Signature-based Handling of Asserted information using toKENs. SHAKEN specifies how STIR can be deployed in service provider networks. It provides both a reference architecture for SIP and a certificate management framework.
STIR/SHAKEN Process
The common STIR/SHAKEN flow can be described by the following diagram:
-
The calling party places a phone call using the originating telephone service provider network.
- The originating telephone service provider checks the call source and calling number, and uses the authentication service to determine how to attest for the validity of the calling number. The available attestation levels include:
- Full Attestation (A)
- Partial Attestation (B)
- Gateway Attestation (C)
Refer to the next section for more information on each of the attestation levels.
-
Based on the authentication service information, the originating telephone service provider adds the SIP Identity header to the call. The header is signed with a digital signature. Refer to the section below for more information on what data this header contains and why it is important.
-
After that the call goes to the terminating telephone service provider. There it is submitted to the verification service to verify the signature and header details and to determine whether the call is authentic or spoofed. To do this, the terminating telephone service provider obtains the digital certificate of the originating telephone service provider from the public certificate repository.
- Depending on the verification result, the terminating telephone service provider can either complete the call to the called party, or mark it as possibly spoofed, or even reject it on a suspicion of fraud. Refer to the CarrierX STIR/SHAKEN Implementation section below for more details on how the call can be dealt with in CarrierX.
Attestation Levels
The attestation levels serve two main purposes:
- They identify the originating service provider, which is useful for call traceback. This information can be used by other providers and legal authorities to investigate suspected illegal robocalls or telephone scams.
- They indicate the scope of information that the originating service provider will vouch for.
To make sure that the call is valid, comes from a trusted caller, and not spoofed, the following three attestation levels are used:
-
A or Full Attestation is used when the service provider authenticates the calling party and authorizes them to use the calling number. In other words, with full attestation the carrier knows for sure that the caller ID has not been spoofed. In CarrierX the full attestation is used with the outbound calls where CarrierX rented DIDs are the source of the call.
-
B or Partial Attestation is used when the service provider authenticates the call origination, but cannot verify the call source for the authorized use of the calling number. In other words, although the carrier originates the call and has a relationship with the customer making the call, the carrier cannot be certain the caller ID has not been spoofed. In CarrierX the partial attestation is used with the third-party endpoints owned by CarrierX customers being the source of the call.
-
C or Gateway Attestation is used when the service provider authenticates the gateway where they received the call, but the call source itself (and thus the caller ID authenticity) cannot be verified. In other words, the carrier can only say for certain where the call entered their network. In CarrierX the gateway attestation is used with the third-party endpoints, which CarrierX partners are reselling to other customers, who are the source of the call.
Being a certified communications service provider, CarrierX complies with the US Federal Communications Commission requirements and can attest the call and add the attestation information to the call data.
Depending on the attestation level, the appropriate Identity header is added to the call data. Refer to the next section for more information on what data this header contains.
SIP Identity Header
A typical SIP INVITE
message containing an Identity header in CarrierX looks like the following:
INVITE sip:12059999926;npdi=yes@1.1.1.1:5060 SIP/2.0
Via: SIP/2.0/UDP 12.7.193.185:5060;branch=z9hG4bK5af6e0ac;rport
Max-Forwards: 70
From: "John Smith*" <sip:15162065613@12.7.193.174>;tag=as062a2e2a
To: <sip:12059999926;npdi=yes@1.1.1.1:5060>
Call-ID: 22cccd5d13df02344314b8440baed1c5@12.7.193.174
CSeq: 102 INVITE
Identity: eyJ0eXAiOiJwYXNzcG9ydCIsImFsZyI6IkVTMjU2IiwicHB0Ijoic2hha2VuIiwieDV1IjoiaHR0cHM6Ly9zdG9yYWdlLmNhcnJpZXJ4LmNvbS9jZXJ0LmNydCJ9.eyJhdHRlc3QiOiJBIiwiZGVzdCI6eyJ0biI6WyIxMjA1OTk5OTkyNiJdfSwiaWF0IjoxNjE0MTcxOTIyLCJvcmlnIjp7InRuIjoiMTUxNjIwNjU2MTMifSwib3JpZ2lkIjoiZjQyMjA3MTAtNzZhMC0xMWViLWEyYTgtOTBlOWVlOWY1NGQ1In0.tx7OkEv36tmH9NYPD9HSIcrmA0i7ABRha-QBjlbVdYH-MrbGkdL-G7qIJbe7wLDB;info=<https://storage.carrierx.com/cert.crt>alg=ES256;ppt=shaken
The Identity header contains the following parts:
- A base64-encoded Persona Assertion Token (PASSporT) with the information about the call and the signature used to sign it. The token consists of three sections separated with periods (
.
):- Header containing the information about the protocol, encryption, and certificate used to sign the call.
- Payload containing the information about the call itself.
- Signature used to sign the call.
-
The token is followed by the
info
parameter (info=<https://storage.carrierx.com/cert.crt>
), which points to the URL of certificate repository. This repository belongs to the originating service provider. -
The
alg
parameter (alg=ES256
) specifies the encryption algorithm used to create signature. It is always equal toES256
. - The
ppt
parameter (ppt=shaken
) declares that the token is used for STIR/SHAKEN. It is always equal toshaken
.
Header
When we decode the token header, we can see that it contains the information about the means used to sign the call:
{
"alg": "ES256",
"ppt": "shaken",
"typ": "passport",
"x5u": "https://storage.carrierx.com/cert.crt"
}
Attribute | Data Type | Description |
---|---|---|
alg | string | Specifies the encryption algorithm used to create signature. Repeats the alg parameter of the Identity header. Value accepted in this field is ES256 . |
ppt | string | Declares that the token is used for STIR/SHAKEN. Repeats the ppt parameter of the Identity header. Value accepted in this field is shaken . |
typ | string | Defines the token type. Value accepted in this field is passport , corresponding to the base64-encoded Persona Assertion Token (PASSporT). |
x5u | string | Contains the link to the certificate used to sign the token and is equal to the info parameter of the Identity header. |
Payload
When we decode the token payload, we can see that it contains the information about the call itself and the call participants:
{
"attest": "A",
"dest": {
"tn": [
"12059999926"
]
},
"iat": 1614171922,
"orig": {
"tn": "15162065613"
},
"origid": "f4220710-76a0-11eb-a2a8-90e9ee9f54d5"
}
Attribute | Data Type | Description |
---|---|---|
attest | string | Defines the attestation level used with the call. Values accepted in this field are: A , B , or C . Refer to the Attestation Levels section for more information. |
dest | object | An object containing the tn array, which lists the destination numbers or called URIs. |
iat | integer | The UNIX timestamp of the moment when the token was created. |
orig | object | An object containing the calling number or URI. |
origid | string | A globally unique identifier corresponding to the service provider-initiated calls themselves, customers, classes of devices, or other groupings that a service provider might want to use for determining reputation or trace back identification of customers or gateways. |
Signature
The last part of the base64-encoded PASSporT token is a digital signature. SHAKEN implements digital signatures to enable service providers to detect and block call spoofing. To create the digital signature, the authentication service inputs the token header and payload into the hashing algorithm and obtains the hash value. Then it uses the originating provider’s private key from the secure key store and the resulting hash value to create a digital signature unique to the originating provider.
The digital signature is then combined with the original token header and payload to create the signed PASSporT token.
Storing Verification Results
After the digital signature in the Identity header is submitted to the verification service, it will return the result of the call verification.
The service providers can add the result (both successful and failed) to other call headers. For example, the verification results can be stored in:
-
P-Asserted-Identity header, as a
verstat
parameter added to thetel
URI.P-Asserted-Identity: tel:+15162065613;verstat=TN-Validation-Failed
-
From header, as a
verstat
parameter added to thesip
URI.From: "John Smith" <sip:15162065613@12.7.193.174>;tag=as062a2e2a;verstat=No-TN-Validation
-
Custom X- headers (e.g., X-StirResult), which can contain both the attestation and verification results.
X-StirResult: TN-Validation-Passed-A
There are currently three options to pass the verification results through header parameters:
TN-Validation-Passed
for the call being successfully verified.TN-Validation-Failed
for the call verification failed due to some reason.No-TN-Validation
for the call verification skipped due to some reason.
The usage of a specific header to store the verification results depends on the terminating telephone service provider software and hardware, and should be coordinated across the network.
CarrierX STIR/SHAKEN Implementation
According to the US Federal Communications Commission rules, the obligations of a voice service provider depend on the provider role for a particular call:
-
Originating providers must:
(a) authenticate and verify SIP calls originated and terminated on their networks, and
(b) authenticate SIP calls it will exchange with other voice service providers. -
Intermediate providers must:
(a) pass authentication information to the next provider in the chain unaltered, and
(b) authenticate unsigned calls (subject to certain exceptions). -
Terminating providers must verify SIP calls they receive from other providers for termination to the end user.
CarrierX can act as any of the provider type: originating, intermediate, or terminating.
To comply with all the rules, CarrierX uses transformations to implement STIR/SHAKEN procedures at various call stages.
CarrierX Call Verification
The stir_validate
transformation will verify the call and return data that can be used with other transformations.
Its syntax looks like the following:
{
"action": "stir_validate",
"direction": "any",
"operands": []
}
The stir_validate
transformation does not have any operands, instead it returns call verification data that can be used in the further call flow:
{{stir_attest}}
for the attestation level used for the call.{{stir_origid}}
for the ID of the call originator.{{stir_verstat}}
for the TN validation result.
The system then saves the verification data to the Call Detail Record object stir_attest
, stir_origid
, and stir_verstat
attributes accordingly.
Verification Examples
The stir_validate
transformation is normally not used all by itself. You can use it to verify the call signature and then use the output data with other transformations to manage the further call behavior.
An example of such a behavior can look like this:
Here is the list of the transformations used from the figure above:
"transformations": [
{
"action": "stir_validate",
"direction": "inbound",
"operands": []
},
{
"action": "set_header",
"direction": "inbound",
"operands": ["X-StirResult", "{{stir_verstat}}-{{stir_attest}}"]
},
{
"action": "if_match",
"direction": "inbound",
"operands": ["{{stir_verstat}}:{{stir_attest}}", "TN-Validation-Passed:[AB]", "rewrite_from_header_param", "cnam", "(.{1,14})", "\\1*"]
},
{
"action": "if_match",
"direction": "inbound",
"operands": ["{{stir_verstat}}", "No-TN-Validation", "rewrite_from_header_param", "cnam", ".*", "POSSIBLE FRAUD"]
},
{
"action": "if_match",
"direction": "inbound",
"operands": ["{{stir_verstat}}", "TN-Validation-Failed", "reject", "forbidden"]
}
]
These transformations will be used depending on the call source and their resulting call flow will be the following:
-
The call from the Calling Party #1 is digitally signed by the originating provider, it returns a valid
origid
, together with theA
attestation level (received from the{{stir_attest}}
variable) and theTN-Validation-Passed
verification status (received from the{{stir_verstat}}
variable). In this case, CarrierX comes to a conclusion that this is a trusted caller, adds the verification information as either the P-Asserted-Identity header parameter or the X-StirResult header, marks the CNAM of the From header with some sign (e.g.,*
) to signify a trusted caller, and after this the caller can be displayed as verified to the called party. -
The call from the Calling Party #2 is not signed by the originating provider. It returns the
No-TN-Validation
verification status (received from the{{stir_verstat}}
variable). Nor it is originating from CarrierX network. In this case, CarrierX cannot be sure whether it is a trusted caller or the number might be spoofed. CarrierX adds the verification information as either the P-Asserted-Identity header parameter or the X-StirResult header, and after this the caller will be displayed with some warning to the called party. -
The call from the Calling Party #3 is signed by the originating provider, but fails the verification. It returns the
TN-Verification-Failed
verification status (received from the{{stir_verstat}}
variable). In this case, CarrierX stops any further call flow using thereject
transformation, and the called party will never receive such a call.
Further Reading
Read the following articles to get a better understanding of how things work in CarrierX: