
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 (1.3.6.1.5.5.7.1.26) 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 asn1=SEQUENCE:tn_auth_list [tn_auth_list] field1=EXP:0,IA5:1001 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 ] EOF $ od -An -t x1 -w TNAuthList.der | sed -e 's/ /:/g' -e 's/^/1.3.6.1.5.5.7.1.26=DER/' >>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 Certificate: Data: Version: 3 (0x2) Serial Number: 2b:9c:a0:0c:3f:c2:64:c7:6f:c9:90:15:b1:db:f1:68:71:1f:c5:09 Signature Algorithm: ecdsa-with-SHA256 Issuer: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd Validity 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) pub: 04:0b:80:14:49:3e:92:dc:a5:71:21:a5:3c:c2:37: a3:0f:26:b4:03:e2:32:e9:6d:37:28:18:d5:fb:ae: c0:a7:9c:3c:ed:40:84:2a:dd:2f:9b:bd:45:f1:f7: f0:df:df:7d:5a:14:38:eb:37:dc:ea:14:2a:97:fc: 4e:69:91:9c:cb ASN1 OID: prime256v1 NIST CURVE: P-256 X509v3 extensions: 1.3.6.1.5.5.7.1.26: 0.....1001 X509v3 Subject Key Identifier: 4D:83:8E:38:60:7D:06:01:63:6F:10:06:05:81:68:3E:DD:FF:DA:38 X509v3 Authority Key Identifier: AA:8E:B2:62:DB:76:B2:75:9B:8D:BF:CD:91:67:22:DE:DD:EC:1D:02 Signature Algorithm: ecdsa-with-SHA256 Signature Value: 30:46:02:21:00:b0:1e:d6:2f:15:92:d9:35:c5:f0:b9:27:cd: 10:47:73:1a:72:ed:06:6c:31:e2:96:eb:2b:78:38:9a:04:23: e8:02:21:00:b9:4b:fb:65:7f:32:9a:48:c5:30:0c:dd:71:fd: 13:4e:92:da:f7:73:8e:45:b7:35:07:7d:f7:02:7e:a4:d3:55
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