
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
