How Heartbleed Leaked Private Keys
blog.cloudflare.com
blog.cloudflare.com
It isn't just their attention to detail that is impressive. They go out of their way not just to point out issue, but suggest fixes.
Too many Heartbleed blog posts from across the blogosphere, and sadly, HN comments, set out to criticize without suggesting something better.
Cloudflare has shown again that they are actively engaging the community for the communities benefit as well as their own.
This seems to be a very effective marketing strategy (I assume it is anyway).
Looking impressive with hindsight is relatively easy.
In that same blog post we also said that we were revoking and reissuing all our SSL keys, and started the challenge web site to see if private keys could be retrieved.
http://blog.cloudflare.com/answering-the-critical-question-c...
So, yeah, we didn't from the outset figure out how to get the private keys, but we decided that the risk was too high so we want ahead with revocation.
"And, we have reason to believe based on the data structures used by OpenSSL and the modified version of NGINX that we use, that it may in fact be impossible."
as
"We've reviewed the code and we don't think it's vulnerable."
Obviously you disagree.
When the original statement was posted I actually went back to the header to check the author, thinking "surely jgc wouldn't post something this marketroid?"
Only in hindsight do they point at the get-out clauses.
You have to consider the whole post, which led off with why Cloudflare believed keys wouldn't leak, then went on with a 1000+ word description of how malloc() worked, complete with diagrams, and then concluded with a belief the keys wouldn't leak.
If, instead of running "The Cloudflare Challenge", Cloudflare had simply had you generate the memory diagrams that you built last week, it would have been a different post and less of a waste of everyone's time.
The results of the challenge were a good learning possibility for a lot of people and we, the observers, have now also something we can point to as an example.
Doing any challenge to demonstrate key recovery might have been a sound plan, but the specific challenge that Cloudflare promoted was one that pessimized the discovery function of the challenge and optimized the the reinforcement of their false prediction; to wit, they tied people's hands behind their back, forcing them to attack a remote instance of a process with an unsure memory layout.
if(b->d) OPENSSL_free(b->d);
in OpenSSL :(To me it reads fine and the idea is that is frees that data address if its occupied. I'm sure I'm not the only one who is curious why this is bad.
if (b->d != NULL)
{Insisting on braces is a style concern, though it does seem to protect people from themselves to some extent.
Code should be written for the benefit of humans, not compilers.
if ((bool(b->d != NULL) == true) { }
much better to be explicit, don't you think?
The program will work with no problems, but sensitive data that has been used then freed is available for retrieval when bugs like heartbleed are found.
As the article suggests the right way is to clean the data from memory ( by overwriting it with something else) before freeing it.
For instance if you set a stack-resident buffer that contained a key to all zeros using memset, then simply exit the scope, most optimisations will detect it as unnecessary (wtf? this never gets read back, who cares?) and ditch the line.
Search for memset_s (part of the C11 standard) for a clear function that can survive optimisers.