[cryptography] Just how bad is OpenSSL ?
code at funwithsoftware.org
Sat Oct 27 21:47:05 EDT 2012
On 10/26/12 11:29 AM, John Case wrote:
> So, given what is in the stanford report and then reading this rant
> about openssl, I am wondering just how bad openssl is ? I've never had
> to implement it or code with it, so I really have no idea.
I think that "OpenSSL is written by monkeys" is a bit sensationalist and
unfair, but I do think it's fair to say that OpenSSL is user-hostile,
and is written by experts for their own use, not for others to come
along and use.
The biggest problem with OpenSSL is that it is really, really poorly
documented. There is no "big picture, gentle introduction"
documentation that ships with OpenSSL. Most of the OpenSSL functions
are documented in man pages, but some important functions are not
documented. And the man pages often don't explain enough about the
functions, like "why would I want to use this function instead of that
one, when they both sound like they do the same thing?" Also, the
naming of the man pages is user-hostile. The worst one is that there is
a man page named "rand". The other OpenSSL man pages tell me to see
"rand(3)". But, of course, "man 3 rand" gets me the man page for the C
standard library function, rand(). I eventually figured out I needed to
do "man 3ssl rand" to get the man page for OpenSSL's random number
As far as I can tell, there is only one decent book that has been
written about OpenSSL: the O'Reilly book "Network Security with
OpenSSL". It is ten years old now, which is not as bad as it sounds,
because OpenSSL hasn't changed that much since then. Nevertheless, it
obviously doesn't cover anything that's been added to OpenSSL in the
past decade, and I had to modify some of the code examples because
current versions of OpenSSL are better about using "const" in function
prototypes, for instance. I also got some good laughs, like when the
book talked about this brand-new algorithm called AES that OpenSSL had
just recently added support for.
Between reading the O'Reilly book, the man pages, the OpenSSL mailing
list, random things people have written on the web, and of course, the
source code (a lot!), I've been able to use OpenSSL, but it's been very
slow and frustrating, and I curse the name of OpenSSL every day.
Besides the poor documentation, the other thing about OpenSSL is that it
is definitely not "batteries included." Now, I'm not expecting it to be
some high-level https library like curl. I intentionally wanted a
low-level TLS library, because my job was to encapsulate a custom
messaging protocol in TLS. But still, OpenSSL is lacking in some things
I would hope a low-level TLS library would have. For instance, it
doesn't have everything you need to validate certificates, and you need
to write some of that code yourself.
One of the most glaring things OpenSSL is missing out-of-the-box is
thread safety. If you want OpenSSL to be threadsafe, you have to supply
your own callback. This is different than the approach taken by many
other libraries (for example, libevent, or GnuTLS) which supply
threading implementations for pthreads and Win32, and only require
callbacks if you are on a more exotic operating system. Not only is it
annoying to have to supply this boilerplate code, but my bigger concern
is that it makes it very tricky to use OpenSSL from more than one
library in the same process. Assuming that each library wants to be
threadsafe, and wants to hide its use of OpenSSL as an implementation
detail (rather than telling the user "you need to supply OpenSSL thread
callbacks"), then that means each library needs to set the OpenSSL
threading callbacks to point at its own implementation. But since the
OpenSSL threading callbacks are global, only one of them is going to
"win". Now, it's possible that everything will be okay, because whoever
"wins" will just end up providing thread safety to everyone. But, it
seems kind of sketchy and scary, and I can imagine bad things happening,
like if one library is initialized (and thus sets the OpenSSL callbacks)
after another library is already using OpenSSL.
(One of the things I'm getting at in the previous paragraph is that
OpenSSL seems to be written with the intention that it's only going to
be used by the "main program", which a single person or organization is
going to write. OpenSSL doesn't seem to have in mind the possibility
that it will be used by multiple, higher-level libraries which don't
know anything about each other, but which are all used by a single
program in a single address space.)
So, I think that OpenSSL could be made better by two things: (1) better
documentation, and (2) a small "helper" library that sits on top of it
and provides thread-safety callbacks, and other "missing" helper
functions like certificate validation. But, the helper library should
be small, simple, and low-level enough that it would be possible to
convince the high-level libraries (such as curl, libevent, etc.) to link
against it, rather than each providing their own thread callbacks to
OpenSSL. I've felt some temptation to write such a library, if there
are people besides me who think it is a good idea and would be
interested in using it.
However, if you have a choice of what TLS library to use, you might be
better off using a different one, such as GnuTLS. GnuTLS has an
absolutely wonderful manual; the contrast between OpenSSL's
documentation and GnuTLS's documentation is like night and day!
However, despite the atrocious documentation, I ended up picking OpenSSL
over GnuTLS for my project (a closed-source project at work, not
something I was doing on my own) for a couple of reasons:
(1) We wanted to use libevent, and libevent has an integration with
OpenSSL. If we'd used GnuTLS, we would have had to write our own
integration between libevent and GnuTLS.
(2) GnuTLS is LGPL-licensed, which is normally not a problem for
closed-source software. However, we needed to support a wide variety of
platforms, including iPhone, and we had some concern that the LGPL was
not compatible with the terms of the iOS App Store.
For the most part, I would say that OpenSSL is not badly written, just
badly documented. I am not a cryptography expert (just a smart,
experienced programmer, trying to use TLS) so I'm not in a particularly
good position to judge the cryptographic merits of OpenSSL. For the
most part, it seems sound, although a couple of things have given me
pause. One is OPENSSL_cleanse, which overwrites memory with random
data. Every other cryptography library I've seen seems to be happy with
just overwriting sensitive memory with zero. I haven't seen any
explanation of why OpenSSL believes that overwriting with random data is
better than overwriting with zero. In the absence of an explanation, it
feels a bit cargo-cultish.
The other thing that bugged me a bit was in the infamous rand(3ssl) man
3. The state should be very large. If the RNG is being used
to generate 4096 bit RSA keys, 2 2048 bit random strings
are required (at a minimum). If your RNG state only has
128 bits, you are obviously limiting the search space to
128 bits, not 2048. I'm probably getting a little
carried away on this last point but it does indicate that
it may not be a bad idea to keep quite a lot of RNG
state. It should be easier to break a cipher than guess
the RNG seed data.
This seems to contradict the advice given on Linux's random(4) man page:
The amount of seed material required to generate a crypto‐
graphic key equals the effective key size of the key. For
example, a 3072-bit RSA or Diffie-Hellman private key has an
effective key size of 128 bits (it requires about 2^128 oper‐
ations to break) so a key generator only needs 128 bits (16
bytes) of seed material from /dev/random.
While some safety margin above that minimum is reasonable, as
a guard against flaws in the CPRNG algorithm, no crypto‐
graphic primitive available today can hope to promise more
than 256 bits of security, so if any program reads more than
256 bits (32 bytes) from the kernel random pool per invoca‐
tion, or per reasonable reseed interval (not less than one
minute), that should be taken as a sign that its cryptography
is not skilfully implemented.
Anyway, sorry for this long semi-rant which went off on a few tangents,
but I hope it answers your question of what the experience is like for
someone new to OpenSSL.
More information about the cryptography