STARTTLS Documentation

From the makers of InspIRCd.
Jump to: navigation, search

What Is STARTTLS?

STARTTLS is a protocol feature commonly found in e-mail protocols, which allows SSL and plaintext connections to co-exist on the same port. This is useful as it simplifies firewall rules (only requiring one port to be opened rather than two) and adds user-friendliness as the user must only know one port (in IRC's case, port 6667). On InspIRCd, the STARTTLS extension requires m_cap.so and m_ssl_gnutls.so.

IRC STARTTLS is an open standard, and we encourage all client developers and IRC Daemon developers to implement it where possible, to provide more choice for users. This protocol is fairly easy to implement if your client/ircd already supports SSL, and even easier if it also already supports the CAP extension.

How does it work?

To use STARTTLS a client simply sends STARTTLS to the server before the client registers with the server using the NICK and USER commands. After sending this command both client and server switch to TLS/SSL mode, based upon the plaintext numeric reply generated by the STARTTLS command, and cannot switch back to plain text mode. The client must then send an SSL/TLS handshake to the server and the connection continues in the same manner as one on a dedicated SSL port (such as 6697).

What is TLS, compared to SSL?

TLS is a newer name for the SSL protocol suite. Both protocols are inter-operable and a client may use OpenSSL, for example, to implement the STARTTLS protocol.

How can an IRC client discover support for STARTTLS?

There are two different methods for discovering STARTTLS support, each with advantages and disadvantages

Discovery via CAP

There is a somewhat standardized method of determining server capabilities, called the CAP extension which is implemented in ratbox and all derivatives, and InspIRCd and derivatives. CAP is also under consideration by the Undernet and IRCNet developers. Sending 'CAP LS' to enumerate the capabilities of the server (before client registration) will return the tls capability in the list if STARTTLS is available.

It is important to note that if m_cap is not loaded on an InspIRCd server, or a server does not support CAP at all, then CAP LS will generate no output. The client author must send the normal PASS/USER/NICK immediately following the CAP LS command to handle this case.

It is worth noting here that a client may request the tls capability with CAP REQ, but this will do nothing. The STARTTLS command will operate on servers which advertise the capability regardless of if the client requests the capability or not. This is to keep compatibility with version 1.1 of this specification.

Example session where TLS is discovered

<< :test2.chatspike.net NOTICE Auth :*** Looking up your hostname...
<< :test2.chatspike.net NOTICE Auth :*** Found your hostname (brainwave.brainbox.cc) -- cached
>> CAP LS
>> NICK :Brain
>> USER Brain * * :Test user
<< :test2.chatspike.net CAP * LS :sasl userhost-in-names tls multi-prefix
>> STARTTLS
<< :test2.chatspike.net 670 nickname :STARTTLS successful, go ahead with TLS handshake

           (tls handshake goes here)

>> CAP END

After receiving the 670 numeric, the client immediately sends the TLS handshake, which will cause the server to respond in a similar fashion.

If there was a failure initializing TLS, you would instead receive the 691 numeric:

<< :test2.chatspike.net 691 nickname :STARTTLS failure
>> CAP END

Forced request

With automatic discovery, it is possible for an attacker to strip the tls indicator from the TCP stream and/or forge a 691 reply to the STARTTLS command, forcing a fallback to plaintext. Additionally, the server password must be sent in the clear to support servers that do not respond to CAP LS.

If it is known that a specific server supports STARTTLS (for example, by the user choosing STARTTLS as an option when connecting, or possibly a cached value from previous connections to the server), then the STARTTLS command can be sent as the first command to the server. If the client does not get a 670 response from the server, the connection should be aborted and an error presented to the user.

Example session where TLS is used

<< :test2.chatspike.net NOTICE Auth :*** Looking up your hostname...
>> STARTTLS
<< :test2.chatspike.net NOTICE Auth :*** Found your hostname (brainwave.brainbox.cc)
<< :test2.chatspike.net 670 nickname :STARTTLS successful, go ahead with TLS handshake

           (tls handshake goes here)

>> PASS :verysecret
>> NICK :Brain

After receiving the 670 numeric, the client immediately sends the TLS handshake, which will cause the server to respond in a similar fashion.

Recommended Client Interface

  • Clients should allow the user to specify that TLS be used to connect to a server. This should be an option when setting up servers, similar to the interface that allows specifying that a port requires SSL.
  • If a user has requested that TLS be used, the client must use TLS to connect or clearly warn the user if the TLS session setup fails. Otherwise, the client is vulnerable to a downgrade attack: an attacker can remove the STARTTLS request from the stream sent to the server and/or remove the TLS capabilities from the text sent by the server.
  • If a user does not specify that TLS be used to connect, the client may attempt to negotiate a TLS session automatically by querying for the tls CAP. If this automatic negotiation succeeds, an option for the user to require TLS on all future connections to the server may be useful.
  • A server may optionally advertise a STARTTLS token in the RPL_ISUPPORT (005) numeric after registration, if STARTTLS is supported. Client authors should not use this as a facility for detecting STARTTLS in any way if they intend to use it. This would introduce a dangerous security hole by leaking server passwords etc. It is purely informational, for users and simple statistics bots to gather information from.

Handling errors

  • In the case that the STARTTLS command fails, it is the client author's responsibility to make the user completely aware that their connection is still plaintext and they should exercise caution. It is recommended that an option to disconnect (even so far as to be made the default behaviour) should be provided in this case.
  • In the case that the 691 error numeric is received, the client should take action to warn the user that their connection will not be secured, or potentially take other automatic action such as disconnecting from the server to avoid plaintext, or reconnecting to a dedicated SSL port.
  • If CAP negotiation has been used to verify TLS support, it is relatively safe for the client to wait after STARTTLS for one of the 670 or 691 numerics, as one or the other can always be guaranteed as a response from the STARTTLS command if it exists.
  • If a client tries to send STARTTLS more than once, the duplicate requests will generate the 691 numeric for TLS failure.
  • If an error occurs and the user has specified an absolute requirement on TLS/SSL, then the client should reconnect to a dedicated SSL port if available, or not connect at all without the user reconfiguring the client.

Clients With STARTTLS Support

External references

Versions

  1. Version 1.0 - Initial revision 24 July 2008
  2. Version 1.1 - Change failure numeric from 671 to 691 to resolve conflict with unreal's SSL numeric 31 December 2008
  3. Version 1.2 - Clarify the difference between automatic discovery of TLS and forced use, relax the ordering restriction to avoid forcing a timeout on servers not supporting CAP. 16 February 2010