Introduction to TLS and DTLS
****************************

TLS stands for ``Transport Layer Security'' and is the successor of SSL, the Secure Sockets Layer protocol SSL3 designed by Netscape.  TLS is an Internet protocol, defined by IETF (IETF, or Internet Engineering Task Force, is a large open international community of network designers, operators, vendors, and researchers concerned with the evolution of the Internet architecture and the smooth operation of the Internet. It is open to any interested individual.), described in RFC5246. The protocol provides confidentiality, and authentication layers over any reliable transport layer.  The description, above, refers to TLS 1.0 but applies to all other TLS versions as the differences between the protocols are not major.

The DTLS protocol, or ``Datagram TLS'' RFC4347 is a protocol with identical goals as TLS, but can operate under unreliable transport layers such as UDP. The discussions below apply to this protocol as well, except when noted otherwise.

TLS Layers
==========

TLS is a layered protocol, and consists of the record protocol, the handshake protocol and the alert protocol. The record protocol is to serve all other protocols and is above the transport layer.  The record protocol offers symmetric encryption, and data authenticity (In early versions of TLS compression was optionally available as well. This is no longer the case in recent versions of the protocol.). The alert protocol offers some signaling to the other protocols. It can help informing the peer for the cause of failures and other error conditions.  See The Alert Protocol, for more information.  The alert protocol is above the record protocol.

The handshake protocol is responsible for the security parameters' negotiation, the initial key exchange and authentication. See The Handshake Protocol, for more information about the handshake protocol.  The protocol layering in TLS is shown in fig-tls-layers.

Figure: The TLS protocol layers.

The Transport Layer
===================

TLS is not limited to any transport layer and can be used above any transport layer, as long as it is a reliable one.  DTLS can be used over reliable and unreliable transport layers. GnuTLS supports TCP and UDP layers transparently using the Berkeley sockets API. However, any transport layer can be used by providing callbacks for GnuTLS to access the transport layer (for details see Setting up the transport layer).

The TLS record protocol
=======================

The record protocol is the secure communications provider. Its purpose is to encrypt, and authenticate packets. The record layer functions can be called at any time after the handshake process is finished, when there is need to receive or send data. In DTLS however, due to re-transmission timers used in the handshake out-of-order handshake data might be received for some time (maximum 60 seconds) after the handshake process is finished.

The functions to access the record protocol are limited to send and receive functions, which might, given the importance of this protocol in TLS, seem awkward.  This is because the record protocol's parameters are all set by the handshake protocol. The record protocol initially starts with NULL parameters, which means no encryption, and no MAC is used. Encryption and authentication begin just after the handshake protocol has finished.

Encryption algorithms used in the record layer
----------------------------------------------

Confidentiality in the record layer is achieved by using symmetric ciphers like AES or CHACHA20.  Ciphers are encryption algorithms that use a single, secret, key to encrypt and decrypt data. Early versions of TLS separated between block and stream ciphers and had message authentication plugged in to them by the protocol, though later versions switched to using authenticated-encryption (AEAD) ciphers. The AEAD ciphers are defined to combine encryption and authentication, and as such they are not only more efficient, as the primitives used are designed to interoperate nicely, but they are also known to interoperate in a secure way.

The supported in GnuTLS ciphers and MAC algorithms are shown in tab:ciphers and tab:macs.

Algorithm   Type   Applicable Protocols   Description
AES-128-GCM, AES-256-GCM
AEAD
TLS 1.2, TLS 1.3
This is the AES algorithm in the authenticated encryption GCM mode.
This mode combines message authentication and encryption and can
be extremely fast on CPUs that support hardware acceleration.

AES-128-CCM, AES-256-CCM
AEAD
TLS 1.2, TLS 1.3
This is the AES algorithm in the authenticated encryption CCM mode.
This mode combines message authentication and encryption and is
often used by systems without AES or GCM acceleration support.

