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 functions.

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 page:

       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.

--Patrick

_______________________________________________
cryptography mailing list
cryptography@randombit.net
http://lists.randombit.net/mailman/listinfo/cryptography

Reply via email to