OpenSSL Security Advisory
openssl.org
openssl.org
I think the latest big thing I've learned in my career is that trying to fix broken input data silently is always bad. Fixing stuff silently isn't helpful for the callers, it's very difficult to do and it produces additional code which also isn't running in the normal case, so it's much more likely to be broken.
Additionally, your callers will start to depend on your behaviour and suddenly you have what amounts to two separate implementations in your code.
I learned that while blowing up (though don't call exit if you're a library. Please.) is initially annoying for callers, in the end, it will be better for you and your callers because code will be testable, correct and more secure (because there's less of it)
When dealing with integration among many parties, there is tremendous pressure to just "make it work". The web arguably is an example of this - the standards were post-facto representations of what's already implemented.
Of course we are all hating the long term implications on our codebases , but "let's force everyone to do it one way through strict behaviour" seems to discount the social dynamics of interoperability.
Moving away from Postel's principle in production will not lead to successful open and interoperable implementations, it will rather trend towards towards one single implementation , likely open source, that is shared and tweaked by all. That has some positive (interop!) and negative implications (limited ability to innovate / dragged down into programmer religions, etc).
His famous principle is about border cases, when the spec is vague, handwavy or thought by some to be vague. It's not about the other cases.
Remember that Jon Postel was the RFC editor. He didn't want anyone to ignore the RFCs, he wanted the RFCs to be readable and pleasant, and he wanted implementers to do the right thing when when an RFC erred on the side of readability.
FWIW I wrote a blog post about this a few years ago, http://rant.gulbrandsen.priv.no/postel-principle
HTTP also has corner cases that widely-used implementations simply aren't handling consistently because the original RFCs are vague or the ideas being conveyed are buried in even older RFCs that nobody has the incentive to drill in to, or simply aren't known to them.
IMHO the IETF really should move to a wiki format, where information and wording changes on a particular protocol can be seen in one place. Plaintext snapshots of particular versions could still be published.
[0] https://www.ietf.org/mail-archive/web/dnsop/current/msg13349...
[1] https://kea.isc.org/wiki/ZoneLoadingRequirements#a3.3RFCimpl...
Is the rule a bit messy? Yes it is!
It's so much simpler to use, and less problematic.
I would say it's also true for security-related protocols, such as in this case.
But for general network protocols some leniency in processing is necessary, or even beneficial for forwards-compatibility.
The problem is that you want to retire a 1024-bit CA root, and replace it with a 4096-bit CA root. To do this effectively, new clients need to stop trusting the old 1024-bit CA root, or there's no point doing the transition.
However, you still want certificates that you issue to be verified by old clients that don't know about the 4096-bit CA root.
To solve this, you issue certificates with two alternate chains of trust - one up to the old 1024-bit root, and one up to the new 4096-bit root - and teach the new clients to check all the alternate chains.
It's this last bit that required the code change in OpenSSL, which contained the logic error that resulted in this vulnerability.
Before someone provides the standard "submit a patch" retort, I'll note that the variable naming is in full compliance with https://www.openssl.org/about/codingstyle.txt even if the function length isn't. A quick sample of other files suggests the function length matches actual practice elsewhere, too.
I'll grant that having variables named with "tmp" is confusing out of context, I guess. But if you're trying to start a Java-style war over this stuff, just recognize that most of the world has moved on and views names like those as perfectly fine when used within standard idioms.
i = sk_X509_num(ctx->chain);
i = check_trust(ctx);
i = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain, ctx->param->flags);
What a mess. I would probably start by moving towards a module / class for all the functions that take either an X509_STORE_CTX *ctx pointer or something accessed through ctx.To actually comprehend this function requires storing those 14 names in short-term memory, reading through the over 300 lines of remaining code, filling in bits of the meaning of those names as they become clear, and only then reading the code again with that mental map. That's the case where none of the 14 have slipped my mind by the time I get back around. That just seems like an awful lot of overhead to net something that could be as easy as reading names if they were better chosen.
Just as a demonstration, why don't you time how long it takes you to figure out what j actually is and then report back?
class Function<T> {
public apply(T param);
}"Do not unnecessarily use braces around a single statement:
if (condition)
action();
and if (condition)
do_this();
else
do_that();
"Didn't people learn from the goto fail bug ? http://embeddedgurus.com/barr-code/2014/03/apples-gotofail-s...
If you consider all braces to be necessary, then that's a truism and you can safely ignore it. "I didn't unnecessarily use them: we always use them because that's the safe thing to do."
//okay
if (condition) return foo;
//not okay
if (condition)
return foo;
//not okay
if (condition) do_foo();
else do_bar();
In the second case, the else can be considered a continuation. In the first example, there's little chance of confusion or the introduction of an error, in the second and third, that is not necessarily the case.If it doesn't look/fit well on one line, break it up with braces.
if((somevar != checkvar((byte)othervar)) & (i != 3)) somefunc();
someotherfunc();
A bit exaggerating, I agree, but not far off from some real-world examples and quite confusing.
I've seen far, far, far worse...
Bug added: https://github.com/openssl/openssl/commit/da084a5ec6cebd67ae...
Bug removed: https://github.com/openssl/openssl/commit/2aacec8f4a5ba1b365...
Although that's just the committer: https://twitter.com/agl__/status/619129579580469248
For interest, the line that was fixed from the first commit is:
https://github.com/openssl/openssl/commit/da084a5ec6cebd67ae...
/* Remember how many untrusted certs we have */
j = num;
Flawless.https://ma.ttias.be/openssl-cve-2015-1793-man-middle-attack/
"The vulnerability appears to exist only in OpenSSL releases that happened in June 2015 and later. That leaves a lot of Linux distributions relatively safe, since they haven't gotten an OpenSSL update in a while.
Red Hat, CentOS and Ubuntu appear to be entirely unaffected by this vulnerability, since they had no OpenSSL updates since June 2015."
No wonder distros take their time moving to a new version. I really hope one of the alternative SSL libraries get picked up by the major distros. This is embarrassing, especially for those of us who have to justify FOSS in our environment.
LibreSSL looks promising. Hopefully competition will mean better outcomes for such critical libraries.
It's not the number of bugs that matters, or even the fact that new bugs get introduced over time - rather it's the severity of the bugs, how rapidly the bugs are realized, and ultimately how fast they are dealt with.
In this case, it appears to have been a pretty rapid resolution - ie. about 1 month from it being introduced, realized, and fixed.
A lot of folks like to lean on LibreSSL and cite "supposed problems" with OpenSSL, just as you have done now. This is a naive approach -- LibreSSL took OpenSSL, cannibalized and gutted it, and all sorts of new, untested, un-vetted code injected. OpenSSL was written largely by crypto specialists, where LibreSSL is mostly a bunch of grumbling developers, with little to no prior crypto experience.
There's a reason the world is not jumping on LibreSSL just yet. There's a reason foundations outside of the LibreSSL home (OpenBSD) such as the Core Infrastructure Foundation have not backed it -- it's simply not ready, is very unproven, and won't be for a long, long time, if ever.
Give OpenSSL a break. It works far better than nay-sayers want to let on, and has done so for almost 2 decades.
What?
1) Why they believe so,
2) Why they haven't filed security advisories to advise the rest of us, and
3) Why you don't hear about banks being wiped clean because crackers were able to bypass SSH's security measures.
It's possible they're right, but as with all extraordinary claims, the onus of proof is on the ones making them.
2) I tried to explain millions of people around the world rely on it and use it. I argue it's probably safe (within reason - obviously the weak point is the private key file).
These were also the guys who refused to install packages we asked for from the community RedHat repository claiming security vulnerabilities but then they just admitted they installed some packages from there for their own use for puppet and other things they do.
This is an example of them doing better. A bug was found, reported to them, and they responded quickly giving advanced notice too.
Test for CVE-2015-1793 (Alternate Chains Certificate Forgery)
Chain is as follows:
rootCA (self-signed)
|
interCA
|
subinterCA subinterCA (self-signed)
| |
leaf ------------------
|
bad
rootCA, interCA, subinterCA, subinterCA (ss) all have CA=TRUE
leaf and bad have CA=FALSE
subinterCA and subinterCA (ss) have the same subject name and keys
interCA (but not rootCA) and subinterCA (ss) are in the trusted store
(roots.pem)
leaf and subinterCA are in the untrusted list (untrusted.pem)
bad is the certificate being verified (bad.pem)
Versions vulnerable to CVE-2015-1793 will fail to detect that leaf has
CA=FALSE, and will therefore incorrectly verify badopenssl would accept certs that have been issued by a non-ca cert (which is trusted).
So if you have control over the leaf cert, you can just use it for contacting openssl.
If you don't have control over the leaf cert, you can't issue a bad cert.
Am I missing something?
If I understand the advisory correctly then this means that somebody could set up a webserver with a specially-crafted certificate and pretend to be somebody else, assuming that the client is running a vulnerable version of OpenSSL.
Is that right? I wish they would write these advisories in a slightly more helpful fashion.
(clearly there are far fewer of those around but they do exist)
OpenSSL Security Advisory [9 Jul 2015]
=======================================
Alternative chains certificate forgery (CVE-2015-1793)
======================================================
Severity: High
During certificate verification, OpenSSL (starting from version 1.0.1n and 1.0.2b) will attempt to find an alternative certificate chain if the first attempt to build such a chain fails. An error in the implementation of this logic can mean that an attacker could cause certain checks on untrusted certificates to be bypassed, such as the CA flag, enabling them to use a valid leaf certificate to act as a CA and "issue" an invalid certificate.
This issue will impact any application that verifies certificates including SSL/TLS/DTLS clients and SSL/TLS/DTLS servers using client authentication.
This issue affects OpenSSL versions 1.0.2c, 1.0.2b, 1.0.1n and 1.0.1o.
OpenSSL 1.0.2b/1.0.2c users should upgrade to 1.0.2d OpenSSL 1.0.1n/1.0.1o users should upgrade to 1.0.1p
This issue was reported to OpenSSL on 24th June 2015 by Adam Langley/David Benjamin (Google/BoringSSL). The fix was developed by the BoringSSL project.
Note
====
As per our previous announcements and our Release Strategy (https://www.openssl.org/about/releasestrat.html), support for OpenSSL versions 1.0.0 and 0.9.8 will cease on 31st December 2015. No security updates for these releases will be provided after that date. Users of these releases are advised to upgrade.
References
==========
URL for this Security Advisory: https://www.openssl.org/news/secadv_20150709.txt
Note: the online version of the advisory may be updated with additional details over time.
For details of OpenSSL severity classifications please see: https://www.openssl.org/about/secpolicy.html
Huh? Of the 22 vulnerabilities OpenSSL has disclosed since March (4 high severity, 14 moderate, 4 low), LibreSSL has been vulnerable to 8 (0 high, 6 moderate, 2 low).
References:
March: https://marc.info/?l=openbsd-cvs&m=142677372515025&w=2
June: https://marc.info/?l=openbsd-announce&m=143406498020131&w=2
Today: https://marc.info/?l=openbsd-tech&m=143645910727507&w=2
Distributions such as CentOS/RHEL which are focused on stability are not going to replace OpenSSL in any existing releases.
I've been testing this against each release for some time and I'm very happy with it.
Note that recently a big clean up of the openssl codebase has taken place so openssl master no longer exposes the internals of structs etc. meaning it's both more auditable and more maintainable. This code is not yet released however.
See: Exherbo Linux (http://www.exherbo.org/docs/eapi/providers-and-virtuals.html). This isn't one of the big distros, but you do have a choice.
Many projects have also invested heavily into optimizing the performance of OpenSSL itself or the use of its interfaces.
You can't sprinkle "magic SSL dust" over these components and just start using an alternative. In some cases, significant, non-trivial changes would be required to change which library is used.
The reality is, as fast as OpenSSL development is moving now, it remains the better option for a lot of projects because of the significant investments already being made and concerns I mentioned earlier.
Some more details & patching guide here: https://ma.ttias.be/openssl-cve-2015-1793-man-middle-attack/
I was considering using the `ec2.py` script from Vagrant's dynamic inventory docs and then running SSH command execution over all our instances to upgrade the packages for both Ubuntu and AWS AMIs (yum), just to be safe. Guess I don't need to after all!
*) Alternate chains certificate forgery
During certificate verfification, OpenSSL will attempt to find an
alternative certificate chain if the first attempt to build such a chain
fails. An error in the implementation of this logic can mean that an
attacker could cause certain checks on untrusted certificates to be
bypassed, such as the CA flag, enabling them to use a valid leaf
certificate to act as a CA and "issue" an invalid certificate.
This issue was reported to OpenSSL by Adam Langley/David Benjamin
(Google/BoringSSL).
[Matt Caswell]in order to exploit the attack in hex you need find a CA that will directly issue certificates off of a certificate in a trust store. apparently, this is not the recommended policy for CAs. so I made this tweet: (https://twitter.com/benmmurphy/status/613733887211139072)
'does anyone know a CA that signs directly from their root certs or has intermediate certs in trust stores? asking for a friend.'
and apparently there are some CAs that will do this. in the case of hex i think the chain you need to create looks something like this:
RANDOM CERT SIGNED BY ISSUER NOT IN TRUST STORE
|
V
VALID_CERT_SIGNED_BY_CERT_IN_TRUST_STORE (effectively treated as CA bit set)
|
V
EVIL CERTIFICATE SIGNED BY PREVIOUS CERTSee https://mullvad.net/en/v2/news for more details.
http://people.canonical.com/~ubuntu-security/cve/2015/CVE-20...
But everybody must upgrade their browsers ASAP.
These are not activities which a web server does though.
These are activities usually triggered by developers or administrators, not by web servers remotely and they have to do with a web application, not a web server.
And even then, for this attack to be meaningful you'd need to have active MITM between the server and PyPI or rubygems at the time when the developer or administrator was updating this. In a good datacenter, this should not be possible. Employees of the DC and national security agencies, which may be able to perform active attacks in such datacenters would probably be the biggest risk.
Yeah. Which is pretty much the thing (or one of the things anyway) that TLS is supposed to prevent!
>These are activities usually triggered by developers or administrators, not by web servers remotely and they have to do with a web application, not a web server.
Some strange distinctions. A server running a web application may well want to make requests to PyPI when being provisioned.
It's wrong in that this is very much your problem. It's right in that there is nothing you can do about it except hope that all the people who might try to connect to your website are using a patched (or pre-broken) verison of OpenSSL.
Patching your server-side version of OpenSSL (while a good idea) will not solve the problem because certificate verification is done (as it must be) browser-side.
all quibbling aside, most people would probably need an explanation to understand your post, as the recent version of debian is indeed affected, as in debian-unstable (sid)'s openssl.
If not, submit patches.
An OpenSSL team member said, "If you're in a position to offer technical criticism you're in a position to offer technical help." While it sounds like their pleading for help, its because WE ARE. There are 3 full time maintainers, 1 is a dog :P and only ~10-16 regular patch submitters.
A lot of that has now changed with the Core Infrastructure Initiative.
Here you go!