CHACHA20-POLY1305
AEAD
TLS 1.2, TLS 1.3
CHACHA20-POLY1305 is an authenticated encryption algorithm based on CHACHA20 cipher and
POLY1305 MAC. CHACHA20 is a refinement of SALSA20 algorithm, an approved cipher by
the European ESTREAM project. POLY1305 is Wegman-Carter, one-time authenticator. The
combination provides a fast stream cipher suitable for systems where a hardware AES
accelerator is not available.

AES-128-CCM-8, AES-256-CCM-8
AEAD
TLS 1.2, TLS 1.3
This is the AES algorithm in the authenticated encryption CCM mode
with a truncated to 64-bit authentication tag. This mode is for
communication with restricted systems.

CAMELLIA-128-GCM, CAMELLIA-256-GCM
AEAD
TLS 1.2
This is the CAMELLIA algorithm in the authenticated encryption GCM mode.

AES-128-CBC, AES-256-CBC
Legacy (block)
TLS 1.0, TLS 1.1, TLS 1.2
AES or RIJNDAEL is the block cipher algorithm that replaces the old
DES algorithm.  It has 128 bits block size and is used in CBC mode.

CAMELLIA-128-CBC, CAMELLIA-256-CBC
Legacy (block)
TLS 1.0, TLS 1.1, TLS 1.2
This is an 128-bit block cipher developed by Mitsubishi and NTT. It
is one of the approved ciphers of the European NESSIE and Japanese
CRYPTREC projects.

3DES-CBC
Legacy (block)
TLS 1.0, TLS 1.1, TLS 1.2
This is the DES block cipher algorithm used with triple
encryption (EDE). Has 64 bits block size and is used in CBC mode.

ARCFOUR-128
Legacy (stream)
TLS 1.0, TLS 1.1, TLS 1.2
ARCFOUR-128 is a compatible algorithm with RSA's RC4 algorithm, which is considered to be a trade
secret. It is a considered to be broken, and is only used for compatibility
purposed. For this reason it is not enabled by default.

GOST28147-TC26Z-CNT
Legacy (stream)
TLS 1.2
This is a 64-bit block cipher GOST 28147-89 with TC26Z S-Box working in CNT
mode. It is one of the approved ciphers in Russia. It is not enabled by default.

NULL
Legacy (stream)
TLS 1.0, TLS 1.1, TLS 1.2
NULL is the empty/identity cipher which doesn't encrypt any data. It can be
combined with data authentication under TLS 1.2 or earlier, but is only used
transiently under TLS 1.3 until encryption starts. This cipher cannot be negotiated
by default (need to be explicitly enabled) under TLS 1.2, and cannot be
negotiated at all under TLS 1.3. When enabled, TLS 1.3 (or later) support will be
implicitly disabled.

Table: Supported ciphers in TLS.

Algorithm   Description
MAC-MD5
This is an HMAC based on MD5 a cryptographic hash algorithm designed
by Ron Rivest. Outputs 128 bits of data.

MAC-SHA1
An HMAC based on the SHA1 cryptographic hash algorithm
designed by NSA. Outputs 160 bits of data.

MAC-SHA256
An HMAC based on SHA2-256. Outputs 256 bits of data.

MAC-SHA384
An HMAC based on SHA2-384. Outputs 384 bits of data.

GOST28147-TC26Z-IMIT
This is a 64-bit block cipher GOST 28147-89 with TC26Z S-Box working in special
MAC mode called Imitovstavks. It is one of the approved MAC algorithms in
Russia. Outputs 32 bits of data. It is not enabled by default.

MAC-AEAD
This indicates that an authenticated encryption algorithm, such as
GCM, is in use.

Table: Supported MAC algorithms in TLS.

Compression algorithms and the record layer
-------------------------------------------

In early versions of TLS the record layer supported compression. However, that proved to be problematic in many ways, and enabled several attacks based on traffic analysis on the transported data. For that newer versions of the protocol no longer offer compression, and GnuTLS since 3.6.0 no longer implements any support for compression.

