STIR/SHAKEN in Asterisk

What is STIR/SHAKEN?

STIR/SHAKEN (Secure Telephony Identity Revisited / Signature-based Handling of Asserted information using toKENs) is a new technology that the telecommunications industry is using to help combat telephony fraud. We’ve all received spam calls, and some of us may have even received a call from a caller ID we recognized, but ended up not being what we expected. In just the time it has taken me to write the first part of this blog post, I’ve received two spam calls already. This has been a major issue for years now, but with the help of STIR/SHAKEN, we can drastically reduce the chances of this happening.

How it Works

STIR/SHAKEN is a certificate-based technology that uses private and public keys to identify the source of a call. This establishes a chain of trust from one entity to another. Trusted providers will hold a private key that they use to sign SIP headers (specifically, the Identity header will have this signature), and they will provide the public key for others to download and verify against the private key. A lot of information is stored in this header, including the attestation, caller ID, public key URL, and more. The attestation will be used to determine what level of trust this call is trying to establish. From there, the receiver of the call can decide what they would like to do with that information. Here’s an example of what an Identity header might look like:

Identity: eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cDovL3Rlc3RpbmcxMjMifQ==.eyJvcmlnIjp7InRuIjoiMTIzNDU2NyJ9LCJhdHRlc3QiOiJCIiwib3JpZ2lkIjoiYXN0ZXJpc2siLCJpYXQiOjE1OTA1ODgzODV9.MEUCIQCmINlklk+fCxEEjgbbwE5X7DAEy19aPRfLvypXrKUwpwIgaDtEzKZoGRa/Omof9iC6tPQPzsKazN1hygDWOc9uWXQ=;info=<https://testing123.com/test.crt>alg=ES256;ppt=shaken

The header, payload, and signature are all BASE64 encoded and separated by periods. Let’s take a look at the header:

eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cDovL3Rlc3RpbmcxMjMifQ==

If we BASE64 decode this, we get:

{"alg":"ES256","ppt":"shaken","typ":"passport","x5u":"http://testing123"}

The header is a JSON object containing (at minimum) the encryption algorithm, ppt, type, and public key URL. At the time of writing this, ppt must be “shaken” and typ must be “passport”.

Now, the payload:

eyJvcmlnIjp7InRuIjoiMTIzNDU2NyJ9LCJhdHRlc3QiOiJCIiwib3JpZ2lkIjoiYXN0ZXJpc2siLCJpYXQiOjE1OTA1ODgzODV9

Again, after we BASE64 decode this, we get:

{"orig":{"tn":"1234567"},"attest":"B","origid":"asterisk","iat":1590588385}

The payload is also a JSON object, containing the caller ID number, attestation, origination ID, and timestamp. Most of the information in here will be used to compare against conditions that need to be met in order for the call to succeed.

The signature follows the payload, up until the semicolon. After that, we have:

info=<https://testing123.com/test.crt>alg=ES256;ppt=shaken

This is all information that we’ve seen before in the previous sections. Using this, we have all the information we need to verify that a call actually came from where it said it did!

STIR/SHAKEN Configuration

Asterisk already has STIR/SHAKEN support implemented. It’s an option within the “endpoint” section of pjsip.conf:

[my_endpoint]
type=endpoint
stir_shaken=yes

By default, this option is set to no. If you want STIR/SHAKEN support for your calls, you will have to enable this option for those endpoints. That’s all you have to do in pjsip.conf. The rest is configured in stir_shaken.conf. Here’s an example of what that configuration file might look like:

[general]
ca_file=/etc/asterisk/stir/ca.crt
ca_path=/etc/asterisk/stir/ca
cache_max_size=1000
curl_timeout=2
signature_timeout=15

[my_cert]
type=certificate
path=/etc/asterisk/stir/mycert.pem
public_key_url=http://testing.com/test.crt
caller_id_number=1234567
attestation=C
origid=MyAsterisk

The general Section

The first option (ca_file) points to the certificate authority file. This will be used if you are the certificate authority for other providers. The second option (ca_path) is the path to the chain of trust. The third option (cache_max_size) will set how many certificates can be stored in memory. When downloading a public key to verify a signature, the curl_timeout option will be used to determine how many seconds we should wait before terminating the request. It’s a good idea to keep this number low, especially if you plan on having a lot of traffic utilizing STIR/SHAKEN. The signature_timeout is used to specify how long a signature is valid for. If we receive an Identity header that was signed greater than this many seconds ago, we won’t consider it valid. This is a preference and can generally be ignored unless you want tighter restrictions.

The certificate Section

Now let’s look at the certificate. Of course, type must be certificate for the following options to take effect. The path points to the location of your private key for this certificate on your system. The public_key_url provides a URL that others can download your public key from. The caller_id_number specifies which caller ID this certificate should belong to. Eventually, this will be replaced and the certificate file itself will have numbers that it will belong to. The attestation determines what level of trust this certificate has, and the origid states where the certificate came from. This is the bread and butter for most STIR/SHAKEN operations.

After all of this has been set up, you can place a call and Asterisk will perform all of the necessary steps for signing and verifying! All inbound and outbound INVITEs will now sign the payload and add an Identity header, and check the Identity header upon receipt, respectively.

STIR/SHAKEN Dialplan

Another cool thing you can do is check STIR/SHAKEN results in the dialplan. The STIR_SHAKEN function will report back the verification result for you to use however you want. The possible results are “Verification not present”, “Signature failed”, “Verification mismatch”, and “Verification passed”. If the result is “Verification not present”, that means there was no STIR/SHAKEN information to process (no Identity header). “Verification mismatch” means that information inside of the payload did not match information in the SIP message. “Verification passed” means that STIR/SHAKEN verification was a success. “Signature failed” means that either the signature and public key did not match, or the signature failed for another reason. Based on these results, you can decide what course of action to take. Here are some examples:

exten => example1,1,STIR_SHAKEN(count)

exten => example2,1,STIR_SHAKEN(0, verify_result)

exten => example3,1,STIR_SHAKEN(5, identity)

exten => example4,1,STIR_SHAKEN(2, attestation)

You already know what verify_result means, but there’s some other information you can get as well. If you just pass count to the function, it will return how many STIR/SHAKEN identities there are. You can then iterate through them all and get other information. That’s where the numbers come in. To get the verification result, you must first pass in the index of the identity you want the information for, and then the name of the information that you want. Currently, you can retrieve the verify_result, identity, and attestation.

Conclusion

That’s all there is to it! The setup is fairly minimal, but the impact it will have on customers is huge. By following the above steps to configure Asterisk for STIR/SHAKEN, you will be able to prevent several spam calls, saving time and money. More work will be done on STIR/SHAKEN in the future as the technology and industry continue to evolve, but the groundwork is already done and can be used now. Give it a try and help us improve Asterisk with your feedback!

About the Author

What can we help you find?