Securing the Association of the DTLS Certificate With the User’s SIP-URI


imagesThe SIP protocol can be used to establish SRTP security using DTLS protocol. The DTLS extension ([RFC 5764]) is used. It describes a mechanism to transport a fingerprint attribute in SDP. So the fingerprint of the self-signed certificate can be inserted by the user agent (UA) in the SDP and sent over SIP to the proxy over an integrity protected channel (carried over TLS transport protocol). The fingerprint in the SDP looks like this:

a=fingerprint:sha-1 99:41:49:83:4a:97:0e:1f:ef:6d:f7:c9:c7:70:9d:1f:66:79:a8:07

Then after the user has been authenticated, the proxy generates a hash where the certificate’s fingerprint and SIP user ID are among others included in the calculation. The proxy signs the hash using its private key and inserts the signature in a new header field in the SIP message (the Identity header field). This secure the association between the DTLS certificate and the user’s SIP URI. The Identity-Info header field helps the verifier (the receiver of the SIP/SDP message) in the verification of the signature included in the Identity header field.

The certificates are being used as a carriers for the public keys and used to authenticate the counterpart and negotiate the session keys (symmetric keys). Then the session keys are used by SRTP to encrypt/decrypt the media. The offerer sends its fingerprint in the request and the answerer sends its fingerprint in the corresponding response after accepting the offer.

Using SIP Identity and Identity-Info

The solution as i mentioned above is using the SIP Identity ([RFC 4474]) to sign the binding of the fingerprint to the user. This is done by the proxy responsible for that user. The proxy is the holder of the private key of its domain. After the user is successfully authenticated, it is authorized to claim the identity (AOR of the user). The proxy creates the signature of the hash using its private key and inserts it in Identity header field. The proxy also inserts the place where the verifier can acquire the proxy’s certificate (public key) using the Identity-Info header field.


Identity: CyI4+nAkHrH3ntmaxgr01TMxTmtjP7MASwliNRdupRI1vpkXRvZXx1ja9k

Note the part “/cert” in the Identity-Info URL which addresses a certificate.

The Hash Generation

The signature of the hash is added as an Identity header field in the SIP message. The calculation of the hash must contain mainly the AOR of the user and the fingerprint included in the SDP in the body of the message.  According to RFC [4474], the signature/hash is generated from certain components of SIP message, among others:

  • The AoR of the UA sending the message (or addr-spec of the From header field)
  •  The addr-spec component of the Contact header field value.
  • The whole SDP body (the fingerprint is here)
  • …….

Fingerprint Verification

Using the header Identity-Info, the user agent verifies that the fingerprint of the certificate received over the DTLS handshake matches the fingerprint received in the SDP of SIP request/response.


Datagram Transport Layer Security (DTLS)



The DTLS protocol ([RFC 6347]) is based on TLS protocol to provide similar security for the network traffic transported on datagram transport protocols (e.g. UDP). Usually the real time applications like media streaming and internet telephony are delay sensitive for the transported data so they use datagram transport to carry their data. DTLS  runs on UDP to secure the data in a transparent way (inserted between the application layer and transport layer). DTLS runs in application space without any kernel modifications. The DTLS preserves the in-order delivery of data which is not provided by the datagram transport. Current version of DTLS is 1.2

Why DTLS and NOT TLS for Datagram Transport

The answer is simply because using datagram transport like UDP means the packets could be lost or reordered and TLS cannot handle this (this is handled by TCP when it is used). So we take the TLS and add minimal changes to fix the unreliability problem and we call the result DTLS.

WhyDTLSMore specifically, the problems that are in TLS if datagram transport are used:

  • In TLS there is what is called integrity check which depends on the sequence number. For example record N is lost –> then the integrity check on record N+1 will fail because the wrong sequence number. The sequence numbers are implicit in the records. The record could also reach but in a wrong order. For example record N+1 reached before the record N.
  • The record could reach many times (replayed).
  • The TLS handshake will break if the handshake messages are lost.
  • Handshake message size is big (many kilobytes): as we know in UDP, datagrams are limited to 1500 bytes.

So the goal is changing TLS to solve the above problems and then we get DTLS. Briefly DTLS solves the problems by:

  • Banning the stream ciphers to make the records independent (don’t have the same cryptographic context – cipher key).
  • Adding explicit sequence numbers in the records.
  • Using retransmission timer for packet loss handling.
  • Handshake message fragmentation –> Each DTLS handshake message must contain fragment offset and fragment length.
  • Maintaining a bitmap window of received records so if a record is previously received it will be discarded.

The client automatically generates self-signed certificates for each peer. This means there is no certificate chain verification. The certificates themselves cannot be used to authenticate the peer because they are self-signed. So the DTLS provides encryption and integrity, but let the authentication to be done by the application.

Library Support For DTLS 1.2

Botan, GnuTLS, MatrixSSL, OpenSSL, wolfSSL

Restrictions of FIFO-based Communications in Linux

Problem Definition

To explain this we will take OpenSIPS’s fifo as an example. It is used to communicate with OpenSIPS’s management interface “Mi”. Assume “/tmp/opensips_fifo” is the fifo file. OpenSIPS is the owner of this pipe and OpenSIPS-CP wants to access/read/write to/from the pipe. As we know everything is a file in Linux so this pipe is just a file and we want to manage how OpenSIPS-CP or other programs can access this pipe to send requests or receive reponses to/from OpenSIPS. OpenSIPS is executed by user=opensips and group=opensips. OpenSIPS-CP is executed by user=apache and group=apache. To see this:  # ps -aux | grep httpd or opensips.