On record padding
-----------------

The TLS 1.3 protocol allows for extra padding of records to prevent statistical analysis based on the length of exchanged messages. GnuTLS takes advantage of this feature, by allowing the user to specify the amount of padding for a particular message. The simplest interface is provided by gnutls_record_send2, and is made available when under TLS1.3; alternatively gnutls_record_can_use_length_hiding can be queried.

Note that this interface is not sufficient to completely hide the length of the data. The application code may reveal the data transferred by leaking its data processing time, or by leaking the TLS1.3 record processing time by GnuTLS. That is because under TLS1.3 the padding removal time depends on the padding data for an efficient implementation. To make that processing constant time the gnutls_init function must be called with the flag GNUTLS_SAFE_PADDING_CHECK.

gnutls_record_send2

Older GnuTLS versions provided an API suitable for cases where the sender sends data that are always within a given range. That API is still available, and consists of the following functions.

gnutls_record_can_use_length_hiding,gnutls_record_send_range

The TLS alert protocol
======================

The alert protocol is there to allow signals to be sent between peers. These signals are mostly used to inform the peer about the cause of a protocol failure. Some of these signals are used internally by the protocol and the application protocol does not have to cope with them (e.g. GNUTLS_A_CLOSE_NOTIFY), and others refer to the application protocol solely (e.g. GNUTLS_A_USER_CANCELLED).  An alert signal includes a level indication which may be either fatal or warning (under TLS1.3 all alerts are fatal). Fatal alerts always terminate the current connection, and prevent future re-negotiations using the current session ID. All supported alert messages are summarized in the table below.

The alert messages are protected by the record protocol, thus the information that is included does not leak. You must take extreme care for the alert information not to leak to a possible attacker, via public log files etc.

     [file alerts.texi not included]

The TLS handshake protocol
==========================

The handshake protocol is responsible for the ciphersuite negotiation, the initial key exchange, and the authentication of the two peers. This is fully controlled by the application layer, thus your program has to set up the required parameters. The main handshake function is gnutls_handshake. In the next paragraphs we elaborate on the handshake protocol, i.e., the ciphersuite negotiation.

TLS ciphersuites
----------------

The TLS cipher suites have slightly different meaning under different protocols. Under TLS 1.3, a cipher suite indicates the symmetric encryption algorithm in use, as well as the pseudo-random function (PRF) used in the TLS session.

Under TLS 1.2 or early the handshake protocol negotiates cipher suites of a special form illustrated by the TLS_DHE_RSA_WITH_3DES_CBC_SHA cipher suite name. A typical cipher suite contains these parameters:

  * The key exchange algorithm. DHE_RSA in the example.

  * The Symmetric encryption algorithm and mode 3DES_CBC in this example.

  * The MAC (MAC stands for Message Authentication Code. It can be described as a keyed hash algorithm. See RFC2104.) algorithm used for authentication. MAC_SHA is used in the above example.

The cipher suite negotiated in the handshake protocol will affect the record protocol, by enabling encryption and data authentication.  Note that you should not over rely on TLS to negotiate the strongest available cipher suite. Do not enable ciphers and algorithms that you consider weak.

All the supported ciphersuites are listed in ciphersuites.

Authentication
--------------

The key exchange algorithms of the TLS protocol offer authentication, which is a prerequisite for a secure connection. The available authentication methods in GnuTLS, under TLS 1.3 or earlier versions, follow.

  * Certificate authentication: Authenticated key exchange using public key infrastructure and X.509 certificates.

  * PSK authentication: Authenticated key exchange using a pre-shared key.

Under TLS 1.2 or earlier versions, the following authentication methods are also available.

  * SRP authentication: Authenticated key exchange using a password.

  * Anonymous authentication: Key exchange without peer authentication.

Client authentication
---------------------

In the case of ciphersuites that use certificate authentication, the authentication of the client is optional in TLS.  A server may request a certificate from the client using the gnutls_certificate_server_set_request function. We elaborate in Certificate credentials.

