So CVE-2020-13777 came out while I wasn't looking last week. The GnuTLS advisory (GNUTLS-SA-2020-06-03) is pretty opaque so I'll refer instead to this tweet from @FiloSottile (Go team security lead):

PSA: don't rely on GnuTLS, please.

CVE-2020-13777 Whoops, for the past 10 releases most TLS 1.0–1.2 connection could be passively decrypted and most TLS 1.3 connections intercepted. Trivially.

Also, TLS 1.2–1.0 session tickets are awful.

You are reading this correctly: supposedly encrypted TLS connections made with affected GnuTLS releases are vulnerable to passive cleartext recovery attack (and active for 1.3, but who uses that anyways). That is extremely bad. It's pretty close to just switching everyone to HTTP instead of HTTPS, more or less. I would have a lot more to say about the security of GnuTLS in particular -- and security in general -- but I am mostly concerned about patching holes in the roof right now, so this article is not about that.

This article is about figuring out what, exactly, was exposed in our infrastructure because of this.

  1. Affected packages
  2. Not affected
  3. Caveats
  4. Other technical details
  5. Moving forward

Affected packages

Assuming you're running Debian, this will show a list of packages that Depends on GnuTLS:

apt-cache --installed rdepends libgnutls30 | grep '^ ' | sort -u

This assumes you run this only on hosts running Buster or above. Otherwise you'll need to figure out a way to pick machines running GnuTLS 3.6.4 or later.

Note that this list only first level dependencies! It is perfectly possible that another package uses GnuTLS without being listed here. For example, in the above list I have libcurl3-gnutls, so the be really thorough, I would actually need to recurse down the dependency tree.

On my desktop, this shows an "interesting" list of targets:

Arguably, fetchers like apt, curl, fwupd, and wget rely on HTTPS for "authentication" more than secrecy, although apt has its own OpenPGP-based authentication so that wouldn't matter anyways. Still, this is truly distressing. And I haven't mentioned here things like gobby, network-manager, systemd, and others - the scope of this is broad. Hell, even good old lynx links against GnuTLS.

In our infrastructure, the magic command looks something like this:

cumin -o txt -p 0  'F:lsbdistcodename=buster' "apt-cache --installed rdepends libgnutls30 | grep '^ ' | sort -u" | tee gnutls-rdepds-per-host | awk '{print $NF}' | sort | uniq -c | sort -n

There, the result is even more worrisome, as those important packages seem to rely on GnuTLS for their transport security:

mandos is especially distressing although it's probably not vulnerable because it seems it doesn't store the cleartext -- it's encrypted with the client's OpenPGP public key -- so the TLS tunnel never sees the cleartext either.

Other reports have also mentioned the following servers link against GnuTLS and could be vulnerable:

Not affected

Those programs are not affected by this vulnerability:

This list is not exhaustive, naturally, but serves as an example of common software you don't need to worry about.

The vulnerability only exists in GnuTLS, as far as we know, so programs linking against other libraries are not vulnerable.

Because the vulnerability affects session tickets -- and those are set on the server side of the TLS connection -- only users of GnuTLS as a server are vulnerable. This means, for example, that while weechat uses GnuTLS, it will only suffer from the problem when acting as a server (which it does, in relay mode) or, of course, if the remote IRC server also uses GnuTLS. Same with apt, curl, wget, or git: it is unlikely to be a problem because it is only used as a client; the remote server is usually a webserver -- not git itself -- when using TLS.

Caveats

Keep in mind that it's not because a package links against GnuTLS that it uses it. For example, I have been told that, on Arch Linux, if both GnuTLS and OpenSSL are available, the mutt package will use the latter, so it's not affected. I haven't confirmed that myself nor have I checked on Debian.

Also, because it relies on session tickets, there's a time window after which the ticket gets cycled and properly initialized. But that is apparently 6 hours by default so it is going to protect only really long-lasting TLS sessions, which are uncommon, I would argue.

My audit is limited. For example, it might have been better to walk the shared library dependencies directly, instead of relying on Debian package dependencies.

Other technical details

It seems the vulnerability might have been introduced in this merge request, itself following a (entirely reasonable) feature request to make it easier to rotate session tickets. The merge request was open for a few months and was thoroughly reviewed by a peer before being merged. Interestingly, the vulnerable function (_gnutls_initialize_session_ticket_key_rotation), explicitly says:

 * This function will not enable session ticket keys on the server side. That is done
 * with the gnutls_session_ticket_enable_server() function. This function just initializes
 * the internal state to support periodical rotation of the session ticket encryption key.

In other words, it thinks it is not responsible for session ticket initialization, yet it is. Indeed, the merge request fixing the problem unconditionally does this:

memcpy(session->key.initial_stek, key->data, key->size);

I haven't reviewed the code and the vulnerability in detail, so take the above with a grain of salt.

The full patch is available here. See also the upstream issue 1011, the upstream advisory, the Debian security tracker, and the Redhat Bugzilla.

Moving forward

The impact of this vulnerability depends on the affected packages and how they are used. It can range from "meh, someone knows I downloaded that Debian package yesterday" to "holy crap my full disk encryption passwords are compromised, I need to re-encrypt all my drives", including "I need to change all LDAP and MySQL passwords".

It promises to be a fun week for some people at least.

Looking ahead, however, one has to wonder whether we should follow @FiloSottile's advice and stop using GnuTLS altogether. There are at least a few programs that link against GnuTLS because of the OpenSSL licensing oddities but that has been first announced in 2015, then definitely and clearly resolved in 2017 -- or maybe that was in 2018? Anyways it's fixed, pinky-promise-I-swear, except if you're one of those weirdos still using GPL-2, of course. Even though OpenSSL isn't the simplest and secure TLS implementation out there, it could preferable to GnuTLS and maybe we should consider changing Debian packages to use it in the future.

But then again, the last time something like this happened, it was Heartbleed and GnuTLS wasn't affected, so who knows... It is likely that people don't have OpenSSL in mind when they suggest moving away from GnuTLS and instead think of other TLS libraries like mbedtls (previously known as PolarSSL), NSS, BoringSSL, LibreSSL and so on. Not that those are totally sinless either...

"This is fine", as they say...

Mandos

Mandos co-author here. You are correct about Mandos; only OpenPGP encrypted data is sent over the TLS connection. Also, Mandos does use TLS1.3, so only active connections could ever have been intercepted and decrypted.

If one would suspect that this actually has been done, what one should do on each Mandos client is change the OpenPGP key, generate a new encrypted blob for the Mandos server configuration, using the same password for the encrypted disk; the password can not have been compromised unless the OpenPGP secret key from the client also was compromised. (Of course, changing the encrypted disk password is also an option, but that would also mean generating a new encrypted blob for the Mandos server configuration, which would mean more work than the other option.)

Regarding your comment about Heartbleed; I agree; in using GnuTLS, we have been able to avoid being affected by most of the TLS vulnerabilities in recent years. Also, we do not know of any other TLS library which provides either OpenPGP keys as session keys (RFC 6091), or raw public keys (RFC 7250). We prefer to avoid X.509 certificates, so we need either one; GnuTLS recently switched from the former to the latter.

Comment by teddy
Created . Edited .