How To Generate Self-Signed STIR/SHAKEN Certificates

After having received some positive feedback on our presentation on the topic at hand at ClueCon ’22, let’s go through a more detailed run-down of all steps required, from a cryptographic point of view, in order to first become a fictive STIR/SHAKEN CA (Certification Authority), then to begin issuing signed certificates for various (also fictive) VoIP Service Providers.

For key and certificate generation, we will mostly be using the OpenSSL toolkit on a Debian-like OS:

apt -y install openssl coreutils

Becoming a CA

The first step is to become a Certification Authority. For this, we will need a root CA certificate and private key. And thanks to the renowned reputation of our community, all of the world’s operating systems will immediately recognize our key pairs as being trustworthy… (spoiler alert: no, they will not!).

First, we set up our work directory and generate a private key using Elliptic-Curve cryptography (smaller key size, but equal or even better security):

$ mkdir /tmp/stir-shaken-ca
$ cd /tmp/stir-shaken-ca

$ openssl ecparam -noout -name prime256v1 -genkey -out ca-key.pem

Finally, we generate a corresponding certificate (public key) for our key:

# Tip: you can just press Enter/Enter/Enter... to skip filling in the info
$ openssl req -x509 -new -nodes -key ca-key.pem -sha256 -days 1825 -out ca-cert.pem

$ ls
ca-cert.pem  ca-key.pem

Issuing SP Certificates

My congratulations on you becoming a DIY, unauthorized STIR/SHAKEN CA! Let’s put that unrecognized CA key pair to work and start signing tons of self-generated Service Provider STIR/SHAKEN certificates with it!

Similarly to earlier, let’s set up our SP work directory and generate an EC private key:

$ mkdir /tmp/stir-shaken-sp1
$ cd /tmp/stir-shaken-sp1

$ openssl ecparam -noout -name prime256v1 -genkey -out sp-key.pem

Here is where STIR/SHAKEN comes into play, with its TNAuthList extension ( to the X.509 certificate which we must include, otherwise the certificate is likely to be rejected by most STIR/SHAKEN software out there. For example, the OpenSIPS stir_shaken module will definitely reject any X.509 cert with a missing TNAuthList.

First, we generate an openssl.conf file which includes a hex-encoded TNAuthList extension (see the trailing line of the final file):

$ cat >TNAuthList.conf << EOF

$ openssl asn1parse -genconf TNAuthList.conf -out TNAuthList.der

$ cat >openssl.conf << EOF
[ req ]
distinguished_name = req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
commonName = "SHAKEN"
[ v3_req ]

$ od -An -t x1 -w TNAuthList.der | sed -e 's/ /:/g' -e 's/^/' >>openssl.conf

Next, as Service Provider, we generate a Certificate Signing Request (CSR), which we will finally “submit” to our Certification Authority:

# generate a Certificate Signing Request, which includes our required TNAuthorizationList
$ openssl req -new -nodes -key sp-key.pem -keyform PEM \
    -subj '/C=US/ST=VA/L=Somewhere/O=AcmeTelecom, Inc./OU=VOIP/CN=SHAKEN' \
    -sha256 -config openssl.conf \
    -out sp-csr.pem

Finally, as the Certification Authority, we accept the CSR, then generate and sign the STIR/SHAKEN certificate (public key):

# on the CA side, generate the certificate (User-CSR + CA-cert + CA-key => User-cert)
$  openssl x509 -req -in sp-csr.pem -CA ../stir-shaken-ca/ca-cert.pem -CAkey ../stir-shaken-ca/ca-key.pem -CAcreateserial \
  -days 825 -sha256 -extfile openssl.conf -extensions v3_req -out sp-cert.pem

And we are done! Our signed SP cert and private key files are now available:

$ ls sp*
sp-cert.pem sp-key.pem

As an optional step, here is how you can verify whether a given SP certificate contains the TNAuthList extension or not:

$ openssl x509 -in sp-cert.pem -text -noout
        Version: 3 (0x2)
        Serial Number:
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd
            Not Before: Oct 20 17:40:41 2022 GMT
            Not After : Jan 22 17:40:41 2025 GMT
        Subject: C = US, ST = VA, L = Somewhere, O = "AcmeTelecom, Inc.", OU = VOIP, CN = SHAKEN
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
            X509v3 Authority Key Identifier: 
    Signature Algorithm: ecdsa-with-SHA256
    Signature Value:

opensips.cfg Settings

Finally, in your opensips.cfg file, make sure to explicitly add our “dummy” CA to the list of trusted certification authorities in order for all SP certificates generated by it to pass as “valid” certificates:

modparam("stir_shaken", "ca_list", "/tmp/stir-shaken-ca/ca-cert.pem")

Happy hacking!
//OpenSIPS Team @ TadSummit Nov 8-9 2022

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s