Resuming sessions
-----------------

The TLS handshake process performs expensive calculations and a busy server might easily be put under load. To reduce the load, session resumption may be used. This is a feature of the TLS protocol which allows a client to connect to a server after a successful handshake, without the expensive calculations.  This is achieved by re-using the previously established keys, meaning the server needs to store the state of established connections (unless session tickets are used -- Session tickets).

Session resumption is an integral part of GnuTLS, and Session resumption, ex-resume-client illustrate typical uses of it.

TLS extensions
==============

A number of extensions to the TLS protocol have been proposed mainly in TLSEXT. The extensions supported in GnuTLS are discussed in the subsections that follow.

Maximum fragment length negotiation
-----------------------------------

This extension allows a TLS implementation to negotiate a smaller value for record packet maximum length. This extension may be useful to clients with constrained capabilities. The functions shown below can be used to control this extension.

gnutls_record_get_max_size,gnutls_record_set_max_size

Server name indication
----------------------

A common problem in HTTPS servers is the fact that the TLS protocol is not aware of the hostname that a client connects to, when the handshake procedure begins. For that reason the TLS server has no way to know which certificate to send.

This extension solves that problem within the TLS protocol, and allows a client to send the HTTP hostname before the handshake begins within the first handshake packet.  The functions gnutls_server_name_set and gnutls_server_name_get can be used to enable this extension, or to retrieve the name sent by a client.

gnutls_server_name_set,gnutls_server_name_get

Session tickets
---------------

To resume a TLS session, the server normally stores session parameters.  This complicates deployment, and can be avoided by delegating the storage to the client. Because session parameters are sensitive they are encrypted and authenticated with a key only known to the server and then sent to the client. The Session Tickets extension is described in RFC 5077 TLSTKT.

A disadvantage of session tickets is that they eliminate the effects of forward secrecy when a server uses the same key for long time. That is, the secrecy of all sessions on a server using tickets depends on the ticket key being kept secret. For that reason server keys should be rotated and discarded regularly.

Since version 3.1.3 GnuTLS clients transparently support session tickets, unless forward secrecy is explicitly requested (with the PFS priority string).

Under TLS 1.3 session tickets are mandatory for session resumption, and they do not share the forward secrecy concerns as with TLS 1.2 or earlier.

HeartBeat
---------

This is a TLS extension that allows to ping and receive confirmation from the peer, and is described in RFC6520. The extension is disabled by default and gnutls_heartbeat_enable can be used to enable it. A policy may be negotiated to only allow sending heartbeat messages or sending and receiving. The current session policy can be checked with gnutls_heartbeat_allowed. The requests coming from the peer result to GNUTLS_E_HEARTBEAT_PING_RECEIVED being returned from the receive function. Ping requests to peer can be send via gnutls_heartbeat_ping.

gnutls_heartbeat_allowed,gnutls_heartbeat_enable

gnutls_heartbeat_ping,gnutls_heartbeat_pong,gnutls_heartbeat_set_timeouts,gnutls_heartbeat_get_timeout

Safe renegotiation
------------------

TLS gives the option to two communicating parties to renegotiate and update their security parameters. One useful example of this feature was for a client to initially connect using anonymous negotiation to a server, and the renegotiate using some authenticated ciphersuite. This occurred to avoid having the client sending its credentials in the clear.

However this renegotiation, as initially designed would not ensure that the party one is renegotiating is the same as the one in the initial negotiation. For example one server could forward all renegotiation traffic to an other server who will see this traffic as an initial negotiation attempt.

This might be seen as a valid design decision, but it seems it was not widely known or understood, thus today some application protocols use the TLS renegotiation feature in a manner that enables a malicious server to insert content of his choice in the beginning of a TLS session.

