[gnutls-devel] GnuTLS | Non-conforming cookie computation (#1240)

Read-only notification of GnuTLS library development activities gnutls-devel at lists.gnutls.org
Sun May 16 15:56:41 CEST 2021

Paul created an issue: https://gitlab.com/gnutls/gnutls/-/issues/1240

## Description of problem:

The [RFC](https://www.rfc-editor.org/rfc/rfc6347.html#page-17) states the following on computing the cookie:

>   When responding to a HelloVerifyRequest, the client MUST use the same
>   parameter values (version, random, session_id, cipher_suites,
>   compression_method) as it did in the original ClientHello.  The
>   server SHOULD use those values to generate its cookie and verify that
>   they are correct upon cookie receipt. 
>  ...
>  Cookie = HMAC(Secret, Client-IP, Client-Parameters)

According to our testing, the DTLS server applications provided with GnuTLS (e.g. udp_serv.c) do not use  supported cipher suites to compute a cookie from the first Client Hello received from the client. From looking at the source code of [udp_serv.c](https://gitlab.com/gnutls/gnutls/-/blob/fec8a392591f0d8d048b2d60e8873535ef130279/src/udp-serv.c#L129), it appears only the peer address is used, and none of the ClientHello parameters. This leads to situation where the first ClientHello can have different values for these parameters compared to the second ClientHello. For example, it allows for the interaction:

* -> ClientHello(supportedCipherSuites=TLS_ECDHE...)
* <- HelloVerifyRequest
* -> ClientHello(supportedCipherSuites=TLS_PSK...)
* <- ServerHello

This is a minor non-conformance, since cookie exchange in this form still prevents Denial of Service. The library method which generates the cookie [`gnutls_dtls_cookie_send` ](https://gitlab.com/gnutls/gnutls/-/blob/fec8a392591f0d8d048b2d60e8873535ef130279/lib/dtls.c#L839) has a `client_data` buffer parameter used to compute the cookie. Including in it ClientHello parameters would make cookie computation conform to the standard. 

## Version of gnutls used:

## Operating System
Ubuntu 20

## How reproducible:
I attached files necessary for reproduction (see reproduction.tar.gz) using [DTLS-Fuzzer](https://github.com/assist-project/dtls-fuzzer/). Also included in the archive is a capture of the interaction similar to the one described. DTLS-Fuzzer requires  the JDK for Java 8. On Ubuntu, this can be installed  by running:
`sudo apt-get install openjdk-8-jdk`

Unpack the archive, `cd` to resulting folder and run `bash reproduce.sh`, while running an instance of Wireshark on the side. The reproduction script will: 
* setup DTLS-Fuzzer;
* launch gnutls-serv utility (it is assumed the correct version of GnuTLS is already installed)
* launch DTLS-Fuzzer to execute input sequence found in 'test_sequence', upon which DTLS-Fuzzer will send two ClientHellos with different supported cipher suites. 

## Actual results:
The server generates ServerHello, ServerHelloDone, despite having received ClientHello messages with different parameters.

## Expected results:
If the RFC had been followed, the second ClientHello should have been rejected


Reply to this email directly or view it on GitLab: https://gitlab.com/gnutls/gnutls/-/issues/1240
You're receiving this email because of your account on gitlab.com.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.gnupg.org/pipermail/gnutls-devel/attachments/20210516/6f623b42/attachment-0001.html>

More information about the Gnutls-devel mailing list