eric-brechemier / how-i-replaced-skype-with-twilio

How I replaced Skype with Twilio to make phone calls from my computer
Creative Commons Attribution 4.0 International
42 stars 8 forks source link

Calls are not encrypted #8

Closed eric-brechemier closed 2 years ago

eric-brechemier commented 5 years ago

Twilio does not currently support encryption of calls registered with Twilio's endpoint. Encrypted transport is only supported with SIP trunking:

NOTE: Twilio does not support SRTP on SIP Interface. SRTP is supported on Elastic SIP Trunking. — https://www.twilio.com/docs/voice/api/sip-making-calls#transport

AmIJesse commented 3 years ago

Twilio does appear to support call encryption now, under the sip domain settings you can enable "Secure Media", and enable "SRTP" and "Mandatory Encryption" under linphone's "Calls abd Chat" settings.

eric-brechemier commented 3 years ago

@AmIJesse Thank you for the heads-up. I'll try it out.

eric-brechemier commented 2 years ago

Secure Media

Secure Media uses encryption to ensure that the call media and associated signaling remains private during transmission. Transport Layer Security (TLS) provides encryption for SIP signaling. Secure Real-time Transport Protocol (SRTP) provides encryption for call content/media packets.

SRTP provides a framework for the encryption of RTP & RTCP. RFC 4568, Session Description Protocol (SDP) Security Description (SDES) for Media Streams, defines such a protocol specifically designed to exchange cryptographic material using a newly defined SDP crypto attribute.


Inbound:

You can enable or disable Secure Media in your SIP Domain. It is disabled by default.

You can expect the following:

  • Enabled: TLS must be used to encrypt SIP messages and SRTP must be used for the media packets. Any non-encrypted calls will be rejected.
  • Disabled: RTP must be used for media packets. SIP messages may be sent in the clear or using TLS. Any SRTP encrypted calls will be rejected.

info

  • *SRTP supports the following crypyto suites: AES_CM_128_HMAC_SHA1_80 and AES_CM_128_HMAC_SHA1_32. Both may be included in an order of preference.**
  • *The optional master key identifier (MKI) parameter is not supported**

Outbound:

Ensure you configure secure=true parameter as part of SIP URI to secure media in SIP outbound calls.

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Dial>
    <Sip>sip:jack@example.com;secure=true</Sip>
  </Dial>
</Response>

The default port 5061 will be used for TLS.

info

  • Only a single crypto suite for SRTP will be included: AES_CM_128_HMAC_SHA1_80
  • The optional master key identifier (MKI) parameter is not supported

Importing Twilio's Root CA Certificate

TLS is used to encrypt SIP signaling between SIP endpoints. In order for this to function properly, it is required that certain devices in your network import an SSL certificate. Twilio uses certificates from a CA (Certificate Authority). It is important that you add the following root certificate to your communications infrastructure to establish its authenticity on the network. Download Twilio's CA certificate.

It is important to note that Twilio uses a wildcard certificate which can be used for multiple subdomains of a domain (*.sip.twilio.com). If your network element does not support wild carded certificates please disable certificate validation. (...) — https://www.twilio.com/docs/voice/api/secure-media

eric-brechemier commented 2 years ago

Also:

Transport

Set a parameter on your SIP URI to specify what transport protocol you want to use. Currently, this is limited to UDP, TCP and TLS. By default, Twilio sends your SIP INVITE over UDP. Change this by using the transport parameter:

<?xml version="1.0" encoding="UTF-8"?>

sip:jack@example.com;transport=tcp

Alternatively, you may customize it to use TLS for SIP signaling. When using TLS, the default port will be 5061 however, a different one may be specified.

<?xml version="1.0" encoding="UTF-8"?>

sip:jack@example.com;transport=tls

https://www.twilio.com/docs/voice/twiml/sip#transport

eric-brechemier commented 2 years ago

I have updated the corresponding section of the step by step setup:

Create a SIP Domain

(…)

  1. Under Secure Media, click the Disabled button to encrypt SIP registration and calls, deterring eavesdropping:

Secure Media Enabled

eric-brechemier commented 2 years ago

I have also added instructions to configure call encryption in Linphone. The option to send SIP registration over TLS was already selected.

Connect to SIP from your Computer

(…)

  1. Open Linphone > Preferences > Calls and Chat.

  2. Under Calls, click the SRTP button. I also chose to make encryption mandatory, just to make sure.

Call Encryption Settings in Linphone

Note: Twilio will neither accept unencrypted calls on a domain where encryption has been enabled, nor encrypted calls on a domain where it has not been enabled. Once encryption has been enabled for a SIP domain, you have to use it, otherwise all your calls will get rejected.

eric-brechemier commented 2 years ago

With these two changes, SIP registrations and calls are now expected to be encrypted.

eric-brechemier commented 2 years ago

Linphone shows outgoing calls as encrypted with SRTP:

outgoing-call-encrypted
eric-brechemier commented 2 years ago

As noted by user _Eduardosquidwardo on Reddit, the Encryption is mandatory option must not be selected at this point.

Otherwise, incoming calls are rejected by Linphone, which answers:

SIP/2.0 488 Not acceptable here

after the SDP offer/answer process fails:

Doing SDP offer/answer process of type incoming
Declining mline 0, no corresponding stream in local capabilities description.

While when Encryption is mandatory is disabled, the SDP offer/answer process succeeds with:

