[openssl-users] Authentication over ECDHE
Jakob Bohm
jb-openssl at wisemo.com
Sat Dec 29 15:53:25 UTC 2018
On 29/12/2018 14:19, C.Wehrmeyer wrote:
> I don't have access to the actual testing environments until Wednesday
> next year, so I've had to create a private account.
>
> > Which version of OpenSSL is this? (I don't remember if you said this
> > already).
>
> I'm not entirely sure, but I *think* it's 1.1.0.
>
> =====================================================================
>
> OK, so I've been reading the mails before going to sleep and spent
> some time thinking and researching about this, and I've come to a
> conclusion: OpenSSL is a goddamn mess, SSL_clear() is pretty much
> superfluous, and as such shouldn't exist.
>
> Why? Well, to quote Viktor here:
>
> > DO NOT reuse the same SSL handle for multiple connections,
>
> And that is fricking bullshit. Not the quote itself or the suggestion
> - it's unlikely you had anything to do with the actual code - but the
> way things have been thought through (or rather, have not been thought
> through) by the library devs. I've written highly scalable libraries
> in the past before, and one thing you always want to do there is to
> trim fat. And "object allocation and initialisation" is something that
> you very much want to trim fat of, not only for obvious reasons such
> as malloc() and free() (or whatever OpenSSL uses as wrappers) being
> complexity monsters, but also for cache reasons (loading different
> cache line hurts performance). That's why you usually have functions
> like XXX_clear() or XXX_reset(), which do exactly that - prepare an
> object for another usage. memset() (or the OpenSSL equivalent of a
> secure memset) your allocated resources. I don't really see the
> problem here.
>
> Now add to that the fact that OpenSSL has been moving towards making
> its structures opaque, thus falling into the same trap that Microsoft
> has with COM and DirectX, and you can kind of see why, if you can't
> really determine anymore WHERE your object is going to be stored, you
> at least want to keep reusing it. This is not PHP, where people
> allocate memory all willy-nilly, or C++, where people don't even have
> shame anymore to use std::vector<std::strings> str_array instead of
> good old static const char*const str_array[] while expecting things to
> be made faster by invisible memory pools (and horribly failing at it),
> but C, where you want to think about each step quite carefully.
>
> Then OpenSSL even provides an SSL_clear function which is advertised
> like this:
>
> > SSL_clear - reset SSL object to allow another connection
>
> , and then, only later, in a big warning block, decides to tell the
> reader that this function only works when the stars align quite
> correctly and you've sacrificed at least two virgins, because:
>
> > The reset operation however keeps several settings of the last
> > sessions
>
> Then, as the documentation suggests, I read the entry for
> SSL_get_session:
>
> > The ssl session contains all information required to re-establish the
> > connection without a full handshake for SSL versions up to and
> > including TLSv1.2. In TLSv1.3 the same is true, but sessions are
> > established after the main handshake has occurred.
>
> And at this point it all falls apart. From my understanding OpenSSL
> keeps a session cache for servers so that key exchanges and protocol
> handshakes can be avoided. Problem is, *we're using ECDHE, where the
> last E stands for "ephemeral"*. In simple English: throw away the keys
> after you're done, we want to have forward secrecy. And then OpenSSL
> keeps a fresh copy of those for everyone who happened to be logged on
> at this point. Heartbleed apparently wasn't enough of a warning. Oh,
> but lets move everything to the heap so that it's more secure there now.
>
> I don't want to reuse a session with ephemeral keys; I want to reuse
> an object that is supposed to already have resources allocated for
> doing its job, as is indicated by the documentation of this function
> except for a small note at the end that tells you that the devs didn't
> really think about what "ephemeral" means.
>
The session caching in the SSL and TLS protocols is to skip the
expensive key exchange when reconnecting within a few seconds,
as is extremely common with web browsers opening up to 8 parallel
connections to each server.
There is hopefully a configuration option to tell the OpenSSL server
end SSL_CTX to not do this, just as there should (for multi-process
web servers) be an option to hand the state storage over to the web
server application for inter-process sharing in whatever the web
server application (and its configuration) deems secure.
> Creating a new SSL object (EVEN FROM AN EXISTING SSL_CTX object) entails:
>
> - allocating the memory for the object itself on the heap (via
> OPENSSL_zalloc)
> - creating and managing a new lock for the object, and who knows for
> much more subobjects
> - creating a duplicate of the cipher suite stack (which isn't even a
> flat copy, but something that can cause the code to call
> OPENSSL_malloc *twice* in the worst case)
> - creating a duplicate of the certificates (which I don't even use,
> but that doesn't stop the code of ssl_cert_dup() to call
> OPENSSL_zalloc *in its very first line!*)
> - setting up a bunch of callbacks
> - copying 32 bytes for a sid_ctx
> - creating an X509_VERIFY_PARAM object (*which calls OPENSSL_zalloc
> again*) as well as creating a deep copy of the SSL_CTX's parameter via
> X509_VERIFY_PARAM_inherit(), with Thor knows how many copies hidden in
> all those *set* and *deep_copy* routines
> - copying EC point formats from the context - deep again, of course,
> at least that's what OPENSSL_memdup() makes me think
> - copying supported group informations, and of course deep again!
> - deep-copying an ALPN object
> - SSL_clear()-ing the object (no, really!)
> - deep-copying a CRYPTO_EX_DATA object via CRYPTO_new_ex_data ... at
> this point, is anyone surprised here that timing attacks against
> crypto are *still* so successful? Because I'm not. Not at all.
>
> I didn't bother looking up what freeing entails - it's obvious to
> anyone at this point that OpenSSL is a severe victim of feature creep,
> that its memory allocation scheme is a mess, and long story short: I
> will NOT free a perfectly fine object just because of incompetent
> devs' chutzpah expecting their users to allocate memory dynamically en
> mass for no goddamn reason whenever a new connection comes in. Fix
> your goddamn code.
>
> And don't give me any "trust us, we're experienced programmers"
> bullshit. I've *seen* ssl/record/ssl3_record.c:
>
> > static const unsigned char ssl3_pad_1[48] = {
> > 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
> > 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
> > 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
> > 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
> > 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
> > 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
> > };
> > static const unsigned char ssl3_pad_2[48] = {
> > 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
> > 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
> > 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
> > 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
> > 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
> > 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
> > };
>
> What's wrong with that, you ask? Let me show you how I'd have done that:
>
> > static const unsigned char ssl3_pad_1[] =
> > {
> > "66666666"
> > "66666666"
> > "66666666"
> > "66666666"
> > "66666666"
> > "66666666"
> > };
> >
> > static const unsigned char*ssl3_pad_2[] =
> > {
> > "\\\\\\\\\\\\\\\\"
> > "\\\\\\\\\\\\\\\\"
> > "\\\\\\\\\\\\\\\\"
> > "\\\\\\\\\\\\\\\\"
> > "\\\\\\\\\\\\\\\\"
> > "\\\\\\\\\\\\\\\\"
> > };
>
> So, no. I don't trust anyone. Especially not this mess of a code.
Well, these two latter arrays look like a stray copy of the HMAC
constants "ipad" and "opad", which (while looking like ASCII), are
defined as exact hex constants even on a non-ASCII machine, such
as PDP-11 or an IBM mainframe.
I wonder if those constants are actually still used somewhere in
the SSL3 code, or if they have been properly replaced by calls to
the HMAC implementation in libcrypto.
Enjoy
Jakob
--
Jakob Bohm, CIO, Partner, WiseMo A/S. https://www.wisemo.com
Transformervej 29, 2860 Søborg, Denmark. Direct +45 31 13 16 10
This public discussion message is non-binding and may contain errors.
WiseMo - Remote Service Management for PCs, Phones and Embedded
More information about the openssl-users
mailing list