top | item 7338389

GnuTLS certificate verification vulnerability announced (CVE-2014-0092)

65 points| mpyne | 12 years ago | reply

The GnuTLS team has their announcement at http://www.gnutls.org/security.html#GNUTLS-SA-2014-2 but the announcement with details seems to be Red Hat's at https://rhn.redhat.com/errata/RHSA-2014-0247.html

"It was discovered that GnuTLS did not correctly handle certain errors that could occur during the verification of an X.509 certificate, causing it to incorrectly report a successful verification. An attacker could use this flaw to create a specially crafted certificate that could be accepted by GnuTLS as valid for a site chosen by the attacker."

40 comments

order
[+] tptacek|12 years ago|reply
Here's the diff:

https://www.gitorious.org/gnutls/gnutls/commit/6aa26f78150cc...

Uninitialized "result" variable? Any time the code hits one of those "cleanup" gotos, it's probably returning nonzero unexpectedly?

Later: @filcab on Twitter points out the much dumber issue, which is that if issuer_version is < 0, the function returns issuer_version and not zero. Ow.

(Who uses GnuTLS?)

[+] dfc|12 years ago|reply

  emacs + email/nntp
  wget
  vlc
  network-manager
  mutt
  empathy
That is just the highlights for libgnutls26.

I had forgotten about libcurl3-gnutls. There are a lot of things that depend on the libcurl3-gnutls, that list is long and distinguished. But I feel a little icky listing things without actually verifying they are affected. Just because they depend on the libs does not mean they use the bad code in the lib.

If you want to see what depends on libgnutls26 or libcurl3-gnutls in debian:

  $ apt-cache rdepends library-name
The --installed filter selects only those things that you have installed that depend on X:

  $ apt-cache --installed rdepends library-name
Scoreboard:

  dfc@ronin:~$ apt-cache  rdepends libgnutls26 libgnutls28 libcurl3-gnutls |wc
      629     632   10661
  dfc@ronin:~$ apt-cache  rdepends libssl1.0.0|wc
      751     752   11642
[+] sanxiyn|12 years ago|reply
git on Debian, for example. In general, GPL programs need special exception to link to OpenSSL, and git is licensed under GPL without the exception.
[+] mike-cardwell|12 years ago|reply
Exim can be compiled against OpenSSL or GnuTLS. The official Debian package comes compiled against GnuTLS, although it is trivial to build a Debian package compiled against OpenSSL instead.
[+] cjg_|12 years ago|reply
I wonder if there is any TLS library that actually does certificate verification properly...
[+] illumen|12 years ago|reply
This is similar to the Apple SSL bug.

Good on them for looking for similar errors in their own code. Thanks Redhat, for the audit, and for making the internet safer!

This is a win for Free software (and OSS), since the history of the bug can be traced, and outside developers can audit it. We still don't know how the bug got in there with the Apple bug - since the repository is not open.

[+] stephenr|12 years ago|reply
So Apple has an admittedly serious bug that is in the wild on iOS for ~17 months, and desktops for ~ 4 1/2 months, and everyone shits on Apple for it.

GNUTLS has a (using your words) "similar" bug in the wild for more than 13 YEARS, and its nothing but praise because "they audited the code"?

[+] lawnchair_larry|12 years ago|reply
This is definitely a moment of shame, not praise. Good on RedHat for the audit, but a dark moment for GnuTLS. That was some dumb code in a very important place. Nobody reviewed that at all, clearly.
[+] zvrba|12 years ago|reply
For all C++ haters and C defenders: the cleanup/fail labels set result to 0 and perform a bunch of _gnutls_free_datum calls. This would not have happened in a properly designed C++ program because you could have just written "return 0;" and let the compiler release the resources (RAII, destructors).

IMO, C is no longer suitable as a systems programming language. It has stopped being that a long time ago, and its only value is ABI stability. (COM and similar technologies work with C++ and other languages, so C is unnecessary even for that purpose.)

[+] illumen|12 years ago|reply
What do you think of C++ and timing attacks? What do you think of the surface area of the C++ runtime itself? How do you find auditors for C++ code, when the standard is so big no one person could possibly understand it all?

These are genuine questions, it would be great to hear your answers about these things :)

[+] yetfeo|12 years ago|reply
> IMO, C is no longer suitable as a systems programming language.

Neither is C++. People writing new systems level code should seriously consider safer languages. ATS, Rust, Mercury, OCaml, SML, and many others.

[+] simias|12 years ago|reply
What if you have a bug in your destructor then? Bugs happen, in any language.

Maybe C++ is better suited, maybe it isn't. I don't care. It's not the problem here.

The problem is poor test coverage and code auditing. You could rewrite it in prolog for all I care, it doesn't address this core issue. Don't miss the forest for the trees.

[+] jmnicolas|12 years ago|reply
For those like me, wondering what GnuTLS is :

"GnuTLS is a secure communications library implementing the SSL, TLS and DTLS protocols and technologies around them. It provides a simple C language application programming interface (API) to access the secure communications protocols as well as APIs to parse and write X.509, PKCS #12, OpenPGP and other required structures. It is aimed to be portable and efficient with focus on security and interoperability."

from : http://www.gnutls.org/

[+] rkangel|12 years ago|reply
What do other people think about the "goto" pattern for handling errors? I've never been a huge fan of it due to the unclear control flow you get, a point of view which this seems to back up very well. I'd much rather set a return/error code appropriately, encase each chunk of code in a 'if (OK == ec) {...}' and then clean up based on the ec at the bottom. That way what code is executed in any given circumstance is blindingly obvious and so is the clean up.

The "goto fail" pattern seems pretty common though - I was wondering what it had in its favour apart from being a easier to type (which would also be true of "not checking for errors" for example).

[+] mpyne|12 years ago|reply
It's actually not horrific IMHO in the context of C when you use it explicitly in this fashion, as a "poor man's exceptions with resource cleanup". And it's not simply a method to avoid typing, it helps with the very common design pattern of:

    acquire A
    acquire B
    acquire C
    
    do_work
    
    release C
    release B
    release A
It has all the benefit of "common return path" (since it is a common return path) without the 8 levels of indentation and random subsidiary conditional checks that obscure the code logic and add their own confusion. Instead you fail as fast as possible.

Like any other design pattern (C or otherwise) it's easy to misuse or abuse and it's not suited to every combination of library usage.

[+] blueskin_|12 years ago|reply
Again, I find myself wondering "Why not just use OpenSSL instead?"
[+] rweir|12 years ago|reply
perhaps read any of the other comments? tldr, license and it's also terrible.