And we have this error message “Cannot connect to OpenSIPS Server via Management Interface (/tmp/opensips_fifo)“. Be sure you are using the right name of the fifo file. Be aware if there is a space at the front or at the end of file path. Be sure that you are talking with the intended OpenSIPS server in case you have many OpenSIPS instances working on the same machine. Be sure the opensips is simply running (OpenSIPS restart may solve the problem). If all that is ok and still you have the error message then start your journey through this article.

Here i have Fedora 20, PHP 5.5.17 , Apache 2.4, OpenSIPS-CP 6.0 , OpenSIPS 1.11. Do the corresponding of everything in your system.

What to Do

Temporarily disable SeLinux. We will come back to it.

  • Discretionary Access Control (DAC): In OpenSIPS configuration file we have this line “modparam(“mi_fifo”, “fifo_mode”, 0666)”  so OpenSIPs create the fifo file with the permission 666 (Owner=6,Group=6, Others=6) which is “prw-rw-rw-“. This means read and write permission for the owner, group, and the others. The letter p means this file is pipe.
  • User:Group Ownership: OpenSIPS-CP executed by apache so add apache user to opensips group if you don’t want to give permissions to others. For this, you can use # system-config-users. To list the members in the group:

# lid -g $groupName

  • Access Control List (ACL): use ACL to give permissions to a specific user For example let Apache user has rw access to the fifo file:

# setfacl -m u:apache:rw /tmp/opensips_fifo

To check the list

# getfacl /tmp/opensips_fifo

Eiciel is GNOME tool to visually configure the ACL entries. # yum install eiciel and to run it  # eiciel the GUI will open. Choose the directory and start editing the acl. Visual ACL

  • Programming Language Restrictions: The programming language may apply some kind of restrictions on accessing files. Web programming language like PHP has safe_mode and open_basedir features. Open /etc/php.ini to disable these. For example file_exists() php function check whether the file or directory is exists or not. This Function return False due to safe_mode restrictions. When safe_mode is enabled (safe_mode = On in php.ini), PHP checks to see if the owner of the current php script matches the owner of the file to be operated on. Safe_mode is removed in PHP-5  but we have to keep programming language restrictions in our minds.
  • Web Server Restrictions: For example Apache web server protects directories and files from hosts/web clients by defining policy rules in httpd.conf.

Example 1: “Linux root is inaccessible by everyone”

<Directory />
AllowOverride none
Require all denied

The default is denying access to the entirety of your server’s file system. You must explicitly permit access to the server’s directories

Example 2: The area /var/www/opensips-cp/web can be accessed by everyone:

<Directory  /var/www/opensips-cp/web>

Options Indexes FollowSymLinks MultiViews

AllowOverride None
Require all granted


  • PrivateTmp Feature: This is new feature since Fedora 16 and Red Hat Enterprise Linux 7. “PrivateTmp” is an option in systemd unit configuration files.

PrivateTmp: “Takes a boolean argument. If true sets up a new file system namespace for the executed processes and mounts a private /tmp directory inside it, that is not shared by processes outside of the namespace. This is useful to secure access to temporary files of the process, but makes sharing between processes via /tmp impossible. Defaults to false.”

If the fifo file which is shared between two processes (apache and opensips) created in /tmp so you have to disable this feature. To disable it do the following:

# vim /usr/lib/systemd/system/httpd.service

Change the line PrivateTmp=true to PrivateTmp=false

# systemctl –system daemon-reload

# systemctl restart httpd.service

  • Umask

It could be helpful if you check the umask of the running process which accessing the file and the umask of the file. umask of the specific file can be changed by setfacl command and graphically by Eiciel . To change the  umask of running process, take the id of the process for example httpd # ps -ef |grep httpd.  Enter the gdp # gdp –pid=httpd-Process-Id. To change the umask to 0, type  call umask(0) in gdp console. The umask will be 0 and the command will give you the previous umask value.

  • SeLinux: SeLinux might prevent the access to the file (access, link, unlink,…. ). Selinux Troubleshooter can help you to know how to fix this. How to allow for example httpd process to access FIFO file. Keep your eyes on the SeLinux alerts and do what the troubleshooter suggests. The file “/var/log/audit/audit.log”  contain the alerts and what you did is this:

# grep httpd /var/log/audit/audit.log | audit2allow -M minpol
# semodule -i minpol.pp

If you go through all the points above you will be able to solve the problem .Remember if you make any changes in the configuration file, restart the service.

Where to Look to Trace the Error

Reading the log files is the key (basically here /var/log/*). Make some changes in the configuration somewhere, restart the corresponding service and re-read the log files again. Repeat this till you get no errors. Now  in our use case of opensips’s fifo we can see a list of available fifo commands in opensips-cp web interface. This means Apache (opensips-cp) and the opensips can communicates through the fifo file.


OpenSIPS-CP can request the dialog information from OpenSIPS through the fifo file. See the figures below of the early dialog and the confirmed dialog.



Below is a php client which try to connect to opensips fifo file and send commands. Copy the text and save it in opensips-cp/web/Fifotest.php and then call it from the browser /ipaddress/cp/Fifotest.php. Use it to test the fifo connection.

Source: FIFO Client PHP Example