The most prominent vulnerability was with HTTPS. There servers request a renegotiation to enforce an anonymous user to use a certificate in order to access certain parts of a web site.  The attack works by having the attacker simulate a client and connect to a server, with server-only authentication, and send some data intended to cause harm.  The server will then require renegotiation from him in order to perform the request. When the proper client attempts to contact the server, the attacker hijacks that connection and forwards traffic to the initial server that requested renegotiation.  The attacker will not be able to read the data exchanged between the client and the server.  However, the server will (incorrectly) assume that the initial request sent by the attacker was sent by the now authenticated client.  The result is a prefix plain-text injection attack.

The above is just one example.  Other vulnerabilities exists that do not rely on the TLS renegotiation to change the client's authenticated status (either TLS or application layer).

While fixing these application protocols and implementations would be one natural reaction, an extension to TLS has been designed that cryptographically binds together any renegotiated handshakes with the initial negotiation.  When the extension is used, the attack is detected and the session can be terminated.  The extension is specified in RFC5746.

GnuTLS supports the safe renegotiation extension.  The default behavior is as follows.  Clients will attempt to negotiate the safe renegotiation extension when talking to servers.  Servers will accept the extension when presented by clients.  Clients and servers will permit an initial handshake to complete even when the other side does not support the safe renegotiation extension.  Clients and servers will refuse renegotiation attempts when the extension has not been negotiated.

Note that permitting clients to connect to servers when the safe renegotiation extension is not enabled, is open up for attacks. Changing this default behavior would prevent interoperability against the majority of deployed servers out there.  We will reconsider this default behavior in the future when more servers have been upgraded. Note that it is easy to configure clients to always require the safe renegotiation extension from servers.

To modify the default behavior, we have introduced some new priority strings (see Priority Strings). The %UNSAFE_RENEGOTIATION priority string permits (re-)handshakes even when the safe renegotiation extension was not negotiated. The default behavior is %PARTIAL_RENEGOTIATION that will prevent renegotiation with clients and servers not supporting the extension. This is secure for servers but leaves clients vulnerable to some attacks, but this is a trade-off between security and compatibility with old servers. The %SAFE_RENEGOTIATION priority string makes clients and servers require the extension for every handshake. The latter is the most secure option for clients, at the cost of not being able to connect to legacy servers. Servers will also deny clients that do not support the extension from connecting.

It is possible to disable use of the extension completely, in both clients and servers, by using the %DISABLE_SAFE_RENEGOTIATION priority string however we strongly recommend you to only do this for debugging and test purposes.

The default values if the flags above are not specified are:

Server:
     %PARTIAL_RENEGOTIATION

Client:
     %PARTIAL_RENEGOTIATION

For applications we have introduced a new API related to safe renegotiation.  The gnutls_safe_renegotiation_status function is used to check if the extension has been negotiated on a session, and can be used both by clients and servers.

OCSP status request
-------------------

The Online Certificate Status Protocol (OCSP) is a protocol that allows the client to verify the server certificate for revocation without messing with certificate revocation lists. Its drawback is that it requires the client to connect to the server's CA OCSP server and request the status of the certificate. This extension however, enables a TLS server to include its CA OCSP server response in the handshake. That is an HTTPS server may periodically run ocsptool (see ocsptool Invocation) to obtain its certificate revocation status and serve it to the clients. That way a client avoids an additional connection to the OCSP server.

See OCSP stapling for further information.

Since version 3.1.3 GnuTLS clients transparently support the certificate status request.

SRTP
----

The TLS protocol was extended in RFC5764 to provide keying material to the Secure RTP (SRTP) protocol. The SRTP protocol provides an encapsulation of encrypted data that is optimized for voice data. With the SRTP TLS extension two peers can negotiate keys using TLS or DTLS and obtain keying material for use with SRTP. The available SRTP profiles are listed below.

gnutls_srtp_profile_t,Supported SRTP profiles

To enable use the following functions.

gnutls_srtp_set_profile,gnutls_srtp_set_profile_direct

To obtain the negotiated keys use the function below.

