Skip to content

TLSAuthentication

Scott Godin edited this page Jan 29, 2021 · 1 revision

Table of Contents

Introduction

reSIProcate aims to provide a solid basis for inter-domain routing of SIP messages with a high degree of trust to ensure that caller ID is authentic. It achieves this using TLS, especially what is documented in RFC 5922.

This page discusses all aspects of TLS in reSIProcate and repro:

  • Acting as a TLS server
  • Optionally accepting (or demanding) client certificates from TLS clients (new from v1.8)
  • Acting as a TLS client: inspecting the remote cert, and sending a `client' cert for mutual authentication if requested by the server

The transport layer TLS

  • Much of the work is done by OpenSSL
  • TLS v1 is the default for repro

reSIProcate, DUM and repro as a TLS server

  • the traditional behavior of the stack involves loading all certs from a single directory. CA root certs are in files matching the pattern root_cert_*.pem, our server certs must be in files matching the pattern domain_cert_.pem
  • from 1.8, the CA root certs can be loaded from a separate directory (e.g. /etc/ssl/certs/* on Debian)

Accepting connections from TLS clients with certificates

  • client certificates can be ignored, optional, or mandatory
  • if `optional', and if the client sends a cert, the cert must pass all the tests or their request will be rejected

Checking the peer certificate

  • we make no distinction whether the peer is a TLS client or TLS server
  • at connection setup, transport layer checking of a peer's client or server cert is done (e.g. checking the expiry date, checking the CA is trusted)
  • for each SIP message received, and regardless of whether the connection is client or server mode, the stack can check each message that it receives against the cert (e.g. to validate the From: header)
  • in practice, the resip::TlsPeerAuthManager (in dum) and repro::CertificateAuthenticator (in repro) are checking the From: header of every SIP message from the peer, these classes can be subclasses to implement other checks
  • furthermore, they support two types of checks on the From: header/certificate, (a) for a domain cert, any user is permitted and (b) for a peer using a URI in their cert (e.g. bob@example.org), only the exact URI will be permitted in the From: header

Mapping/permissioning TLS peers for additional identities

  • Sometimes the device has a certificate with a CN that does not match the user identity (`From:' header value)
  • Case study: Polycom phones
    • Extremely good provisioning system based on TLS
    • Every phone has a built in X.509 client certificate created at the factory
    • In the certificate, the Common Name (CN) value is the MAC address of the phone
  • As of repro 1.8.5 (and on trunk), it is possible to create mappings from CN (such as the Polycom MAC addresses) to actual SIP IDs
  • In repro.config, define CommonNameMappings, e.g:
 CommonNameMappings = /etc/repro/tlsUserMappings.txt
  • In the mappings file, the format is very precise. Each line must have exactly the following:
    • the CN from the phone certificate (e.g. the MAC address)
    • a TAB symbol
    • the permitted user ID, or multiple user IDs, separated by commas
  • the permitted user ID can be either user@domain, or just a domain
    • if a domain is given, then the device with the certificate can use any SIP ID in that domain
  • Here is a sample for a Polycom phone:
 0004F22B3EB5	alice@example.org
 0004F224A6AC	bob@example.org,eve@example.org
 0004F2266D79	pocock.com.au

Analysis

Here are some permutations of how the TLS authentication options work together:

DIGEST auth X.509 auth Client mode challange 3rd party Client certs Client type From(MyDomain) Result
N N n/a n/a n/a n/a n/a No checks done
Y N n/a n/a n/a n/a n/a should work as before
N Y Optional n/a n/a n/a n/a t.b.c.
Y Y Optional n/a N user Y User challenged
Y Y Optional n/a Y user Y Cert must be valid, user challenged too
Y Y Optional n N 3rd party N Rejected, must present a cert proving domain ownership
Y Y Optional n Y 3rd party N Each message accepted iff `From:' domain matches cert

The gotchas

  • if the peer is a trusted proxy, a reSIProcate instance may NOT want to apply From: header filtering. For example, if reSIProcate is used to create a softphone, the trusted proxy may be receiving SIP messages from the outside world (from any arbitrary domain), verifying the source is good, and then relaying them to the softphone. In this case, reSIProcate should not match the From: header against the proxy's TLS certificate.
  • not all devices send their domain or username. E.g. a Polycom phone sends it's MAC address in the common name of the client certificate. In this case, a subclass of resip::TlsPeerAuthManager would need to know how to map the MAC addresses to authorized identities (perhaps an async database lookup)
  • an email certificate is not automatically trusted, as the email address in the subjectAltName is ONLY officially valid for email. A hack is available (useEmailAsSIP) that allows these certificates to be treated as if they contained SIP URIs.

Future work in this area

  • support Extended Key Usage (EKU)
  • async framework for authorization checks (authorizedForThisIdentity method)
  • async framework for mapping lookups
  • storing mappings in BDB
  • separate specification of CA roots trusted for each TLS connection and/or for client or server mode
  • more sophisticated rules for giving different rights to different users based on the CA who signed their cert

Likely TLS peers

  • Other instances of repro connecting to each other
  • Jitsi supports client certificates - see ReproMutualTLSAuthenticationJitsi for detailed setup guide
  • Kamailio is a SIP proxy with good TLS support
  • OpenSIPS and Asterisk have basic TLS support (not full RFC 5922)
  • Polycom phones all have built in client certificates, and they will automatically send the cert if asked for it
  • Lumicall

Testing manually

Various command line utilities exist for simulating TLS connections and feeding in SIP messages with cut and paste:

  • openssl s_client
  • openssl s_server
  • gnutls-cli
  • gnutls-serv
Clone this wiki locally