Doing SDP offer/answer process of type incoming
Found matching configurations: local configuration index 0 remote offered configuration index 0
eric-brechemier commented 2 years ago

Linphone shows that incoming calls are not encrypted:

incoming-call-not-encrypted
eric-brechemier commented 2 years ago

I have disabled Encryption is mandatory option for now, until I find how to encrypt incoming calls as well.

Connect to SIP from your Computer

(…)

If you choose to make encryption mandatory, incoming calls will get rejected unless they are encrypted as well. This option must not be checked at this point.

Encryption is not mandatory

eric-brechemier commented 2 years ago

This is the behavior described in the Secure Media documentation.

The Secure Media option of SIP domains applies to inbound calls only. When enabled, SRTP encryption must be used by the Linphone client, or calls will get rejected.

For outbound calls, an extra parameter must be included in the <Sip> URL of the <Dial> verb in TwiML:

Ensure you configure secure=true parameter as part of SIP URI to secure media in SIP outbound calls.

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Dial>
    <Sip>sip:jack@example.com;secure=true</Sip>
  </Dial>
</Response>
eric-brechemier commented 2 years ago

After this change in the TwiML Bin Receiving Calls from Regular Phones to SIP, incoming calls are now encrypted with SRTP as well:

incoming-call-is-encrypted-with-srtp

It becomes possible to make encryption mandatory, and incoming calls are no longer rejected, since they are encrypted:

encryption-is-mandatory
eric-brechemier commented 2 years ago

Two parameters must be set in the SIP URL:

eric-brechemier commented 2 years ago

Including both parameters in the URL leads the call to fail, when Linphone requires encryption, in the same as when no call encryption was applied:

2022-02-19 19:58:44:083 [linphone/liblinphone] MESSAGE Doing SDP offer/answer process of type incoming
2022-02-19 19:58:44:083 [linphone/liblinphone] MESSAGE Declining mline 0, no corresponding stream in local capabilities description.

and disabling this requirement, the incoming call is no longer encrypted.

It thus appears that usage of secure=true, described in the Secure Media documentation, is superseding the more limited transport=tls parameter described in the documentation of the TwiML <Sip> noun.

I'll use secure=true alone from this point.

eric-brechemier commented 2 years ago

Calls are now encrypted.

eric-brechemier commented 2 years ago

I combined SIP parameters with &amp; instead of ;. Let's try again.

The format of SIP URLs is described in RFC 2543:

  SIP-URL         = "sip:" [ userinfo "@" ] hostport
                    url-parameters [ headers ]
  userinfo        = user [ ":" password ]
  user            = *( unreserved | escaped
                  | "&" | "=" | "+" | "$" | "," )
  password        = *( unreserved | escaped
                  | "&" | "=" | "+" | "$" | "," )
  hostport        = host [ ":" port ]
  host            = hostname | IPv4address
  hostname        = *( domainlabel "." ) toplabel [ "." ]
  domainlabel     = alphanum | alphanum *( alphanum | "-" ) alphanum
  toplabel        = alpha | alpha *( alphanum | "-" ) alphanum
  IPv4address     = 1*digit "." 1*digit "." 1*digit "." 1*digit
  port            = *digit
  url-parameters  = *( ";" url-parameter )
  url-parameter   = transport-param | user-param | method-param
                  | ttl-param | maddr-param | other-param
  transport-param = "transport=" ( "udp" | "tcp" )
  ttl-param       = "ttl=" ttl
  ttl             = 1*3DIGIT       ; 0 to 255
  maddr-param     = "maddr=" host
  user-param      = "user=" ( "phone" | "ip" )
  method-param    = "method=" Method
  tag-param       = "tag=" UUID
  UUID            = 1*( hex | "-" )
  other-param     = ( token | ( token "=" ( token | quoted-string )))
  headers         = "?" header *( "&" header )
  header          = hname "=" hvalue
  hname           = 1*uric
  hvalue          = *uric
  uric            = reserved | unreserved | escaped
  reserved        = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
                    "$" | ","
  digits          = 1*DIGIT

   Figure 3: SIP URL syntax
eric-brechemier commented 2 years ago

Both parameters can be included in this way:

<Sip>sip:jack@example.com;transport=tls;secure=true</Sip>

The previous form resulted in invalid parameter values:

transport: tls&secure=true

or

secure: true&transport=tls
eric-brechemier commented 2 years ago

I updated the description of Linphone client setup, adding the possibility to make encryption of inbound calls required.

Connect to SIP from your Computer

(…)

  1. I also chose to make encryption mandatory. This check applies to incoming calls. When this check is enabled, incoming calls will get rejected unless they are encrypted as well. Leaving the check disabled allows to receive incoming calls even if they were sent encrypted. We will configure our bridge to always encrypt incoming calls, so it's up to you.

Encryption is not mandatory

Encryption is mandatory

eric-brechemier commented 2 years ago

I also updated the description of the steps to configure the TwiML Bin script Receiving Phone Calls from Regular Phones to SIP:

Receiving Calls

(…)

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Dial>
    <Sip>sip:me@1-202-555-0162.sip.us1.twilio.com;transport=tls;secure=true</Sip>
  </Dial>
</Response>

(…)

New TwiML Bin Receiving Calls from Regular Phones to SIP

eric-brechemier commented 2 years ago

@AmIJesse Thanks! Starting from your input, I have finally made the changes to successfully encrypt phone calls.