gnutls_srtp_get_keys

Other helper functions are listed below.

gnutls_srtp_get_selected_profile,gnutls_srtp_get_profile_name,gnutls_srtp_get_profile_id

False Start
-----------

The TLS protocol was extended in RFC7918 to allow the client to send data to server in a single round trip. This change however operates on the borderline of the TLS protocol security guarantees and should be used for the cases where the reduced latency outperforms the risk of an adversary intercepting the transferred data. In GnuTLS applications can use the GNUTLS_ENABLE_FALSE_START as option to gnutls_init to request an early return of the gnutls_handshake function. After that early return the application is expected to transfer any data to be piggybacked on the last handshake message.

After handshake's early termination, the application is expected to transmit data using gnutls_record_send, and call gnutls_record_recv on any received data as soon, to ensure that handshake completes timely. That is, especially relevant for applications which set an explicit time limit for the handshake process via gnutls_handshake_set_timeout.

Note however, that the API ensures that the early return will not happen if the false start requirements are not satisfied. That is, on ciphersuites which are not enabled for false start or on insufficient key sizes, the handshake process will complete properly (i.e., no early return). To verify that false start was used you may use gnutls_session_get_flags and check for the GNUTLS_SFLAGS_FALSE_START flag. For GnuTLS the false start is enabled for the following key exchange methods (see RFC7918 for rationale)

  * DHE

  * ECDHE

but only when the negotiated parameters exceed GNUTLS_SEC_PARAM_HIGH --see tab:key-sizes, and when under (D)TLS 1.2 or later.

Application Layer Protocol Negotiation (ALPN)
---------------------------------------------

The TLS protocol was extended in RFC7301 to provide the application layer a method of negotiating the application protocol version. This allows for negotiation of the application protocol during the TLS handshake, thus reducing round-trips. The application protocol is described by an opaque string. To enable, use the following functions.

gnutls_alpn_set_protocols,gnutls_alpn_get_selected_protocol

Note that these functions are intended to be used with protocols that are registered in the Application Layer Protocol Negotiation IANA registry. While you can use them for other protocols (at the risk of collisions), it is preferable to register them.

Extensions and Supplemental Data
--------------------------------

It is possible to transfer supplemental data during the TLS handshake, following RFC4680. This is for "custom" protocol modifications for applications which may want to transfer additional data (e.g. additional authentication messages). Such an exchange requires a custom extension to be registered. The provided API for this functionality is low-level and described in TLS Hello Extension Handling.

     [file sec-tls-app.texi not included]

On SSL 2 and older protocols
============================

One of the initial decisions in the GnuTLS development was to implement the known security protocols for the transport layer. Initially TLS 1.0 was implemented since it was the latest at that time, and was considered to be the most advanced in security properties.  Later the SSL 3.0 protocol was implemented since it is still the only protocol supported by several servers and there are no serious security vulnerabilities known.

One question that may arise is why we didn't implement SSL 2.0 in the library.  There are several reasons, most important being that it has serious security flaws, unacceptable for a modern security library.  Other than that, this protocol is barely used by anyone these days since it has been deprecated since 1996.  The security problems in SSL 2.0 include:

  * Message integrity compromised. The SSLv2 message authentication uses the MD5 function, and is insecure.

  * Man-in-the-middle attack. There is no protection of the handshake in SSLv2, which permits a man-in-the-middle attack.

  * Truncation attack. SSLv2 relies on TCP FIN to close the session, so the attacker can forge a TCP FIN, and the peer cannot tell if it was a legitimate end of data or not.

  * Weak message integrity for export ciphers. The cryptographic keys in SSLv2 are used for both message authentication and encryption, so if weak encryption schemes are negotiated (say 40-bit keys) the message authentication code uses the same weak key, which isn't necessary.

Other protocols such as Microsoft's PCT 1 and PCT 2 were not implemented because they were also abandoned and deprecated by SSL 3.0 and later TLS 1.0.